summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/include
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/include')
-rw-r--r--contrib/llvm/include/llvm-c/Core.h24
-rw-r--r--contrib/llvm/include/llvm-c/ExecutionEngine.h2
-rw-r--r--contrib/llvm/include/llvm-c/OrcBindings.h75
-rw-r--r--contrib/llvm/include/llvm-c/Support.h2
-rw-r--r--contrib/llvm/include/llvm-c/TargetMachine.h2
-rw-r--r--contrib/llvm/include/llvm-c/Transforms/Scalar.h3
-rw-r--r--contrib/llvm/include/llvm-c/Transforms/Vectorize.h2
-rw-r--r--contrib/llvm/include/llvm-c/Types.h14
-rw-r--r--contrib/llvm/include/llvm-c/lto.h144
-rw-r--r--contrib/llvm/include/llvm/ADT/APFloat.h380
-rw-r--r--contrib/llvm/include/llvm/ADT/APInt.h1092
-rw-r--r--contrib/llvm/include/llvm/ADT/APSInt.h16
-rw-r--r--contrib/llvm/include/llvm/ADT/AllocatorList.h61
-rw-r--r--contrib/llvm/include/llvm/ADT/ArrayRef.h56
-rw-r--r--contrib/llvm/include/llvm/ADT/BitVector.h479
-rw-r--r--contrib/llvm/include/llvm/ADT/BreadthFirstIterator.h163
-rw-r--r--contrib/llvm/include/llvm/ADT/DAGDeltaAlgorithm.h10
-rw-r--r--contrib/llvm/include/llvm/ADT/DeltaAlgorithm.h10
-rw-r--r--contrib/llvm/include/llvm/ADT/DenseMap.h87
-rw-r--r--contrib/llvm/include/llvm/ADT/DenseMapInfo.h58
-rw-r--r--contrib/llvm/include/llvm/ADT/DenseSet.h69
-rw-r--r--contrib/llvm/include/llvm/ADT/DepthFirstIterator.h25
-rw-r--r--contrib/llvm/include/llvm/ADT/EquivalenceClasses.h22
-rw-r--r--contrib/llvm/include/llvm/ADT/FoldingSet.h233
-rw-r--r--contrib/llvm/include/llvm/ADT/GraphTraits.h45
-rw-r--r--contrib/llvm/include/llvm/ADT/ImmutableList.h8
-rw-r--r--contrib/llvm/include/llvm/ADT/ImmutableMap.h62
-rw-r--r--contrib/llvm/include/llvm/ADT/ImmutableSet.h127
-rw-r--r--contrib/llvm/include/llvm/ADT/IndexedMap.h18
-rw-r--r--contrib/llvm/include/llvm/ADT/IntervalMap.h49
-rw-r--r--contrib/llvm/include/llvm/ADT/IntrusiveRefCntPtr.h18
-rw-r--r--contrib/llvm/include/llvm/ADT/MapVector.h24
-rw-r--r--contrib/llvm/include/llvm/ADT/None.h5
-rw-r--r--contrib/llvm/include/llvm/ADT/Optional.h33
-rw-r--r--contrib/llvm/include/llvm/ADT/PackedVector.h6
-rw-r--r--contrib/llvm/include/llvm/ADT/PointerEmbeddedInt.h30
-rw-r--r--contrib/llvm/include/llvm/ADT/PointerUnion.h12
-rw-r--r--contrib/llvm/include/llvm/ADT/PostOrderIterator.h39
-rw-r--r--contrib/llvm/include/llvm/ADT/PriorityWorklist.h13
-rw-r--r--contrib/llvm/include/llvm/ADT/SCCIterator.h20
-rw-r--r--contrib/llvm/include/llvm/ADT/STLExtras.h254
-rw-r--r--contrib/llvm/include/llvm/ADT/ScopedHashTable.h16
-rw-r--r--contrib/llvm/include/llvm/ADT/Sequence.h21
-rw-r--r--contrib/llvm/include/llvm/ADT/SetVector.h30
-rw-r--r--contrib/llvm/include/llvm/ADT/SmallBitVector.h133
-rw-r--r--contrib/llvm/include/llvm/ADT/SmallPtrSet.h92
-rw-r--r--contrib/llvm/include/llvm/ADT/SmallSet.h7
-rw-r--r--contrib/llvm/include/llvm/ADT/SmallVector.h72
-rw-r--r--contrib/llvm/include/llvm/ADT/SparseBitVector.h39
-rw-r--r--contrib/llvm/include/llvm/ADT/SparseMultiSet.h41
-rw-r--r--contrib/llvm/include/llvm/ADT/SparseSet.h22
-rw-r--r--contrib/llvm/include/llvm/ADT/Statistic.h12
-rw-r--r--contrib/llvm/include/llvm/ADT/StringExtras.h106
-rw-r--r--contrib/llvm/include/llvm/ADT/StringMap.h192
-rw-r--r--contrib/llvm/include/llvm/ADT/StringRef.h30
-rw-r--r--contrib/llvm/include/llvm/ADT/StringSet.h17
-rw-r--r--contrib/llvm/include/llvm/ADT/TinyPtrVector.h14
-rw-r--r--contrib/llvm/include/llvm/ADT/Triple.h42
-rw-r--r--contrib/llvm/include/llvm/ADT/UniqueVector.h15
-rw-r--r--contrib/llvm/include/llvm/ADT/ilist_base.h6
-rw-r--r--contrib/llvm/include/llvm/ADT/ilist_iterator.h59
-rw-r--r--contrib/llvm/include/llvm/ADT/ilist_node.h50
-rw-r--r--contrib/llvm/include/llvm/ADT/iterator.h42
-rw-r--r--contrib/llvm/include/llvm/ADT/iterator_range.h2
-rw-r--r--contrib/llvm/include/llvm/ADT/simple_ilist.h33
-rw-r--r--contrib/llvm/include/llvm/Analysis/AliasAnalysis.h18
-rw-r--r--contrib/llvm/include/llvm/Analysis/AliasSetTracker.h20
-rw-r--r--contrib/llvm/include/llvm/Analysis/AssumptionCache.h37
-rw-r--r--contrib/llvm/include/llvm/Analysis/BasicAliasAnalysis.h18
-rw-r--r--contrib/llvm/include/llvm/Analysis/BlockFrequencyInfo.h10
-rw-r--r--contrib/llvm/include/llvm/Analysis/BlockFrequencyInfoImpl.h21
-rw-r--r--contrib/llvm/include/llvm/Analysis/BranchProbabilityInfo.h13
-rw-r--r--contrib/llvm/include/llvm/Analysis/CFGPrinter.h3
-rw-r--r--contrib/llvm/include/llvm/Analysis/CFLAliasAnalysisUtils.h58
-rw-r--r--contrib/llvm/include/llvm/Analysis/CFLAndersAliasAnalysis.h27
-rw-r--r--contrib/llvm/include/llvm/Analysis/CFLSteensAliasAnalysis.h24
-rw-r--r--contrib/llvm/include/llvm/Analysis/CGSCCPassManager.h26
-rw-r--r--contrib/llvm/include/llvm/Analysis/CallGraph.h14
-rw-r--r--contrib/llvm/include/llvm/Analysis/ConstantFolding.h12
-rw-r--r--contrib/llvm/include/llvm/Analysis/DemandedBits.h6
-rw-r--r--contrib/llvm/include/llvm/Analysis/DominanceFrontier.h55
-rw-r--r--contrib/llvm/include/llvm/Analysis/DominanceFrontierImpl.h44
-rw-r--r--contrib/llvm/include/llvm/Analysis/IVUsers.h2
-rw-r--r--contrib/llvm/include/llvm/Analysis/IndirectCallSiteVisitor.h12
-rw-r--r--contrib/llvm/include/llvm/Analysis/InlineCost.h12
-rw-r--r--contrib/llvm/include/llvm/Analysis/InstructionSimplify.h485
-rw-r--r--contrib/llvm/include/llvm/Analysis/IteratedDominanceFrontier.h21
-rw-r--r--contrib/llvm/include/llvm/Analysis/LazyBlockFrequencyInfo.h104
-rw-r--r--contrib/llvm/include/llvm/Analysis/LazyBranchProbabilityInfo.h21
-rw-r--r--contrib/llvm/include/llvm/Analysis/LazyCallGraph.h537
-rw-r--r--contrib/llvm/include/llvm/Analysis/LazyValueInfo.h25
-rw-r--r--contrib/llvm/include/llvm/Analysis/Loads.h40
-rw-r--r--contrib/llvm/include/llvm/Analysis/LoopAccessAnalysis.h37
-rw-r--r--contrib/llvm/include/llvm/Analysis/LoopInfo.h62
-rw-r--r--contrib/llvm/include/llvm/Analysis/LoopInfoImpl.h267
-rw-r--r--contrib/llvm/include/llvm/Analysis/LoopPass.h5
-rw-r--r--contrib/llvm/include/llvm/Analysis/MemoryBuiltins.h53
-rw-r--r--contrib/llvm/include/llvm/Analysis/MemoryDependenceAnalysis.h2
-rw-r--r--contrib/llvm/include/llvm/Analysis/MemorySSA.h (renamed from contrib/llvm/include/llvm/Transforms/Utils/MemorySSA.h)590
-rw-r--r--contrib/llvm/include/llvm/Analysis/MemorySSAUpdater.h153
-rw-r--r--contrib/llvm/include/llvm/Analysis/ObjCARCAnalysisUtils.h2
-rw-r--r--contrib/llvm/include/llvm/Analysis/ObjCARCInstKind.h2
-rw-r--r--contrib/llvm/include/llvm/Analysis/ObjectUtils.h42
-rw-r--r--contrib/llvm/include/llvm/Analysis/OptimizationDiagnosticInfo.h156
-rw-r--r--contrib/llvm/include/llvm/Analysis/OrderedBasicBlock.h1
-rw-r--r--contrib/llvm/include/llvm/Analysis/PostDominators.h8
-rw-r--r--contrib/llvm/include/llvm/Analysis/ProfileSummaryInfo.h43
-rw-r--r--contrib/llvm/include/llvm/Analysis/PtrUseVisitor.h5
-rw-r--r--contrib/llvm/include/llvm/Analysis/RegionInfo.h235
-rw-r--r--contrib/llvm/include/llvm/Analysis/RegionInfoImpl.h47
-rw-r--r--contrib/llvm/include/llvm/Analysis/RegionIterator.h77
-rw-r--r--contrib/llvm/include/llvm/Analysis/RegionPass.h5
-rw-r--r--contrib/llvm/include/llvm/Analysis/ScalarEvolution.h296
-rw-r--r--contrib/llvm/include/llvm/Analysis/ScalarEvolutionExpander.h2
-rw-r--r--contrib/llvm/include/llvm/Analysis/ScalarEvolutionExpressions.h94
-rw-r--r--contrib/llvm/include/llvm/Analysis/ScalarEvolutionNormalization.h45
-rw-r--r--contrib/llvm/include/llvm/Analysis/TargetLibraryInfo.def132
-rw-r--r--contrib/llvm/include/llvm/Analysis/TargetLibraryInfo.h99
-rw-r--r--contrib/llvm/include/llvm/Analysis/TargetTransformInfo.h351
-rw-r--r--contrib/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h108
-rw-r--r--contrib/llvm/include/llvm/Analysis/TypeMetadataUtils.h12
-rw-r--r--contrib/llvm/include/llvm/Analysis/ValueTracking.h101
-rw-r--r--contrib/llvm/include/llvm/Analysis/VectorUtils.h59
-rw-r--r--contrib/llvm/include/llvm/BinaryFormat/COFF.h719
-rw-r--r--contrib/llvm/include/llvm/BinaryFormat/Dwarf.def838
-rw-r--r--contrib/llvm/include/llvm/BinaryFormat/Dwarf.h (renamed from contrib/llvm/include/llvm/Support/Dwarf.h)132
-rw-r--r--contrib/llvm/include/llvm/BinaryFormat/ELF.h (renamed from contrib/llvm/include/llvm/Support/ELF.h)95
-rw-r--r--contrib/llvm/include/llvm/BinaryFormat/ELFRelocs/AArch64.def (renamed from contrib/llvm/include/llvm/Support/ELFRelocs/AArch64.def)37
-rw-r--r--contrib/llvm/include/llvm/BinaryFormat/ELFRelocs/AMDGPU.def (renamed from contrib/llvm/include/llvm/Support/ELFRelocs/AMDGPU.def)0
-rw-r--r--contrib/llvm/include/llvm/BinaryFormat/ELFRelocs/ARM.def (renamed from contrib/llvm/include/llvm/Support/ELFRelocs/ARM.def)0
-rw-r--r--contrib/llvm/include/llvm/BinaryFormat/ELFRelocs/AVR.def (renamed from contrib/llvm/include/llvm/Support/ELFRelocs/AVR.def)0
-rw-r--r--contrib/llvm/include/llvm/BinaryFormat/ELFRelocs/BPF.def (renamed from contrib/llvm/include/llvm/Support/ELFRelocs/BPF.def)0
-rw-r--r--contrib/llvm/include/llvm/BinaryFormat/ELFRelocs/Hexagon.def (renamed from contrib/llvm/include/llvm/Support/ELFRelocs/Hexagon.def)5
-rw-r--r--contrib/llvm/include/llvm/BinaryFormat/ELFRelocs/Lanai.def (renamed from contrib/llvm/include/llvm/Support/ELFRelocs/Lanai.def)0
-rw-r--r--contrib/llvm/include/llvm/BinaryFormat/ELFRelocs/Mips.def (renamed from contrib/llvm/include/llvm/Support/ELFRelocs/Mips.def)0
-rw-r--r--contrib/llvm/include/llvm/BinaryFormat/ELFRelocs/PowerPC.def (renamed from contrib/llvm/include/llvm/Support/ELFRelocs/PowerPC.def)0
-rw-r--r--contrib/llvm/include/llvm/BinaryFormat/ELFRelocs/PowerPC64.def (renamed from contrib/llvm/include/llvm/Support/ELFRelocs/PowerPC64.def)0
-rw-r--r--contrib/llvm/include/llvm/BinaryFormat/ELFRelocs/RISCV.def (renamed from contrib/llvm/include/llvm/Support/ELFRelocs/RISCV.def)0
-rw-r--r--contrib/llvm/include/llvm/BinaryFormat/ELFRelocs/Sparc.def (renamed from contrib/llvm/include/llvm/Support/ELFRelocs/Sparc.def)0
-rw-r--r--contrib/llvm/include/llvm/BinaryFormat/ELFRelocs/SystemZ.def (renamed from contrib/llvm/include/llvm/Support/ELFRelocs/SystemZ.def)0
-rw-r--r--contrib/llvm/include/llvm/BinaryFormat/ELFRelocs/WebAssembly.def (renamed from contrib/llvm/include/llvm/Support/ELFRelocs/WebAssembly.def)0
-rw-r--r--contrib/llvm/include/llvm/BinaryFormat/ELFRelocs/i386.def (renamed from contrib/llvm/include/llvm/Support/ELFRelocs/i386.def)0
-rw-r--r--contrib/llvm/include/llvm/BinaryFormat/ELFRelocs/x86_64.def (renamed from contrib/llvm/include/llvm/Support/ELFRelocs/x86_64.def)0
-rw-r--r--contrib/llvm/include/llvm/BinaryFormat/MachO.def (renamed from contrib/llvm/include/llvm/Support/MachO.def)4
-rw-r--r--contrib/llvm/include/llvm/BinaryFormat/MachO.h1985
-rw-r--r--contrib/llvm/include/llvm/BinaryFormat/Magic.h73
-rw-r--r--contrib/llvm/include/llvm/BinaryFormat/Wasm.h217
-rw-r--r--contrib/llvm/include/llvm/BinaryFormat/WasmRelocs/WebAssembly.def13
-rw-r--r--contrib/llvm/include/llvm/Bitcode/BitcodeReader.h55
-rw-r--r--contrib/llvm/include/llvm/Bitcode/BitcodeWriter.h53
-rw-r--r--contrib/llvm/include/llvm/Bitcode/LLVMBitCodes.h70
-rw-r--r--contrib/llvm/include/llvm/CodeGen/Analysis.h7
-rw-r--r--contrib/llvm/include/llvm/CodeGen/AsmPrinter.h92
-rw-r--r--contrib/llvm/include/llvm/CodeGen/AtomicExpandUtils.h26
-rw-r--r--contrib/llvm/include/llvm/CodeGen/BasicTTIImpl.h328
-rw-r--r--contrib/llvm/include/llvm/CodeGen/CallingConvLower.h10
-rw-r--r--contrib/llvm/include/llvm/CodeGen/CommandFlags.h49
-rw-r--r--contrib/llvm/include/llvm/CodeGen/DFAPacketizer.h37
-rw-r--r--contrib/llvm/include/llvm/CodeGen/DIE.h111
-rw-r--r--contrib/llvm/include/llvm/CodeGen/ExecutionDepsFix.h230
-rw-r--r--contrib/llvm/include/llvm/CodeGen/ExpandReductions.h24
-rw-r--r--contrib/llvm/include/llvm/CodeGen/FastISel.h119
-rw-r--r--contrib/llvm/include/llvm/CodeGen/FaultMaps.h78
-rw-r--r--contrib/llvm/include/llvm/CodeGen/FunctionLoweringInfo.h55
-rw-r--r--contrib/llvm/include/llvm/CodeGen/GCMetadata.h38
-rw-r--r--contrib/llvm/include/llvm/CodeGen/GCMetadataPrinter.h25
-rw-r--r--contrib/llvm/include/llvm/CodeGen/GCStrategy.h48
-rw-r--r--contrib/llvm/include/llvm/CodeGen/GlobalISel/CallLowering.h83
-rw-r--r--contrib/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h124
-rw-r--r--contrib/llvm/include/llvm/CodeGen/GlobalISel/InstructionSelector.h221
-rw-r--r--contrib/llvm/include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h337
-rw-r--r--contrib/llvm/include/llvm/CodeGen/GlobalISel/Legalizer.h3
-rw-r--r--contrib/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h22
-rw-r--r--contrib/llvm/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h78
-rw-r--r--contrib/llvm/include/llvm/CodeGen/GlobalISel/Localizer.h78
-rw-r--r--contrib/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h262
-rw-r--r--contrib/llvm/include/llvm/CodeGen/GlobalISel/RegBankSelect.h66
-rw-r--r--contrib/llvm/include/llvm/CodeGen/GlobalISel/RegisterBank.h2
-rw-r--r--contrib/llvm/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h112
-rw-r--r--contrib/llvm/include/llvm/CodeGen/GlobalISel/Types.h12
-rw-r--r--contrib/llvm/include/llvm/CodeGen/GlobalISel/Utils.h42
-rw-r--r--contrib/llvm/include/llvm/CodeGen/ISDOpcodes.h79
-rw-r--r--contrib/llvm/include/llvm/CodeGen/LazyMachineBlockFrequencyInfo.h76
-rw-r--r--contrib/llvm/include/llvm/CodeGen/LexicalScopes.h43
-rw-r--r--contrib/llvm/include/llvm/CodeGen/LiveInterval.h114
-rw-r--r--contrib/llvm/include/llvm/CodeGen/LiveIntervalAnalysis.h183
-rw-r--r--contrib/llvm/include/llvm/CodeGen/LiveIntervalUnion.h129
-rw-r--r--contrib/llvm/include/llvm/CodeGen/LivePhysRegs.h116
-rw-r--r--contrib/llvm/include/llvm/CodeGen/LiveRangeEdit.h80
-rw-r--r--contrib/llvm/include/llvm/CodeGen/LiveRegMatrix.h21
-rw-r--r--contrib/llvm/include/llvm/CodeGen/LiveRegUnits.h130
-rw-r--r--contrib/llvm/include/llvm/CodeGen/LiveStackAnalysis.h23
-rw-r--r--contrib/llvm/include/llvm/CodeGen/LowLevelType.h190
-rw-r--r--contrib/llvm/include/llvm/CodeGen/MIRParser/MIRParser.h20
-rw-r--r--contrib/llvm/include/llvm/CodeGen/MIRPrinter.h46
-rw-r--r--contrib/llvm/include/llvm/CodeGen/MIRYamlMapping.h144
-rw-r--r--contrib/llvm/include/llvm/CodeGen/MachineBasicBlock.h152
-rw-r--r--contrib/llvm/include/llvm/CodeGen/MachineBlockFrequencyInfo.h25
-rw-r--r--contrib/llvm/include/llvm/CodeGen/MachineCombinerPattern.h2
-rw-r--r--contrib/llvm/include/llvm/CodeGen/MachineConstantPool.h17
-rw-r--r--contrib/llvm/include/llvm/CodeGen/MachineDominanceFrontier.h38
-rw-r--r--contrib/llvm/include/llvm/CodeGen/MachineDominators.h49
-rw-r--r--contrib/llvm/include/llvm/CodeGen/MachineFrameInfo.h37
-rw-r--r--contrib/llvm/include/llvm/CodeGen/MachineFunction.h131
-rw-r--r--contrib/llvm/include/llvm/CodeGen/MachineFunctionInitializer.h38
-rw-r--r--contrib/llvm/include/llvm/CodeGen/MachineFunctionPass.h2
-rw-r--r--contrib/llvm/include/llvm/CodeGen/MachineInstr.h142
-rw-r--r--contrib/llvm/include/llvm/CodeGen/MachineInstrBuilder.h40
-rw-r--r--contrib/llvm/include/llvm/CodeGen/MachineInstrBundleIterator.h72
-rw-r--r--contrib/llvm/include/llvm/CodeGen/MachineLoopInfo.h31
-rw-r--r--contrib/llvm/include/llvm/CodeGen/MachineMemOperand.h22
-rw-r--r--contrib/llvm/include/llvm/CodeGen/MachineModuleInfo.h53
-rw-r--r--contrib/llvm/include/llvm/CodeGen/MachineModuleInfoImpls.h2
-rw-r--r--contrib/llvm/include/llvm/CodeGen/MachineOperand.h26
-rw-r--r--contrib/llvm/include/llvm/CodeGen/MachineOptimizationRemarkEmitter.h203
-rw-r--r--contrib/llvm/include/llvm/CodeGen/MachinePassRegistry.h37
-rw-r--r--contrib/llvm/include/llvm/CodeGen/MachinePostDominators.h2
-rw-r--r--contrib/llvm/include/llvm/CodeGen/MachineRegionInfo.h130
-rw-r--r--contrib/llvm/include/llvm/CodeGen/MachineRegisterInfo.h191
-rw-r--r--contrib/llvm/include/llvm/CodeGen/MachineScheduler.h121
-rw-r--r--contrib/llvm/include/llvm/CodeGen/MachineTraceMetrics.h66
-rw-r--r--contrib/llvm/include/llvm/CodeGen/MachineValueType.h669
-rw-r--r--contrib/llvm/include/llvm/CodeGen/MacroFusion.h50
-rw-r--r--contrib/llvm/include/llvm/CodeGen/PBQP/CostAllocator.h61
-rw-r--r--contrib/llvm/include/llvm/CodeGen/PBQP/Graph.h99
-rw-r--r--contrib/llvm/include/llvm/CodeGen/PBQP/Math.h22
-rw-r--r--contrib/llvm/include/llvm/CodeGen/PBQP/ReductionRules.h36
-rw-r--r--contrib/llvm/include/llvm/CodeGen/PBQP/Solution.h23
-rw-r--r--contrib/llvm/include/llvm/CodeGen/PBQPRAConstraint.h22
-rw-r--r--contrib/llvm/include/llvm/CodeGen/Passes.h88
-rw-r--r--contrib/llvm/include/llvm/CodeGen/PseudoSourceValue.h6
-rw-r--r--contrib/llvm/include/llvm/CodeGen/RegAllocPBQP.h123
-rw-r--r--contrib/llvm/include/llvm/CodeGen/RegAllocRegistry.h17
-rw-r--r--contrib/llvm/include/llvm/CodeGen/RegisterClassInfo.h43
-rw-r--r--contrib/llvm/include/llvm/CodeGen/RegisterPressure.h82
-rw-r--r--contrib/llvm/include/llvm/CodeGen/RegisterScavenging.h64
-rw-r--r--contrib/llvm/include/llvm/CodeGen/RegisterUsageInfo.h17
-rw-r--r--contrib/llvm/include/llvm/CodeGen/RuntimeLibcalls.h42
-rw-r--r--contrib/llvm/include/llvm/CodeGen/ScheduleDAG.h523
-rw-r--r--contrib/llvm/include/llvm/CodeGen/ScheduleDAGInstrs.h206
-rw-r--r--contrib/llvm/include/llvm/CodeGen/ScheduleDAGMutation.h25
-rw-r--r--contrib/llvm/include/llvm/CodeGen/ScheduleDFS.h26
-rw-r--r--contrib/llvm/include/llvm/CodeGen/ScheduleHazardRecognizer.h8
-rw-r--r--contrib/llvm/include/llvm/CodeGen/SchedulerRegistry.h17
-rw-r--r--contrib/llvm/include/llvm/CodeGen/ScoreboardHazardRecognizer.h22
-rw-r--r--contrib/llvm/include/llvm/CodeGen/SelectionDAG.h260
-rw-r--r--contrib/llvm/include/llvm/CodeGen/SelectionDAGAddressAnalysis.h64
-rw-r--r--contrib/llvm/include/llvm/CodeGen/SelectionDAGISel.h23
-rw-r--r--contrib/llvm/include/llvm/CodeGen/SelectionDAGNodes.h388
-rw-r--r--contrib/llvm/include/llvm/CodeGen/SlotIndexes.h48
-rw-r--r--contrib/llvm/include/llvm/CodeGen/StackMaps.h82
-rw-r--r--contrib/llvm/include/llvm/CodeGen/StackProtector.h37
-rw-r--r--contrib/llvm/include/llvm/CodeGen/TailDuplicator.h37
-rw-r--r--contrib/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h75
-rw-r--r--contrib/llvm/include/llvm/CodeGen/TargetPassConfig.h68
-rw-r--r--contrib/llvm/include/llvm/CodeGen/TargetSchedule.h34
-rw-r--r--contrib/llvm/include/llvm/CodeGen/ValueTypes.h221
-rw-r--r--contrib/llvm/include/llvm/CodeGen/ValueTypes.td218
-rw-r--r--contrib/llvm/include/llvm/CodeGen/VirtRegMap.h9
-rw-r--r--contrib/llvm/include/llvm/CodeGen/WinEHFuncInfo.h36
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/CVRecord.h31
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/CVSymbolVisitor.h2
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/CVTypeDumper.h56
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h42
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/CodeView.h88
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/CodeViewError.h1
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/CodeViewRecordIO.h15
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/CodeViewSymbols.def (renamed from contrib/llvm/include/llvm/DebugInfo/CodeView/CVSymbolTypes.def)0
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/CodeViewTypes.def (renamed from contrib/llvm/include/llvm/DebugInfo/CodeView/TypeRecords.def)6
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h104
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/DebugCrossExSubsection.h68
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/DebugCrossImpSubsection.h95
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/DebugFrameDataSubsection.h60
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h121
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/DebugLinesSubsection.h150
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/DebugStringTableSubsection.h89
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/DebugSubsection.h52
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/DebugSubsectionRecord.h103
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/DebugSubsectionVisitor.h114
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/DebugSymbolRVASubsection.h67
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/DebugSymbolsSubsection.h56
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/DebugUnknownSubsection.h32
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/EnumTables.h14
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/Formatters.h73
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/GUID.h55
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h113
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/Line.h21
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/ModuleSubstream.h89
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/ModuleSubstreamVisitor.h136
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/RecordSerialization.h44
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/StringsAndChecksums.h102
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolDeserializer.h40
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolDumper.h11
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolRecord.h41
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolRecordMapping.h17
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolSerializer.h81
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolVisitorCallbackPipeline.h10
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h8
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h10
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/TypeCollection.h38
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/TypeDatabase.h55
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/TypeDatabaseVisitor.h53
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/TypeDeserializer.h37
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/TypeDumpVisitor.h29
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/TypeDumperBase.h0
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/TypeIndex.h98
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/TypeIndexDiscovery.h41
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/TypeName.h22
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/TypeRecord.h239
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/TypeRecordMapping.h14
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/TypeSerializer.h71
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/TypeStreamMerger.h69
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/TypeTableBuilder.h32
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/TypeTableCollection.h43
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h10
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h17
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/DIContext.h76
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h58
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h49
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFAttribute.h56
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFCompileUnit.h23
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h158
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFDataExtractor.h48
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h22
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h35
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugAranges.h26
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h14
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h41
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h247
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h27
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugMacro.h5
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugPubTable.h20
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h68
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFDie.h218
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFFormValue.h313
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFGdbIndex.h36
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFRelocMap.h24
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFSection.h12
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h28
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h191
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFUnitIndex.h25
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFVerifier.h144
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/MSF/ByteStream.h169
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/MSF/MSFBuilder.h13
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/MSF/MSFCommon.h18
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/MSF/MappedBlockStream.h109
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/MSF/SequencedItemStream.h93
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/MSF/StreamInterface.h53
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/MSF/StreamReader.h121
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/MSF/StreamRef.h135
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/MSF/StreamWriter.h92
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/ConcreteSymbolEnumerator.h10
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/DIA/DIAEnumDebugStreams.h1
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/DIA/DIAEnumLineNumbers.h1
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/DIA/DIAEnumSourceFiles.h1
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/DIA/DIAEnumSymbols.h1
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/DIA/DIARawSymbol.h4
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/DIA/DIASession.h2
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/GenericError.h1
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/IPDBDataStream.h16
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/IPDBEnumChildren.h4
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/IPDBRawSymbol.h7
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/IPDBSession.h13
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h (renamed from contrib/llvm/include/llvm/DebugInfo/PDB/Raw/ModInfo.h)46
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h105
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/Native/DbiModuleList.h118
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/Native/DbiStream.h (renamed from contrib/llvm/include/llvm/DebugInfo/PDB/Raw/DbiStream.h)69
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h (renamed from contrib/llvm/include/llvm/DebugInfo/PDB/Raw/DbiStreamBuilder.h)54
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/Native/EnumTables.h (renamed from contrib/llvm/include/llvm/DebugInfo/PDB/Raw/EnumTables.h)0
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/Native/Formatters.h45
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/Native/GlobalsStream.h (renamed from contrib/llvm/include/llvm/DebugInfo/PDB/Raw/GlobalsStream.h)12
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/Native/Hash.h (renamed from contrib/llvm/include/llvm/DebugInfo/PDB/Raw/Hash.h)14
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/Native/HashTable.h109
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/Native/ISectionContribVisitor.h (renamed from contrib/llvm/include/llvm/DebugInfo/PDB/Raw/ISectionContribVisitor.h)0
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/Native/InfoStream.h (renamed from contrib/llvm/include/llvm/DebugInfo/PDB/Raw/InfoStream.h)30
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/Native/InfoStreamBuilder.h (renamed from contrib/llvm/include/llvm/DebugInfo/PDB/Raw/InfoStreamBuilder.h)26
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/Native/ModuleDebugStream.h82
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/Native/NamedStreamMap.h60
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/Native/NativeBuiltinSymbol.h49
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/Native/NativeCompilandSymbol.h39
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/Native/NativeEnumModules.h41
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/Native/NativeExeSymbol.h41
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/Native/NativeRawSymbol.h216
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/Native/NativeSession.h (renamed from contrib/llvm/include/llvm/DebugInfo/PDB/Raw/RawSession.h)29
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/Native/PDBFile.h (renamed from contrib/llvm/include/llvm/DebugInfo/PDB/Raw/PDBFile.h)37
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/Native/PDBFileBuilder.h (renamed from contrib/llvm/include/llvm/DebugInfo/PDB/Raw/PDBFileBuilder.h)19
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/Native/PDBStringTable.h65
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/Native/PDBStringTableBuilder.h59
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/Native/PublicsStream.h (renamed from contrib/llvm/include/llvm/DebugInfo/PDB/Raw/PublicsStream.h)30
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/Native/PublicsStreamBuilder.h54
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/Native/RawConstants.h (renamed from contrib/llvm/include/llvm/DebugInfo/PDB/Raw/RawConstants.h)23
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/Native/RawError.h (renamed from contrib/llvm/include/llvm/DebugInfo/PDB/Raw/RawError.h)1
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/Native/RawTypes.h (renamed from contrib/llvm/include/llvm/DebugInfo/PDB/Raw/RawTypes.h)52
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/Native/SymbolStream.h (renamed from contrib/llvm/include/llvm/DebugInfo/PDB/Raw/SymbolStream.h)4
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/Native/TpiHashing.h24
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/Native/TpiStream.h (renamed from contrib/llvm/include/llvm/DebugInfo/PDB/Raw/TpiStream.h)47
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/Native/TpiStreamBuilder.h (renamed from contrib/llvm/include/llvm/DebugInfo/PDB/Raw/TpiStreamBuilder.h)48
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/PDB.h16
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/PDBContext.h3
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/PDBExtras.h19
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymDumper.h16
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbol.h41
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolBlock.h2
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolCompiland.h2
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolCompilandDetails.h2
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolCompilandEnv.h2
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolData.h8
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolExe.h2
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolFunc.h12
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolFuncDebugEnd.h2
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolFuncDebugStart.h2
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolLabel.h2
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolPublicSymbol.h2
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolThunk.h6
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolTypeArray.h9
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h11
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h2
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h12
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolTypeFriend.h4
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolTypeFunctionArg.h6
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h11
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolTypePointer.h7
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h8
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h16
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolTypeVTable.h7
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolTypeVTableShape.h2
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolUsingNamespace.h2
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/PDBTypes.h51
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/Raw/ModStream.h62
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/Raw/NameHashTable.h54
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/Raw/NameMap.h44
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/Raw/NameMapBuilder.h45
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/Raw/TpiHashing.h95
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/UDTLayout.h182
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/Symbolize/DIPrinter.h7
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/Symbolize/SymbolizableModule.h16
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h26
-rw-r--r--contrib/llvm/include/llvm/ExecutionEngine/ExecutionEngine.h43
-rw-r--r--contrib/llvm/include/llvm/ExecutionEngine/GenericValue.h33
-rw-r--r--contrib/llvm/include/llvm/ExecutionEngine/JITEventListener.h8
-rw-r--r--contrib/llvm/include/llvm/ExecutionEngine/JITSymbol.h102
-rw-r--r--contrib/llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h262
-rw-r--r--contrib/llvm/include/llvm/ExecutionEngine/Orc/CompileUtils.h71
-rw-r--r--contrib/llvm/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h53
-rw-r--r--contrib/llvm/include/llvm/ExecutionEngine/Orc/GlobalMappingLayer.h43
-rw-r--r--contrib/llvm/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h131
-rw-r--r--contrib/llvm/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h63
-rw-r--r--contrib/llvm/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h26
-rw-r--r--contrib/llvm/include/llvm/ExecutionEngine/Orc/LambdaResolver.h13
-rw-r--r--contrib/llvm/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h159
-rw-r--r--contrib/llvm/include/llvm/ExecutionEngine/Orc/ObjectTransformLayer.h35
-rw-r--r--contrib/llvm/include/llvm/ExecutionEngine/Orc/OrcABISupport.h47
-rw-r--r--contrib/llvm/include/llvm/ExecutionEngine/Orc/OrcError.h21
-rw-r--r--contrib/llvm/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h61
-rw-r--r--contrib/llvm/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.h15
-rw-r--r--contrib/llvm/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h61
-rw-r--r--contrib/llvm/include/llvm/ExecutionEngine/Orc/RPCSerialization.h254
-rw-r--r--contrib/llvm/include/llvm/ExecutionEngine/Orc/RPCUtils.h787
-rw-r--r--contrib/llvm/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h (renamed from contrib/llvm/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h)229
-rw-r--r--contrib/llvm/include/llvm/ExecutionEngine/Orc/RawByteChannel.h44
-rw-r--r--contrib/llvm/include/llvm/ExecutionEngine/RTDyldMemoryManager.h19
-rw-r--r--contrib/llvm/include/llvm/ExecutionEngine/RuntimeDyld.h30
-rw-r--r--contrib/llvm/include/llvm/ExecutionEngine/RuntimeDyldChecker.h6
-rw-r--r--contrib/llvm/include/llvm/IR/Argument.h106
-rw-r--r--contrib/llvm/include/llvm/IR/Attributes.h527
-rw-r--r--contrib/llvm/include/llvm/IR/Attributes.td5
-rw-r--r--contrib/llvm/include/llvm/IR/BasicBlock.h166
-rw-r--r--contrib/llvm/include/llvm/IR/CFG.h54
-rw-r--r--contrib/llvm/include/llvm/IR/CallSite.h214
-rw-r--r--contrib/llvm/include/llvm/IR/CallingConv.h34
-rw-r--r--contrib/llvm/include/llvm/IR/Comdat.h6
-rw-r--r--contrib/llvm/include/llvm/IR/Constant.h11
-rw-r--r--contrib/llvm/include/llvm/IR/ConstantRange.h55
-rw-r--r--contrib/llvm/include/llvm/IR/Constants.h63
-rw-r--r--contrib/llvm/include/llvm/IR/DIBuilder.h101
-rw-r--r--contrib/llvm/include/llvm/IR/DataLayout.h87
-rw-r--r--contrib/llvm/include/llvm/IR/DebugInfo.h25
-rw-r--r--contrib/llvm/include/llvm/IR/DebugInfoFlags.def3
-rw-r--r--contrib/llvm/include/llvm/IR/DebugInfoMetadata.h399
-rw-r--r--contrib/llvm/include/llvm/IR/DebugLoc.h10
-rw-r--r--contrib/llvm/include/llvm/IR/DerivedTypes.h58
-rw-r--r--contrib/llvm/include/llvm/IR/DerivedUser.h45
-rw-r--r--contrib/llvm/include/llvm/IR/DiagnosticInfo.h614
-rw-r--r--contrib/llvm/include/llvm/IR/Dominators.h108
-rw-r--r--contrib/llvm/include/llvm/IR/Function.h234
-rw-r--r--contrib/llvm/include/llvm/IR/GetElementPtrTypeIterator.h8
-rw-r--r--contrib/llvm/include/llvm/IR/GlobalAlias.h10
-rw-r--r--contrib/llvm/include/llvm/IR/GlobalIFunc.h10
-rw-r--r--contrib/llvm/include/llvm/IR/GlobalIndirectSymbol.h20
-rw-r--r--contrib/llvm/include/llvm/IR/GlobalObject.h19
-rw-r--r--contrib/llvm/include/llvm/IR/GlobalValue.h44
-rw-r--r--contrib/llvm/include/llvm/IR/GlobalVariable.h76
-rw-r--r--contrib/llvm/include/llvm/IR/IRBuilder.h187
-rw-r--r--contrib/llvm/include/llvm/IR/InlineAsm.h35
-rw-r--r--contrib/llvm/include/llvm/IR/InstIterator.h34
-rw-r--r--contrib/llvm/include/llvm/IR/InstVisitor.h3
-rw-r--r--contrib/llvm/include/llvm/IR/InstrTypes.h120
-rw-r--r--contrib/llvm/include/llvm/IR/Instruction.def10
-rw-r--r--contrib/llvm/include/llvm/IR/Instruction.h88
-rw-r--r--contrib/llvm/include/llvm/IR/Instructions.h1011
-rw-r--r--contrib/llvm/include/llvm/IR/IntrinsicInst.h371
-rw-r--r--contrib/llvm/include/llvm/IR/Intrinsics.h30
-rw-r--r--contrib/llvm/include/llvm/IR/Intrinsics.td274
-rw-r--r--contrib/llvm/include/llvm/IR/IntrinsicsAMDGPU.td317
-rw-r--r--contrib/llvm/include/llvm/IR/IntrinsicsARM.td188
-rw-r--r--contrib/llvm/include/llvm/IR/IntrinsicsHexagon.td896
-rw-r--r--contrib/llvm/include/llvm/IR/IntrinsicsNVVM.td84
-rw-r--r--contrib/llvm/include/llvm/IR/IntrinsicsPowerPC.td34
-rw-r--r--contrib/llvm/include/llvm/IR/IntrinsicsSystemZ.td43
-rw-r--r--contrib/llvm/include/llvm/IR/IntrinsicsWebAssembly.td6
-rw-r--r--contrib/llvm/include/llvm/IR/IntrinsicsX86.td259
-rw-r--r--contrib/llvm/include/llvm/IR/LLVMContext.h54
-rw-r--r--contrib/llvm/include/llvm/IR/LegacyPassManager.h3
-rw-r--r--contrib/llvm/include/llvm/IR/LegacyPassNameParser.h10
-rw-r--r--contrib/llvm/include/llvm/IR/MDBuilder.h9
-rw-r--r--contrib/llvm/include/llvm/IR/Mangler.h4
-rw-r--r--contrib/llvm/include/llvm/IR/Metadata.h110
-rw-r--r--contrib/llvm/include/llvm/IR/Module.h161
-rw-r--r--contrib/llvm/include/llvm/IR/ModuleSummaryIndex.h507
-rw-r--r--contrib/llvm/include/llvm/IR/ModuleSummaryIndexYAML.h169
-rw-r--r--contrib/llvm/include/llvm/IR/OperandTraits.h9
-rw-r--r--contrib/llvm/include/llvm/IR/Operator.h69
-rw-r--r--contrib/llvm/include/llvm/IR/OptBisect.h18
-rw-r--r--contrib/llvm/include/llvm/IR/PassManager.h223
-rw-r--r--contrib/llvm/include/llvm/IR/PassManagerInternal.h13
-rw-r--r--contrib/llvm/include/llvm/IR/PatternMatch.h397
-rw-r--r--contrib/llvm/include/llvm/IR/PredIteratorCache.h14
-rw-r--r--contrib/llvm/include/llvm/IR/ProfileSummary.h20
-rw-r--r--contrib/llvm/include/llvm/IR/SafepointIRVerifier.h35
-rw-r--r--contrib/llvm/include/llvm/IR/Statepoint.h51
-rw-r--r--contrib/llvm/include/llvm/IR/SymbolTableListTraits.h38
-rw-r--r--contrib/llvm/include/llvm/IR/TrackingMDRef.h33
-rw-r--r--contrib/llvm/include/llvm/IR/Type.h57
-rw-r--r--contrib/llvm/include/llvm/IR/TypeFinder.h18
-rw-r--r--contrib/llvm/include/llvm/IR/Use.h56
-rw-r--r--contrib/llvm/include/llvm/IR/UseListOrder.h9
-rw-r--r--contrib/llvm/include/llvm/IR/User.h41
-rw-r--r--contrib/llvm/include/llvm/IR/Value.def17
-rw-r--r--contrib/llvm/include/llvm/IR/Value.h115
-rw-r--r--contrib/llvm/include/llvm/IR/ValueHandle.h325
-rw-r--r--contrib/llvm/include/llvm/IR/ValueMap.h42
-rw-r--r--contrib/llvm/include/llvm/IR/ValueSymbolTable.h51
-rw-r--r--contrib/llvm/include/llvm/IR/Verifier.h15
-rw-r--r--contrib/llvm/include/llvm/InitializePasses.h139
-rw-r--r--contrib/llvm/include/llvm/LTO/Caching.h15
-rw-r--r--contrib/llvm/include/llvm/LTO/Config.h13
-rw-r--r--contrib/llvm/include/llvm/LTO/LTO.h231
-rw-r--r--contrib/llvm/include/llvm/LTO/LTOBackend.h7
-rw-r--r--contrib/llvm/include/llvm/LTO/legacy/LTOCodeGenerator.h7
-rw-r--r--contrib/llvm/include/llvm/LTO/legacy/LTOModule.h2
-rw-r--r--contrib/llvm/include/llvm/LTO/legacy/ThinLTOCodeGenerator.h19
-rw-r--r--contrib/llvm/include/llvm/LinkAllIR.h2
-rw-r--r--contrib/llvm/include/llvm/LinkAllPasses.h9
-rw-r--r--contrib/llvm/include/llvm/Linker/IRMover.h6
-rw-r--r--contrib/llvm/include/llvm/Linker/Linker.h19
-rw-r--r--contrib/llvm/include/llvm/MC/ConstantPools.h17
-rw-r--r--contrib/llvm/include/llvm/MC/LaneBitmask.h12
-rw-r--r--contrib/llvm/include/llvm/MC/MCAsmBackend.h42
-rw-r--r--contrib/llvm/include/llvm/MC/MCAsmInfo.h150
-rw-r--r--contrib/llvm/include/llvm/MC/MCAsmInfoCOFF.h42
-rw-r--r--contrib/llvm/include/llvm/MC/MCAsmInfoDarwin.h16
-rw-r--r--contrib/llvm/include/llvm/MC/MCAsmInfoELF.h10
-rw-r--r--contrib/llvm/include/llvm/MC/MCAsmInfoWasm.h24
-rw-r--r--contrib/llvm/include/llvm/MC/MCAssembler.h95
-rw-r--r--contrib/llvm/include/llvm/MC/MCCodeEmitter.h15
-rw-r--r--contrib/llvm/include/llvm/MC/MCCodeView.h4
-rw-r--r--contrib/llvm/include/llvm/MC/MCContext.h189
-rw-r--r--contrib/llvm/include/llvm/MC/MCDisassembler/MCDisassembler.h18
-rw-r--r--contrib/llvm/include/llvm/MC/MCDisassembler/MCRelocationInfo.h18
-rw-r--r--contrib/llvm/include/llvm/MC/MCDisassembler/MCSymbolizer.h16
-rw-r--r--contrib/llvm/include/llvm/MC/MCDwarf.h56
-rw-r--r--contrib/llvm/include/llvm/MC/MCELFObjectWriter.h27
-rw-r--r--contrib/llvm/include/llvm/MC/MCELFStreamer.h26
-rw-r--r--contrib/llvm/include/llvm/MC/MCExpr.h88
-rw-r--r--contrib/llvm/include/llvm/MC/MCFixup.h2
-rw-r--r--contrib/llvm/include/llvm/MC/MCFragment.h36
-rw-r--r--contrib/llvm/include/llvm/MC/MCInst.h35
-rw-r--r--contrib/llvm/include/llvm/MC/MCInstPrinter.h16
-rw-r--r--contrib/llvm/include/llvm/MC/MCInstrAnalysis.h11
-rw-r--r--contrib/llvm/include/llvm/MC/MCInstrDesc.h9
-rw-r--r--contrib/llvm/include/llvm/MC/MCInstrItineraries.h28
-rw-r--r--contrib/llvm/include/llvm/MC/MCLabel.h12
-rw-r--r--contrib/llvm/include/llvm/MC/MCLinkerOptimizationHint.h19
-rw-r--r--contrib/llvm/include/llvm/MC/MCMachObjectWriter.h22
-rw-r--r--contrib/llvm/include/llvm/MC/MCObjectFileInfo.h9
-rw-r--r--contrib/llvm/include/llvm/MC/MCObjectStreamer.h7
-rw-r--r--contrib/llvm/include/llvm/MC/MCObjectWriter.h26
-rw-r--r--contrib/llvm/include/llvm/MC/MCParser/AsmCond.h10
-rw-r--r--contrib/llvm/include/llvm/MC/MCParser/AsmLexer.h19
-rw-r--r--contrib/llvm/include/llvm/MC/MCParser/MCAsmLexer.h39
-rw-r--r--contrib/llvm/include/llvm/MC/MCParser/MCAsmParser.h45
-rw-r--r--contrib/llvm/include/llvm/MC/MCParser/MCAsmParserExtension.h26
-rw-r--r--contrib/llvm/include/llvm/MC/MCParser/MCAsmParserUtils.h5
-rw-r--r--contrib/llvm/include/llvm/MC/MCParser/MCParsedAsmOperand.h14
-rw-r--r--contrib/llvm/include/llvm/MC/MCParser/MCTargetAsmParser.h36
-rw-r--r--contrib/llvm/include/llvm/MC/MCRegisterInfo.h66
-rw-r--r--contrib/llvm/include/llvm/MC/MCSection.h43
-rw-r--r--contrib/llvm/include/llvm/MC/MCSectionCOFF.h8
-rw-r--r--contrib/llvm/include/llvm/MC/MCSectionELF.h23
-rw-r--r--contrib/llvm/include/llvm/MC/MCSectionMachO.h5
-rw-r--r--contrib/llvm/include/llvm/MC/MCSectionWasm.h88
-rw-r--r--contrib/llvm/include/llvm/MC/MCStreamer.h43
-rw-r--r--contrib/llvm/include/llvm/MC/MCSubtargetInfo.h36
-rw-r--r--contrib/llvm/include/llvm/MC/MCSymbol.h33
-rw-r--r--contrib/llvm/include/llvm/MC/MCSymbolCOFF.h13
-rw-r--r--contrib/llvm/include/llvm/MC/MCSymbolWasm.h73
-rw-r--r--contrib/llvm/include/llvm/MC/MCTargetOptions.h47
-rw-r--r--contrib/llvm/include/llvm/MC/MCValue.h2
-rw-r--r--contrib/llvm/include/llvm/MC/MCWasmObjectWriter.h52
-rw-r--r--contrib/llvm/include/llvm/MC/MCWasmStreamer.h83
-rw-r--r--contrib/llvm/include/llvm/MC/MCWinCOFFObjectWriter.h16
-rw-r--r--contrib/llvm/include/llvm/MC/MCWinCOFFStreamer.h11
-rw-r--r--contrib/llvm/include/llvm/MC/MachineLocation.h30
-rw-r--r--contrib/llvm/include/llvm/MC/StringTableBuilder.h11
-rw-r--r--contrib/llvm/include/llvm/MC/SubtargetFeature.h96
-rw-r--r--contrib/llvm/include/llvm/Object/Archive.h50
-rw-r--r--contrib/llvm/include/llvm/Object/ArchiveWriter.h1
-rw-r--r--contrib/llvm/include/llvm/Object/Binary.h44
-rw-r--r--contrib/llvm/include/llvm/Object/COFF.h264
-rw-r--r--contrib/llvm/include/llvm/Object/COFFImportFile.h44
-rw-r--r--contrib/llvm/include/llvm/Object/COFFModuleDefinition.h53
-rw-r--r--contrib/llvm/include/llvm/Object/Decompressor.h7
-rw-r--r--contrib/llvm/include/llvm/Object/ELF.h76
-rw-r--r--contrib/llvm/include/llvm/Object/ELFObjectFile.h81
-rw-r--r--contrib/llvm/include/llvm/Object/ELFTypes.h168
-rw-r--r--contrib/llvm/include/llvm/Object/IRObjectFile.h17
-rw-r--r--contrib/llvm/include/llvm/Object/IRSymtab.h349
-rw-r--r--contrib/llvm/include/llvm/Object/MachO.h318
-rw-r--r--contrib/llvm/include/llvm/Object/MachOUniversal.h4
-rw-r--r--contrib/llvm/include/llvm/Object/ModuleSummaryIndexObjectFile.h96
-rw-r--r--contrib/llvm/include/llvm/Object/ModuleSymbolTable.h17
-rw-r--r--contrib/llvm/include/llvm/Object/ObjectFile.h82
-rw-r--r--contrib/llvm/include/llvm/Object/RelocVisitor.h578
-rw-r--r--contrib/llvm/include/llvm/Object/StackMapParser.h43
-rw-r--r--contrib/llvm/include/llvm/Object/SymbolicFile.h39
-rw-r--r--contrib/llvm/include/llvm/Object/Wasm.h163
-rw-r--r--contrib/llvm/include/llvm/Object/WindowsResource.h219
-rw-r--r--contrib/llvm/include/llvm/ObjectYAML/COFFYAML.h115
-rw-r--r--contrib/llvm/include/llvm/ObjectYAML/CodeViewYAMLDebugSections.h140
-rw-r--r--contrib/llvm/include/llvm/ObjectYAML/CodeViewYAMLSymbols.h49
-rw-r--r--contrib/llvm/include/llvm/ObjectYAML/CodeViewYAMLTypes.h71
-rw-r--r--contrib/llvm/include/llvm/ObjectYAML/DWARFEmitter.h49
-rw-r--r--contrib/llvm/include/llvm/ObjectYAML/DWARFYAML.h89
-rw-r--r--contrib/llvm/include/llvm/ObjectYAML/ELFYAML.h22
-rw-r--r--contrib/llvm/include/llvm/ObjectYAML/MachOYAML.h57
-rw-r--r--contrib/llvm/include/llvm/ObjectYAML/ObjectYAML.h15
-rw-r--r--contrib/llvm/include/llvm/ObjectYAML/WasmYAML.h400
-rw-r--r--contrib/llvm/include/llvm/ObjectYAML/YAML.h30
-rw-r--r--contrib/llvm/include/llvm/Option/Arg.h15
-rw-r--r--contrib/llvm/include/llvm/Option/ArgList.h244
-rw-r--r--contrib/llvm/include/llvm/Option/OptParser.td2
-rw-r--r--contrib/llvm/include/llvm/Option/OptSpecifier.h40
-rw-r--r--contrib/llvm/include/llvm/Option/OptTable.h42
-rw-r--r--contrib/llvm/include/llvm/Option/Option.h17
-rw-r--r--contrib/llvm/include/llvm/Pass.h2
-rw-r--r--contrib/llvm/include/llvm/PassInfo.h21
-rw-r--r--contrib/llvm/include/llvm/PassSupport.h22
-rw-r--r--contrib/llvm/include/llvm/Passes/PassBuilder.h368
-rw-r--r--contrib/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h111
-rw-r--r--contrib/llvm/include/llvm/ProfileData/Coverage/CoverageMappingReader.h46
-rw-r--r--contrib/llvm/include/llvm/ProfileData/Coverage/CoverageMappingWriter.h15
-rw-r--r--contrib/llvm/include/llvm/ProfileData/InstrProf.h313
-rw-r--r--contrib/llvm/include/llvm/ProfileData/InstrProfData.inc84
-rw-r--r--contrib/llvm/include/llvm/ProfileData/InstrProfReader.h151
-rw-r--r--contrib/llvm/include/llvm/ProfileData/InstrProfWriter.h39
-rw-r--r--contrib/llvm/include/llvm/ProfileData/ProfileCommon.h53
-rw-r--r--contrib/llvm/include/llvm/ProfileData/SampleProf.h133
-rw-r--r--contrib/llvm/include/llvm/ProfileData/SampleProfReader.h37
-rw-r--r--contrib/llvm/include/llvm/ProfileData/SampleProfWriter.h31
-rw-r--r--contrib/llvm/include/llvm/Support/AArch64TargetParser.def42
-rw-r--r--contrib/llvm/include/llvm/Support/AMDGPUCodeObjectMetadata.h422
-rw-r--r--contrib/llvm/include/llvm/Support/ARMAttributeParser.h140
-rw-r--r--contrib/llvm/include/llvm/Support/ARMBuildAttributes.h14
-rw-r--r--contrib/llvm/include/llvm/Support/ARMTargetParser.def46
-rw-r--r--contrib/llvm/include/llvm/Support/Allocator.h50
-rw-r--r--contrib/llvm/include/llvm/Support/ArrayRecycler.h3
-rw-r--r--contrib/llvm/include/llvm/Support/Atomic.h5
-rw-r--r--contrib/llvm/include/llvm/Support/BinaryByteStream.h192
-rw-r--r--contrib/llvm/include/llvm/Support/BinaryItemStream.h108
-rw-r--r--contrib/llvm/include/llvm/Support/BinaryStream.h78
-rw-r--r--contrib/llvm/include/llvm/Support/BinaryStreamArray.h (renamed from contrib/llvm/include/llvm/DebugInfo/MSF/StreamArray.h)142
-rw-r--r--contrib/llvm/include/llvm/Support/BinaryStreamError.h48
-rw-r--r--contrib/llvm/include/llvm/Support/BinaryStreamReader.h270
-rw-r--r--contrib/llvm/include/llvm/Support/BinaryStreamRef.h229
-rw-r--r--contrib/llvm/include/llvm/Support/BinaryStreamWriter.h183
-rw-r--r--contrib/llvm/include/llvm/Support/BlockFrequency.h4
-rw-r--r--contrib/llvm/include/llvm/Support/BranchProbability.h12
-rw-r--r--contrib/llvm/include/llvm/Support/CBindingWrapping.h2
-rw-r--r--contrib/llvm/include/llvm/Support/COFF.h680
-rw-r--r--contrib/llvm/include/llvm/Support/CachePruning.h76
-rw-r--r--contrib/llvm/include/llvm/Support/Casting.h109
-rw-r--r--contrib/llvm/include/llvm/Support/Chrono.h95
-rw-r--r--contrib/llvm/include/llvm/Support/CommandLine.h78
-rw-r--r--contrib/llvm/include/llvm/Support/Compiler.h25
-rw-r--r--contrib/llvm/include/llvm/Support/Compression.h24
-rw-r--r--contrib/llvm/include/llvm/Support/ConvertUTF.h2
-rw-r--r--contrib/llvm/include/llvm/Support/DataExtractor.h63
-rw-r--r--contrib/llvm/include/llvm/Support/Debug.h28
-rw-r--r--contrib/llvm/include/llvm/Support/DebugCounter.h165
-rw-r--r--contrib/llvm/include/llvm/Support/Dwarf.def811
-rw-r--r--contrib/llvm/include/llvm/Support/DynamicLibrary.h30
-rw-r--r--contrib/llvm/include/llvm/Support/Endian.h253
-rw-r--r--contrib/llvm/include/llvm/Support/Errno.h12
-rw-r--r--contrib/llvm/include/llvm/Support/Error.h148
-rw-r--r--contrib/llvm/include/llvm/Support/ErrorHandling.h48
-rw-r--r--contrib/llvm/include/llvm/Support/ErrorOr.h18
-rw-r--r--contrib/llvm/include/llvm/Support/FileSystem.h329
-rw-r--r--contrib/llvm/include/llvm/Support/Format.h25
-rw-r--r--contrib/llvm/include/llvm/Support/FormatAdapters.h16
-rw-r--r--contrib/llvm/include/llvm/Support/FormatCommon.h20
-rw-r--r--contrib/llvm/include/llvm/Support/FormatProviders.h22
-rw-r--r--contrib/llvm/include/llvm/Support/FormatVariadic.h4
-rw-r--r--contrib/llvm/include/llvm/Support/GCOV.h89
-rw-r--r--contrib/llvm/include/llvm/Support/GenericDomTree.h671
-rw-r--r--contrib/llvm/include/llvm/Support/GenericDomTreeConstruction.h1111
-rw-r--r--contrib/llvm/include/llvm/Support/GraphWriter.h59
-rw-r--r--contrib/llvm/include/llvm/Support/Host.h22
-rw-r--r--contrib/llvm/include/llvm/Support/KnownBits.h200
-rw-r--r--contrib/llvm/include/llvm/Support/LEB128.h79
-rw-r--r--contrib/llvm/include/llvm/Support/LowLevelTypeImpl.h309
-rw-r--r--contrib/llvm/include/llvm/Support/MD5.h59
-rw-r--r--contrib/llvm/include/llvm/Support/MachO.h1936
-rw-r--r--contrib/llvm/include/llvm/Support/ManagedStatic.h20
-rw-r--r--contrib/llvm/include/llvm/Support/MathExtras.h141
-rw-r--r--contrib/llvm/include/llvm/Support/MemoryBuffer.h24
-rw-r--r--contrib/llvm/include/llvm/Support/Parallel.h249
-rw-r--r--contrib/llvm/include/llvm/Support/Path.h91
-rw-r--r--contrib/llvm/include/llvm/Support/PointerLikeTypeTraits.h14
-rw-r--r--contrib/llvm/include/llvm/Support/RWMutex.h25
-rw-r--r--contrib/llvm/include/llvm/Support/Recycler.h3
-rw-r--r--contrib/llvm/include/llvm/Support/Regex.h2
-rw-r--r--contrib/llvm/include/llvm/Support/ReverseIteration.h17
-rw-r--r--contrib/llvm/include/llvm/Support/SMLoc.h4
-rw-r--r--contrib/llvm/include/llvm/Support/ScopedPrinter.h7
-rw-r--r--contrib/llvm/include/llvm/Support/Solaris/sys/regset.h (renamed from contrib/llvm/include/llvm/Support/Solaris.h)20
-rw-r--r--contrib/llvm/include/llvm/Support/SourceMgr.h59
-rw-r--r--contrib/llvm/include/llvm/Support/StringPool.h24
-rw-r--r--contrib/llvm/include/llvm/Support/StringSaver.h2
-rw-r--r--contrib/llvm/include/llvm/Support/TargetParser.h11
-rw-r--r--contrib/llvm/include/llvm/Support/TargetRegistry.h166
-rw-r--r--contrib/llvm/include/llvm/Support/ThreadPool.h43
-rw-r--r--contrib/llvm/include/llvm/Support/Threading.h104
-rw-r--r--contrib/llvm/include/llvm/Support/Timer.h4
-rw-r--r--contrib/llvm/include/llvm/Support/TrailingObjects.h7
-rw-r--r--contrib/llvm/include/llvm/Support/UnicodeCharRanges.h7
-rw-r--r--contrib/llvm/include/llvm/Support/UniqueLock.h18
-rw-r--r--contrib/llvm/include/llvm/Support/Wasm.h87
-rw-r--r--contrib/llvm/include/llvm/Support/YAMLParser.h111
-rw-r--r--contrib/llvm/include/llvm/Support/YAMLTraits.h357
-rw-r--r--contrib/llvm/include/llvm/Support/raw_sha1_ostream.h4
-rw-r--r--contrib/llvm/include/llvm/Support/thread.h14
-rw-r--r--contrib/llvm/include/llvm/Support/type_traits.h29
-rw-r--r--contrib/llvm/include/llvm/TableGen/Main.h14
-rw-r--r--contrib/llvm/include/llvm/TableGen/Record.h220
-rw-r--r--contrib/llvm/include/llvm/TableGen/SetTheory.h6
-rw-r--r--contrib/llvm/include/llvm/TableGen/StringMatcher.h11
-rw-r--r--contrib/llvm/include/llvm/TableGen/StringToOffsetTable.h10
-rw-r--r--contrib/llvm/include/llvm/Target/GenericOpcodes.td163
-rw-r--r--contrib/llvm/include/llvm/Target/GlobalISel/RegisterBank.td16
-rw-r--r--contrib/llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td75
-rw-r--r--contrib/llvm/include/llvm/Target/GlobalISel/Target.td48
-rw-r--r--contrib/llvm/include/llvm/Target/Target.td54
-rw-r--r--contrib/llvm/include/llvm/Target/TargetCallingConv.h202
-rw-r--r--contrib/llvm/include/llvm/Target/TargetGlobalISel.td29
-rw-r--r--contrib/llvm/include/llvm/Target/TargetInstrInfo.h230
-rw-r--r--contrib/llvm/include/llvm/Target/TargetLowering.h543
-rw-r--r--contrib/llvm/include/llvm/Target/TargetLoweringObjectFile.h57
-rw-r--r--contrib/llvm/include/llvm/Target/TargetMachine.h30
-rw-r--r--contrib/llvm/include/llvm/Target/TargetOpcodes.def76
-rw-r--r--contrib/llvm/include/llvm/Target/TargetOptions.h97
-rw-r--r--contrib/llvm/include/llvm/Target/TargetRegisterInfo.h139
-rw-r--r--contrib/llvm/include/llvm/Target/TargetSchedule.td7
-rw-r--r--contrib/llvm/include/llvm/Target/TargetSelectionDAG.td24
-rw-r--r--contrib/llvm/include/llvm/Target/TargetSubtargetInfo.h32
-rw-r--r--contrib/llvm/include/llvm/Testing/Support/Error.h69
-rw-r--r--contrib/llvm/include/llvm/Testing/Support/SupportHelpers.h47
-rw-r--r--contrib/llvm/include/llvm/ToolDrivers/llvm-dlltool/DlltoolDriver.h24
-rw-r--r--contrib/llvm/include/llvm/ToolDrivers/llvm-lib/LibDriver.h (renamed from contrib/llvm/include/llvm/LibDriver/LibDriver.h)6
-rw-r--r--contrib/llvm/include/llvm/Transforms/IPO.h45
-rw-r--r--contrib/llvm/include/llvm/Transforms/IPO/ArgumentPromotion.h31
-rw-r--r--contrib/llvm/include/llvm/Transforms/IPO/FunctionAttrs.h17
-rw-r--r--contrib/llvm/include/llvm/Transforms/IPO/FunctionImport.h19
-rw-r--r--contrib/llvm/include/llvm/Transforms/IPO/GlobalDCE.h21
-rw-r--r--contrib/llvm/include/llvm/Transforms/IPO/LowerTypeTests.h10
-rw-r--r--contrib/llvm/include/llvm/Transforms/IPO/PassManagerBuilder.h22
-rw-r--r--contrib/llvm/include/llvm/Transforms/IPO/ThinLTOBitcodeWriter.h41
-rw-r--r--contrib/llvm/include/llvm/Transforms/InstrProfiling.h48
-rw-r--r--contrib/llvm/include/llvm/Transforms/Instrumentation.h92
-rw-r--r--contrib/llvm/include/llvm/Transforms/PGOInstrumentation.h15
-rw-r--r--contrib/llvm/include/llvm/Transforms/SampleProfile.h4
-rw-r--r--contrib/llvm/include/llvm/Transforms/Scalar.h43
-rw-r--r--contrib/llvm/include/llvm/Transforms/Scalar/ConstantHoisting.h10
-rw-r--r--contrib/llvm/include/llvm/Transforms/Scalar/Float2Int.h2
-rw-r--r--contrib/llvm/include/llvm/Transforms/Scalar/GVN.h9
-rw-r--r--contrib/llvm/include/llvm/Transforms/Scalar/GVNExpression.h344
-rw-r--r--contrib/llvm/include/llvm/Transforms/Scalar/JumpThreading.h10
-rw-r--r--contrib/llvm/include/llvm/Transforms/Scalar/LoopDataPrefetch.h8
-rw-r--r--contrib/llvm/include/llvm/Transforms/Scalar/LoopDeletion.h17
-rw-r--r--contrib/llvm/include/llvm/Transforms/Scalar/LoopLoadElimination.h30
-rw-r--r--contrib/llvm/include/llvm/Transforms/Scalar/LoopPassManager.h36
-rw-r--r--contrib/llvm/include/llvm/Transforms/Scalar/LoopPredication.h32
-rw-r--r--contrib/llvm/include/llvm/Transforms/Scalar/LoopSink.h40
-rw-r--r--contrib/llvm/include/llvm/Transforms/Scalar/LoopUnrollPass.h30
-rw-r--r--contrib/llvm/include/llvm/Transforms/Scalar/MemCpyOptimizer.h11
-rw-r--r--contrib/llvm/include/llvm/Transforms/Scalar/NaryReassociate.h2
-rw-r--r--contrib/llvm/include/llvm/Transforms/Scalar/Reassociate.h2
-rw-r--r--contrib/llvm/include/llvm/Transforms/Scalar/SROA.h18
-rw-r--r--contrib/llvm/include/llvm/Transforms/Scalar/SimpleLoopUnswitch.h53
-rw-r--r--contrib/llvm/include/llvm/Transforms/Scalar/SimplifyCFG.h9
-rw-r--r--contrib/llvm/include/llvm/Transforms/Utils/BasicBlockUtils.h9
-rw-r--r--contrib/llvm/include/llvm/Transforms/Utils/BuildLibCalls.h4
-rw-r--r--contrib/llvm/include/llvm/Transforms/Utils/Cloning.h65
-rw-r--r--contrib/llvm/include/llvm/Transforms/Utils/CodeExtractor.h46
-rw-r--r--contrib/llvm/include/llvm/Transforms/Utils/EscapeEnumerator.h2
-rw-r--r--contrib/llvm/include/llvm/Transforms/Utils/FunctionComparator.h4
-rw-r--r--contrib/llvm/include/llvm/Transforms/Utils/FunctionImportUtils.h11
-rw-r--r--contrib/llvm/include/llvm/Transforms/Utils/GlobalStatus.h31
-rw-r--r--contrib/llvm/include/llvm/Transforms/Utils/ImportedFunctionsInliningStatistics.h2
-rw-r--r--contrib/llvm/include/llvm/Transforms/Utils/Local.h47
-rw-r--r--contrib/llvm/include/llvm/Transforms/Utils/LoopUtils.h110
-rw-r--r--contrib/llvm/include/llvm/Transforms/Utils/LoopVersioning.h2
-rw-r--r--contrib/llvm/include/llvm/Transforms/Utils/LowerMemIntrinsics.h62
-rw-r--r--contrib/llvm/include/llvm/Transforms/Utils/Mem2Reg.h2
-rw-r--r--contrib/llvm/include/llvm/Transforms/Utils/ModuleUtils.h14
-rw-r--r--contrib/llvm/include/llvm/Transforms/Utils/NameAnonGlobals.h8
-rw-r--r--contrib/llvm/include/llvm/Transforms/Utils/OrderedInstructions.h54
-rw-r--r--contrib/llvm/include/llvm/Transforms/Utils/PredicateInfo.h295
-rw-r--r--contrib/llvm/include/llvm/Transforms/Utils/PromoteMemToReg.h3
-rw-r--r--contrib/llvm/include/llvm/Transforms/Utils/SSAUpdater.h38
-rw-r--r--contrib/llvm/include/llvm/Transforms/Utils/SSAUpdaterImpl.h10
-rw-r--r--contrib/llvm/include/llvm/Transforms/Utils/SimplifyIndVar.h15
-rw-r--r--contrib/llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h9
-rw-r--r--contrib/llvm/include/llvm/Transforms/Utils/SymbolRewriter.h23
-rw-r--r--contrib/llvm/include/llvm/Transforms/Utils/UnifyFunctionExitNodes.h12
-rw-r--r--contrib/llvm/include/llvm/Transforms/Utils/UnrollLoop.h5
-rw-r--r--contrib/llvm/include/llvm/Transforms/Utils/VNCoercion.h108
-rw-r--r--contrib/llvm/include/llvm/Transforms/Utils/ValueMapper.h24
-rw-r--r--contrib/llvm/include/llvm/Transforms/Vectorize.h7
-rw-r--r--contrib/llvm/include/llvm/Transforms/Vectorize/LoopVectorize.h2
-rw-r--r--contrib/llvm/include/llvm/Transforms/Vectorize/SLPVectorizer.h18
-rw-r--r--contrib/llvm/include/llvm/XRay/Graph.h494
-rw-r--r--contrib/llvm/include/llvm/XRay/InstrumentationMap.h131
-rw-r--r--contrib/llvm/include/llvm/XRay/XRayRecord.h9
-rw-r--r--contrib/llvm/include/llvm/XRay/YAMLXRayRecord.h2
-rw-r--r--contrib/llvm/include/llvm/module.modulemap65
845 files changed, 46210 insertions, 22538 deletions
diff --git a/contrib/llvm/include/llvm-c/Core.h b/contrib/llvm/include/llvm-c/Core.h
index 7f5c05d..22cef23 100644
--- a/contrib/llvm/include/llvm-c/Core.h
+++ b/contrib/llvm/include/llvm-c/Core.h
@@ -1040,6 +1040,20 @@ LLVMBool LLVMIsOpaqueStruct(LLVMTypeRef StructTy);
LLVMTypeRef LLVMGetElementType(LLVMTypeRef Ty);
/**
+ * Returns type's subtypes
+ *
+ * @see llvm::Type::subtypes()
+ */
+void LLVMGetSubtypes(LLVMTypeRef Tp, LLVMTypeRef *Arr);
+
+/**
+ * Return the number of types in the derived type.
+ *
+ * @see llvm::Type::getNumContainedTypes()
+ */
+unsigned LLVMGetNumContainedTypes(LLVMTypeRef Tp);
+
+/**
* Create a fixed size array type that refers to a specific type.
*
* The created type will exist in the context that its element type
@@ -2131,6 +2145,16 @@ LLVMValueRef LLVMMDNodeInContext(LLVMContextRef C, LLVMValueRef *Vals,
LLVMValueRef LLVMMDNode(LLVMValueRef *Vals, unsigned Count);
/**
+ * Obtain a Metadata as a Value.
+ */
+LLVMValueRef LLVMMetadataAsValue(LLVMContextRef C, LLVMMetadataRef MD);
+
+/**
+ * Obtain a Value as a Metadata.
+ */
+LLVMMetadataRef LLVMValueAsMetadata(LLVMValueRef Val);
+
+/**
* Obtain the underlying string from a MDString value.
*
* @param V Instance to obtain string from.
diff --git a/contrib/llvm/include/llvm-c/ExecutionEngine.h b/contrib/llvm/include/llvm-c/ExecutionEngine.h
index b72a91a..51830fe 100644
--- a/contrib/llvm/include/llvm-c/ExecutionEngine.h
+++ b/contrib/llvm/include/llvm-c/ExecutionEngine.h
@@ -19,9 +19,9 @@
#ifndef LLVM_C_EXECUTIONENGINE_H
#define LLVM_C_EXECUTIONENGINE_H
-#include "llvm-c/Types.h"
#include "llvm-c/Target.h"
#include "llvm-c/TargetMachine.h"
+#include "llvm-c/Types.h"
#ifdef __cplusplus
extern "C" {
diff --git a/contrib/llvm/include/llvm-c/OrcBindings.h b/contrib/llvm/include/llvm-c/OrcBindings.h
index de2969a..7ee3954 100644
--- a/contrib/llvm/include/llvm-c/OrcBindings.h
+++ b/contrib/llvm/include/llvm-c/OrcBindings.h
@@ -29,6 +29,8 @@
extern "C" {
#endif
+typedef struct LLVMOpaqueSharedModule *LLVMSharedModuleRef;
+typedef struct LLVMOpaqueSharedObjectBuffer *LLVMSharedObjectBufferRef;
typedef struct LLVMOrcOpaqueJITStack *LLVMOrcJITStackRef;
typedef uint32_t LLVMOrcModuleHandle;
typedef uint64_t LLVMOrcTargetAddress;
@@ -39,6 +41,45 @@ typedef uint64_t (*LLVMOrcLazyCompileCallbackFn)(LLVMOrcJITStackRef JITStack,
typedef enum { LLVMOrcErrSuccess = 0, LLVMOrcErrGeneric } LLVMOrcErrorCode;
/**
+ * Turn an LLVMModuleRef into an LLVMSharedModuleRef.
+ *
+ * The JIT uses shared ownership for LLVM modules, since it is generally
+ * difficult to know when the JIT will be finished with a module (and the JIT
+ * has no way of knowing when a user may be finished with one).
+ *
+ * Calling this method with an LLVMModuleRef creates a shared-pointer to the
+ * module, and returns a reference to this shared pointer.
+ *
+ * The shared module should be disposed when finished with by calling
+ * LLVMOrcDisposeSharedModule (not LLVMDisposeModule). The Module will be
+ * deleted when the last shared pointer owner relinquishes it.
+ */
+
+LLVMSharedModuleRef LLVMOrcMakeSharedModule(LLVMModuleRef Mod);
+
+/**
+ * Dispose of a shared module.
+ *
+ * The module should not be accessed after this call. The module will be
+ * deleted once all clients (including the JIT itself) have released their
+ * shared pointers.
+ */
+
+void LLVMOrcDisposeSharedModuleRef(LLVMSharedModuleRef SharedMod);
+
+/**
+ * Get an LLVMSharedObjectBufferRef from an LLVMMemoryBufferRef.
+ */
+LLVMSharedObjectBufferRef
+LLVMOrcMakeSharedObjectBuffer(LLVMMemoryBufferRef ObjBuffer);
+
+/**
+ * Dispose of a shared object buffer.
+ */
+void
+LLVMOrcDisposeSharedObjectBufferRef(LLVMSharedObjectBufferRef SharedObjBuffer);
+
+/**
* Create an ORC JIT stack.
*
* The client owns the resulting stack, and must call OrcDisposeInstance(...)
@@ -72,8 +113,9 @@ void LLVMOrcDisposeMangledSymbol(char *MangledSymbol);
/**
* Create a lazy compile callback.
*/
-LLVMOrcTargetAddress
+LLVMOrcErrorCode
LLVMOrcCreateLazyCompileCallback(LLVMOrcJITStackRef JITStack,
+ LLVMOrcTargetAddress *RetAddr,
LLVMOrcLazyCompileCallbackFn Callback,
void *CallbackCtx);
@@ -94,26 +136,31 @@ LLVMOrcErrorCode LLVMOrcSetIndirectStubPointer(LLVMOrcJITStackRef JITStack,
/**
* Add module to be eagerly compiled.
*/
-LLVMOrcModuleHandle
-LLVMOrcAddEagerlyCompiledIR(LLVMOrcJITStackRef JITStack, LLVMModuleRef Mod,
+LLVMOrcErrorCode
+LLVMOrcAddEagerlyCompiledIR(LLVMOrcJITStackRef JITStack,
+ LLVMOrcModuleHandle *RetHandle,
+ LLVMSharedModuleRef Mod,
LLVMOrcSymbolResolverFn SymbolResolver,
void *SymbolResolverCtx);
/**
* Add module to be lazily compiled one function at a time.
*/
-LLVMOrcModuleHandle
-LLVMOrcAddLazilyCompiledIR(LLVMOrcJITStackRef JITStack, LLVMModuleRef Mod,
+LLVMOrcErrorCode
+LLVMOrcAddLazilyCompiledIR(LLVMOrcJITStackRef JITStack,
+ LLVMOrcModuleHandle *RetHandle,
+ LLVMSharedModuleRef Mod,
LLVMOrcSymbolResolverFn SymbolResolver,
void *SymbolResolverCtx);
/**
* Add an object file.
*/
-LLVMOrcModuleHandle LLVMOrcAddObjectFile(LLVMOrcJITStackRef JITStack,
- LLVMObjectFileRef Obj,
- LLVMOrcSymbolResolverFn SymbolResolver,
- void *SymbolResolverCtx);
+LLVMOrcErrorCode LLVMOrcAddObjectFile(LLVMOrcJITStackRef JITStack,
+ LLVMOrcModuleHandle *RetHandle,
+ LLVMSharedObjectBufferRef Obj,
+ LLVMOrcSymbolResolverFn SymbolResolver,
+ void *SymbolResolverCtx);
/**
* Remove a module set from the JIT.
@@ -121,18 +168,20 @@ LLVMOrcModuleHandle LLVMOrcAddObjectFile(LLVMOrcJITStackRef JITStack,
* This works for all modules that can be added via OrcAdd*, including object
* files.
*/
-void LLVMOrcRemoveModule(LLVMOrcJITStackRef JITStack, LLVMOrcModuleHandle H);
+LLVMOrcErrorCode LLVMOrcRemoveModule(LLVMOrcJITStackRef JITStack,
+ LLVMOrcModuleHandle H);
/**
* Get symbol address from JIT instance.
*/
-LLVMOrcTargetAddress LLVMOrcGetSymbolAddress(LLVMOrcJITStackRef JITStack,
- const char *SymbolName);
+LLVMOrcErrorCode LLVMOrcGetSymbolAddress(LLVMOrcJITStackRef JITStack,
+ LLVMOrcTargetAddress *RetAddr,
+ const char *SymbolName);
/**
* Dispose of an ORC JIT stack.
*/
-void LLVMOrcDisposeInstance(LLVMOrcJITStackRef JITStack);
+LLVMOrcErrorCode LLVMOrcDisposeInstance(LLVMOrcJITStackRef JITStack);
#ifdef __cplusplus
}
diff --git a/contrib/llvm/include/llvm-c/Support.h b/contrib/llvm/include/llvm-c/Support.h
index 735d1fb..6de184c 100644
--- a/contrib/llvm/include/llvm-c/Support.h
+++ b/contrib/llvm/include/llvm-c/Support.h
@@ -14,8 +14,8 @@
#ifndef LLVM_C_SUPPORT_H
#define LLVM_C_SUPPORT_H
-#include "llvm/Support/DataTypes.h"
#include "llvm-c/Types.h"
+#include "llvm/Support/DataTypes.h"
#ifdef __cplusplus
extern "C" {
diff --git a/contrib/llvm/include/llvm-c/TargetMachine.h b/contrib/llvm/include/llvm-c/TargetMachine.h
index 1d1f61f..f4f7f76 100644
--- a/contrib/llvm/include/llvm-c/TargetMachine.h
+++ b/contrib/llvm/include/llvm-c/TargetMachine.h
@@ -19,8 +19,8 @@
#ifndef LLVM_C_TARGETMACHINE_H
#define LLVM_C_TARGETMACHINE_H
-#include "llvm-c/Types.h"
#include "llvm-c/Target.h"
+#include "llvm-c/Types.h"
#ifdef __cplusplus
extern "C" {
diff --git a/contrib/llvm/include/llvm-c/Transforms/Scalar.h b/contrib/llvm/include/llvm-c/Transforms/Scalar.h
index 8991e09..b9612b9 100644
--- a/contrib/llvm/include/llvm-c/Transforms/Scalar.h
+++ b/contrib/llvm/include/llvm-c/Transforms/Scalar.h
@@ -44,6 +44,9 @@ void LLVMAddAlignmentFromAssumptionsPass(LLVMPassManagerRef PM);
/** See llvm::createCFGSimplificationPass function. */
void LLVMAddCFGSimplificationPass(LLVMPassManagerRef PM);
+/** See llvm::createLateCFGSimplificationPass function. */
+void LLVMAddLateCFGSimplificationPass(LLVMPassManagerRef PM);
+
/** See llvm::createDeadStoreEliminationPass function. */
void LLVMAddDeadStoreEliminationPass(LLVMPassManagerRef PM);
diff --git a/contrib/llvm/include/llvm-c/Transforms/Vectorize.h b/contrib/llvm/include/llvm-c/Transforms/Vectorize.h
index a82ef49..cf8306a 100644
--- a/contrib/llvm/include/llvm-c/Transforms/Vectorize.h
+++ b/contrib/llvm/include/llvm-c/Transforms/Vectorize.h
@@ -33,7 +33,7 @@ extern "C" {
* @{
*/
-/** See llvm::createBBVectorizePass function. */
+/** DEPRECATED - Use LLVMAddSLPVectorizePass */
void LLVMAddBBVectorizePass(LLVMPassManagerRef PM);
/** See llvm::createLoopVectorizePass function. */
diff --git a/contrib/llvm/include/llvm-c/Types.h b/contrib/llvm/include/llvm-c/Types.h
index 3d472a6..d63ea4d 100644
--- a/contrib/llvm/include/llvm-c/Types.h
+++ b/contrib/llvm/include/llvm-c/Types.h
@@ -83,6 +83,13 @@ typedef struct LLVMOpaqueValue *LLVMValueRef;
typedef struct LLVMOpaqueBasicBlock *LLVMBasicBlockRef;
/**
+ * Represents an LLVM Metadata.
+ *
+ * This models llvm::Metadata.
+ */
+typedef struct LLVMOpaqueMetadata *LLVMMetadataRef;
+
+/**
* Represents an LLVM basic block builder.
*
* This models llvm::IRBuilder.
@@ -90,6 +97,13 @@ typedef struct LLVMOpaqueBasicBlock *LLVMBasicBlockRef;
typedef struct LLVMOpaqueBuilder *LLVMBuilderRef;
/**
+ * Represents an LLVM debug info builder.
+ *
+ * This models llvm::DIBuilder.
+ */
+typedef struct LLVMOpaqueDIBuilder *LLVMDIBuilderRef;
+
+/**
* Interface used to provide a module to JIT or interpreter.
* This is now just a synonym for llvm::Module, but we have to keep using the
* different type to keep binary compatibility.
diff --git a/contrib/llvm/include/llvm-c/lto.h b/contrib/llvm/include/llvm-c/lto.h
index c3af74c..8d45b78 100644
--- a/contrib/llvm/include/llvm-c/lto.h
+++ b/contrib/llvm/include/llvm-c/lto.h
@@ -551,7 +551,7 @@ lto_codegen_set_should_embed_uselists(lto_code_gen_t cg,
lto_bool_t ShouldEmbedUselists);
/**
- * @}
+ * @} // endgoup LLVMCLTO
* @defgroup LLVMCTLTO ThinLTO
* @ingroup LLVMC
*
@@ -669,75 +669,6 @@ extern lto_bool_t thinlto_codegen_set_pic_model(thinlto_code_gen_t cg,
lto_codegen_model);
/**
- * @}
- * @defgroup LLVMCTLTO_CACHING ThinLTO Cache Control
- * @ingroup LLVMCTLTO
- *
- * These entry points control the ThinLTO cache. The cache is intended to
- * support incremental build, and thus needs to be persistent accross build.
- * The client enabled the cache by supplying a path to an existing directory.
- * The code generator will use this to store objects files that may be reused
- * during a subsequent build.
- * To avoid filling the disk space, a few knobs are provided:
- * - The pruning interval limit the frequency at which the garbage collector
- * will try to scan the cache directory to prune it from expired entries.
- * Setting to -1 disable the pruning (default).
- * - The pruning expiration time indicates to the garbage collector how old an
- * entry needs to be to be removed.
- * - Finally, the garbage collector can be instructed to prune the cache till
- * the occupied space goes below a threshold.
- * @{
- */
-
-/**
- * Sets the path to a directory to use as a cache storage for incremental build.
- * Setting this activates caching.
- *
- * \since LTO_API_VERSION=18
- */
-extern void thinlto_codegen_set_cache_dir(thinlto_code_gen_t cg,
- const char *cache_dir);
-
-/**
- * Sets the cache pruning interval (in seconds). A negative value disable the
- * pruning. An unspecified default value will be applied, and a value of 0 will
- * be ignored.
- *
- * \since LTO_API_VERSION=18
- */
-extern void thinlto_codegen_set_cache_pruning_interval(thinlto_code_gen_t cg,
- int interval);
-
-/**
- * Sets the maximum cache size that can be persistent across build, in terms of
- * percentage of the available space on the the disk. Set to 100 to indicate
- * no limit, 50 to indicate that the cache size will not be left over half the
- * available space. A value over 100 will be reduced to 100, a value of 0 will
- * be ignored. An unspecified default value will be applied.
- *
- * The formula looks like:
- * AvailableSpace = FreeSpace + ExistingCacheSize
- * NewCacheSize = AvailableSpace * P/100
- *
- * \since LTO_API_VERSION=18
- */
-extern void thinlto_codegen_set_final_cache_size_relative_to_available_space(
- thinlto_code_gen_t cg, unsigned percentage);
-
-/**
- * Sets the expiration (in seconds) for an entry in the cache. An unspecified
- * default value will be applied. A value of 0 will be ignored.
- *
- * \since LTO_API_VERSION=18
- */
-extern void thinlto_codegen_set_cache_entry_expiration(thinlto_code_gen_t cg,
- unsigned expiration);
-
-/**
- * @}
- */
-
-/**
* Sets the path to a directory to use as a storage for temporary bitcode files.
* The intention is to make the bitcode files available for debugging at various
* stage of the pipeline.
@@ -820,12 +751,77 @@ extern void thinlto_codegen_add_cross_referenced_symbol(thinlto_code_gen_t cg,
const char *name,
int length);
-#ifdef __cplusplus
-}
-#endif
+/**
+ * @} // endgoup LLVMCTLTO
+ * @defgroup LLVMCTLTO_CACHING ThinLTO Cache Control
+ * @ingroup LLVMCTLTO
+ *
+ * These entry points control the ThinLTO cache. The cache is intended to
+ * support incremental build, and thus needs to be persistent accross build.
+ * The client enabled the cache by supplying a path to an existing directory.
+ * The code generator will use this to store objects files that may be reused
+ * during a subsequent build.
+ * To avoid filling the disk space, a few knobs are provided:
+ * - The pruning interval limit the frequency at which the garbage collector
+ * will try to scan the cache directory to prune it from expired entries.
+ * Setting to -1 disable the pruning (default).
+ * - The pruning expiration time indicates to the garbage collector how old an
+ * entry needs to be to be removed.
+ * - Finally, the garbage collector can be instructed to prune the cache till
+ * the occupied space goes below a threshold.
+ * @{
+ */
+
+/**
+ * Sets the path to a directory to use as a cache storage for incremental build.
+ * Setting this activates caching.
+ *
+ * \since LTO_API_VERSION=18
+ */
+extern void thinlto_codegen_set_cache_dir(thinlto_code_gen_t cg,
+ const char *cache_dir);
+
+/**
+ * Sets the cache pruning interval (in seconds). A negative value disable the
+ * pruning. An unspecified default value will be applied, and a value of 0 will
+ * be ignored.
+ *
+ * \since LTO_API_VERSION=18
+ */
+extern void thinlto_codegen_set_cache_pruning_interval(thinlto_code_gen_t cg,
+ int interval);
+
+/**
+ * Sets the maximum cache size that can be persistent across build, in terms of
+ * percentage of the available space on the the disk. Set to 100 to indicate
+ * no limit, 50 to indicate that the cache size will not be left over half the
+ * available space. A value over 100 will be reduced to 100, a value of 0 will
+ * be ignored. An unspecified default value will be applied.
+ *
+ * The formula looks like:
+ * AvailableSpace = FreeSpace + ExistingCacheSize
+ * NewCacheSize = AvailableSpace * P/100
+ *
+ * \since LTO_API_VERSION=18
+ */
+extern void thinlto_codegen_set_final_cache_size_relative_to_available_space(
+ thinlto_code_gen_t cg, unsigned percentage);
/**
- * @}
+ * Sets the expiration (in seconds) for an entry in the cache. An unspecified
+ * default value will be applied. A value of 0 will be ignored.
+ *
+ * \since LTO_API_VERSION=18
*/
+extern void thinlto_codegen_set_cache_entry_expiration(thinlto_code_gen_t cg,
+ unsigned expiration);
+
+/**
+ * @} // endgroup LLVMCTLTO_CACHING
+ */
+
+#ifdef __cplusplus
+}
+#endif
#endif /* LLVM_C_LTO_H */
diff --git a/contrib/llvm/include/llvm/ADT/APFloat.h b/contrib/llvm/include/llvm/ADT/APFloat.h
index 0030423..9c5e392 100644
--- a/contrib/llvm/include/llvm/ADT/APFloat.h
+++ b/contrib/llvm/include/llvm/ADT/APFloat.h
@@ -18,9 +18,19 @@
#define LLVM_ADT_APFLOAT_H
#include "llvm/ADT/APInt.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/Support/ErrorHandling.h"
#include <memory>
+#define APFLOAT_DISPATCH_ON_SEMANTICS(METHOD_CALL) \
+ do { \
+ if (usesLayout<IEEEFloat>(getSemantics())) \
+ return U.IEEE.METHOD_CALL; \
+ if (usesLayout<DoubleAPFloat>(getSemantics())) \
+ return U.Double.METHOD_CALL; \
+ llvm_unreachable("Unexpected semantics"); \
+ } while (false)
+
namespace llvm {
struct fltSemantics;
@@ -42,7 +52,7 @@ enum lostFraction { // Example of truncated bits:
lfMoreThanHalf // 1xxxxx x's not all zero
};
-/// \brief A self-contained host- and target-independent arbitrary-precision
+/// A self-contained host- and target-independent arbitrary-precision
/// floating-point software implementation.
///
/// APFloat uses bignum integer arithmetic as provided by static functions in
@@ -130,22 +140,25 @@ enum lostFraction { // Example of truncated bits:
// implementation classes. This struct should not define any non-static data
// members.
struct APFloatBase {
+ typedef APInt::WordType integerPart;
+ static const unsigned integerPartWidth = APInt::APINT_BITS_PER_WORD;
+
/// A signed type to represent a floating point numbers unbiased exponent.
typedef signed short ExponentType;
/// \name Floating Point Semantics.
/// @{
- static const fltSemantics &IEEEhalf();
- static const fltSemantics &IEEEsingle();
- static const fltSemantics &IEEEdouble();
- static const fltSemantics &IEEEquad();
- static const fltSemantics &PPCDoubleDouble();
- static const fltSemantics &x87DoubleExtended();
+ static const fltSemantics &IEEEhalf() LLVM_READNONE;
+ static const fltSemantics &IEEEsingle() LLVM_READNONE;
+ static const fltSemantics &IEEEdouble() LLVM_READNONE;
+ static const fltSemantics &IEEEquad() LLVM_READNONE;
+ static const fltSemantics &PPCDoubleDouble() LLVM_READNONE;
+ static const fltSemantics &x87DoubleExtended() LLVM_READNONE;
/// A Pseudo fltsemantic used to construct APFloats that cannot conflict with
/// anything real.
- static const fltSemantics &Bogus();
+ static const fltSemantics &Bogus() LLVM_READNONE;
/// @}
@@ -191,7 +204,7 @@ struct APFloatBase {
uninitialized
};
- /// \brief Enumeration of \c ilogb error results.
+ /// Enumeration of \c ilogb error results.
enum IlogbErrorKinds {
IEK_Zero = INT_MIN + 1,
IEK_NaN = INT_MIN,
@@ -227,7 +240,7 @@ public:
/// @}
- /// \brief Returns whether this instance allocated memory.
+ /// Returns whether this instance allocated memory.
bool needsCleanup() const { return partCount() > 1; }
/// \name Convenience "constructors"
@@ -235,10 +248,6 @@ public:
/// @}
- /// Used to insert APFloat objects, or objects that contain APFloat objects,
- /// into FoldingSets.
- void Profile(FoldingSetNodeID &NID) const;
-
/// \name Arithmetic
/// @{
@@ -255,53 +264,12 @@ public:
/// IEEE-754R 5.3.1: nextUp/nextDown.
opStatus next(bool nextDown);
- /// \brief Operator+ overload which provides the default
- /// \c nmNearestTiesToEven rounding mode and *no* error checking.
- IEEEFloat operator+(const IEEEFloat &RHS) const {
- IEEEFloat Result = *this;
- Result.add(RHS, rmNearestTiesToEven);
- return Result;
- }
-
- /// \brief Operator- overload which provides the default
- /// \c nmNearestTiesToEven rounding mode and *no* error checking.
- IEEEFloat operator-(const IEEEFloat &RHS) const {
- IEEEFloat Result = *this;
- Result.subtract(RHS, rmNearestTiesToEven);
- return Result;
- }
-
- /// \brief Operator* overload which provides the default
- /// \c nmNearestTiesToEven rounding mode and *no* error checking.
- IEEEFloat operator*(const IEEEFloat &RHS) const {
- IEEEFloat Result = *this;
- Result.multiply(RHS, rmNearestTiesToEven);
- return Result;
- }
-
- /// \brief Operator/ overload which provides the default
- /// \c nmNearestTiesToEven rounding mode and *no* error checking.
- IEEEFloat operator/(const IEEEFloat &RHS) const {
- IEEEFloat Result = *this;
- Result.divide(RHS, rmNearestTiesToEven);
- return Result;
- }
-
/// @}
/// \name Sign operations.
/// @{
void changeSign();
- void clearSign();
- void copySign(const IEEEFloat &);
-
- /// \brief A static helper to produce a copy of an APFloat value with its sign
- /// copied from some other APFloat.
- static IEEEFloat copySign(IEEEFloat Value, const IEEEFloat &Sign) {
- Value.copySign(Sign);
- return Value;
- }
/// @}
@@ -309,9 +277,8 @@ public:
/// @{
opStatus convert(const fltSemantics &, roundingMode, bool *);
- opStatus convertToInteger(integerPart *, unsigned int, bool, roundingMode,
- bool *) const;
- opStatus convertToInteger(APSInt &, roundingMode, bool *) const;
+ opStatus convertToInteger(MutableArrayRef<integerPart>, unsigned int, bool,
+ roundingMode, bool *) const;
opStatus convertFromAPInt(const APInt &, bool, roundingMode);
opStatus convertFromSignExtendedInteger(const integerPart *, unsigned int,
bool, roundingMode);
@@ -398,7 +365,7 @@ public:
/// Returns true if and only if the number has the largest possible finite
/// magnitude in the current semantics.
bool isLargest() const;
-
+
/// Returns true if and only if the number is an exact integer.
bool isInteger() const;
@@ -407,7 +374,7 @@ public:
IEEEFloat &operator=(const IEEEFloat &);
IEEEFloat &operator=(IEEEFloat &&);
- /// \brief Overload to compute a hash code for an APFloat value.
+ /// Overload to compute a hash code for an APFloat value.
///
/// Note that the use of hash codes for floating point values is in general
/// frought with peril. Equality is hard to define for these values. For
@@ -430,6 +397,12 @@ public:
/// consider inserting before falling back to scientific
/// notation. 0 means to always use scientific notation.
///
+ /// \param TruncateZero Indicate whether to remove the trailing zero in
+ /// fraction part or not. Also setting this parameter to false forcing
+ /// producing of output more similar to default printf behavior.
+ /// Specifically the lower e is used as exponent delimiter and exponent
+ /// always contains no less than two digits.
+ ///
/// Number Precision MaxPadding Result
/// ------ --------- ---------- ------
/// 1.01E+4 5 2 10100
@@ -439,13 +412,13 @@ public:
/// 1.01E-2 4 2 0.0101
/// 1.01E-2 4 1 1.01E-2
void toString(SmallVectorImpl<char> &Str, unsigned FormatPrecision = 0,
- unsigned FormatMaxPadding = 3) const;
+ unsigned FormatMaxPadding = 3, bool TruncateZero = true) const;
/// If this value has an exact multiplicative inverse, store it in inv and
/// return true.
- bool getExactInverse(IEEEFloat *inv) const;
+ bool getExactInverse(APFloat *inv) const;
- /// \brief Returns the exponent of the internal representation of the APFloat.
+ /// Returns the exponent of the internal representation of the APFloat.
///
/// Because the radix of APFloat is 2, this is equivalent to floor(log2(x)).
/// For special APFloat values, this returns special error codes:
@@ -456,7 +429,7 @@ public:
///
friend int ilogb(const IEEEFloat &Arg);
- /// \brief Returns: X * 2^Exp for integral exponents.
+ /// Returns: X * 2^Exp for integral exponents.
friend IEEEFloat scalbn(IEEEFloat X, int Exp, roundingMode);
friend IEEEFloat frexp(const IEEEFloat &X, int &Exp, roundingMode);
@@ -532,8 +505,9 @@ private:
opStatus addOrSubtract(const IEEEFloat &, roundingMode, bool subtract);
opStatus handleOverflow(roundingMode);
bool roundAwayFromZero(roundingMode, lostFraction, unsigned int) const;
- opStatus convertToSignExtendedInteger(integerPart *, unsigned int, bool,
- roundingMode, bool *) const;
+ opStatus convertToSignExtendedInteger(MutableArrayRef<integerPart>,
+ unsigned int, bool, roundingMode,
+ bool *) const;
opStatus convertFromUnsignedParts(const integerPart *, unsigned int,
roundingMode);
opStatus convertFromHexadecimalString(StringRef, roundingMode);
@@ -636,6 +610,13 @@ public:
opStatus add(const DoubleAPFloat &RHS, roundingMode RM);
opStatus subtract(const DoubleAPFloat &RHS, roundingMode RM);
+ opStatus multiply(const DoubleAPFloat &RHS, roundingMode RM);
+ opStatus divide(const DoubleAPFloat &RHS, roundingMode RM);
+ opStatus remainder(const DoubleAPFloat &RHS);
+ opStatus mod(const DoubleAPFloat &RHS);
+ opStatus fusedMultiplyAdd(const DoubleAPFloat &Multiplicand,
+ const DoubleAPFloat &Addend, roundingMode RM);
+ opStatus roundToIntegral(roundingMode RM);
void changeSign();
cmpResult compareAbsoluteValue(const DoubleAPFloat &RHS) const;
@@ -643,9 +624,49 @@ public:
bool isNegative() const;
void makeInf(bool Neg);
+ void makeZero(bool Neg);
+ void makeLargest(bool Neg);
+ void makeSmallest(bool Neg);
+ void makeSmallestNormalized(bool Neg);
void makeNaN(bool SNaN, bool Neg, const APInt *fill);
+
+ cmpResult compare(const DoubleAPFloat &RHS) const;
+ bool bitwiseIsEqual(const DoubleAPFloat &RHS) const;
+ APInt bitcastToAPInt() const;
+ opStatus convertFromString(StringRef, roundingMode);
+ opStatus next(bool nextDown);
+
+ opStatus convertToInteger(MutableArrayRef<integerPart> Input,
+ unsigned int Width, bool IsSigned, roundingMode RM,
+ bool *IsExact) const;
+ opStatus convertFromAPInt(const APInt &Input, bool IsSigned, roundingMode RM);
+ opStatus convertFromSignExtendedInteger(const integerPart *Input,
+ unsigned int InputSize, bool IsSigned,
+ roundingMode RM);
+ opStatus convertFromZeroExtendedInteger(const integerPart *Input,
+ unsigned int InputSize, bool IsSigned,
+ roundingMode RM);
+ unsigned int convertToHexString(char *DST, unsigned int HexDigits,
+ bool UpperCase, roundingMode RM) const;
+
+ bool isDenormal() const;
+ bool isSmallest() const;
+ bool isLargest() const;
+ bool isInteger() const;
+
+ void toString(SmallVectorImpl<char> &Str, unsigned FormatPrecision,
+ unsigned FormatMaxPadding, bool TruncateZero = true) const;
+
+ bool getExactInverse(APFloat *inv) const;
+
+ friend int ilogb(const DoubleAPFloat &Arg);
+ friend DoubleAPFloat scalbn(DoubleAPFloat X, int Exp, roundingMode);
+ friend DoubleAPFloat frexp(const DoubleAPFloat &X, int &Exp, roundingMode);
+ friend hash_code hash_value(const DoubleAPFloat &Arg);
};
+hash_code hash_value(const DoubleAPFloat &Arg);
+
} // End detail namespace
// This is a interface class that is currently forwarding functionalities from
@@ -770,26 +791,24 @@ class APFloat : public APFloatBase {
llvm_unreachable("Unexpected semantics");
}
- void makeZero(bool Neg) { getIEEE().makeZero(Neg); }
+ void makeZero(bool Neg) { APFLOAT_DISPATCH_ON_SEMANTICS(makeZero(Neg)); }
- void makeInf(bool Neg) {
- if (usesLayout<IEEEFloat>(*U.semantics))
- return U.IEEE.makeInf(Neg);
- if (usesLayout<DoubleAPFloat>(*U.semantics))
- return U.Double.makeInf(Neg);
- llvm_unreachable("Unexpected semantics");
- }
+ void makeInf(bool Neg) { APFLOAT_DISPATCH_ON_SEMANTICS(makeInf(Neg)); }
void makeNaN(bool SNaN, bool Neg, const APInt *fill) {
- getIEEE().makeNaN(SNaN, Neg, fill);
+ APFLOAT_DISPATCH_ON_SEMANTICS(makeNaN(SNaN, Neg, fill));
}
- void makeLargest(bool Neg) { getIEEE().makeLargest(Neg); }
+ void makeLargest(bool Neg) {
+ APFLOAT_DISPATCH_ON_SEMANTICS(makeLargest(Neg));
+ }
- void makeSmallest(bool Neg) { getIEEE().makeSmallest(Neg); }
+ void makeSmallest(bool Neg) {
+ APFLOAT_DISPATCH_ON_SEMANTICS(makeSmallest(Neg));
+ }
void makeSmallestNormalized(bool Neg) {
- getIEEE().makeSmallestNormalized(Neg);
+ APFLOAT_DISPATCH_ON_SEMANTICS(makeSmallestNormalized(Neg));
}
// FIXME: This is due to clang 3.3 (or older version) always checks for the
@@ -804,7 +823,8 @@ class APFloat : public APFloatBase {
: U(std::move(F), S) {}
cmpResult compareAbsoluteValue(const APFloat &RHS) const {
- assert(&getSemantics() == &RHS.getSemantics());
+ assert(&getSemantics() == &RHS.getSemantics() &&
+ "Should only compare APFloats with the same semantics");
if (usesLayout<IEEEFloat>(getSemantics()))
return U.IEEE.compareAbsoluteValue(RHS.U.IEEE);
if (usesLayout<DoubleAPFloat>(getSemantics()))
@@ -827,13 +847,7 @@ public:
~APFloat() = default;
- bool needsCleanup() const {
- if (usesLayout<IEEEFloat>(getSemantics()))
- return U.IEEE.needsCleanup();
- if (usesLayout<DoubleAPFloat>(getSemantics()))
- return U.Double.needsCleanup();
- llvm_unreachable("Unexpected semantics");
- }
+ bool needsCleanup() const { APFLOAT_DISPATCH_ON_SEMANTICS(needsCleanup()); }
/// Factory for Positive and Negative Zero.
///
@@ -920,9 +934,13 @@ public:
/// \param isIEEE - If 128 bit number, select between PPC and IEEE
static APFloat getAllOnesValue(unsigned BitWidth, bool isIEEE = false);
- void Profile(FoldingSetNodeID &NID) const { getIEEE().Profile(NID); }
+ /// Used to insert APFloat objects, or objects that contain APFloat objects,
+ /// into FoldingSets.
+ void Profile(FoldingSetNodeID &NID) const;
opStatus add(const APFloat &RHS, roundingMode RM) {
+ assert(&getSemantics() == &RHS.getSemantics() &&
+ "Should only call on two APFloats with the same semantics");
if (usesLayout<IEEEFloat>(getSemantics()))
return U.IEEE.add(RHS.U.IEEE, RM);
if (usesLayout<DoubleAPFloat>(getSemantics()))
@@ -930,6 +948,8 @@ public:
llvm_unreachable("Unexpected semantics");
}
opStatus subtract(const APFloat &RHS, roundingMode RM) {
+ assert(&getSemantics() == &RHS.getSemantics() &&
+ "Should only call on two APFloats with the same semantics");
if (usesLayout<IEEEFloat>(getSemantics()))
return U.IEEE.subtract(RHS.U.IEEE, RM);
if (usesLayout<DoubleAPFloat>(getSemantics()))
@@ -937,95 +957,172 @@ public:
llvm_unreachable("Unexpected semantics");
}
opStatus multiply(const APFloat &RHS, roundingMode RM) {
- return getIEEE().multiply(RHS.getIEEE(), RM);
+ assert(&getSemantics() == &RHS.getSemantics() &&
+ "Should only call on two APFloats with the same semantics");
+ if (usesLayout<IEEEFloat>(getSemantics()))
+ return U.IEEE.multiply(RHS.U.IEEE, RM);
+ if (usesLayout<DoubleAPFloat>(getSemantics()))
+ return U.Double.multiply(RHS.U.Double, RM);
+ llvm_unreachable("Unexpected semantics");
}
opStatus divide(const APFloat &RHS, roundingMode RM) {
- return getIEEE().divide(RHS.getIEEE(), RM);
+ assert(&getSemantics() == &RHS.getSemantics() &&
+ "Should only call on two APFloats with the same semantics");
+ if (usesLayout<IEEEFloat>(getSemantics()))
+ return U.IEEE.divide(RHS.U.IEEE, RM);
+ if (usesLayout<DoubleAPFloat>(getSemantics()))
+ return U.Double.divide(RHS.U.Double, RM);
+ llvm_unreachable("Unexpected semantics");
}
opStatus remainder(const APFloat &RHS) {
- return getIEEE().remainder(RHS.getIEEE());
+ assert(&getSemantics() == &RHS.getSemantics() &&
+ "Should only call on two APFloats with the same semantics");
+ if (usesLayout<IEEEFloat>(getSemantics()))
+ return U.IEEE.remainder(RHS.U.IEEE);
+ if (usesLayout<DoubleAPFloat>(getSemantics()))
+ return U.Double.remainder(RHS.U.Double);
+ llvm_unreachable("Unexpected semantics");
+ }
+ opStatus mod(const APFloat &RHS) {
+ assert(&getSemantics() == &RHS.getSemantics() &&
+ "Should only call on two APFloats with the same semantics");
+ if (usesLayout<IEEEFloat>(getSemantics()))
+ return U.IEEE.mod(RHS.U.IEEE);
+ if (usesLayout<DoubleAPFloat>(getSemantics()))
+ return U.Double.mod(RHS.U.Double);
+ llvm_unreachable("Unexpected semantics");
}
- opStatus mod(const APFloat &RHS) { return getIEEE().mod(RHS.getIEEE()); }
opStatus fusedMultiplyAdd(const APFloat &Multiplicand, const APFloat &Addend,
roundingMode RM) {
- return getIEEE().fusedMultiplyAdd(Multiplicand.getIEEE(), Addend.getIEEE(),
- RM);
+ assert(&getSemantics() == &Multiplicand.getSemantics() &&
+ "Should only call on APFloats with the same semantics");
+ assert(&getSemantics() == &Addend.getSemantics() &&
+ "Should only call on APFloats with the same semantics");
+ if (usesLayout<IEEEFloat>(getSemantics()))
+ return U.IEEE.fusedMultiplyAdd(Multiplicand.U.IEEE, Addend.U.IEEE, RM);
+ if (usesLayout<DoubleAPFloat>(getSemantics()))
+ return U.Double.fusedMultiplyAdd(Multiplicand.U.Double, Addend.U.Double,
+ RM);
+ llvm_unreachable("Unexpected semantics");
}
opStatus roundToIntegral(roundingMode RM) {
- return getIEEE().roundToIntegral(RM);
+ APFLOAT_DISPATCH_ON_SEMANTICS(roundToIntegral(RM));
}
- opStatus next(bool nextDown) { return getIEEE().next(nextDown); }
+ // TODO: bool parameters are not readable and a source of bugs.
+ // Do something.
+ opStatus next(bool nextDown) {
+ APFLOAT_DISPATCH_ON_SEMANTICS(next(nextDown));
+ }
+
+ /// Add two APFloats, rounding ties to the nearest even.
+ /// No error checking.
APFloat operator+(const APFloat &RHS) const {
- return APFloat(getIEEE() + RHS.getIEEE(), getSemantics());
+ APFloat Result(*this);
+ (void)Result.add(RHS, rmNearestTiesToEven);
+ return Result;
}
+ /// Subtract two APFloats, rounding ties to the nearest even.
+ /// No error checking.
APFloat operator-(const APFloat &RHS) const {
- return APFloat(getIEEE() - RHS.getIEEE(), getSemantics());
+ APFloat Result(*this);
+ (void)Result.subtract(RHS, rmNearestTiesToEven);
+ return Result;
}
+ /// Multiply two APFloats, rounding ties to the nearest even.
+ /// No error checking.
APFloat operator*(const APFloat &RHS) const {
- return APFloat(getIEEE() * RHS.getIEEE(), getSemantics());
+ APFloat Result(*this);
+ (void)Result.multiply(RHS, rmNearestTiesToEven);
+ return Result;
}
+ /// Divide the first APFloat by the second, rounding ties to the nearest even.
+ /// No error checking.
APFloat operator/(const APFloat &RHS) const {
- return APFloat(getIEEE() / RHS.getIEEE(), getSemantics());
+ APFloat Result(*this);
+ (void)Result.divide(RHS, rmNearestTiesToEven);
+ return Result;
}
- void changeSign() { getIEEE().changeSign(); }
- void clearSign() { getIEEE().clearSign(); }
- void copySign(const APFloat &RHS) { getIEEE().copySign(RHS.getIEEE()); }
+ void changeSign() { APFLOAT_DISPATCH_ON_SEMANTICS(changeSign()); }
+ void clearSign() {
+ if (isNegative())
+ changeSign();
+ }
+ void copySign(const APFloat &RHS) {
+ if (isNegative() != RHS.isNegative())
+ changeSign();
+ }
+ /// A static helper to produce a copy of an APFloat value with its sign
+ /// copied from some other APFloat.
static APFloat copySign(APFloat Value, const APFloat &Sign) {
- return APFloat(IEEEFloat::copySign(Value.getIEEE(), Sign.getIEEE()),
- Value.getSemantics());
+ Value.copySign(Sign);
+ return Value;
}
opStatus convert(const fltSemantics &ToSemantics, roundingMode RM,
bool *losesInfo);
- opStatus convertToInteger(integerPart *Input, unsigned int Width,
- bool IsSigned, roundingMode RM,
+ opStatus convertToInteger(MutableArrayRef<integerPart> Input,
+ unsigned int Width, bool IsSigned, roundingMode RM,
bool *IsExact) const {
- return getIEEE().convertToInteger(Input, Width, IsSigned, RM, IsExact);
+ APFLOAT_DISPATCH_ON_SEMANTICS(
+ convertToInteger(Input, Width, IsSigned, RM, IsExact));
}
opStatus convertToInteger(APSInt &Result, roundingMode RM,
- bool *IsExact) const {
- return getIEEE().convertToInteger(Result, RM, IsExact);
- }
+ bool *IsExact) const;
opStatus convertFromAPInt(const APInt &Input, bool IsSigned,
roundingMode RM) {
- return getIEEE().convertFromAPInt(Input, IsSigned, RM);
+ APFLOAT_DISPATCH_ON_SEMANTICS(convertFromAPInt(Input, IsSigned, RM));
}
opStatus convertFromSignExtendedInteger(const integerPart *Input,
unsigned int InputSize, bool IsSigned,
roundingMode RM) {
- return getIEEE().convertFromSignExtendedInteger(Input, InputSize, IsSigned,
- RM);
+ APFLOAT_DISPATCH_ON_SEMANTICS(
+ convertFromSignExtendedInteger(Input, InputSize, IsSigned, RM));
}
opStatus convertFromZeroExtendedInteger(const integerPart *Input,
unsigned int InputSize, bool IsSigned,
roundingMode RM) {
- return getIEEE().convertFromZeroExtendedInteger(Input, InputSize, IsSigned,
- RM);
+ APFLOAT_DISPATCH_ON_SEMANTICS(
+ convertFromZeroExtendedInteger(Input, InputSize, IsSigned, RM));
}
opStatus convertFromString(StringRef, roundingMode);
- APInt bitcastToAPInt() const { return getIEEE().bitcastToAPInt(); }
+ APInt bitcastToAPInt() const {
+ APFLOAT_DISPATCH_ON_SEMANTICS(bitcastToAPInt());
+ }
double convertToDouble() const { return getIEEE().convertToDouble(); }
float convertToFloat() const { return getIEEE().convertToFloat(); }
bool operator==(const APFloat &) const = delete;
cmpResult compare(const APFloat &RHS) const {
- return getIEEE().compare(RHS.getIEEE());
+ assert(&getSemantics() == &RHS.getSemantics() &&
+ "Should only compare APFloats with the same semantics");
+ if (usesLayout<IEEEFloat>(getSemantics()))
+ return U.IEEE.compare(RHS.U.IEEE);
+ if (usesLayout<DoubleAPFloat>(getSemantics()))
+ return U.Double.compare(RHS.U.Double);
+ llvm_unreachable("Unexpected semantics");
}
bool bitwiseIsEqual(const APFloat &RHS) const {
- return getIEEE().bitwiseIsEqual(RHS.getIEEE());
+ if (&getSemantics() != &RHS.getSemantics())
+ return false;
+ if (usesLayout<IEEEFloat>(getSemantics()))
+ return U.IEEE.bitwiseIsEqual(RHS.U.IEEE);
+ if (usesLayout<DoubleAPFloat>(getSemantics()))
+ return U.Double.bitwiseIsEqual(RHS.U.Double);
+ llvm_unreachable("Unexpected semantics");
}
unsigned int convertToHexString(char *DST, unsigned int HexDigits,
bool UpperCase, roundingMode RM) const {
- return getIEEE().convertToHexString(DST, HexDigits, UpperCase, RM);
+ APFLOAT_DISPATCH_ON_SEMANTICS(
+ convertToHexString(DST, HexDigits, UpperCase, RM));
}
bool isZero() const { return getCategory() == fcZero; }
@@ -1033,7 +1130,7 @@ public:
bool isNaN() const { return getCategory() == fcNaN; }
bool isNegative() const { return getIEEE().isNegative(); }
- bool isDenormal() const { return getIEEE().isDenormal(); }
+ bool isDenormal() const { APFLOAT_DISPATCH_ON_SEMANTICS(isDenormal()); }
bool isSignaling() const { return getIEEE().isSignaling(); }
bool isNormal() const { return !isDenormal() && isFiniteNonZero(); }
@@ -1045,30 +1142,24 @@ public:
bool isFiniteNonZero() const { return isFinite() && !isZero(); }
bool isPosZero() const { return isZero() && !isNegative(); }
bool isNegZero() const { return isZero() && isNegative(); }
- bool isSmallest() const { return getIEEE().isSmallest(); }
- bool isLargest() const { return getIEEE().isLargest(); }
- bool isInteger() const { return getIEEE().isInteger(); }
+ bool isSmallest() const { APFLOAT_DISPATCH_ON_SEMANTICS(isSmallest()); }
+ bool isLargest() const { APFLOAT_DISPATCH_ON_SEMANTICS(isLargest()); }
+ bool isInteger() const { APFLOAT_DISPATCH_ON_SEMANTICS(isInteger()); }
APFloat &operator=(const APFloat &RHS) = default;
APFloat &operator=(APFloat &&RHS) = default;
void toString(SmallVectorImpl<char> &Str, unsigned FormatPrecision = 0,
- unsigned FormatMaxPadding = 3) const {
- return getIEEE().toString(Str, FormatPrecision, FormatMaxPadding);
+ unsigned FormatMaxPadding = 3, bool TruncateZero = true) const {
+ APFLOAT_DISPATCH_ON_SEMANTICS(
+ toString(Str, FormatPrecision, FormatMaxPadding, TruncateZero));
}
void print(raw_ostream &) const;
void dump() const;
bool getExactInverse(APFloat *inv) const {
- return getIEEE().getExactInverse(inv ? &inv->getIEEE() : nullptr);
- }
-
- // This is for internal test only.
- // TODO: Remove it after the PPCDoubleDouble transition.
- const APFloat &getSecondFloat() const {
- assert(&getSemantics() == &PPCDoubleDouble());
- return U.Double.getSecond();
+ APFLOAT_DISPATCH_ON_SEMANTICS(getExactInverse(inv));
}
friend hash_code hash_value(const APFloat &Arg);
@@ -1085,22 +1176,36 @@ public:
/// xlC compiler.
hash_code hash_value(const APFloat &Arg);
inline APFloat scalbn(APFloat X, int Exp, APFloat::roundingMode RM) {
- return APFloat(scalbn(X.getIEEE(), Exp, RM), X.getSemantics());
+ if (APFloat::usesLayout<detail::IEEEFloat>(X.getSemantics()))
+ return APFloat(scalbn(X.U.IEEE, Exp, RM), X.getSemantics());
+ if (APFloat::usesLayout<detail::DoubleAPFloat>(X.getSemantics()))
+ return APFloat(scalbn(X.U.Double, Exp, RM), X.getSemantics());
+ llvm_unreachable("Unexpected semantics");
}
-/// \brief Equivalent of C standard library function.
+/// Equivalent of C standard library function.
///
/// While the C standard says Exp is an unspecified value for infinity and nan,
/// this returns INT_MAX for infinities, and INT_MIN for NaNs.
inline APFloat frexp(const APFloat &X, int &Exp, APFloat::roundingMode RM) {
- return APFloat(frexp(X.getIEEE(), Exp, RM), X.getSemantics());
+ if (APFloat::usesLayout<detail::IEEEFloat>(X.getSemantics()))
+ return APFloat(frexp(X.U.IEEE, Exp, RM), X.getSemantics());
+ if (APFloat::usesLayout<detail::DoubleAPFloat>(X.getSemantics()))
+ return APFloat(frexp(X.U.Double, Exp, RM), X.getSemantics());
+ llvm_unreachable("Unexpected semantics");
}
-/// \brief Returns the absolute value of the argument.
+/// Returns the absolute value of the argument.
inline APFloat abs(APFloat X) {
X.clearSign();
return X;
}
+/// \brief Returns the negated value of the argument.
+inline APFloat neg(APFloat X) {
+ X.changeSign();
+ return X;
+}
+
/// Implements IEEE minNum semantics. Returns the smaller of the 2 arguments if
/// both are not NaN. If either argument is a NaN, returns the other argument.
LLVM_READONLY
@@ -1125,4 +1230,5 @@ inline APFloat maxnum(const APFloat &A, const APFloat &B) {
} // namespace llvm
+#undef APFLOAT_DISPATCH_ON_SEMANTICS
#endif // LLVM_ADT_APFLOAT_H
diff --git a/contrib/llvm/include/llvm/ADT/APInt.h b/contrib/llvm/include/llvm/ADT/APInt.h
index 2c0713d..a1cce6e 100644
--- a/contrib/llvm/include/llvm/ADT/APInt.h
+++ b/contrib/llvm/include/llvm/ADT/APInt.h
@@ -32,14 +32,6 @@ class raw_ostream;
template <typename T> class SmallVectorImpl;
template <typename T> class ArrayRef;
-// An unsigned host type used as a single part of a multi-part
-// bignum.
-typedef uint64_t integerPart;
-
-const unsigned int host_char_bit = 8;
-const unsigned int integerPartWidth =
- host_char_bit * static_cast<unsigned int>(sizeof(integerPart));
-
class APInt;
inline APInt operator-(APInt);
@@ -75,31 +67,40 @@ inline APInt operator-(APInt);
/// uses in its IR. This simplifies its use for LLVM.
///
class LLVM_NODISCARD APInt {
- unsigned BitWidth; ///< The number of bits in this APInt.
+public:
+ typedef uint64_t WordType;
+
+ /// This enum is used to hold the constants we needed for APInt.
+ enum : unsigned {
+ /// Byte size of a word.
+ APINT_WORD_SIZE = sizeof(WordType),
+ /// Bits in a word.
+ APINT_BITS_PER_WORD = APINT_WORD_SIZE * CHAR_BIT
+ };
+
+ static const WordType WORD_MAX = ~WordType(0);
+private:
/// This union is used to store the integer value. When the
/// integer bit-width <= 64, it uses VAL, otherwise it uses pVal.
union {
uint64_t VAL; ///< Used to store the <= 64 bits integer value.
uint64_t *pVal; ///< Used to store the >64 bits integer value.
- };
+ } U;
- /// This enum is used to hold the constants we needed for APInt.
- enum {
- /// Bits in a word
- APINT_BITS_PER_WORD =
- static_cast<unsigned int>(sizeof(uint64_t)) * CHAR_BIT,
- /// Byte size of a word
- APINT_WORD_SIZE = static_cast<unsigned int>(sizeof(uint64_t))
- };
+ unsigned BitWidth; ///< The number of bits in this APInt.
friend struct DenseMapAPIntKeyInfo;
+ friend class APSInt;
+
/// \brief Fast internal constructor
///
/// This constructor is used only internally for speed of construction of
/// temporaries. It is unsafe for general use so it is not public.
- APInt(uint64_t *val, unsigned bits) : BitWidth(bits), pVal(val) {}
+ APInt(uint64_t *val, unsigned bits) : BitWidth(bits) {
+ U.pVal = val;
+ }
/// \brief Determine if this APInt just has one word to store value.
///
@@ -139,28 +140,28 @@ class LLVM_NODISCARD APInt {
/// zero'd out.
APInt &clearUnusedBits() {
// Compute how many bits are used in the final word
- unsigned wordBits = BitWidth % APINT_BITS_PER_WORD;
- if (wordBits == 0)
- // If all bits are used, we want to leave the value alone. This also
- // avoids the undefined behavior of >> when the shift is the same size as
- // the word size (64).
- return *this;
+ unsigned WordBits = ((BitWidth-1) % APINT_BITS_PER_WORD) + 1;
// Mask out the high bits.
- uint64_t mask = ~uint64_t(0ULL) >> (APINT_BITS_PER_WORD - wordBits);
+ uint64_t mask = WORD_MAX >> (APINT_BITS_PER_WORD - WordBits);
if (isSingleWord())
- VAL &= mask;
+ U.VAL &= mask;
else
- pVal[getNumWords() - 1] &= mask;
+ U.pVal[getNumWords() - 1] &= mask;
return *this;
}
/// \brief Get the word corresponding to a bit position
/// \returns the corresponding word for the specified bit position.
uint64_t getWord(unsigned bitPosition) const {
- return isSingleWord() ? VAL : pVal[whichWord(bitPosition)];
+ return isSingleWord() ? U.VAL : U.pVal[whichWord(bitPosition)];
}
+ /// Utility method to change the bit width of this APInt to new bit width,
+ /// allocating and/or deallocating as necessary. There is no guarantee on the
+ /// value of any bits upon return. Caller should populate the bits after.
+ void reallocate(unsigned NewBitWidth);
+
/// \brief Convert a char array into an APInt
///
/// \param radix 2, 8, 10, 16, or 36
@@ -181,8 +182,9 @@ class LLVM_NODISCARD APInt {
/// provides a more convenient form of divide for internal use since KnuthDiv
/// has specific constraints on its inputs. If those constraints are not met
/// then it provides a simpler form of divide.
- static void divide(const APInt &LHS, unsigned lhsWords, const APInt &RHS,
- unsigned rhsWords, APInt *Quotient, APInt *Remainder);
+ static void divide(const WordType *LHS, unsigned lhsWords,
+ const WordType *RHS, unsigned rhsWords, WordType *Quotient,
+ WordType *Remainder);
/// out-of-line slow case for inline constructor
void initSlowCase(uint64_t val, bool isSigned);
@@ -194,34 +196,63 @@ class LLVM_NODISCARD APInt {
void initSlowCase(const APInt &that);
/// out-of-line slow case for shl
- APInt shlSlowCase(unsigned shiftAmt) const;
-
- /// out-of-line slow case for operator&
- APInt AndSlowCase(const APInt &RHS) const;
+ void shlSlowCase(unsigned ShiftAmt);
- /// out-of-line slow case for operator|
- APInt OrSlowCase(const APInt &RHS) const;
+ /// out-of-line slow case for lshr.
+ void lshrSlowCase(unsigned ShiftAmt);
- /// out-of-line slow case for operator^
- APInt XorSlowCase(const APInt &RHS) const;
+ /// out-of-line slow case for ashr.
+ void ashrSlowCase(unsigned ShiftAmt);
/// out-of-line slow case for operator=
- APInt &AssignSlowCase(const APInt &RHS);
+ void AssignSlowCase(const APInt &RHS);
/// out-of-line slow case for operator==
- bool EqualSlowCase(const APInt &RHS) const;
-
- /// out-of-line slow case for operator==
- bool EqualSlowCase(uint64_t Val) const;
+ bool EqualSlowCase(const APInt &RHS) const LLVM_READONLY;
/// out-of-line slow case for countLeadingZeros
- unsigned countLeadingZerosSlowCase() const;
+ unsigned countLeadingZerosSlowCase() const LLVM_READONLY;
+
+ /// out-of-line slow case for countLeadingOnes.
+ unsigned countLeadingOnesSlowCase() const LLVM_READONLY;
+
+ /// out-of-line slow case for countTrailingZeros.
+ unsigned countTrailingZerosSlowCase() const LLVM_READONLY;
/// out-of-line slow case for countTrailingOnes
- unsigned countTrailingOnesSlowCase() const;
+ unsigned countTrailingOnesSlowCase() const LLVM_READONLY;
/// out-of-line slow case for countPopulation
- unsigned countPopulationSlowCase() const;
+ unsigned countPopulationSlowCase() const LLVM_READONLY;
+
+ /// out-of-line slow case for intersects.
+ bool intersectsSlowCase(const APInt &RHS) const LLVM_READONLY;
+
+ /// out-of-line slow case for isSubsetOf.
+ bool isSubsetOfSlowCase(const APInt &RHS) const LLVM_READONLY;
+
+ /// out-of-line slow case for setBits.
+ void setBitsSlowCase(unsigned loBit, unsigned hiBit);
+
+ /// out-of-line slow case for flipAllBits.
+ void flipAllBitsSlowCase();
+
+ /// out-of-line slow case for operator&=.
+ void AndAssignSlowCase(const APInt& RHS);
+
+ /// out-of-line slow case for operator|=.
+ void OrAssignSlowCase(const APInt& RHS);
+
+ /// out-of-line slow case for operator^=.
+ void XorAssignSlowCase(const APInt& RHS);
+
+ /// Unsigned comparison. Returns -1, 0, or 1 if this APInt is less than, equal
+ /// to, or greater than RHS.
+ int compare(const APInt &RHS) const LLVM_READONLY;
+
+ /// Signed comparison. Returns -1, 0, or 1 if this APInt is less than, equal
+ /// to, or greater than RHS.
+ int compareSigned(const APInt &RHS) const LLVM_READONLY;
public:
/// \name Constructors
@@ -238,13 +269,14 @@ public:
/// \param val the initial value of the APInt
/// \param isSigned how to treat signedness of val
APInt(unsigned numBits, uint64_t val, bool isSigned = false)
- : BitWidth(numBits), VAL(0) {
+ : BitWidth(numBits) {
assert(BitWidth && "bitwidth too small");
- if (isSingleWord())
- VAL = val;
- else
+ if (isSingleWord()) {
+ U.VAL = val;
+ clearUnusedBits();
+ } else {
initSlowCase(val, isSigned);
- clearUnusedBits();
+ }
}
/// \brief Construct an APInt of numBits width, initialized as bigVal[].
@@ -280,22 +312,23 @@ public:
/// Simply makes *this a copy of that.
/// @brief Copy Constructor.
- APInt(const APInt &that) : BitWidth(that.BitWidth), VAL(0) {
+ APInt(const APInt &that) : BitWidth(that.BitWidth) {
if (isSingleWord())
- VAL = that.VAL;
+ U.VAL = that.U.VAL;
else
initSlowCase(that);
}
/// \brief Move Constructor.
- APInt(APInt &&that) : BitWidth(that.BitWidth), VAL(that.VAL) {
+ APInt(APInt &&that) : BitWidth(that.BitWidth) {
+ memcpy(&U, &that.U, sizeof(U));
that.BitWidth = 0;
}
/// \brief Destructor.
~APInt() {
if (needsCleanup())
- delete[] pVal;
+ delete[] U.pVal;
}
/// \brief Default constructor that creates an uninteresting APInt
@@ -303,7 +336,7 @@ public:
///
/// This is useful for object deserialization (pair this with the static
/// method Read).
- explicit APInt() : BitWidth(1), VAL(0) {}
+ explicit APInt() : BitWidth(1) { U.VAL = 0; }
/// \brief Returns whether this instance allocated memory.
bool needsCleanup() const { return !isSingleWord(); }
@@ -328,21 +361,50 @@ public:
/// This tests the high bit of the APInt to determine if it is unset.
bool isNonNegative() const { return !isNegative(); }
+ /// \brief Determine if sign bit of this APInt is set.
+ ///
+ /// This tests the high bit of this APInt to determine if it is set.
+ ///
+ /// \returns true if this APInt has its sign bit set, false otherwise.
+ bool isSignBitSet() const { return (*this)[BitWidth-1]; }
+
+ /// \brief Determine if sign bit of this APInt is clear.
+ ///
+ /// This tests the high bit of this APInt to determine if it is clear.
+ ///
+ /// \returns true if this APInt has its sign bit clear, false otherwise.
+ bool isSignBitClear() const { return !isSignBitSet(); }
+
/// \brief Determine if this APInt Value is positive.
///
/// This tests if the value of this APInt is positive (> 0). Note
/// that 0 is not a positive value.
///
/// \returns true if this APInt is positive.
- bool isStrictlyPositive() const { return isNonNegative() && !!*this; }
+ bool isStrictlyPositive() const { return isNonNegative() && !isNullValue(); }
/// \brief Determine if all bits are set
///
/// This checks to see if the value has all bits of the APInt are set or not.
bool isAllOnesValue() const {
if (isSingleWord())
- return VAL == ~integerPart(0) >> (APINT_BITS_PER_WORD - BitWidth);
- return countPopulationSlowCase() == BitWidth;
+ return U.VAL == WORD_MAX >> (APINT_BITS_PER_WORD - BitWidth);
+ return countTrailingOnesSlowCase() == BitWidth;
+ }
+
+ /// \brief Determine if all bits are clear
+ ///
+ /// This checks to see if the value has all bits of the APInt are clear or
+ /// not.
+ bool isNullValue() const { return !*this; }
+
+ /// \brief Determine if this is a value of 1.
+ ///
+ /// This checks to see if the value of this APInt is one.
+ bool isOneValue() const {
+ if (isSingleWord())
+ return U.VAL == 1;
+ return countLeadingZerosSlowCase() == BitWidth - 1;
}
/// \brief Determine if this is the largest unsigned value.
@@ -356,21 +418,25 @@ public:
/// This checks to see if the value of this APInt is the maximum signed
/// value for the APInt's bit width.
bool isMaxSignedValue() const {
- return !isNegative() && countPopulation() == BitWidth - 1;
+ if (isSingleWord())
+ return U.VAL == ((WordType(1) << (BitWidth - 1)) - 1);
+ return !isNegative() && countTrailingOnesSlowCase() == BitWidth - 1;
}
/// \brief Determine if this is the smallest unsigned value.
///
/// This checks to see if the value of this APInt is the minimum unsigned
/// value for the APInt's bit width.
- bool isMinValue() const { return !*this; }
+ bool isMinValue() const { return isNullValue(); }
/// \brief Determine if this is the smallest signed value.
///
/// This checks to see if the value of this APInt is the minimum signed
/// value for the APInt's bit width.
bool isMinSignedValue() const {
- return isNegative() && isPowerOf2();
+ if (isSingleWord())
+ return U.VAL == (WordType(1) << (BitWidth - 1));
+ return isNegative() && countTrailingZerosSlowCase() == BitWidth - 1;
}
/// \brief Check if this APInt has an N-bits unsigned integer value.
@@ -390,14 +456,14 @@ public:
/// \returns true if the argument APInt value is a power of two > 0.
bool isPowerOf2() const {
if (isSingleWord())
- return isPowerOf2_64(VAL);
+ return isPowerOf2_64(U.VAL);
return countPopulationSlowCase() == 1;
}
- /// \brief Check if the APInt's value is returned by getSignBit.
+ /// \brief Check if the APInt's value is returned by getSignMask.
///
- /// \returns true if this is the value returned by getSignBit.
- bool isSignBit() const { return isMinSignedValue(); }
+ /// \returns true if this is the value returned by getSignMask.
+ bool isSignMask() const { return isMinSignedValue(); }
/// \brief Convert APInt to a boolean value.
///
@@ -406,9 +472,8 @@ public:
/// If this value is smaller than the specified limit, return it, otherwise
/// return the limit value. This causes the value to saturate to the limit.
- uint64_t getLimitedValue(uint64_t Limit = ~0ULL) const {
- return (getActiveBits() > 64 || getZExtValue() > Limit) ? Limit
- : getZExtValue();
+ uint64_t getLimitedValue(uint64_t Limit = UINT64_MAX) const {
+ return ugt(Limit) ? Limit : getZExtValue();
}
/// \brief Check if the APInt consists of a repeated bit pattern.
@@ -418,6 +483,38 @@ public:
/// width without remainder.
bool isSplat(unsigned SplatSizeInBits) const;
+ /// \returns true if this APInt value is a sequence of \param numBits ones
+ /// starting at the least significant bit with the remainder zero.
+ bool isMask(unsigned numBits) const {
+ assert(numBits != 0 && "numBits must be non-zero");
+ assert(numBits <= BitWidth && "numBits out of range");
+ if (isSingleWord())
+ return U.VAL == (WORD_MAX >> (APINT_BITS_PER_WORD - numBits));
+ unsigned Ones = countTrailingOnesSlowCase();
+ return (numBits == Ones) &&
+ ((Ones + countLeadingZerosSlowCase()) == BitWidth);
+ }
+
+ /// \returns true if this APInt is a non-empty sequence of ones starting at
+ /// the least significant bit with the remainder zero.
+ /// Ex. isMask(0x0000FFFFU) == true.
+ bool isMask() const {
+ if (isSingleWord())
+ return isMask_64(U.VAL);
+ unsigned Ones = countTrailingOnesSlowCase();
+ return (Ones > 0) && ((Ones + countLeadingZerosSlowCase()) == BitWidth);
+ }
+
+ /// \brief Return true if this APInt value contains a sequence of ones with
+ /// the remainder zero.
+ bool isShiftedMask() const {
+ if (isSingleWord())
+ return isShiftedMask_64(U.VAL);
+ unsigned Ones = countPopulationSlowCase();
+ unsigned LeadZ = countLeadingZerosSlowCase();
+ return (Ones + LeadZ + countTrailingZeros()) == BitWidth;
+ }
+
/// @}
/// \name Value Generators
/// @{
@@ -444,11 +541,11 @@ public:
return API;
}
- /// \brief Get the SignBit for a specific bit width.
+ /// \brief Get the SignMask for a specific bit width.
///
/// This is just a wrapper function of getSignedMinValue(), and it helps code
- /// readability when we want to get a SignBit.
- static APInt getSignBit(unsigned BitWidth) {
+ /// readability when we want to get a SignMask.
+ static APInt getSignMask(unsigned BitWidth) {
return getSignedMinValue(BitWidth);
}
@@ -456,7 +553,7 @@ public:
///
/// \returns the all-ones value for an APInt of the specified bit-width.
static APInt getAllOnesValue(unsigned numBits) {
- return APInt(numBits, UINT64_MAX, true);
+ return APInt(numBits, WORD_MAX, true);
}
/// \brief Get the '0' value.
@@ -501,12 +598,26 @@ public:
///
/// \returns An APInt value with the requested bits set.
static APInt getBitsSet(unsigned numBits, unsigned loBit, unsigned hiBit) {
- assert(hiBit <= numBits && "hiBit out of range");
- assert(loBit < numBits && "loBit out of range");
- if (hiBit < loBit)
- return getLowBitsSet(numBits, hiBit) |
- getHighBitsSet(numBits, numBits - loBit);
- return getLowBitsSet(numBits, hiBit - loBit).shl(loBit);
+ APInt Res(numBits, 0);
+ Res.setBits(loBit, hiBit);
+ return Res;
+ }
+
+ /// \brief Get a value with upper bits starting at loBit set.
+ ///
+ /// Constructs an APInt value that has a contiguous range of bits set. The
+ /// bits from loBit (inclusive) to numBits (exclusive) will be set. All other
+ /// bits will be zero. For example, with parameters(32, 12) you would get
+ /// 0xFFFFF000.
+ ///
+ /// \param numBits the intended bit width of the result
+ /// \param loBit the index of the lowest bit to set.
+ ///
+ /// \returns An APInt value with the requested bits set.
+ static APInt getBitsSetFrom(unsigned numBits, unsigned loBit) {
+ APInt Res(numBits, 0);
+ Res.setBitsFrom(loBit);
+ return Res;
}
/// \brief Get a value with high bits set
@@ -516,15 +627,9 @@ public:
/// \param numBits the bitwidth of the result
/// \param hiBitsSet the number of high-order bits set in the result.
static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet) {
- assert(hiBitsSet <= numBits && "Too many bits to set!");
- // Handle a degenerate case, to avoid shifting by word size
- if (hiBitsSet == 0)
- return APInt(numBits, 0);
- unsigned shiftAmt = numBits - hiBitsSet;
- // For small values, return quickly
- if (numBits <= APINT_BITS_PER_WORD)
- return APInt(numBits, ~0ULL << shiftAmt);
- return getAllOnesValue(numBits).shl(shiftAmt);
+ APInt Res(numBits, 0);
+ Res.setHighBits(hiBitsSet);
+ return Res;
}
/// \brief Get a value with low bits set
@@ -534,28 +639,13 @@ public:
/// \param numBits the bitwidth of the result
/// \param loBitsSet the number of low-order bits set in the result.
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet) {
- assert(loBitsSet <= numBits && "Too many bits to set!");
- // Handle a degenerate case, to avoid shifting by word size
- if (loBitsSet == 0)
- return APInt(numBits, 0);
- if (loBitsSet == APINT_BITS_PER_WORD)
- return APInt(numBits, UINT64_MAX);
- // For small values, return quickly.
- if (loBitsSet <= APINT_BITS_PER_WORD)
- return APInt(numBits, UINT64_MAX >> (APINT_BITS_PER_WORD - loBitsSet));
- return getAllOnesValue(numBits).lshr(numBits - loBitsSet);
+ APInt Res(numBits, 0);
+ Res.setLowBits(loBitsSet);
+ return Res;
}
/// \brief Return a value containing V broadcasted over NewLen bits.
- static APInt getSplat(unsigned NewLen, const APInt &V) {
- assert(NewLen >= V.getBitWidth() && "Can't splat to smaller bit width!");
-
- APInt Val = V.zextOrSelf(NewLen);
- for (unsigned I = V.getBitWidth(); I < NewLen; I <<= 1)
- Val |= Val << I;
-
- return Val;
- }
+ static APInt getSplat(unsigned NewLen, const APInt &V);
/// \brief Determine if two APInts have the same value, after zero-extending
/// one of them (if needed!) to ensure that the bit-widths match.
@@ -577,8 +667,8 @@ public:
/// conversions.
const uint64_t *getRawData() const {
if (isSingleWord())
- return &VAL;
- return &pVal[0];
+ return &U.VAL;
+ return &U.pVal[0];
}
/// @}
@@ -587,7 +677,9 @@ public:
/// \brief Postfix increment operator.
///
- /// \returns a new APInt value representing *this incremented by one
+ /// Increments *this by 1.
+ ///
+ /// \returns a new APInt value representing the original value of *this.
const APInt operator++(int) {
APInt API(*this);
++(*this);
@@ -601,7 +693,9 @@ public:
/// \brief Postfix decrement operator.
///
- /// \returns a new APInt representing *this decremented by one.
+ /// Decrements *this by 1.
+ ///
+ /// \returns a new APInt value representing the original value of *this.
const APInt operator--(int) {
APInt API(*this);
--(*this);
@@ -613,17 +707,6 @@ public:
/// \returns *this decremented by one.
APInt &operator--();
- /// \brief Unary bitwise complement operator.
- ///
- /// Performs a bitwise complement operation on this APInt.
- ///
- /// \returns an APInt that is the bitwise complement of *this
- APInt operator~() const {
- APInt Result(*this);
- Result.flipAllBits();
- return Result;
- }
-
/// \brief Logical negation operator.
///
/// Performs logical negation operation on this APInt.
@@ -631,12 +714,8 @@ public:
/// \returns true if *this is zero, false otherwise.
bool operator!() const {
if (isSingleWord())
- return !VAL;
-
- for (unsigned i = 0; i != getNumWords(); ++i)
- if (pVal[i])
- return false;
- return true;
+ return U.VAL == 0;
+ return countLeadingZerosSlowCase() == BitWidth;
}
/// @}
@@ -649,34 +728,27 @@ public:
APInt &operator=(const APInt &RHS) {
// If the bitwidths are the same, we can avoid mucking with memory
if (isSingleWord() && RHS.isSingleWord()) {
- VAL = RHS.VAL;
+ U.VAL = RHS.U.VAL;
BitWidth = RHS.BitWidth;
return clearUnusedBits();
}
- return AssignSlowCase(RHS);
+ AssignSlowCase(RHS);
+ return *this;
}
/// @brief Move assignment operator.
APInt &operator=(APInt &&that) {
- if (!isSingleWord()) {
- // The MSVC STL shipped in 2013 requires that self move assignment be a
- // no-op. Otherwise algorithms like stable_sort will produce answers
- // where half of the output is left in a moved-from state.
- if (this == &that)
- return *this;
- delete[] pVal;
- }
+ assert(this != &that && "Self-move not supported");
+ if (!isSingleWord())
+ delete[] U.pVal;
// Use memcpy so that type based alias analysis sees both VAL and pVal
// as modified.
- memcpy(&VAL, &that.VAL, sizeof(uint64_t));
+ memcpy(&U, &that.U, sizeof(U));
- // If 'this == &that', avoid zeroing our own bitwidth by storing to 'that'
- // first.
- unsigned ThatBitWidth = that.BitWidth;
+ BitWidth = that.BitWidth;
that.BitWidth = 0;
- BitWidth = ThatBitWidth;
return *this;
}
@@ -688,7 +760,16 @@ public:
/// than 64, the value is zero filled in the unspecified high order bits.
///
/// \returns *this after assignment of RHS value.
- APInt &operator=(uint64_t RHS);
+ APInt &operator=(uint64_t RHS) {
+ if (isSingleWord()) {
+ U.VAL = RHS;
+ clearUnusedBits();
+ } else {
+ U.pVal[0] = RHS;
+ memset(U.pVal+1, 0, (getNumWords() - 1) * APINT_WORD_SIZE);
+ }
+ return *this;
+ }
/// \brief Bitwise AND assignment operator.
///
@@ -696,7 +777,29 @@ public:
/// assigned to *this.
///
/// \returns *this after ANDing with RHS.
- APInt &operator&=(const APInt &RHS);
+ APInt &operator&=(const APInt &RHS) {
+ assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
+ if (isSingleWord())
+ U.VAL &= RHS.U.VAL;
+ else
+ AndAssignSlowCase(RHS);
+ return *this;
+ }
+
+ /// \brief Bitwise AND assignment operator.
+ ///
+ /// Performs a bitwise AND operation on this APInt and RHS. RHS is
+ /// logically zero-extended or truncated to match the bit-width of
+ /// the LHS.
+ APInt &operator&=(uint64_t RHS) {
+ if (isSingleWord()) {
+ U.VAL &= RHS;
+ return *this;
+ }
+ U.pVal[0] &= RHS;
+ memset(U.pVal+1, 0, (getNumWords() - 1) * APINT_WORD_SIZE);
+ return *this;
+ }
/// \brief Bitwise OR assignment operator.
///
@@ -704,7 +807,14 @@ public:
/// assigned *this;
///
/// \returns *this after ORing with RHS.
- APInt &operator|=(const APInt &RHS);
+ APInt &operator|=(const APInt &RHS) {
+ assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
+ if (isSingleWord())
+ U.VAL |= RHS.U.VAL;
+ else
+ OrAssignSlowCase(RHS);
+ return *this;
+ }
/// \brief Bitwise OR assignment operator.
///
@@ -713,10 +823,10 @@ public:
/// the LHS.
APInt &operator|=(uint64_t RHS) {
if (isSingleWord()) {
- VAL |= RHS;
+ U.VAL |= RHS;
clearUnusedBits();
} else {
- pVal[0] |= RHS;
+ U.pVal[0] |= RHS;
}
return *this;
}
@@ -727,7 +837,29 @@ public:
/// assigned to *this.
///
/// \returns *this after XORing with RHS.
- APInt &operator^=(const APInt &RHS);
+ APInt &operator^=(const APInt &RHS) {
+ assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
+ if (isSingleWord())
+ U.VAL ^= RHS.U.VAL;
+ else
+ XorAssignSlowCase(RHS);
+ return *this;
+ }
+
+ /// \brief Bitwise XOR assignment operator.
+ ///
+ /// Performs a bitwise XOR operation on this APInt and RHS. RHS is
+ /// logically zero-extended or truncated to match the bit-width of
+ /// the LHS.
+ APInt &operator^=(uint64_t RHS) {
+ if (isSingleWord()) {
+ U.VAL ^= RHS;
+ clearUnusedBits();
+ } else {
+ U.pVal[0] ^= RHS;
+ }
+ return *this;
+ }
/// \brief Multiplication assignment operator.
///
@@ -735,6 +867,7 @@ public:
///
/// \returns *this
APInt &operator*=(const APInt &RHS);
+ APInt &operator*=(uint64_t RHS);
/// \brief Addition assignment operator.
///
@@ -756,68 +889,30 @@ public:
///
/// Shifts *this left by shiftAmt and assigns the result to *this.
///
- /// \returns *this after shifting left by shiftAmt
- APInt &operator<<=(unsigned shiftAmt) {
- *this = shl(shiftAmt);
+ /// \returns *this after shifting left by ShiftAmt
+ APInt &operator<<=(unsigned ShiftAmt) {
+ assert(ShiftAmt <= BitWidth && "Invalid shift amount");
+ if (isSingleWord()) {
+ if (ShiftAmt == BitWidth)
+ U.VAL = 0;
+ else
+ U.VAL <<= ShiftAmt;
+ return clearUnusedBits();
+ }
+ shlSlowCase(ShiftAmt);
return *this;
}
- /// @}
- /// \name Binary Operators
- /// @{
-
- /// \brief Bitwise AND operator.
- ///
- /// Performs a bitwise AND operation on *this and RHS.
- ///
- /// \returns An APInt value representing the bitwise AND of *this and RHS.
- APInt operator&(const APInt &RHS) const {
- assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
- if (isSingleWord())
- return APInt(getBitWidth(), VAL & RHS.VAL);
- return AndSlowCase(RHS);
- }
- APInt And(const APInt &RHS) const { return this->operator&(RHS); }
-
- /// \brief Bitwise OR operator.
- ///
- /// Performs a bitwise OR operation on *this and RHS.
- ///
- /// \returns An APInt value representing the bitwise OR of *this and RHS.
- APInt operator|(const APInt &RHS) const {
- assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
- if (isSingleWord())
- return APInt(getBitWidth(), VAL | RHS.VAL);
- return OrSlowCase(RHS);
- }
-
- /// \brief Bitwise OR function.
+ /// \brief Left-shift assignment function.
///
- /// Performs a bitwise or on *this and RHS. This is implemented by simply
- /// calling operator|.
+ /// Shifts *this left by shiftAmt and assigns the result to *this.
///
- /// \returns An APInt value representing the bitwise OR of *this and RHS.
- APInt Or(const APInt &RHS) const { return this->operator|(RHS); }
+ /// \returns *this after shifting left by ShiftAmt
+ APInt &operator<<=(const APInt &ShiftAmt);
- /// \brief Bitwise XOR operator.
- ///
- /// Performs a bitwise XOR operation on *this and RHS.
- ///
- /// \returns An APInt value representing the bitwise XOR of *this and RHS.
- APInt operator^(const APInt &RHS) const {
- assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
- if (isSingleWord())
- return APInt(BitWidth, VAL ^ RHS.VAL);
- return XorSlowCase(RHS);
- }
-
- /// \brief Bitwise XOR function.
- ///
- /// Performs a bitwise XOR operation on *this and RHS. This is implemented
- /// through the usage of operator^.
- ///
- /// \returns An APInt value representing the bitwise XOR of *this and RHS.
- APInt Xor(const APInt &RHS) const { return this->operator^(RHS); }
+ /// @}
+ /// \name Binary Operators
+ /// @{
/// \brief Multiplication operator.
///
@@ -837,24 +932,56 @@ public:
/// \brief Arithmetic right-shift function.
///
/// Arithmetic right-shift this APInt by shiftAmt.
- APInt ashr(unsigned shiftAmt) const;
+ APInt ashr(unsigned ShiftAmt) const {
+ APInt R(*this);
+ R.ashrInPlace(ShiftAmt);
+ return R;
+ }
+
+ /// Arithmetic right-shift this APInt by ShiftAmt in place.
+ void ashrInPlace(unsigned ShiftAmt) {
+ assert(ShiftAmt <= BitWidth && "Invalid shift amount");
+ if (isSingleWord()) {
+ int64_t SExtVAL = SignExtend64(U.VAL, BitWidth);
+ if (ShiftAmt == BitWidth)
+ U.VAL = SExtVAL >> (APINT_BITS_PER_WORD - 1); // Fill with sign bit.
+ else
+ U.VAL = SExtVAL >> ShiftAmt;
+ clearUnusedBits();
+ return;
+ }
+ ashrSlowCase(ShiftAmt);
+ }
/// \brief Logical right-shift function.
///
/// Logical right-shift this APInt by shiftAmt.
- APInt lshr(unsigned shiftAmt) const;
+ APInt lshr(unsigned shiftAmt) const {
+ APInt R(*this);
+ R.lshrInPlace(shiftAmt);
+ return R;
+ }
+
+ /// Logical right-shift this APInt by ShiftAmt in place.
+ void lshrInPlace(unsigned ShiftAmt) {
+ assert(ShiftAmt <= BitWidth && "Invalid shift amount");
+ if (isSingleWord()) {
+ if (ShiftAmt == BitWidth)
+ U.VAL = 0;
+ else
+ U.VAL >>= ShiftAmt;
+ return;
+ }
+ lshrSlowCase(ShiftAmt);
+ }
/// \brief Left-shift function.
///
/// Left-shift this APInt by shiftAmt.
APInt shl(unsigned shiftAmt) const {
- assert(shiftAmt <= BitWidth && "Invalid shift amount");
- if (isSingleWord()) {
- if (shiftAmt >= BitWidth)
- return APInt(BitWidth, 0); // avoid undefined shift results
- return APInt(BitWidth, VAL << shiftAmt);
- }
- return shlSlowCase(shiftAmt);
+ APInt R(*this);
+ R <<= shiftAmt;
+ return R;
}
/// \brief Rotate left by rotateAmt.
@@ -866,17 +993,35 @@ public:
/// \brief Arithmetic right-shift function.
///
/// Arithmetic right-shift this APInt by shiftAmt.
- APInt ashr(const APInt &shiftAmt) const;
+ APInt ashr(const APInt &ShiftAmt) const {
+ APInt R(*this);
+ R.ashrInPlace(ShiftAmt);
+ return R;
+ }
+
+ /// Arithmetic right-shift this APInt by shiftAmt in place.
+ void ashrInPlace(const APInt &shiftAmt);
/// \brief Logical right-shift function.
///
/// Logical right-shift this APInt by shiftAmt.
- APInt lshr(const APInt &shiftAmt) const;
+ APInt lshr(const APInt &ShiftAmt) const {
+ APInt R(*this);
+ R.lshrInPlace(ShiftAmt);
+ return R;
+ }
+
+ /// Logical right-shift this APInt by ShiftAmt in place.
+ void lshrInPlace(const APInt &ShiftAmt);
/// \brief Left-shift function.
///
/// Left-shift this APInt by shiftAmt.
- APInt shl(const APInt &shiftAmt) const;
+ APInt shl(const APInt &ShiftAmt) const {
+ APInt R(*this);
+ R <<= ShiftAmt;
+ return R;
+ }
/// \brief Rotate left by rotateAmt.
APInt rotl(const APInt &rotateAmt) const;
@@ -891,11 +1036,13 @@ public:
///
/// \returns a new APInt value containing the division result
APInt udiv(const APInt &RHS) const;
+ APInt udiv(uint64_t RHS) const;
/// \brief Signed division function for APInt.
///
/// Signed divide this APInt by APInt RHS.
APInt sdiv(const APInt &RHS) const;
+ APInt sdiv(int64_t RHS) const;
/// \brief Unsigned remainder operation.
///
@@ -907,11 +1054,13 @@ public:
///
/// \returns a new APInt value containing the remainder result
APInt urem(const APInt &RHS) const;
+ uint64_t urem(uint64_t RHS) const;
/// \brief Function for signed remainder operation.
///
/// Signed remainder operation on APInt.
APInt srem(const APInt &RHS) const;
+ int64_t srem(int64_t RHS) const;
/// \brief Dual division/remainder interface.
///
@@ -922,9 +1071,13 @@ public:
/// udivrem(X, Y, X, Y), for example.
static void udivrem(const APInt &LHS, const APInt &RHS, APInt &Quotient,
APInt &Remainder);
+ static void udivrem(const APInt &LHS, uint64_t RHS, APInt &Quotient,
+ uint64_t &Remainder);
static void sdivrem(const APInt &LHS, const APInt &RHS, APInt &Quotient,
APInt &Remainder);
+ static void sdivrem(const APInt &LHS, int64_t RHS, APInt &Quotient,
+ int64_t &Remainder);
// Operations that return overflow indicators.
APInt sadd_ov(const APInt &RHS, bool &Overflow) const;
@@ -942,9 +1095,7 @@ public:
/// \returns the bit value at bitPosition
bool operator[](unsigned bitPosition) const {
assert(bitPosition < getBitWidth() && "Bit position out of bounds!");
- return (maskBit(bitPosition) &
- (isSingleWord() ? VAL : pVal[whichWord(bitPosition)])) !=
- 0;
+ return (maskBit(bitPosition) & getWord(bitPosition)) != 0;
}
/// @}
@@ -958,7 +1109,7 @@ public:
bool operator==(const APInt &RHS) const {
assert(BitWidth == RHS.BitWidth && "Comparison requires equal bit widths");
if (isSingleWord())
- return VAL == RHS.VAL;
+ return U.VAL == RHS.U.VAL;
return EqualSlowCase(RHS);
}
@@ -969,9 +1120,7 @@ public:
///
/// \returns true if *this == Val
bool operator==(uint64_t Val) const {
- if (isSingleWord())
- return VAL == Val;
- return EqualSlowCase(Val);
+ return (isSingleWord() || getActiveBits() <= 64) && getZExtValue() == Val;
}
/// \brief Equality comparison.
@@ -1012,7 +1161,7 @@ public:
/// the validity of the less-than relationship.
///
/// \returns true if *this < RHS when both are considered unsigned.
- bool ult(const APInt &RHS) const;
+ bool ult(const APInt &RHS) const { return compare(RHS) < 0; }
/// \brief Unsigned less than comparison
///
@@ -1021,7 +1170,8 @@ public:
///
/// \returns true if *this < RHS when considered unsigned.
bool ult(uint64_t RHS) const {
- return getActiveBits() > 64 ? false : getZExtValue() < RHS;
+ // Only need to check active bits if not a single word.
+ return (isSingleWord() || getActiveBits() <= 64) && getZExtValue() < RHS;
}
/// \brief Signed less than comparison
@@ -1030,7 +1180,7 @@ public:
/// validity of the less-than relationship.
///
/// \returns true if *this < RHS when both are considered signed.
- bool slt(const APInt &RHS) const;
+ bool slt(const APInt &RHS) const { return compareSigned(RHS) < 0; }
/// \brief Signed less than comparison
///
@@ -1039,7 +1189,8 @@ public:
///
/// \returns true if *this < RHS when considered signed.
bool slt(int64_t RHS) const {
- return getMinSignedBits() > 64 ? isNegative() : getSExtValue() < RHS;
+ return (!isSingleWord() && getMinSignedBits() > 64) ? isNegative()
+ : getSExtValue() < RHS;
}
/// \brief Unsigned less or equal comparison
@@ -1048,7 +1199,7 @@ public:
/// validity of the less-or-equal relationship.
///
/// \returns true if *this <= RHS when both are considered unsigned.
- bool ule(const APInt &RHS) const { return ult(RHS) || eq(RHS); }
+ bool ule(const APInt &RHS) const { return compare(RHS) <= 0; }
/// \brief Unsigned less or equal comparison
///
@@ -1064,7 +1215,7 @@ public:
/// validity of the less-or-equal relationship.
///
/// \returns true if *this <= RHS when both are considered signed.
- bool sle(const APInt &RHS) const { return slt(RHS) || eq(RHS); }
+ bool sle(const APInt &RHS) const { return compareSigned(RHS) <= 0; }
/// \brief Signed less or equal comparison
///
@@ -1080,7 +1231,7 @@ public:
/// the validity of the greater-than relationship.
///
/// \returns true if *this > RHS when both are considered unsigned.
- bool ugt(const APInt &RHS) const { return !ult(RHS) && !eq(RHS); }
+ bool ugt(const APInt &RHS) const { return !ule(RHS); }
/// \brief Unsigned greater than comparison
///
@@ -1089,7 +1240,8 @@ public:
///
/// \returns true if *this > RHS when considered unsigned.
bool ugt(uint64_t RHS) const {
- return getActiveBits() > 64 ? true : getZExtValue() > RHS;
+ // Only need to check active bits if not a single word.
+ return (!isSingleWord() && getActiveBits() > 64) || getZExtValue() > RHS;
}
/// \brief Signed greather than comparison
@@ -1098,7 +1250,7 @@ public:
/// validity of the greater-than relationship.
///
/// \returns true if *this > RHS when both are considered signed.
- bool sgt(const APInt &RHS) const { return !slt(RHS) && !eq(RHS); }
+ bool sgt(const APInt &RHS) const { return !sle(RHS); }
/// \brief Signed greater than comparison
///
@@ -1107,7 +1259,8 @@ public:
///
/// \returns true if *this > RHS when considered signed.
bool sgt(int64_t RHS) const {
- return getMinSignedBits() > 64 ? !isNegative() : getSExtValue() > RHS;
+ return (!isSingleWord() && getMinSignedBits() > 64) ? !isNegative()
+ : getSExtValue() > RHS;
}
/// \brief Unsigned greater or equal comparison
@@ -1144,7 +1297,20 @@ public:
/// This operation tests if there are any pairs of corresponding bits
/// between this APInt and RHS that are both set.
- bool intersects(const APInt &RHS) const { return (*this & RHS) != 0; }
+ bool intersects(const APInt &RHS) const {
+ assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
+ if (isSingleWord())
+ return (U.VAL & RHS.U.VAL) != 0;
+ return intersectsSlowCase(RHS);
+ }
+
+ /// This operation checks that all bits set in this APInt are also set in RHS.
+ bool isSubsetOf(const APInt &RHS) const {
+ assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
+ if (isSingleWord())
+ return (U.VAL & ~RHS.U.VAL) == 0;
+ return isSubsetOfSlowCase(RHS);
+ }
/// @}
/// \name Resizing Operators
@@ -1202,12 +1368,10 @@ public:
/// \brief Set every bit to 1.
void setAllBits() {
if (isSingleWord())
- VAL = UINT64_MAX;
- else {
+ U.VAL = WORD_MAX;
+ else
// Set all the bits in all the words.
- for (unsigned i = 0; i < getNumWords(); ++i)
- pVal[i] = UINT64_MAX;
- }
+ memset(U.pVal, -1, getNumWords() * APINT_WORD_SIZE);
// Clear the unused ones
clearUnusedBits();
}
@@ -1215,30 +1379,87 @@ public:
/// \brief Set a given bit to 1.
///
/// Set the given bit to 1 whose position is given as "bitPosition".
- void setBit(unsigned bitPosition);
+ void setBit(unsigned BitPosition) {
+ assert(BitPosition <= BitWidth && "BitPosition out of range");
+ WordType Mask = maskBit(BitPosition);
+ if (isSingleWord())
+ U.VAL |= Mask;
+ else
+ U.pVal[whichWord(BitPosition)] |= Mask;
+ }
+
+ /// Set the sign bit to 1.
+ void setSignBit() {
+ setBit(BitWidth - 1);
+ }
+
+ /// Set the bits from loBit (inclusive) to hiBit (exclusive) to 1.
+ void setBits(unsigned loBit, unsigned hiBit) {
+ assert(hiBit <= BitWidth && "hiBit out of range");
+ assert(loBit <= BitWidth && "loBit out of range");
+ assert(loBit <= hiBit && "loBit greater than hiBit");
+ if (loBit == hiBit)
+ return;
+ if (loBit < APINT_BITS_PER_WORD && hiBit <= APINT_BITS_PER_WORD) {
+ uint64_t mask = WORD_MAX >> (APINT_BITS_PER_WORD - (hiBit - loBit));
+ mask <<= loBit;
+ if (isSingleWord())
+ U.VAL |= mask;
+ else
+ U.pVal[0] |= mask;
+ } else {
+ setBitsSlowCase(loBit, hiBit);
+ }
+ }
+
+ /// Set the top bits starting from loBit.
+ void setBitsFrom(unsigned loBit) {
+ return setBits(loBit, BitWidth);
+ }
+
+ /// Set the bottom loBits bits.
+ void setLowBits(unsigned loBits) {
+ return setBits(0, loBits);
+ }
+
+ /// Set the top hiBits bits.
+ void setHighBits(unsigned hiBits) {
+ return setBits(BitWidth - hiBits, BitWidth);
+ }
/// \brief Set every bit to 0.
void clearAllBits() {
if (isSingleWord())
- VAL = 0;
+ U.VAL = 0;
else
- memset(pVal, 0, getNumWords() * APINT_WORD_SIZE);
+ memset(U.pVal, 0, getNumWords() * APINT_WORD_SIZE);
}
/// \brief Set a given bit to 0.
///
/// Set the given bit to 0 whose position is given as "bitPosition".
- void clearBit(unsigned bitPosition);
+ void clearBit(unsigned BitPosition) {
+ assert(BitPosition <= BitWidth && "BitPosition out of range");
+ WordType Mask = ~maskBit(BitPosition);
+ if (isSingleWord())
+ U.VAL &= Mask;
+ else
+ U.pVal[whichWord(BitPosition)] &= Mask;
+ }
+
+ /// Set the sign bit to 0.
+ void clearSignBit() {
+ clearBit(BitWidth - 1);
+ }
/// \brief Toggle every bit to its opposite value.
void flipAllBits() {
- if (isSingleWord())
- VAL ^= UINT64_MAX;
- else {
- for (unsigned i = 0; i < getNumWords(); ++i)
- pVal[i] ^= UINT64_MAX;
+ if (isSingleWord()) {
+ U.VAL ^= WORD_MAX;
+ clearUnusedBits();
+ } else {
+ flipAllBitsSlowCase();
}
- clearUnusedBits();
}
/// \brief Toggles a given bit to its opposite value.
@@ -1247,6 +1468,18 @@ public:
/// as "bitPosition".
void flipBit(unsigned bitPosition);
+ /// Negate this APInt in place.
+ void negate() {
+ flipAllBits();
+ ++(*this);
+ }
+
+ /// Insert the bits from a smaller APInt starting at bitPosition.
+ void insertBits(const APInt &SubBits, unsigned bitPosition);
+
+ /// Return an APInt with the extracted bits [bitPosition,bitPosition+numBits).
+ APInt extractBits(unsigned numBits, unsigned bitPosition) const;
+
/// @}
/// \name Value Characterization Functions
/// @{
@@ -1308,9 +1541,9 @@ public:
/// uint64_t. Otherwise an assertion will result.
uint64_t getZExtValue() const {
if (isSingleWord())
- return VAL;
+ return U.VAL;
assert(getActiveBits() <= 64 && "Too many bits for uint64_t");
- return pVal[0];
+ return U.pVal[0];
}
/// \brief Get sign extended value
@@ -1320,10 +1553,9 @@ public:
/// int64_t. Otherwise an assertion will result.
int64_t getSExtValue() const {
if (isSingleWord())
- return int64_t(VAL << (APINT_BITS_PER_WORD - BitWidth)) >>
- (APINT_BITS_PER_WORD - BitWidth);
+ return SignExtend64(U.VAL, BitWidth);
assert(getMinSignedBits() <= 64 && "Too many bits for int64_t");
- return int64_t(pVal[0]);
+ return int64_t(U.pVal[0]);
}
/// \brief Get bits required for string value.
@@ -1343,7 +1575,7 @@ public:
unsigned countLeadingZeros() const {
if (isSingleWord()) {
unsigned unusedBits = APINT_BITS_PER_WORD - BitWidth;
- return llvm::countLeadingZeros(VAL) - unusedBits;
+ return llvm::countLeadingZeros(U.VAL) - unusedBits;
}
return countLeadingZerosSlowCase();
}
@@ -1356,7 +1588,11 @@ public:
///
/// \returns 0 if the high order bit is not set, otherwise returns the number
/// of 1 bits from the most significant to the least
- unsigned countLeadingOnes() const;
+ unsigned countLeadingOnes() const {
+ if (isSingleWord())
+ return llvm::countLeadingOnes(U.VAL << (APINT_BITS_PER_WORD - BitWidth));
+ return countLeadingOnesSlowCase();
+ }
/// Computes the number of leading bits of this APInt that are equal to its
/// sign bit.
@@ -1372,7 +1608,11 @@ public:
///
/// \returns BitWidth if the value is zero, otherwise returns the number of
/// zeros from the least significant bit to the first one bit.
- unsigned countTrailingZeros() const;
+ unsigned countTrailingZeros() const {
+ if (isSingleWord())
+ return std::min(unsigned(llvm::countTrailingZeros(U.VAL)), BitWidth);
+ return countTrailingZerosSlowCase();
+ }
/// \brief Count the number of trailing one bits.
///
@@ -1384,7 +1624,7 @@ public:
/// of ones from the least significant bit to the first zero bit.
unsigned countTrailingOnes() const {
if (isSingleWord())
- return llvm::countTrailingOnes(VAL);
+ return llvm::countTrailingOnes(U.VAL);
return countTrailingOnesSlowCase();
}
@@ -1396,7 +1636,7 @@ public:
/// \returns 0 if the value is zero, otherwise returns the number of set bits.
unsigned countPopulation() const {
if (isSingleWord())
- return llvm::countPopulation(VAL);
+ return llvm::countPopulation(U.VAL);
return countPopulationSlowCase();
}
@@ -1451,12 +1691,7 @@ public:
/// re-interprets the bits as a double. Note that it is valid to do this on
/// any bit width. Exactly 64 bits will be translated.
double bitsToDouble() const {
- union {
- uint64_t I;
- double D;
- } T;
- T.I = (isSingleWord() ? VAL : pVal[0]);
- return T.D;
+ return BitsToDouble(getWord(0));
}
/// \brief Converts APInt bits to a double
@@ -1465,12 +1700,7 @@ public:
/// re-interprets the bits as a float. Note that it is valid to do this on
/// any bit width. Exactly 32 bits will be translated.
float bitsToFloat() const {
- union {
- unsigned I;
- float F;
- } T;
- T.I = unsigned((isSingleWord() ? VAL : pVal[0]));
- return T.F;
+ return BitsToFloat(getWord(0));
}
/// \brief Converts a double to APInt bits.
@@ -1478,12 +1708,7 @@ public:
/// The conversion does not do a translation from double to integer, it just
/// re-interprets the bits of the double.
static APInt doubleToBits(double V) {
- union {
- uint64_t I;
- double D;
- } T;
- T.D = V;
- return APInt(sizeof T * CHAR_BIT, T.I);
+ return APInt(sizeof(double) * CHAR_BIT, DoubleToBits(V));
}
/// \brief Converts a float to APInt bits.
@@ -1491,12 +1716,7 @@ public:
/// The conversion does not do a translation from float to integer, it just
/// re-interprets the bits of the float.
static APInt floatToBits(float V) {
- union {
- unsigned I;
- float F;
- } T;
- T.F = V;
- return APInt(sizeof T * CHAR_BIT, T.I);
+ return APInt(sizeof(float) * CHAR_BIT, FloatToBits(V));
}
/// @}
@@ -1524,13 +1744,13 @@ public:
/// referencing 2 in a space where 2 does no exist.
unsigned nearestLogBase2() const {
// Special case when we have a bitwidth of 1. If VAL is 1, then we
- // get 0. If VAL is 0, we get UINT64_MAX which gets truncated to
+ // get 0. If VAL is 0, we get WORD_MAX which gets truncated to
// UINT32_MAX.
if (BitWidth == 1)
- return VAL - 1;
+ return U.VAL - 1;
// Handle the zero case.
- if (!getBoolValue())
+ if (isNullValue())
return UINT32_MAX;
// The non-zero case is handled by computing:
@@ -1589,46 +1809,50 @@ public:
/// Sets the least significant part of a bignum to the input value, and zeroes
/// out higher parts.
- static void tcSet(integerPart *, integerPart, unsigned int);
+ static void tcSet(WordType *, WordType, unsigned);
/// Assign one bignum to another.
- static void tcAssign(integerPart *, const integerPart *, unsigned int);
+ static void tcAssign(WordType *, const WordType *, unsigned);
/// Returns true if a bignum is zero, false otherwise.
- static bool tcIsZero(const integerPart *, unsigned int);
+ static bool tcIsZero(const WordType *, unsigned);
/// Extract the given bit of a bignum; returns 0 or 1. Zero-based.
- static int tcExtractBit(const integerPart *, unsigned int bit);
+ static int tcExtractBit(const WordType *, unsigned bit);
/// Copy the bit vector of width srcBITS from SRC, starting at bit srcLSB, to
/// DST, of dstCOUNT parts, such that the bit srcLSB becomes the least
/// significant bit of DST. All high bits above srcBITS in DST are
/// zero-filled.
- static void tcExtract(integerPart *, unsigned int dstCount,
- const integerPart *, unsigned int srcBits,
- unsigned int srcLSB);
+ static void tcExtract(WordType *, unsigned dstCount,
+ const WordType *, unsigned srcBits,
+ unsigned srcLSB);
/// Set the given bit of a bignum. Zero-based.
- static void tcSetBit(integerPart *, unsigned int bit);
+ static void tcSetBit(WordType *, unsigned bit);
/// Clear the given bit of a bignum. Zero-based.
- static void tcClearBit(integerPart *, unsigned int bit);
+ static void tcClearBit(WordType *, unsigned bit);
/// Returns the bit number of the least or most significant set bit of a
/// number. If the input number has no bits set -1U is returned.
- static unsigned int tcLSB(const integerPart *, unsigned int);
- static unsigned int tcMSB(const integerPart *parts, unsigned int n);
+ static unsigned tcLSB(const WordType *, unsigned n);
+ static unsigned tcMSB(const WordType *parts, unsigned n);
/// Negate a bignum in-place.
- static void tcNegate(integerPart *, unsigned int);
+ static void tcNegate(WordType *, unsigned);
/// DST += RHS + CARRY where CARRY is zero or one. Returns the carry flag.
- static integerPart tcAdd(integerPart *, const integerPart *,
- integerPart carry, unsigned);
+ static WordType tcAdd(WordType *, const WordType *,
+ WordType carry, unsigned);
+ /// DST += RHS. Returns the carry flag.
+ static WordType tcAddPart(WordType *, WordType, unsigned);
/// DST -= RHS + CARRY where CARRY is zero or one. Returns the carry flag.
- static integerPart tcSubtract(integerPart *, const integerPart *,
- integerPart carry, unsigned);
+ static WordType tcSubtract(WordType *, const WordType *,
+ WordType carry, unsigned);
+ /// DST -= RHS. Returns the carry flag.
+ static WordType tcSubtractPart(WordType *, WordType, unsigned);
/// DST += SRC * MULTIPLIER + PART if add is true
/// DST = SRC * MULTIPLIER + PART if add is false
@@ -1640,23 +1864,22 @@ public:
/// Otherwise DST is filled with the least significant DSTPARTS parts of the
/// result, and if all of the omitted higher parts were zero return zero,
/// otherwise overflow occurred and return one.
- static int tcMultiplyPart(integerPart *dst, const integerPart *src,
- integerPart multiplier, integerPart carry,
- unsigned int srcParts, unsigned int dstParts,
+ static int tcMultiplyPart(WordType *dst, const WordType *src,
+ WordType multiplier, WordType carry,
+ unsigned srcParts, unsigned dstParts,
bool add);
/// DST = LHS * RHS, where DST has the same width as the operands and is
/// filled with the least significant parts of the result. Returns one if
/// overflow occurred, otherwise zero. DST must be disjoint from both
/// operands.
- static int tcMultiply(integerPart *, const integerPart *, const integerPart *,
+ static int tcMultiply(WordType *, const WordType *, const WordType *,
unsigned);
/// DST = LHS * RHS, where DST has width the sum of the widths of the
- /// operands. No overflow occurs. DST must be disjoint from both
- /// operands. Returns the number of parts required to hold the result.
- static unsigned int tcFullMultiply(integerPart *, const integerPart *,
- const integerPart *, unsigned, unsigned);
+ /// operands. No overflow occurs. DST must be disjoint from both operands.
+ static void tcFullMultiply(WordType *, const WordType *,
+ const WordType *, unsigned, unsigned);
/// If RHS is zero LHS and REMAINDER are left unchanged, return one.
/// Otherwise set LHS to LHS / RHS with the fractional part discarded, set
@@ -1667,38 +1890,39 @@ public:
/// SCRATCH is a bignum of the same size as the operands and result for use by
/// the routine; its contents need not be initialized and are destroyed. LHS,
/// REMAINDER and SCRATCH must be distinct.
- static int tcDivide(integerPart *lhs, const integerPart *rhs,
- integerPart *remainder, integerPart *scratch,
- unsigned int parts);
+ static int tcDivide(WordType *lhs, const WordType *rhs,
+ WordType *remainder, WordType *scratch,
+ unsigned parts);
- /// Shift a bignum left COUNT bits. Shifted in bits are zero. There are no
- /// restrictions on COUNT.
- static void tcShiftLeft(integerPart *, unsigned int parts,
- unsigned int count);
+ /// Shift a bignum left Count bits. Shifted in bits are zero. There are no
+ /// restrictions on Count.
+ static void tcShiftLeft(WordType *, unsigned Words, unsigned Count);
- /// Shift a bignum right COUNT bits. Shifted in bits are zero. There are no
- /// restrictions on COUNT.
- static void tcShiftRight(integerPart *, unsigned int parts,
- unsigned int count);
+ /// Shift a bignum right Count bits. Shifted in bits are zero. There are no
+ /// restrictions on Count.
+ static void tcShiftRight(WordType *, unsigned Words, unsigned Count);
/// The obvious AND, OR and XOR and complement operations.
- static void tcAnd(integerPart *, const integerPart *, unsigned int);
- static void tcOr(integerPart *, const integerPart *, unsigned int);
- static void tcXor(integerPart *, const integerPart *, unsigned int);
- static void tcComplement(integerPart *, unsigned int);
+ static void tcAnd(WordType *, const WordType *, unsigned);
+ static void tcOr(WordType *, const WordType *, unsigned);
+ static void tcXor(WordType *, const WordType *, unsigned);
+ static void tcComplement(WordType *, unsigned);
/// Comparison (unsigned) of two bignums.
- static int tcCompare(const integerPart *, const integerPart *, unsigned int);
+ static int tcCompare(const WordType *, const WordType *, unsigned);
/// Increment a bignum in-place. Return the carry flag.
- static integerPart tcIncrement(integerPart *, unsigned int);
+ static WordType tcIncrement(WordType *dst, unsigned parts) {
+ return tcAddPart(dst, 1, parts);
+ }
/// Decrement a bignum in-place. Return the borrow flag.
- static integerPart tcDecrement(integerPart *, unsigned int);
+ static WordType tcDecrement(WordType *dst, unsigned parts) {
+ return tcSubtractPart(dst, 1, parts);
+ }
/// Set the least significant BITS and clear the rest.
- static void tcSetLeastSignificantBits(integerPart *, unsigned int,
- unsigned int bits);
+ static void tcSetLeastSignificantBits(WordType *, unsigned, unsigned bits);
/// \brief debug method
void dump() const;
@@ -1723,14 +1947,81 @@ inline bool operator==(uint64_t V1, const APInt &V2) { return V2 == V1; }
inline bool operator!=(uint64_t V1, const APInt &V2) { return V2 != V1; }
+/// \brief Unary bitwise complement operator.
+///
+/// \returns an APInt that is the bitwise complement of \p v.
+inline APInt operator~(APInt v) {
+ v.flipAllBits();
+ return v;
+}
+
+inline APInt operator&(APInt a, const APInt &b) {
+ a &= b;
+ return a;
+}
+
+inline APInt operator&(const APInt &a, APInt &&b) {
+ b &= a;
+ return std::move(b);
+}
+
+inline APInt operator&(APInt a, uint64_t RHS) {
+ a &= RHS;
+ return a;
+}
+
+inline APInt operator&(uint64_t LHS, APInt b) {
+ b &= LHS;
+ return b;
+}
+
+inline APInt operator|(APInt a, const APInt &b) {
+ a |= b;
+ return a;
+}
+
+inline APInt operator|(const APInt &a, APInt &&b) {
+ b |= a;
+ return std::move(b);
+}
+
+inline APInt operator|(APInt a, uint64_t RHS) {
+ a |= RHS;
+ return a;
+}
+
+inline APInt operator|(uint64_t LHS, APInt b) {
+ b |= LHS;
+ return b;
+}
+
+inline APInt operator^(APInt a, const APInt &b) {
+ a ^= b;
+ return a;
+}
+
+inline APInt operator^(const APInt &a, APInt &&b) {
+ b ^= a;
+ return std::move(b);
+}
+
+inline APInt operator^(APInt a, uint64_t RHS) {
+ a ^= RHS;
+ return a;
+}
+
+inline APInt operator^(uint64_t LHS, APInt b) {
+ b ^= LHS;
+ return b;
+}
+
inline raw_ostream &operator<<(raw_ostream &OS, const APInt &I) {
I.print(OS, true);
return OS;
}
inline APInt operator-(APInt v) {
- v.flipAllBits();
- ++v;
+ v.negate();
return v;
}
@@ -1760,7 +2051,7 @@ inline APInt operator-(APInt a, const APInt &b) {
}
inline APInt operator-(const APInt &a, APInt &&b) {
- b = -std::move(b);
+ b.negate();
b += a;
return std::move(b);
}
@@ -1771,11 +2062,21 @@ inline APInt operator-(APInt a, uint64_t RHS) {
}
inline APInt operator-(uint64_t LHS, APInt b) {
- b = -std::move(b);
+ b.negate();
b += LHS;
return b;
}
+inline APInt operator*(APInt a, uint64_t RHS) {
+ a *= RHS;
+ return a;
+}
+
+inline APInt operator*(uint64_t LHS, APInt b) {
+ b *= LHS;
+ return b;
+}
+
namespace APIntOps {
@@ -1799,47 +2100,13 @@ inline const APInt &umax(const APInt &A, const APInt &B) {
return A.ugt(B) ? A : B;
}
-/// \brief Check if the specified APInt has a N-bits unsigned integer value.
-inline bool isIntN(unsigned N, const APInt &APIVal) { return APIVal.isIntN(N); }
-
-/// \brief Check if the specified APInt has a N-bits signed integer value.
-inline bool isSignedIntN(unsigned N, const APInt &APIVal) {
- return APIVal.isSignedIntN(N);
-}
-
-/// \returns true if the argument APInt value is a sequence of ones starting at
-/// the least significant bit with the remainder zero.
-inline bool isMask(unsigned numBits, const APInt &APIVal) {
- return numBits <= APIVal.getBitWidth() &&
- APIVal == APInt::getLowBitsSet(APIVal.getBitWidth(), numBits);
-}
-
-/// \returns true if the argument is a non-empty sequence of ones starting at
-/// the least significant bit with the remainder zero (32 bit version).
-/// Ex. isMask(0x0000FFFFU) == true.
-inline bool isMask(const APInt &Value) {
- return (Value != 0) && ((Value + 1) & Value) == 0;
-}
-
-/// \brief Return true if the argument APInt value contains a sequence of ones
-/// with the remainder zero.
-inline bool isShiftedMask(unsigned numBits, const APInt &APIVal) {
- return isMask(numBits, (APIVal - APInt(numBits, 1)) | APIVal);
-}
-
-/// \brief Returns a byte-swapped representation of the specified APInt Value.
-inline APInt byteSwap(const APInt &APIVal) { return APIVal.byteSwap(); }
-
-/// \brief Returns the floor log base 2 of the specified APInt value.
-inline unsigned logBase2(const APInt &APIVal) { return APIVal.logBase2(); }
-
-/// \brief Compute GCD of two APInt values.
+/// \brief Compute GCD of two unsigned APInt values.
///
/// This function returns the greatest common divisor of the two APInt values
-/// using Euclid's algorithm.
+/// using Stein's algorithm.
///
-/// \returns the greatest common divisor of Val1 and Val2
-APInt GreatestCommonDivisor(const APInt &Val1, const APInt &Val2);
+/// \returns the greatest common divisor of A and B.
+APInt GreatestCommonDivisor(APInt A, APInt B);
/// \brief Converts the given APInt to a double value.
///
@@ -1879,83 +2146,6 @@ inline APInt RoundFloatToAPInt(float Float, unsigned width) {
return RoundDoubleToAPInt(double(Float), width);
}
-/// \brief Arithmetic right-shift function.
-///
-/// Arithmetic right-shift the APInt by shiftAmt.
-inline APInt ashr(const APInt &LHS, unsigned shiftAmt) {
- return LHS.ashr(shiftAmt);
-}
-
-/// \brief Logical right-shift function.
-///
-/// Logical right-shift the APInt by shiftAmt.
-inline APInt lshr(const APInt &LHS, unsigned shiftAmt) {
- return LHS.lshr(shiftAmt);
-}
-
-/// \brief Left-shift function.
-///
-/// Left-shift the APInt by shiftAmt.
-inline APInt shl(const APInt &LHS, unsigned shiftAmt) {
- return LHS.shl(shiftAmt);
-}
-
-/// \brief Signed division function for APInt.
-///
-/// Signed divide APInt LHS by APInt RHS.
-inline APInt sdiv(const APInt &LHS, const APInt &RHS) { return LHS.sdiv(RHS); }
-
-/// \brief Unsigned division function for APInt.
-///
-/// Unsigned divide APInt LHS by APInt RHS.
-inline APInt udiv(const APInt &LHS, const APInt &RHS) { return LHS.udiv(RHS); }
-
-/// \brief Function for signed remainder operation.
-///
-/// Signed remainder operation on APInt.
-inline APInt srem(const APInt &LHS, const APInt &RHS) { return LHS.srem(RHS); }
-
-/// \brief Function for unsigned remainder operation.
-///
-/// Unsigned remainder operation on APInt.
-inline APInt urem(const APInt &LHS, const APInt &RHS) { return LHS.urem(RHS); }
-
-/// \brief Function for multiplication operation.
-///
-/// Performs multiplication on APInt values.
-inline APInt mul(const APInt &LHS, const APInt &RHS) { return LHS * RHS; }
-
-/// \brief Function for addition operation.
-///
-/// Performs addition on APInt values.
-inline APInt add(const APInt &LHS, const APInt &RHS) { return LHS + RHS; }
-
-/// \brief Function for subtraction operation.
-///
-/// Performs subtraction on APInt values.
-inline APInt sub(const APInt &LHS, const APInt &RHS) { return LHS - RHS; }
-
-/// \brief Bitwise AND function for APInt.
-///
-/// Performs bitwise AND operation on APInt LHS and
-/// APInt RHS.
-inline APInt And(const APInt &LHS, const APInt &RHS) { return LHS & RHS; }
-
-/// \brief Bitwise OR function for APInt.
-///
-/// Performs bitwise OR operation on APInt LHS and APInt RHS.
-inline APInt Or(const APInt &LHS, const APInt &RHS) { return LHS | RHS; }
-
-/// \brief Bitwise XOR function for APInt.
-///
-/// Performs bitwise XOR operation on APInt.
-inline APInt Xor(const APInt &LHS, const APInt &RHS) { return LHS ^ RHS; }
-
-/// \brief Bitwise complement function.
-///
-/// Performs a bitwise complement operation on APInt.
-inline APInt Not(const APInt &APIVal) { return ~APIVal; }
-
} // End of APIntOps namespace
// See friend declaration above. This additional declaration is required in
diff --git a/contrib/llvm/include/llvm/ADT/APSInt.h b/contrib/llvm/include/llvm/ADT/APSInt.h
index 813b368..dabbf33 100644
--- a/contrib/llvm/include/llvm/ADT/APSInt.h
+++ b/contrib/llvm/include/llvm/ADT/APSInt.h
@@ -125,7 +125,10 @@ public:
return IsUnsigned ? APSInt(lshr(Amt), true) : APSInt(ashr(Amt), false);
}
APSInt& operator>>=(unsigned Amt) {
- *this = *this >> Amt;
+ if (IsUnsigned)
+ lshrInPlace(Amt);
+ else
+ ashrInPlace(Amt);
return *this;
}
@@ -179,7 +182,7 @@ public:
return APSInt(static_cast<const APInt&>(*this) << Bits, IsUnsigned);
}
APSInt& operator<<=(unsigned Amt) {
- *this = *this << Amt;
+ static_cast<APInt&>(*this) <<= Amt;
return *this;
}
@@ -235,19 +238,16 @@ public:
assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
return APSInt(static_cast<const APInt&>(*this) & RHS, IsUnsigned);
}
- APSInt And(const APSInt &RHS) const { return this->operator&(RHS); }
APSInt operator|(const APSInt& RHS) const {
assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
return APSInt(static_cast<const APInt&>(*this) | RHS, IsUnsigned);
}
- APSInt Or(const APSInt &RHS) const { return this->operator|(RHS); }
APSInt operator^(const APSInt &RHS) const {
assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
return APSInt(static_cast<const APInt&>(*this) ^ RHS, IsUnsigned);
}
- APSInt Xor(const APSInt &RHS) const { return this->operator^(RHS); }
APSInt operator*(const APSInt& RHS) const {
assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
@@ -288,12 +288,12 @@ public:
/// \brief Compare underlying values of two numbers.
static int compareValues(const APSInt &I1, const APSInt &I2) {
if (I1.getBitWidth() == I2.getBitWidth() && I1.isSigned() == I2.isSigned())
- return I1 == I2 ? 0 : I1 > I2 ? 1 : -1;
+ return I1.IsUnsigned ? I1.compare(I2) : I1.compareSigned(I2);
// Check for a bit-width mismatch.
if (I1.getBitWidth() > I2.getBitWidth())
return compareValues(I1, I2.extend(I1.getBitWidth()));
- else if (I2.getBitWidth() > I1.getBitWidth())
+ if (I2.getBitWidth() > I1.getBitWidth())
return compareValues(I1.extend(I2.getBitWidth()), I2);
// We have a signedness mismatch. Check for negative values and do an
@@ -308,7 +308,7 @@ public:
return 1;
}
- return I1.eq(I2) ? 0 : I1.ugt(I2) ? 1 : -1;
+ return I1.compare(I2);
}
static APSInt get(int64_t X) { return APSInt(APInt(64, X), false); }
diff --git a/contrib/llvm/include/llvm/ADT/AllocatorList.h b/contrib/llvm/include/llvm/ADT/AllocatorList.h
index 05a549f..178c674 100644
--- a/contrib/llvm/include/llvm/ADT/AllocatorList.h
+++ b/contrib/llvm/include/llvm/ADT/AllocatorList.h
@@ -10,10 +10,16 @@
#ifndef LLVM_ADT_ALLOCATORLIST_H
#define LLVM_ADT_ALLOCATORLIST_H
+#include "llvm/ADT/ilist_node.h"
#include "llvm/ADT/iterator.h"
#include "llvm/ADT/simple_ilist.h"
#include "llvm/Support/Allocator.h"
+#include <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <iterator>
#include <type_traits>
+#include <utility>
namespace llvm {
@@ -39,7 +45,8 @@ template <class T, class AllocatorT> class AllocatorList : AllocatorT {
T V;
};
- typedef simple_ilist<Node> list_type;
+ using list_type = simple_ilist<Node>;
+
list_type List;
AllocatorT &getAlloc() { return *this; }
@@ -51,13 +58,17 @@ template <class T, class AllocatorT> class AllocatorList : AllocatorT {
struct Cloner {
AllocatorList &AL;
+
Cloner(AllocatorList &AL) : AL(AL) {}
+
Node *operator()(const Node &N) const { return AL.create(N.V); }
};
struct Disposer {
AllocatorList &AL;
+
Disposer(AllocatorList &AL) : AL(AL) {}
+
void operator()(Node *N) const {
N->~Node();
AL.getAlloc().Deallocate(N);
@@ -65,13 +76,13 @@ template <class T, class AllocatorT> class AllocatorList : AllocatorT {
};
public:
- typedef T value_type;
- typedef T *pointer;
- typedef T &reference;
- typedef const T *const_pointer;
- typedef const T &const_reference;
- typedef typename list_type::size_type size_type;
- typedef typename list_type::difference_type difference_type;
+ using value_type = T;
+ using pointer = T *;
+ using reference = T &;
+ using const_pointer = const T *;
+ using const_reference = const T &;
+ using size_type = typename list_type::size_type;
+ using difference_type = typename list_type::difference_type;
private:
template <class ValueT, class IteratorBase>
@@ -83,20 +94,18 @@ private:
friend class IteratorImpl;
friend AllocatorList;
- typedef iterator_adaptor_base<IteratorImpl<ValueT, IteratorBase>,
- IteratorBase, std::bidirectional_iterator_tag,
- ValueT>
- base_type;
+ using base_type =
+ iterator_adaptor_base<IteratorImpl<ValueT, IteratorBase>, IteratorBase,
+ std::bidirectional_iterator_tag, ValueT>;
public:
- typedef ValueT value_type;
- typedef ValueT *pointer;
- typedef ValueT &reference;
+ using value_type = ValueT;
+ using pointer = ValueT *;
+ using reference = ValueT &;
IteratorImpl() = default;
IteratorImpl(const IteratorImpl &) = default;
IteratorImpl &operator=(const IteratorImpl &) = default;
- ~IteratorImpl() = default;
explicit IteratorImpl(const IteratorBase &I) : base_type(I) {}
@@ -106,6 +115,8 @@ private:
OtherIteratorBase, IteratorBase>::value>::type * = nullptr)
: base_type(X.wrapped()) {}
+ ~IteratorImpl() = default;
+
reference operator*() const { return base_type::wrapped()->V; }
pointer operator->() const { return &operator*(); }
@@ -118,30 +129,34 @@ private:
};
public:
- typedef IteratorImpl<T, typename list_type::iterator> iterator;
- typedef IteratorImpl<T, typename list_type::reverse_iterator>
- reverse_iterator;
- typedef IteratorImpl<const T, typename list_type::const_iterator>
- const_iterator;
- typedef IteratorImpl<const T, typename list_type::const_reverse_iterator>
- const_reverse_iterator;
+ using iterator = IteratorImpl<T, typename list_type::iterator>;
+ using reverse_iterator =
+ IteratorImpl<T, typename list_type::reverse_iterator>;
+ using const_iterator =
+ IteratorImpl<const T, typename list_type::const_iterator>;
+ using const_reverse_iterator =
+ IteratorImpl<const T, typename list_type::const_reverse_iterator>;
AllocatorList() = default;
AllocatorList(AllocatorList &&X)
: AllocatorT(std::move(X.getAlloc())), List(std::move(X.List)) {}
+
AllocatorList(const AllocatorList &X) {
List.cloneFrom(X.List, Cloner(*this), Disposer(*this));
}
+
AllocatorList &operator=(AllocatorList &&X) {
clear(); // Dispose of current nodes explicitly.
List = std::move(X.List);
getAlloc() = std::move(X.getAlloc());
return *this;
}
+
AllocatorList &operator=(const AllocatorList &X) {
List.cloneFrom(X.List, Cloner(*this), Disposer(*this));
return *this;
}
+
~AllocatorList() { clear(); }
void swap(AllocatorList &RHS) {
diff --git a/contrib/llvm/include/llvm/ADT/ArrayRef.h b/contrib/llvm/include/llvm/ADT/ArrayRef.h
index b3fe31f..925ebaf 100644
--- a/contrib/llvm/include/llvm/ADT/ArrayRef.h
+++ b/contrib/llvm/include/llvm/ADT/ArrayRef.h
@@ -1,4 +1,4 @@
-//===--- ArrayRef.h - Array Reference Wrapper -------------------*- C++ -*-===//
+//===- ArrayRef.h - Array Reference Wrapper ---------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -12,12 +12,21 @@
#include "llvm/ADT/Hashing.h"
#include "llvm/ADT/None.h"
-#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/Compiler.h"
+#include <algorithm>
#include <array>
+#include <cassert>
+#include <cstddef>
+#include <initializer_list>
+#include <iterator>
+#include <memory>
+#include <type_traits>
#include <vector>
namespace llvm {
+
/// ArrayRef - Represent a constant reference to an array (0 or more elements
/// consecutively in memory), i.e. a start pointer and a length. It allows
/// various APIs to take consecutive elements easily and conveniently.
@@ -32,28 +41,27 @@ namespace llvm {
template<typename T>
class LLVM_NODISCARD ArrayRef {
public:
- typedef const T *iterator;
- typedef const T *const_iterator;
- typedef size_t size_type;
-
- typedef std::reverse_iterator<iterator> reverse_iterator;
+ using iterator = const T *;
+ using const_iterator = const T *;
+ using size_type = size_t;
+ using reverse_iterator = std::reverse_iterator<iterator>;
private:
/// The start of the array, in an external buffer.
- const T *Data;
+ const T *Data = nullptr;
/// The number of elements.
- size_type Length;
+ size_type Length = 0;
public:
/// @name Constructors
/// @{
/// Construct an empty ArrayRef.
- /*implicit*/ ArrayRef() : Data(nullptr), Length(0) {}
+ /*implicit*/ ArrayRef() = default;
/// Construct an empty ArrayRef from None.
- /*implicit*/ ArrayRef(NoneType) : Data(nullptr), Length(0) {}
+ /*implicit*/ ArrayRef(NoneType) {}
/// Construct an ArrayRef from a single element.
/*implicit*/ ArrayRef(const T &OneElt)
@@ -282,9 +290,8 @@ namespace llvm {
template<typename T>
class LLVM_NODISCARD MutableArrayRef : public ArrayRef<T> {
public:
- typedef T *iterator;
-
- typedef std::reverse_iterator<iterator> reverse_iterator;
+ using iterator = T *;
+ using reverse_iterator = std::reverse_iterator<iterator>;
/// Construct an empty MutableArrayRef.
/*implicit*/ MutableArrayRef() : ArrayRef<T>() {}
@@ -416,19 +423,23 @@ namespace llvm {
/// This is a MutableArrayRef that owns its array.
template <typename T> class OwningArrayRef : public MutableArrayRef<T> {
public:
- OwningArrayRef() {}
+ OwningArrayRef() = default;
OwningArrayRef(size_t Size) : MutableArrayRef<T>(new T[Size], Size) {}
+
OwningArrayRef(ArrayRef<T> Data)
: MutableArrayRef<T>(new T[Data.size()], Data.size()) {
std::copy(Data.begin(), Data.end(), this->begin());
}
+
OwningArrayRef(OwningArrayRef &&Other) { *this = Other; }
+
OwningArrayRef &operator=(OwningArrayRef &&Other) {
delete[] this->data();
this->MutableArrayRef<T>::operator=(Other);
Other.MutableArrayRef<T>::operator=(MutableArrayRef<T>());
return *this;
}
+
~OwningArrayRef() { delete[] this->data(); }
};
@@ -487,6 +498,18 @@ namespace llvm {
return ArrayRef<T>(Arr);
}
+ /// Construct a MutableArrayRef from a single element.
+ template<typename T>
+ MutableArrayRef<T> makeMutableArrayRef(T &OneElt) {
+ return OneElt;
+ }
+
+ /// Construct a MutableArrayRef from a pointer and length.
+ template<typename T>
+ MutableArrayRef<T> makeMutableArrayRef(T *data, size_t length) {
+ return MutableArrayRef<T>(data, length);
+ }
+
/// @}
/// @name ArrayRef Comparison Operators
/// @{
@@ -505,13 +528,14 @@ namespace llvm {
// ArrayRefs can be treated like a POD type.
template <typename T> struct isPodLike;
- template <typename T> struct isPodLike<ArrayRef<T> > {
+ template <typename T> struct isPodLike<ArrayRef<T>> {
static const bool value = true;
};
template <typename T> hash_code hash_value(ArrayRef<T> S) {
return hash_combine_range(S.begin(), S.end());
}
+
} // end namespace llvm
#endif // LLVM_ADT_ARRAYREF_H
diff --git a/contrib/llvm/include/llvm/ADT/BitVector.h b/contrib/llvm/include/llvm/ADT/BitVector.h
index cf3756d..e68ef5f 100644
--- a/contrib/llvm/include/llvm/ADT/BitVector.h
+++ b/contrib/llvm/include/llvm/ADT/BitVector.h
@@ -14,6 +14,8 @@
#ifndef LLVM_ADT_BITVECTOR_H
#define LLVM_ADT_BITVECTOR_H
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/iterator_range.h"
#include "llvm/Support/MathExtras.h"
#include <algorithm>
#include <cassert>
@@ -25,6 +27,50 @@
namespace llvm {
+/// ForwardIterator for the bits that are set.
+/// Iterators get invalidated when resize / reserve is called.
+template <typename BitVectorT> class const_set_bits_iterator_impl {
+ const BitVectorT &Parent;
+ int Current = 0;
+
+ void advance() {
+ assert(Current != -1 && "Trying to advance past end.");
+ Current = Parent.find_next(Current);
+ }
+
+public:
+ const_set_bits_iterator_impl(const BitVectorT &Parent, int Current)
+ : Parent(Parent), Current(Current) {}
+ explicit const_set_bits_iterator_impl(const BitVectorT &Parent)
+ : const_set_bits_iterator_impl(Parent, Parent.find_first()) {}
+ const_set_bits_iterator_impl(const const_set_bits_iterator_impl &) = default;
+
+ const_set_bits_iterator_impl operator++(int) {
+ auto Prev = *this;
+ advance();
+ return Prev;
+ }
+
+ const_set_bits_iterator_impl &operator++() {
+ advance();
+ return *this;
+ }
+
+ unsigned operator*() const { return Current; }
+
+ bool operator==(const const_set_bits_iterator_impl &Other) const {
+ assert(&Parent == &Other.Parent &&
+ "Comparing iterators from different BitVectors");
+ return Current == Other.Current;
+ }
+
+ bool operator!=(const const_set_bits_iterator_impl &Other) const {
+ assert(&Parent == &Other.Parent &&
+ "Comparing iterators from different BitVectors");
+ return Current != Other.Current;
+ }
+};
+
class BitVector {
typedef unsigned long BitWord;
@@ -33,9 +79,8 @@ class BitVector {
static_assert(BITWORD_SIZE == 64 || BITWORD_SIZE == 32,
"Unsupported word size");
- BitWord *Bits; // Actual bits.
- unsigned Size; // Size of bitvector in bits.
- unsigned Capacity; // Number of BitWords allocated in the Bits array.
+ MutableArrayRef<BitWord> Bits; // Actual bits.
+ unsigned Size; // Size of bitvector in bits.
public:
typedef unsigned size_type;
@@ -73,18 +118,28 @@ public:
}
};
+ typedef const_set_bits_iterator_impl<BitVector> const_set_bits_iterator;
+ typedef const_set_bits_iterator set_iterator;
- /// BitVector default ctor - Creates an empty bitvector.
- BitVector() : Size(0), Capacity(0) {
- Bits = nullptr;
+ const_set_bits_iterator set_bits_begin() const {
+ return const_set_bits_iterator(*this);
+ }
+ const_set_bits_iterator set_bits_end() const {
+ return const_set_bits_iterator(*this, -1);
}
+ iterator_range<const_set_bits_iterator> set_bits() const {
+ return make_range(set_bits_begin(), set_bits_end());
+ }
+
+ /// BitVector default ctor - Creates an empty bitvector.
+ BitVector() : Size(0) {}
/// BitVector ctor - Creates a bitvector of specified number of bits. All
/// bits are initialized to the specified value.
explicit BitVector(unsigned s, bool t = false) : Size(s) {
- Capacity = NumBitWords(s);
- Bits = (BitWord *)std::malloc(Capacity * sizeof(BitWord));
- init_words(Bits, Capacity, t);
+ size_t Capacity = NumBitWords(s);
+ Bits = allocate(Capacity);
+ init_words(Bits, t);
if (t)
clear_unused_bits();
}
@@ -92,25 +147,21 @@ public:
/// BitVector copy ctor.
BitVector(const BitVector &RHS) : Size(RHS.size()) {
if (Size == 0) {
- Bits = nullptr;
- Capacity = 0;
+ Bits = MutableArrayRef<BitWord>();
return;
}
- Capacity = NumBitWords(RHS.size());
- Bits = (BitWord *)std::malloc(Capacity * sizeof(BitWord));
- std::memcpy(Bits, RHS.Bits, Capacity * sizeof(BitWord));
+ size_t Capacity = NumBitWords(RHS.size());
+ Bits = allocate(Capacity);
+ std::memcpy(Bits.data(), RHS.Bits.data(), Capacity * sizeof(BitWord));
}
- BitVector(BitVector &&RHS)
- : Bits(RHS.Bits), Size(RHS.Size), Capacity(RHS.Capacity) {
- RHS.Bits = nullptr;
- RHS.Size = RHS.Capacity = 0;
+ BitVector(BitVector &&RHS) : Bits(RHS.Bits), Size(RHS.Size) {
+ RHS.Bits = MutableArrayRef<BitWord>();
+ RHS.Size = 0;
}
- ~BitVector() {
- std::free(Bits);
- }
+ ~BitVector() { std::free(Bits.data()); }
/// empty - Tests whether there are no bits in this bitvector.
bool empty() const { return Size == 0; }
@@ -152,49 +203,177 @@ public:
return !any();
}
- /// find_first - Returns the index of the first set bit, -1 if none
- /// of the bits are set.
- int find_first() const {
- for (unsigned i = 0; i < NumBitWords(size()); ++i)
- if (Bits[i] != 0)
- return i * BITWORD_SIZE + countTrailingZeros(Bits[i]);
+ /// find_first_in - Returns the index of the first set bit in the range
+ /// [Begin, End). Returns -1 if all bits in the range are unset.
+ int find_first_in(unsigned Begin, unsigned End) const {
+ assert(Begin <= End && End <= Size);
+ if (Begin == End)
+ return -1;
+
+ unsigned FirstWord = Begin / BITWORD_SIZE;
+ unsigned LastWord = (End - 1) / BITWORD_SIZE;
+
+ // Check subsequent words.
+ for (unsigned i = FirstWord; i <= LastWord; ++i) {
+ BitWord Copy = Bits[i];
+
+ if (i == FirstWord) {
+ unsigned FirstBit = Begin % BITWORD_SIZE;
+ Copy &= maskTrailingZeros<BitWord>(FirstBit);
+ }
+
+ if (i == LastWord) {
+ unsigned LastBit = (End - 1) % BITWORD_SIZE;
+ Copy &= maskTrailingOnes<BitWord>(LastBit + 1);
+ }
+ if (Copy != 0)
+ return i * BITWORD_SIZE + countTrailingZeros(Copy);
+ }
return -1;
}
- /// find_next - Returns the index of the next set bit following the
- /// "Prev" bit. Returns -1 if the next set bit is not found.
- int find_next(unsigned Prev) const {
- ++Prev;
- if (Prev >= Size)
+ /// find_last_in - Returns the index of the last set bit in the range
+ /// [Begin, End). Returns -1 if all bits in the range are unset.
+ int find_last_in(unsigned Begin, unsigned End) const {
+ assert(Begin <= End && End <= Size);
+ if (Begin == End)
return -1;
- unsigned WordPos = Prev / BITWORD_SIZE;
- unsigned BitPos = Prev % BITWORD_SIZE;
- BitWord Copy = Bits[WordPos];
- // Mask off previous bits.
- Copy &= ~0UL << BitPos;
+ unsigned LastWord = (End - 1) / BITWORD_SIZE;
+ unsigned FirstWord = Begin / BITWORD_SIZE;
+
+ for (unsigned i = LastWord + 1; i >= FirstWord + 1; --i) {
+ unsigned CurrentWord = i - 1;
+
+ BitWord Copy = Bits[CurrentWord];
+ if (CurrentWord == LastWord) {
+ unsigned LastBit = (End - 1) % BITWORD_SIZE;
+ Copy &= maskTrailingOnes<BitWord>(LastBit + 1);
+ }
+
+ if (CurrentWord == FirstWord) {
+ unsigned FirstBit = Begin % BITWORD_SIZE;
+ Copy &= maskTrailingZeros<BitWord>(FirstBit);
+ }
+
+ if (Copy != 0)
+ return (CurrentWord + 1) * BITWORD_SIZE - countLeadingZeros(Copy) - 1;
+ }
+
+ return -1;
+ }
- if (Copy != 0)
- return WordPos * BITWORD_SIZE + countTrailingZeros(Copy);
+ /// find_first_unset_in - Returns the index of the first unset bit in the
+ /// range [Begin, End). Returns -1 if all bits in the range are set.
+ int find_first_unset_in(unsigned Begin, unsigned End) const {
+ assert(Begin <= End && End <= Size);
+ if (Begin == End)
+ return -1;
+
+ unsigned FirstWord = Begin / BITWORD_SIZE;
+ unsigned LastWord = (End - 1) / BITWORD_SIZE;
// Check subsequent words.
- for (unsigned i = WordPos+1; i < NumBitWords(size()); ++i)
- if (Bits[i] != 0)
- return i * BITWORD_SIZE + countTrailingZeros(Bits[i]);
+ for (unsigned i = FirstWord; i <= LastWord; ++i) {
+ BitWord Copy = Bits[i];
+
+ if (i == FirstWord) {
+ unsigned FirstBit = Begin % BITWORD_SIZE;
+ Copy |= maskTrailingOnes<BitWord>(FirstBit);
+ }
+
+ if (i == LastWord) {
+ unsigned LastBit = (End - 1) % BITWORD_SIZE;
+ Copy |= maskTrailingZeros<BitWord>(LastBit + 1);
+ }
+ if (Copy != ~0UL) {
+ unsigned Result = i * BITWORD_SIZE + countTrailingOnes(Copy);
+ return Result < size() ? Result : -1;
+ }
+ }
+ return -1;
+ }
+
+ /// find_last_unset_in - Returns the index of the last unset bit in the
+ /// range [Begin, End). Returns -1 if all bits in the range are set.
+ int find_last_unset_in(unsigned Begin, unsigned End) const {
+ assert(Begin <= End && End <= Size);
+ if (Begin == End)
+ return -1;
+
+ unsigned LastWord = (End - 1) / BITWORD_SIZE;
+ unsigned FirstWord = Begin / BITWORD_SIZE;
+
+ for (unsigned i = LastWord + 1; i >= FirstWord + 1; --i) {
+ unsigned CurrentWord = i - 1;
+
+ BitWord Copy = Bits[CurrentWord];
+ if (CurrentWord == LastWord) {
+ unsigned LastBit = (End - 1) % BITWORD_SIZE;
+ Copy |= maskTrailingZeros<BitWord>(LastBit + 1);
+ }
+
+ if (CurrentWord == FirstWord) {
+ unsigned FirstBit = Begin % BITWORD_SIZE;
+ Copy |= maskTrailingOnes<BitWord>(FirstBit);
+ }
+
+ if (Copy != ~0UL) {
+ unsigned Result =
+ (CurrentWord + 1) * BITWORD_SIZE - countLeadingOnes(Copy) - 1;
+ return Result < Size ? Result : -1;
+ }
+ }
return -1;
}
- /// clear - Clear all bits.
+ /// find_first - Returns the index of the first set bit, -1 if none
+ /// of the bits are set.
+ int find_first() const { return find_first_in(0, Size); }
+
+ /// find_last - Returns the index of the last set bit, -1 if none of the bits
+ /// are set.
+ int find_last() const { return find_last_in(0, Size); }
+
+ /// find_next - Returns the index of the next set bit following the
+ /// "Prev" bit. Returns -1 if the next set bit is not found.
+ int find_next(unsigned Prev) const { return find_first_in(Prev + 1, Size); }
+
+ /// find_prev - Returns the index of the first set bit that precedes the
+ /// the bit at \p PriorTo. Returns -1 if all previous bits are unset.
+ int find_prev(unsigned PriorTo) const { return find_last_in(0, PriorTo); }
+
+ /// find_first_unset - Returns the index of the first unset bit, -1 if all
+ /// of the bits are set.
+ int find_first_unset() const { return find_first_unset_in(0, Size); }
+
+ /// find_next_unset - Returns the index of the next unset bit following the
+ /// "Prev" bit. Returns -1 if all remaining bits are set.
+ int find_next_unset(unsigned Prev) const {
+ return find_first_unset_in(Prev + 1, Size);
+ }
+
+ /// find_last_unset - Returns the index of the last unset bit, -1 if all of
+ /// the bits are set.
+ int find_last_unset() const { return find_last_unset_in(0, Size); }
+
+ /// find_prev_unset - Returns the index of the first unset bit that precedes
+ /// the bit at \p PriorTo. Returns -1 if all previous bits are set.
+ int find_prev_unset(unsigned PriorTo) {
+ return find_last_unset_in(0, PriorTo);
+ }
+
+ /// clear - Removes all bits from the bitvector. Does not change capacity.
void clear() {
Size = 0;
}
/// resize - Grow or shrink the bitvector.
void resize(unsigned N, bool t = false) {
- if (N > Capacity * BITWORD_SIZE) {
- unsigned OldCapacity = Capacity;
+ if (N > getBitCapacity()) {
+ unsigned OldCapacity = Bits.size();
grow(N);
- init_words(&Bits[OldCapacity], (Capacity-OldCapacity), t);
+ init_words(Bits.drop_front(OldCapacity), t);
}
// Set any old unused bits that are now included in the BitVector. This
@@ -211,19 +390,19 @@ public:
}
void reserve(unsigned N) {
- if (N > Capacity * BITWORD_SIZE)
+ if (N > getBitCapacity())
grow(N);
}
// Set, reset, flip
BitVector &set() {
- init_words(Bits, Capacity, true);
+ init_words(Bits, true);
clear_unused_bits();
return *this;
}
BitVector &set(unsigned Idx) {
- assert(Bits && "Bits never allocated");
+ assert(Bits.data() && "Bits never allocated");
Bits[Idx / BITWORD_SIZE] |= BitWord(1) << (Idx % BITWORD_SIZE);
return *this;
}
@@ -258,7 +437,7 @@ public:
}
BitVector &reset() {
- init_words(Bits, Capacity, false);
+ init_words(Bits, false);
return *this;
}
@@ -420,27 +599,126 @@ public:
return *this;
}
+ BitVector &operator>>=(unsigned N) {
+ assert(N <= Size);
+ if (LLVM_UNLIKELY(empty() || N == 0))
+ return *this;
+
+ unsigned NumWords = NumBitWords(Size);
+ assert(NumWords >= 1);
+
+ wordShr(N / BITWORD_SIZE);
+
+ unsigned BitDistance = N % BITWORD_SIZE;
+ if (BitDistance == 0)
+ return *this;
+
+ // When the shift size is not a multiple of the word size, then we have
+ // a tricky situation where each word in succession needs to extract some
+ // of the bits from the next word and or them into this word while
+ // shifting this word to make room for the new bits. This has to be done
+ // for every word in the array.
+
+ // Since we're shifting each word right, some bits will fall off the end
+ // of each word to the right, and empty space will be created on the left.
+ // The final word in the array will lose bits permanently, so starting at
+ // the beginning, work forwards shifting each word to the right, and
+ // OR'ing in the bits from the end of the next word to the beginning of
+ // the current word.
+
+ // Example:
+ // Starting with {0xAABBCCDD, 0xEEFF0011, 0x22334455} and shifting right
+ // by 4 bits.
+ // Step 1: Word[0] >>= 4 ; 0x0ABBCCDD
+ // Step 2: Word[0] |= 0x10000000 ; 0x1ABBCCDD
+ // Step 3: Word[1] >>= 4 ; 0x0EEFF001
+ // Step 4: Word[1] |= 0x50000000 ; 0x5EEFF001
+ // Step 5: Word[2] >>= 4 ; 0x02334455
+ // Result: { 0x1ABBCCDD, 0x5EEFF001, 0x02334455 }
+ const BitWord Mask = maskTrailingOnes<BitWord>(BitDistance);
+ const unsigned LSH = BITWORD_SIZE - BitDistance;
+
+ for (unsigned I = 0; I < NumWords - 1; ++I) {
+ Bits[I] >>= BitDistance;
+ Bits[I] |= (Bits[I + 1] & Mask) << LSH;
+ }
+
+ Bits[NumWords - 1] >>= BitDistance;
+
+ return *this;
+ }
+
+ BitVector &operator<<=(unsigned N) {
+ assert(N <= Size);
+ if (LLVM_UNLIKELY(empty() || N == 0))
+ return *this;
+
+ unsigned NumWords = NumBitWords(Size);
+ assert(NumWords >= 1);
+
+ wordShl(N / BITWORD_SIZE);
+
+ unsigned BitDistance = N % BITWORD_SIZE;
+ if (BitDistance == 0)
+ return *this;
+
+ // When the shift size is not a multiple of the word size, then we have
+ // a tricky situation where each word in succession needs to extract some
+ // of the bits from the previous word and or them into this word while
+ // shifting this word to make room for the new bits. This has to be done
+ // for every word in the array. This is similar to the algorithm outlined
+ // in operator>>=, but backwards.
+
+ // Since we're shifting each word left, some bits will fall off the end
+ // of each word to the left, and empty space will be created on the right.
+ // The first word in the array will lose bits permanently, so starting at
+ // the end, work backwards shifting each word to the left, and OR'ing
+ // in the bits from the end of the next word to the beginning of the
+ // current word.
+
+ // Example:
+ // Starting with {0xAABBCCDD, 0xEEFF0011, 0x22334455} and shifting left
+ // by 4 bits.
+ // Step 1: Word[2] <<= 4 ; 0x23344550
+ // Step 2: Word[2] |= 0x0000000E ; 0x2334455E
+ // Step 3: Word[1] <<= 4 ; 0xEFF00110
+ // Step 4: Word[1] |= 0x0000000A ; 0xEFF0011A
+ // Step 5: Word[0] <<= 4 ; 0xABBCCDD0
+ // Result: { 0xABBCCDD0, 0xEFF0011A, 0x2334455E }
+ const BitWord Mask = maskLeadingOnes<BitWord>(BitDistance);
+ const unsigned RSH = BITWORD_SIZE - BitDistance;
+
+ for (int I = NumWords - 1; I > 0; --I) {
+ Bits[I] <<= BitDistance;
+ Bits[I] |= (Bits[I - 1] & Mask) >> RSH;
+ }
+ Bits[0] <<= BitDistance;
+ clear_unused_bits();
+
+ return *this;
+ }
+
// Assignment operator.
const BitVector &operator=(const BitVector &RHS) {
if (this == &RHS) return *this;
Size = RHS.size();
unsigned RHSWords = NumBitWords(Size);
- if (Size <= Capacity * BITWORD_SIZE) {
+ if (Size <= getBitCapacity()) {
if (Size)
- std::memcpy(Bits, RHS.Bits, RHSWords * sizeof(BitWord));
+ std::memcpy(Bits.data(), RHS.Bits.data(), RHSWords * sizeof(BitWord));
clear_unused_bits();
return *this;
}
// Grow the bitvector to have enough elements.
- Capacity = RHSWords;
- assert(Capacity > 0 && "negative capacity?");
- BitWord *NewBits = (BitWord *)std::malloc(Capacity * sizeof(BitWord));
- std::memcpy(NewBits, RHS.Bits, Capacity * sizeof(BitWord));
+ unsigned NewCapacity = RHSWords;
+ assert(NewCapacity > 0 && "negative capacity?");
+ auto NewBits = allocate(NewCapacity);
+ std::memcpy(NewBits.data(), RHS.Bits.data(), NewCapacity * sizeof(BitWord));
// Destroy the old bits.
- std::free(Bits);
+ std::free(Bits.data());
Bits = NewBits;
return *this;
@@ -449,13 +727,12 @@ public:
const BitVector &operator=(BitVector &&RHS) {
if (this == &RHS) return *this;
- std::free(Bits);
+ std::free(Bits.data());
Bits = RHS.Bits;
Size = RHS.Size;
- Capacity = RHS.Capacity;
- RHS.Bits = nullptr;
- RHS.Size = RHS.Capacity = 0;
+ RHS.Bits = MutableArrayRef<BitWord>();
+ RHS.Size = 0;
return *this;
}
@@ -463,7 +740,6 @@ public:
void swap(BitVector &RHS) {
std::swap(Bits, RHS.Bits);
std::swap(Size, RHS.Size);
- std::swap(Capacity, RHS.Capacity);
}
//===--------------------------------------------------------------------===//
@@ -503,6 +779,64 @@ public:
}
private:
+ /// \brief Perform a logical left shift of \p Count words by moving everything
+ /// \p Count words to the right in memory.
+ ///
+ /// While confusing, words are stored from least significant at Bits[0] to
+ /// most significant at Bits[NumWords-1]. A logical shift left, however,
+ /// moves the current least significant bit to a higher logical index, and
+ /// fills the previous least significant bits with 0. Thus, we actually
+ /// need to move the bytes of the memory to the right, not to the left.
+ /// Example:
+ /// Words = [0xBBBBAAAA, 0xDDDDFFFF, 0x00000000, 0xDDDD0000]
+ /// represents a BitVector where 0xBBBBAAAA contain the least significant
+ /// bits. So if we want to shift the BitVector left by 2 words, we need to
+ /// turn this into 0x00000000 0x00000000 0xBBBBAAAA 0xDDDDFFFF by using a
+ /// memmove which moves right, not left.
+ void wordShl(uint32_t Count) {
+ if (Count == 0)
+ return;
+
+ uint32_t NumWords = NumBitWords(Size);
+
+ auto Src = Bits.take_front(NumWords).drop_back(Count);
+ auto Dest = Bits.take_front(NumWords).drop_front(Count);
+
+ // Since we always move Word-sized chunks of data with src and dest both
+ // aligned to a word-boundary, we don't need to worry about endianness
+ // here.
+ std::memmove(Dest.begin(), Src.begin(), Dest.size() * sizeof(BitWord));
+ std::memset(Bits.data(), 0, Count * sizeof(BitWord));
+ clear_unused_bits();
+ }
+
+ /// \brief Perform a logical right shift of \p Count words by moving those
+ /// words to the left in memory. See wordShl for more information.
+ ///
+ void wordShr(uint32_t Count) {
+ if (Count == 0)
+ return;
+
+ uint32_t NumWords = NumBitWords(Size);
+
+ auto Src = Bits.take_front(NumWords).drop_front(Count);
+ auto Dest = Bits.take_front(NumWords).drop_back(Count);
+ assert(Dest.size() == Src.size());
+
+ std::memmove(Dest.begin(), Src.begin(), Dest.size() * sizeof(BitWord));
+ std::memset(Dest.end(), 0, Count * sizeof(BitWord));
+ }
+
+ MutableArrayRef<BitWord> allocate(size_t NumWords) {
+ BitWord *RawBits = (BitWord *)std::malloc(NumWords * sizeof(BitWord));
+ return MutableArrayRef<BitWord>(RawBits, NumWords);
+ }
+
+ int next_unset_in_word(int WordIndex, BitWord Word) const {
+ unsigned Result = WordIndex * BITWORD_SIZE + countTrailingOnes(Word);
+ return Result < size() ? Result : -1;
+ }
+
unsigned NumBitWords(unsigned S) const {
return (S + BITWORD_SIZE-1) / BITWORD_SIZE;
}
@@ -511,8 +845,8 @@ private:
void set_unused_bits(bool t = true) {
// Set high words first.
unsigned UsedWords = NumBitWords(Size);
- if (Capacity > UsedWords)
- init_words(&Bits[UsedWords], (Capacity-UsedWords), t);
+ if (Bits.size() > UsedWords)
+ init_words(Bits.drop_front(UsedWords), t);
// Then set any stray high bits of the last used word.
unsigned ExtraBits = Size % BITWORD_SIZE;
@@ -531,15 +865,17 @@ private:
}
void grow(unsigned NewSize) {
- Capacity = std::max(NumBitWords(NewSize), Capacity * 2);
- assert(Capacity > 0 && "realloc-ing zero space");
- Bits = (BitWord *)std::realloc(Bits, Capacity * sizeof(BitWord));
-
+ size_t NewCapacity = std::max<size_t>(NumBitWords(NewSize), Bits.size() * 2);
+ assert(NewCapacity > 0 && "realloc-ing zero space");
+ BitWord *NewBits =
+ (BitWord *)std::realloc(Bits.data(), NewCapacity * sizeof(BitWord));
+ Bits = MutableArrayRef<BitWord>(NewBits, NewCapacity);
clear_unused_bits();
}
- void init_words(BitWord *B, unsigned NumWords, bool t) {
- memset(B, 0 - (int)t, NumWords*sizeof(BitWord));
+ void init_words(MutableArrayRef<BitWord> B, bool t) {
+ if (B.size() > 0)
+ memset(B.data(), 0 - (int)t, B.size() * sizeof(BitWord));
}
template<bool AddBits, bool InvertMask>
@@ -571,7 +907,8 @@ private:
public:
/// Return the size (in bytes) of the bit vector.
- size_t getMemorySize() const { return Capacity * sizeof(BitWord); }
+ size_t getMemorySize() const { return Bits.size() * sizeof(BitWord); }
+ size_t getBitCapacity() const { return Bits.size() * BITWORD_SIZE; }
};
static inline size_t capacity_in_bytes(const BitVector &X) {
diff --git a/contrib/llvm/include/llvm/ADT/BreadthFirstIterator.h b/contrib/llvm/include/llvm/ADT/BreadthFirstIterator.h
new file mode 100644
index 0000000..6bc63c2
--- /dev/null
+++ b/contrib/llvm/include/llvm/ADT/BreadthFirstIterator.h
@@ -0,0 +1,163 @@
+//===- llvm/ADT/BreadthFirstIterator.h - Breadth First iterator -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file builds on the ADT/GraphTraits.h file to build a generic breadth
+// first graph iterator. This file exposes the following functions/types:
+//
+// bf_begin/bf_end/bf_iterator
+// * Normal breadth-first iteration - visit a graph level-by-level.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_BREADTHFIRSTITERATOR_H
+#define LLVM_ADT_BREADTHFIRSTITERATOR_H
+
+#include "llvm/ADT/GraphTraits.h"
+#include "llvm/ADT/None.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/iterator_range.h"
+#include <iterator>
+#include <queue>
+#include <utility>
+
+namespace llvm {
+
+// bf_iterator_storage - A private class which is used to figure out where to
+// store the visited set. We only provide a non-external variant for now.
+template <class SetType> class bf_iterator_storage {
+public:
+ SetType Visited;
+};
+
+// The visited state for the iteration is a simple set.
+template <typename NodeRef, unsigned SmallSize = 8>
+using bf_iterator_default_set = SmallPtrSet<NodeRef, SmallSize>;
+
+// Generic Breadth first search iterator.
+template <class GraphT,
+ class SetType =
+ bf_iterator_default_set<typename GraphTraits<GraphT>::NodeRef>,
+ class GT = GraphTraits<GraphT>>
+class bf_iterator
+ : public std::iterator<std::forward_iterator_tag, typename GT::NodeRef>,
+ public bf_iterator_storage<SetType> {
+ using super = std::iterator<std::forward_iterator_tag, typename GT::NodeRef>;
+
+ using NodeRef = typename GT::NodeRef;
+ using ChildItTy = typename GT::ChildIteratorType;
+
+ // First element is the node reference, second is the next child to visit.
+ using QueueElement = std::pair<NodeRef, Optional<ChildItTy>>;
+
+ // Visit queue - used to maintain BFS ordering.
+ // Optional<> because we need markers for levels.
+ std::queue<Optional<QueueElement>> VisitQueue;
+
+ // Current level.
+ unsigned Level;
+
+private:
+ inline bf_iterator(NodeRef Node) {
+ this->Visited.insert(Node);
+ Level = 0;
+
+ // Also, insert a dummy node as marker.
+ VisitQueue.push(QueueElement(Node, None));
+ VisitQueue.push(None);
+ }
+
+ inline bf_iterator() = default;
+
+ inline void toNext() {
+ Optional<QueueElement> Head = VisitQueue.front();
+ QueueElement H = Head.getValue();
+ NodeRef Node = H.first;
+ Optional<ChildItTy> &ChildIt = H.second;
+
+ if (!ChildIt)
+ ChildIt.emplace(GT::child_begin(Node));
+ while (*ChildIt != GT::child_end(Node)) {
+ NodeRef Next = *(*ChildIt)++;
+
+ // Already visited?
+ if (this->Visited.insert(Next).second)
+ VisitQueue.push(QueueElement(Next, None));
+ }
+ VisitQueue.pop();
+
+ // Go to the next element skipping markers if needed.
+ if (!VisitQueue.empty()) {
+ Head = VisitQueue.front();
+ if (Head != None)
+ return;
+ Level += 1;
+ VisitQueue.pop();
+
+ // Don't push another marker if this is the last
+ // element.
+ if (!VisitQueue.empty())
+ VisitQueue.push(None);
+ }
+ }
+
+public:
+ using pointer = typename super::pointer;
+
+ // Provide static begin and end methods as our public "constructors"
+ static bf_iterator begin(const GraphT &G) {
+ return bf_iterator(GT::getEntryNode(G));
+ }
+
+ static bf_iterator end(const GraphT &G) { return bf_iterator(); }
+
+ bool operator==(const bf_iterator &RHS) const {
+ return VisitQueue == RHS.VisitQueue;
+ }
+
+ bool operator!=(const bf_iterator &RHS) const { return !(*this == RHS); }
+
+ const NodeRef &operator*() const { return VisitQueue.front()->first; }
+
+ // This is a nonstandard operator-> that dereferenfces the pointer an extra
+ // time so that you can actually call methods on the node, because the
+ // contained type is a pointer.
+ NodeRef operator->() const { return **this; }
+
+ bf_iterator &operator++() { // Pre-increment
+ toNext();
+ return *this;
+ }
+
+ bf_iterator operator++(int) { // Post-increment
+ bf_iterator ItCopy = *this;
+ ++*this;
+ return ItCopy;
+ }
+
+ unsigned getLevel() const { return Level; }
+};
+
+// Provide global constructors that automatically figure out correct types.
+template <class T> bf_iterator<T> bf_begin(const T &G) {
+ return bf_iterator<T>::begin(G);
+}
+
+template <class T> bf_iterator<T> bf_end(const T &G) {
+ return bf_iterator<T>::end(G);
+}
+
+// Provide an accessor method to use them in range-based patterns.
+template <class T> iterator_range<bf_iterator<T>> breadth_first(const T &G) {
+ return make_range(bf_begin(G), bf_end(G));
+}
+
+} // end namespace llvm
+
+#endif // LLVM_ADT_BREADTHFIRSTITERATOR_H
diff --git a/contrib/llvm/include/llvm/ADT/DAGDeltaAlgorithm.h b/contrib/llvm/include/llvm/ADT/DAGDeltaAlgorithm.h
index 5ea0fe8..41fdd43 100644
--- a/contrib/llvm/include/llvm/ADT/DAGDeltaAlgorithm.h
+++ b/contrib/llvm/include/llvm/ADT/DAGDeltaAlgorithm.h
@@ -1,4 +1,4 @@
-//===--- DAGDeltaAlgorithm.h - A DAG Minimization Algorithm ----*- C++ -*--===//
+//===- DAGDeltaAlgorithm.h - A DAG Minimization Algorithm ------*- C++ -*--===//
//
// The LLVM Compiler Infrastructure
//
@@ -40,12 +40,12 @@ class DAGDeltaAlgorithm {
virtual void anchor();
public:
- typedef unsigned change_ty;
- typedef std::pair<change_ty, change_ty> edge_ty;
+ using change_ty = unsigned;
+ using edge_ty = std::pair<change_ty, change_ty>;
// FIXME: Use a decent data structure.
- typedef std::set<change_ty> changeset_ty;
- typedef std::vector<changeset_ty> changesetlist_ty;
+ using changeset_ty = std::set<change_ty>;
+ using changesetlist_ty = std::vector<changeset_ty>;
public:
virtual ~DAGDeltaAlgorithm() = default;
diff --git a/contrib/llvm/include/llvm/ADT/DeltaAlgorithm.h b/contrib/llvm/include/llvm/ADT/DeltaAlgorithm.h
index a26f37d..6becb2a 100644
--- a/contrib/llvm/include/llvm/ADT/DeltaAlgorithm.h
+++ b/contrib/llvm/include/llvm/ADT/DeltaAlgorithm.h
@@ -1,4 +1,4 @@
-//===--- DeltaAlgorithm.h - A Set Minimization Algorithm -------*- C++ -*--===//
+//===- DeltaAlgorithm.h - A Set Minimization Algorithm ---------*- C++ -*--===//
//
// The LLVM Compiler Infrastructure
//
@@ -35,10 +35,10 @@ namespace llvm {
/// predicate.
class DeltaAlgorithm {
public:
- typedef unsigned change_ty;
+ using change_ty = unsigned;
// FIXME: Use a decent data structure.
- typedef std::set<change_ty> changeset_ty;
- typedef std::vector<changeset_ty> changesetlist_ty;
+ using changeset_ty = std::set<change_ty>;
+ using changesetlist_ty = std::vector<changeset_ty>;
private:
/// Cache of failed test results. Successful test results are never cached
@@ -90,4 +90,4 @@ public:
} // end namespace llvm
-#endif
+#endif // LLVM_ADT_DELTAALGORITHM_H
diff --git a/contrib/llvm/include/llvm/ADT/DenseMap.h b/contrib/llvm/include/llvm/ADT/DenseMap.h
index 0b4b09d..b311e69 100644
--- a/contrib/llvm/include/llvm/ADT/DenseMap.h
+++ b/contrib/llvm/include/llvm/ADT/DenseMap.h
@@ -25,8 +25,8 @@
#include <cstddef>
#include <cstring>
#include <iterator>
-#include <limits>
#include <new>
+#include <type_traits>
#include <utility>
namespace llvm {
@@ -53,15 +53,19 @@ class DenseMapIterator;
template <typename DerivedT, typename KeyT, typename ValueT, typename KeyInfoT,
typename BucketT>
class DenseMapBase : public DebugEpochBase {
+ template <typename T>
+ using const_arg_type_t = typename const_pointer_or_const_ref<T>::type;
+
public:
- typedef unsigned size_type;
- typedef KeyT key_type;
- typedef ValueT mapped_type;
- typedef BucketT value_type;
-
- typedef DenseMapIterator<KeyT, ValueT, KeyInfoT, BucketT> iterator;
- typedef DenseMapIterator<KeyT, ValueT, KeyInfoT, BucketT, true>
- const_iterator;
+ using size_type = unsigned;
+ using key_type = KeyT;
+ using mapped_type = ValueT;
+ using value_type = BucketT;
+
+ using iterator = DenseMapIterator<KeyT, ValueT, KeyInfoT, BucketT>;
+ using const_iterator =
+ DenseMapIterator<KeyT, ValueT, KeyInfoT, BucketT, true>;
+
inline iterator begin() {
// When the map is empty, avoid the overhead of AdvancePastEmptyBuckets().
return empty() ? end() : iterator(getBuckets(), getBucketsEnd(), *this);
@@ -119,18 +123,18 @@ public:
}
/// Return 1 if the specified key is in the map, 0 otherwise.
- size_type count(const KeyT &Val) const {
+ size_type count(const_arg_type_t<KeyT> Val) const {
const BucketT *TheBucket;
return LookupBucketFor(Val, TheBucket) ? 1 : 0;
}
- iterator find(const KeyT &Val) {
+ iterator find(const_arg_type_t<KeyT> Val) {
BucketT *TheBucket;
if (LookupBucketFor(Val, TheBucket))
return iterator(TheBucket, getBucketsEnd(), *this, true);
return end();
}
- const_iterator find(const KeyT &Val) const {
+ const_iterator find(const_arg_type_t<KeyT> Val) const {
const BucketT *TheBucket;
if (LookupBucketFor(Val, TheBucket))
return const_iterator(TheBucket, getBucketsEnd(), *this, true);
@@ -159,7 +163,7 @@ public:
/// lookup - Return the entry for the specified key, or a default
/// constructed value if no such entry exists.
- ValueT lookup(const KeyT &Val) const {
+ ValueT lookup(const_arg_type_t<KeyT> Val) const {
const BucketT *TheBucket;
if (LookupBucketFor(Val, TheBucket))
return TheBucket->getSecond();
@@ -384,13 +388,18 @@ protected:
static unsigned getHashValue(const KeyT &Val) {
return KeyInfoT::getHashValue(Val);
}
+
template<typename LookupKeyT>
static unsigned getHashValue(const LookupKeyT &Val) {
return KeyInfoT::getHashValue(Val);
}
+
static const KeyT getEmptyKey() {
+ static_assert(std::is_base_of<DenseMapBase, DerivedT>::value,
+ "Must pass the derived type to this template!");
return KeyInfoT::getEmptyKey();
}
+
static const KeyT getTombstoneKey() {
return KeyInfoT::getTombstoneKey();
}
@@ -399,39 +408,51 @@ private:
unsigned getNumEntries() const {
return static_cast<const DerivedT *>(this)->getNumEntries();
}
+
void setNumEntries(unsigned Num) {
static_cast<DerivedT *>(this)->setNumEntries(Num);
}
+
void incrementNumEntries() {
setNumEntries(getNumEntries() + 1);
}
+
void decrementNumEntries() {
setNumEntries(getNumEntries() - 1);
}
+
unsigned getNumTombstones() const {
return static_cast<const DerivedT *>(this)->getNumTombstones();
}
+
void setNumTombstones(unsigned Num) {
static_cast<DerivedT *>(this)->setNumTombstones(Num);
}
+
void incrementNumTombstones() {
setNumTombstones(getNumTombstones() + 1);
}
+
void decrementNumTombstones() {
setNumTombstones(getNumTombstones() - 1);
}
+
const BucketT *getBuckets() const {
return static_cast<const DerivedT *>(this)->getBuckets();
}
+
BucketT *getBuckets() {
return static_cast<DerivedT *>(this)->getBuckets();
}
+
unsigned getNumBuckets() const {
return static_cast<const DerivedT *>(this)->getNumBuckets();
}
+
BucketT *getBucketsEnd() {
return getBuckets() + getNumBuckets();
}
+
const BucketT *getBucketsEnd() const {
return getBuckets() + getNumBuckets();
}
@@ -582,10 +603,11 @@ template <typename KeyT, typename ValueT,
typename BucketT = detail::DenseMapPair<KeyT, ValueT>>
class DenseMap : public DenseMapBase<DenseMap<KeyT, ValueT, KeyInfoT, BucketT>,
KeyT, ValueT, KeyInfoT, BucketT> {
+ friend class DenseMapBase<DenseMap, KeyT, ValueT, KeyInfoT, BucketT>;
+
// Lift some types from the dependent base class into this class for
// simplicity of referring to them.
- typedef DenseMapBase<DenseMap, KeyT, ValueT, KeyInfoT, BucketT> BaseT;
- friend class DenseMapBase<DenseMap, KeyT, ValueT, KeyInfoT, BucketT>;
+ using BaseT = DenseMapBase<DenseMap, KeyT, ValueT, KeyInfoT, BucketT>;
BucketT *Buckets;
unsigned NumEntries;
@@ -700,6 +722,7 @@ private:
unsigned getNumEntries() const {
return NumEntries;
}
+
void setNumEntries(unsigned Num) {
NumEntries = Num;
}
@@ -707,6 +730,7 @@ private:
unsigned getNumTombstones() const {
return NumTombstones;
}
+
void setNumTombstones(unsigned Num) {
NumTombstones = Num;
}
@@ -738,10 +762,12 @@ class SmallDenseMap
: public DenseMapBase<
SmallDenseMap<KeyT, ValueT, InlineBuckets, KeyInfoT, BucketT>, KeyT,
ValueT, KeyInfoT, BucketT> {
+ friend class DenseMapBase<SmallDenseMap, KeyT, ValueT, KeyInfoT, BucketT>;
+
// Lift some types from the dependent base class into this class for
// simplicity of referring to them.
- typedef DenseMapBase<SmallDenseMap, KeyT, ValueT, KeyInfoT, BucketT> BaseT;
- friend class DenseMapBase<SmallDenseMap, KeyT, ValueT, KeyInfoT, BucketT>;
+ using BaseT = DenseMapBase<SmallDenseMap, KeyT, ValueT, KeyInfoT, BucketT>;
+
static_assert(isPowerOf2_64(InlineBuckets),
"InlineBuckets must be a power of 2.");
@@ -967,6 +993,7 @@ private:
unsigned getNumEntries() const {
return NumEntries;
}
+
void setNumEntries(unsigned Num) {
// NumEntries is hardcoded to be 31 bits wide.
assert(Num < (1U << 31) && "Cannot support more than 1<<31 entries");
@@ -976,6 +1003,7 @@ private:
unsigned getNumTombstones() const {
return NumTombstones;
}
+
void setNumTombstones(unsigned Num) {
NumTombstones = Num;
}
@@ -987,15 +1015,18 @@ private:
// 'storage.buffer' static type is 'char *'.
return reinterpret_cast<const BucketT *>(storage.buffer);
}
+
BucketT *getInlineBuckets() {
return const_cast<BucketT *>(
const_cast<const SmallDenseMap *>(this)->getInlineBuckets());
}
+
const LargeRep *getLargeRep() const {
assert(!Small);
// Note, same rule about aliasing as with getInlineBuckets.
return reinterpret_cast<const LargeRep *>(storage.buffer);
}
+
LargeRep *getLargeRep() {
return const_cast<LargeRep *>(
const_cast<const SmallDenseMap *>(this)->getLargeRep());
@@ -1004,10 +1035,12 @@ private:
const BucketT *getBuckets() const {
return Small ? getInlineBuckets() : getLargeRep()->Buckets;
}
+
BucketT *getBuckets() {
return const_cast<BucketT *>(
const_cast<const SmallDenseMap *>(this)->getBuckets());
}
+
unsigned getNumBuckets() const {
return Small ? InlineBuckets : getLargeRep()->NumBuckets;
}
@@ -1032,23 +1065,25 @@ private:
template <typename KeyT, typename ValueT, typename KeyInfoT, typename Bucket,
bool IsConst>
class DenseMapIterator : DebugEpochBase::HandleBase {
- typedef DenseMapIterator<KeyT, ValueT, KeyInfoT, Bucket, true> ConstIterator;
friend class DenseMapIterator<KeyT, ValueT, KeyInfoT, Bucket, true>;
friend class DenseMapIterator<KeyT, ValueT, KeyInfoT, Bucket, false>;
+ using ConstIterator = DenseMapIterator<KeyT, ValueT, KeyInfoT, Bucket, true>;
+
public:
- typedef ptrdiff_t difference_type;
- typedef typename std::conditional<IsConst, const Bucket, Bucket>::type
- value_type;
- typedef value_type *pointer;
- typedef value_type &reference;
- typedef std::forward_iterator_tag iterator_category;
+ using difference_type = ptrdiff_t;
+ using value_type =
+ typename std::conditional<IsConst, const Bucket, Bucket>::type;
+ using pointer = value_type *;
+ using reference = value_type &;
+ using iterator_category = std::forward_iterator_tag;
private:
- pointer Ptr, End;
+ pointer Ptr = nullptr;
+ pointer End = nullptr;
public:
- DenseMapIterator() : Ptr(nullptr), End(nullptr) {}
+ DenseMapIterator() = default;
DenseMapIterator(pointer Pos, pointer E, const DebugEpochBase &Epoch,
bool NoAdvance = false)
diff --git a/contrib/llvm/include/llvm/ADT/DenseMapInfo.h b/contrib/llvm/include/llvm/ADT/DenseMapInfo.h
index a844ebc..a96904c 100644
--- a/contrib/llvm/include/llvm/ADT/DenseMapInfo.h
+++ b/contrib/llvm/include/llvm/ADT/DenseMapInfo.h
@@ -18,7 +18,10 @@
#include "llvm/ADT/Hashing.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/PointerLikeTypeTraits.h"
-#include "llvm/Support/type_traits.h"
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
+#include <utility>
namespace llvm {
@@ -38,15 +41,18 @@ struct DenseMapInfo<T*> {
Val <<= PointerLikeTypeTraits<T*>::NumLowBitsAvailable;
return reinterpret_cast<T*>(Val);
}
+
static inline T* getTombstoneKey() {
uintptr_t Val = static_cast<uintptr_t>(-2);
Val <<= PointerLikeTypeTraits<T*>::NumLowBitsAvailable;
return reinterpret_cast<T*>(Val);
}
+
static unsigned getHashValue(const T *PtrVal) {
return (unsigned((uintptr_t)PtrVal) >> 4) ^
(unsigned((uintptr_t)PtrVal) >> 9);
}
+
static bool isEqual(const T *LHS, const T *RHS) { return LHS == RHS; }
};
@@ -55,16 +61,29 @@ template<> struct DenseMapInfo<char> {
static inline char getEmptyKey() { return ~0; }
static inline char getTombstoneKey() { return ~0 - 1; }
static unsigned getHashValue(const char& Val) { return Val * 37U; }
+
static bool isEqual(const char &LHS, const char &RHS) {
return LHS == RHS;
}
};
+// Provide DenseMapInfo for unsigned shorts.
+template <> struct DenseMapInfo<unsigned short> {
+ static inline unsigned short getEmptyKey() { return 0xFFFF; }
+ static inline unsigned short getTombstoneKey() { return 0xFFFF - 1; }
+ static unsigned getHashValue(const unsigned short &Val) { return Val * 37U; }
+
+ static bool isEqual(const unsigned short &LHS, const unsigned short &RHS) {
+ return LHS == RHS;
+ }
+};
+
// Provide DenseMapInfo for unsigned ints.
template<> struct DenseMapInfo<unsigned> {
static inline unsigned getEmptyKey() { return ~0U; }
static inline unsigned getTombstoneKey() { return ~0U - 1; }
static unsigned getHashValue(const unsigned& Val) { return Val * 37U; }
+
static bool isEqual(const unsigned& LHS, const unsigned& RHS) {
return LHS == RHS;
}
@@ -74,9 +93,11 @@ template<> struct DenseMapInfo<unsigned> {
template<> struct DenseMapInfo<unsigned long> {
static inline unsigned long getEmptyKey() { return ~0UL; }
static inline unsigned long getTombstoneKey() { return ~0UL - 1L; }
+
static unsigned getHashValue(const unsigned long& Val) {
return (unsigned)(Val * 37UL);
}
+
static bool isEqual(const unsigned long& LHS, const unsigned long& RHS) {
return LHS == RHS;
}
@@ -86,20 +107,31 @@ template<> struct DenseMapInfo<unsigned long> {
template<> struct DenseMapInfo<unsigned long long> {
static inline unsigned long long getEmptyKey() { return ~0ULL; }
static inline unsigned long long getTombstoneKey() { return ~0ULL - 1ULL; }
+
static unsigned getHashValue(const unsigned long long& Val) {
return (unsigned)(Val * 37ULL);
}
+
static bool isEqual(const unsigned long long& LHS,
const unsigned long long& RHS) {
return LHS == RHS;
}
};
+// Provide DenseMapInfo for shorts.
+template <> struct DenseMapInfo<short> {
+ static inline short getEmptyKey() { return 0x7FFF; }
+ static inline short getTombstoneKey() { return -0x7FFF - 1; }
+ static unsigned getHashValue(const short &Val) { return Val * 37U; }
+ static bool isEqual(const short &LHS, const short &RHS) { return LHS == RHS; }
+};
+
// Provide DenseMapInfo for ints.
template<> struct DenseMapInfo<int> {
static inline int getEmptyKey() { return 0x7fffffff; }
static inline int getTombstoneKey() { return -0x7fffffff - 1; }
static unsigned getHashValue(const int& Val) { return (unsigned)(Val * 37U); }
+
static bool isEqual(const int& LHS, const int& RHS) {
return LHS == RHS;
}
@@ -110,10 +142,13 @@ template<> struct DenseMapInfo<long> {
static inline long getEmptyKey() {
return (1UL << (sizeof(long) * 8 - 1)) - 1UL;
}
+
static inline long getTombstoneKey() { return getEmptyKey() - 1L; }
+
static unsigned getHashValue(const long& Val) {
return (unsigned)(Val * 37UL);
}
+
static bool isEqual(const long& LHS, const long& RHS) {
return LHS == RHS;
}
@@ -123,9 +158,11 @@ template<> struct DenseMapInfo<long> {
template<> struct DenseMapInfo<long long> {
static inline long long getEmptyKey() { return 0x7fffffffffffffffLL; }
static inline long long getTombstoneKey() { return -0x7fffffffffffffffLL-1; }
+
static unsigned getHashValue(const long long& Val) {
return (unsigned)(Val * 37ULL);
}
+
static bool isEqual(const long long& LHS,
const long long& RHS) {
return LHS == RHS;
@@ -134,19 +171,21 @@ template<> struct DenseMapInfo<long long> {
// Provide DenseMapInfo for all pairs whose members have info.
template<typename T, typename U>
-struct DenseMapInfo<std::pair<T, U> > {
- typedef std::pair<T, U> Pair;
- typedef DenseMapInfo<T> FirstInfo;
- typedef DenseMapInfo<U> SecondInfo;
+struct DenseMapInfo<std::pair<T, U>> {
+ using Pair = std::pair<T, U>;
+ using FirstInfo = DenseMapInfo<T>;
+ using SecondInfo = DenseMapInfo<U>;
static inline Pair getEmptyKey() {
return std::make_pair(FirstInfo::getEmptyKey(),
SecondInfo::getEmptyKey());
}
+
static inline Pair getTombstoneKey() {
return std::make_pair(FirstInfo::getTombstoneKey(),
SecondInfo::getTombstoneKey());
}
+
static unsigned getHashValue(const Pair& PairVal) {
uint64_t key = (uint64_t)FirstInfo::getHashValue(PairVal.first) << 32
| (uint64_t)SecondInfo::getHashValue(PairVal.second);
@@ -160,6 +199,7 @@ struct DenseMapInfo<std::pair<T, U> > {
key ^= (key >> 31);
return (unsigned)key;
}
+
static bool isEqual(const Pair &LHS, const Pair &RHS) {
return FirstInfo::isEqual(LHS.first, RHS.first) &&
SecondInfo::isEqual(LHS.second, RHS.second);
@@ -172,16 +212,19 @@ template <> struct DenseMapInfo<StringRef> {
return StringRef(reinterpret_cast<const char *>(~static_cast<uintptr_t>(0)),
0);
}
+
static inline StringRef getTombstoneKey() {
return StringRef(reinterpret_cast<const char *>(~static_cast<uintptr_t>(1)),
0);
}
+
static unsigned getHashValue(StringRef Val) {
assert(Val.data() != getEmptyKey().data() && "Cannot hash the empty key!");
assert(Val.data() != getTombstoneKey().data() &&
"Cannot hash the tombstone key!");
return (unsigned)(hash_value(Val));
}
+
static bool isEqual(StringRef LHS, StringRef RHS) {
if (RHS.data() == getEmptyKey().data())
return LHS.data() == getEmptyKey().data();
@@ -197,16 +240,19 @@ template <typename T> struct DenseMapInfo<ArrayRef<T>> {
return ArrayRef<T>(reinterpret_cast<const T *>(~static_cast<uintptr_t>(0)),
size_t(0));
}
+
static inline ArrayRef<T> getTombstoneKey() {
return ArrayRef<T>(reinterpret_cast<const T *>(~static_cast<uintptr_t>(1)),
size_t(0));
}
+
static unsigned getHashValue(ArrayRef<T> Val) {
assert(Val.data() != getEmptyKey().data() && "Cannot hash the empty key!");
assert(Val.data() != getTombstoneKey().data() &&
"Cannot hash the tombstone key!");
return (unsigned)(hash_value(Val));
}
+
static bool isEqual(ArrayRef<T> LHS, ArrayRef<T> RHS) {
if (RHS.data() == getEmptyKey().data())
return LHS.data() == getEmptyKey().data();
@@ -218,4 +264,4 @@ template <typename T> struct DenseMapInfo<ArrayRef<T>> {
} // end namespace llvm
-#endif
+#endif // LLVM_ADT_DENSEMAPINFO_H
diff --git a/contrib/llvm/include/llvm/ADT/DenseSet.h b/contrib/llvm/include/llvm/ADT/DenseSet.h
index b25d3b7c..7e5171c 100644
--- a/contrib/llvm/include/llvm/ADT/DenseSet.h
+++ b/contrib/llvm/include/llvm/ADT/DenseSet.h
@@ -15,11 +15,18 @@
#define LLVM_ADT_DENSESET_H
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseMapInfo.h"
+#include "llvm/Support/type_traits.h"
+#include <algorithm>
+#include <cstddef>
#include <initializer_list>
+#include <iterator>
+#include <utility>
namespace llvm {
namespace detail {
+
struct DenseSetEmpty {};
// Use the empty base class trick so we can create a DenseMap where the buckets
@@ -49,10 +56,13 @@ class DenseSetImpl {
"DenseMap buckets unexpectedly large!");
MapTy TheMap;
+ template <typename T>
+ using const_arg_type_t = typename const_pointer_or_const_ref<T>::type;
+
public:
- typedef ValueT key_type;
- typedef ValueT value_type;
- typedef unsigned size_type;
+ using key_type = ValueT;
+ using value_type = ValueT;
+ using size_type = unsigned;
explicit DenseSetImpl(unsigned InitialReserve = 0) : TheMap(InitialReserve) {}
@@ -78,7 +88,7 @@ public:
}
/// Return 1 if the specified key is in the set, 0 otherwise.
- size_type count(const ValueT &V) const {
+ size_type count(const_arg_type_t<ValueT> V) const {
return TheMap.count(V);
}
@@ -90,43 +100,52 @@ public:
// Iterators.
+ class ConstIterator;
+
class Iterator {
typename MapTy::iterator I;
friend class DenseSetImpl;
+ friend class ConstIterator;
public:
- typedef typename MapTy::iterator::difference_type difference_type;
- typedef ValueT value_type;
- typedef value_type *pointer;
- typedef value_type &reference;
- typedef std::forward_iterator_tag iterator_category;
+ using difference_type = typename MapTy::iterator::difference_type;
+ using value_type = ValueT;
+ using pointer = value_type *;
+ using reference = value_type &;
+ using iterator_category = std::forward_iterator_tag;
+ Iterator() = default;
Iterator(const typename MapTy::iterator &i) : I(i) {}
ValueT &operator*() { return I->getFirst(); }
+ const ValueT &operator*() const { return I->getFirst(); }
ValueT *operator->() { return &I->getFirst(); }
+ const ValueT *operator->() const { return &I->getFirst(); }
Iterator& operator++() { ++I; return *this; }
Iterator operator++(int) { auto T = *this; ++I; return T; }
- bool operator==(const Iterator& X) const { return I == X.I; }
- bool operator!=(const Iterator& X) const { return I != X.I; }
+ bool operator==(const ConstIterator& X) const { return I == X.I; }
+ bool operator!=(const ConstIterator& X) const { return I != X.I; }
};
class ConstIterator {
typename MapTy::const_iterator I;
friend class DenseSet;
+ friend class Iterator;
public:
- typedef typename MapTy::const_iterator::difference_type difference_type;
- typedef ValueT value_type;
- typedef value_type *pointer;
- typedef value_type &reference;
- typedef std::forward_iterator_tag iterator_category;
-
+ using difference_type = typename MapTy::const_iterator::difference_type;
+ using value_type = ValueT;
+ using pointer = value_type *;
+ using reference = value_type &;
+ using iterator_category = std::forward_iterator_tag;
+
+ ConstIterator() = default;
+ ConstIterator(const Iterator &B) : I(B.I) {}
ConstIterator(const typename MapTy::const_iterator &i) : I(i) {}
- const ValueT &operator*() { return I->getFirst(); }
- const ValueT *operator->() { return &I->getFirst(); }
+ const ValueT &operator*() const { return I->getFirst(); }
+ const ValueT *operator->() const { return &I->getFirst(); }
ConstIterator& operator++() { ++I; return *this; }
ConstIterator operator++(int) { auto T = *this; ++I; return T; }
@@ -134,8 +153,8 @@ public:
bool operator!=(const ConstIterator& X) const { return I != X.I; }
};
- typedef Iterator iterator;
- typedef ConstIterator const_iterator;
+ using iterator = Iterator;
+ using const_iterator = ConstIterator;
iterator begin() { return Iterator(TheMap.begin()); }
iterator end() { return Iterator(TheMap.end()); }
@@ -143,8 +162,8 @@ public:
const_iterator begin() const { return ConstIterator(TheMap.begin()); }
const_iterator end() const { return ConstIterator(TheMap.end()); }
- iterator find(const ValueT &V) { return Iterator(TheMap.find(V)); }
- const_iterator find(const ValueT &V) const {
+ iterator find(const_arg_type_t<ValueT> V) { return Iterator(TheMap.find(V)); }
+ const_iterator find(const_arg_type_t<ValueT> V) const {
return ConstIterator(TheMap.find(V));
}
@@ -195,7 +214,7 @@ public:
}
};
-} // namespace detail
+} // end namespace detail
/// Implements a dense probed hash-table based set.
template <typename ValueT, typename ValueInfoT = DenseMapInfo<ValueT>>
@@ -233,4 +252,4 @@ public:
} // end namespace llvm
-#endif
+#endif // LLVM_ADT_DENSESET_H
diff --git a/contrib/llvm/include/llvm/ADT/DepthFirstIterator.h b/contrib/llvm/include/llvm/ADT/DepthFirstIterator.h
index c545732..e964d7f 100644
--- a/contrib/llvm/include/llvm/ADT/DepthFirstIterator.h
+++ b/contrib/llvm/include/llvm/ADT/DepthFirstIterator.h
@@ -68,13 +68,14 @@ public:
// cross edges in the spanning tree but is not used in the common case.
template <typename NodeRef, unsigned SmallSize=8>
struct df_iterator_default_set : public SmallPtrSet<NodeRef, SmallSize> {
- typedef SmallPtrSet<NodeRef, SmallSize> BaseSet;
- typedef typename BaseSet::iterator iterator;
- std::pair<iterator,bool> insert(NodeRef N) { return BaseSet::insert(N) ; }
+ using BaseSet = SmallPtrSet<NodeRef, SmallSize>;
+ using iterator = typename BaseSet::iterator;
+
+ std::pair<iterator,bool> insert(NodeRef N) { return BaseSet::insert(N); }
template <typename IterT>
void insert(IterT Begin, IterT End) { BaseSet::insert(Begin,End); }
- void completed(NodeRef) { }
+ void completed(NodeRef) {}
};
// Generic Depth First Iterator
@@ -85,15 +86,14 @@ template <class GraphT,
class df_iterator
: public std::iterator<std::forward_iterator_tag, typename GT::NodeRef>,
public df_iterator_storage<SetType, ExtStorage> {
- typedef std::iterator<std::forward_iterator_tag, typename GT::NodeRef> super;
-
- typedef typename GT::NodeRef NodeRef;
- typedef typename GT::ChildIteratorType ChildItTy;
+ using super = std::iterator<std::forward_iterator_tag, typename GT::NodeRef>;
+ using NodeRef = typename GT::NodeRef;
+ using ChildItTy = typename GT::ChildIteratorType;
// First element is node reference, second is the 'next child' to visit.
// The second child is initialized lazily to pick up graph changes during the
// DFS.
- typedef std::pair<NodeRef, Optional<ChildItTy>> StackElement;
+ using StackElement = std::pair<NodeRef, Optional<ChildItTy>>;
// VisitStack - Used to maintain the ordering. Top = current block
std::vector<StackElement> VisitStack;
@@ -103,12 +103,15 @@ private:
this->Visited.insert(Node);
VisitStack.push_back(StackElement(Node, None));
}
+
inline df_iterator() = default; // End is when stack is empty
+
inline df_iterator(NodeRef Node, SetType &S)
: df_iterator_storage<SetType, ExtStorage>(S) {
if (this->Visited.insert(Node).second)
VisitStack.push_back(StackElement(Node, None));
}
+
inline df_iterator(SetType &S)
: df_iterator_storage<SetType, ExtStorage>(S) {
// End is when stack is empty
@@ -135,14 +138,14 @@ private:
}
}
this->Visited.completed(Node);
-
+
// Oops, ran out of successors... go up a level on the stack.
VisitStack.pop_back();
} while (!VisitStack.empty());
}
public:
- typedef typename super::pointer pointer;
+ using pointer = typename super::pointer;
// Provide static begin and end methods as our public "constructors"
static df_iterator begin(const GraphT &G) {
diff --git a/contrib/llvm/include/llvm/ADT/EquivalenceClasses.h b/contrib/llvm/include/llvm/ADT/EquivalenceClasses.h
index 8fcac17..af293d4 100644
--- a/contrib/llvm/include/llvm/ADT/EquivalenceClasses.h
+++ b/contrib/llvm/include/llvm/ADT/EquivalenceClasses.h
@@ -1,4 +1,4 @@
-//===-- llvm/ADT/EquivalenceClasses.h - Generic Equiv. Classes --*- C++ -*-===//
+//===- llvm/ADT/EquivalenceClasses.h - Generic Equiv. Classes ---*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -69,6 +69,7 @@ class EquivalenceClasses {
/// leader is determined by a bit stolen from one of the pointers.
class ECValue {
friend class EquivalenceClasses;
+
mutable const ECValue *Leader, *Next;
ElemTy Data;
@@ -141,14 +142,14 @@ public:
//
/// iterator* - Provides a way to iterate over all values in the set.
- typedef typename std::set<ECValue>::const_iterator iterator;
+ using iterator = typename std::set<ECValue>::const_iterator;
+
iterator begin() const { return TheMapping.begin(); }
iterator end() const { return TheMapping.end(); }
bool empty() const { return TheMapping.empty(); }
/// member_* Iterate over the members of an equivalence class.
- ///
class member_iterator;
member_iterator member_begin(iterator I) const {
// Only leaders provide anything to iterate over.
@@ -204,7 +205,6 @@ public:
/// equivalence class it is in. This does the path-compression part that
/// makes union-find "union findy". This returns an end iterator if the value
/// is not in the equivalence class.
- ///
member_iterator findLeader(iterator I) const {
if (I == TheMapping.end()) return member_end();
return member_iterator(I->getLeader());
@@ -241,15 +241,17 @@ public:
class member_iterator : public std::iterator<std::forward_iterator_tag,
const ElemTy, ptrdiff_t> {
- typedef std::iterator<std::forward_iterator_tag,
- const ElemTy, ptrdiff_t> super;
- const ECValue *Node;
friend class EquivalenceClasses;
+ using super = std::iterator<std::forward_iterator_tag,
+ const ElemTy, ptrdiff_t>;
+
+ const ECValue *Node;
+
public:
- typedef size_t size_type;
- typedef typename super::pointer pointer;
- typedef typename super::reference reference;
+ using size_type = size_t;
+ using pointer = typename super::pointer;
+ using reference = typename super::reference;
explicit member_iterator() = default;
explicit member_iterator(const ECValue *N) : Node(N) {}
diff --git a/contrib/llvm/include/llvm/ADT/FoldingSet.h b/contrib/llvm/include/llvm/ADT/FoldingSet.h
index dab1829..c5987a9 100644
--- a/contrib/llvm/include/llvm/ADT/FoldingSet.h
+++ b/contrib/llvm/include/llvm/ADT/FoldingSet.h
@@ -40,7 +40,7 @@ namespace llvm {
/// FoldingSetNode. The node class must also define a Profile method used to
/// establish the unique bits of data for the node. The Profile method is
/// passed a FoldingSetNodeID object which is used to gather the bits. Just
-/// call one of the Add* functions defined in the FoldingSetImpl::NodeID class.
+/// call one of the Add* functions defined in the FoldingSetBase::NodeID class.
/// NOTE: That the folding set does not own the nodes and it is the
/// responsibility of the user to dispose of the nodes.
///
@@ -104,13 +104,13 @@ class FoldingSetNodeID;
class StringRef;
//===----------------------------------------------------------------------===//
-/// FoldingSetImpl - Implements the folding set functionality. The main
+/// FoldingSetBase - Implements the folding set functionality. The main
/// structure is an array of buckets. Each bucket is indexed by the hash of
/// the nodes it contains. The bucket itself points to the nodes contained
/// in the bucket via a singly linked list. The last node in the list points
/// back to the bucket to facilitate node removal.
///
-class FoldingSetImpl {
+class FoldingSetBase {
virtual void anchor(); // Out of line virtual method.
protected:
@@ -126,10 +126,10 @@ protected:
/// is greater than twice the number of buckets.
unsigned NumNodes;
- explicit FoldingSetImpl(unsigned Log2InitSize = 6);
- FoldingSetImpl(FoldingSetImpl &&Arg);
- FoldingSetImpl &operator=(FoldingSetImpl &&RHS);
- ~FoldingSetImpl();
+ explicit FoldingSetBase(unsigned Log2InitSize = 6);
+ FoldingSetBase(FoldingSetBase &&Arg);
+ FoldingSetBase &operator=(FoldingSetBase &&RHS);
+ ~FoldingSetBase();
public:
//===--------------------------------------------------------------------===//
@@ -152,33 +152,6 @@ public:
/// clear - Remove all nodes from the folding set.
void clear();
- /// 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);
-
- /// 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);
-
- /// 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);
-
- /// 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);
-
- /// InsertNode - Insert the specified node into the folding set, knowing that
- /// it is not already in the folding set.
- void InsertNode(Node *N) {
- Node *Inserted = GetOrInsertNode(N);
- (void)Inserted;
- assert(Inserted == N && "Node already inserted!");
- }
-
/// size - Returns the number of nodes in the folding set.
unsigned size() const { return NumNodes; }
@@ -220,6 +193,28 @@ protected:
/// 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.
+
+ /// 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);
+
+ /// 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);
+
+ /// 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);
+
+ /// 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);
};
//===----------------------------------------------------------------------===//
@@ -293,7 +288,7 @@ public:
FoldingSetNodeIDRef(const unsigned *D, size_t S) : Data(D), Size(S) {}
/// ComputeHash - Compute a strong hash value for this FoldingSetNodeIDRef,
- /// used to lookup the node in the FoldingSetImpl.
+ /// used to lookup the node in the FoldingSetBase.
unsigned ComputeHash() const;
bool operator==(FoldingSetNodeIDRef) const;
@@ -345,7 +340,7 @@ public:
inline void clear() { Bits.clear(); }
/// ComputeHash - Compute a strong hash value for this FoldingSetNodeID, used
- /// to lookup the node in the FoldingSetImpl.
+ /// to lookup the node in the FoldingSetBase.
unsigned ComputeHash() const;
/// operator== - Used to compare two nodes to each other.
@@ -368,7 +363,7 @@ public:
};
// Convenience type to hide the implementation of the folding set.
-typedef FoldingSetImpl::Node FoldingSetNode;
+typedef FoldingSetBase::Node FoldingSetNode;
template<class T> class FoldingSetIterator;
template<class T> class FoldingSetBucketIterator;
@@ -408,6 +403,71 @@ 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 {
+protected:
+ explicit FoldingSetImpl(unsigned Log2InitSize)
+ : FoldingSetBase(Log2InitSize) {}
+
+ FoldingSetImpl(FoldingSetImpl &&Arg) = default;
+ FoldingSetImpl &operator=(FoldingSetImpl &&RHS) = default;
+ ~FoldingSetImpl() = default;
+
+public:
+ typedef FoldingSetIterator<T> iterator;
+ iterator begin() { return iterator(Buckets); }
+ iterator end() { return iterator(Buckets+NumBuckets); }
+
+ typedef FoldingSetIterator<const T> const_iterator;
+ const_iterator begin() const { return const_iterator(Buckets); }
+ const_iterator end() const { return const_iterator(Buckets+NumBuckets); }
+
+ typedef FoldingSetBucketIterator<T> bucket_iterator;
+
+ bucket_iterator bucket_begin(unsigned hash) {
+ return bucket_iterator(Buckets + (hash & (NumBuckets-1)));
+ }
+
+ bucket_iterator bucket_end(unsigned hash) {
+ return bucket_iterator(Buckets + (hash & (NumBuckets-1)), true);
+ }
+
+ /// 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); }
+
+ /// 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));
+ }
+
+ /// 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));
+ }
+
+ /// 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);
+ }
+
+ /// InsertNode - Insert the specified node into the folding set, knowing that
+ /// it is not already in the folding set.
+ void InsertNode(T *N) {
+ T *Inserted = GetOrInsertNode(N);
+ (void)Inserted;
+ assert(Inserted == N && "Node already inserted!");
+ }
+};
+
+//===----------------------------------------------------------------------===//
/// FoldingSet - This template class is used to instantiate a specialized
/// implementation of the folding set to the node class T. T must be a
/// subclass of FoldingSetNode and implement a Profile function.
@@ -416,8 +476,10 @@ DefaultContextualFoldingSetTrait<T, Ctx>::ComputeHash(T &X,
/// 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 {
-private:
+template <class T> class FoldingSet final : public FoldingSetImpl<T> {
+ using Super = FoldingSetImpl<T>;
+ using Node = typename Super::Node;
+
/// 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 {
@@ -442,45 +504,10 @@ private:
public:
explicit FoldingSet(unsigned Log2InitSize = 6)
- : FoldingSetImpl(Log2InitSize) {}
-
- FoldingSet(FoldingSet &&Arg) : FoldingSetImpl(std::move(Arg)) {}
- FoldingSet &operator=(FoldingSet &&RHS) {
- (void)FoldingSetImpl::operator=(std::move(RHS));
- return *this;
- }
-
- typedef FoldingSetIterator<T> iterator;
- iterator begin() { return iterator(Buckets); }
- iterator end() { return iterator(Buckets+NumBuckets); }
-
- typedef FoldingSetIterator<const T> const_iterator;
- const_iterator begin() const { return const_iterator(Buckets); }
- const_iterator end() const { return const_iterator(Buckets+NumBuckets); }
-
- typedef FoldingSetBucketIterator<T> bucket_iterator;
-
- bucket_iterator bucket_begin(unsigned hash) {
- return bucket_iterator(Buckets + (hash & (NumBuckets-1)));
- }
-
- bucket_iterator bucket_end(unsigned hash) {
- return bucket_iterator(Buckets + (hash & (NumBuckets-1)), true);
- }
+ : Super(Log2InitSize) {}
- /// 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(Node *N) {
- return static_cast<T *>(FoldingSetImpl::GetOrInsertNode(N));
- }
-
- /// 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 *>(FoldingSetImpl::FindNodeOrInsertPos(ID, InsertPos));
- }
+ FoldingSet(FoldingSet &&Arg) = default;
+ FoldingSet &operator=(FoldingSet &&RHS) = default;
};
//===----------------------------------------------------------------------===//
@@ -493,74 +520,42 @@ public:
/// function with signature
/// void Profile(FoldingSetNodeID &, Ctx);
template <class T, class Ctx>
-class ContextualFoldingSet final : public FoldingSetImpl {
+class ContextualFoldingSet final : public FoldingSetImpl<T> {
// Unfortunately, this can't derive from FoldingSet<T> because the
- // construction vtable for FoldingSet<T> requires
+ // construction of the vtable for FoldingSet<T> requires
// FoldingSet<T>::GetNodeProfile to be instantiated, which in turn
// requires a single-argument T::Profile().
-private:
+ using Super = FoldingSetImpl<T>;
+ using Node = typename Super::Node;
+
Ctx Context;
/// GetNodeProfile - Each instantiatation of the FoldingSet needs to provide a
/// way to convert nodes into a unique specifier.
- void GetNodeProfile(FoldingSetImpl::Node *N,
- FoldingSetNodeID &ID) const override {
+ void GetNodeProfile(Node *N, FoldingSetNodeID &ID) const override {
T *TN = static_cast<T *>(N);
ContextualFoldingSetTrait<T, Ctx>::Profile(*TN, ID, Context);
}
- bool NodeEquals(FoldingSetImpl::Node *N, const FoldingSetNodeID &ID,
- unsigned IDHash, FoldingSetNodeID &TempID) const override {
+ bool NodeEquals(Node *N, const FoldingSetNodeID &ID, unsigned IDHash,
+ FoldingSetNodeID &TempID) const override {
T *TN = static_cast<T *>(N);
return ContextualFoldingSetTrait<T, Ctx>::Equals(*TN, ID, IDHash, TempID,
Context);
}
- unsigned ComputeNodeHash(FoldingSetImpl::Node *N,
- FoldingSetNodeID &TempID) const override {
+ unsigned ComputeNodeHash(Node *N, FoldingSetNodeID &TempID) const override {
T *TN = static_cast<T *>(N);
return ContextualFoldingSetTrait<T, Ctx>::ComputeHash(*TN, TempID, Context);
}
public:
explicit ContextualFoldingSet(Ctx Context, unsigned Log2InitSize = 6)
- : FoldingSetImpl(Log2InitSize), Context(Context)
+ : Super(Log2InitSize), Context(Context)
{}
Ctx getContext() const { return Context; }
-
- typedef FoldingSetIterator<T> iterator;
- iterator begin() { return iterator(Buckets); }
- iterator end() { return iterator(Buckets+NumBuckets); }
-
- typedef FoldingSetIterator<const T> const_iterator;
- const_iterator begin() const { return const_iterator(Buckets); }
- const_iterator end() const { return const_iterator(Buckets+NumBuckets); }
-
- typedef FoldingSetBucketIterator<T> bucket_iterator;
-
- bucket_iterator bucket_begin(unsigned hash) {
- return bucket_iterator(Buckets + (hash & (NumBuckets-1)));
- }
-
- bucket_iterator bucket_end(unsigned hash) {
- return bucket_iterator(Buckets + (hash & (NumBuckets-1)), true);
- }
-
- /// 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(Node *N) {
- return static_cast<T *>(FoldingSetImpl::GetOrInsertNode(N));
- }
-
- /// 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 *>(FoldingSetImpl::FindNodeOrInsertPos(ID, InsertPos));
- }
};
//===----------------------------------------------------------------------===//
diff --git a/contrib/llvm/include/llvm/ADT/GraphTraits.h b/contrib/llvm/include/llvm/ADT/GraphTraits.h
index 29bbcb0..225d9eb 100644
--- a/contrib/llvm/include/llvm/ADT/GraphTraits.h
+++ b/contrib/llvm/include/llvm/ADT/GraphTraits.h
@@ -1,4 +1,4 @@
-//===-- llvm/ADT/GraphTraits.h - Graph traits template ----------*- C++ -*-===//
+//===- llvm/ADT/GraphTraits.h - Graph traits template -----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -18,6 +18,8 @@
#ifndef LLVM_ADT_GRAPHTRAITS_H
#define LLVM_ADT_GRAPHTRAITS_H
+#include "llvm/ADT/iterator_range.h"
+
namespace llvm {
// GraphTraits - This class should be specialized by different graph types...
@@ -39,7 +41,6 @@ struct GraphTraits {
// static ChildIteratorType child_end (NodeRef)
// Return iterators that point to the beginning and ending of the child
// node list for the specified node.
- //
// typedef ...iterator nodes_iterator; - dereference to a NodeRef
// static nodes_iterator nodes_begin(GraphType *G)
@@ -48,8 +49,6 @@ struct GraphTraits {
// static unsigned size (GraphType *G)
// Return total number of nodes in the graph
- //
-
// If anyone tries to use this class without having an appropriate
// specialization, make an error. If you get this error, it's because you
@@ -57,11 +56,9 @@ struct GraphTraits {
// graph, or you need to define it for a new graph type. Either that or
// your argument to XXX_begin(...) is unknown or needs to have the proper .h
// file #include'd.
- //
- typedef typename GraphType::UnknownGraphTypeError NodeRef;
+ using NodeRef = typename GraphType::UnknownGraphTypeError;
};
-
// Inverse - This class is used as a little marker class to tell the graph
// iterator to iterate over the graph in a graph defined "Inverse" ordering.
// Not all graphs define an inverse ordering, and if they do, it depends on
@@ -72,7 +69,7 @@ struct GraphTraits {
// for (; I != E; ++I) { ... }
//
// Which is equivalent to:
-// df_iterator<Inverse<Method*> > I = idf_begin(M), E = idf_end(M);
+// df_iterator<Inverse<Method*>> I = idf_begin(M), E = idf_end(M);
// for (; I != E; ++I) { ... }
//
template <class GraphType>
@@ -86,6 +83,34 @@ struct Inverse {
// inverse falls back to the original graph.
template <class T> struct GraphTraits<Inverse<Inverse<T>>> : GraphTraits<T> {};
-} // End llvm namespace
+// Provide iterator ranges for the graph traits nodes and children
+template <class GraphType>
+iterator_range<typename GraphTraits<GraphType>::nodes_iterator>
+nodes(const GraphType &G) {
+ return make_range(GraphTraits<GraphType>::nodes_begin(G),
+ GraphTraits<GraphType>::nodes_end(G));
+}
+template <class GraphType>
+iterator_range<typename GraphTraits<Inverse<GraphType>>::nodes_iterator>
+inverse_nodes(const GraphType &G) {
+ return make_range(GraphTraits<Inverse<GraphType>>::nodes_begin(G),
+ GraphTraits<Inverse<GraphType>>::nodes_end(G));
+}
+
+template <class GraphType>
+iterator_range<typename GraphTraits<GraphType>::ChildIteratorType>
+children(const typename GraphTraits<GraphType>::NodeRef &G) {
+ return make_range(GraphTraits<GraphType>::child_begin(G),
+ GraphTraits<GraphType>::child_end(G));
+}
+
+template <class GraphType>
+iterator_range<typename GraphTraits<Inverse<GraphType>>::ChildIteratorType>
+inverse_children(const typename GraphTraits<GraphType>::NodeRef &G) {
+ return make_range(GraphTraits<Inverse<GraphType>>::child_begin(G),
+ GraphTraits<Inverse<GraphType>>::child_end(G));
+}
+
+} // end namespace llvm
-#endif
+#endif // LLVM_ADT_GRAPHTRAITS_H
diff --git a/contrib/llvm/include/llvm/ADT/ImmutableList.h b/contrib/llvm/include/llvm/ADT/ImmutableList.h
index e5f51ba..60d63e0 100644
--- a/contrib/llvm/include/llvm/ADT/ImmutableList.h
+++ b/contrib/llvm/include/llvm/ADT/ImmutableList.h
@@ -63,8 +63,8 @@ public:
template <typename T>
class ImmutableList {
public:
- typedef T value_type;
- typedef ImmutableListFactory<T> Factory;
+ using value_type = T;
+ using Factory = ImmutableListFactory<T>;
private:
const ImmutableListImpl<T>* X;
@@ -141,8 +141,8 @@ public:
template <typename T>
class ImmutableListFactory {
- typedef ImmutableListImpl<T> ListTy;
- typedef FoldingSet<ListTy> CacheTy;
+ using ListTy = ImmutableListImpl<T>;
+ using CacheTy = FoldingSet<ListTy>;
CacheTy Cache;
uintptr_t Allocator;
diff --git a/contrib/llvm/include/llvm/ADT/ImmutableMap.h b/contrib/llvm/include/llvm/ADT/ImmutableMap.h
index f197d40..10d1e1f 100644
--- a/contrib/llvm/include/llvm/ADT/ImmutableMap.h
+++ b/contrib/llvm/include/llvm/ADT/ImmutableMap.h
@@ -26,12 +26,12 @@ namespace llvm {
/// only the first element (the key) is used by isEqual and isLess.
template <typename T, typename S>
struct ImutKeyValueInfo {
- typedef const std::pair<T,S> value_type;
- typedef const value_type& value_type_ref;
- typedef const T key_type;
- typedef const T& key_type_ref;
- typedef const S data_type;
- typedef const S& data_type_ref;
+ using value_type = const std::pair<T,S>;
+ using value_type_ref = const value_type&;
+ using key_type = const T;
+ using key_type_ref = const T&;
+ using data_type = const S;
+ using data_type_ref = const S&;
static inline key_type_ref KeyOfValue(value_type_ref V) {
return V.first;
@@ -62,13 +62,13 @@ template <typename KeyT, typename ValT,
typename ValInfo = ImutKeyValueInfo<KeyT,ValT>>
class ImmutableMap {
public:
- typedef typename ValInfo::value_type value_type;
- typedef typename ValInfo::value_type_ref value_type_ref;
- typedef typename ValInfo::key_type key_type;
- typedef typename ValInfo::key_type_ref key_type_ref;
- typedef typename ValInfo::data_type data_type;
- typedef typename ValInfo::data_type_ref data_type_ref;
- typedef ImutAVLTree<ValInfo> TreeTy;
+ using value_type = typename ValInfo::value_type;
+ using value_type_ref = typename ValInfo::value_type_ref;
+ using key_type = typename ValInfo::key_type;
+ using key_type_ref = typename ValInfo::key_type_ref;
+ using data_type = typename ValInfo::data_type;
+ using data_type_ref = typename ValInfo::data_type_ref;
+ using TreeTy = ImutAVLTree<ValInfo>;
protected:
TreeTy* Root;
@@ -86,6 +86,10 @@ public:
if (Root) { Root->retain(); }
}
+ ~ImmutableMap() {
+ if (Root) { Root->release(); }
+ }
+
ImmutableMap &operator=(const ImmutableMap &X) {
if (Root != X.Root) {
if (X.Root) { X.Root->retain(); }
@@ -95,10 +99,6 @@ public:
return *this;
}
- ~ImmutableMap() {
- if (Root) { Root->release(); }
- }
-
class Factory {
typename TreeTy::Factory F;
const bool Canonicalize;
@@ -166,12 +166,14 @@ private:
template <typename Callback>
struct CBWrapper {
Callback C;
+
void operator()(value_type_ref V) { C(V.first,V.second); }
};
template <typename Callback>
struct CBWrapperRef {
Callback &C;
+
CBWrapperRef(Callback& c) : C(c) {}
void operator()(value_type_ref V) { C(V.first,V.second); }
@@ -254,14 +256,14 @@ template <typename KeyT, typename ValT,
typename ValInfo = ImutKeyValueInfo<KeyT,ValT>>
class ImmutableMapRef {
public:
- typedef typename ValInfo::value_type value_type;
- typedef typename ValInfo::value_type_ref value_type_ref;
- typedef typename ValInfo::key_type key_type;
- typedef typename ValInfo::key_type_ref key_type_ref;
- typedef typename ValInfo::data_type data_type;
- typedef typename ValInfo::data_type_ref data_type_ref;
- typedef ImutAVLTree<ValInfo> TreeTy;
- typedef typename TreeTy::Factory FactoryTy;
+ using value_type = typename ValInfo::value_type;
+ using value_type_ref = typename ValInfo::value_type_ref;
+ using key_type = typename ValInfo::key_type;
+ using key_type_ref = typename ValInfo::key_type_ref;
+ using data_type = typename ValInfo::data_type;
+ using data_type_ref = typename ValInfo::data_type_ref;
+ using TreeTy = ImutAVLTree<ValInfo>;
+ using FactoryTy = typename TreeTy::Factory;
protected:
TreeTy *Root;
@@ -292,6 +294,11 @@ public:
}
}
+ ~ImmutableMapRef() {
+ if (Root)
+ Root->release();
+ }
+
ImmutableMapRef &operator=(const ImmutableMapRef &X) {
if (Root != X.Root) {
if (X.Root)
@@ -306,11 +313,6 @@ public:
return *this;
}
- ~ImmutableMapRef() {
- if (Root)
- Root->release();
- }
-
static inline ImmutableMapRef getEmptyMap(FactoryTy *F) {
return ImmutableMapRef(0, F);
}
diff --git a/contrib/llvm/include/llvm/ADT/ImmutableSet.h b/contrib/llvm/include/llvm/ADT/ImmutableSet.h
index 0724a28..9d580c5 100644
--- a/contrib/llvm/include/llvm/ADT/ImmutableSet.h
+++ b/contrib/llvm/include/llvm/ADT/ImmutableSet.h
@@ -16,16 +16,16 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/FoldingSet.h"
-#include "llvm/ADT/iterator.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/iterator.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/ErrorHandling.h"
#include <cassert>
-#include <functional>
-#include <vector>
#include <cstdint>
+#include <functional>
#include <iterator>
#include <new>
+#include <vector>
namespace llvm {
@@ -41,18 +41,16 @@ template <typename ImutInfo> class ImutAVLTreeGenericIterator;
template <typename ImutInfo >
class ImutAVLTree {
public:
- typedef typename ImutInfo::key_type_ref key_type_ref;
- typedef typename ImutInfo::value_type value_type;
- typedef typename ImutInfo::value_type_ref value_type_ref;
+ using key_type_ref = typename ImutInfo::key_type_ref;
+ using value_type = typename ImutInfo::value_type;
+ using value_type_ref = typename ImutInfo::value_type_ref;
+ using Factory = ImutAVLFactory<ImutInfo>;
+ using iterator = ImutAVLTreeInOrderIterator<ImutInfo>;
- typedef ImutAVLFactory<ImutInfo> Factory;
friend class ImutAVLFactory<ImutInfo>;
friend class ImutIntervalAVLFactory<ImutInfo>;
-
friend class ImutAVLTreeGenericIterator<ImutInfo>;
- typedef ImutAVLTreeInOrderIterator<ImutInfo> iterator;
-
//===----------------------------------------------------===//
// Public Interface.
//===----------------------------------------------------===//
@@ -225,17 +223,17 @@ private:
Factory *factory;
ImutAVLTree *left;
ImutAVLTree *right;
- ImutAVLTree *prev;
- ImutAVLTree *next;
+ ImutAVLTree *prev = nullptr;
+ ImutAVLTree *next = nullptr;
- unsigned height : 28;
- unsigned IsMutable : 1;
- unsigned IsDigestCached : 1;
- unsigned IsCanonicalized : 1;
+ unsigned height : 28;
+ bool IsMutable : 1;
+ bool IsDigestCached : 1;
+ bool IsCanonicalized : 1;
value_type value;
- uint32_t digest;
- uint32_t refCount;
+ uint32_t digest = 0;
+ uint32_t refCount = 0;
//===----------------------------------------------------===//
// Internal methods (node manipulation; used by Factory).
@@ -246,9 +244,8 @@ private:
/// ImutAVLFactory.
ImutAVLTree(Factory *f, ImutAVLTree* l, ImutAVLTree* r, value_type_ref v,
unsigned height)
- : factory(f), left(l), right(r), prev(nullptr), next(nullptr),
- height(height), IsMutable(true), IsDigestCached(false),
- IsCanonicalized(0), value(v), digest(0), refCount(0)
+ : factory(f), left(l), right(r), height(height), IsMutable(true),
+ IsDigestCached(false), IsCanonicalized(false), value(v)
{
if (left) left->retain();
if (right) right->retain();
@@ -369,11 +366,11 @@ public:
template <typename ImutInfo >
class ImutAVLFactory {
friend class ImutAVLTree<ImutInfo>;
- typedef ImutAVLTree<ImutInfo> TreeTy;
- typedef typename TreeTy::value_type_ref value_type_ref;
- typedef typename TreeTy::key_type_ref key_type_ref;
- typedef DenseMap<unsigned, TreeTy*> CacheTy;
+ using TreeTy = ImutAVLTree<ImutInfo>;
+ using value_type_ref = typename TreeTy::value_type_ref;
+ using key_type_ref = typename TreeTy::key_type_ref;
+ using CacheTy = DenseMap<unsigned, TreeTy*>;
CacheTy Cache;
uintptr_t Allocator;
@@ -659,7 +656,7 @@ public:
enum VisitFlag { VisitedNone=0x0, VisitedLeft=0x1, VisitedRight=0x3,
Flags=0x3 };
- typedef ImutAVLTree<ImutInfo> TreeTy;
+ using TreeTy = ImutAVLTree<ImutInfo>;
ImutAVLTreeGenericIterator() = default;
ImutAVLTreeGenericIterator(const TreeTy *Root) {
@@ -764,11 +761,12 @@ template <typename ImutInfo>
class ImutAVLTreeInOrderIterator
: public std::iterator<std::bidirectional_iterator_tag,
ImutAVLTree<ImutInfo>> {
- typedef ImutAVLTreeGenericIterator<ImutInfo> InternalIteratorTy;
+ using InternalIteratorTy = ImutAVLTreeGenericIterator<ImutInfo>;
+
InternalIteratorTy InternalItr;
public:
- typedef ImutAVLTree<ImutInfo> TreeTy;
+ using TreeTy = ImutAVLTree<ImutInfo>;
ImutAVLTreeInOrderIterator(const TreeTy* Root) : InternalItr(Root) {
if (Root)
@@ -840,8 +838,8 @@ struct ImutAVLValueIterator
/// and generic handling of pointers is done below.
template <typename T>
struct ImutProfileInfo {
- typedef const T value_type;
- typedef const T& value_type_ref;
+ using value_type = const T;
+ using value_type_ref = const T&;
static void Profile(FoldingSetNodeID &ID, value_type_ref X) {
FoldingSetTrait<T>::Profile(X,ID);
@@ -851,8 +849,8 @@ struct ImutProfileInfo {
/// Profile traits for integers.
template <typename T>
struct ImutProfileInteger {
- typedef const T value_type;
- typedef const T& value_type_ref;
+ using value_type = const T;
+ using value_type_ref = const T&;
static void Profile(FoldingSetNodeID &ID, value_type_ref X) {
ID.AddInteger(X);
@@ -878,8 +876,8 @@ PROFILE_INTEGER_INFO(unsigned long long)
/// Profile traits for booleans.
template <>
struct ImutProfileInfo<bool> {
- typedef const bool value_type;
- typedef const bool& value_type_ref;
+ using value_type = const bool;
+ using value_type_ref = const bool&;
static void Profile(FoldingSetNodeID &ID, value_type_ref X) {
ID.AddBoolean(X);
@@ -890,8 +888,8 @@ struct ImutProfileInfo<bool> {
/// references to unique objects.
template <typename T>
struct ImutProfileInfo<T*> {
- typedef const T* value_type;
- typedef value_type value_type_ref;
+ using value_type = const T*;
+ using value_type_ref = value_type;
static void Profile(FoldingSetNodeID &ID, value_type_ref X) {
ID.AddPointer(X);
@@ -910,12 +908,12 @@ struct ImutProfileInfo<T*> {
/// std::equal_to<> and std::less<> to perform comparison of elements.
template <typename T>
struct ImutContainerInfo : public ImutProfileInfo<T> {
- typedef typename ImutProfileInfo<T>::value_type value_type;
- typedef typename ImutProfileInfo<T>::value_type_ref value_type_ref;
- typedef value_type key_type;
- typedef value_type_ref key_type_ref;
- typedef bool data_type;
- typedef bool data_type_ref;
+ using value_type = typename ImutProfileInfo<T>::value_type;
+ using value_type_ref = typename ImutProfileInfo<T>::value_type_ref;
+ using key_type = value_type;
+ using key_type_ref = value_type_ref;
+ using data_type = bool;
+ using data_type_ref = bool;
static key_type_ref KeyOfValue(value_type_ref D) { return D; }
static data_type_ref DataOfValue(value_type_ref) { return true; }
@@ -936,12 +934,12 @@ struct ImutContainerInfo : public ImutProfileInfo<T> {
/// their addresses.
template <typename T>
struct ImutContainerInfo<T*> : public ImutProfileInfo<T*> {
- typedef typename ImutProfileInfo<T*>::value_type value_type;
- typedef typename ImutProfileInfo<T*>::value_type_ref value_type_ref;
- typedef value_type key_type;
- typedef value_type_ref key_type_ref;
- typedef bool data_type;
- typedef bool data_type_ref;
+ using value_type = typename ImutProfileInfo<T*>::value_type;
+ using value_type_ref = typename ImutProfileInfo<T*>::value_type_ref;
+ using key_type = value_type;
+ using key_type_ref = value_type_ref;
+ using data_type = bool;
+ using data_type_ref = bool;
static key_type_ref KeyOfValue(value_type_ref D) { return D; }
static data_type_ref DataOfValue(value_type_ref) { return true; }
@@ -960,9 +958,9 @@ struct ImutContainerInfo<T*> : public ImutProfileInfo<T*> {
template <typename ValT, typename ValInfo = ImutContainerInfo<ValT>>
class ImmutableSet {
public:
- typedef typename ValInfo::value_type value_type;
- typedef typename ValInfo::value_type_ref value_type_ref;
- typedef ImutAVLTree<ValInfo> TreeTy;
+ using value_type = typename ValInfo::value_type;
+ using value_type_ref = typename ValInfo::value_type_ref;
+ using TreeTy = ImutAVLTree<ValInfo>;
private:
TreeTy *Root;
@@ -980,6 +978,10 @@ public:
if (Root) { Root->retain(); }
}
+ ~ImmutableSet() {
+ if (Root) { Root->release(); }
+ }
+
ImmutableSet &operator=(const ImmutableSet &X) {
if (Root != X.Root) {
if (X.Root) { X.Root->retain(); }
@@ -989,10 +991,6 @@ public:
return *this;
}
- ~ImmutableSet() {
- if (Root) { Root->release(); }
- }
-
class Factory {
typename TreeTy::Factory F;
const bool Canonicalize;
@@ -1084,7 +1082,7 @@ public:
// Iterators.
//===--------------------------------------------------===//
- typedef ImutAVLValueIterator<ImmutableSet> iterator;
+ using iterator = ImutAVLValueIterator<ImmutableSet>;
iterator begin() const { return iterator(Root); }
iterator end() const { return iterator(); }
@@ -1112,10 +1110,10 @@ public:
template <typename ValT, typename ValInfo = ImutContainerInfo<ValT>>
class ImmutableSetRef {
public:
- typedef typename ValInfo::value_type value_type;
- typedef typename ValInfo::value_type_ref value_type_ref;
- typedef ImutAVLTree<ValInfo> TreeTy;
- typedef typename TreeTy::Factory FactoryTy;
+ using value_type = typename ValInfo::value_type;
+ using value_type_ref = typename ValInfo::value_type_ref;
+ using TreeTy = ImutAVLTree<ValInfo>;
+ using FactoryTy = typename TreeTy::Factory;
private:
TreeTy *Root;
@@ -1138,6 +1136,10 @@ public:
if (Root) { Root->retain(); }
}
+ ~ImmutableSetRef() {
+ if (Root) { Root->release(); }
+ }
+
ImmutableSetRef &operator=(const ImmutableSetRef &X) {
if (Root != X.Root) {
if (X.Root) { X.Root->retain(); }
@@ -1147,9 +1149,6 @@ public:
}
return *this;
}
- ~ImmutableSetRef() {
- if (Root) { Root->release(); }
- }
static ImmutableSetRef getEmptySet(FactoryTy *F) {
return ImmutableSetRef(0, F);
@@ -1196,7 +1195,7 @@ public:
// Iterators.
//===--------------------------------------------------===//
- typedef ImutAVLValueIterator<ImmutableSetRef> iterator;
+ using iterator = ImutAVLValueIterator<ImmutableSetRef>;
iterator begin() const { return iterator(Root); }
iterator end() const { return iterator(); }
diff --git a/contrib/llvm/include/llvm/ADT/IndexedMap.h b/contrib/llvm/include/llvm/ADT/IndexedMap.h
index 5ba85c0..2ee80d2 100644
--- a/contrib/llvm/include/llvm/ADT/IndexedMap.h
+++ b/contrib/llvm/include/llvm/ADT/IndexedMap.h
@@ -20,28 +20,28 @@
#ifndef LLVM_ADT_INDEXEDMAP_H
#define LLVM_ADT_INDEXEDMAP_H
-#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/STLExtras.h"
#include <cassert>
-#include <functional>
namespace llvm {
-template <typename T, typename ToIndexT = llvm::identity<unsigned> >
+template <typename T, typename ToIndexT = identity<unsigned>>
class IndexedMap {
- typedef typename ToIndexT::argument_type IndexT;
+ using IndexT = typename ToIndexT::argument_type;
// Prefer SmallVector with zero inline storage over std::vector. IndexedMaps
// can grow very large and SmallVector grows more efficiently as long as T
// is trivially copyable.
- typedef SmallVector<T, 0> StorageT;
+ using StorageT = SmallVector<T, 0>;
+
StorageT storage_;
T nullVal_;
ToIndexT toIndex_;
public:
- IndexedMap() : nullVal_(T()) { }
+ IndexedMap() : nullVal_(T()) {}
- explicit IndexedMap(const T& val) : nullVal_(val) { }
+ explicit IndexedMap(const T& val) : nullVal_(val) {}
typename StorageT::reference operator[](IndexT n) {
assert(toIndex_(n) < storage_.size() && "index out of bounds!");
@@ -80,6 +80,6 @@ template <typename T, typename ToIndexT = llvm::identity<unsigned> >
}
};
-} // End llvm namespace
+} // end namespace llvm
-#endif
+#endif // LLVM_ADT_INDEXEDMAP_H
diff --git a/contrib/llvm/include/llvm/ADT/IntervalMap.h b/contrib/llvm/include/llvm/ADT/IntervalMap.h
index 430b967..f713668 100644
--- a/contrib/llvm/include/llvm/ADT/IntervalMap.h
+++ b/contrib/llvm/include/llvm/ADT/IntervalMap.h
@@ -106,6 +106,7 @@
#include "llvm/Support/RecyclingAllocator.h"
#include <algorithm>
#include <cassert>
+#include <cstdint>
#include <iterator>
#include <new>
#include <utility>
@@ -186,7 +187,7 @@ struct IntervalMapHalfOpenInfo {
/// It should be considered private to the implementation.
namespace IntervalMapImpl {
-typedef std::pair<unsigned,unsigned> IdxPair;
+using IdxPair = std::pair<unsigned,unsigned>;
//===----------------------------------------------------------------------===//
//--- IntervalMapImpl::NodeBase ---//
@@ -445,7 +446,7 @@ struct NodeSizer {
LeafSize = DesiredLeafSize > MinLeafSize ? DesiredLeafSize : MinLeafSize
};
- typedef NodeBase<std::pair<KeyT, KeyT>, ValT, LeafSize> LeafBase;
+ using LeafBase = NodeBase<std::pair<KeyT, KeyT>, ValT, LeafSize>;
enum {
// Now that we have the leaf branching factor, compute the actual allocation
@@ -461,8 +462,8 @@ struct NodeSizer {
/// This typedef is very likely to be identical for all IntervalMaps with
/// reasonably sized entries, so the same allocator can be shared among
/// different kinds of maps.
- typedef RecyclingAllocator<BumpPtrAllocator, char,
- AllocBytes, CacheLineBytes> Allocator;
+ using Allocator =
+ RecyclingAllocator<BumpPtrAllocator, char, AllocBytes, CacheLineBytes>;
};
//===----------------------------------------------------------------------===//
@@ -930,12 +931,12 @@ template <typename KeyT, typename ValT,
unsigned N = IntervalMapImpl::NodeSizer<KeyT, ValT>::LeafSize,
typename Traits = IntervalMapInfo<KeyT>>
class IntervalMap {
- typedef IntervalMapImpl::NodeSizer<KeyT, ValT> Sizer;
- typedef IntervalMapImpl::LeafNode<KeyT, ValT, Sizer::LeafSize, Traits> Leaf;
- typedef IntervalMapImpl::BranchNode<KeyT, ValT, Sizer::BranchSize, Traits>
- Branch;
- typedef IntervalMapImpl::LeafNode<KeyT, ValT, N, Traits> RootLeaf;
- typedef IntervalMapImpl::IdxPair IdxPair;
+ using Sizer = IntervalMapImpl::NodeSizer<KeyT, ValT>;
+ using Leaf = IntervalMapImpl::LeafNode<KeyT, ValT, Sizer::LeafSize, Traits>;
+ using Branch =
+ IntervalMapImpl::BranchNode<KeyT, ValT, Sizer::BranchSize, Traits>;
+ using RootLeaf = IntervalMapImpl::LeafNode<KeyT, ValT, N, Traits>;
+ using IdxPair = IntervalMapImpl::IdxPair;
// The RootLeaf capacity is given as a template parameter. We must compute the
// corresponding RootBranch capacity.
@@ -945,8 +946,8 @@ class IntervalMap {
RootBranchCap = DesiredRootBranchCap ? DesiredRootBranchCap : 1
};
- typedef IntervalMapImpl::BranchNode<KeyT, ValT, RootBranchCap, Traits>
- RootBranch;
+ using RootBranch =
+ IntervalMapImpl::BranchNode<KeyT, ValT, RootBranchCap, Traits>;
// When branched, we store a global start key as well as the branch node.
struct RootBranchData {
@@ -955,10 +956,10 @@ class IntervalMap {
};
public:
- typedef typename Sizer::Allocator Allocator;
- typedef KeyT KeyType;
- typedef ValT ValueType;
- typedef Traits KeyTraits;
+ using Allocator = typename Sizer::Allocator;
+ using KeyType = KeyT;
+ using ValueType = ValT;
+ using KeyTraits = Traits;
private:
// The root data is either a RootLeaf or a RootBranchData instance.
@@ -1290,7 +1291,7 @@ protected:
friend class IntervalMap;
// The map referred to.
- IntervalMap *map;
+ IntervalMap *map = nullptr;
// We store a full path from the root to the current position.
// The path may be partially filled, but never between iterator calls.
@@ -1338,7 +1339,7 @@ protected:
public:
/// const_iterator - Create an iterator that isn't pointing anywhere.
- const_iterator() : map(nullptr) {}
+ const_iterator() = default;
/// setMap - Change the map iterated over. This call must be followed by a
/// call to goToBegin(), goToEnd(), or find()
@@ -1509,7 +1510,8 @@ const_iterator::treeAdvanceTo(KeyT x) {
template <typename KeyT, typename ValT, unsigned N, typename Traits>
class IntervalMap<KeyT, ValT, N, Traits>::iterator : public const_iterator {
friend class IntervalMap;
- typedef IntervalMapImpl::IdxPair IdxPair;
+
+ using IdxPair = IntervalMapImpl::IdxPair;
explicit iterator(IntervalMap &map) : const_iterator(map) {}
@@ -2003,7 +2005,7 @@ iterator::overflow(unsigned Level) {
// Elements have been rearranged, now update node sizes and stops.
bool SplitRoot = false;
unsigned Pos = 0;
- for (;;) {
+ while (true) {
KeyT Stop = Node[Pos]->stop(NewSize[Pos]-1);
if (NewNode && Pos == NewNode) {
SplitRoot = insertNode(Level, NodeRef(Node[Pos], NewSize[Pos]), Stop);
@@ -2045,8 +2047,9 @@ iterator::overflow(unsigned Level) {
///
template <typename MapA, typename MapB>
class IntervalMapOverlaps {
- typedef typename MapA::KeyType KeyType;
- typedef typename MapA::KeyTraits Traits;
+ using KeyType = typename MapA::KeyType;
+ using Traits = typename MapA::KeyTraits;
+
typename MapA::const_iterator posA;
typename MapB::const_iterator posB;
@@ -2071,7 +2074,7 @@ class IntervalMapOverlaps {
// Already overlapping.
return;
- for (;;) {
+ while (true) {
// Make a.end > b.start.
posA.advanceTo(posB.start());
if (!posA.valid() || !Traits::stopLess(posB.stop(), posA.start()))
diff --git a/contrib/llvm/include/llvm/ADT/IntrusiveRefCntPtr.h b/contrib/llvm/include/llvm/ADT/IntrusiveRefCntPtr.h
index a77cf04..430ef86 100644
--- a/contrib/llvm/include/llvm/ADT/IntrusiveRefCntPtr.h
+++ b/contrib/llvm/include/llvm/ADT/IntrusiveRefCntPtr.h
@@ -1,4 +1,4 @@
-//== llvm/ADT/IntrusiveRefCntPtr.h - Smart Refcounting Pointer ---*- C++ -*-==//
+//==- llvm/ADT/IntrusiveRefCntPtr.h - Smart Refcounting Pointer --*- C++ -*-==//
//
// The LLVM Compiler Infrastructure
//
@@ -73,9 +73,10 @@ template <class Derived> class RefCountedBase {
public:
RefCountedBase() = default;
- RefCountedBase(const RefCountedBase &) : RefCount(0) {}
+ RefCountedBase(const RefCountedBase &) {}
void Retain() const { ++RefCount; }
+
void Release() const {
assert(RefCount > 0 && "Reference count is already zero.");
if (--RefCount == 0)
@@ -136,7 +137,7 @@ template <typename T> class IntrusiveRefCntPtr {
T *Obj = nullptr;
public:
- typedef T element_type;
+ using element_type = T;
explicit IntrusiveRefCntPtr() = default;
IntrusiveRefCntPtr(T *obj) : Obj(obj) { retain(); }
@@ -153,13 +154,13 @@ public:
retain();
}
+ ~IntrusiveRefCntPtr() { release(); }
+
IntrusiveRefCntPtr &operator=(IntrusiveRefCntPtr S) {
swap(S);
return *this;
}
- ~IntrusiveRefCntPtr() { release(); }
-
T &operator*() const { return *Obj; }
T *operator->() const { return Obj; }
T *get() const { return Obj; }
@@ -183,6 +184,7 @@ private:
if (Obj)
IntrusiveRefCntPtrInfo<T>::retain(Obj);
}
+
void release() {
if (Obj)
IntrusiveRefCntPtrInfo<T>::release(Obj);
@@ -248,14 +250,16 @@ bool operator!=(const IntrusiveRefCntPtr<T> &A, std::nullptr_t B) {
template <typename From> struct simplify_type;
template <class T> struct simplify_type<IntrusiveRefCntPtr<T>> {
- typedef T *SimpleType;
+ using SimpleType = T *;
+
static SimpleType getSimplifiedValue(IntrusiveRefCntPtr<T> &Val) {
return Val.get();
}
};
template <class T> struct simplify_type<const IntrusiveRefCntPtr<T>> {
- typedef /*const*/ T *SimpleType;
+ using SimpleType = /*const*/ T *;
+
static SimpleType getSimplifiedValue(const IntrusiveRefCntPtr<T> &Val) {
return Val.get();
}
diff --git a/contrib/llvm/include/llvm/ADT/MapVector.h b/contrib/llvm/include/llvm/ADT/MapVector.h
index ac18857..26a555e 100644
--- a/contrib/llvm/include/llvm/ADT/MapVector.h
+++ b/contrib/llvm/include/llvm/ADT/MapVector.h
@@ -19,6 +19,12 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
+#include <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <iterator>
+#include <type_traits>
+#include <utility>
#include <vector>
namespace llvm {
@@ -27,20 +33,20 @@ namespace llvm {
/// in a deterministic order. The values are kept in a std::vector and the
/// mapping is done with DenseMap from Keys to indexes in that vector.
template<typename KeyT, typename ValueT,
- typename MapType = llvm::DenseMap<KeyT, unsigned>,
- typename VectorType = std::vector<std::pair<KeyT, ValueT> > >
+ typename MapType = DenseMap<KeyT, unsigned>,
+ typename VectorType = std::vector<std::pair<KeyT, ValueT>>>
class MapVector {
- typedef typename VectorType::value_type value_type;
- typedef typename VectorType::size_type size_type;
+ using value_type = typename VectorType::value_type;
+ using size_type = typename VectorType::size_type;
MapType Map;
VectorType Vector;
public:
- typedef typename VectorType::iterator iterator;
- typedef typename VectorType::const_iterator const_iterator;
- typedef typename VectorType::reverse_iterator reverse_iterator;
- typedef typename VectorType::const_reverse_iterator const_reverse_iterator;
+ using iterator = typename VectorType::iterator;
+ using const_iterator = typename VectorType::const_iterator;
+ using reverse_iterator = typename VectorType::reverse_iterator;
+ using const_reverse_iterator = typename VectorType::const_reverse_iterator;
/// Clear the MapVector and return the underlying vector.
VectorType takeVector() {
@@ -220,4 +226,4 @@ struct SmallMapVector
} // end namespace llvm
-#endif
+#endif // LLVM_ADT_MAPVECTOR_H
diff --git a/contrib/llvm/include/llvm/ADT/None.h b/contrib/llvm/include/llvm/ADT/None.h
index d69ec17..c7a99c6 100644
--- a/contrib/llvm/include/llvm/ADT/None.h
+++ b/contrib/llvm/include/llvm/ADT/None.h
@@ -19,8 +19,9 @@
namespace llvm {
/// \brief A simple null object to allow implicit construction of Optional<T>
/// and similar types without having to spell out the specialization's name.
-enum class NoneType { None };
-const NoneType None = None;
+// (constant value 1 in an attempt to workaround MSVC build issue... )
+enum class NoneType { None = 1 };
+const NoneType None = NoneType::None;
}
#endif
diff --git a/contrib/llvm/include/llvm/ADT/Optional.h b/contrib/llvm/include/llvm/ADT/Optional.h
index 701872c..b782d9d 100644
--- a/contrib/llvm/include/llvm/ADT/Optional.h
+++ b/contrib/llvm/include/llvm/ADT/Optional.h
@@ -1,4 +1,4 @@
-//===-- Optional.h - Simple variant for passing optional values ---*- C++ -*-=//
+//===- Optional.h - Simple variant for passing optional values --*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -19,6 +19,8 @@
#include "llvm/ADT/None.h"
#include "llvm/Support/AlignOf.h"
#include "llvm/Support/Compiler.h"
+#include "llvm/Support/type_traits.h"
+#include <algorithm>
#include <cassert>
#include <new>
#include <utility>
@@ -28,15 +30,18 @@ namespace llvm {
template<typename T>
class Optional {
AlignedCharArrayUnion<T> storage;
- bool hasVal;
+ bool hasVal = false;
+
public:
- typedef T value_type;
+ using value_type = T;
+
+ Optional(NoneType) {}
+ explicit Optional() {}
- Optional(NoneType) : hasVal(false) {}
- explicit Optional() : hasVal(false) {}
Optional(const T &y) : hasVal(true) {
new (storage.buffer) T(y);
}
+
Optional(const Optional &O) : hasVal(O.hasVal) {
if (hasVal)
new (storage.buffer) T(*O);
@@ -45,12 +50,18 @@ public:
Optional(T &&y) : hasVal(true) {
new (storage.buffer) T(std::forward<T>(y));
}
+
Optional(Optional<T> &&O) : hasVal(O) {
if (O) {
new (storage.buffer) T(std::move(*O));
O.reset();
}
}
+
+ ~Optional() {
+ reset();
+ }
+
Optional &operator=(T &&y) {
if (hasVal)
**this = std::move(y);
@@ -60,6 +71,7 @@ public:
}
return *this;
}
+
Optional &operator=(Optional &&O) {
if (!O)
reset();
@@ -112,10 +124,6 @@ public:
}
}
- ~Optional() {
- reset();
- }
-
const T* getPointer() const { assert(hasVal); return reinterpret_cast<const T*>(storage.buffer); }
T* getPointer() { assert(hasVal); return reinterpret_cast<T*>(storage.buffer); }
const T& getValue() const LLVM_LVALUE_FUNCTION { assert(hasVal); return *getPointer(); }
@@ -144,8 +152,7 @@ public:
#endif
};
-template <typename T> struct isPodLike;
-template <typename T> struct isPodLike<Optional<T> > {
+template <typename T> struct isPodLike<Optional<T>> {
// An Optional<T> is pod-like if T is.
static const bool value = isPodLike<T>::value;
};
@@ -284,6 +291,6 @@ template <typename T> bool operator>=(const T &X, const Optional<T> &Y) {
return !(X < Y);
}
-} // end llvm namespace
+} // end namespace llvm
-#endif
+#endif // LLVM_ADT_OPTIONAL_H
diff --git a/contrib/llvm/include/llvm/ADT/PackedVector.h b/contrib/llvm/include/llvm/ADT/PackedVector.h
index 8f925f1..95adc29 100644
--- a/contrib/llvm/include/llvm/ADT/PackedVector.h
+++ b/contrib/llvm/include/llvm/ADT/PackedVector.h
@@ -76,8 +76,8 @@ template <typename T, unsigned BitNum, typename BitVectorTy = BitVector>
class PackedVector : public PackedVectorBase<T, BitNum, BitVectorTy,
std::numeric_limits<T>::is_signed> {
BitVectorTy Bits;
- typedef PackedVectorBase<T, BitNum, BitVectorTy,
- std::numeric_limits<T>::is_signed> base;
+ using base = PackedVectorBase<T, BitNum, BitVectorTy,
+ std::numeric_limits<T>::is_signed>;
public:
class reference {
@@ -99,7 +99,7 @@ public:
};
PackedVector() = default;
- explicit PackedVector(unsigned size) : Bits(size << (BitNum-1)) { }
+ explicit PackedVector(unsigned size) : Bits(size << (BitNum-1)) {}
bool empty() const { return Bits.empty(); }
diff --git a/contrib/llvm/include/llvm/ADT/PointerEmbeddedInt.h b/contrib/llvm/include/llvm/ADT/PointerEmbeddedInt.h
index 2279d43..34323b5 100644
--- a/contrib/llvm/include/llvm/ADT/PointerEmbeddedInt.h
+++ b/contrib/llvm/include/llvm/ADT/PointerEmbeddedInt.h
@@ -13,7 +13,10 @@
#include "llvm/ADT/DenseMapInfo.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/PointerLikeTypeTraits.h"
+#include <cassert>
#include <climits>
+#include <cstdint>
+#include <type_traits>
namespace llvm {
@@ -29,7 +32,7 @@ namespace llvm {
/// Also, the default constructed value zero initializes the integer.
template <typename IntT, int Bits = sizeof(IntT) * CHAR_BIT>
class PointerEmbeddedInt {
- uintptr_t Value;
+ uintptr_t Value = 0;
// Note: This '<' is correct; using '<=' would result in some shifts
// overflowing their storage types.
@@ -54,15 +57,12 @@ class PointerEmbeddedInt {
explicit PointerEmbeddedInt(uintptr_t Value, RawValueTag) : Value(Value) {}
public:
- PointerEmbeddedInt() : Value(0) {}
+ PointerEmbeddedInt() = default;
- PointerEmbeddedInt(IntT I) {
- *this = I;
- }
+ PointerEmbeddedInt(IntT I) { *this = I; }
PointerEmbeddedInt &operator=(IntT I) {
- assert((std::is_signed<IntT>::value ? llvm::isInt<Bits>(I)
- : llvm::isUInt<Bits>(I)) &&
+ assert((std::is_signed<IntT>::value ? isInt<Bits>(I) : isUInt<Bits>(I)) &&
"Integer has bits outside those preserved!");
Value = static_cast<uintptr_t>(I) << Shift;
return *this;
@@ -81,15 +81,17 @@ public:
// types.
template <typename IntT, int Bits>
class PointerLikeTypeTraits<PointerEmbeddedInt<IntT, Bits>> {
- typedef PointerEmbeddedInt<IntT, Bits> T;
+ using T = PointerEmbeddedInt<IntT, Bits>;
public:
static inline void *getAsVoidPointer(const T &P) {
return reinterpret_cast<void *>(P.Value);
}
+
static inline T getFromVoidPointer(void *P) {
return T(reinterpret_cast<uintptr_t>(P), typename T::RawValueTag());
}
+
static inline T getFromVoidPointer(const void *P) {
return T(reinterpret_cast<uintptr_t>(P), typename T::RawValueTag());
}
@@ -101,17 +103,19 @@ public:
// itself can be a key.
template <typename IntT, int Bits>
struct DenseMapInfo<PointerEmbeddedInt<IntT, Bits>> {
- typedef PointerEmbeddedInt<IntT, Bits> T;
-
- typedef DenseMapInfo<IntT> IntInfo;
+ using T = PointerEmbeddedInt<IntT, Bits>;
+ using IntInfo = DenseMapInfo<IntT>;
static inline T getEmptyKey() { return IntInfo::getEmptyKey(); }
static inline T getTombstoneKey() { return IntInfo::getTombstoneKey(); }
+
static unsigned getHashValue(const T &Arg) {
return IntInfo::getHashValue(Arg);
}
+
static bool isEqual(const T &LHS, const T &RHS) { return LHS == RHS; }
};
-}
-#endif
+} // end namespace llvm
+
+#endif // LLVM_ADT_POINTEREMBEDDEDINT_H
diff --git a/contrib/llvm/include/llvm/ADT/PointerUnion.h b/contrib/llvm/include/llvm/ADT/PointerUnion.h
index a8ac186..aeab641 100644
--- a/contrib/llvm/include/llvm/ADT/PointerUnion.h
+++ b/contrib/llvm/include/llvm/ADT/PointerUnion.h
@@ -19,8 +19,8 @@
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/Support/PointerLikeTypeTraits.h"
#include <cassert>
-#include <cstdint>
#include <cstddef>
+#include <cstdint>
namespace llvm {
@@ -31,7 +31,7 @@ template <typename T> struct PointerUnionTypeSelectorReturn {
/// Get a type based on whether two types are the same or not.
///
/// For:
-///
+///
/// \code
/// typedef typename PointerUnionTypeSelector<T1, T2, EQ, NE>::Return Ret;
/// \endcode
@@ -158,7 +158,7 @@ public:
assert(
get<PT1>() == Val.getPointer() &&
"Can't get the address because PointerLikeTypeTraits changes the ptr");
- return (PT1 *)Val.getAddrOfPointer();
+ return const_cast<PT1 *>(reinterpret_cast<const PT1 *>(Val.getAddrOfPointer()));
}
/// Assignment from nullptr which just clears the union.
@@ -190,17 +190,17 @@ public:
};
template <typename PT1, typename PT2>
-static bool operator==(PointerUnion<PT1, PT2> lhs, PointerUnion<PT1, PT2> rhs) {
+bool operator==(PointerUnion<PT1, PT2> lhs, PointerUnion<PT1, PT2> rhs) {
return lhs.getOpaqueValue() == rhs.getOpaqueValue();
}
template <typename PT1, typename PT2>
-static bool operator!=(PointerUnion<PT1, PT2> lhs, PointerUnion<PT1, PT2> rhs) {
+bool operator!=(PointerUnion<PT1, PT2> lhs, PointerUnion<PT1, PT2> rhs) {
return lhs.getOpaqueValue() != rhs.getOpaqueValue();
}
template <typename PT1, typename PT2>
-static bool operator<(PointerUnion<PT1, PT2> lhs, PointerUnion<PT1, PT2> rhs) {
+bool operator<(PointerUnion<PT1, PT2> lhs, PointerUnion<PT1, PT2> rhs) {
return lhs.getOpaqueValue() < rhs.getOpaqueValue();
}
diff --git a/contrib/llvm/include/llvm/ADT/PostOrderIterator.h b/contrib/llvm/include/llvm/ADT/PostOrderIterator.h
index e519b5c..dc8a9b6 100644
--- a/contrib/llvm/include/llvm/ADT/PostOrderIterator.h
+++ b/contrib/llvm/include/llvm/ADT/PostOrderIterator.h
@@ -17,9 +17,9 @@
#define LLVM_ADT_POSTORDERITERATOR_H
#include "llvm/ADT/GraphTraits.h"
-#include "llvm/ADT/iterator_range.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/iterator_range.h"
#include <iterator>
#include <set>
#include <utility>
@@ -96,24 +96,14 @@ template <class GraphT,
class po_iterator
: public std::iterator<std::forward_iterator_tag, typename GT::NodeRef>,
public po_iterator_storage<SetType, ExtStorage> {
- typedef std::iterator<std::forward_iterator_tag, typename GT::NodeRef> super;
- typedef typename GT::NodeRef NodeRef;
- typedef typename GT::ChildIteratorType ChildItTy;
+ using super = std::iterator<std::forward_iterator_tag, typename GT::NodeRef>;
+ using NodeRef = typename GT::NodeRef;
+ using ChildItTy = typename GT::ChildIteratorType;
// 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;
- void traverseChild() {
- while (VisitStack.back().second != GT::child_end(VisitStack.back().first)) {
- NodeRef BB = *VisitStack.back().second++;
- if (this->insertEdge(Optional<NodeRef>(VisitStack.back().first), BB)) {
- // If the block is not visited...
- VisitStack.push_back(std::make_pair(BB, GT::child_begin(BB)));
- }
- }
- }
-
po_iterator(NodeRef BB) {
this->insertEdge(Optional<NodeRef>(), BB);
VisitStack.push_back(std::make_pair(BB, GT::child_begin(BB)));
@@ -134,8 +124,18 @@ class po_iterator
: po_iterator_storage<SetType, ExtStorage>(S) {
} // End is when stack is empty.
+ void traverseChild() {
+ while (VisitStack.back().second != GT::child_end(VisitStack.back().first)) {
+ NodeRef BB = *VisitStack.back().second++;
+ if (this->insertEdge(Optional<NodeRef>(VisitStack.back().first), BB)) {
+ // If the block is not visited...
+ VisitStack.push_back(std::make_pair(BB, GT::child_begin(BB)));
+ }
+ }
+ }
+
public:
- typedef typename super::pointer pointer;
+ using pointer = typename super::pointer;
// Provide static "constructors"...
static po_iterator begin(GraphT G) {
@@ -268,6 +268,10 @@ inverse_post_order_ext(const T &G, SetType &S) {
// with a postorder iterator to build the data structures). The moral of this
// story is: Don't create more ReversePostOrderTraversal classes than necessary.
//
+// Because it does the traversal in its constructor, it won't invalidate when
+// BasicBlocks are removed, *but* it may contain erased blocks. Some places
+// rely on this behavior (i.e. GVN).
+//
// This class should be used like this:
// {
// ReversePostOrderTraversal<Function*> RPOT(FuncPtr); // Expensive to create
@@ -282,7 +286,8 @@ inverse_post_order_ext(const T &G, SetType &S) {
template<class GraphT, class GT = GraphTraits<GraphT>>
class ReversePostOrderTraversal {
- typedef typename GT::NodeRef NodeRef;
+ using NodeRef = typename GT::NodeRef;
+
std::vector<NodeRef> Blocks; // Block list in normal PO order
void Initialize(NodeRef BB) {
@@ -290,7 +295,7 @@ class ReversePostOrderTraversal {
}
public:
- typedef typename std::vector<NodeRef>::reverse_iterator rpo_iterator;
+ using rpo_iterator = typename std::vector<NodeRef>::reverse_iterator;
ReversePostOrderTraversal(GraphT G) { Initialize(GT::getEntryNode(G)); }
diff --git a/contrib/llvm/include/llvm/ADT/PriorityWorklist.h b/contrib/llvm/include/llvm/ADT/PriorityWorklist.h
index 3198dd4..aa531f3 100644
--- a/contrib/llvm/include/llvm/ADT/PriorityWorklist.h
+++ b/contrib/llvm/include/llvm/ADT/PriorityWorklist.h
@@ -18,12 +18,13 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/Sequence.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Compiler.h"
#include <algorithm>
#include <cassert>
#include <cstddef>
+#include <iterator>
+#include <type_traits>
#include <vector>
namespace llvm {
@@ -55,11 +56,11 @@ template <typename T, typename VectorT = std::vector<T>,
typename MapT = DenseMap<T, ptrdiff_t>>
class PriorityWorklist {
public:
- typedef T value_type;
- typedef T key_type;
- typedef T& reference;
- typedef const T& const_reference;
- typedef typename MapT::size_type size_type;
+ using value_type = T;
+ using key_type = T;
+ using reference = T&;
+ using const_reference = const T&;
+ using size_type = typename MapT::size_type;
/// Construct an empty PriorityWorklist
PriorityWorklist() = default;
diff --git a/contrib/llvm/include/llvm/ADT/SCCIterator.h b/contrib/llvm/include/llvm/ADT/SCCIterator.h
index 9a8a7b1..784a58d 100644
--- a/contrib/llvm/include/llvm/ADT/SCCIterator.h
+++ b/contrib/llvm/include/llvm/ADT/SCCIterator.h
@@ -1,4 +1,4 @@
-//===---- ADT/SCCIterator.h - Strongly Connected Comp. Iter. ----*- C++ -*-===//
+//===- ADT/SCCIterator.h - Strongly Connected Comp. Iter. -------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -43,10 +43,10 @@ template <class GraphT, class GT = GraphTraits<GraphT>>
class scc_iterator : public iterator_facade_base<
scc_iterator<GraphT, GT>, std::forward_iterator_tag,
const std::vector<typename GT::NodeRef>, ptrdiff_t> {
- typedef typename GT::NodeRef NodeRef;
- typedef typename GT::ChildIteratorType ChildItTy;
- typedef std::vector<NodeRef> SccTy;
- typedef typename scc_iterator::reference reference;
+ using NodeRef = typename GT::NodeRef;
+ using ChildItTy = typename GT::ChildIteratorType;
+ using SccTy = std::vector<NodeRef>;
+ using reference = typename scc_iterator::reference;
/// Element of VisitStack during DFS.
struct StackElement {
@@ -232,16 +232,6 @@ template <class T> scc_iterator<T> scc_end(const T &G) {
return scc_iterator<T>::end(G);
}
-/// \brief Construct the begin iterator for a deduced graph type T's Inverse<T>.
-template <class T> scc_iterator<Inverse<T>> scc_begin(const Inverse<T> &G) {
- return scc_iterator<Inverse<T>>::begin(G);
-}
-
-/// \brief Construct the end iterator for a deduced graph type T's Inverse<T>.
-template <class T> scc_iterator<Inverse<T>> scc_end(const Inverse<T> &G) {
- return scc_iterator<Inverse<T>>::end(G);
-}
-
} // end namespace llvm
#endif // LLVM_ADT_SCCITERATOR_H
diff --git a/contrib/llvm/include/llvm/ADT/STLExtras.h b/contrib/llvm/include/llvm/ADT/STLExtras.h
index ec121e0..83f289c 100644
--- a/contrib/llvm/include/llvm/ADT/STLExtras.h
+++ b/contrib/llvm/include/llvm/ADT/STLExtras.h
@@ -23,11 +23,13 @@
#include <cstdlib> // for qsort
#include <functional>
#include <iterator>
+#include <limits>
#include <memory>
#include <tuple>
#include <utility> // for std::pair
#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/iterator.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/Support/Compiler.h"
@@ -44,6 +46,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 detail namespace
//===----------------------------------------------------------------------===//
@@ -94,6 +100,8 @@ class function_ref<Ret(Params...)> {
}
public:
+ function_ref() : callback(nullptr) {}
+
template <typename Callable>
function_ref(Callable &&callable,
typename std::enable_if<
@@ -104,6 +112,8 @@ public:
Ret operator()(Params ...params) const {
return callback(callable, std::forward<Params>(params)...);
}
+
+ operator bool() const { return callback; }
};
// deleter - Very very very simple method that is used to invoke operator
@@ -123,7 +133,7 @@ inline void deleter(T *Ptr) {
//===----------------------------------------------------------------------===//
// mapped_iterator - This is a simple iterator adapter that causes a function to
-// be dereferenced whenever operator* is invoked on the iterator.
+// be applied whenever operator* is invoked on the iterator.
//
template <class RootIt, class UnaryFunc>
class mapped_iterator {
@@ -134,9 +144,8 @@ public:
iterator_category;
typedef typename std::iterator_traits<RootIt>::difference_type
difference_type;
- typedef typename std::result_of<
- UnaryFunc(decltype(*std::declval<RootIt>()))>
- ::type value_type;
+ typedef decltype(std::declval<UnaryFunc>()(*std::declval<RootIt>()))
+ value_type;
typedef void pointer;
//typedef typename UnaryFunc::result_type *pointer;
@@ -356,65 +365,126 @@ template <size_t... I> struct index_sequence;
template <class... Ts> struct index_sequence_for;
namespace detail {
-template <typename... Iters> class zip_first {
-public:
- typedef std::input_iterator_tag iterator_category;
- typedef std::tuple<decltype(*std::declval<Iters>())...> value_type;
+using std::declval;
+
+// We have to alias this since inlining the actual type at the usage site
+// in the parameter list of iterator_facade_base<> below ICEs MSVC 2017.
+template<typename... Iters> struct ZipTupleType {
+ typedef std::tuple<decltype(*declval<Iters>())...> type;
+};
+
+template <typename ZipType, typename... Iters>
+using zip_traits = iterator_facade_base<
+ ZipType, typename std::common_type<std::bidirectional_iterator_tag,
+ typename std::iterator_traits<
+ Iters>::iterator_category...>::type,
+ // ^ TODO: Implement random access methods.
+ typename ZipTupleType<Iters...>::type,
+ typename std::iterator_traits<typename std::tuple_element<
+ 0, std::tuple<Iters...>>::type>::difference_type,
+ // ^ FIXME: This follows boost::make_zip_iterator's assumption that all
+ // inner iterators have the same difference_type. It would fail if, for
+ // instance, the second field's difference_type were non-numeric while the
+ // first is.
+ typename ZipTupleType<Iters...>::type *,
+ typename ZipTupleType<Iters...>::type>;
+
+template <typename ZipType, typename... Iters>
+struct zip_common : public zip_traits<ZipType, Iters...> {
+ using Base = zip_traits<ZipType, Iters...>;
+ using value_type = typename Base::value_type;
+
std::tuple<Iters...> iterators;
-private:
- template <size_t... Ns> value_type deres(index_sequence<Ns...>) {
+protected:
+ template <size_t... Ns> value_type deref(index_sequence<Ns...>) const {
return value_type(*std::get<Ns>(iterators)...);
}
- template <size_t... Ns> decltype(iterators) tup_inc(index_sequence<Ns...>) {
+ template <size_t... Ns>
+ decltype(iterators) tup_inc(index_sequence<Ns...>) const {
return std::tuple<Iters...>(std::next(std::get<Ns>(iterators))...);
}
+ template <size_t... Ns>
+ decltype(iterators) tup_dec(index_sequence<Ns...>) const {
+ return std::tuple<Iters...>(std::prev(std::get<Ns>(iterators))...);
+ }
+
public:
- value_type operator*() { return deres(index_sequence_for<Iters...>{}); }
+ zip_common(Iters &&... ts) : iterators(std::forward<Iters>(ts)...) {}
- void operator++() { iterators = tup_inc(index_sequence_for<Iters...>{}); }
+ value_type operator*() { return deref(index_sequence_for<Iters...>{}); }
+
+ const value_type operator*() const {
+ return deref(index_sequence_for<Iters...>{});
+ }
- bool operator!=(const zip_first<Iters...> &other) const {
- return std::get<0>(iterators) != std::get<0>(other.iterators);
+ ZipType &operator++() {
+ iterators = tup_inc(index_sequence_for<Iters...>{});
+ return *reinterpret_cast<ZipType *>(this);
}
- zip_first(Iters &&... ts) : iterators(std::forward<Iters>(ts)...) {}
+
+ ZipType &operator--() {
+ static_assert(Base::IsBidirectional,
+ "All inner iterators must be at least bidirectional.");
+ iterators = tup_dec(index_sequence_for<Iters...>{});
+ return *reinterpret_cast<ZipType *>(this);
+ }
+};
+
+template <typename... Iters>
+struct zip_first : public zip_common<zip_first<Iters...>, Iters...> {
+ using Base = zip_common<zip_first<Iters...>, Iters...>;
+
+ bool operator==(const zip_first<Iters...> &other) const {
+ return std::get<0>(this->iterators) == std::get<0>(other.iterators);
+ }
+
+ zip_first(Iters &&... ts) : Base(std::forward<Iters>(ts)...) {}
};
-template <typename... Iters> class zip_shortest : public zip_first<Iters...> {
+template <typename... Iters>
+class zip_shortest : public zip_common<zip_shortest<Iters...>, Iters...> {
template <size_t... Ns>
- bool test(const zip_first<Iters...> &other, index_sequence<Ns...>) const {
+ bool test(const zip_shortest<Iters...> &other, index_sequence<Ns...>) const {
return all_of(std::initializer_list<bool>{std::get<Ns>(this->iterators) !=
std::get<Ns>(other.iterators)...},
identity<bool>{});
}
public:
- bool operator!=(const zip_first<Iters...> &other) const {
- return test(other, index_sequence_for<Iters...>{});
+ using Base = zip_common<zip_shortest<Iters...>, Iters...>;
+
+ bool operator==(const zip_shortest<Iters...> &other) const {
+ return !test(other, index_sequence_for<Iters...>{});
}
- zip_shortest(Iters &&... ts)
- : zip_first<Iters...>(std::forward<Iters>(ts)...) {}
+
+ zip_shortest(Iters &&... ts) : Base(std::forward<Iters>(ts)...) {}
};
template <template <typename...> class ItType, typename... Args> class zippy {
public:
- typedef ItType<decltype(std::begin(std::declval<Args>()))...> iterator;
+ using iterator = ItType<decltype(std::begin(std::declval<Args>()))...>;
+ using iterator_category = typename iterator::iterator_category;
+ using value_type = typename iterator::value_type;
+ using difference_type = typename iterator::difference_type;
+ using pointer = typename iterator::pointer;
+ using reference = typename iterator::reference;
private:
std::tuple<Args...> ts;
- template <size_t... Ns> iterator begin_impl(index_sequence<Ns...>) {
+ template <size_t... Ns> iterator begin_impl(index_sequence<Ns...>) const {
return iterator(std::begin(std::get<Ns>(ts))...);
}
- template <size_t... Ns> iterator end_impl(index_sequence<Ns...>) {
+ template <size_t... Ns> iterator end_impl(index_sequence<Ns...>) const {
return iterator(std::end(std::get<Ns>(ts))...);
}
public:
- iterator begin() { return begin_impl(index_sequence_for<Args...>{}); }
- iterator end() { return end_impl(index_sequence_for<Args...>{}); }
+ iterator begin() const { return begin_impl(index_sequence_for<Args...>{}); }
+ iterator end() const { return end_impl(index_sequence_for<Args...>{}); }
zippy(Args &&... ts_) : ts(std::forward<Args>(ts_)...) {}
};
} // End detail namespace
@@ -640,6 +710,18 @@ struct is_one_of<T, U, Ts...> {
std::is_same<T, U>::value || is_one_of<T, Ts...>::value;
};
+/// \brief traits class for checking whether type T is a base class for all
+/// the given types in the variadic list.
+template <typename T, typename... Ts> struct are_base_of {
+ static const bool value = true;
+};
+
+template <typename T, typename U, typename... Ts>
+struct are_base_of<T, U, Ts...> {
+ static const bool value =
+ std::is_base_of<T, U>::value && are_base_of<T, Ts...>::value;
+};
+
//===----------------------------------------------------------------------===//
// Extra additions for arrays
//===----------------------------------------------------------------------===//
@@ -777,6 +859,13 @@ auto remove_if(R &&Range, UnaryPredicate P) -> decltype(std::begin(Range)) {
return std::remove_if(std::begin(Range), std::end(Range), P);
}
+/// Provide wrappers to std::copy_if which take ranges instead of having to
+/// pass begin/end explicitly.
+template <typename R, typename OutputIt, typename UnaryPredicate>
+OutputIt copy_if(R &&Range, OutputIt Out, UnaryPredicate P) {
+ return std::copy_if(std::begin(Range), std::end(Range), Out, P);
+}
+
/// Wrapper function around std::find to detect if an element exists
/// in a container.
template <typename R, typename E>
@@ -815,6 +904,15 @@ auto partition(R &&Range, UnaryPredicate P) -> decltype(std::begin(Range)) {
return std::partition(std::begin(Range), std::end(Range), P);
}
+/// \brief Given a range of type R, iterate the entire range and return a
+/// SmallVector with elements of the vector. This is useful, for example,
+/// when you want to iterate a range and then sort the results.
+template <unsigned Size, typename R>
+SmallVector<typename std::remove_const<detail::ValueOfRange<R>>::type, Size>
+to_vector(R &&Range) {
+ return {std::begin(Range), std::end(Range)};
+}
+
/// Provide a container algorithm similar to C++ Library Fundamentals v2's
/// `erase_if` which is equivalent to:
///
@@ -909,47 +1007,85 @@ template <typename T> struct deref {
};
namespace detail {
-template <typename R> class enumerator_impl {
-public:
- template <typename X> struct result_pair {
- result_pair(std::size_t Index, X Value) : Index(Index), Value(Value) {}
+template <typename R> class enumerator_iter;
- const std::size_t Index;
- X Value;
- };
+template <typename R> struct result_pair {
+ friend class enumerator_iter<R>;
- class iterator {
- typedef
- typename std::iterator_traits<IterOfRange<R>>::reference iter_reference;
- typedef result_pair<iter_reference> result_type;
+ result_pair() : Index(-1) {}
+ result_pair(std::size_t Index, IterOfRange<R> Iter)
+ : Index(Index), Iter(Iter) {}
- public:
- iterator(IterOfRange<R> &&Iter, std::size_t Index)
- : Iter(Iter), Index(Index) {}
+ result_pair<R> &operator=(const result_pair<R> &Other) {
+ Index = Other.Index;
+ Iter = Other.Iter;
+ return *this;
+ }
- result_type operator*() const { return result_type(Index, *Iter); }
+ std::size_t index() const { return Index; }
+ const ValueOfRange<R> &value() const { return *Iter; }
+ ValueOfRange<R> &value() { return *Iter; }
- iterator &operator++() {
- ++Iter;
- ++Index;
- return *this;
- }
+private:
+ std::size_t Index;
+ IterOfRange<R> Iter;
+};
- bool operator!=(const iterator &RHS) const { return Iter != RHS.Iter; }
+template <typename R>
+class enumerator_iter
+ : public iterator_facade_base<
+ enumerator_iter<R>, std::forward_iterator_tag, result_pair<R>,
+ typename std::iterator_traits<IterOfRange<R>>::difference_type,
+ typename std::iterator_traits<IterOfRange<R>>::pointer,
+ typename std::iterator_traits<IterOfRange<R>>::reference> {
+ using result_type = result_pair<R>;
- private:
- IterOfRange<R> Iter;
- std::size_t Index;
- };
+public:
+ explicit enumerator_iter(IterOfRange<R> EndIter)
+ : Result(std::numeric_limits<size_t>::max(), EndIter) { }
+ enumerator_iter(std::size_t Index, IterOfRange<R> Iter)
+ : Result(Index, Iter) {}
+
+ result_type &operator*() { return Result; }
+ const result_type &operator*() const { return Result; }
+
+ enumerator_iter<R> &operator++() {
+ assert(Result.Index != std::numeric_limits<size_t>::max());
+ ++Result.Iter;
+ ++Result.Index;
+ return *this;
+ }
+
+ bool operator==(const enumerator_iter<R> &RHS) const {
+ // Don't compare indices here, only iterators. It's possible for an end
+ // iterator to have different indices depending on whether it was created
+ // by calling std::end() versus incrementing a valid iterator.
+ return Result.Iter == RHS.Result.Iter;
+ }
+
+ enumerator_iter<R> &operator=(const enumerator_iter<R> &Other) {
+ Result = Other.Result;
+ return *this;
+ }
+
+private:
+ result_type Result;
+};
+
+template <typename R> class enumerator {
public:
- explicit enumerator_impl(R &&Range) : Range(std::forward<R>(Range)) {}
+ explicit enumerator(R &&Range) : TheRange(std::forward<R>(Range)) {}
- iterator begin() { return iterator(std::begin(Range), 0); }
- iterator end() { return iterator(std::end(Range), std::size_t(-1)); }
+ enumerator_iter<R> begin() {
+ return enumerator_iter<R>(0, std::begin(TheRange));
+ }
+ enumerator_iter<R> end() {
+ return enumerator_iter<R>(std::end(TheRange));
+ }
private:
- R Range;
+ R TheRange;
};
}
@@ -959,7 +1095,7 @@ private:
///
/// std::vector<char> Items = {'A', 'B', 'C', 'D'};
/// for (auto X : enumerate(Items)) {
-/// printf("Item %d - %c\n", X.Index, X.Value);
+/// printf("Item %d - %c\n", X.index(), X.value());
/// }
///
/// Output:
@@ -968,8 +1104,8 @@ private:
/// Item 2 - C
/// Item 3 - D
///
-template <typename R> detail::enumerator_impl<R> enumerate(R &&Range) {
- return detail::enumerator_impl<R>(std::forward<R>(Range));
+template <typename R> detail::enumerator<R> enumerate(R &&TheRange) {
+ return detail::enumerator<R>(std::forward<R>(TheRange));
}
namespace detail {
diff --git a/contrib/llvm/include/llvm/ADT/ScopedHashTable.h b/contrib/llvm/include/llvm/ADT/ScopedHashTable.h
index ad805b0..22b0c1b 100644
--- a/contrib/llvm/include/llvm/ADT/ScopedHashTable.h
+++ b/contrib/llvm/include/llvm/ADT/ScopedHashTable.h
@@ -109,6 +109,7 @@ private:
ScopedHashTableVal<K, V> *getLastValInScope() {
return LastValInScope;
}
+
void setLastValInScope(ScopedHashTableVal<K, V> *Val) {
LastValInScope = Val;
}
@@ -151,13 +152,14 @@ class ScopedHashTable {
public:
/// ScopeTy - This is a helpful typedef that allows clients to get easy access
/// to the name of the scope for this hash table.
- typedef ScopedHashTableScope<K, V, KInfo, AllocatorTy> ScopeTy;
- typedef unsigned size_type;
+ using ScopeTy = ScopedHashTableScope<K, V, KInfo, AllocatorTy>;
+ using size_type = unsigned;
private:
friend class ScopedHashTableScope<K, V, KInfo, AllocatorTy>;
- typedef ScopedHashTableVal<K, V> ValTy;
+ using ValTy = ScopedHashTableVal<K, V>;
+
DenseMap<K, ValTy*, KInfo> TopLevelMap;
ScopeTy *CurScope = nullptr;
@@ -165,7 +167,7 @@ private:
public:
ScopedHashTable() = default;
- ScopedHashTable(AllocatorTy A) : CurScope(0), Allocator(A) {}
+ ScopedHashTable(AllocatorTy A) : Allocator(A) {}
ScopedHashTable(const ScopedHashTable &) = delete;
ScopedHashTable &operator=(const ScopedHashTable &) = delete;
@@ -182,8 +184,8 @@ public:
return TopLevelMap.count(Key);
}
- V lookup(const K &Key) {
- typename DenseMap<K, ValTy*, KInfo>::iterator I = TopLevelMap.find(Key);
+ V lookup(const K &Key) const {
+ auto I = TopLevelMap.find(Key);
if (I != TopLevelMap.end())
return I->second->getValue();
@@ -194,7 +196,7 @@ public:
insertIntoScope(CurScope, Key, Val);
}
- typedef ScopedHashTableIterator<K, V, KInfo> iterator;
+ using iterator = ScopedHashTableIterator<K, V, KInfo>;
iterator end() { return iterator(0); }
diff --git a/contrib/llvm/include/llvm/ADT/Sequence.h b/contrib/llvm/include/llvm/ADT/Sequence.h
index 5d36831..3d4a897 100644
--- a/contrib/llvm/include/llvm/ADT/Sequence.h
+++ b/contrib/llvm/include/llvm/ADT/Sequence.h
@@ -13,27 +13,31 @@
///
//===----------------------------------------------------------------------===//
-#ifndef LLVM_ADT_SEQ_H
-#define LLVM_ADT_SEQ_H
+#ifndef LLVM_ADT_SEQUENCE_H
+#define LLVM_ADT_SEQUENCE_H
#include "llvm/ADT/iterator.h"
#include "llvm/ADT/iterator_range.h"
+#include <algorithm>
+#include <iterator>
+#include <utility>
namespace llvm {
namespace detail {
+
template <typename ValueT>
class value_sequence_iterator
: public iterator_facade_base<value_sequence_iterator<ValueT>,
std::random_access_iterator_tag,
const ValueT> {
- typedef typename value_sequence_iterator::iterator_facade_base BaseT;
+ using BaseT = typename value_sequence_iterator::iterator_facade_base;
ValueT Value;
public:
- typedef typename BaseT::difference_type difference_type;
- typedef typename BaseT::reference reference;
+ using difference_type = typename BaseT::difference_type;
+ using reference = typename BaseT::reference;
value_sequence_iterator() = default;
value_sequence_iterator(const value_sequence_iterator &) = default;
@@ -65,7 +69,8 @@ public:
reference operator*() const { return Value; }
};
-} // End detail namespace.
+
+} // end namespace detail
template <typename ValueT>
iterator_range<detail::value_sequence_iterator<ValueT>> seq(ValueT Begin,
@@ -74,6 +79,6 @@ iterator_range<detail::value_sequence_iterator<ValueT>> seq(ValueT Begin,
detail::value_sequence_iterator<ValueT>(End));
}
-}
+} // end namespace llvm
-#endif
+#endif // LLVM_ADT_SEQUENCE_H
diff --git a/contrib/llvm/include/llvm/ADT/SetVector.h b/contrib/llvm/include/llvm/ADT/SetVector.h
index 4dc18bc..04ed52f 100644
--- a/contrib/llvm/include/llvm/ADT/SetVector.h
+++ b/contrib/llvm/include/llvm/ADT/SetVector.h
@@ -40,17 +40,17 @@ template <typename T, typename Vector = std::vector<T>,
typename Set = DenseSet<T>>
class SetVector {
public:
- typedef T value_type;
- typedef T key_type;
- typedef T& reference;
- typedef const T& const_reference;
- typedef Set set_type;
- typedef Vector vector_type;
- typedef typename vector_type::const_iterator iterator;
- typedef typename vector_type::const_iterator const_iterator;
- typedef typename vector_type::const_reverse_iterator reverse_iterator;
- typedef typename vector_type::const_reverse_iterator const_reverse_iterator;
- typedef typename vector_type::size_type size_type;
+ using value_type = T;
+ using key_type = T;
+ using reference = T&;
+ using const_reference = const T&;
+ using set_type = Set;
+ using vector_type = Vector;
+ using iterator = typename vector_type::const_iterator;
+ using const_iterator = typename vector_type::const_iterator;
+ using reverse_iterator = typename vector_type::const_reverse_iterator;
+ using const_reverse_iterator = typename vector_type::const_reverse_iterator;
+ using size_type = typename vector_type::size_type;
/// \brief Construct an empty SetVector
SetVector() = default;
@@ -119,6 +119,12 @@ public:
return vector_.rend();
}
+ /// \brief Return the first element of the SetVector.
+ const T &front() const {
+ assert(!empty() && "Cannot call front() on empty SetVector!");
+ return vector_.front();
+ }
+
/// \brief Return the last element of the SetVector.
const T &back() const {
assert(!empty() && "Cannot call back() on empty SetVector!");
@@ -232,7 +238,7 @@ public:
bool operator!=(const SetVector &that) const {
return vector_ != that.vector_;
}
-
+
/// \brief Compute This := This u S, return whether 'This' changed.
/// TODO: We should be able to use set_union from SetOperations.h, but
/// SetVector interface is inconsistent with DenseSet.
diff --git a/contrib/llvm/include/llvm/ADT/SmallBitVector.h b/contrib/llvm/include/llvm/ADT/SmallBitVector.h
index bb99e0c..b639174 100644
--- a/contrib/llvm/include/llvm/ADT/SmallBitVector.h
+++ b/contrib/llvm/include/llvm/ADT/SmallBitVector.h
@@ -15,8 +15,15 @@
#define LLVM_ADT_SMALLBITVECTOR_H
#include "llvm/ADT/BitVector.h"
+#include "llvm/ADT/iterator_range.h"
#include "llvm/Support/MathExtras.h"
+#include <algorithm>
#include <cassert>
+#include <climits>
+#include <cstddef>
+#include <cstdint>
+#include <limits>
+#include <utility>
namespace llvm {
@@ -29,7 +36,7 @@ class SmallBitVector {
// TODO: In "large" mode, a pointer to a BitVector is used, leading to an
// unnecessary level of indirection. It would be more efficient to use a
// pointer to memory containing size, allocation size, and the array of bits.
- uintptr_t X;
+ uintptr_t X = 1;
enum {
// The number of bits in this class.
@@ -54,7 +61,8 @@ class SmallBitVector {
"Unsupported word size");
public:
- typedef unsigned size_type;
+ using size_type = unsigned;
+
// Encapsulation of a single bit.
class reference {
SmallBitVector &TheVector;
@@ -117,9 +125,7 @@ private:
}
// Return the size.
- size_t getSmallSize() const {
- return getSmallRawBits() >> SmallNumDataBits;
- }
+ size_t getSmallSize() const { return getSmallRawBits() >> SmallNumDataBits; }
void setSmallSize(size_t Size) {
setSmallRawBits(getSmallBits() | (Size << SmallNumDataBits));
@@ -137,7 +143,7 @@ private:
public:
/// Creates an empty bitvector.
- SmallBitVector() : X(1) {}
+ SmallBitVector() = default;
/// Creates a bitvector of specified number of bits. All bits are initialized
/// to the specified value.
@@ -165,6 +171,21 @@ public:
delete getPointer();
}
+ using const_set_bits_iterator = const_set_bits_iterator_impl<SmallBitVector>;
+ using set_iterator = const_set_bits_iterator;
+
+ const_set_bits_iterator set_bits_begin() const {
+ return const_set_bits_iterator(*this);
+ }
+
+ const_set_bits_iterator set_bits_end() const {
+ return const_set_bits_iterator(*this, -1);
+ }
+
+ iterator_range<const_set_bits_iterator> set_bits() const {
+ return make_range(set_bits_begin(), set_bits_end());
+ }
+
/// Tests whether there are no bits in this bitvector.
bool empty() const {
return isSmall() ? getSmallSize() == 0 : getPointer()->empty();
@@ -216,6 +237,39 @@ public:
return getPointer()->find_first();
}
+ int find_last() const {
+ if (isSmall()) {
+ uintptr_t Bits = getSmallBits();
+ if (Bits == 0)
+ return -1;
+ return NumBaseBits - countLeadingZeros(Bits);
+ }
+ return getPointer()->find_last();
+ }
+
+ /// Returns the index of the first unset bit, -1 if all of the bits are set.
+ int find_first_unset() const {
+ if (isSmall()) {
+ if (count() == getSmallSize())
+ return -1;
+
+ uintptr_t Bits = getSmallBits();
+ return countTrailingOnes(Bits);
+ }
+ return getPointer()->find_first_unset();
+ }
+
+ int find_last_unset() const {
+ if (isSmall()) {
+ if (count() == getSmallSize())
+ return -1;
+
+ uintptr_t Bits = getSmallBits();
+ return NumBaseBits - countLeadingOnes(Bits);
+ }
+ return getPointer()->find_last_unset();
+ }
+
/// Returns the index of the next set bit following the "Prev" bit.
/// Returns -1 if the next set bit is not found.
int find_next(unsigned Prev) const {
@@ -230,6 +284,41 @@ public:
return getPointer()->find_next(Prev);
}
+ /// Returns the index of the next unset bit following the "Prev" bit.
+ /// 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 = (1 << Prev) - 1;
+ Bits |= Mask;
+
+ if (Bits == ~uintptr_t(0) || Prev + 1 >= getSmallSize())
+ return -1;
+ return countTrailingOnes(Bits);
+ }
+ return getPointer()->find_next_unset(Prev);
+ }
+
+ /// find_prev - Returns the index of the first set bit that precedes the
+ /// the bit at \p PriorTo. Returns -1 if all previous bits are unset.
+ int find_prev(unsigned PriorTo) const {
+ if (isSmall()) {
+ if (PriorTo == 0)
+ return -1;
+
+ --PriorTo;
+ uintptr_t Bits = getSmallBits();
+ Bits &= maskTrailingOnes<uintptr_t>(PriorTo + 1);
+ if (Bits == 0)
+ return -1;
+
+ return NumBaseBits - countLeadingZeros(Bits) - 1;
+ }
+ return getPointer()->find_prev(PriorTo);
+ }
+
/// Clear all bits.
void clear() {
if (!isSmall())
@@ -479,6 +568,22 @@ public:
return *this;
}
+ SmallBitVector &operator<<=(unsigned N) {
+ if (isSmall())
+ setSmallBits(getSmallBits() << N);
+ else
+ getPointer()->operator<<=(N);
+ return *this;
+ }
+
+ SmallBitVector &operator>>=(unsigned N) {
+ if (isSmall())
+ setSmallBits(getSmallBits() >> N);
+ else
+ getPointer()->operator>>=(N);
+ return *this;
+ }
+
// Assignment operator.
const SmallBitVector &operator=(const SmallBitVector &RHS) {
if (isSmall()) {
@@ -582,14 +687,16 @@ operator^(const SmallBitVector &LHS, const SmallBitVector &RHS) {
return Result;
}
-} // End llvm namespace
+} // end namespace llvm
namespace std {
- /// Implement std::swap in terms of BitVector swap.
- inline void
- swap(llvm::SmallBitVector &LHS, llvm::SmallBitVector &RHS) {
- LHS.swap(RHS);
- }
+
+/// Implement std::swap in terms of BitVector swap.
+inline void
+swap(llvm::SmallBitVector &LHS, llvm::SmallBitVector &RHS) {
+ LHS.swap(RHS);
}
-#endif
+} // end namespace std
+
+#endif // LLVM_ADT_SMALLBITVECTOR_H
diff --git a/contrib/llvm/include/llvm/ADT/SmallPtrSet.h b/contrib/llvm/include/llvm/ADT/SmallPtrSet.h
index 49feb9d..4e8a249 100644
--- a/contrib/llvm/include/llvm/ADT/SmallPtrSet.h
+++ b/contrib/llvm/include/llvm/ADT/SmallPtrSet.h
@@ -15,24 +15,18 @@
#ifndef LLVM_ADT_SMALLPTRSET_H
#define LLVM_ADT_SMALLPTRSET_H
-#include "llvm/Config/abi-breaking.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/PointerLikeTypeTraits.h"
+#include "llvm/Support/ReverseIteration.h"
+#include "llvm/Support/type_traits.h"
#include <cassert>
#include <cstddef>
-#include <cstring>
#include <cstdlib>
+#include <cstring>
#include <initializer_list>
#include <iterator>
#include <utility>
-#if LLVM_ENABLE_ABI_BREAKING_CHECKS
-namespace llvm {
-template <class T = void> struct ReverseIterate { static bool value; };
-template <class T> bool ReverseIterate<T>::value = false;
-}
-#endif
-
namespace llvm {
/// SmallPtrSetImplBase - This is the common code shared among all the
@@ -91,7 +85,7 @@ protected:
}
public:
- typedef unsigned size_type;
+ using size_type = unsigned;
SmallPtrSetImplBase &operator=(const SmallPtrSetImplBase &) = delete;
@@ -166,8 +160,8 @@ protected:
const void *const *P = find_imp(Ptr);
if (P == EndPointer())
return false;
-
- const void ** Loc = const_cast<const void **>(P);
+
+ const void **Loc = const_cast<const void **>(P);
assert(*Loc == Ptr && "broken find!");
*Loc = getTombstoneMarker();
NumTombstones++;
@@ -193,7 +187,7 @@ protected:
return Bucket;
return EndPointer();
}
-
+
private:
bool isSmall() const { return CurArray == SmallArray; }
@@ -259,11 +253,10 @@ protected:
}
#if LLVM_ENABLE_ABI_BREAKING_CHECKS
void RetreatIfNotValid() {
- --Bucket;
- assert(Bucket <= End);
+ assert(Bucket >= End);
while (Bucket != End &&
- (*Bucket == SmallPtrSetImplBase::getEmptyMarker() ||
- *Bucket == SmallPtrSetImplBase::getTombstoneMarker())) {
+ (Bucket[-1] == SmallPtrSetImplBase::getEmptyMarker() ||
+ Bucket[-1] == SmallPtrSetImplBase::getTombstoneMarker())) {
--Bucket;
}
}
@@ -273,14 +266,14 @@ protected:
/// SmallPtrSetIterator - This implements a const_iterator for SmallPtrSet.
template<typename PtrTy>
class SmallPtrSetIterator : public SmallPtrSetIteratorImpl {
- typedef PointerLikeTypeTraits<PtrTy> PtrTraits;
+ using PtrTraits = PointerLikeTypeTraits<PtrTy>;
public:
- typedef PtrTy value_type;
- typedef PtrTy reference;
- typedef PtrTy pointer;
- typedef std::ptrdiff_t difference_type;
- typedef std::forward_iterator_tag iterator_category;
+ using value_type = PtrTy;
+ using reference = PtrTy;
+ using pointer = PtrTy;
+ using difference_type = std::ptrdiff_t;
+ using iterator_category = std::forward_iterator_tag;
explicit SmallPtrSetIterator(const void *const *BP, const void *const *E)
: SmallPtrSetIteratorImpl(BP, E) {}
@@ -288,6 +281,12 @@ public:
// Most methods provided by baseclass.
const PtrTy operator*() const {
+#if LLVM_ENABLE_ABI_BREAKING_CHECKS
+ if (ReverseIterate<bool>::value) {
+ assert(Bucket > End);
+ return PtrTraits::getFromVoidPointer(const_cast<void *>(Bucket[-1]));
+ }
+#endif
assert(Bucket < End);
return PtrTraits::getFromVoidPointer(const_cast<void*>(*Bucket));
}
@@ -295,6 +294,7 @@ public:
inline SmallPtrSetIterator& operator++() { // Preincrement
#if LLVM_ENABLE_ABI_BREAKING_CHECKS
if (ReverseIterate<bool>::value) {
+ --Bucket;
RetreatIfNotValid();
return *this;
}
@@ -343,7 +343,9 @@ struct RoundUpToPowerOfTwo {
/// to avoid encoding a particular small size in the interface boundary.
template <typename PtrType>
class SmallPtrSetImpl : public SmallPtrSetImplBase {
- typedef PointerLikeTypeTraits<PtrType> PtrTraits;
+ using ConstPtrType = typename add_const_past_pointer<PtrType>::type;
+ using PtrTraits = PointerLikeTypeTraits<PtrType>;
+ using ConstPtrTraits = PointerLikeTypeTraits<ConstPtrType>;
protected:
// Constructors that forward to the base.
@@ -356,8 +358,10 @@ protected:
: SmallPtrSetImplBase(SmallStorage, SmallSize) {}
public:
- typedef SmallPtrSetIterator<PtrType> iterator;
- typedef SmallPtrSetIterator<PtrType> const_iterator;
+ using iterator = SmallPtrSetIterator<PtrType>;
+ using const_iterator = SmallPtrSetIterator<PtrType>;
+ using key_type = ConstPtrType;
+ using value_type = PtrType;
SmallPtrSetImpl(const SmallPtrSetImpl &) = delete;
@@ -367,7 +371,7 @@ public:
/// the element equal to Ptr.
std::pair<iterator, bool> insert(PtrType Ptr) {
auto p = insert_imp(PtrTraits::getAsVoidPointer(Ptr));
- return std::make_pair(iterator(p.first, EndPointer()), p.second);
+ return std::make_pair(makeIterator(p.first), p.second);
}
/// erase - If the set contains the specified pointer, remove it and return
@@ -375,14 +379,10 @@ public:
bool erase(PtrType Ptr) {
return erase_imp(PtrTraits::getAsVoidPointer(Ptr));
}
-
/// count - Return 1 if the specified pointer is in the set, 0 otherwise.
- size_type count(PtrType Ptr) const {
- return find(Ptr) != endPtr() ? 1 : 0;
- }
- iterator find(PtrType Ptr) const {
- auto *P = find_imp(PtrTraits::getAsVoidPointer(Ptr));
- return iterator(P, EndPointer());
+ size_type count(ConstPtrType Ptr) const { return find(Ptr) != end() ? 1 : 0; }
+ iterator find(ConstPtrType Ptr) const {
+ return makeIterator(find_imp(ConstPtrTraits::getAsVoidPointer(Ptr)));
}
template <typename IterT>
@@ -395,25 +395,23 @@ public:
insert(IL.begin(), IL.end());
}
- inline iterator begin() const {
+ iterator begin() const {
#if LLVM_ENABLE_ABI_BREAKING_CHECKS
if (ReverseIterate<bool>::value)
- return endPtr();
+ return makeIterator(EndPointer() - 1);
#endif
- return iterator(CurArray, EndPointer());
+ return makeIterator(CurArray);
}
- inline iterator end() const {
+ iterator end() const { return makeIterator(EndPointer()); }
+
+private:
+ /// Create an iterator that dereferences to same place as the given pointer.
+ iterator makeIterator(const void *const *P) const {
#if LLVM_ENABLE_ABI_BREAKING_CHECKS
if (ReverseIterate<bool>::value)
- return iterator(CurArray, CurArray);
+ return iterator(P == EndPointer() ? CurArray : P + 1, CurArray);
#endif
- return endPtr();
- }
-
-private:
- inline iterator endPtr() const {
- const void *const *End = EndPointer();
- return iterator(End, End);
+ return iterator(P, EndPointer());
}
};
@@ -428,7 +426,7 @@ class SmallPtrSet : public SmallPtrSetImpl<PtrType> {
// DenseSet<> instead if you expect many elements in the set.
static_assert(SmallSize <= 32, "SmallSize should be small");
- typedef SmallPtrSetImpl<PtrType> BaseT;
+ using BaseT = SmallPtrSetImpl<PtrType>;
// Make sure that SmallSize is a power of two, round up if not.
enum { SmallSizePowTwo = RoundUpToPowerOfTwo<SmallSize>::Val };
diff --git a/contrib/llvm/include/llvm/ADT/SmallSet.h b/contrib/llvm/include/llvm/ADT/SmallSet.h
index 6dac167..d52d0f0 100644
--- a/contrib/llvm/include/llvm/ADT/SmallSet.h
+++ b/contrib/llvm/include/llvm/ADT/SmallSet.h
@@ -39,8 +39,9 @@ class SmallSet {
/// we will never use.
SmallVector<T, N> Vector;
std::set<T, C> Set;
- typedef typename SmallVector<T, N>::const_iterator VIterator;
- typedef typename SmallVector<T, N>::iterator mutable_iterator;
+
+ using VIterator = typename SmallVector<T, N>::const_iterator;
+ using mutable_iterator = typename SmallVector<T, N>::iterator;
// In small mode SmallPtrSet uses linear search for the elements, so it is
// not a good idea to choose this value too high. You may consider using a
@@ -48,7 +49,7 @@ class SmallSet {
static_assert(N <= 32, "N should be small");
public:
- typedef size_t size_type;
+ using size_type = size_t;
SmallSet() = default;
diff --git a/contrib/llvm/include/llvm/ADT/SmallVector.h b/contrib/llvm/include/llvm/ADT/SmallVector.h
index b958821..bf2a62f 100644
--- a/contrib/llvm/include/llvm/ADT/SmallVector.h
+++ b/contrib/llvm/include/llvm/ADT/SmallVector.h
@@ -71,7 +71,7 @@ private:
// Allocate raw space for N elements of type T. If T has a ctor or dtor, we
// don't want it to be automatically run, so we need to represent the space as
// something else. Use an array of char of sufficient alignment.
- typedef AlignedCharArrayUnion<T> U;
+ using U = AlignedCharArrayUnion<T>;
U FirstEl;
// Space after 'FirstEl' is clobbered, do not add any instance vars after it.
@@ -96,19 +96,19 @@ protected:
void setEnd(T *P) { this->EndX = P; }
public:
- typedef size_t size_type;
- typedef ptrdiff_t difference_type;
- typedef T value_type;
- typedef T *iterator;
- typedef const T *const_iterator;
+ using size_type = size_t;
+ using difference_type = ptrdiff_t;
+ using value_type = T;
+ using iterator = T *;
+ using const_iterator = const T *;
- typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
- typedef std::reverse_iterator<iterator> reverse_iterator;
+ using const_reverse_iterator = std::reverse_iterator<const_iterator>;
+ using reverse_iterator = std::reverse_iterator<iterator>;
- typedef T &reference;
- typedef const T &const_reference;
- typedef T *pointer;
- typedef const T *const_pointer;
+ using reference = T &;
+ using const_reference = const T &;
+ using pointer = T *;
+ using const_pointer = const T *;
// forward iterator creation methods.
LLVM_ATTRIBUTE_ALWAYS_INLINE
@@ -319,12 +319,12 @@ public:
/// reduce code duplication based on the SmallVector 'N' template parameter.
template <typename T>
class SmallVectorImpl : public SmallVectorTemplateBase<T, isPodLike<T>::value> {
- typedef SmallVectorTemplateBase<T, isPodLike<T>::value > SuperClass;
+ using SuperClass = SmallVectorTemplateBase<T, isPodLike<T>::value>;
public:
- typedef typename SuperClass::iterator iterator;
- typedef typename SuperClass::const_iterator const_iterator;
- typedef typename SuperClass::size_type size_type;
+ using iterator = typename SuperClass::iterator;
+ using const_iterator = typename SuperClass::const_iterator;
+ using size_type = typename SuperClass::size_type;
protected:
// Default ctor - Initialize to empty.
@@ -388,7 +388,10 @@ public:
void swap(SmallVectorImpl &RHS);
/// Add the specified range to the end of the SmallVector.
- template<typename in_iter>
+ template <typename in_iter,
+ typename = typename std::enable_if<std::is_convertible<
+ typename std::iterator_traits<in_iter>::iterator_category,
+ std::input_iterator_tag>::value>::type>
void append(in_iter in_start, in_iter in_end) {
size_type NumInputs = std::distance(in_start, in_end);
// Grow allocated space if needed.
@@ -415,6 +418,9 @@ public:
append(IL.begin(), IL.end());
}
+ // FIXME: Consider assigning over existing elements, rather than clearing &
+ // re-initializing them - for all assign(...) variants.
+
void assign(size_type NumElts, const T &Elt) {
clear();
if (this->capacity() < NumElts)
@@ -423,6 +429,15 @@ public:
std::uninitialized_fill(this->begin(), this->end(), Elt);
}
+ template <typename in_iter,
+ typename = typename std::enable_if<std::is_convertible<
+ typename std::iterator_traits<in_iter>::iterator_category,
+ std::input_iterator_tag>::value>::type>
+ void assign(in_iter in_start, in_iter in_end) {
+ clear();
+ append(in_start, in_end);
+ }
+
void assign(std::initializer_list<T> IL) {
clear();
append(IL);
@@ -571,7 +586,10 @@ public:
return I;
}
- template<typename ItTy>
+ template <typename ItTy,
+ typename = typename std::enable_if<std::is_convertible<
+ typename std::iterator_traits<ItTy>::iterator_category,
+ std::input_iterator_tag>::value>::type>
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();
@@ -845,15 +863,17 @@ class SmallVector : public SmallVectorImpl<T> {
SmallVectorStorage<T, N> Storage;
public:
- SmallVector() : SmallVectorImpl<T>(N) {
- }
+ SmallVector() : SmallVectorImpl<T>(N) {}
explicit SmallVector(size_t Size, const T &Value = T())
: SmallVectorImpl<T>(N) {
this->assign(Size, Value);
}
- template<typename ItTy>
+ template <typename ItTy,
+ typename = typename std::enable_if<std::is_convertible<
+ typename std::iterator_traits<ItTy>::iterator_category,
+ std::input_iterator_tag>::value>::type>
SmallVector(ItTy S, ItTy E) : SmallVectorImpl<T>(N) {
this->append(S, E);
}
@@ -883,16 +903,16 @@ public:
SmallVectorImpl<T>::operator=(::std::move(RHS));
}
- const SmallVector &operator=(SmallVector &&RHS) {
- SmallVectorImpl<T>::operator=(::std::move(RHS));
- return *this;
- }
-
SmallVector(SmallVectorImpl<T> &&RHS) : SmallVectorImpl<T>(N) {
if (!RHS.empty())
SmallVectorImpl<T>::operator=(::std::move(RHS));
}
+ const SmallVector &operator=(SmallVector &&RHS) {
+ SmallVectorImpl<T>::operator=(::std::move(RHS));
+ return *this;
+ }
+
const SmallVector &operator=(SmallVectorImpl<T> &&RHS) {
SmallVectorImpl<T>::operator=(::std::move(RHS));
return *this;
diff --git a/contrib/llvm/include/llvm/ADT/SparseBitVector.h b/contrib/llvm/include/llvm/ADT/SparseBitVector.h
index e2822c4..4cbf40c 100644
--- a/contrib/llvm/include/llvm/ADT/SparseBitVector.h
+++ b/contrib/llvm/include/llvm/ADT/SparseBitVector.h
@@ -1,4 +1,4 @@
-//===- llvm/ADT/SparseBitVector.h - Efficient Sparse BitVector -*- C++ -*- ===//
+//===- llvm/ADT/SparseBitVector.h - Efficient Sparse BitVector --*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -41,8 +41,8 @@ namespace llvm {
template <unsigned ElementSize = 128> struct SparseBitVectorElement {
public:
- typedef unsigned long BitWord;
- typedef unsigned size_type;
+ using BitWord = unsigned long;
+ using size_type = unsigned;
enum {
BITWORD_SIZE = sizeof(BitWord) * CHAR_BIT,
BITWORDS_PER_ELEMENT = (ElementSize + BITWORD_SIZE - 1) / BITWORD_SIZE,
@@ -100,7 +100,7 @@ public:
Bits[Idx / BITWORD_SIZE] |= 1L << (Idx % BITWORD_SIZE);
}
- bool test_and_set (unsigned Idx) {
+ bool test_and_set(unsigned Idx) {
bool old = test(Idx);
if (!old) {
set(Idx);
@@ -132,6 +132,17 @@ public:
llvm_unreachable("Illegal empty element");
}
+ /// find_last - Returns the index of the last set bit.
+ int find_last() const {
+ for (unsigned I = 0; I < BITWORDS_PER_ELEMENT; ++I) {
+ unsigned Idx = BITWORDS_PER_ELEMENT - I - 1;
+ if (Bits[Idx] != 0)
+ return Idx * BITWORD_SIZE + BITWORD_SIZE -
+ countLeadingZeros(Bits[Idx]) - 1;
+ }
+ llvm_unreachable("Illegal empty element");
+ }
+
/// find_next - Returns the index of the next set bit starting from the
/// "Curr" bit. Returns -1 if the next set bit is not found.
int find_next(unsigned Curr) const {
@@ -243,9 +254,9 @@ public:
template <unsigned ElementSize = 128>
class SparseBitVector {
- typedef std::list<SparseBitVectorElement<ElementSize>> ElementList;
- typedef typename ElementList::iterator ElementListIter;
- typedef typename ElementList::const_iterator ElementListConstIter;
+ using ElementList = std::list<SparseBitVectorElement<ElementSize>>;
+ using ElementListIter = typename ElementList::iterator;
+ using ElementListConstIter = typename ElementList::const_iterator;
enum {
BITWORD_SIZE = SparseBitVectorElement<ElementSize>::BITWORD_SIZE
};
@@ -410,14 +421,12 @@ class SparseBitVector {
};
public:
- typedef SparseBitVectorIterator iterator;
+ using iterator = SparseBitVectorIterator;
SparseBitVector() {
CurrElementIter = Elements.begin();
}
- ~SparseBitVector() = default;
-
// SparseBitVector copy ctor.
SparseBitVector(const SparseBitVector &RHS) {
ElementListConstIter ElementIter = RHS.Elements.begin();
@@ -429,6 +438,8 @@ public:
CurrElementIter = Elements.begin ();
}
+ ~SparseBitVector() = default;
+
// Clear.
void clear() {
Elements.clear();
@@ -768,6 +779,14 @@ public:
return (First.index() * ElementSize) + First.find_first();
}
+ // Return the last set bit in the bitmap. Return -1 if no bits are set.
+ int find_last() const {
+ if (Elements.empty())
+ return -1;
+ const SparseBitVectorElement<ElementSize> &Last = *(Elements.rbegin());
+ return (Last.index() * ElementSize) + Last.find_last();
+ }
+
// Return true if the SparseBitVector is empty
bool empty() const {
return Elements.empty();
diff --git a/contrib/llvm/include/llvm/ADT/SparseMultiSet.h b/contrib/llvm/include/llvm/ADT/SparseMultiSet.h
index 08da4b6..c91e0d7 100644
--- a/contrib/llvm/include/llvm/ADT/SparseMultiSet.h
+++ b/contrib/llvm/include/llvm/ADT/SparseMultiSet.h
@@ -1,4 +1,4 @@
-//===--- llvm/ADT/SparseMultiSet.h - Sparse multiset ------------*- C++ -*-===//
+//===- llvm/ADT/SparseMultiSet.h - Sparse multiset --------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -21,9 +21,9 @@
#ifndef LLVM_ADT_SPARSEMULTISET_H
#define LLVM_ADT_SPARSEMULTISET_H
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/SparseSet.h"
-#include "llvm/ADT/STLExtras.h"
#include <cassert>
#include <cstdint>
#include <cstdlib>
@@ -101,7 +101,7 @@ class SparseMultiSet {
unsigned Prev;
unsigned Next;
- SMSNode(ValueT D, unsigned P, unsigned N) : Data(D), Prev(P), Next(N) { }
+ SMSNode(ValueT D, unsigned P, unsigned N) : Data(D), Prev(P), Next(N) {}
/// List tails have invalid Nexts.
bool isTail() const {
@@ -118,8 +118,8 @@ class SparseMultiSet {
bool isValid() const { return Prev != INVALID; }
};
- typedef typename KeyFunctorT::argument_type KeyT;
- typedef SmallVector<SMSNode, 8> DenseT;
+ using KeyT = typename KeyFunctorT::argument_type;
+ using DenseT = SmallVector<SMSNode, 8>;
DenseT Dense;
SparseT *Sparse = nullptr;
unsigned Universe = 0;
@@ -183,12 +183,12 @@ class SparseMultiSet {
}
public:
- typedef ValueT value_type;
- typedef ValueT &reference;
- typedef const ValueT &const_reference;
- typedef ValueT *pointer;
- typedef const ValueT *const_pointer;
- typedef unsigned size_type;
+ using value_type = ValueT;
+ using reference = ValueT &;
+ using const_reference = const ValueT &;
+ using pointer = ValueT *;
+ using const_pointer = const ValueT *;
+ using size_type = unsigned;
SparseMultiSet() = default;
SparseMultiSet(const SparseMultiSet &) = delete;
@@ -227,7 +227,7 @@ public:
unsigned SparseIdx;
iterator_base(SMSPtrTy P, unsigned I, unsigned SI)
- : SMS(P), Idx(I), SparseIdx(SI) { }
+ : SMS(P), Idx(I), SparseIdx(SI) {}
/// Whether our iterator has fallen outside our dense vector.
bool isEnd() const {
@@ -248,11 +248,11 @@ public:
void setNext(unsigned N) { SMS->Dense[Idx].Next = N; }
public:
- typedef std::iterator<std::bidirectional_iterator_tag, ValueT> super;
- typedef typename super::value_type value_type;
- typedef typename super::difference_type difference_type;
- typedef typename super::pointer pointer;
- typedef typename super::reference reference;
+ using super = std::iterator<std::bidirectional_iterator_tag, ValueT>;
+ using value_type = typename super::value_type;
+ using difference_type = typename super::difference_type;
+ using pointer = typename super::pointer;
+ using reference = typename super::reference;
reference operator*() const {
assert(isKeyed() && SMS->sparseIndex(SMS->Dense[Idx].Data) == SparseIdx &&
@@ -308,11 +308,12 @@ public:
return I;
}
};
- typedef iterator_base<SparseMultiSet *> iterator;
- typedef iterator_base<const SparseMultiSet *> const_iterator;
+
+ using iterator = iterator_base<SparseMultiSet *>;
+ using const_iterator = iterator_base<const SparseMultiSet *>;
// Convenience types
- typedef std::pair<iterator, iterator> RangePair;
+ using RangePair = std::pair<iterator, iterator>;
/// Returns an iterator past this container. Note that such an iterator cannot
/// be decremented, but will compare equal to other end iterators.
diff --git a/contrib/llvm/include/llvm/ADT/SparseSet.h b/contrib/llvm/include/llvm/ADT/SparseSet.h
index 00c18c7..25ade88 100644
--- a/contrib/llvm/include/llvm/ADT/SparseSet.h
+++ b/contrib/llvm/include/llvm/ADT/SparseSet.h
@@ -1,4 +1,4 @@
-//===--- llvm/ADT/SparseSet.h - Sparse set ----------------------*- C++ -*-===//
+//===- llvm/ADT/SparseSet.h - Sparse set ------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -125,9 +125,9 @@ class SparseSet {
!std::numeric_limits<SparseT>::is_signed,
"SparseT must be an unsigned integer type");
- typedef typename KeyFunctorT::argument_type KeyT;
- typedef SmallVector<ValueT, 8> DenseT;
- typedef unsigned size_type;
+ using KeyT = typename KeyFunctorT::argument_type;
+ using DenseT = SmallVector<ValueT, 8>;
+ using size_type = unsigned;
DenseT Dense;
SparseT *Sparse = nullptr;
unsigned Universe = 0;
@@ -135,11 +135,11 @@ class SparseSet {
SparseSetValFunctor<KeyT, ValueT, KeyFunctorT> ValIndexOf;
public:
- typedef ValueT value_type;
- typedef ValueT &reference;
- typedef const ValueT &const_reference;
- typedef ValueT *pointer;
- typedef const ValueT *const_pointer;
+ using value_type = ValueT;
+ using reference = ValueT &;
+ using const_reference = const ValueT &;
+ using pointer = ValueT *;
+ using const_pointer = const ValueT *;
SparseSet() = default;
SparseSet(const SparseSet &) = delete;
@@ -168,8 +168,8 @@ public:
}
// Import trivial vector stuff from DenseT.
- typedef typename DenseT::iterator iterator;
- typedef typename DenseT::const_iterator const_iterator;
+ using iterator = typename DenseT::iterator;
+ using const_iterator = typename DenseT::const_iterator;
const_iterator begin() const { return Dense.begin(); }
const_iterator end() const { return Dense.end(); }
diff --git a/contrib/llvm/include/llvm/ADT/Statistic.h b/contrib/llvm/include/llvm/ADT/Statistic.h
index 53fa2a5..d5ebba4 100644
--- a/contrib/llvm/include/llvm/ADT/Statistic.h
+++ b/contrib/llvm/include/llvm/ADT/Statistic.h
@@ -101,6 +101,16 @@ public:
return init();
}
+ void updateMax(unsigned V) {
+ unsigned PrevMax = Value.load(std::memory_order_relaxed);
+ // Keep trying to update max until we succeed or another thread produces
+ // a bigger max than us.
+ while (V > PrevMax && !Value.compare_exchange_weak(
+ PrevMax, V, std::memory_order_relaxed)) {
+ }
+ init();
+ }
+
#else // Statistics are disabled in release builds.
const Statistic &operator=(unsigned Val) {
@@ -131,6 +141,8 @@ public:
return *this;
}
+ void updateMax(unsigned V) {}
+
#endif // !defined(NDEBUG) || defined(LLVM_ENABLE_STATS)
protected:
diff --git a/contrib/llvm/include/llvm/ADT/StringExtras.h b/contrib/llvm/include/llvm/ADT/StringExtras.h
index 488748a..cc32bf4 100644
--- a/contrib/llvm/include/llvm/ADT/StringExtras.h
+++ b/contrib/llvm/include/llvm/ADT/StringExtras.h
@@ -1,4 +1,4 @@
-//===-- llvm/ADT/StringExtras.h - Useful string functions -------*- C++ -*-===//
+//===- llvm/ADT/StringExtras.h - Useful string functions --------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,13 +14,22 @@
#ifndef LLVM_ADT_STRINGEXTRAS_H
#define LLVM_ADT_STRINGEXTRAS_H
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/DataTypes.h"
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
+#include <cstdlib>
+#include <cstring>
#include <iterator>
+#include <string>
+#include <utility>
namespace llvm {
-class raw_ostream;
+
template<typename T> class SmallVectorImpl;
+class raw_ostream;
/// hexdigit - Return the hexadecimal character for the
/// given number \p X (which should be less than 16).
@@ -34,6 +43,11 @@ static inline StringRef toStringRef(bool B) {
return StringRef(B ? "true" : "false");
}
+/// Construct a string ref from an array ref of unsigned chars.
+static inline StringRef toStringRef(ArrayRef<uint8_t> Input) {
+ return StringRef(reinterpret_cast<const char *>(Input.begin()), Input.size());
+}
+
/// Interpret the given character \p C as a hexadecimal digit and return its
/// value.
///
@@ -62,7 +76,7 @@ static inline std::string utohexstr(uint64_t X, bool LowerCase = false) {
/// Convert buffer \p Input to its hexadecimal representation.
/// The returned string is double the size of \p Input.
-static inline std::string toHex(StringRef Input) {
+inline std::string toHex(StringRef Input) {
static const char *const LUT = "0123456789ABCDEF";
size_t Length = Input.size();
@@ -76,6 +90,73 @@ static inline std::string toHex(StringRef Input) {
return Output;
}
+inline std::string toHex(ArrayRef<uint8_t> Input) {
+ return toHex(toStringRef(Input));
+}
+
+static inline uint8_t hexFromNibbles(char MSB, char LSB) {
+ unsigned U1 = hexDigitValue(MSB);
+ unsigned U2 = hexDigitValue(LSB);
+ assert(U1 != -1U && U2 != -1U);
+
+ return static_cast<uint8_t>((U1 << 4) | U2);
+}
+
+/// Convert hexadecimal string \p Input to its binary representation.
+/// The return string is half the size of \p Input.
+static inline std::string fromHex(StringRef Input) {
+ if (Input.empty())
+ return std::string();
+
+ std::string Output;
+ Output.reserve((Input.size() + 1) / 2);
+ if (Input.size() % 2 == 1) {
+ Output.push_back(hexFromNibbles('0', Input.front()));
+ Input = Input.drop_front();
+ }
+
+ assert(Input.size() % 2 == 0);
+ while (!Input.empty()) {
+ uint8_t Hex = hexFromNibbles(Input[0], Input[1]);
+ Output.push_back(Hex);
+ Input = Input.drop_front(2);
+ }
+ return Output;
+}
+
+/// \brief Convert the string \p S to an integer of the specified type using
+/// the radix \p Base. If \p Base is 0, auto-detects the radix.
+/// Returns true if the number was successfully converted, false otherwise.
+template <typename N> bool to_integer(StringRef S, N &Num, unsigned Base = 0) {
+ return !S.getAsInteger(Base, Num);
+}
+
+namespace detail {
+template <typename N>
+inline bool to_float(const Twine &T, N &Num, N (*StrTo)(const char *, char **)) {
+ SmallString<32> Storage;
+ StringRef S = T.toNullTerminatedStringRef(Storage);
+ char *End;
+ N Temp = StrTo(S.data(), &End);
+ if (*End != '\0')
+ return false;
+ Num = Temp;
+ return true;
+}
+}
+
+inline bool to_float(const Twine &T, float &Num) {
+ return detail::to_float(T, Num, strtof);
+}
+
+inline bool to_float(const Twine &T, double &Num) {
+ return detail::to_float(T, Num, strtod);
+}
+
+inline bool to_float(const Twine &T, long double &Num) {
+ return detail::to_float(T, Num, strtold);
+}
+
static inline std::string utostr(uint64_t X, bool isNeg = false) {
char Buffer[21];
char *BufPtr = std::end(Buffer);
@@ -91,7 +172,6 @@ static inline std::string utostr(uint64_t X, bool isNeg = false) {
return std::string(BufPtr, std::end(Buffer));
}
-
static inline std::string itostr(int64_t X) {
if (X < 0)
return utostr(static_cast<uint64_t>(-X), true);
@@ -224,16 +304,24 @@ template <typename A1, typename... Args>
inline size_t join_items_size(const A1 &A, Args &&... Items) {
return join_one_item_size(A) + join_items_size(std::forward<Args>(Items)...);
}
-}
+
+} // end namespace detail
/// Joins the strings in the range [Begin, End), adding Separator between
/// the elements.
template <typename IteratorT>
inline std::string join(IteratorT Begin, IteratorT End, StringRef Separator) {
- typedef typename std::iterator_traits<IteratorT>::iterator_category tag;
+ using tag = typename std::iterator_traits<IteratorT>::iterator_category;
return detail::join_impl(Begin, End, Separator, tag());
}
+/// Joins the strings in the range [R.begin(), R.end()), adding Separator
+/// between the elements.
+template <typename Range>
+inline std::string join(Range &&R, StringRef Separator) {
+ return join(R.begin(), R.end(), Separator);
+}
+
/// Joins the strings in the parameter pack \p Items, adding \p Separator
/// between the elements. All arguments must be implicitly convertible to
/// std::string, or there should be an overload of std::string::operator+=()
@@ -251,6 +339,6 @@ inline std::string join_items(Sep Separator, Args &&... Items) {
return Result;
}
-} // End llvm namespace
+} // end namespace llvm
-#endif
+#endif // LLVM_ADT_STRINGEXTRAS_H
diff --git a/contrib/llvm/include/llvm/ADT/StringMap.h b/contrib/llvm/include/llvm/ADT/StringMap.h
index 24e3ecf..d573148 100644
--- a/contrib/llvm/include/llvm/ADT/StringMap.h
+++ b/contrib/llvm/include/llvm/ADT/StringMap.h
@@ -1,4 +1,4 @@
-//===--- StringMap.h - String Hash table map interface ----------*- C++ -*-===//
+//===- StringMap.h - String Hash table map interface ------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -15,25 +15,24 @@
#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/Support/PointerLikeTypeTraits.h"
+#include <algorithm>
#include <cassert>
#include <cstdint>
#include <cstdlib>
#include <cstring>
-#include <utility>
#include <initializer_list>
-#include <new>
+#include <iterator>
#include <utility>
namespace llvm {
- template<typename ValueT>
- class StringMapConstIterator;
- template<typename ValueT>
- class StringMapIterator;
- template<typename ValueTy>
- class StringMapEntry;
+template<typename ValueTy> class StringMapConstIterator;
+template<typename ValueTy> class StringMapIterator;
+template<typename ValueTy> class StringMapKeyIterator;
/// StringMapEntryBase - Shared base class of StringMapEntry instances.
class StringMapEntryBase {
@@ -52,17 +51,15 @@ protected:
// Array of NumBuckets pointers to entries, null pointers are holes.
// TheTable[NumBuckets] contains a sentinel value for easy iteration. Followed
// by an array of the actual hash values as unsigned integers.
- StringMapEntryBase **TheTable;
- unsigned NumBuckets;
- unsigned NumItems;
- unsigned NumTombstones;
+ StringMapEntryBase **TheTable = nullptr;
+ unsigned NumBuckets = 0;
+ unsigned NumItems = 0;
+ unsigned NumTombstones = 0;
unsigned ItemSize;
protected:
explicit StringMapImpl(unsigned itemSize)
- : TheTable(nullptr),
- // Initialize the map with zero buckets to allocation.
- NumBuckets(0), NumItems(0), NumTombstones(0), ItemSize(itemSize) {}
+ : ItemSize(itemSize) {}
StringMapImpl(StringMapImpl &&RHS)
: TheTable(RHS.TheTable), NumBuckets(RHS.NumBuckets),
NumItems(RHS.NumItems), NumTombstones(RHS.NumTombstones),
@@ -224,9 +221,10 @@ class StringMap : public StringMapImpl {
AllocatorTy Allocator;
public:
- typedef StringMapEntry<ValueTy> MapEntryTy;
+ using MapEntryTy = StringMapEntry<ValueTy>;
StringMap() : StringMapImpl(static_cast<unsigned>(sizeof(MapEntryTy))) {}
+
explicit StringMap(unsigned InitialSize)
: StringMapImpl(InitialSize, static_cast<unsigned>(sizeof(MapEntryTy))) {}
@@ -247,12 +245,6 @@ public:
StringMap(StringMap &&RHS)
: StringMapImpl(std::move(RHS)), Allocator(std::move(RHS.Allocator)) {}
- StringMap &operator=(StringMap RHS) {
- StringMapImpl::swap(RHS);
- std::swap(Allocator, RHS.Allocator);
- return *this;
- }
-
StringMap(const StringMap &RHS) :
StringMapImpl(static_cast<unsigned>(sizeof(MapEntryTy))),
Allocator(RHS.Allocator) {
@@ -288,16 +280,37 @@ public:
// not worthwhile.
}
+ StringMap &operator=(StringMap RHS) {
+ StringMapImpl::swap(RHS);
+ std::swap(Allocator, RHS.Allocator);
+ return *this;
+ }
+
+ ~StringMap() {
+ // Delete all the elements in the map, but don't reset the elements
+ // to default values. This is a copy of clear(), but avoids unnecessary
+ // work not required in the destructor.
+ if (!empty()) {
+ for (unsigned I = 0, E = NumBuckets; I != E; ++I) {
+ StringMapEntryBase *Bucket = TheTable[I];
+ if (Bucket && Bucket != getTombstoneVal()) {
+ static_cast<MapEntryTy*>(Bucket)->Destroy(Allocator);
+ }
+ }
+ }
+ free(TheTable);
+ }
+
AllocatorTy &getAllocator() { return Allocator; }
const AllocatorTy &getAllocator() const { return Allocator; }
- typedef const char* key_type;
- typedef ValueTy mapped_type;
- typedef StringMapEntry<ValueTy> value_type;
- typedef size_t size_type;
+ using key_type = const char*;
+ using mapped_type = ValueTy;
+ using value_type = StringMapEntry<ValueTy>;
+ using size_type = size_t;
- typedef StringMapConstIterator<ValueTy> const_iterator;
- typedef StringMapIterator<ValueTy> iterator;
+ using const_iterator = StringMapConstIterator<ValueTy>;
+ using iterator = StringMapIterator<ValueTy>;
iterator begin() {
return iterator(TheTable, NumBuckets == 0);
@@ -312,6 +325,11 @@ public:
return const_iterator(TheTable+NumBuckets, true);
}
+ iterator_range<StringMapKeyIterator<ValueTy>> keys() const {
+ return make_range(StringMapKeyIterator<ValueTy>(begin()),
+ StringMapKeyIterator<ValueTy>(end()));
+ }
+
iterator find(StringRef Key) {
int Bucket = FindKey(Key);
if (Bucket == -1) return end();
@@ -427,59 +445,41 @@ public:
erase(I);
return true;
}
-
- ~StringMap() {
- // Delete all the elements in the map, but don't reset the elements
- // to default values. This is a copy of clear(), but avoids unnecessary
- // work not required in the destructor.
- if (!empty()) {
- for (unsigned I = 0, E = NumBuckets; I != E; ++I) {
- StringMapEntryBase *Bucket = TheTable[I];
- if (Bucket && Bucket != getTombstoneVal()) {
- static_cast<MapEntryTy*>(Bucket)->Destroy(Allocator);
- }
- }
- }
- free(TheTable);
- }
};
-template <typename ValueTy> class StringMapConstIterator {
+template <typename DerivedTy, typename ValueTy>
+class StringMapIterBase
+ : public iterator_facade_base<DerivedTy, std::forward_iterator_tag,
+ ValueTy> {
protected:
StringMapEntryBase **Ptr = nullptr;
public:
- typedef StringMapEntry<ValueTy> value_type;
+ StringMapIterBase() = default;
- StringMapConstIterator() = default;
-
- explicit StringMapConstIterator(StringMapEntryBase **Bucket,
- bool NoAdvance = false)
- : Ptr(Bucket) {
+ explicit StringMapIterBase(StringMapEntryBase **Bucket,
+ bool NoAdvance = false)
+ : Ptr(Bucket) {
if (!NoAdvance) AdvancePastEmptyBuckets();
}
- const value_type &operator*() const {
- return *static_cast<StringMapEntry<ValueTy>*>(*Ptr);
- }
- const value_type *operator->() const {
- return static_cast<StringMapEntry<ValueTy>*>(*Ptr);
+ DerivedTy &operator=(const DerivedTy &Other) {
+ Ptr = Other.Ptr;
+ return static_cast<DerivedTy &>(*this);
}
- bool operator==(const StringMapConstIterator &RHS) const {
- return Ptr == RHS.Ptr;
- }
- bool operator!=(const StringMapConstIterator &RHS) const {
- return Ptr != RHS.Ptr;
- }
+ bool operator==(const DerivedTy &RHS) const { return Ptr == RHS.Ptr; }
- inline StringMapConstIterator& operator++() { // Preincrement
+ DerivedTy &operator++() { // Preincrement
++Ptr;
AdvancePastEmptyBuckets();
- return *this;
+ return static_cast<DerivedTy &>(*this);
}
- StringMapConstIterator operator++(int) { // Postincrement
- StringMapConstIterator tmp = *this; ++*this; return tmp;
+
+ DerivedTy operator++(int) { // Post-increment
+ DerivedTy Tmp(Ptr);
+ ++*this;
+ return Tmp;
}
private:
@@ -489,24 +489,68 @@ private:
}
};
-template<typename ValueTy>
-class StringMapIterator : public StringMapConstIterator<ValueTy> {
+template <typename ValueTy>
+class StringMapConstIterator
+ : public StringMapIterBase<StringMapConstIterator<ValueTy>,
+ const StringMapEntry<ValueTy>> {
+ using base = StringMapIterBase<StringMapConstIterator<ValueTy>,
+ const StringMapEntry<ValueTy>>;
+
public:
- StringMapIterator() = default;
+ StringMapConstIterator() = default;
+ explicit StringMapConstIterator(StringMapEntryBase **Bucket,
+ bool NoAdvance = false)
+ : base(Bucket, NoAdvance) {}
+
+ const StringMapEntry<ValueTy> &operator*() const {
+ return *static_cast<const StringMapEntry<ValueTy> *>(*this->Ptr);
+ }
+};
+
+template <typename ValueTy>
+class StringMapIterator : public StringMapIterBase<StringMapIterator<ValueTy>,
+ StringMapEntry<ValueTy>> {
+ using base =
+ StringMapIterBase<StringMapIterator<ValueTy>, StringMapEntry<ValueTy>>;
+public:
+ StringMapIterator() = default;
explicit StringMapIterator(StringMapEntryBase **Bucket,
bool NoAdvance = false)
- : StringMapConstIterator<ValueTy>(Bucket, NoAdvance) {
- }
+ : base(Bucket, NoAdvance) {}
StringMapEntry<ValueTy> &operator*() const {
- return *static_cast<StringMapEntry<ValueTy>*>(*this->Ptr);
+ return *static_cast<StringMapEntry<ValueTy> *>(*this->Ptr);
}
- StringMapEntry<ValueTy> *operator->() const {
- return static_cast<StringMapEntry<ValueTy>*>(*this->Ptr);
+
+ operator StringMapConstIterator<ValueTy>() const {
+ return StringMapConstIterator<ValueTy>(this->Ptr, true);
}
};
+template <typename ValueTy>
+class StringMapKeyIterator
+ : public iterator_adaptor_base<StringMapKeyIterator<ValueTy>,
+ StringMapConstIterator<ValueTy>,
+ std::forward_iterator_tag, StringRef> {
+ using base = iterator_adaptor_base<StringMapKeyIterator<ValueTy>,
+ StringMapConstIterator<ValueTy>,
+ std::forward_iterator_tag, StringRef>;
+
+public:
+ StringMapKeyIterator() = default;
+ explicit StringMapKeyIterator(StringMapConstIterator<ValueTy> Iter)
+ : base(std::move(Iter)) {}
+
+ StringRef &operator*() {
+ Key = this->wrapped()->getKey();
+ return Key;
+ }
+
+private:
+ StringRef Key;
+};
+
} // end namespace llvm
#endif // LLVM_ADT_STRINGMAP_H
diff --git a/contrib/llvm/include/llvm/ADT/StringRef.h b/contrib/llvm/include/llvm/ADT/StringRef.h
index d80a848..f6c93a8 100644
--- a/contrib/llvm/include/llvm/ADT/StringRef.h
+++ b/contrib/llvm/include/llvm/ADT/StringRef.h
@@ -1,4 +1,4 @@
-//===--- StringRef.h - Constant String Reference Wrapper --------*- C++ -*-===//
+//===- StringRef.h - Constant String Reference Wrapper ----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -15,16 +15,18 @@
#include "llvm/Support/Compiler.h"
#include <algorithm>
#include <cassert>
+#include <cstddef>
#include <cstring>
#include <limits>
#include <string>
+#include <type_traits>
#include <utility>
namespace llvm {
- template <typename T>
- class SmallVectorImpl;
+
class APInt;
class hash_code;
+ template <typename T> class SmallVectorImpl;
class StringRef;
/// Helper functions for StringRef::getAsInteger.
@@ -46,10 +48,11 @@ namespace llvm {
/// general safe to store a StringRef.
class StringRef {
public:
- typedef const char *iterator;
- typedef const char *const_iterator;
static const size_t npos = ~size_t(0);
- typedef size_t size_type;
+
+ using iterator = const char *;
+ using const_iterator = const char *;
+ using size_type = size_t;
private:
/// The start of the string, in an external buffer.
@@ -557,6 +560,14 @@ namespace llvm {
/// string is well-formed in the given radix.
bool getAsInteger(unsigned Radix, APInt &Result) const;
+ /// Parse the current string as an IEEE double-precision floating
+ /// point value. The string must be a well-formed double.
+ ///
+ /// If \p AllowInexact is false, the function will fail if the string
+ /// cannot be represented exactly. Otherwise, the function only fails
+ /// in case of an overflow or underflow.
+ bool getAsDouble(double &Result, bool AllowInexact = true) const;
+
/// @}
/// @name String Operations
/// @{
@@ -600,7 +611,7 @@ namespace llvm {
return drop_back(size() - N);
}
- /// Return a StringRef equal to 'this' but with only the first \p N
+ /// Return a StringRef equal to 'this' but with only the last \p N
/// elements remaining. If \p N is greater than the length of the
/// string, the entire string is returned.
LLVM_NODISCARD
@@ -898,6 +909,7 @@ namespace llvm {
// StringRefs can be treated like a POD type.
template <typename T> struct isPodLike;
template <> struct isPodLike<StringRef> { static const bool value = true; };
-}
-#endif
+} // end namespace llvm
+
+#endif // LLVM_ADT_STRINGREF_H
diff --git a/contrib/llvm/include/llvm/ADT/StringSet.h b/contrib/llvm/include/llvm/ADT/StringSet.h
index c32c2a4..9af44c0 100644
--- a/contrib/llvm/include/llvm/ADT/StringSet.h
+++ b/contrib/llvm/include/llvm/ADT/StringSet.h
@@ -1,4 +1,4 @@
-//===--- StringSet.h - The LLVM Compiler Driver -----------------*- C++ -*-===//
+//===- StringSet.h - The LLVM Compiler Driver -------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -15,13 +15,19 @@
#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 = llvm::MallocAllocator>
- class StringSet : public llvm::StringMap<char, AllocatorTy> {
- typedef llvm::StringMap<char, AllocatorTy> base;
+ template <class AllocatorTy = MallocAllocator>
+ class StringSet : public StringMap<char, AllocatorTy> {
+ using base = StringMap<char, AllocatorTy>;
+
public:
StringSet() = default;
StringSet(std::initializer_list<StringRef> S) {
@@ -40,6 +46,7 @@ namespace llvm {
base::insert(std::make_pair(*It, '\0'));
}
};
-}
+
+} // end namespace llvm
#endif // LLVM_ADT_STRINGSET_H
diff --git a/contrib/llvm/include/llvm/ADT/TinyPtrVector.h b/contrib/llvm/include/llvm/ADT/TinyPtrVector.h
index ca43b60..7974071 100644
--- a/contrib/llvm/include/llvm/ADT/TinyPtrVector.h
+++ b/contrib/llvm/include/llvm/ADT/TinyPtrVector.h
@@ -30,9 +30,9 @@ namespace llvm {
template <typename EltTy>
class TinyPtrVector {
public:
- typedef SmallVector<EltTy, 4> VecTy;
- typedef typename VecTy::value_type value_type;
- typedef PointerUnion<EltTy, VecTy *> PtrUnion;
+ using VecTy = SmallVector<EltTy, 4>;
+ using value_type = typename VecTy::value_type;
+ using PtrUnion = PointerUnion<EltTy, VecTy *>;
private:
PtrUnion Val;
@@ -167,10 +167,10 @@ public:
return Val.template get<VecTy*>()->size();
}
- typedef EltTy *iterator;
- typedef const EltTy *const_iterator;
- typedef std::reverse_iterator<iterator> reverse_iterator;
- typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+ using iterator = EltTy *;
+ using const_iterator = const EltTy *;
+ using reverse_iterator = std::reverse_iterator<iterator>;
+ using const_reverse_iterator = std::reverse_iterator<const_iterator>;
iterator begin() {
if (Val.template is<EltTy>())
diff --git a/contrib/llvm/include/llvm/ADT/Triple.h b/contrib/llvm/include/llvm/ADT/Triple.h
index d4130e1..cd56065 100644
--- a/contrib/llvm/include/llvm/ADT/Triple.h
+++ b/contrib/llvm/include/llvm/ADT/Triple.h
@@ -59,6 +59,7 @@ public:
mips64, // MIPS64: mips64
mips64el, // MIPS64EL: mips64el
msp430, // MSP430: msp430
+ nios2, // NIOSII: nios2
ppc, // PPC: powerpc
ppc64, // PPC64: powerpc64, ppu
ppc64le, // PPC64LE: powerpc64le
@@ -110,6 +111,7 @@ public:
ARMSubArch_v7m,
ARMSubArch_v7s,
ARMSubArch_v7k,
+ ARMSubArch_v7ve,
ARMSubArch_v6,
ARMSubArch_v6m,
ARMSubArch_v6k,
@@ -139,11 +141,13 @@ public:
Myriad,
AMD,
Mesa,
- LastVendorType = Mesa
+ SUSE,
+ LastVendorType = SUSE
};
enum OSType {
UnknownOS,
+ Ananas,
CloudABI,
Darwin,
DragonFly,
@@ -206,6 +210,7 @@ public:
COFF,
ELF,
MachO,
+ Wasm,
};
private:
@@ -235,7 +240,9 @@ public:
/// Default constructor is the same as an empty string and leaves all
/// triple fields unknown.
- Triple() : Data(), Arch(), Vendor(), OS(), Environment(), ObjectFormat() {}
+ Triple()
+ : Data(), Arch(), SubArch(), Vendor(), OS(), Environment(),
+ ObjectFormat() {}
explicit Triple(const Twine &Str);
Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr);
@@ -249,6 +256,10 @@ public:
ObjectFormat == Other.ObjectFormat;
}
+ bool operator!=(const Triple &Other) const {
+ return !(*this == Other);
+ }
+
/// @}
/// @name Normalization
/// @{
@@ -558,7 +569,8 @@ public:
/// Tests whether the OS uses glibc.
bool isOSGlibc() const {
- return getOS() == Triple::Linux || getOS() == Triple::KFreeBSD;
+ return (getOS() == Triple::Linux || getOS() == Triple::KFreeBSD) &&
+ !isAndroid();
}
/// Tests whether the OS uses the ELF binary format.
@@ -576,6 +588,11 @@ public:
return getObjectFormat() == Triple::MachO;
}
+ /// Tests whether the OS uses the Wasm binary format.
+ bool isOSBinFormatWasm() const {
+ return getObjectFormat() == Triple::Wasm;
+ }
+
/// Tests whether the target is the PS4 CPU
bool isPS4CPU() const {
return getArch() == Triple::x86_64 &&
@@ -592,6 +609,19 @@ public:
/// Tests whether the target is Android
bool isAndroid() const { return getEnvironment() == Triple::Android; }
+ bool isAndroidVersionLT(unsigned Major) const {
+ assert(isAndroid() && "Not an Android triple!");
+
+ unsigned Env[3];
+ getEnvironmentVersion(Env[0], Env[1], Env[2]);
+
+ // 64-bit targets did not exist before API level 21 (Lollipop).
+ if (isArch64Bit() && Env[0] < 21)
+ Env[0] = 21;
+
+ return Env[0] < Major;
+ }
+
/// Tests whether the environment is musl-libc
bool isMusl() const {
return getEnvironment() == Triple::Musl ||
@@ -700,6 +730,12 @@ public:
/// \returns true if the triple is little endian, false otherwise.
bool isLittleEndian() const;
+ /// Test whether target triples are compatible.
+ bool isCompatibleWith(const Triple &Other) const;
+
+ /// Merge target triples.
+ std::string merge(const Triple &Other) const;
+
/// @}
/// @name Static helpers for IDs.
/// @{
diff --git a/contrib/llvm/include/llvm/ADT/UniqueVector.h b/contrib/llvm/include/llvm/ADT/UniqueVector.h
index e1ab4b5..b17fb23 100644
--- a/contrib/llvm/include/llvm/ADT/UniqueVector.h
+++ b/contrib/llvm/include/llvm/ADT/UniqueVector.h
@@ -1,4 +1,4 @@
-//===-- llvm/ADT/UniqueVector.h ---------------------------------*- C++ -*-===//
+//===- llvm/ADT/UniqueVector.h ----------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -24,16 +24,15 @@ namespace llvm {
/// Entries can be fetched using operator[] with the entry ID.
template<class T> class UniqueVector {
public:
- typedef typename std::vector<T> VectorType;
- typedef typename VectorType::iterator iterator;
- typedef typename VectorType::const_iterator const_iterator;
+ using VectorType = typename std::vector<T>;
+ using iterator = typename VectorType::iterator;
+ using const_iterator = typename VectorType::const_iterator;
private:
// Map - Used to handle the correspondence of entry to ID.
std::map<T, unsigned> Map;
// Vector - ID ordered vector of entries. Entries can be indexed by ID - 1.
- //
VectorType Vector;
public:
@@ -68,7 +67,6 @@ public:
}
/// operator[] - Returns a reference to the entry with the specified ID.
- ///
const T &operator[](unsigned ID) const {
assert(ID-1 < size() && "ID is 0 or out of range!");
return Vector[ID - 1];
@@ -87,21 +85,18 @@ public:
const_iterator end() const { return Vector.end(); }
/// size - Returns the number of entries in the vector.
- ///
size_t size() const { return Vector.size(); }
/// empty - Returns true if the vector is empty.
- ///
bool empty() const { return Vector.empty(); }
/// reset - Clears all the entries.
- ///
void reset() {
Map.clear();
Vector.resize(0, 0);
}
};
-} // End of namespace llvm
+} // end namespace llvm
#endif // LLVM_ADT_UNIQUEVECTOR_H
diff --git a/contrib/llvm/include/llvm/ADT/ilist_base.h b/contrib/llvm/include/llvm/ADT/ilist_base.h
index 1ffc864..3d818a4 100644
--- a/contrib/llvm/include/llvm/ADT/ilist_base.h
+++ b/contrib/llvm/include/llvm/ADT/ilist_base.h
@@ -1,4 +1,4 @@
-//===- llvm/ADT/ilist_base.h - Intrusive List Base ---------------*- C++ -*-==//
+//===- llvm/ADT/ilist_base.h - Intrusive List Base --------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -12,15 +12,13 @@
#include "llvm/ADT/ilist_node_base.h"
#include <cassert>
-#include <cstddef>
-#include <type_traits>
namespace llvm {
/// Implementations of list algorithms using ilist_node_base.
template <bool EnableSentinelTracking> class ilist_base {
public:
- typedef ilist_node_base<EnableSentinelTracking> node_base_type;
+ using node_base_type = ilist_node_base<EnableSentinelTracking>;
static void insertBeforeImpl(node_base_type &Next, node_base_type &N) {
node_base_type &Prev = *Next.getPrev();
diff --git a/contrib/llvm/include/llvm/ADT/ilist_iterator.h b/contrib/llvm/include/llvm/ADT/ilist_iterator.h
index c848d1a..671e644 100644
--- a/contrib/llvm/include/llvm/ADT/ilist_iterator.h
+++ b/contrib/llvm/include/llvm/ADT/ilist_iterator.h
@@ -1,4 +1,4 @@
-//===- llvm/ADT/ilist_iterator.h - Intrusive List Iterator -------*- C++ -*-==//
+//===- llvm/ADT/ilist_iterator.h - Intrusive List Iterator ------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -23,28 +23,30 @@ namespace ilist_detail {
/// Find const-correct node types.
template <class OptionsT, bool IsConst> struct IteratorTraits;
template <class OptionsT> struct IteratorTraits<OptionsT, false> {
- typedef typename OptionsT::value_type value_type;
- typedef typename OptionsT::pointer pointer;
- typedef typename OptionsT::reference reference;
- typedef ilist_node_impl<OptionsT> *node_pointer;
- typedef ilist_node_impl<OptionsT> &node_reference;
+ using value_type = typename OptionsT::value_type;
+ using pointer = typename OptionsT::pointer;
+ using reference = typename OptionsT::reference;
+ using node_pointer = ilist_node_impl<OptionsT> *;
+ using node_reference = ilist_node_impl<OptionsT> &;
};
template <class OptionsT> struct IteratorTraits<OptionsT, true> {
- typedef const typename OptionsT::value_type value_type;
- typedef typename OptionsT::const_pointer pointer;
- typedef typename OptionsT::const_reference reference;
- typedef const ilist_node_impl<OptionsT> *node_pointer;
- typedef const ilist_node_impl<OptionsT> &node_reference;
+ using value_type = const typename OptionsT::value_type;
+ using pointer = typename OptionsT::const_pointer;
+ using reference = typename OptionsT::const_reference;
+ using node_pointer = const ilist_node_impl<OptionsT> *;
+ using node_reference = const ilist_node_impl<OptionsT> &;
};
template <bool IsReverse> struct IteratorHelper;
template <> struct IteratorHelper<false> : ilist_detail::NodeAccess {
- typedef ilist_detail::NodeAccess Access;
+ using Access = ilist_detail::NodeAccess;
+
template <class T> static void increment(T *&I) { I = Access::getNext(*I); }
template <class T> static void decrement(T *&I) { I = Access::getPrev(*I); }
};
template <> struct IteratorHelper<true> : ilist_detail::NodeAccess {
- typedef ilist_detail::NodeAccess Access;
+ using Access = ilist_detail::NodeAccess;
+
template <class T> static void increment(T *&I) { I = Access::getPrev(*I); }
template <class T> static void decrement(T *&I) { I = Access::getNext(*I); }
};
@@ -58,24 +60,23 @@ class ilist_iterator : ilist_detail::SpecificNodeAccess<OptionsT> {
friend ilist_iterator<OptionsT, !IsReverse, IsConst>;
friend ilist_iterator<OptionsT, !IsReverse, !IsConst>;
- typedef ilist_detail::IteratorTraits<OptionsT, IsConst> Traits;
- typedef ilist_detail::SpecificNodeAccess<OptionsT> Access;
+ using Traits = ilist_detail::IteratorTraits<OptionsT, IsConst>;
+ using Access = ilist_detail::SpecificNodeAccess<OptionsT>;
public:
- typedef typename Traits::value_type value_type;
- typedef typename Traits::pointer pointer;
- typedef typename Traits::reference reference;
- typedef ptrdiff_t difference_type;
- typedef std::bidirectional_iterator_tag iterator_category;
-
- typedef typename OptionsT::const_pointer const_pointer;
- typedef typename OptionsT::const_reference const_reference;
+ using value_type = typename Traits::value_type;
+ using pointer = typename Traits::pointer;
+ using reference = typename Traits::reference;
+ using difference_type = ptrdiff_t;
+ using iterator_category = std::bidirectional_iterator_tag;
+ using const_pointer = typename OptionsT::const_pointer;
+ using const_reference = typename OptionsT::const_reference;
private:
- typedef typename Traits::node_pointer node_pointer;
- typedef typename Traits::node_reference node_reference;
+ using node_pointer = typename Traits::node_pointer;
+ using node_reference = typename Traits::node_reference;
- node_pointer NodePtr;
+ node_pointer NodePtr = nullptr;
public:
/// Create from an ilist_node.
@@ -83,7 +84,7 @@ public:
explicit ilist_iterator(pointer NP) : NodePtr(Access::getNodePtr(NP)) {}
explicit ilist_iterator(reference NR) : NodePtr(Access::getNodePtr(&NR)) {}
- ilist_iterator() : NodePtr(nullptr) {}
+ ilist_iterator() = default;
// This is templated so that we can allow constructing a const iterator from
// a nonconst iterator...
@@ -184,8 +185,8 @@ template <typename From> struct simplify_type;
/// FIXME: remove this, since there is no implicit conversion to NodeTy.
template <class OptionsT, bool IsConst>
struct simplify_type<ilist_iterator<OptionsT, false, IsConst>> {
- typedef ilist_iterator<OptionsT, false, IsConst> iterator;
- typedef typename iterator::pointer SimpleType;
+ using iterator = ilist_iterator<OptionsT, false, IsConst>;
+ using SimpleType = typename iterator::pointer;
static SimpleType getSimplifiedValue(const iterator &Node) { return &*Node; }
};
diff --git a/contrib/llvm/include/llvm/ADT/ilist_node.h b/contrib/llvm/include/llvm/ADT/ilist_node.h
index 7244d0f..3362611 100644
--- a/contrib/llvm/include/llvm/ADT/ilist_node.h
+++ b/contrib/llvm/include/llvm/ADT/ilist_node.h
@@ -1,4 +1,4 @@
-//==-- llvm/ADT/ilist_node.h - Intrusive Linked List Helper ------*- C++ -*-==//
+//===- llvm/ADT/ilist_node.h - Intrusive Linked List Helper -----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -21,11 +21,10 @@
namespace llvm {
namespace ilist_detail {
+
struct NodeAccess;
-} // end namespace ilist_detail
-template<typename NodeTy>
-struct ilist_traits;
+} // end namespace ilist_detail
template <class OptionsT, bool IsReverse, bool IsConst> class ilist_iterator;
template <class OptionsT> class ilist_sentinel;
@@ -39,9 +38,9 @@ template <class OptionsT> class ilist_sentinel;
/// provide type safety: you can't insert nodes of \a ilist_node_impl into the
/// wrong \a simple_ilist or \a iplist.
template <class OptionsT> class ilist_node_impl : OptionsT::node_base_type {
- typedef typename OptionsT::value_type value_type;
- typedef typename OptionsT::node_base_type node_base_type;
- typedef typename OptionsT::list_base_type list_base_type;
+ using value_type = typename OptionsT::value_type;
+ using node_base_type = typename OptionsT::node_base_type;
+ using list_base_type = typename OptionsT::list_base_type;
friend typename OptionsT::list_base_type;
friend struct ilist_detail::NodeAccess;
@@ -52,17 +51,18 @@ template <class OptionsT> class ilist_node_impl : OptionsT::node_base_type {
friend class ilist_iterator<OptionsT, true, true>;
protected:
- ilist_node_impl() = default;
+ using self_iterator = ilist_iterator<OptionsT, false, false>;
+ using const_self_iterator = ilist_iterator<OptionsT, false, true>;
+ using reverse_self_iterator = ilist_iterator<OptionsT, true, false>;
+ using const_reverse_self_iterator = ilist_iterator<OptionsT, true, true>;
- typedef ilist_iterator<OptionsT, false, false> self_iterator;
- typedef ilist_iterator<OptionsT, false, true> const_self_iterator;
- typedef ilist_iterator<OptionsT, true, false> reverse_self_iterator;
- typedef ilist_iterator<OptionsT, true, true> const_reverse_self_iterator;
+ ilist_node_impl() = default;
private:
ilist_node_impl *getPrev() {
return static_cast<ilist_node_impl *>(node_base_type::getPrev());
}
+
ilist_node_impl *getNext() {
return static_cast<ilist_node_impl *>(node_base_type::getNext());
}
@@ -70,6 +70,7 @@ private:
const ilist_node_impl *getPrev() const {
return static_cast<ilist_node_impl *>(node_base_type::getPrev());
}
+
const ilist_node_impl *getNext() const {
return static_cast<ilist_node_impl *>(node_base_type::getNext());
}
@@ -80,9 +81,11 @@ private:
public:
self_iterator getIterator() { return self_iterator(*this); }
const_self_iterator getIterator() const { return const_self_iterator(*this); }
+
reverse_self_iterator getReverseIterator() {
return reverse_self_iterator(*this);
}
+
const_reverse_self_iterator getReverseIterator() const {
return const_reverse_self_iterator(*this);
}
@@ -151,6 +154,7 @@ class ilist_node
};
namespace ilist_detail {
+
/// An access class for ilist_node private API.
///
/// This gives access to the private parts of ilist nodes. Nodes for an ilist
@@ -163,15 +167,18 @@ protected:
static ilist_node_impl<OptionsT> *getNodePtr(typename OptionsT::pointer N) {
return N;
}
+
template <class OptionsT>
static const ilist_node_impl<OptionsT> *
getNodePtr(typename OptionsT::const_pointer N) {
return N;
}
+
template <class OptionsT>
static typename OptionsT::pointer getValuePtr(ilist_node_impl<OptionsT> *N) {
return static_cast<typename OptionsT::pointer>(N);
}
+
template <class OptionsT>
static typename OptionsT::const_pointer
getValuePtr(const ilist_node_impl<OptionsT> *N) {
@@ -182,15 +189,18 @@ protected:
static ilist_node_impl<OptionsT> *getPrev(ilist_node_impl<OptionsT> &N) {
return N.getPrev();
}
+
template <class OptionsT>
static ilist_node_impl<OptionsT> *getNext(ilist_node_impl<OptionsT> &N) {
return N.getNext();
}
+
template <class OptionsT>
static const ilist_node_impl<OptionsT> *
getPrev(const ilist_node_impl<OptionsT> &N) {
return N.getPrev();
}
+
template <class OptionsT>
static const ilist_node_impl<OptionsT> *
getNext(const ilist_node_impl<OptionsT> &N) {
@@ -200,23 +210,27 @@ protected:
template <class OptionsT> struct SpecificNodeAccess : NodeAccess {
protected:
- typedef typename OptionsT::pointer pointer;
- typedef typename OptionsT::const_pointer const_pointer;
- typedef ilist_node_impl<OptionsT> node_type;
+ using pointer = typename OptionsT::pointer;
+ using const_pointer = typename OptionsT::const_pointer;
+ using node_type = ilist_node_impl<OptionsT>;
static node_type *getNodePtr(pointer N) {
return NodeAccess::getNodePtr<OptionsT>(N);
}
+
static const node_type *getNodePtr(const_pointer N) {
return NodeAccess::getNodePtr<OptionsT>(N);
}
+
static pointer getValuePtr(node_type *N) {
return NodeAccess::getValuePtr<OptionsT>(N);
}
+
static const_pointer getValuePtr(const node_type *N) {
return NodeAccess::getValuePtr<OptionsT>(N);
}
};
+
} // end namespace ilist_detail
template <class OptionsT>
@@ -265,6 +279,7 @@ public:
getNodeParent()->*(ParentTy::getSublistAccess((NodeTy *)nullptr));
return List.getPrevNode(*static_cast<NodeTy *>(this));
}
+
/// \brief Get the previous node, or \c nullptr for the list head.
const NodeTy *getPrevNode() const {
return const_cast<ilist_node_with_parent *>(this)->getPrevNode();
@@ -278,6 +293,7 @@ public:
getNodeParent()->*(ParentTy::getSublistAccess((NodeTy *)nullptr));
return List.getNextNode(*static_cast<NodeTy *>(this));
}
+
/// \brief Get the next node, or \c nullptr for the list tail.
const NodeTy *getNextNode() const {
return const_cast<ilist_node_with_parent *>(this)->getNextNode();
@@ -285,6 +301,6 @@ public:
/// @}
};
-} // End llvm namespace
+} // end namespace llvm
-#endif
+#endif // LLVM_ADT_ILIST_NODE_H
diff --git a/contrib/llvm/include/llvm/ADT/iterator.h b/contrib/llvm/include/llvm/ADT/iterator.h
index 6470e09..15720a6 100644
--- a/contrib/llvm/include/llvm/ADT/iterator.h
+++ b/contrib/llvm/include/llvm/ADT/iterator.h
@@ -10,9 +10,12 @@
#ifndef LLVM_ADT_ITERATOR_H
#define LLVM_ADT_ITERATOR_H
+#include "llvm/ADT/iterator_range.h"
+#include <algorithm>
#include <cstddef>
#include <iterator>
#include <type_traits>
+#include <utility>
namespace llvm {
@@ -91,6 +94,8 @@ protected:
public:
DerivedT operator+(DifferenceTypeT n) const {
+ static_assert(std::is_base_of<iterator_facade_base, DerivedT>::value,
+ "Must pass the derived type to this template!");
static_assert(
IsRandomAccess,
"The '+' operator is only defined for random access iterators.");
@@ -114,6 +119,8 @@ public:
}
DerivedT &operator++() {
+ static_assert(std::is_base_of<iterator_facade_base, DerivedT>::value,
+ "Must pass the derived type to this template!");
return static_cast<DerivedT *>(this)->operator+=(1);
}
DerivedT operator++(int) {
@@ -160,9 +167,15 @@ public:
return !static_cast<const DerivedT *>(this)->operator<(RHS);
}
+ PointerT operator->() { return &static_cast<DerivedT *>(this)->operator*(); }
PointerT operator->() const {
return &static_cast<const DerivedT *>(this)->operator*();
}
+ ReferenceProxy operator[](DifferenceTypeT n) {
+ static_assert(IsRandomAccess,
+ "Subscripting is only defined for random access iterators.");
+ return ReferenceProxy(static_cast<DerivedT *>(this)->operator+(n));
+ }
ReferenceProxy operator[](DifferenceTypeT n) const {
static_assert(IsRandomAccess,
"Subscripting is only defined for random access iterators.");
@@ -195,19 +208,22 @@ template <
class iterator_adaptor_base
: public iterator_facade_base<DerivedT, IteratorCategoryT, T,
DifferenceTypeT, PointerT, ReferenceT> {
- typedef typename iterator_adaptor_base::iterator_facade_base BaseT;
+ using BaseT = typename iterator_adaptor_base::iterator_facade_base;
protected:
WrappedIteratorT I;
iterator_adaptor_base() = default;
- explicit iterator_adaptor_base(WrappedIteratorT u) : I(std::move(u)) {}
+ explicit iterator_adaptor_base(WrappedIteratorT u) : I(std::move(u)) {
+ static_assert(std::is_base_of<iterator_adaptor_base, DerivedT>::value,
+ "Must pass the derived type to this template!");
+ }
const WrappedIteratorT &wrapped() const { return I; }
public:
- typedef DifferenceTypeT difference_type;
+ using difference_type = DifferenceTypeT;
DerivedT &operator+=(difference_type n) {
static_assert(
@@ -265,7 +281,7 @@ public:
/// which is implemented with some iterator over T*s:
///
/// \code
-/// typedef pointee_iterator<SmallVectorImpl<T *>::iterator> iterator;
+/// using iterator = pointee_iterator<SmallVectorImpl<T *>::iterator>;
/// \endcode
template <typename WrappedIteratorT,
typename T = typename std::remove_reference<
@@ -283,6 +299,15 @@ struct pointee_iterator
T &operator*() const { return **this->I; }
};
+template <typename RangeT, typename WrappedIteratorT =
+ decltype(std::begin(std::declval<RangeT>()))>
+iterator_range<pointee_iterator<WrappedIteratorT>>
+make_pointee_range(RangeT &&Range) {
+ using PointeeIteratorT = pointee_iterator<WrappedIteratorT>;
+ return make_range(PointeeIteratorT(std::begin(std::forward<RangeT>(Range))),
+ PointeeIteratorT(std::end(std::forward<RangeT>(Range))));
+}
+
template <typename WrappedIteratorT,
typename T = decltype(&*std::declval<WrappedIteratorT>())>
class pointer_iterator
@@ -300,6 +325,15 @@ public:
const T &operator*() const { return Ptr = &*this->I; }
};
+template <typename RangeT, typename WrappedIteratorT =
+ decltype(std::begin(std::declval<RangeT>()))>
+iterator_range<pointer_iterator<WrappedIteratorT>>
+make_pointer_range(RangeT &&Range) {
+ using PointerIteratorT = pointer_iterator<WrappedIteratorT>;
+ return make_range(PointerIteratorT(std::begin(std::forward<RangeT>(Range))),
+ PointerIteratorT(std::end(std::forward<RangeT>(Range))));
+}
+
} // end namespace llvm
#endif // LLVM_ADT_ITERATOR_H
diff --git a/contrib/llvm/include/llvm/ADT/iterator_range.h b/contrib/llvm/include/llvm/ADT/iterator_range.h
index 3dd679b..3cbf619 100644
--- a/contrib/llvm/include/llvm/ADT/iterator_range.h
+++ b/contrib/llvm/include/llvm/ADT/iterator_range.h
@@ -19,8 +19,8 @@
#ifndef LLVM_ADT_ITERATOR_RANGE_H
#define LLVM_ADT_ITERATOR_RANGE_H
-#include <utility>
#include <iterator>
+#include <utility>
namespace llvm {
diff --git a/contrib/llvm/include/llvm/ADT/simple_ilist.h b/contrib/llvm/include/llvm/ADT/simple_ilist.h
index a1ab591..4c7598a 100644
--- a/contrib/llvm/include/llvm/ADT/simple_ilist.h
+++ b/contrib/llvm/include/llvm/ADT/simple_ilist.h
@@ -13,9 +13,14 @@
#include "llvm/ADT/ilist_base.h"
#include "llvm/ADT/ilist_iterator.h"
#include "llvm/ADT/ilist_node.h"
+#include "llvm/ADT/ilist_node_options.h"
+#include "llvm/Support/Compiler.h"
#include <algorithm>
#include <cassert>
#include <cstddef>
+#include <functional>
+#include <iterator>
+#include <utility>
namespace llvm {
@@ -77,23 +82,23 @@ class simple_ilist
typename ilist_detail::compute_node_options<T, Options...>::type> {
static_assert(ilist_detail::check_options<Options...>::value,
"Unrecognized node option!");
- typedef
- typename ilist_detail::compute_node_options<T, Options...>::type OptionsT;
- typedef typename OptionsT::list_base_type list_base_type;
+ using OptionsT =
+ typename ilist_detail::compute_node_options<T, Options...>::type;
+ using list_base_type = typename OptionsT::list_base_type;
ilist_sentinel<OptionsT> Sentinel;
public:
- typedef typename OptionsT::value_type value_type;
- typedef typename OptionsT::pointer pointer;
- typedef typename OptionsT::reference reference;
- typedef typename OptionsT::const_pointer const_pointer;
- typedef typename OptionsT::const_reference const_reference;
- typedef ilist_iterator<OptionsT, false, false> iterator;
- typedef ilist_iterator<OptionsT, false, true> const_iterator;
- typedef ilist_iterator<OptionsT, true, false> reverse_iterator;
- typedef ilist_iterator<OptionsT, true, true> const_reverse_iterator;
- typedef size_t size_type;
- typedef ptrdiff_t difference_type;
+ using value_type = typename OptionsT::value_type;
+ using pointer = typename OptionsT::pointer;
+ using reference = typename OptionsT::reference;
+ using const_pointer = typename OptionsT::const_pointer;
+ using const_reference = typename OptionsT::const_reference;
+ using iterator = ilist_iterator<OptionsT, false, false>;
+ using const_iterator = ilist_iterator<OptionsT, false, true>;
+ using reverse_iterator = ilist_iterator<OptionsT, true, false>;
+ using const_reverse_iterator = ilist_iterator<OptionsT, true, true>;
+ using size_type = size_t;
+ using difference_type = ptrdiff_t;
simple_ilist() = default;
~simple_ilist() = default;
diff --git a/contrib/llvm/include/llvm/Analysis/AliasAnalysis.h b/contrib/llvm/include/llvm/Analysis/AliasAnalysis.h
index d8e5043..e00ae4f 100644
--- a/contrib/llvm/include/llvm/Analysis/AliasAnalysis.h
+++ b/contrib/llvm/include/llvm/Analysis/AliasAnalysis.h
@@ -38,11 +38,11 @@
#ifndef LLVM_ANALYSIS_ALIASANALYSIS_H
#define LLVM_ANALYSIS_ALIASANALYSIS_H
+#include "llvm/Analysis/MemoryLocation.h"
+#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/IR/CallSite.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/PassManager.h"
-#include "llvm/Analysis/MemoryLocation.h"
-#include "llvm/Analysis/TargetLibraryInfo.h"
namespace llvm {
class BasicAAResult;
@@ -443,11 +443,7 @@ public:
/// getModRefInfo (for fences) - Return information about whether
/// a particular store modifies or reads the specified memory location.
- ModRefInfo getModRefInfo(const FenceInst *S, const MemoryLocation &Loc) {
- // Conservatively correct. (We could possibly be a bit smarter if
- // Loc is a alloca that doesn't escape.)
- return MRI_ModRef;
- }
+ ModRefInfo getModRefInfo(const FenceInst *S, const MemoryLocation &Loc);
/// getModRefInfo (for fences) - A convenience wrapper.
ModRefInfo getModRefInfo(const FenceInst *S, const Value *P, uint64_t Size) {
@@ -528,6 +524,14 @@ public:
/// Check whether or not an instruction may read or write the specified
/// memory location.
///
+ /// Note explicitly that getModRefInfo considers the effects of reading and
+ /// writing the memory location, and not the effect of ordering relative to
+ /// other instructions. Thus, a volatile load is considered to be Ref,
+ /// because it does not actually write memory, it just can't be reordered
+ /// relative to other volatiles (or removed). Atomic ordered loads/stores are
+ /// considered ModRef ATM because conservatively, the visible effect appears
+ /// as if memory was written, not just an ordering constraint.
+ ///
/// An instruction that doesn't read or write memory may be trivially LICM'd
/// for example.
///
diff --git a/contrib/llvm/include/llvm/Analysis/AliasSetTracker.h b/contrib/llvm/include/llvm/Analysis/AliasSetTracker.h
index 5d11b22..daafd2f 100644
--- a/contrib/llvm/include/llvm/Analysis/AliasSetTracker.h
+++ b/contrib/llvm/include/llvm/Analysis/AliasSetTracker.h
@@ -69,10 +69,15 @@ class AliasSet : public ilist_node<AliasSet> {
if (AAInfo == DenseMapInfo<AAMDNodes>::getEmptyKey())
// We don't have a AAInfo yet. Set it to NewAAInfo.
AAInfo = NewAAInfo;
- else if (AAInfo != NewAAInfo)
- // NewAAInfo conflicts with AAInfo.
- AAInfo = DenseMapInfo<AAMDNodes>::getTombstoneKey();
-
+ else {
+ AAMDNodes Intersection(AAInfo.intersect(NewAAInfo));
+ if (!Intersection) {
+ // NewAAInfo conflicts with AAInfo.
+ AAInfo = DenseMapInfo<AAMDNodes>::getTombstoneKey();
+ return SizeChanged;
+ }
+ AAInfo = Intersection;
+ }
return SizeChanged;
}
@@ -121,7 +126,10 @@ class AliasSet : public ilist_node<AliasSet> {
AliasSet *Forward;
/// All instructions without a specific address in this alias set.
- std::vector<AssertingVH<Instruction> > UnknownInsts;
+ /// In rare cases this vector can have a null'ed out WeakVH
+ /// instances (can happen if some other loop pass deletes an
+ /// instruction in this list).
+ std::vector<WeakVH> UnknownInsts;
/// Number of nodes pointing to this AliasSet plus the number of AliasSets
/// forwarding to it.
@@ -171,7 +179,7 @@ class AliasSet : public ilist_node<AliasSet> {
Instruction *getUnknownInst(unsigned i) const {
assert(i < UnknownInsts.size());
- return UnknownInsts[i];
+ return cast_or_null<Instruction>(UnknownInsts[i]);
}
public:
diff --git a/contrib/llvm/include/llvm/Analysis/AssumptionCache.h b/contrib/llvm/include/llvm/Analysis/AssumptionCache.h
index 79287ed..58d72af 100644
--- a/contrib/llvm/include/llvm/Analysis/AssumptionCache.h
+++ b/contrib/llvm/include/llvm/Analysis/AssumptionCache.h
@@ -21,8 +21,8 @@
#include "llvm/ADT/SmallSet.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Instructions.h"
-#include "llvm/IR/ValueHandle.h"
#include "llvm/IR/PassManager.h"
+#include "llvm/IR/ValueHandle.h"
#include "llvm/Pass.h"
#include <memory>
@@ -31,11 +31,10 @@ namespace llvm {
/// \brief A cache of @llvm.assume calls within a function.
///
/// This cache provides fast lookup of assumptions within a function by caching
-/// them and amortizing the cost of scanning for them across all queries. The
-/// cache is also conservatively self-updating so that it will never return
-/// incorrect results about a function even as the function is being mutated.
-/// However, flushing the cache and rebuilding it (or explicitly updating it)
-/// may allow it to discover new assumptions.
+/// them and amortizing the cost of scanning for them across all queries. Passes
+/// that create new assumptions are required to call registerAssumption() to
+/// register any new @llvm.assume calls that they create. Deletions of
+/// @llvm.assume calls do not require special handling.
class AssumptionCache {
/// \brief The function for which this cache is handling assumptions.
///
@@ -44,7 +43,7 @@ class AssumptionCache {
/// \brief Vector of weak value handles to calls of the @llvm.assume
/// intrinsic.
- SmallVector<WeakVH, 4> AssumeHandles;
+ SmallVector<WeakTrackingVH, 4> AssumeHandles;
class AffectedValueCallbackVH final : public CallbackVH {
AssumptionCache *AC;
@@ -63,12 +62,12 @@ class AssumptionCache {
/// \brief A map of values about which an assumption might be providing
/// information to the relevant set of assumptions.
using AffectedValuesMap =
- DenseMap<AffectedValueCallbackVH, SmallVector<WeakVH, 1>,
- AffectedValueCallbackVH::DMI>;
+ DenseMap<AffectedValueCallbackVH, SmallVector<WeakTrackingVH, 1>,
+ AffectedValueCallbackVH::DMI>;
AffectedValuesMap AffectedValues;
/// Get the vector of assumptions which affect a value from the cache.
- SmallVector<WeakVH, 1> &getOrInsertAffectedValues(Value *V);
+ SmallVector<WeakTrackingVH, 1> &getOrInsertAffectedValues(Value *V);
/// Copy affected values in the cache for OV to be affected values for NV.
void copyAffectedValuesInCache(Value *OV, Value *NV);
@@ -87,6 +86,13 @@ public:
/// its instructions.
AssumptionCache(Function &F) : F(F), Scanned(false) {}
+ /// This cache is designed to be self-updating and so it should never be
+ /// invalidated.
+ bool invalidate(Function &, const PreservedAnalyses &,
+ FunctionAnalysisManager::Invalidator &) {
+ return false;
+ }
+
/// \brief Add an @llvm.assume intrinsic to this function's cache.
///
/// The call passed in must be an instruction within this function and must
@@ -114,20 +120,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<WeakVH> assumptions() {
+ MutableArrayRef<WeakTrackingVH> assumptions() {
if (!Scanned)
scanFunction();
return AssumeHandles;
}
/// \brief Access the list of assumptions which affect this value.
- MutableArrayRef<WeakVH> assumptionsFor(const Value *V) {
+ MutableArrayRef<WeakTrackingVH> assumptionsFor(const Value *V) {
if (!Scanned)
scanFunction();
auto AVI = AffectedValues.find_as(const_cast<Value *>(V));
if (AVI == AffectedValues.end())
- return MutableArrayRef<WeakVH>();
+ return MutableArrayRef<WeakTrackingVH>();
return AVI->second;
}
@@ -196,7 +202,10 @@ public:
AssumptionCacheTracker();
~AssumptionCacheTracker() override;
- void releaseMemory() override { AssumptionCaches.shrink_and_clear(); }
+ void releaseMemory() override {
+ verifyAnalysis();
+ AssumptionCaches.shrink_and_clear();
+ }
void verifyAnalysis() const override;
bool doFinalization(Module &) override {
diff --git a/contrib/llvm/include/llvm/Analysis/BasicAliasAnalysis.h b/contrib/llvm/include/llvm/Analysis/BasicAliasAnalysis.h
index addfffa..14e4bde 100644
--- a/contrib/llvm/include/llvm/Analysis/BasicAliasAnalysis.h
+++ b/contrib/llvm/include/llvm/Analysis/BasicAliasAnalysis.h
@@ -233,6 +233,24 @@ FunctionPass *createBasicAAWrapperPass();
/// populated to the best of our ability for a particular function when inside
/// of a \c ModulePass or a \c CallGraphSCCPass.
BasicAAResult createLegacyPMBasicAAResult(Pass &P, Function &F);
+
+/// This class is a functor to be used in legacy module or SCC passes for
+/// computing AA results for a function. We store the results in fields so that
+/// they live long enough to be queried, but we re-use them each time.
+class LegacyAARGetter {
+ Pass &P;
+ Optional<BasicAAResult> BAR;
+ Optional<AAResults> AAR;
+
+public:
+ LegacyAARGetter(Pass &P) : P(P) {}
+ AAResults &operator()(Function &F) {
+ BAR.emplace(createLegacyPMBasicAAResult(P, F));
+ AAR.emplace(createLegacyPMAAResults(P, F, *BAR));
+ return *AAR;
+ }
+};
+
}
#endif
diff --git a/contrib/llvm/include/llvm/Analysis/BlockFrequencyInfo.h b/contrib/llvm/include/llvm/Analysis/BlockFrequencyInfo.h
index 562041d..cbae01c 100644
--- a/contrib/llvm/include/llvm/Analysis/BlockFrequencyInfo.h
+++ b/contrib/llvm/include/llvm/Analysis/BlockFrequencyInfo.h
@@ -45,6 +45,10 @@ public:
~BlockFrequencyInfo();
+ /// Handle invalidation explicitly.
+ bool invalidate(Function &F, const PreservedAnalyses &PA,
+ FunctionAnalysisManager::Invalidator &);
+
const Function *getFunction() const;
const BranchProbabilityInfo *getBPI() const;
void view() const;
@@ -69,6 +73,12 @@ public:
// Set the frequency of the given basic block.
void setBlockFreq(const BasicBlock *BB, uint64_t Freq);
+ /// Set the frequency of \p ReferenceBB to \p Freq and scale the frequencies
+ /// of the blocks in \p BlocksToScale such that their frequencies relative
+ /// to \p ReferenceBB remain unchanged.
+ void setBlockFreqAndScale(const BasicBlock *ReferenceBB, uint64_t Freq,
+ SmallPtrSetImpl<BasicBlock *> &BlocksToScale);
+
/// calculate - compute block frequency info for the given function.
void calculate(const Function &F, const BranchProbabilityInfo &BPI,
const LoopInfo &LI);
diff --git a/contrib/llvm/include/llvm/Analysis/BlockFrequencyInfoImpl.h b/contrib/llvm/include/llvm/Analysis/BlockFrequencyInfoImpl.h
index 3f4428d..5de3821 100644
--- a/contrib/llvm/include/llvm/Analysis/BlockFrequencyInfoImpl.h
+++ b/contrib/llvm/include/llvm/Analysis/BlockFrequencyInfoImpl.h
@@ -1164,9 +1164,8 @@ template <class BT> struct BlockEdgesAdder {
void operator()(IrreducibleGraph &G, IrreducibleGraph::IrrNode &Irr,
const LoopData *OuterLoop) {
const BlockT *BB = BFI.RPOT[Irr.Node.Index];
- for (auto I = Successor::child_begin(BB), E = Successor::child_end(BB);
- I != E; ++I)
- G.addEdge(Irr, BFI.getNode(*I), OuterLoop);
+ for (const auto Succ : children<const BlockT *>(BB))
+ G.addEdge(Irr, BFI.getNode(Succ), OuterLoop);
}
};
}
@@ -1210,10 +1209,9 @@ BlockFrequencyInfoImpl<BT>::propagateMassToSuccessors(LoopData *OuterLoop,
return false;
} else {
const BlockT *BB = getBlock(Node);
- for (auto SI = Successor::child_begin(BB), SE = Successor::child_end(BB);
- SI != SE; ++SI)
- if (!addToDist(Dist, OuterLoop, Node, getNode(*SI),
- getWeightFromBranchProb(BPI->getEdgeProbability(BB, SI))))
+ for (const auto Succ : children<const BlockT *>(BB))
+ if (!addToDist(Dist, OuterLoop, Node, getNode(Succ),
+ getWeightFromBranchProb(BPI->getEdgeProbability(BB, Succ))))
// Irreducible backedge.
return false;
}
@@ -1291,11 +1289,14 @@ struct BFIDOTGraphTraitsBase : public DefaultDOTGraphTraits {
}
std::string getNodeLabel(NodeRef Node, const BlockFrequencyInfoT *Graph,
- GVDAGType GType) {
+ GVDAGType GType, int layout_order = -1) {
std::string Result;
raw_string_ostream OS(Result);
- OS << Node->getName().str() << " : ";
+ if (layout_order != -1)
+ OS << Node->getName() << "[" << layout_order << "] : ";
+ else
+ OS << Node->getName() << " : ";
switch (GType) {
case GVDT_Fraction:
Graph->printBlockFreq(OS, Node);
@@ -1352,4 +1353,4 @@ struct BFIDOTGraphTraitsBase : public DefaultDOTGraphTraits {
#undef DEBUG_TYPE
-#endif
+#endif // LLVM_ANALYSIS_BLOCKFREQUENCYINFOIMPL_H
diff --git a/contrib/llvm/include/llvm/Analysis/BranchProbabilityInfo.h b/contrib/llvm/include/llvm/Analysis/BranchProbabilityInfo.h
index 14b7a7f..94d3d4d 100644
--- a/contrib/llvm/include/llvm/Analysis/BranchProbabilityInfo.h
+++ b/contrib/llvm/include/llvm/Analysis/BranchProbabilityInfo.h
@@ -26,6 +26,7 @@
namespace llvm {
class LoopInfo;
+class TargetLibraryInfo;
class raw_ostream;
/// \brief Analysis providing branch probability information.
@@ -43,8 +44,9 @@ class raw_ostream;
class BranchProbabilityInfo {
public:
BranchProbabilityInfo() {}
- BranchProbabilityInfo(const Function &F, const LoopInfo &LI) {
- calculate(F, LI);
+ BranchProbabilityInfo(const Function &F, const LoopInfo &LI,
+ const TargetLibraryInfo *TLI = nullptr) {
+ calculate(F, LI, TLI);
}
BranchProbabilityInfo(BranchProbabilityInfo &&Arg)
@@ -116,7 +118,8 @@ public:
return IsLikely ? LikelyProb : LikelyProb.getCompl();
}
- void calculate(const Function &F, const LoopInfo &LI);
+ void calculate(const Function &F, const LoopInfo &LI,
+ const TargetLibraryInfo *TLI = nullptr);
/// Forget analysis results for the given basic block.
void eraseBlock(const BasicBlock *BB);
@@ -164,12 +167,14 @@ private:
/// \brief Track the set of blocks that always lead to a cold call.
SmallPtrSet<const BasicBlock *, 16> PostDominatedByColdCall;
+ void updatePostDominatedByUnreachable(const BasicBlock *BB);
+ void updatePostDominatedByColdCall(const BasicBlock *BB);
bool calcUnreachableHeuristics(const BasicBlock *BB);
bool calcMetadataWeights(const BasicBlock *BB);
bool calcColdCallHeuristics(const BasicBlock *BB);
bool calcPointerHeuristics(const BasicBlock *BB);
bool calcLoopBranchHeuristics(const BasicBlock *BB, const LoopInfo &LI);
- bool calcZeroHeuristics(const BasicBlock *BB);
+ bool calcZeroHeuristics(const BasicBlock *BB, const TargetLibraryInfo *TLI);
bool calcFloatingPointHeuristics(const BasicBlock *BB);
bool calcInvokeHeuristics(const BasicBlock *BB);
};
diff --git a/contrib/llvm/include/llvm/Analysis/CFGPrinter.h b/contrib/llvm/include/llvm/Analysis/CFGPrinter.h
index efaa9d6..5786769 100644
--- a/contrib/llvm/include/llvm/Analysis/CFGPrinter.h
+++ b/contrib/llvm/include/llvm/Analysis/CFGPrinter.h
@@ -140,8 +140,7 @@ struct DOTGraphTraits<const Function*> : public DefaultDOTGraphTraits {
std::string Str;
raw_string_ostream OS(Str);
- SwitchInst::ConstCaseIt Case =
- SwitchInst::ConstCaseIt::fromSuccessorIndex(SI, SuccNo);
+ auto Case = *SwitchInst::ConstCaseIt::fromSuccessorIndex(SI, SuccNo);
OS << Case.getCaseValue()->getValue();
return OS.str();
}
diff --git a/contrib/llvm/include/llvm/Analysis/CFLAliasAnalysisUtils.h b/contrib/llvm/include/llvm/Analysis/CFLAliasAnalysisUtils.h
new file mode 100644
index 0000000..981a8dd
--- /dev/null
+++ b/contrib/llvm/include/llvm/Analysis/CFLAliasAnalysisUtils.h
@@ -0,0 +1,58 @@
+//=- CFLAliasAnalysisUtils.h - Utilities for CFL Alias Analysis ----*- C++-*-=//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// \file
+// These are the utilities/helpers used by the CFL Alias Analyses available in
+// tree, i.e. Steensgaard's and Andersens'.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_CFLALIASANALYSISUTILS_H
+#define LLVM_ANALYSIS_CFLALIASANALYSISUTILS_H
+
+#include "llvm/IR/Function.h"
+#include "llvm/IR/ValueHandle.h"
+
+namespace llvm {
+namespace cflaa {
+
+template <typename AAResult> struct FunctionHandle final : public CallbackVH {
+ FunctionHandle(Function *Fn, AAResult *Result)
+ : CallbackVH(Fn), Result(Result) {
+ assert(Fn != nullptr);
+ assert(Result != nullptr);
+ }
+
+ void deleted() override { removeSelfFromCache(); }
+ void allUsesReplacedWith(Value *) override { removeSelfFromCache(); }
+
+private:
+ AAResult *Result;
+
+ void removeSelfFromCache() {
+ assert(Result != nullptr);
+ auto *Val = getValPtr();
+ Result->evict(cast<Function>(Val));
+ setValPtr(nullptr);
+ }
+};
+
+static inline const Function *parentFunctionOfValue(const Value *Val) {
+ if (auto *Inst = dyn_cast<Instruction>(Val)) {
+ auto *Bb = Inst->getParent();
+ return Bb->getParent();
+ }
+
+ if (auto *Arg = dyn_cast<Argument>(Val))
+ return Arg->getParent();
+ return nullptr;
+} // namespace cflaa
+} // namespace llvm
+}
+
+#endif // LLVM_ANALYSIS_CFLALIASANALYSISUTILS_H
diff --git a/contrib/llvm/include/llvm/Analysis/CFLAndersAliasAnalysis.h b/contrib/llvm/include/llvm/Analysis/CFLAndersAliasAnalysis.h
index f3520aa..4146ad4 100644
--- a/contrib/llvm/include/llvm/Analysis/CFLAndersAliasAnalysis.h
+++ b/contrib/llvm/include/llvm/Analysis/CFLAndersAliasAnalysis.h
@@ -18,8 +18,8 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/Optional.h"
#include "llvm/Analysis/AliasAnalysis.h"
+#include "llvm/Analysis/CFLAliasAnalysisUtils.h"
#include "llvm/IR/Function.h"
-#include "llvm/IR/ValueHandle.h"
#include "llvm/Pass.h"
#include <forward_list>
@@ -47,7 +47,7 @@ public:
return false;
}
/// Evict the given function from cache
- void evict(const Function &Fn);
+ void evict(const Function *Fn);
/// \brief Get the alias summary for the given function
/// Return nullptr if the summary is not found or not available
@@ -57,27 +57,6 @@ public:
AliasResult alias(const MemoryLocation &, const MemoryLocation &);
private:
- struct FunctionHandle final : public CallbackVH {
- FunctionHandle(Function *Fn, CFLAndersAAResult *Result)
- : CallbackVH(Fn), Result(Result) {
- assert(Fn != nullptr);
- assert(Result != nullptr);
- }
-
- void deleted() override { removeSelfFromCache(); }
- void allUsesReplacedWith(Value *) override { removeSelfFromCache(); }
-
- private:
- CFLAndersAAResult *Result;
-
- void removeSelfFromCache() {
- assert(Result != nullptr);
- auto *Val = getValPtr();
- Result->evict(*cast<Function>(Val));
- setValPtr(nullptr);
- }
- };
-
/// \brief Ensures that the given function is available in the cache.
/// Returns the appropriate entry from the cache.
const Optional<FunctionInfo> &ensureCached(const Function &);
@@ -97,7 +76,7 @@ private:
/// that simply has empty sets.
DenseMap<const Function *, Optional<FunctionInfo>> Cache;
- std::forward_list<FunctionHandle> Handles;
+ std::forward_list<cflaa::FunctionHandle<CFLAndersAAResult>> Handles;
};
/// Analysis pass providing a never-invalidated alias analysis result.
diff --git a/contrib/llvm/include/llvm/Analysis/CFLSteensAliasAnalysis.h b/contrib/llvm/include/llvm/Analysis/CFLSteensAliasAnalysis.h
index 3aae9a1..fd3fa5f 100644
--- a/contrib/llvm/include/llvm/Analysis/CFLSteensAliasAnalysis.h
+++ b/contrib/llvm/include/llvm/Analysis/CFLSteensAliasAnalysis.h
@@ -19,6 +19,7 @@
#include "llvm/ADT/None.h"
#include "llvm/ADT/Optional.h"
#include "llvm/Analysis/AliasAnalysis.h"
+#include "llvm/Analysis/CFLAliasAnalysisUtils.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/ValueHandle.h"
@@ -85,27 +86,6 @@ public:
}
private:
- struct FunctionHandle final : public CallbackVH {
- FunctionHandle(Function *Fn, CFLSteensAAResult *Result)
- : CallbackVH(Fn), Result(Result) {
- assert(Fn != nullptr);
- assert(Result != nullptr);
- }
-
- void deleted() override { removeSelfFromCache(); }
- void allUsesReplacedWith(Value *) override { removeSelfFromCache(); }
-
- private:
- CFLSteensAAResult *Result;
-
- void removeSelfFromCache() {
- assert(Result != nullptr);
- auto *Val = getValPtr();
- Result->evict(cast<Function>(Val));
- setValPtr(nullptr);
- }
- };
-
const TargetLibraryInfo &TLI;
/// \brief Cached mapping of Functions to their StratifiedSets.
@@ -114,7 +94,7 @@ private:
/// have any kind of recursion, it is discernable from a function
/// that simply has empty sets.
DenseMap<Function *, Optional<FunctionInfo>> Cache;
- std::forward_list<FunctionHandle> Handles;
+ std::forward_list<cflaa::FunctionHandle<CFLSteensAAResult>> Handles;
FunctionInfo buildSetsFrom(Function *F);
};
diff --git a/contrib/llvm/include/llvm/Analysis/CGSCCPassManager.h b/contrib/llvm/include/llvm/Analysis/CGSCCPassManager.h
index 6fbe532..32868cb 100644
--- a/contrib/llvm/include/llvm/Analysis/CGSCCPassManager.h
+++ b/contrib/llvm/include/llvm/Analysis/CGSCCPassManager.h
@@ -334,6 +334,7 @@ public:
InvalidSCCSet, nullptr, nullptr};
PreservedAnalyses PA = PreservedAnalyses::all();
+ CG.buildRefSCCs();
for (auto RCI = CG.postorder_ref_scc_begin(),
RCE = CG.postorder_ref_scc_end();
RCI != RCE;) {
@@ -576,12 +577,17 @@ public:
// analyses will eventually occur when the module pass completes.
PA.intersect(std::move(PassPA));
- // Update the call graph based on this function pass. This may also
- // update the current SCC to point to a smaller, more refined SCC.
- CurrentC = &updateCGAndAnalysisManagerForFunctionPass(
- CG, *CurrentC, *N, AM, UR, DebugLogging);
- assert(CG.lookupSCC(*N) == CurrentC &&
- "Current SCC not updated to the SCC containing the current node!");
+ // If the call graph hasn't been preserved, update it based on this
+ // function pass. This may also update the current SCC to point to
+ // a smaller, more refined SCC.
+ auto PAC = PA.getChecker<LazyCallGraphAnalysis>();
+ if (!PAC.preserved() && !PAC.preservedSet<AllAnalysesOn<Module>>()) {
+ CurrentC = &updateCGAndAnalysisManagerForFunctionPass(
+ CG, *CurrentC, *N, AM, UR, DebugLogging);
+ assert(
+ CG.lookupSCC(*N) == CurrentC &&
+ "Current SCC not updated to the SCC containing the current node!");
+ }
}
// By definition we preserve the proxy. And we preserve all analyses on
@@ -645,7 +651,7 @@ public:
LazyCallGraph::SCC *C = &InitialC;
// Collect value handles for all of the indirect call sites.
- SmallVector<WeakVH, 8> CallHandles;
+ SmallVector<WeakTrackingVH, 8> CallHandles;
// Struct to track the counts of direct and indirect calls in each function
// of the SCC.
@@ -657,7 +663,7 @@ public:
// Put value handles on all of the indirect calls and return the number of
// direct calls for each function in the SCC.
auto ScanSCC = [](LazyCallGraph::SCC &C,
- SmallVectorImpl<WeakVH> &CallHandles) {
+ SmallVectorImpl<WeakTrackingVH> &CallHandles) {
assert(CallHandles.empty() && "Must start with a clear set of handles.");
SmallVector<CallCount, 4> CallCounts;
@@ -670,7 +676,7 @@ public:
++Count.Direct;
} else {
++Count.Indirect;
- CallHandles.push_back(WeakVH(&I));
+ CallHandles.push_back(WeakTrackingVH(&I));
}
}
}
@@ -698,7 +704,7 @@ public:
"Cannot have changed the size of the SCC!");
// Check whether any of the handles were devirtualized.
- auto IsDevirtualizedHandle = [&](WeakVH &CallH) {
+ auto IsDevirtualizedHandle = [&](WeakTrackingVH &CallH) {
if (!CallH)
return false;
auto CS = CallSite(CallH);
diff --git a/contrib/llvm/include/llvm/Analysis/CallGraph.h b/contrib/llvm/include/llvm/Analysis/CallGraph.h
index 4ecbaa7..01469a2 100644
--- a/contrib/llvm/include/llvm/Analysis/CallGraph.h
+++ b/contrib/llvm/include/llvm/Analysis/CallGraph.h
@@ -41,12 +41,6 @@
/// of all of the caller-callee relationships, which is useful for
/// transformations.
///
-/// The CallGraph class also attempts to figure out what the root of the
-/// CallGraph is, which it currently does by looking for a function named
-/// 'main'. If no function named 'main' is found, the external node is used as
-/// the entry node, reflecting the fact that any function without internal
-/// linkage could be called into (which is common for libraries).
-///
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_CALLGRAPH_H
@@ -82,10 +76,6 @@ class CallGraph {
/// \brief A map from \c Function* to \c CallGraphNode*.
FunctionMapTy FunctionMap;
- /// \brief Root is root of the call graph, or the external node if a 'main'
- /// function couldn't be found.
- CallGraphNode *Root;
-
/// \brief This node has edges to all external functions and those internal
/// functions that have their address taken.
CallGraphNode *ExternalCallingNode;
@@ -172,7 +162,7 @@ class CallGraphNode {
public:
/// \brief A pair of the calling instruction (a call or invoke)
/// and the call graph node being called.
- typedef std::pair<WeakVH, CallGraphNode *> CallRecord;
+ typedef std::pair<WeakTrackingVH, CallGraphNode *> CallRecord;
public:
typedef std::vector<CallRecord> CalledFunctionsVector;
@@ -272,7 +262,7 @@ public:
private:
friend class CallGraph;
- AssertingVH<Function> F;
+ Function *F;
std::vector<CallRecord> CalledFunctions;
diff --git a/contrib/llvm/include/llvm/Analysis/ConstantFolding.h b/contrib/llvm/include/llvm/Analysis/ConstantFolding.h
index 517842c..4203474 100644
--- a/contrib/llvm/include/llvm/Analysis/ConstantFolding.h
+++ b/contrib/llvm/include/llvm/Analysis/ConstantFolding.h
@@ -31,6 +31,7 @@ class DataLayout;
class Function;
class GlobalValue;
class Instruction;
+class ImmutableCallSite;
class TargetLibraryInfo;
class Type;
@@ -100,6 +101,12 @@ Constant *ConstantFoldExtractValueInstruction(Constant *Agg,
/// successful; if not, null is returned.
Constant *ConstantFoldExtractElementInstruction(Constant *Val, Constant *Idx);
+/// \brief 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.
+Constant *ConstantFoldShuffleVectorInstruction(Constant *V1, Constant *V2,
+ Constant *Mask);
+
/// ConstantFoldLoadFromConstPtr - Return the value that a load from C would
/// produce if it is constant and determinable. If this is not determinable,
/// return null.
@@ -119,11 +126,12 @@ Constant *ConstantFoldLoadThroughGEPIndices(Constant *C,
/// canConstantFoldCallTo - Return true if its even possible to fold a call to
/// the specified function.
-bool canConstantFoldCallTo(const Function *F);
+bool canConstantFoldCallTo(ImmutableCallSite CS, const Function *F);
/// ConstantFoldCall - Attempt to constant fold a call to the specified function
/// with the specified arguments, returning null if unsuccessful.
-Constant *ConstantFoldCall(Function *F, ArrayRef<Constant *> Operands,
+Constant *ConstantFoldCall(ImmutableCallSite CS, Function *F,
+ ArrayRef<Constant *> Operands,
const TargetLibraryInfo *TLI = nullptr);
/// \brief Check whether the given call has no side-effects.
diff --git a/contrib/llvm/include/llvm/Analysis/DemandedBits.h b/contrib/llvm/include/llvm/Analysis/DemandedBits.h
index c603274..e52c66f 100644
--- a/contrib/llvm/include/llvm/Analysis/DemandedBits.h
+++ b/contrib/llvm/include/llvm/Analysis/DemandedBits.h
@@ -22,11 +22,11 @@
#ifndef LLVM_ANALYSIS_DEMANDED_BITS_H
#define LLVM_ANALYSIS_DEMANDED_BITS_H
-#include "llvm/Pass.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/IR/PassManager.h"
+#include "llvm/Pass.h"
namespace llvm {
@@ -35,6 +35,7 @@ class Function;
class Instruction;
class DominatorTree;
class AssumptionCache;
+struct KnownBits;
class DemandedBits {
public:
@@ -58,8 +59,7 @@ private:
void determineLiveOperandBits(const Instruction *UserI,
const Instruction *I, unsigned OperandNo,
const APInt &AOut, APInt &AB,
- APInt &KnownZero, APInt &KnownOne,
- APInt &KnownZero2, APInt &KnownOne2);
+ KnownBits &Known, KnownBits &Known2);
bool Analyzed;
diff --git a/contrib/llvm/include/llvm/Analysis/DominanceFrontier.h b/contrib/llvm/include/llvm/Analysis/DominanceFrontier.h
index b9667f8..b566aea 100644
--- a/contrib/llvm/include/llvm/Analysis/DominanceFrontier.h
+++ b/contrib/llvm/include/llvm/Analysis/DominanceFrontier.h
@@ -29,9 +29,9 @@ namespace llvm {
/// DominanceFrontierBase - Common base class for computing forward and inverse
/// dominance frontiers for a function.
///
-template <class BlockT>
+template <class BlockT, bool IsPostDom>
class DominanceFrontierBase {
-public:
+ public:
typedef std::set<BlockT *> DomSetType; // Dom set for a bb
typedef std::map<BlockT *, DomSetType> DomSetMapType; // Dom set map
@@ -40,10 +40,10 @@ protected:
DomSetMapType Frontiers;
std::vector<BlockT *> Roots;
- const bool IsPostDominators;
+ static constexpr bool IsPostDominators = IsPostDom;
-public:
- DominanceFrontierBase(bool isPostDom) : IsPostDominators(isPostDom) {}
+ public:
+ DominanceFrontierBase() {}
/// getRoots - Return the root blocks of the current CFG. This may include
/// multiple blocks if we are computing post dominators. For forward
@@ -96,7 +96,7 @@ public:
/// compare - Return true if the other dominance frontier base matches
/// this dominance frontier base. Otherwise return false.
- bool compare(DominanceFrontierBase<BlockT> &Other) const;
+ bool compare(DominanceFrontierBase &Other) const;
/// print - Convert to human readable form
///
@@ -113,22 +113,21 @@ public:
/// used to compute a forward dominator frontiers.
///
template <class BlockT>
-class ForwardDominanceFrontierBase : public DominanceFrontierBase<BlockT> {
-private:
+class ForwardDominanceFrontierBase
+ : public DominanceFrontierBase<BlockT, false> {
+ private:
typedef GraphTraits<BlockT *> BlockTraits;
public:
- typedef DominatorTreeBase<BlockT> DomTreeT;
- typedef DomTreeNodeBase<BlockT> DomTreeNodeT;
- typedef typename DominanceFrontierBase<BlockT>::DomSetType DomSetType;
-
- ForwardDominanceFrontierBase() : DominanceFrontierBase<BlockT>(false) {}
-
- void analyze(DomTreeT &DT) {
- this->Roots = DT.getRoots();
- assert(this->Roots.size() == 1 &&
- "Only one entry block for forward domfronts!");
- calculate(DT, DT[this->Roots[0]]);
+ typedef DomTreeBase<BlockT> DomTreeT;
+ typedef DomTreeNodeBase<BlockT> DomTreeNodeT;
+ typedef typename DominanceFrontierBase<BlockT, false>::DomSetType DomSetType;
+
+ void analyze(DomTreeT &DT) {
+ this->Roots = DT.getRoots();
+ assert(this->Roots.size() == 1 &&
+ "Only one entry block for forward domfronts!");
+ calculate(DT, DT[this->Roots[0]]);
}
const DomSetType &calculate(const DomTreeT &DT, const DomTreeNodeT *Node);
@@ -136,11 +135,16 @@ public:
class DominanceFrontier : public ForwardDominanceFrontierBase<BasicBlock> {
public:
- typedef DominatorTreeBase<BasicBlock> DomTreeT;
- typedef DomTreeNodeBase<BasicBlock> DomTreeNodeT;
- typedef DominanceFrontierBase<BasicBlock>::DomSetType DomSetType;
- typedef DominanceFrontierBase<BasicBlock>::iterator iterator;
- typedef DominanceFrontierBase<BasicBlock>::const_iterator const_iterator;
+ typedef DomTreeBase<BasicBlock> DomTreeT;
+ typedef DomTreeNodeBase<BasicBlock> DomTreeNodeT;
+ typedef DominanceFrontierBase<BasicBlock, false>::DomSetType DomSetType;
+ typedef DominanceFrontierBase<BasicBlock, false>::iterator iterator;
+ typedef DominanceFrontierBase<BasicBlock, false>::const_iterator
+ const_iterator;
+
+ /// Handle invalidation explicitly.
+ bool invalidate(Function &F, const PreservedAnalyses &PA,
+ FunctionAnalysisManager::Invalidator &);
};
class DominanceFrontierWrapperPass : public FunctionPass {
@@ -164,7 +168,8 @@ public:
void dump() const;
};
-extern template class DominanceFrontierBase<BasicBlock>;
+extern template class DominanceFrontierBase<BasicBlock, false>;
+extern template class DominanceFrontierBase<BasicBlock, true>;
extern template class ForwardDominanceFrontierBase<BasicBlock>;
/// \brief Analysis pass which computes a \c DominanceFrontier.
diff --git a/contrib/llvm/include/llvm/Analysis/DominanceFrontierImpl.h b/contrib/llvm/include/llvm/Analysis/DominanceFrontierImpl.h
index 629ae38..5093b97 100644
--- a/contrib/llvm/include/llvm/Analysis/DominanceFrontierImpl.h
+++ b/contrib/llvm/include/llvm/Analysis/DominanceFrontierImpl.h
@@ -39,33 +39,33 @@ public:
const DomTreeNodeT *parentNode;
};
-template <class BlockT>
-void DominanceFrontierBase<BlockT>::removeBlock(BlockT *BB) {
+template <class BlockT, bool IsPostDom>
+void DominanceFrontierBase<BlockT, IsPostDom>::removeBlock(BlockT *BB) {
assert(find(BB) != end() && "Block is not in DominanceFrontier!");
for (iterator I = begin(), E = end(); I != E; ++I)
I->second.erase(BB);
Frontiers.erase(BB);
}
-template <class BlockT>
-void DominanceFrontierBase<BlockT>::addToFrontier(iterator I,
- BlockT *Node) {
+template <class BlockT, bool IsPostDom>
+void DominanceFrontierBase<BlockT, IsPostDom>::addToFrontier(iterator I,
+ BlockT *Node) {
assert(I != end() && "BB is not in DominanceFrontier!");
assert(I->second.count(Node) && "Node is not in DominanceFrontier of BB");
I->second.erase(Node);
}
-template <class BlockT>
-void DominanceFrontierBase<BlockT>::removeFromFrontier(iterator I,
- BlockT *Node) {
+template <class BlockT, bool IsPostDom>
+void DominanceFrontierBase<BlockT, IsPostDom>::removeFromFrontier(
+ iterator I, BlockT *Node) {
assert(I != end() && "BB is not in DominanceFrontier!");
assert(I->second.count(Node) && "Node is not in DominanceFrontier of BB");
I->second.erase(Node);
}
-template <class BlockT>
-bool DominanceFrontierBase<BlockT>::compareDomSet(DomSetType &DS1,
- const DomSetType &DS2) const {
+template <class BlockT, bool IsPostDom>
+bool DominanceFrontierBase<BlockT, IsPostDom>::compareDomSet(
+ DomSetType &DS1, const DomSetType &DS2) const {
std::set<BlockT *> tmpSet;
for (BlockT *BB : DS2)
tmpSet.insert(BB);
@@ -88,9 +88,9 @@ bool DominanceFrontierBase<BlockT>::compareDomSet(DomSetType &DS1,
return false;
}
-template <class BlockT>
-bool DominanceFrontierBase<BlockT>::compare(
- DominanceFrontierBase<BlockT> &Other) const {
+template <class BlockT, bool IsPostDom>
+bool DominanceFrontierBase<BlockT, IsPostDom>::compare(
+ DominanceFrontierBase<BlockT, IsPostDom> &Other) const {
DomSetMapType tmpFrontiers;
for (typename DomSetMapType::const_iterator I = Other.begin(),
E = Other.end();
@@ -118,8 +118,8 @@ bool DominanceFrontierBase<BlockT>::compare(
return false;
}
-template <class BlockT>
-void DominanceFrontierBase<BlockT>::print(raw_ostream &OS) const {
+template <class BlockT, bool IsPostDom>
+void DominanceFrontierBase<BlockT, IsPostDom>::print(raw_ostream &OS) const {
for (const_iterator I = begin(), E = end(); I != E; ++I) {
OS << " DomFrontier for BB ";
if (I->first)
@@ -142,8 +142,8 @@ void DominanceFrontierBase<BlockT>::print(raw_ostream &OS) const {
}
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
-template <class BlockT>
-void DominanceFrontierBase<BlockT>::dump() const {
+template <class BlockT, bool IsPostDom>
+void DominanceFrontierBase<BlockT, IsPostDom>::dump() const {
print(dbgs());
}
#endif
@@ -174,12 +174,10 @@ ForwardDominanceFrontierBase<BlockT>::calculate(const DomTreeT &DT,
// Visit each block only once.
if (visited.insert(currentBB).second) {
// Loop over CFG successors to calculate DFlocal[currentNode]
- for (auto SI = BlockTraits::child_begin(currentBB),
- SE = BlockTraits::child_end(currentBB);
- SI != SE; ++SI) {
+ for (const auto Succ : children<BlockT *>(currentBB)) {
// Does Node immediately dominate this successor?
- if (DT[*SI]->getIDom() != currentNode)
- S.insert(*SI);
+ if (DT[Succ]->getIDom() != currentNode)
+ S.insert(Succ);
}
}
diff --git a/contrib/llvm/include/llvm/Analysis/IVUsers.h b/contrib/llvm/include/llvm/Analysis/IVUsers.h
index bb572dd..035b974 100644
--- a/contrib/llvm/include/llvm/Analysis/IVUsers.h
+++ b/contrib/llvm/include/llvm/Analysis/IVUsers.h
@@ -80,7 +80,7 @@ private:
/// OperandValToReplace - The Value of the operand in the user instruction
/// that this IVStrideUse is representing.
- WeakVH OperandValToReplace;
+ WeakTrackingVH OperandValToReplace;
/// PostIncLoops - The set of loops for which Expr has been adjusted to
/// use post-inc mode. This corresponds with SCEVExpander's post-inc concept.
diff --git a/contrib/llvm/include/llvm/Analysis/IndirectCallSiteVisitor.h b/contrib/llvm/include/llvm/Analysis/IndirectCallSiteVisitor.h
index 71a8cb8..3c40cc0 100644
--- a/contrib/llvm/include/llvm/Analysis/IndirectCallSiteVisitor.h
+++ b/contrib/llvm/include/llvm/Analysis/IndirectCallSiteVisitor.h
@@ -21,16 +21,8 @@ struct PGOIndirectCallSiteVisitor
PGOIndirectCallSiteVisitor() {}
void visitCallSite(CallSite CS) {
- if (CS.getCalledFunction() || !CS.getCalledValue())
- return;
- Instruction *I = CS.getInstruction();
- if (CallInst *CI = dyn_cast<CallInst>(I)) {
- if (CI->isInlineAsm())
- return;
- }
- if (isa<Constant>(CS.getCalledValue()))
- return;
- IndirectCallInsts.push_back(I);
+ if (CS.isIndirectCall())
+ IndirectCallInsts.push_back(CS.getInstruction());
}
};
diff --git a/contrib/llvm/include/llvm/Analysis/InlineCost.h b/contrib/llvm/include/llvm/Analysis/InlineCost.h
index 5e7b002..f33a2de 100644
--- a/contrib/llvm/include/llvm/Analysis/InlineCost.h
+++ b/contrib/llvm/include/llvm/Analysis/InlineCost.h
@@ -14,13 +14,14 @@
#ifndef LLVM_ANALYSIS_INLINECOST_H
#define LLVM_ANALYSIS_INLINECOST_H
-#include "llvm/Analysis/CallGraphSCCPass.h"
#include "llvm/Analysis/AssumptionCache.h"
+#include "llvm/Analysis/CallGraphSCCPass.h"
#include <cassert>
#include <climits>
namespace llvm {
class AssumptionCacheTracker;
+class BlockFrequencyInfo;
class CallSite;
class DataLayout;
class Function;
@@ -137,6 +138,9 @@ struct InlineParams {
/// Threshold to use when the callsite is considered hot.
Optional<int> HotCallSiteThreshold;
+
+ /// Threshold to use when the callsite is considered cold.
+ Optional<int> ColdCallSiteThreshold;
};
/// Generate the parameters to tune the inline cost analysis based only on the
@@ -156,6 +160,10 @@ InlineParams getInlineParams(int Threshold);
/// the -Oz flag.
InlineParams getInlineParams(unsigned OptLevel, unsigned SizeOptLevel);
+/// Return the cost associated with a callsite, including parameter passing
+/// and the call/return instruction.
+int getCallsiteCost(CallSite CS, const DataLayout &DL);
+
/// \brief Get an InlineCost object representing the cost of inlining this
/// callsite.
///
@@ -171,6 +179,7 @@ InlineCost
getInlineCost(CallSite CS, const InlineParams &Params,
TargetTransformInfo &CalleeTTI,
std::function<AssumptionCache &(Function &)> &GetAssumptionCache,
+ Optional<function_ref<BlockFrequencyInfo &(Function &)>> GetBFI,
ProfileSummaryInfo *PSI);
/// \brief Get an InlineCost with the callee explicitly specified.
@@ -182,6 +191,7 @@ InlineCost
getInlineCost(CallSite CS, Function *Callee, const InlineParams &Params,
TargetTransformInfo &CalleeTTI,
std::function<AssumptionCache &(Function &)> &GetAssumptionCache,
+ Optional<function_ref<BlockFrequencyInfo &(Function &)>> GetBFI,
ProfileSummaryInfo *PSI);
/// \brief Minimal filter to detect invalid constructs for inlining.
diff --git a/contrib/llvm/include/llvm/Analysis/InstructionSimplify.h b/contrib/llvm/include/llvm/Analysis/InstructionSimplify.h
index 47d6118..be0f32e 100644
--- a/contrib/llvm/include/llvm/Analysis/InstructionSimplify.h
+++ b/contrib/llvm/include/llvm/Analysis/InstructionSimplify.h
@@ -35,291 +35,210 @@
#include "llvm/IR/User.h"
namespace llvm {
- template<typename T>
- class ArrayRef;
- class AssumptionCache;
- class DominatorTree;
- class Instruction;
- class DataLayout;
- class FastMathFlags;
- class TargetLibraryInfo;
- class Type;
- class Value;
-
- /// Given operands for an Add, fold the result or return null.
- Value *SimplifyAddInst(Value *LHS, Value *RHS, bool isNSW, bool isNUW,
- const DataLayout &DL,
- const TargetLibraryInfo *TLI = nullptr,
- const DominatorTree *DT = nullptr,
- AssumptionCache *AC = nullptr,
- const Instruction *CxtI = nullptr);
-
- /// Given operands for a Sub, fold the result or return null.
- Value *SimplifySubInst(Value *LHS, Value *RHS, bool isNSW, bool isNUW,
- const DataLayout &DL,
- const TargetLibraryInfo *TLI = nullptr,
- const DominatorTree *DT = nullptr,
- AssumptionCache *AC = nullptr,
- const Instruction *CxtI = nullptr);
-
- /// Given operands for an FAdd, fold the result or return null.
- Value *SimplifyFAddInst(Value *LHS, Value *RHS, FastMathFlags FMF,
- const DataLayout &DL,
- const TargetLibraryInfo *TLI = nullptr,
- const DominatorTree *DT = nullptr,
- AssumptionCache *AC = nullptr,
- const Instruction *CxtI = nullptr);
-
- /// Given operands for an FSub, fold the result or return null.
- Value *SimplifyFSubInst(Value *LHS, Value *RHS, FastMathFlags FMF,
- const DataLayout &DL,
- const TargetLibraryInfo *TLI = nullptr,
- const DominatorTree *DT = nullptr,
- AssumptionCache *AC = nullptr,
- const Instruction *CxtI = nullptr);
-
- /// Given operands for an FMul, fold the result or return null.
- Value *SimplifyFMulInst(Value *LHS, Value *RHS, FastMathFlags FMF,
- const DataLayout &DL,
- const TargetLibraryInfo *TLI = nullptr,
- const DominatorTree *DT = nullptr,
- AssumptionCache *AC = nullptr,
- const Instruction *CxtI = nullptr);
-
- /// Given operands for a Mul, fold the result or return null.
- Value *SimplifyMulInst(Value *LHS, Value *RHS, const DataLayout &DL,
- const TargetLibraryInfo *TLI = nullptr,
- const DominatorTree *DT = nullptr,
- AssumptionCache *AC = nullptr,
- const Instruction *CxtI = nullptr);
-
- /// Given operands for an SDiv, fold the result or return null.
- Value *SimplifySDivInst(Value *LHS, Value *RHS, const DataLayout &DL,
- const TargetLibraryInfo *TLI = nullptr,
- const DominatorTree *DT = nullptr,
- AssumptionCache *AC = nullptr,
- const Instruction *CxtI = nullptr);
-
- /// Given operands for a UDiv, fold the result or return null.
- Value *SimplifyUDivInst(Value *LHS, Value *RHS, const DataLayout &DL,
- const TargetLibraryInfo *TLI = nullptr,
- const DominatorTree *DT = nullptr,
- AssumptionCache *AC = nullptr,
- const Instruction *CxtI = nullptr);
-
- /// Given operands for an FDiv, fold the result or return null.
- Value *SimplifyFDivInst(Value *LHS, Value *RHS, FastMathFlags FMF,
- const DataLayout &DL,
- const TargetLibraryInfo *TLI = nullptr,
- const DominatorTree *DT = nullptr,
- AssumptionCache *AC = nullptr,
- const Instruction *CxtI = nullptr);
-
- /// Given operands for an SRem, fold the result or return null.
- Value *SimplifySRemInst(Value *LHS, Value *RHS, const DataLayout &DL,
- const TargetLibraryInfo *TLI = nullptr,
- const DominatorTree *DT = nullptr,
- AssumptionCache *AC = nullptr,
- const Instruction *CxtI = nullptr);
-
- /// Given operands for a URem, fold the result or return null.
- Value *SimplifyURemInst(Value *LHS, Value *RHS, const DataLayout &DL,
- const TargetLibraryInfo *TLI = nullptr,
- const DominatorTree *DT = nullptr,
- AssumptionCache *AC = nullptr,
- const Instruction *CxtI = nullptr);
-
- /// Given operands for an FRem, fold the result or return null.
- Value *SimplifyFRemInst(Value *LHS, Value *RHS, FastMathFlags FMF,
- const DataLayout &DL,
- const TargetLibraryInfo *TLI = nullptr,
- const DominatorTree *DT = nullptr,
- AssumptionCache *AC = nullptr,
- const Instruction *CxtI = nullptr);
-
- /// Given operands for a Shl, fold the result or return null.
- Value *SimplifyShlInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW,
- const DataLayout &DL,
- const TargetLibraryInfo *TLI = nullptr,
- const DominatorTree *DT = nullptr,
- AssumptionCache *AC = nullptr,
- const Instruction *CxtI = nullptr);
-
- /// Given operands for a LShr, fold the result or return null.
- Value *SimplifyLShrInst(Value *Op0, Value *Op1, bool isExact,
- const DataLayout &DL,
- const TargetLibraryInfo *TLI = nullptr,
- const DominatorTree *DT = nullptr,
- AssumptionCache *AC = nullptr,
- const Instruction *CxtI = nullptr);
-
- /// Given operands for a AShr, fold the result or return nulll.
- Value *SimplifyAShrInst(Value *Op0, Value *Op1, bool isExact,
- const DataLayout &DL,
- const TargetLibraryInfo *TLI = nullptr,
- const DominatorTree *DT = nullptr,
- AssumptionCache *AC = nullptr,
- const Instruction *CxtI = nullptr);
-
- /// Given operands for an And, fold the result or return null.
- Value *SimplifyAndInst(Value *LHS, Value *RHS, const DataLayout &DL,
- const TargetLibraryInfo *TLI = nullptr,
- const DominatorTree *DT = nullptr,
- AssumptionCache *AC = nullptr,
- const Instruction *CxtI = nullptr);
-
- /// Given operands for an Or, fold the result or return null.
- Value *SimplifyOrInst(Value *LHS, Value *RHS, const DataLayout &DL,
- const TargetLibraryInfo *TLI = nullptr,
- const DominatorTree *DT = nullptr,
- AssumptionCache *AC = nullptr,
- const Instruction *CxtI = nullptr);
-
- /// Given operands for an Xor, fold the result or return null.
- Value *SimplifyXorInst(Value *LHS, Value *RHS, const DataLayout &DL,
- const TargetLibraryInfo *TLI = nullptr,
- const DominatorTree *DT = nullptr,
- AssumptionCache *AC = nullptr,
- const Instruction *CxtI = nullptr);
-
- /// Given operands for an ICmpInst, fold the result or return null.
- Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
- const DataLayout &DL,
- const TargetLibraryInfo *TLI = nullptr,
- const DominatorTree *DT = nullptr,
- AssumptionCache *AC = nullptr,
- const Instruction *CxtI = nullptr);
-
- /// Given operands for an FCmpInst, fold the result or return null.
- Value *SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
- FastMathFlags FMF, const DataLayout &DL,
- const TargetLibraryInfo *TLI = nullptr,
- const DominatorTree *DT = nullptr,
- AssumptionCache *AC = nullptr,
- const Instruction *CxtI = nullptr);
-
- /// Given operands for a SelectInst, fold the result or return null.
- Value *SimplifySelectInst(Value *Cond, Value *TrueVal, Value *FalseVal,
- const DataLayout &DL,
- const TargetLibraryInfo *TLI = nullptr,
- const DominatorTree *DT = nullptr,
- AssumptionCache *AC = nullptr,
- const Instruction *CxtI = nullptr);
-
- /// Given operands for a GetElementPtrInst, fold the result or return null.
- Value *SimplifyGEPInst(Type *SrcTy, ArrayRef<Value *> Ops,
- const DataLayout &DL,
- const TargetLibraryInfo *TLI = nullptr,
- const DominatorTree *DT = nullptr,
- AssumptionCache *AC = nullptr,
- const Instruction *CxtI = nullptr);
-
- /// Given operands for an InsertValueInst, fold the result or return null.
- Value *SimplifyInsertValueInst(Value *Agg, Value *Val,
- ArrayRef<unsigned> Idxs, const DataLayout &DL,
- const TargetLibraryInfo *TLI = nullptr,
- const DominatorTree *DT = nullptr,
- AssumptionCache *AC = nullptr,
- const Instruction *CxtI = nullptr);
-
- /// Given operands for an ExtractValueInst, fold the result or return null.
- Value *SimplifyExtractValueInst(Value *Agg, ArrayRef<unsigned> Idxs,
- const DataLayout &DL,
- const TargetLibraryInfo *TLI = nullptr,
- const DominatorTree *DT = nullptr,
- AssumptionCache *AC = nullptr,
- const Instruction *CxtI = nullptr);
-
- /// Given operands for an ExtractElementInst, fold the result or return null.
- Value *SimplifyExtractElementInst(Value *Vec, Value *Idx,
- const DataLayout &DL,
+class Function;
+template <typename T, typename... TArgs> class AnalysisManager;
+template <class T> class ArrayRef;
+class AssumptionCache;
+class DominatorTree;
+class Instruction;
+class ImmutableCallSite;
+class DataLayout;
+class FastMathFlags;
+struct LoopStandardAnalysisResults;
+class OptimizationRemarkEmitter;
+class Pass;
+class TargetLibraryInfo;
+class Type;
+class Value;
+
+struct SimplifyQuery {
+ const DataLayout &DL;
+ const TargetLibraryInfo *TLI = nullptr;
+ const DominatorTree *DT = nullptr;
+ AssumptionCache *AC = nullptr;
+ const Instruction *CxtI = nullptr;
+
+ SimplifyQuery(const DataLayout &DL, const Instruction *CXTI = nullptr)
+ : DL(DL), CxtI(CXTI) {}
+
+ SimplifyQuery(const DataLayout &DL, const TargetLibraryInfo *TLI,
+ const DominatorTree *DT = nullptr,
+ AssumptionCache *AC = nullptr,
+ const Instruction *CXTI = nullptr)
+ : DL(DL), TLI(TLI), DT(DT), AC(AC), CxtI(CXTI) {}
+ SimplifyQuery getWithInstruction(Instruction *I) const {
+ SimplifyQuery Copy(*this);
+ Copy.CxtI = I;
+ return Copy;
+ }
+};
+
+// NOTE: the explicit multiple argument versions of these functions are
+// deprecated.
+// Please use the SimplifyQuery versions in new code.
+
+/// Given operands for an Add, fold the result or return null.
+Value *SimplifyAddInst(Value *LHS, Value *RHS, bool isNSW, bool isNUW,
+ const SimplifyQuery &Q);
+
+/// Given operands for a Sub, fold the result or return null.
+Value *SimplifySubInst(Value *LHS, Value *RHS, bool isNSW, bool isNUW,
+ const SimplifyQuery &Q);
+
+/// Given operands for an FAdd, fold the result or return null.
+Value *SimplifyFAddInst(Value *LHS, Value *RHS, FastMathFlags FMF,
+ const SimplifyQuery &Q);
+
+/// Given operands for an FSub, fold the result or return null.
+Value *SimplifyFSubInst(Value *LHS, Value *RHS, FastMathFlags FMF,
+ const SimplifyQuery &Q);
+
+/// Given operands for an FMul, fold the result or return null.
+Value *SimplifyFMulInst(Value *LHS, Value *RHS, FastMathFlags FMF,
+ const SimplifyQuery &Q);
+
+/// Given operands for a Mul, fold the result or return null.
+Value *SimplifyMulInst(Value *LHS, Value *RHS, const SimplifyQuery &Q);
+
+/// Given operands for an SDiv, fold the result or return null.
+Value *SimplifySDivInst(Value *LHS, Value *RHS, const SimplifyQuery &Q);
+
+/// Given operands for a UDiv, fold the result or return null.
+Value *SimplifyUDivInst(Value *LHS, Value *RHS, const SimplifyQuery &Q);
+
+/// Given operands for an FDiv, fold the result or return null.
+Value *SimplifyFDivInst(Value *LHS, Value *RHS, FastMathFlags FMF,
+ const SimplifyQuery &Q);
+
+/// Given operands for an SRem, fold the result or return null.
+Value *SimplifySRemInst(Value *LHS, Value *RHS, const SimplifyQuery &Q);
+
+/// Given operands for a URem, fold the result or return null.
+Value *SimplifyURemInst(Value *LHS, Value *RHS, const SimplifyQuery &Q);
+
+/// Given operands for an FRem, fold the result or return null.
+Value *SimplifyFRemInst(Value *LHS, Value *RHS, FastMathFlags FMF,
+ const SimplifyQuery &Q);
+
+/// Given operands for a Shl, fold the result or return null.
+Value *SimplifyShlInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW,
+ const SimplifyQuery &Q);
+
+/// Given operands for a LShr, fold the result or return null.
+Value *SimplifyLShrInst(Value *Op0, Value *Op1, bool isExact,
+ const SimplifyQuery &Q);
+
+/// Given operands for a AShr, fold the result or return nulll.
+Value *SimplifyAShrInst(Value *Op0, Value *Op1, bool isExact,
+ const SimplifyQuery &Q);
+
+/// Given operands for an And, fold the result or return null.
+Value *SimplifyAndInst(Value *LHS, Value *RHS, const SimplifyQuery &Q);
+
+/// Given operands for an Or, fold the result or return null.
+Value *SimplifyOrInst(Value *LHS, Value *RHS, const SimplifyQuery &Q);
+
+/// Given operands for an Xor, fold the result or return null.
+Value *SimplifyXorInst(Value *LHS, Value *RHS, const SimplifyQuery &Q);
+
+/// Given operands for an ICmpInst, fold the result or return null.
+Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
+ const SimplifyQuery &Q);
+
+/// Given operands for an FCmpInst, fold the result or return null.
+Value *SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
+ FastMathFlags FMF, const SimplifyQuery &Q);
+
+/// Given operands for a SelectInst, fold the result or return null.
+Value *SimplifySelectInst(Value *Cond, Value *TrueVal, Value *FalseVal,
+ const SimplifyQuery &Q);
+
+/// Given operands for a GetElementPtrInst, fold the result or return null.
+Value *SimplifyGEPInst(Type *SrcTy, ArrayRef<Value *> Ops,
+ const SimplifyQuery &Q);
+
+/// Given operands for an InsertValueInst, fold the result or return null.
+Value *SimplifyInsertValueInst(Value *Agg, Value *Val, ArrayRef<unsigned> Idxs,
+ const SimplifyQuery &Q);
+
+/// Given operands for an ExtractValueInst, fold the result or return null.
+Value *SimplifyExtractValueInst(Value *Agg, ArrayRef<unsigned> Idxs,
+ const SimplifyQuery &Q);
+
+/// Given operands for an ExtractElementInst, fold the result or return null.
+Value *SimplifyExtractElementInst(Value *Vec, Value *Idx,
+ const SimplifyQuery &Q);
+
+/// Given operands for a CastInst, fold the result or return null.
+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,
+ Type *RetTy, const SimplifyQuery &Q);
+
+//=== Helper functions for higher up the class hierarchy.
+
+/// Given operands for a CmpInst, fold the result or return null.
+Value *SimplifyCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
+ const SimplifyQuery &Q);
+
+/// Given operands for a BinaryOperator, fold the result or return null.
+Value *SimplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS,
+ const SimplifyQuery &Q);
+
+/// Given operands for an FP BinaryOperator, fold the result or return null.
+/// In contrast to SimplifyBinOp, try to use FastMathFlag when folding the
+/// result. In case we don't need FastMathFlags, simply fall to SimplifyBinOp.
+Value *SimplifyFPBinOp(unsigned Opcode, Value *LHS, Value *RHS,
+ FastMathFlags FMF, const SimplifyQuery &Q);
+
+/// Given a function and iterators over arguments, fold the result or return
+/// null.
+Value *SimplifyCall(ImmutableCallSite CS, Value *V, User::op_iterator ArgBegin,
+ User::op_iterator ArgEnd, const SimplifyQuery &Q);
+
+/// Given a function and set of arguments, fold the result or return null.
+Value *SimplifyCall(ImmutableCallSite CS, Value *V, ArrayRef<Value *> Args,
+ const SimplifyQuery &Q);
+
+/// See if we can compute a simplified version of this instruction. If not,
+/// return null.
+Value *SimplifyInstruction(Instruction *I, const SimplifyQuery &Q,
+ OptimizationRemarkEmitter *ORE = nullptr);
+
+/// Replace all uses of 'I' with 'SimpleV' and simplify the uses recursively.
+///
+/// This first performs a normal RAUW of I with SimpleV. It then recursively
+/// attempts to simplify those users updated by the operation. The 'I'
+/// instruction must not be equal to the simplified value 'SimpleV'.
+///
+/// The function returns true if any simplifications were performed.
+bool replaceAndRecursivelySimplify(Instruction *I, Value *SimpleV,
+ const TargetLibraryInfo *TLI = nullptr,
+ const DominatorTree *DT = nullptr,
+ AssumptionCache *AC = nullptr);
+
+/// Recursively attempt to simplify an instruction.
+///
+/// This routine uses SimplifyInstruction to simplify 'I', and if successful
+/// replaces uses of 'I' with the simplified value. It then recurses on each
+/// of the users impacted. It returns true if any simplifications were
+/// performed.
+bool recursivelySimplifyInstruction(Instruction *I,
const TargetLibraryInfo *TLI = nullptr,
const DominatorTree *DT = nullptr,
- AssumptionCache *AC = nullptr,
- const Instruction *CxtI = nullptr);
-
- /// Given operands for a CastInst, fold the result or return null.
- Value *SimplifyCastInst(unsigned CastOpc, Value *Op, Type *Ty,
- const DataLayout &DL,
- const TargetLibraryInfo *TLI = nullptr,
- const DominatorTree *DT = nullptr,
- AssumptionCache *AC = nullptr,
- const Instruction *CxtI = nullptr);
-
- //=== Helper functions for higher up the class hierarchy.
-
-
- /// Given operands for a CmpInst, fold the result or return null.
- Value *SimplifyCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
- const DataLayout &DL,
- const TargetLibraryInfo *TLI = nullptr,
- const DominatorTree *DT = nullptr,
- AssumptionCache *AC = nullptr,
- const Instruction *CxtI = nullptr);
-
- /// Given operands for a BinaryOperator, fold the result or return null.
- Value *SimplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS,
- const DataLayout &DL,
- const TargetLibraryInfo *TLI = nullptr,
- const DominatorTree *DT = nullptr,
- AssumptionCache *AC = nullptr,
- const Instruction *CxtI = nullptr);
-
- /// Given operands for an FP BinaryOperator, fold the result or return null.
- /// In contrast to SimplifyBinOp, try to use FastMathFlag when folding the
- /// result. In case we don't need FastMathFlags, simply fall to SimplifyBinOp.
- Value *SimplifyFPBinOp(unsigned Opcode, Value *LHS, Value *RHS,
- const FastMathFlags &FMF, const DataLayout &DL,
- const TargetLibraryInfo *TLI = nullptr,
- const DominatorTree *DT = nullptr,
- AssumptionCache *AC = nullptr,
- const Instruction *CxtI = nullptr);
-
- /// Given a function and iterators over arguments, fold the result or return
- /// null.
- Value *SimplifyCall(Value *V, User::op_iterator ArgBegin,
- User::op_iterator ArgEnd, const DataLayout &DL,
- const TargetLibraryInfo *TLI = nullptr,
- const DominatorTree *DT = nullptr,
- AssumptionCache *AC = nullptr,
- const Instruction *CxtI = nullptr);
-
- /// Given a function and set of arguments, fold the result or return null.
- Value *SimplifyCall(Value *V, ArrayRef<Value *> Args, const DataLayout &DL,
- const TargetLibraryInfo *TLI = nullptr,
- const DominatorTree *DT = nullptr,
- AssumptionCache *AC = nullptr,
- const Instruction *CxtI = nullptr);
-
- /// See if we can compute a simplified version of this instruction. If not,
- /// return null.
- Value *SimplifyInstruction(Instruction *I, const DataLayout &DL,
- const TargetLibraryInfo *TLI = nullptr,
- const DominatorTree *DT = nullptr,
- AssumptionCache *AC = nullptr);
-
- /// Replace all uses of 'I' with 'SimpleV' and simplify the uses recursively.
- ///
- /// This first performs a normal RAUW of I with SimpleV. It then recursively
- /// attempts to simplify those users updated by the operation. The 'I'
- /// instruction must not be equal to the simplified value 'SimpleV'.
- ///
- /// The function returns true if any simplifications were performed.
- bool replaceAndRecursivelySimplify(Instruction *I, Value *SimpleV,
- const TargetLibraryInfo *TLI = nullptr,
- const DominatorTree *DT = nullptr,
- AssumptionCache *AC = nullptr);
-
- /// Recursively attempt to simplify an instruction.
- ///
- /// This routine uses SimplifyInstruction to simplify 'I', and if successful
- /// replaces uses of 'I' with the simplified value. It then recurses on each
- /// of the users impacted. It returns true if any simplifications were
- /// performed.
- bool recursivelySimplifyInstruction(Instruction *I,
- const TargetLibraryInfo *TLI = nullptr,
- const DominatorTree *DT = nullptr,
- AssumptionCache *AC = nullptr);
+ AssumptionCache *AC = nullptr);
+
+// These helper functions return a SimplifyQuery structure that contains as
+// many of the optional analysis we use as are currently valid. This is the
+// strongly preferred way of constructing SimplifyQuery in passes.
+const SimplifyQuery getBestSimplifyQuery(Pass &, Function &);
+template <class T, class... TArgs>
+const SimplifyQuery getBestSimplifyQuery(AnalysisManager<T, TArgs...> &,
+ Function &);
+const SimplifyQuery getBestSimplifyQuery(LoopStandardAnalysisResults &,
+ const DataLayout &);
} // end namespace llvm
#endif
diff --git a/contrib/llvm/include/llvm/Analysis/IteratedDominanceFrontier.h b/contrib/llvm/include/llvm/Analysis/IteratedDominanceFrontier.h
index af788c8..edaf4e9 100644
--- a/contrib/llvm/include/llvm/Analysis/IteratedDominanceFrontier.h
+++ b/contrib/llvm/include/llvm/Analysis/IteratedDominanceFrontier.h
@@ -42,11 +42,11 @@ namespace llvm {
/// By default, liveness is not used to prune the IDF computation.
/// The template parameters should be either BasicBlock* or Inverse<BasicBlock
/// *>, depending on if you want the forward or reverse IDF.
-template <class NodeTy>
+template <class NodeTy, bool IsPostDom>
class IDFCalculator {
-
-public:
- IDFCalculator(DominatorTreeBase<BasicBlock> &DT) : DT(DT), useLiveIn(false) {}
+ public:
+ IDFCalculator(DominatorTreeBase<BasicBlock, IsPostDom> &DT)
+ : DT(DT), useLiveIn(false) {}
/// \brief Give the IDF calculator the set of blocks in which the value is
/// defined. This is equivalent to the set of starting blocks it should be
@@ -84,13 +84,12 @@ public:
void calculate(SmallVectorImpl<BasicBlock *> &IDFBlocks);
private:
- DominatorTreeBase<BasicBlock> &DT;
- bool useLiveIn;
- DenseMap<DomTreeNode *, unsigned> DomLevels;
- const SmallPtrSetImpl<BasicBlock *> *LiveInBlocks;
- const SmallPtrSetImpl<BasicBlock *> *DefBlocks;
+ DominatorTreeBase<BasicBlock, IsPostDom> &DT;
+ bool useLiveIn;
+ const SmallPtrSetImpl<BasicBlock *> *LiveInBlocks;
+ const SmallPtrSetImpl<BasicBlock *> *DefBlocks;
};
-typedef IDFCalculator<BasicBlock *> ForwardIDFCalculator;
-typedef IDFCalculator<Inverse<BasicBlock *>> ReverseIDFCalculator;
+typedef IDFCalculator<BasicBlock *, false> ForwardIDFCalculator;
+typedef IDFCalculator<Inverse<BasicBlock *>, true> ReverseIDFCalculator;
}
#endif
diff --git a/contrib/llvm/include/llvm/Analysis/LazyBlockFrequencyInfo.h b/contrib/llvm/include/llvm/Analysis/LazyBlockFrequencyInfo.h
index 5a02b9d..71ce084 100644
--- a/contrib/llvm/include/llvm/Analysis/LazyBlockFrequencyInfo.h
+++ b/contrib/llvm/include/llvm/Analysis/LazyBlockFrequencyInfo.h
@@ -9,7 +9,7 @@
//
// This is an alternative analysis pass to BlockFrequencyInfoWrapperPass. The
// difference is that with this pass the block frequencies are not computed when
-// the analysis pass is executed but rather when the BFI results is explicitly
+// the analysis pass is executed but rather when the BFI result is explicitly
// requested by the analysis client.
//
//===----------------------------------------------------------------------===//
@@ -27,10 +27,58 @@ class BranchProbabilityInfo;
class Function;
class LoopInfo;
+/// Wraps a BFI to allow lazy computation of the block frequencies.
+///
+/// A pass that only conditionally uses BFI can uncondtionally require the
+/// analysis without paying for the overhead if BFI doesn't end up being used.
+template <typename FunctionT, typename BranchProbabilityInfoPassT,
+ typename LoopInfoT, typename BlockFrequencyInfoT>
+class LazyBlockFrequencyInfo {
+public:
+ LazyBlockFrequencyInfo()
+ : Calculated(false), F(nullptr), BPIPass(nullptr), LI(nullptr) {}
+
+ /// Set up the per-function input.
+ void setAnalysis(const FunctionT *F, BranchProbabilityInfoPassT *BPIPass,
+ const LoopInfoT *LI) {
+ this->F = F;
+ this->BPIPass = BPIPass;
+ this->LI = LI;
+ }
+
+ /// Retrieve the BFI with the block frequencies computed.
+ BlockFrequencyInfoT &getCalculated() {
+ if (!Calculated) {
+ assert(F && BPIPass && LI && "call setAnalysis");
+ BFI.calculate(
+ *F, BPIPassTrait<BranchProbabilityInfoPassT>::getBPI(BPIPass), *LI);
+ Calculated = true;
+ }
+ return BFI;
+ }
+
+ const BlockFrequencyInfoT &getCalculated() const {
+ return const_cast<LazyBlockFrequencyInfo *>(this)->getCalculated();
+ }
+
+ void releaseMemory() {
+ BFI.releaseMemory();
+ Calculated = false;
+ setAnalysis(nullptr, nullptr, nullptr);
+ }
+
+private:
+ BlockFrequencyInfoT BFI;
+ bool Calculated;
+ const FunctionT *F;
+ BranchProbabilityInfoPassT *BPIPass;
+ const LoopInfoT *LI;
+};
+
/// \brief This is an alternative analysis pass to
/// BlockFrequencyInfoWrapperPass. The difference is that with this pass the
/// block frequencies are not computed when the analysis pass is executed but
-/// rather when the BFI results is explicitly requested by the analysis client.
+/// rather when the BFI result is explicitly requested by the analysis client.
///
/// There are some additional requirements for any client pass that wants to use
/// the analysis:
@@ -49,54 +97,12 @@ class LoopInfo;
///
/// Note that it is expected that we wouldn't need this functionality for the
/// new PM since with the new PM, analyses are executed on demand.
-class LazyBlockFrequencyInfoPass : public FunctionPass {
-
- /// Wraps a BFI to allow lazy computation of the block frequencies.
- ///
- /// A pass that only conditionally uses BFI can uncondtionally require the
- /// analysis without paying for the overhead if BFI doesn't end up being used.
- class LazyBlockFrequencyInfo {
- public:
- LazyBlockFrequencyInfo()
- : Calculated(false), F(nullptr), BPIPass(nullptr), LI(nullptr) {}
-
- /// Set up the per-function input.
- void setAnalysis(const Function *F, LazyBranchProbabilityInfoPass *BPIPass,
- const LoopInfo *LI) {
- this->F = F;
- this->BPIPass = BPIPass;
- this->LI = LI;
- }
- /// Retrieve the BFI with the block frequencies computed.
- BlockFrequencyInfo &getCalculated() {
- if (!Calculated) {
- assert(F && BPIPass && LI && "call setAnalysis");
- BFI.calculate(*F, BPIPass->getBPI(), *LI);
- Calculated = true;
- }
- return BFI;
- }
-
- const BlockFrequencyInfo &getCalculated() const {
- return const_cast<LazyBlockFrequencyInfo *>(this)->getCalculated();
- }
-
- void releaseMemory() {
- BFI.releaseMemory();
- Calculated = false;
- setAnalysis(nullptr, nullptr, nullptr);
- }
-
- private:
- BlockFrequencyInfo BFI;
- bool Calculated;
- const Function *F;
- LazyBranchProbabilityInfoPass *BPIPass;
- const LoopInfo *LI;
- };
-
- LazyBlockFrequencyInfo LBFI;
+class LazyBlockFrequencyInfoPass : public FunctionPass {
+private:
+ LazyBlockFrequencyInfo<Function, LazyBranchProbabilityInfoPass, LoopInfo,
+ BlockFrequencyInfo>
+ LBFI;
public:
static char ID;
diff --git a/contrib/llvm/include/llvm/Analysis/LazyBranchProbabilityInfo.h b/contrib/llvm/include/llvm/Analysis/LazyBranchProbabilityInfo.h
index c76fa1e..e1d404b 100644
--- a/contrib/llvm/include/llvm/Analysis/LazyBranchProbabilityInfo.h
+++ b/contrib/llvm/include/llvm/Analysis/LazyBranchProbabilityInfo.h
@@ -24,6 +24,7 @@ namespace llvm {
class AnalysisUsage;
class Function;
class LoopInfo;
+class TargetLibraryInfo;
/// \brief This is an alternative analysis pass to
/// BranchProbabilityInfoWrapperPass. The difference is that with this pass the
@@ -55,14 +56,15 @@ class LazyBranchProbabilityInfoPass : public FunctionPass {
/// analysis without paying for the overhead if BPI doesn't end up being used.
class LazyBranchProbabilityInfo {
public:
- LazyBranchProbabilityInfo(const Function *F, const LoopInfo *LI)
- : Calculated(false), F(F), LI(LI) {}
+ LazyBranchProbabilityInfo(const Function *F, const LoopInfo *LI,
+ const TargetLibraryInfo *TLI)
+ : Calculated(false), F(F), LI(LI), TLI(TLI) {}
/// Retrieve the BPI with the branch probabilities computed.
BranchProbabilityInfo &getCalculated() {
if (!Calculated) {
assert(F && LI && "call setAnalysis");
- BPI.calculate(*F, *LI);
+ BPI.calculate(*F, *LI, TLI);
Calculated = true;
}
return BPI;
@@ -77,6 +79,7 @@ class LazyBranchProbabilityInfoPass : public FunctionPass {
bool Calculated;
const Function *F;
const LoopInfo *LI;
+ const TargetLibraryInfo *TLI;
};
std::unique_ptr<LazyBranchProbabilityInfo> LBPI;
@@ -105,5 +108,17 @@ public:
/// \brief Helper for client passes to initialize dependent passes for LBPI.
void initializeLazyBPIPassPass(PassRegistry &Registry);
+
+/// \brief Simple trait class that provides a mapping between BPI passes and the
+/// corresponding BPInfo.
+template <typename PassT> struct BPIPassTrait {
+ static PassT &getBPI(PassT *P) { return *P; }
+};
+
+template <> struct BPIPassTrait<LazyBranchProbabilityInfoPass> {
+ static BranchProbabilityInfo &getBPI(LazyBranchProbabilityInfoPass *P) {
+ return P->getBPI();
+ }
+};
}
#endif
diff --git a/contrib/llvm/include/llvm/Analysis/LazyCallGraph.h b/contrib/llvm/include/llvm/Analysis/LazyCallGraph.h
index bca0aeb..a025f22 100644
--- a/contrib/llvm/include/llvm/Analysis/LazyCallGraph.h
+++ b/contrib/llvm/include/llvm/Analysis/LazyCallGraph.h
@@ -43,6 +43,7 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/iterator.h"
#include "llvm/ADT/iterator_range.h"
+#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Function.h"
@@ -106,6 +107,7 @@ class raw_ostream;
class LazyCallGraph {
public:
class Node;
+ class EdgeSequence;
class SCC;
class RefSCC;
class edge_iterator;
@@ -121,16 +123,6 @@ public:
/// inherently reference edges, and so the reference graph forms a superset
/// of the formal call graph.
///
- /// Furthermore, edges also may point to raw \c Function objects when those
- /// functions have not been scanned and incorporated into the graph (yet).
- /// This is one of the primary ways in which the graph can be lazy. When
- /// functions are scanned and fully incorporated into the graph, all of the
- /// edges referencing them are updated to point to the graph \c Node objects
- /// instead of to the raw \c Function objects. This class even provides
- /// methods to trigger this scan on-demand by attempting to get the target
- /// node of the graph and providing a reference back to the graph in order to
- /// lazily build it if necessary.
- ///
/// All of these forms of edges are fundamentally represented as outgoing
/// edges. The edges are stored in the source node and point at the target
/// node. This allows the edge structure itself to be a very compact data
@@ -141,7 +133,6 @@ public:
enum Kind : bool { Ref = false, Call = true };
Edge();
- explicit Edge(Function &F, Kind K);
explicit Edge(Node &N, Kind K);
/// Test whether the edge is null.
@@ -158,197 +149,251 @@ public:
/// This requires that the edge is not null.
bool isCall() const;
- /// Get the function referenced by this edge.
- ///
- /// This requires that the edge is not null, but will succeed whether we
- /// have built a graph node for the function yet or not.
- Function &getFunction() const;
-
- /// Get the call graph node referenced by this edge if one exists.
+ /// Get the call graph node referenced by this edge.
///
- /// This requires that the edge is not null. If we have built a graph node
- /// for the function this edge points to, this will return that node,
- /// otherwise it will return null.
- Node *getNode() const;
+ /// This requires that the edge is not null.
+ Node &getNode() const;
- /// Get the call graph node for this edge, building it if necessary.
+ /// Get the function referenced by this edge.
///
- /// This requires that the edge is not null. If we have not yet built
- /// a graph node for the function this edge points to, this will first ask
- /// the graph to build that node, inserting it into all the relevant
- /// structures.
- Node &getNode(LazyCallGraph &G);
+ /// This requires that the edge is not null.
+ Function &getFunction() const;
private:
- friend class LazyCallGraph::Node;
+ friend class LazyCallGraph::EdgeSequence;
friend class LazyCallGraph::RefSCC;
- PointerIntPair<PointerUnion<Function *, Node *>, 1, Kind> Value;
+ PointerIntPair<Node *, 1, Kind> Value;
void setKind(Kind K) { Value.setInt(K); }
};
- typedef SmallVector<Edge, 4> EdgeVectorT;
- typedef SmallVectorImpl<Edge> EdgeVectorImplT;
-
- /// A node in the call graph.
+ /// The edge sequence object.
///
- /// This represents a single node. It's primary roles are to cache the list of
- /// callees, de-duplicate and provide fast testing of whether a function is
- /// a callee, and facilitate iteration of child nodes in the graph.
- class Node {
+ /// This typically exists entirely within the node but is exposed as
+ /// a separate type because a node doesn't initially have edges. An explicit
+ /// population step is required to produce this sequence at first and it is
+ /// then cached in the node. It is also used to represent edges entering the
+ /// graph from outside the module to model the graph's roots.
+ ///
+ /// The sequence itself both iterable and indexable. The indexes remain
+ /// stable even as the sequence mutates (including removal).
+ class EdgeSequence {
friend class LazyCallGraph;
- friend class LazyCallGraph::SCC;
+ friend class LazyCallGraph::Node;
friend class LazyCallGraph::RefSCC;
- LazyCallGraph *G;
- Function &F;
+ typedef SmallVector<Edge, 4> VectorT;
+ typedef SmallVectorImpl<Edge> VectorImplT;
- // We provide for the DFS numbering and Tarjan walk lowlink numbers to be
- // stored directly within the node. These are both '-1' when nodes are part
- // of an SCC (or RefSCC), or '0' when not yet reached in a DFS walk.
- int DFSNumber;
- int LowLink;
+ public:
+ /// An iterator used for the edges to both entry nodes and child nodes.
+ class iterator
+ : public iterator_adaptor_base<iterator, VectorImplT::iterator,
+ std::forward_iterator_tag> {
+ friend class LazyCallGraph;
+ friend class LazyCallGraph::Node;
+
+ VectorImplT::iterator E;
+
+ // Build the iterator for a specific position in the edge list.
+ iterator(VectorImplT::iterator BaseI, VectorImplT::iterator E)
+ : iterator_adaptor_base(BaseI), E(E) {
+ while (I != E && !*I)
+ ++I;
+ }
- mutable EdgeVectorT Edges;
- DenseMap<Function *, int> EdgeIndexMap;
+ public:
+ iterator() {}
- /// Basic constructor implements the scanning of F into Edges and
- /// EdgeIndexMap.
- Node(LazyCallGraph &G, Function &F);
+ using iterator_adaptor_base::operator++;
+ iterator &operator++() {
+ do {
+ ++I;
+ } while (I != E && !*I);
+ return *this;
+ }
+ };
- /// Internal helper to insert an edge to a function.
- void insertEdgeInternal(Function &ChildF, Edge::Kind EK);
+ /// An iterator over specifically call edges.
+ ///
+ /// This has the same iteration properties as the \c iterator, but
+ /// restricts itself to edges which represent actual calls.
+ class call_iterator
+ : public iterator_adaptor_base<call_iterator, VectorImplT::iterator,
+ std::forward_iterator_tag> {
+ friend class LazyCallGraph;
+ friend class LazyCallGraph::Node;
+
+ VectorImplT::iterator E;
+
+ /// Advance the iterator to the next valid, call edge.
+ void advanceToNextEdge() {
+ while (I != E && (!*I || !I->isCall()))
+ ++I;
+ }
- /// Internal helper to insert an edge to a node.
- void insertEdgeInternal(Node &ChildN, Edge::Kind EK);
+ // Build the iterator for a specific position in the edge list.
+ call_iterator(VectorImplT::iterator BaseI, VectorImplT::iterator E)
+ : iterator_adaptor_base(BaseI), E(E) {
+ advanceToNextEdge();
+ }
- /// Internal helper to change an edge kind.
- void setEdgeKind(Function &ChildF, Edge::Kind EK);
+ public:
+ call_iterator() {}
- /// Internal helper to remove the edge to the given function.
- void removeEdgeInternal(Function &ChildF);
+ using iterator_adaptor_base::operator++;
+ call_iterator &operator++() {
+ ++I;
+ advanceToNextEdge();
+ return *this;
+ }
+ };
- void clear() {
- Edges.clear();
- EdgeIndexMap.clear();
- }
+ iterator begin() { return iterator(Edges.begin(), Edges.end()); }
+ iterator end() { return iterator(Edges.end(), Edges.end()); }
- /// Print the name of this node's function.
- friend raw_ostream &operator<<(raw_ostream &OS, const Node &N) {
- return OS << N.F.getName();
+ Edge &operator[](int i) { return Edges[i]; }
+ Edge &operator[](Node &N) {
+ assert(EdgeIndexMap.find(&N) != EdgeIndexMap.end() && "No such edge!");
+ return Edges[EdgeIndexMap.find(&N)->second];
}
-
- /// Dump the name of this node's function to stderr.
- void dump() const;
-
- public:
- LazyCallGraph &getGraph() const { return *G; }
-
- Function &getFunction() const { return F; }
-
- edge_iterator begin() const {
- return edge_iterator(Edges.begin(), Edges.end());
+ Edge *lookup(Node &N) {
+ auto EI = EdgeIndexMap.find(&N);
+ return EI != EdgeIndexMap.end() ? &Edges[EI->second] : nullptr;
}
- edge_iterator end() const { return edge_iterator(Edges.end(), Edges.end()); }
- const Edge &operator[](int i) const { return Edges[i]; }
- const Edge &operator[](Function &F) const {
- assert(EdgeIndexMap.find(&F) != EdgeIndexMap.end() && "No such edge!");
- return Edges[EdgeIndexMap.find(&F)->second];
+ call_iterator call_begin() {
+ return call_iterator(Edges.begin(), Edges.end());
}
- const Edge &operator[](Node &N) const { return (*this)[N.getFunction()]; }
+ call_iterator call_end() { return call_iterator(Edges.end(), Edges.end()); }
- const Edge *lookup(Function &F) const {
- auto EI = EdgeIndexMap.find(&F);
- return EI != EdgeIndexMap.end() ? &Edges[EI->second] : nullptr;
+ iterator_range<call_iterator> calls() {
+ return make_range(call_begin(), call_end());
}
- call_edge_iterator call_begin() const {
- return call_edge_iterator(Edges.begin(), Edges.end());
- }
- call_edge_iterator call_end() const {
- return call_edge_iterator(Edges.end(), Edges.end());
- }
+ bool empty() {
+ for (auto &E : Edges)
+ if (E)
+ return false;
- iterator_range<call_edge_iterator> calls() const {
- return make_range(call_begin(), call_end());
+ return true;
}
- /// Equality is defined as address equality.
- bool operator==(const Node &N) const { return this == &N; }
- bool operator!=(const Node &N) const { return !operator==(N); }
- };
+ private:
+ VectorT Edges;
+ DenseMap<Node *, int> EdgeIndexMap;
- /// A lazy iterator used for both the entry nodes and child nodes.
- ///
- /// When this iterator is dereferenced, if not yet available, a function will
- /// be scanned for "calls" or uses of functions and its child information
- /// will be constructed. All of these results are accumulated and cached in
- /// the graph.
- class edge_iterator
- : public iterator_adaptor_base<edge_iterator, EdgeVectorImplT::iterator,
- std::forward_iterator_tag> {
- friend class LazyCallGraph;
- friend class LazyCallGraph::Node;
+ EdgeSequence() = default;
- EdgeVectorImplT::iterator E;
+ /// Internal helper to insert an edge to a node.
+ void insertEdgeInternal(Node &ChildN, Edge::Kind EK);
- // Build the iterator for a specific position in the edge list.
- edge_iterator(EdgeVectorImplT::iterator BaseI,
- EdgeVectorImplT::iterator E)
- : iterator_adaptor_base(BaseI), E(E) {
- while (I != E && !*I)
- ++I;
- }
+ /// Internal helper to change an edge kind.
+ void setEdgeKind(Node &ChildN, Edge::Kind EK);
- public:
- edge_iterator() {}
+ /// Internal helper to remove the edge to the given function.
+ bool removeEdgeInternal(Node &ChildN);
- using iterator_adaptor_base::operator++;
- edge_iterator &operator++() {
- do {
- ++I;
- } while (I != E && !*I);
- return *this;
- }
+ /// Internal helper to replace an edge key with a new one.
+ ///
+ /// This should be used when the function for a particular node in the
+ /// graph gets replaced and we are updating all of the edges to that node
+ /// to use the new function as the key.
+ void replaceEdgeKey(Function &OldTarget, Function &NewTarget);
};
- /// A lazy iterator over specifically call edges.
+ /// A node in the call graph.
///
- /// This has the same iteration properties as the \c edge_iterator, but
- /// restricts itself to edges which represent actual calls.
- class call_edge_iterator
- : public iterator_adaptor_base<call_edge_iterator,
- EdgeVectorImplT::iterator,
- std::forward_iterator_tag> {
+ /// This represents a single node. It's primary roles are to cache the list of
+ /// callees, de-duplicate and provide fast testing of whether a function is
+ /// a callee, and facilitate iteration of child nodes in the graph.
+ ///
+ /// The node works much like an optional in order to lazily populate the
+ /// edges of each node. Until populated, there are no edges. Once populated,
+ /// you can access the edges by dereferencing the node or using the `->`
+ /// operator as if the node was an `Optional<EdgeSequence>`.
+ class Node {
friend class LazyCallGraph;
- friend class LazyCallGraph::Node;
+ friend class LazyCallGraph::RefSCC;
- EdgeVectorImplT::iterator E;
+ public:
+ LazyCallGraph &getGraph() const { return *G; }
- /// Advance the iterator to the next valid, call edge.
- void advanceToNextEdge() {
- while (I != E && (!*I || !I->isCall()))
- ++I;
+ Function &getFunction() const { return *F; }
+
+ StringRef getName() const { return F->getName(); }
+
+ /// Equality is defined as address equality.
+ bool operator==(const Node &N) const { return this == &N; }
+ bool operator!=(const Node &N) const { return !operator==(N); }
+
+ /// Tests whether the node has been populated with edges.
+ operator bool() const { return Edges.hasValue(); }
+
+ // We allow accessing the edges by dereferencing or using the arrow
+ // operator, essentially wrapping the internal optional.
+ EdgeSequence &operator*() const {
+ // Rip const off because the node itself isn't changing here.
+ return const_cast<EdgeSequence &>(*Edges);
}
+ EdgeSequence *operator->() const { return &**this; }
- // Build the iterator for a specific position in the edge list.
- call_edge_iterator(EdgeVectorImplT::iterator BaseI,
- EdgeVectorImplT::iterator E)
- : iterator_adaptor_base(BaseI), E(E) {
- advanceToNextEdge();
+ /// Populate the edges of this node if necessary.
+ ///
+ /// The first time this is called it will populate the edges for this node
+ /// in the graph. It does this by scanning the underlying function, so once
+ /// this is done, any changes to that function must be explicitly reflected
+ /// in updates to the graph.
+ ///
+ /// \returns the populated \c EdgeSequence to simplify walking it.
+ ///
+ /// This will not update or re-scan anything if called repeatedly. Instead,
+ /// the edge sequence is cached and returned immediately on subsequent
+ /// calls.
+ EdgeSequence &populate() {
+ if (Edges)
+ return *Edges;
+
+ return populateSlow();
}
- public:
- call_edge_iterator() {}
+ private:
+ LazyCallGraph *G;
+ Function *F;
- using iterator_adaptor_base::operator++;
- call_edge_iterator &operator++() {
- ++I;
- advanceToNextEdge();
- return *this;
+ // We provide for the DFS numbering and Tarjan walk lowlink numbers to be
+ // stored directly within the node. These are both '-1' when nodes are part
+ // of an SCC (or RefSCC), or '0' when not yet reached in a DFS walk.
+ int DFSNumber;
+ int LowLink;
+
+ Optional<EdgeSequence> Edges;
+
+ /// Basic constructor implements the scanning of F into Edges and
+ /// EdgeIndexMap.
+ Node(LazyCallGraph &G, Function &F)
+ : G(&G), F(&F), DFSNumber(0), LowLink(0) {}
+
+ /// Implementation of the scan when populating.
+ EdgeSequence &populateSlow();
+
+ /// Internal helper to directly replace the function with a new one.
+ ///
+ /// This is used to facilitate tranfsormations which need to replace the
+ /// formal Function object but directly move the body and users from one to
+ /// the other.
+ void replaceFunction(Function &NewF);
+
+ void clear() { Edges.reset(); }
+
+ /// Print the name of this node's function.
+ friend raw_ostream &operator<<(raw_ostream &OS, const Node &N) {
+ return OS << N.F->getName();
}
+
+ /// Dump the name of this node's function to stderr.
+ void dump() const;
};
/// An SCC of the call graph.
@@ -608,17 +653,23 @@ public:
/// Make an existing internal ref edge into a call edge.
///
/// This may form a larger cycle and thus collapse SCCs into TargetN's SCC.
- /// If that happens, the deleted SCC pointers are returned. These SCCs are
- /// not in a valid state any longer but the pointers will remain valid
- /// until destruction of the parent graph instance for the purpose of
- /// clearing cached information.
+ /// If that happens, the optional callback \p MergedCB will be invoked (if
+ /// provided) on the SCCs being merged away prior to actually performing
+ /// the merge. Note that this will never include the target SCC as that
+ /// will be the SCC functions are merged into to resolve the cycle. Once
+ /// this function returns, these merged SCCs are not in a valid state but
+ /// the pointers will remain valid until destruction of the parent graph
+ /// instance for the purpose of clearing cached information. This function
+ /// also returns 'true' if a cycle was formed and some SCCs merged away as
+ /// a convenience.
///
/// After this operation, both SourceN's SCC and TargetN's SCC may move
/// position within this RefSCC's postorder list. Any SCCs merged are
/// merged into the TargetN's SCC in order to preserve reachability analyses
/// which took place on that SCC.
- SmallVector<SCC *, 1> switchInternalEdgeToCall(Node &SourceN,
- Node &TargetN);
+ bool switchInternalEdgeToCall(
+ Node &SourceN, Node &TargetN,
+ function_ref<void(ArrayRef<SCC *> MergedSCCs)> MergeCB = {});
/// Make an existing internal call edge between separate SCCs into a ref
/// edge.
@@ -789,19 +840,26 @@ public:
/// already existing edges.
void insertTrivialRefEdge(Node &SourceN, Node &TargetN);
+ /// Directly replace a node's function with a new function.
+ ///
+ /// This should be used when moving the body and users of a function to
+ /// a new formal function object but not otherwise changing the call graph
+ /// structure in any way.
+ ///
+ /// It requires that the old function in the provided node have zero uses
+ /// and the new function must have calls and references to it establishing
+ /// an equivalent graph.
+ void replaceNodeFunction(Node &N, Function &NewF);
+
///@}
};
/// A post-order depth-first RefSCC iterator over the call graph.
///
- /// This iterator triggers the Tarjan DFS-based formation of the RefSCC (and
- /// SCC) DAG for the call graph, walking it lazily in depth-first post-order.
- /// That is, it always visits RefSCCs for the target of a reference edge
- /// prior to visiting the RefSCC for a source of the edge (when they are in
- /// different RefSCCs).
- ///
- /// When forming each RefSCC, the call edges within it are used to form SCCs
- /// within it, so iterating this also controls the lazy formation of SCCs.
+ /// This iterator walks the cached post-order sequence of RefSCCs. However,
+ /// it trades stability for flexibility. It is restricted to a forward
+ /// iterator but will survive mutations which insert new RefSCCs and continue
+ /// to point to the same RefSCC even if it moves in the post-order sequence.
class postorder_ref_scc_iterator
: public iterator_facade_base<postorder_ref_scc_iterator,
std::forward_iterator_tag, RefSCC> {
@@ -825,12 +883,9 @@ public:
/// populating it if necessary.
static RefSCC *getRC(LazyCallGraph &G, int Index) {
if (Index == (int)G.PostOrderRefSCCs.size())
- if (!G.buildNextRefSCCInPostOrder())
- // We're at the end.
- return nullptr;
+ // We're at the end.
+ return nullptr;
- assert(Index < (int)G.PostOrderRefSCCs.size() &&
- "Built the next post-order RefSCC without growing list!");
return G.PostOrderRefSCCs[Index];
}
@@ -854,22 +909,26 @@ public:
/// This sets up the graph and computes all of the entry points of the graph.
/// No function definitions are scanned until their nodes in the graph are
/// requested during traversal.
- LazyCallGraph(Module &M);
+ LazyCallGraph(Module &M, TargetLibraryInfo &TLI);
LazyCallGraph(LazyCallGraph &&G);
LazyCallGraph &operator=(LazyCallGraph &&RHS);
- edge_iterator begin() {
- return edge_iterator(EntryEdges.begin(), EntryEdges.end());
- }
- edge_iterator end() {
- return edge_iterator(EntryEdges.end(), EntryEdges.end());
- }
+ EdgeSequence::iterator begin() { return EntryEdges.begin(); }
+ EdgeSequence::iterator end() { return EntryEdges.end(); }
+
+ void buildRefSCCs();
postorder_ref_scc_iterator postorder_ref_scc_begin() {
+ if (!EntryEdges.empty())
+ assert(!PostOrderRefSCCs.empty() &&
+ "Must form RefSCCs before iterating them!");
return postorder_ref_scc_iterator(*this);
}
postorder_ref_scc_iterator postorder_ref_scc_end() {
+ if (!EntryEdges.empty())
+ assert(!PostOrderRefSCCs.empty() &&
+ "Must form RefSCCs before iterating them!");
return postorder_ref_scc_iterator(*this,
postorder_ref_scc_iterator::IsAtEndT());
}
@@ -908,6 +967,22 @@ public:
return insertInto(F, N);
}
+ /// Get the sequence of known and defined library functions.
+ ///
+ /// These functions, because they are known to LLVM, can have calls
+ /// introduced out of thin air from arbitrary IR.
+ ArrayRef<Function *> getLibFunctions() const {
+ return LibFunctions.getArrayRef();
+ }
+
+ /// Test whether a function is a known and defined library function tracked by
+ /// the call graph.
+ ///
+ /// Because these functions are known to LLVM they are specially modeled in
+ /// the call graph and even when all IR-level references have been removed
+ /// remain active and reachable.
+ bool isLibFunction(Function &F) const { return LibFunctions.count(&F); }
+
///@{
/// \name Pre-SCC Mutation API
///
@@ -920,19 +995,19 @@ public:
/// below.
/// Update the call graph after inserting a new edge.
- void insertEdge(Node &Caller, Function &Callee, Edge::Kind EK);
+ void insertEdge(Node &SourceN, Node &TargetN, Edge::Kind EK);
/// Update the call graph after inserting a new edge.
- void insertEdge(Function &Caller, Function &Callee, Edge::Kind EK) {
- return insertEdge(get(Caller), Callee, EK);
+ void insertEdge(Function &Source, Function &Target, Edge::Kind EK) {
+ return insertEdge(get(Source), get(Target), EK);
}
/// Update the call graph after deleting an edge.
- void removeEdge(Node &Caller, Function &Callee);
+ void removeEdge(Node &SourceN, Node &TargetN);
/// Update the call graph after deleting an edge.
- void removeEdge(Function &Caller, Function &Callee) {
- return removeEdge(get(Caller), Callee);
+ void removeEdge(Function &Source, Function &Target) {
+ return removeEdge(get(Source), get(Target));
}
///@}
@@ -1013,14 +1088,11 @@ private:
/// Maps function->node for fast lookup.
DenseMap<const Function *, Node *> NodeMap;
- /// The entry nodes to the graph.
+ /// The entry edges into the graph.
///
- /// These nodes are reachable through "external" means. Put another way, they
+ /// These edges are from "external" sources. Put another way, they
/// escape at the module scope.
- EdgeVectorT EntryEdges;
-
- /// Map of the entry nodes in the graph to their indices in \c EntryEdges.
- DenseMap<Function *, int> EntryIndexMap;
+ EdgeSequence EntryEdges;
/// Allocator that holds all the call graph SCCs.
SpecificBumpPtrAllocator<SCC> SCCBPA;
@@ -1045,17 +1117,10 @@ private:
/// These are all of the RefSCCs which have no children.
SmallVector<RefSCC *, 4> LeafRefSCCs;
- /// Stack of nodes in the DFS walk.
- SmallVector<std::pair<Node *, edge_iterator>, 4> DFSStack;
-
- /// Set of entry nodes not-yet-processed into RefSCCs.
- SmallVector<Function *, 4> RefSCCEntryNodes;
-
- /// Stack of nodes the DFS has walked but not yet put into a RefSCC.
- SmallVector<Node *, 4> PendingRefSCCStack;
-
- /// Counter for the next DFS number to assign.
- int NextDFSNumber;
+ /// Defined functions that are also known library functions which the
+ /// optimizer can reason about and therefore might introduce calls to out of
+ /// thin air.
+ SmallSetVector<Function *, 4> LibFunctions;
/// Helper to insert a new function, with an already looked-up entry in
/// the NodeMap.
@@ -1078,6 +1143,23 @@ private:
return new (RefSCCBPA.Allocate()) RefSCC(std::forward<Ts>(Args)...);
}
+ /// Common logic for building SCCs from a sequence of roots.
+ ///
+ /// This is a very generic implementation of the depth-first walk and SCC
+ /// formation algorithm. It uses a generic sequence of roots and generic
+ /// callbacks for each step. This is designed to be used to implement both
+ /// the RefSCC formation and SCC formation with shared logic.
+ ///
+ /// Currently this is a relatively naive implementation of Tarjan's DFS
+ /// algorithm to form the SCCs.
+ ///
+ /// FIXME: We should consider newer variants such as Nuutila.
+ template <typename RootsT, typename GetBeginT, typename GetEndT,
+ typename GetNodeT, typename FormSCCCallbackT>
+ static void buildGenericSCCs(RootsT &&Roots, GetBeginT &&GetBegin,
+ GetEndT &&GetEnd, GetNodeT &&GetNode,
+ FormSCCCallbackT &&FormSCC);
+
/// Build the SCCs for a RefSCC out of a list of nodes.
void buildSCCs(RefSCC &RC, node_stack_range Nodes);
@@ -1098,22 +1180,12 @@ private:
"Index does not point back at RC!");
return IndexIt->second;
}
-
- /// Builds the next node in the post-order RefSCC walk of the call graph and
- /// appends it to the \c PostOrderRefSCCs vector.
- ///
- /// Returns true if a new RefSCC was successfully constructed, and false if
- /// there are no more RefSCCs to build in the graph.
- bool buildNextRefSCCInPostOrder();
};
inline LazyCallGraph::Edge::Edge() : Value() {}
-inline LazyCallGraph::Edge::Edge(Function &F, Kind K) : Value(&F, K) {}
inline LazyCallGraph::Edge::Edge(Node &N, Kind K) : Value(&N, K) {}
-inline LazyCallGraph::Edge::operator bool() const {
- return !Value.getPointer().isNull();
-}
+inline LazyCallGraph::Edge::operator bool() const { return Value.getPointer(); }
inline LazyCallGraph::Edge::Kind LazyCallGraph::Edge::getKind() const {
assert(*this && "Queried a null edge!");
@@ -1125,51 +1197,32 @@ inline bool LazyCallGraph::Edge::isCall() const {
return getKind() == Call;
}
-inline Function &LazyCallGraph::Edge::getFunction() const {
+inline LazyCallGraph::Node &LazyCallGraph::Edge::getNode() const {
assert(*this && "Queried a null edge!");
- auto P = Value.getPointer();
- if (auto *F = P.dyn_cast<Function *>())
- return *F;
-
- return P.get<Node *>()->getFunction();
+ return *Value.getPointer();
}
-inline LazyCallGraph::Node *LazyCallGraph::Edge::getNode() const {
- assert(*this && "Queried a null edge!");
- auto P = Value.getPointer();
- if (auto *N = P.dyn_cast<Node *>())
- return N;
-
- return nullptr;
-}
-
-inline LazyCallGraph::Node &LazyCallGraph::Edge::getNode(LazyCallGraph &G) {
+inline Function &LazyCallGraph::Edge::getFunction() const {
assert(*this && "Queried a null edge!");
- auto P = Value.getPointer();
- if (auto *N = P.dyn_cast<Node *>())
- return *N;
-
- Node &N = G.get(*P.get<Function *>());
- Value.setPointer(&N);
- return N;
+ return getNode().getFunction();
}
// Provide GraphTraits specializations for call graphs.
template <> struct GraphTraits<LazyCallGraph::Node *> {
typedef LazyCallGraph::Node *NodeRef;
- typedef LazyCallGraph::edge_iterator ChildIteratorType;
+ typedef LazyCallGraph::EdgeSequence::iterator ChildIteratorType;
static NodeRef getEntryNode(NodeRef N) { return N; }
- static ChildIteratorType child_begin(NodeRef N) { return N->begin(); }
- static ChildIteratorType child_end(NodeRef N) { return N->end(); }
+ static ChildIteratorType child_begin(NodeRef N) { return (*N)->begin(); }
+ static ChildIteratorType child_end(NodeRef N) { return (*N)->end(); }
};
template <> struct GraphTraits<LazyCallGraph *> {
typedef LazyCallGraph::Node *NodeRef;
- typedef LazyCallGraph::edge_iterator ChildIteratorType;
+ typedef LazyCallGraph::EdgeSequence::iterator ChildIteratorType;
static NodeRef getEntryNode(NodeRef N) { return N; }
- static ChildIteratorType child_begin(NodeRef N) { return N->begin(); }
- static ChildIteratorType child_end(NodeRef N) { return N->end(); }
+ static ChildIteratorType child_begin(NodeRef N) { return (*N)->begin(); }
+ static ChildIteratorType child_end(NodeRef N) { return (*N)->end(); }
};
/// An analysis pass which computes the call graph for a module.
@@ -1185,8 +1238,8 @@ public:
///
/// This just builds the set of entry points to the call graph. The rest is
/// built lazily as it is walked.
- LazyCallGraph run(Module &M, ModuleAnalysisManager &) {
- return LazyCallGraph(M);
+ LazyCallGraph run(Module &M, ModuleAnalysisManager &AM) {
+ return LazyCallGraph(M, AM.getResult<TargetLibraryAnalysis>(M));
}
};
diff --git a/contrib/llvm/include/llvm/Analysis/LazyValueInfo.h b/contrib/llvm/include/llvm/Analysis/LazyValueInfo.h
index 6107910..787c88c 100644
--- a/contrib/llvm/include/llvm/Analysis/LazyValueInfo.h
+++ b/contrib/llvm/include/llvm/Analysis/LazyValueInfo.h
@@ -32,6 +32,7 @@ namespace llvm {
class LazyValueInfo {
friend class LazyValueInfoWrapperPass;
AssumptionCache *AC = nullptr;
+ const DataLayout *DL = nullptr;
class TargetLibraryInfo *TLI = nullptr;
DominatorTree *DT = nullptr;
void *PImpl = nullptr;
@@ -40,16 +41,17 @@ class LazyValueInfo {
public:
~LazyValueInfo();
LazyValueInfo() {}
- LazyValueInfo(AssumptionCache *AC_, TargetLibraryInfo *TLI_,
+ LazyValueInfo(AssumptionCache *AC_, const DataLayout *DL_, TargetLibraryInfo *TLI_,
DominatorTree *DT_)
- : AC(AC_), TLI(TLI_), DT(DT_) {}
+ : AC(AC_), DL(DL_), TLI(TLI_), DT(DT_) {}
LazyValueInfo(LazyValueInfo &&Arg)
- : AC(Arg.AC), TLI(Arg.TLI), DT(Arg.DT), PImpl(Arg.PImpl) {
+ : AC(Arg.AC), DL(Arg.DL), TLI(Arg.TLI), DT(Arg.DT), PImpl(Arg.PImpl) {
Arg.PImpl = nullptr;
}
LazyValueInfo &operator=(LazyValueInfo &&Arg) {
releaseMemory();
AC = Arg.AC;
+ DL = Arg.DL;
TLI = Arg.TLI;
DT = Arg.DT;
PImpl = Arg.PImpl;
@@ -91,6 +93,13 @@ public:
Constant *getConstantOnEdge(Value *V, BasicBlock *FromBB, BasicBlock *ToBB,
Instruction *CxtI = nullptr);
+ /// Return the ConstantRage constraint that is known to hold for the
+ /// specified value on the specified edge. This may be only be called
+ /// on integer-typed Values.
+ ConstantRange getConstantRangeOnEdge(Value *V, BasicBlock *FromBB,
+ BasicBlock *ToBB,
+ Instruction *CxtI = nullptr);
+
/// Inform the analysis cache that we have threaded an edge from
/// PredBB to OldSucc to be from PredBB to NewSucc instead.
void threadEdge(BasicBlock *PredBB, BasicBlock *OldSucc, BasicBlock *NewSucc);
@@ -98,8 +107,18 @@ public:
/// Inform the analysis cache that we have erased a block.
void eraseBlock(BasicBlock *BB);
+ /// 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.
+ void printLVI(Function &F, DominatorTree &DTree, raw_ostream &OS);
+
// For old PM pass. Delete once LazyValueInfoWrapperPass is gone.
void releaseMemory();
+
+ /// Handle invalidation events in the new pass manager.
+ bool invalidate(Function &F, const PreservedAnalyses &PA,
+ FunctionAnalysisManager::Invalidator &Inv);
};
/// \brief Analysis to compute lazy value information.
diff --git a/contrib/llvm/include/llvm/Analysis/Loads.h b/contrib/llvm/include/llvm/Analysis/Loads.h
index e167f36..f110c28 100644
--- a/contrib/llvm/include/llvm/Analysis/Loads.h
+++ b/contrib/llvm/include/llvm/Analysis/Loads.h
@@ -39,6 +39,15 @@ bool isDereferenceableAndAlignedPointer(const Value *V, unsigned Align,
const Instruction *CtxI = nullptr,
const DominatorTree *DT = nullptr);
+/// Returns true if V is always dereferenceable for Size byte with alignment
+/// greater or equal than requested. If the context instruction is specified
+/// performs context-sensitive analysis and returns true if the pointer is
+/// dereferenceable at the specified instruction.
+bool isDereferenceableAndAlignedPointer(const Value *V, unsigned Align,
+ const APInt &Size, const DataLayout &DL,
+ const Instruction *CtxI = nullptr,
+ const DominatorTree *DT = nullptr);
+
/// Return true if we know that executing a load from this value cannot trap.
///
/// If DT and ScanFrom are specified this method performs context-sensitive
@@ -85,8 +94,37 @@ Value *FindAvailableLoadedValue(LoadInst *Load,
BasicBlock::iterator &ScanFrom,
unsigned MaxInstsToScan = DefMaxInstsToScan,
AliasAnalysis *AA = nullptr,
- bool *IsLoadCSE = nullptr);
+ bool *IsLoadCSE = nullptr,
+ unsigned *NumScanedInst = nullptr);
+/// Scan backwards to see if we have the value of the given pointer available
+/// locally within a small number of instructions.
+///
+/// You can use this function to scan across multiple blocks: after you call
+/// this function, if ScanFrom points at the beginning of the block, it's safe
+/// to continue scanning the predecessors.
+///
+/// \param Ptr The pointer we want the load and store to originate from.
+/// \param AccessTy The access type of the pointer.
+/// \param AtLeastAtomic Are we looking for at-least an atomic load/store ? In
+/// case it is false, we can return an atomic or non-atomic load or store. In
+/// case it is true, we need to return an atomic load or store.
+/// \param ScanBB The basic block to scan.
+/// \param [in,out] ScanFrom The location to start scanning from. When this
+/// function returns, it points at the last instruction scanned.
+/// \param MaxInstsToScan The maximum number of instructions to scan. If this
+/// 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
+/// 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);
}
#endif
diff --git a/contrib/llvm/include/llvm/Analysis/LoopAccessAnalysis.h b/contrib/llvm/include/llvm/Analysis/LoopAccessAnalysis.h
index 901b193..2568903 100644
--- a/contrib/llvm/include/llvm/Analysis/LoopAccessAnalysis.h
+++ b/contrib/llvm/include/llvm/Analysis/LoopAccessAnalysis.h
@@ -38,39 +38,6 @@ class SCEVUnionPredicate;
class LoopAccessInfo;
class OptimizationRemarkEmitter;
-/// Optimization analysis message produced during vectorization. Messages inform
-/// the user why vectorization did not occur.
-class LoopAccessReport {
- std::string Message;
- const Instruction *Instr;
-
-protected:
- LoopAccessReport(const Twine &Message, const Instruction *I)
- : Message(Message.str()), Instr(I) {}
-
-public:
- LoopAccessReport(const Instruction *I = nullptr) : Instr(I) {}
-
- template <typename A> LoopAccessReport &operator<<(const A &Value) {
- raw_string_ostream Out(Message);
- Out << Value;
- return *this;
- }
-
- const Instruction *getInstr() const { return Instr; }
-
- std::string &str() { return Message; }
- const std::string &str() const { return Message; }
- operator Twine() { return Message; }
-
- /// \brief Emit an analysis note for \p PassName with the debug location from
- /// the instruction in \p Message if available. Otherwise use the location of
- /// \p TheLoop.
- static void emitAnalysis(const LoopAccessReport &Message, const Loop *TheLoop,
- const char *PassName,
- OptimizationRemarkEmitter &ORE);
-};
-
/// \brief Collection of parameters shared beetween the Loop Vectorizer and the
/// Loop Access Analysis.
struct VectorizerParams {
@@ -126,7 +93,7 @@ struct VectorizerParams {
class MemoryDepChecker {
public:
typedef PointerIntPair<Value *, 1, bool> MemAccessInfo;
- typedef SmallPtrSet<MemAccessInfo, 8> MemAccessInfoSet;
+ typedef SmallVector<MemAccessInfo, 8> MemAccessInfoList;
/// \brief Set of potential dependent memory accesses.
typedef EquivalenceClasses<MemAccessInfo> DepCandidates;
@@ -221,7 +188,7 @@ public:
/// \brief Check whether the dependencies between the accesses are safe.
///
/// Only checks sets with elements in \p CheckDeps.
- bool areDepsSafe(DepCandidates &AccessSets, MemAccessInfoSet &CheckDeps,
+ bool areDepsSafe(DepCandidates &AccessSets, MemAccessInfoList &CheckDeps,
const ValueToValueMap &Strides);
/// \brief No memory dependence was encountered that would inhibit
diff --git a/contrib/llvm/include/llvm/Analysis/LoopInfo.h b/contrib/llvm/include/llvm/Analysis/LoopInfo.h
index 20e6af2..70ce9a8 100644
--- a/contrib/llvm/include/llvm/Analysis/LoopInfo.h
+++ b/contrib/llvm/include/llvm/Analysis/LoopInfo.h
@@ -26,7 +26,7 @@
// * etc...
//
// Note that this analysis specifically identifies *Loops* not cycles or SCCs
-// in the CFG. There can be strongly connected compontents in the CFG which
+// in the CFG. There can be strongly connected components in the CFG which
// this analysis will not recognize and that will not be represented by a Loop
// instance. In particular, a Loop might be inside such a non-loop SCC, or a
// non-loop SCC might contain a sub-SCC which is a Loop.
@@ -56,7 +56,8 @@ class Loop;
class MDNode;
class PHINode;
class raw_ostream;
-template<class N> class DominatorTreeBase;
+template <class N, bool IsPostDom>
+class DominatorTreeBase;
template<class N, class M> class LoopInfoBase;
template<class N, class M> class LoopBase;
@@ -158,11 +159,8 @@ public:
/// True if terminator in the block can branch to another block that is
/// outside of the current loop.
bool isLoopExiting(const BlockT *BB) const {
- typedef GraphTraits<const BlockT*> BlockTraits;
- for (typename BlockTraits::ChildIteratorType SI =
- BlockTraits::child_begin(BB),
- SE = BlockTraits::child_end(BB); SI != SE; ++SI) {
- if (!contains(*SI))
+ for (const auto &Succ : children<const BlockT*>(BB)) {
+ if (!contains(Succ))
return true;
}
return false;
@@ -186,11 +184,8 @@ public:
unsigned NumBackEdges = 0;
BlockT *H = getHeader();
- typedef GraphTraits<Inverse<BlockT*> > InvBlockTraits;
- for (typename InvBlockTraits::ChildIteratorType I =
- InvBlockTraits::child_begin(H),
- E = InvBlockTraits::child_end(H); I != E; ++I)
- if (contains(*I))
+ for (const auto Pred : children<Inverse<BlockT*> >(H))
+ if (contains(Pred))
++NumBackEdges;
return NumBackEdges;
@@ -249,12 +244,9 @@ public:
/// contains a branch back to the header.
void getLoopLatches(SmallVectorImpl<BlockT *> &LoopLatches) const {
BlockT *H = getHeader();
- typedef GraphTraits<Inverse<BlockT*> > InvBlockTraits;
- for (typename InvBlockTraits::ChildIteratorType I =
- InvBlockTraits::child_begin(H),
- E = InvBlockTraits::child_end(H); I != E; ++I)
- if (contains(*I))
- LoopLatches.push_back(*I);
+ for (const auto Pred : children<Inverse<BlockT*>>(H))
+ if (contains(Pred))
+ LoopLatches.push_back(Pred);
}
//===--------------------------------------------------------------------===//
@@ -364,7 +356,7 @@ extern template class LoopBase<BasicBlock, Loop>;
/// Represents a single loop in the control flow graph. Note that not all SCCs
-/// in the CFG are neccessarily loops.
+/// in the CFG are necessarily loops.
class Loop : public LoopBase<BasicBlock, Loop> {
public:
/// \brief A range representing the start and end location of a loop.
@@ -469,7 +461,7 @@ public:
/// the loop that branches to the loop header.
///
/// The LoopID metadata node should have one or more operands and the first
- /// operand should should be the node itself.
+ /// operand should be the node itself.
void setLoopID(MDNode *LoopID) const;
/// Return true if no exit block for the loop has a predecessor that is
@@ -478,7 +470,8 @@ public:
/// Return all unique successor blocks of this loop.
/// These are the blocks _outside of the current loop_ which are branched to.
- /// This assumes that loop exits are in canonical form.
+ /// This assumes that loop exits are in canonical form, i.e. all exits are
+ /// dedicated exits.
void getUniqueExitBlocks(SmallVectorImpl<BasicBlock *> &ExitBlocks) const;
/// If getUniqueExitBlocks would return exactly one block, return that block.
@@ -570,6 +563,23 @@ public:
reverse_iterator rend() const { return TopLevelLoops.rend(); }
bool empty() const { return TopLevelLoops.empty(); }
+ /// Return all of the loops in the function in preorder across the loop
+ /// nests, with siblings in forward program order.
+ ///
+ /// Note that because loops form a forest of trees, preorder is equivalent to
+ /// reverse postorder.
+ SmallVector<LoopT *, 4> getLoopsInPreorder();
+
+ /// Return all of the loops in the function in preorder across the loop
+ /// nests, with siblings in *reverse* program order.
+ ///
+ /// Note that because loops form a forest of trees, preorder is equivalent to
+ /// reverse postorder.
+ ///
+ /// Also note that this is *not* a reverse preorder. Only the siblings are in
+ /// reverse program order.
+ SmallVector<LoopT *, 4> getLoopsInReverseSiblingPreorder();
+
/// Return the inner most loop that BB lives in. If a basic block is in no
/// loop (for example the entry node), null is returned.
LoopT *getLoopFor(const BlockT *BB) const { return BBMap.lookup(BB); }
@@ -654,12 +664,12 @@ public:
}
/// Create the loop forest using a stable algorithm.
- void analyze(const DominatorTreeBase<BlockT> &DomTree);
+ void analyze(const DominatorTreeBase<BlockT, false> &DomTree);
// Debugging
void print(raw_ostream &OS) const;
- void verify(const DominatorTreeBase<BlockT> &DomTree) const;
+ void verify(const DominatorTreeBase<BlockT, false> &DomTree) const;
};
// Implementation in LoopInfoImpl.h
@@ -674,7 +684,7 @@ class LoopInfo : public LoopInfoBase<BasicBlock, Loop> {
LoopInfo(const LoopInfo &) = delete;
public:
LoopInfo() {}
- explicit LoopInfo(const DominatorTreeBase<BasicBlock> &DomTree);
+ explicit LoopInfo(const DominatorTreeBase<BasicBlock, false> &DomTree);
LoopInfo(LoopInfo &&Arg) : BaseT(std::move(static_cast<BaseT &>(Arg))) {}
LoopInfo &operator=(LoopInfo &&RHS) {
@@ -682,6 +692,10 @@ public:
return *this;
}
+ /// Handle invalidation explicitly.
+ bool invalidate(Function &F, const PreservedAnalyses &PA,
+ FunctionAnalysisManager::Invalidator &);
+
// Most of the public interface is provided via LoopInfoBase.
/// Update LoopInfo after removing the last backedge from a loop. This updates
diff --git a/contrib/llvm/include/llvm/Analysis/LoopInfoImpl.h b/contrib/llvm/include/llvm/Analysis/LoopInfoImpl.h
index 833a220..e9177e6 100644
--- a/contrib/llvm/include/llvm/Analysis/LoopInfoImpl.h
+++ b/contrib/llvm/include/llvm/Analysis/LoopInfoImpl.h
@@ -17,8 +17,8 @@
#include "llvm/ADT/DepthFirstIterator.h"
#include "llvm/ADT/PostOrderIterator.h"
-#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SetVector.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/IR/Dominators.h"
@@ -34,14 +34,11 @@ namespace llvm {
template<class BlockT, class LoopT>
void LoopBase<BlockT, LoopT>::
getExitingBlocks(SmallVectorImpl<BlockT *> &ExitingBlocks) const {
- typedef GraphTraits<BlockT*> BlockTraits;
- for (block_iterator BI = block_begin(), BE = block_end(); BI != BE; ++BI)
- for (typename BlockTraits::ChildIteratorType I =
- BlockTraits::child_begin(*BI), E = BlockTraits::child_end(*BI);
- I != E; ++I)
- if (!contains(*I)) {
+ for (const auto BB : blocks())
+ for (const auto &Succ : children<BlockT*>(BB))
+ if (!contains(Succ)) {
// Not in current loop? It must be an exit block.
- ExitingBlocks.push_back(*BI);
+ ExitingBlocks.push_back(BB);
break;
}
}
@@ -63,14 +60,11 @@ BlockT *LoopBase<BlockT, LoopT>::getExitingBlock() const {
template<class BlockT, class LoopT>
void LoopBase<BlockT, LoopT>::
getExitBlocks(SmallVectorImpl<BlockT*> &ExitBlocks) const {
- typedef GraphTraits<BlockT*> BlockTraits;
- for (block_iterator BI = block_begin(), BE = block_end(); BI != BE; ++BI)
- for (typename BlockTraits::ChildIteratorType I =
- BlockTraits::child_begin(*BI), E = BlockTraits::child_end(*BI);
- I != E; ++I)
- if (!contains(*I))
+ for (const auto BB : blocks())
+ for (const auto &Succ : children<BlockT*>(BB))
+ if (!contains(Succ))
// Not in current loop? It must be an exit block.
- ExitBlocks.push_back(*I);
+ ExitBlocks.push_back(Succ);
}
/// getExitBlock - If getExitBlocks would return exactly one block,
@@ -88,20 +82,18 @@ BlockT *LoopBase<BlockT, LoopT>::getExitBlock() const {
template<class BlockT, class LoopT>
void LoopBase<BlockT, LoopT>::
getExitEdges(SmallVectorImpl<Edge> &ExitEdges) const {
- typedef GraphTraits<BlockT*> BlockTraits;
- for (block_iterator BI = block_begin(), BE = block_end(); BI != BE; ++BI)
- for (typename BlockTraits::ChildIteratorType I =
- BlockTraits::child_begin(*BI), E = BlockTraits::child_end(*BI);
- I != E; ++I)
- if (!contains(*I))
+ for (const auto BB : blocks())
+ for (const auto &Succ : children<BlockT*>(BB))
+ if (!contains(Succ))
// Not in current loop? It must be an exit block.
- ExitEdges.push_back(Edge(*BI, *I));
+ ExitEdges.emplace_back(BB, Succ);
}
/// getLoopPreheader - If there is a preheader for this loop, return it. A
/// loop has a preheader if there is only one edge to the header of the loop
-/// from outside of the loop. If this is the case, the block branching to the
-/// header of the loop is the preheader node.
+/// from outside of the loop and it is legal to hoist instructions into the
+/// predecessor. If this is the case, the block branching to the header of the
+/// loop is the preheader node.
///
/// This method returns null if there is no preheader for the loop.
///
@@ -111,6 +103,10 @@ BlockT *LoopBase<BlockT, LoopT>::getLoopPreheader() const {
BlockT *Out = getLoopPredecessor();
if (!Out) return nullptr;
+ // Make sure we are allowed to hoist instructions into the predecessor.
+ if (!Out->isLegalToHoistInto())
+ return nullptr;
+
// Make sure there is only one exit out of the preheader.
typedef GraphTraits<BlockT*> BlockTraits;
typename BlockTraits::ChildIteratorType SI = BlockTraits::child_begin(Out);
@@ -134,15 +130,11 @@ BlockT *LoopBase<BlockT, LoopT>::getLoopPredecessor() const {
// Loop over the predecessors of the header node...
BlockT *Header = getHeader();
- typedef GraphTraits<Inverse<BlockT*> > InvBlockTraits;
- for (typename InvBlockTraits::ChildIteratorType PI =
- InvBlockTraits::child_begin(Header),
- PE = InvBlockTraits::child_end(Header); PI != PE; ++PI) {
- typename InvBlockTraits::NodeRef N = *PI;
- if (!contains(N)) { // If the block is not in the loop...
- if (Out && Out != N)
+ for (const auto Pred : children<Inverse<BlockT*>>(Header)) {
+ if (!contains(Pred)) { // If the block is not in the loop...
+ if (Out && Out != Pred)
return nullptr; // Multiple predecessors outside the loop
- Out = N;
+ Out = Pred;
}
}
@@ -156,17 +148,11 @@ BlockT *LoopBase<BlockT, LoopT>::getLoopPredecessor() const {
template<class BlockT, class LoopT>
BlockT *LoopBase<BlockT, LoopT>::getLoopLatch() const {
BlockT *Header = getHeader();
- typedef GraphTraits<Inverse<BlockT*> > InvBlockTraits;
- typename InvBlockTraits::ChildIteratorType PI =
- InvBlockTraits::child_begin(Header);
- typename InvBlockTraits::ChildIteratorType PE =
- InvBlockTraits::child_end(Header);
BlockT *Latch = nullptr;
- for (; PI != PE; ++PI) {
- typename InvBlockTraits::NodeRef N = *PI;
- if (contains(N)) {
+ for (const auto Pred : children<Inverse<BlockT*>>(Header)) {
+ if (contains(Pred)) {
if (Latch) return nullptr;
- Latch = N;
+ Latch = Pred;
}
}
@@ -239,8 +225,8 @@ void LoopBase<BlockT, LoopT>::verifyLoop() const {
BI = df_ext_begin(getHeader(), VisitSet),
BE = df_ext_end(getHeader(), VisitSet);
- // Keep track of the number of BBs visited.
- unsigned NumVisited = 0;
+ // Keep track of the BBs visited.
+ SmallPtrSet<BlockT*, 8> VisitedBBs;
// Check the individual blocks.
for ( ; BI != BE; ++BI) {
@@ -278,10 +264,18 @@ void LoopBase<BlockT, LoopT>::verifyLoop() const {
assert(BB != &getHeader()->getParent()->front() &&
"Loop contains function entry block!");
- NumVisited++;
+ VisitedBBs.insert(BB);
}
- assert(NumVisited == getNumBlocks() && "Unreachable block in loop");
+ if (VisitedBBs.size() != getNumBlocks()) {
+ dbgs() << "The following blocks are unreachable in the loop: ";
+ for (auto BB : Blocks) {
+ if (!VisitedBBs.count(BB)) {
+ dbgs() << *BB << "\n";
+ }
+ }
+ assert(false && "Unreachable block in loop");
+ }
// Check the subloops.
for (iterator I = begin(), E = end(); I != E; ++I)
@@ -346,10 +340,10 @@ void LoopBase<BlockT, LoopT>::print(raw_ostream &OS, unsigned Depth,
/// Discover a subloop with the specified backedges such that: All blocks within
/// this loop are mapped to this loop or a subloop. And all subloops within this
/// loop have their parent loop set to this loop or a subloop.
-template<class BlockT, class LoopT>
-static void discoverAndMapSubloop(LoopT *L, ArrayRef<BlockT*> Backedges,
- LoopInfoBase<BlockT, LoopT> *LI,
- const DominatorTreeBase<BlockT> &DomTree) {
+template <class BlockT, class LoopT>
+static void discoverAndMapSubloop(
+ LoopT *L, ArrayRef<BlockT *> Backedges, LoopInfoBase<BlockT, LoopT> *LI,
+ const DomTreeBase<BlockT> &DomTree) {
typedef GraphTraits<Inverse<BlockT*> > InvBlockTraits;
unsigned NumBlocks = 0;
@@ -394,11 +388,9 @@ static void discoverAndMapSubloop(LoopT *L, ArrayRef<BlockT*> Backedges,
// within this subloop tree itself. Note that a predecessor may directly
// reach another subloop that is not yet discovered to be a subloop of
// this loop, which we must traverse.
- for (typename InvBlockTraits::ChildIteratorType PI =
- InvBlockTraits::child_begin(PredBB),
- PE = InvBlockTraits::child_end(PredBB); PI != PE; ++PI) {
- if (LI->getLoopFor(*PI) != Subloop)
- ReverseCFGWorklist.push_back(*PI);
+ for (const auto Pred : children<Inverse<BlockT*>>(PredBB)) {
+ if (LI->getLoopFor(Pred) != Subloop)
+ ReverseCFGWorklist.push_back(Pred);
}
}
}
@@ -470,10 +462,9 @@ void PopulateLoopsDFS<BlockT, LoopT>::insertIntoLoop(BlockT *Block) {
///
/// The Block vectors are inclusive, so step 3 requires loop-depth number of
/// insertions per block.
-template<class BlockT, class LoopT>
-void LoopInfoBase<BlockT, LoopT>::
-analyze(const DominatorTreeBase<BlockT> &DomTree) {
-
+template <class BlockT, class LoopT>
+void LoopInfoBase<BlockT, LoopT>::analyze(
+ const DomTreeBase<BlockT> &DomTree) {
// Postorder traversal of the dominator tree.
const DomTreeNodeBase<BlockT> *DomRoot = DomTree.getRootNode();
for (auto DomNode : post_order(DomRoot)) {
@@ -482,13 +473,7 @@ analyze(const DominatorTreeBase<BlockT> &DomTree) {
SmallVector<BlockT *, 4> Backedges;
// Check each predecessor of the potential loop header.
- typedef GraphTraits<Inverse<BlockT*> > InvBlockTraits;
- for (typename InvBlockTraits::ChildIteratorType PI =
- InvBlockTraits::child_begin(Header),
- PE = InvBlockTraits::child_end(Header); PI != PE; ++PI) {
-
- BlockT *Backedge = *PI;
-
+ for (const auto Backedge : children<Inverse<BlockT*>>(Header)) {
// If Header dominates predBB, this is a new loop. Collect the backedges.
if (DomTree.dominates(Header, Backedge)
&& DomTree.isReachableFromEntry(Backedge)) {
@@ -507,6 +492,55 @@ analyze(const DominatorTreeBase<BlockT> &DomTree) {
DFS.traverse(DomRoot->getBlock());
}
+template <class BlockT, class LoopT>
+SmallVector<LoopT *, 4> LoopInfoBase<BlockT, LoopT>::getLoopsInPreorder() {
+ SmallVector<LoopT *, 4> PreOrderLoops, PreOrderWorklist;
+ // The outer-most loop actually goes into the result in the same relative
+ // order as we walk it. But LoopInfo stores the top level loops in reverse
+ // program order so for here we reverse it to get forward program order.
+ // FIXME: If we change the order of LoopInfo we will want to remove the
+ // reverse here.
+ for (LoopT *RootL : reverse(*this)) {
+ assert(PreOrderWorklist.empty() &&
+ "Must start with an empty preorder walk worklist.");
+ PreOrderWorklist.push_back(RootL);
+ do {
+ LoopT *L = PreOrderWorklist.pop_back_val();
+ // Sub-loops are stored in forward program order, but will process the
+ // worklist backwards so append them in reverse order.
+ PreOrderWorklist.append(L->rbegin(), L->rend());
+ PreOrderLoops.push_back(L);
+ } while (!PreOrderWorklist.empty());
+ }
+
+ return PreOrderLoops;
+}
+
+template <class BlockT, class LoopT>
+SmallVector<LoopT *, 4>
+LoopInfoBase<BlockT, LoopT>::getLoopsInReverseSiblingPreorder() {
+ SmallVector<LoopT *, 4> PreOrderLoops, PreOrderWorklist;
+ // The outer-most loop actually goes into the result in the same relative
+ // order as we walk it. LoopInfo stores the top level loops in reverse
+ // program order so we walk in order here.
+ // FIXME: If we change the order of LoopInfo we will want to add a reverse
+ // here.
+ for (LoopT *RootL : *this) {
+ assert(PreOrderWorklist.empty() &&
+ "Must start with an empty preorder walk worklist.");
+ PreOrderWorklist.push_back(RootL);
+ do {
+ LoopT *L = PreOrderWorklist.pop_back_val();
+ // Sub-loops are stored in forward program order, but will process the
+ // worklist backwards so we can just append them in order.
+ PreOrderWorklist.append(L->begin(), L->end());
+ PreOrderLoops.push_back(L);
+ } while (!PreOrderWorklist.empty());
+ }
+
+ return PreOrderLoops;
+}
+
// Debugging
template<class BlockT, class LoopT>
void LoopInfoBase<BlockT, LoopT>::print(raw_ostream &OS) const {
@@ -528,18 +562,51 @@ bool compareVectors(std::vector<T> &BB1, std::vector<T> &BB2) {
}
template <class BlockT, class LoopT>
-static void
-addInnerLoopsToHeadersMap(DenseMap<BlockT *, const LoopT *> &LoopHeaders,
- const LoopInfoBase<BlockT, LoopT> &LI,
- const LoopT &L) {
+void addInnerLoopsToHeadersMap(DenseMap<BlockT *, const LoopT *> &LoopHeaders,
+ const LoopInfoBase<BlockT, LoopT> &LI,
+ const LoopT &L) {
LoopHeaders[L.getHeader()] = &L;
for (LoopT *SL : L)
addInnerLoopsToHeadersMap(LoopHeaders, LI, *SL);
}
+#ifndef NDEBUG
+template <class BlockT, class LoopT>
+static void compareLoops(const LoopT *L, const LoopT *OtherL,
+ DenseMap<BlockT *, const LoopT *> &OtherLoopHeaders) {
+ BlockT *H = L->getHeader();
+ BlockT *OtherH = OtherL->getHeader();
+ assert(H == OtherH &&
+ "Mismatched headers even though found in the same map entry!");
+
+ assert(L->getLoopDepth() == OtherL->getLoopDepth() &&
+ "Mismatched loop depth!");
+ const LoopT *ParentL = L, *OtherParentL = OtherL;
+ do {
+ assert(ParentL->getHeader() == OtherParentL->getHeader() &&
+ "Mismatched parent loop headers!");
+ ParentL = ParentL->getParentLoop();
+ OtherParentL = OtherParentL->getParentLoop();
+ } while (ParentL);
+
+ for (const LoopT *SubL : *L) {
+ BlockT *SubH = SubL->getHeader();
+ const LoopT *OtherSubL = OtherLoopHeaders.lookup(SubH);
+ assert(OtherSubL && "Inner loop is missing in computed loop info!");
+ OtherLoopHeaders.erase(SubH);
+ compareLoops(SubL, OtherSubL, OtherLoopHeaders);
+ }
+
+ std::vector<BlockT *> BBs = L->getBlocks();
+ std::vector<BlockT *> OtherBBs = OtherL->getBlocks();
+ assert(compareVectors(BBs, OtherBBs) &&
+ "Mismatched basic blocks in the loops!");
+}
+#endif
+
template <class BlockT, class LoopT>
void LoopInfoBase<BlockT, LoopT>::verify(
- const DominatorTreeBase<BlockT> &DomTree) const {
+ const DomTreeBase<BlockT> &DomTree) const {
DenseSet<const LoopT*> Loops;
for (iterator I = begin(), E = end(); I != E; ++I) {
assert(!(*I)->getParentLoop() && "Top-level loop has a parent!");
@@ -559,42 +626,32 @@ void LoopInfoBase<BlockT, LoopT>::verify(
LoopInfoBase<BlockT, LoopT> OtherLI;
OtherLI.analyze(DomTree);
- DenseMap<BlockT *, const LoopT *> LoopHeaders1;
- DenseMap<BlockT *, const LoopT *> LoopHeaders2;
-
- for (LoopT *L : *this)
- addInnerLoopsToHeadersMap(LoopHeaders1, *this, *L);
+ // Build a map we can use to move from our LI to the computed one. This
+ // allows us to ignore the particular order in any layer of the loop forest
+ // while still comparing the structure.
+ DenseMap<BlockT *, const LoopT *> OtherLoopHeaders;
for (LoopT *L : OtherLI)
- addInnerLoopsToHeadersMap(LoopHeaders2, OtherLI, *L);
- assert(LoopHeaders1.size() == LoopHeaders2.size() &&
- "LoopInfo is incorrect.");
-
- auto compareLoops = [&](const LoopT *L1, const LoopT *L2) {
- BlockT *H1 = L1->getHeader();
- BlockT *H2 = L2->getHeader();
- if (H1 != H2)
- return false;
- std::vector<BlockT *> BB1 = L1->getBlocks();
- std::vector<BlockT *> BB2 = L2->getBlocks();
- if (!compareVectors(BB1, BB2))
- return false;
-
- std::vector<BlockT *> SubLoopHeaders1;
- std::vector<BlockT *> SubLoopHeaders2;
- for (LoopT *L : *L1)
- SubLoopHeaders1.push_back(L->getHeader());
- for (LoopT *L : *L2)
- SubLoopHeaders2.push_back(L->getHeader());
-
- if (!compareVectors(SubLoopHeaders1, SubLoopHeaders2))
- return false;
- return true;
- };
-
- for (auto &I : LoopHeaders1) {
- BlockT *H = I.first;
- bool LoopsMatch = compareLoops(LoopHeaders1[H], LoopHeaders2[H]);
- assert(LoopsMatch && "LoopInfo is incorrect.");
+ addInnerLoopsToHeadersMap(OtherLoopHeaders, OtherLI, *L);
+
+ // Walk the top level loops and ensure there is a corresponding top-level
+ // loop in the computed version and then recursively compare those loop
+ // nests.
+ for (LoopT *L : *this) {
+ BlockT *Header = L->getHeader();
+ const LoopT *OtherL = OtherLoopHeaders.lookup(Header);
+ assert(OtherL && "Top level loop is missing in computed loop info!");
+ // Now that we've matched this loop, erase its header from the map.
+ OtherLoopHeaders.erase(Header);
+ // And recursively compare these loops.
+ compareLoops(L, OtherL, OtherLoopHeaders);
+ }
+
+ // Any remaining entries in the map are loops which were found when computing
+ // a fresh LoopInfo but not present in the current one.
+ if (!OtherLoopHeaders.empty()) {
+ for (const auto &HeaderAndLoop : OtherLoopHeaders)
+ dbgs() << "Found new loop: " << *HeaderAndLoop.second << "\n";
+ llvm_unreachable("Found new loops when recomputing LoopInfo!");
}
#endif
}
diff --git a/contrib/llvm/include/llvm/Analysis/LoopPass.h b/contrib/llvm/include/llvm/Analysis/LoopPass.h
index 496ae18..75e7688 100644
--- a/contrib/llvm/include/llvm/Analysis/LoopPass.h
+++ b/contrib/llvm/include/llvm/Analysis/LoopPass.h
@@ -126,9 +126,8 @@ public:
}
public:
- // Add a new loop into the loop queue as a child of the given parent, or at
- // the top level if \c ParentLoop is null.
- Loop &addLoop(Loop *ParentLoop);
+ // Add a new loop into the loop queue.
+ void addLoop(Loop &L);
//===--------------------------------------------------------------------===//
/// SimpleAnalysis - Provides simple interface to update analysis info
diff --git a/contrib/llvm/include/llvm/Analysis/MemoryBuiltins.h b/contrib/llvm/include/llvm/Analysis/MemoryBuiltins.h
index b58f07e..23ab372 100644
--- a/contrib/llvm/include/llvm/Analysis/MemoryBuiltins.h
+++ b/contrib/llvm/include/llvm/Analysis/MemoryBuiltins.h
@@ -32,12 +32,6 @@ class TargetLibraryInfo;
class Type;
class Value;
-enum class ObjSizeMode {
- Exact = 0,
- Min = 1,
- Max = 2
-};
-
/// \brief Tests if a value is a call or invoke to a library function that
/// allocates or reallocates memory (either malloc, calloc, realloc, or strdup
/// like).
@@ -60,6 +54,11 @@ bool isCallocLikeFn(const Value *V, const TargetLibraryInfo *TLI,
bool LookThroughBitCast = false);
/// \brief Tests if a value is a call or invoke to a library function that
+/// allocates memory similar to malloc or calloc.
+bool isMallocOrCallocLikeFn(const Value *V, const TargetLibraryInfo *TLI,
+ bool LookThroughBitCast = false);
+
+/// \brief Tests if a value is a call or invoke to a library function that
/// allocates memory (either malloc, calloc, or strdup like).
bool isAllocLikeFn(const Value *V, const TargetLibraryInfo *TLI,
bool LookThroughBitCast = false);
@@ -129,17 +128,36 @@ static inline CallInst *isFreeCall(Value *I, const TargetLibraryInfo *TLI) {
// Utility functions to compute size of objects.
//
+/// Various options to control the behavior of getObjectSize.
+struct ObjectSizeOpts {
+ /// Controls how we handle conditional statements with unknown conditions.
+ enum class Mode : uint8_t {
+ /// Fail to evaluate an unknown condition.
+ Exact,
+ /// Evaluate all branches of an unknown condition. If all evaluations
+ /// succeed, pick the minimum size.
+ Min,
+ /// Same as Min, except we pick the maximum size of all of the branches.
+ Max
+ };
+
+ /// How we want to evaluate this object's size.
+ Mode EvalMode = Mode::Exact;
+ /// Whether to round the result up to the alignment of allocas, byval
+ /// arguments, and global variables.
+ bool RoundToAlign = false;
+ /// If this is true, null pointers in address space 0 will be treated as
+ /// though they can't be evaluated. Otherwise, null is always considered to
+ /// point to a 0 byte region of memory.
+ bool NullIsUnknownSize = false;
+};
+
/// \brief Compute the size of the object pointed by Ptr. Returns true and the
/// object size in Size if successful, and false otherwise. In this context, by
/// object we mean the region of memory starting at Ptr to the end of the
/// underlying object pointed to by Ptr.
-/// If RoundToAlign is true, then Size is rounded up to the aligment of allocas,
-/// byval arguments, and global variables.
-/// If Mode is Min or Max the size will be evaluated even if it depends on
-/// a condition and corresponding value will be returned (min or max).
bool getObjectSize(const Value *Ptr, uint64_t &Size, const DataLayout &DL,
- const TargetLibraryInfo *TLI, bool RoundToAlign = false,
- ObjSizeMode Mode = ObjSizeMode::Exact);
+ const TargetLibraryInfo *TLI, ObjectSizeOpts Opts = {});
/// Try to turn a call to @llvm.objectsize into an integer value of the given
/// Type. Returns null on failure.
@@ -160,8 +178,7 @@ class ObjectSizeOffsetVisitor
const DataLayout &DL;
const TargetLibraryInfo *TLI;
- bool RoundToAlign;
- ObjSizeMode Mode;
+ ObjectSizeOpts Options;
unsigned IntTyBits;
APInt Zero;
SmallPtrSet<Instruction *, 8> SeenInsts;
@@ -174,8 +191,7 @@ class ObjectSizeOffsetVisitor
public:
ObjectSizeOffsetVisitor(const DataLayout &DL, const TargetLibraryInfo *TLI,
- LLVMContext &Context, bool RoundToAlign = false,
- ObjSizeMode Mode = ObjSizeMode::Exact);
+ LLVMContext &Context, ObjectSizeOpts Options = {});
SizeOffsetType compute(Value *V);
@@ -208,6 +224,9 @@ public:
SizeOffsetType visitSelectInst(SelectInst &I);
SizeOffsetType visitUndefValue(UndefValue&);
SizeOffsetType visitInstruction(Instruction &I);
+
+private:
+ bool CheckedZextOrTrunc(APInt &I);
};
typedef std::pair<Value*, Value*> SizeOffsetEvalType;
@@ -219,7 +238,7 @@ class ObjectSizeOffsetEvaluator
: public InstVisitor<ObjectSizeOffsetEvaluator, SizeOffsetEvalType> {
typedef IRBuilder<TargetFolder> BuilderTy;
- typedef std::pair<WeakVH, WeakVH> WeakEvalType;
+ typedef std::pair<WeakTrackingVH, WeakTrackingVH> WeakEvalType;
typedef DenseMap<const Value*, WeakEvalType> CacheMapTy;
typedef SmallPtrSet<const Value*, 8> PtrSetTy;
diff --git a/contrib/llvm/include/llvm/Analysis/MemoryDependenceAnalysis.h b/contrib/llvm/include/llvm/Analysis/MemoryDependenceAnalysis.h
index a401887..1dbbf6c 100644
--- a/contrib/llvm/include/llvm/Analysis/MemoryDependenceAnalysis.h
+++ b/contrib/llvm/include/llvm/Analysis/MemoryDependenceAnalysis.h
@@ -15,8 +15,8 @@
#define LLVM_ANALYSIS_MEMORYDEPENDENCEANALYSIS_H
#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/PointerSumType.h"
#include "llvm/ADT/PointerEmbeddedInt.h"
+#include "llvm/ADT/PointerSumType.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/IR/BasicBlock.h"
diff --git a/contrib/llvm/include/llvm/Transforms/Utils/MemorySSA.h b/contrib/llvm/include/llvm/Analysis/MemorySSA.h
index 408c6a1..5cec2bf 100644
--- a/contrib/llvm/include/llvm/Transforms/Utils/MemorySSA.h
+++ b/contrib/llvm/include/llvm/Analysis/MemorySSA.h
@@ -6,71 +6,71 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-//
-// \file
-// \brief This file exposes an interface to building/using memory SSA to
-// walk memory instructions using a use/def graph.
-//
-// Memory SSA class builds an SSA form that links together memory access
-// instructions such as loads, stores, atomics, and calls. Additionally, it does
-// a trivial form of "heap versioning" Every time the memory state changes in
-// the program, we generate a new heap version. It generates MemoryDef/Uses/Phis
-// that are overlayed on top of the existing instructions.
-//
-// As a trivial example,
-// define i32 @main() #0 {
-// entry:
-// %call = call noalias i8* @_Znwm(i64 4) #2
-// %0 = bitcast i8* %call to i32*
-// %call1 = call noalias i8* @_Znwm(i64 4) #2
-// %1 = bitcast i8* %call1 to i32*
-// store i32 5, i32* %0, align 4
-// store i32 7, i32* %1, align 4
-// %2 = load i32* %0, align 4
-// %3 = load i32* %1, align 4
-// %add = add nsw i32 %2, %3
-// ret i32 %add
-// }
-//
-// Will become
-// define i32 @main() #0 {
-// entry:
-// ; 1 = MemoryDef(0)
-// %call = call noalias i8* @_Znwm(i64 4) #3
-// %2 = bitcast i8* %call to i32*
-// ; 2 = MemoryDef(1)
-// %call1 = call noalias i8* @_Znwm(i64 4) #3
-// %4 = bitcast i8* %call1 to i32*
-// ; 3 = MemoryDef(2)
-// store i32 5, i32* %2, align 4
-// ; 4 = MemoryDef(3)
-// store i32 7, i32* %4, align 4
-// ; MemoryUse(3)
-// %7 = load i32* %2, align 4
-// ; MemoryUse(4)
-// %8 = load i32* %4, align 4
-// %add = add nsw i32 %7, %8
-// ret i32 %add
-// }
-//
-// Given this form, all the stores that could ever effect the load at %8 can be
-// gotten by using the MemoryUse associated with it, and walking from use to def
-// until you hit the top of the function.
-//
-// Each def also has a list of users associated with it, so you can walk from
-// both def to users, and users to defs. Note that we disambiguate MemoryUses,
-// but not the RHS of MemoryDefs. You can see this above at %7, which would
-// otherwise be a MemoryUse(4). Being disambiguated means that for a given
-// store, all the MemoryUses on its use lists are may-aliases of that store (but
-// the MemoryDefs on its use list may not be).
-//
-// MemoryDefs are not disambiguated because it would require multiple reaching
-// definitions, which would require multiple phis, and multiple memoryaccesses
-// per instruction.
+///
+/// \file
+/// \brief This file exposes an interface to building/using memory SSA to
+/// walk memory instructions using a use/def graph.
+///
+/// Memory SSA class builds an SSA form that links together memory access
+/// instructions such as loads, stores, atomics, and calls. Additionally, it
+/// does a trivial form of "heap versioning" Every time the memory state changes
+/// in the program, we generate a new heap version. It generates
+/// MemoryDef/Uses/Phis that are overlayed on top of the existing instructions.
+///
+/// As a trivial example,
+/// define i32 @main() #0 {
+/// entry:
+/// %call = call noalias i8* @_Znwm(i64 4) #2
+/// %0 = bitcast i8* %call to i32*
+/// %call1 = call noalias i8* @_Znwm(i64 4) #2
+/// %1 = bitcast i8* %call1 to i32*
+/// store i32 5, i32* %0, align 4
+/// store i32 7, i32* %1, align 4
+/// %2 = load i32* %0, align 4
+/// %3 = load i32* %1, align 4
+/// %add = add nsw i32 %2, %3
+/// ret i32 %add
+/// }
+///
+/// Will become
+/// define i32 @main() #0 {
+/// entry:
+/// ; 1 = MemoryDef(0)
+/// %call = call noalias i8* @_Znwm(i64 4) #3
+/// %2 = bitcast i8* %call to i32*
+/// ; 2 = MemoryDef(1)
+/// %call1 = call noalias i8* @_Znwm(i64 4) #3
+/// %4 = bitcast i8* %call1 to i32*
+/// ; 3 = MemoryDef(2)
+/// store i32 5, i32* %2, align 4
+/// ; 4 = MemoryDef(3)
+/// store i32 7, i32* %4, align 4
+/// ; MemoryUse(3)
+/// %7 = load i32* %2, align 4
+/// ; MemoryUse(4)
+/// %8 = load i32* %4, align 4
+/// %add = add nsw i32 %7, %8
+/// ret i32 %add
+/// }
+///
+/// Given this form, all the stores that could ever effect the load at %8 can be
+/// gotten by using the MemoryUse associated with it, and walking from use to
+/// def until you hit the top of the function.
+///
+/// Each def also has a list of users associated with it, so you can walk from
+/// both def to users, and users to defs. Note that we disambiguate MemoryUses,
+/// but not the RHS of MemoryDefs. You can see this above at %7, which would
+/// otherwise be a MemoryUse(4). Being disambiguated means that for a given
+/// store, all the MemoryUses on its use lists are may-aliases of that store
+/// (but the MemoryDefs on its use list may not be).
+///
+/// MemoryDefs are not disambiguated because it would require multiple reaching
+/// definitions, which would require multiple phis, and multiple memoryaccesses
+/// per instruction.
//===----------------------------------------------------------------------===//
-#ifndef LLVM_TRANSFORMS_UTILS_MEMORYSSA_H
-#define LLVM_TRANSFORMS_UTILS_MEMORYSSA_H
+#ifndef LLVM_ANALYSIS_MEMORYSSA_H
+#define LLVM_ANALYSIS_MEMORYSSA_H
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/GraphTraits.h"
@@ -79,10 +79,12 @@
#include "llvm/ADT/ilist.h"
#include "llvm/ADT/ilist_node.h"
#include "llvm/ADT/iterator.h"
+#include "llvm/ADT/iterator_range.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/MemoryLocation.h"
#include "llvm/Analysis/PHITransAddr.h"
#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/DerivedUser.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/OperandTraits.h"
@@ -91,9 +93,7 @@
#include "llvm/IR/User.h"
#include "llvm/IR/Value.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>
@@ -104,12 +104,16 @@
namespace llvm {
-class DominatorTree;
class Function;
class Instruction;
class MemoryAccess;
class LLVMContext;
class raw_ostream;
+namespace MSSAHelpers {
+struct AllAccessTag {};
+struct DefsOnlyTag {};
+}
+
enum {
// Used to signify what the default invalid ID is for MemoryAccess's
// getID()
@@ -123,25 +127,32 @@ using const_memoryaccess_def_iterator =
// \brief The base for all memory accesses. All memory accesses in a block are
// linked together using an intrusive list.
-class MemoryAccess : public User, public ilist_node<MemoryAccess> {
- void *operator new(size_t, unsigned) = delete;
- void *operator new(size_t) = delete;
-
+class MemoryAccess
+ : public DerivedUser,
+ public ilist_node<MemoryAccess, ilist_tag<MSSAHelpers::AllAccessTag>>,
+ public ilist_node<MemoryAccess, ilist_tag<MSSAHelpers::DefsOnlyTag>> {
public:
+ using AllAccessType =
+ ilist_node<MemoryAccess, ilist_tag<MSSAHelpers::AllAccessTag>>;
+ using DefsOnlyType =
+ ilist_node<MemoryAccess, ilist_tag<MSSAHelpers::DefsOnlyTag>>;
+
// Methods for support type inquiry through isa, cast, and
// dyn_cast
- static inline bool classof(const MemoryAccess *) { return true; }
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
unsigned ID = V->getValueID();
return ID == MemoryUseVal || ID == MemoryPhiVal || ID == MemoryDefVal;
}
- ~MemoryAccess() override;
+ MemoryAccess(const MemoryAccess &) = delete;
+ MemoryAccess &operator=(const MemoryAccess &) = delete;
+
+ void *operator new(size_t) = delete;
BasicBlock *getBlock() const { return Block; }
- virtual void print(raw_ostream &OS) const = 0;
- virtual void dump() const;
+ void print(raw_ostream &OS) const;
+ void dump() const;
/// \brief The user iterators for a memory access
typedef user_iterator iterator;
@@ -155,6 +166,33 @@ public:
memoryaccess_def_iterator defs_end();
const_memoryaccess_def_iterator defs_end() const;
+ /// \brief Get the iterators for the all access list and the defs only list
+ /// We default to the all access list.
+ AllAccessType::self_iterator getIterator() {
+ return this->AllAccessType::getIterator();
+ }
+ AllAccessType::const_self_iterator getIterator() const {
+ return this->AllAccessType::getIterator();
+ }
+ AllAccessType::reverse_self_iterator getReverseIterator() {
+ return this->AllAccessType::getReverseIterator();
+ }
+ AllAccessType::const_reverse_self_iterator getReverseIterator() const {
+ return this->AllAccessType::getReverseIterator();
+ }
+ DefsOnlyType::self_iterator getDefsIterator() {
+ return this->DefsOnlyType::getIterator();
+ }
+ DefsOnlyType::const_self_iterator getDefsIterator() const {
+ return this->DefsOnlyType::getIterator();
+ }
+ DefsOnlyType::reverse_self_iterator getReverseDefsIterator() {
+ return this->DefsOnlyType::getReverseIterator();
+ }
+ DefsOnlyType::const_reverse_self_iterator getReverseDefsIterator() const {
+ return this->DefsOnlyType::getReverseIterator();
+ }
+
protected:
friend class MemorySSA;
friend class MemoryUseOrDef;
@@ -162,17 +200,20 @@ protected:
friend class MemoryDef;
friend class MemoryPhi;
+ /// \brief Used by MemorySSA to change the block of a MemoryAccess when it is
+ /// moved.
+ void setBlock(BasicBlock *BB) { Block = BB; }
+
/// \brief Used for debugging and tracking things about MemoryAccesses.
/// Guaranteed unique among MemoryAccesses, no guarantees otherwise.
- virtual unsigned getID() const = 0;
+ inline unsigned getID() const;
- MemoryAccess(LLVMContext &C, unsigned Vty, BasicBlock *BB,
- unsigned NumOperands)
- : User(Type::getVoidTy(C), Vty, nullptr, NumOperands), Block(BB) {}
+ MemoryAccess(LLVMContext &C, unsigned Vty, DeleteValueTy DeleteValue,
+ BasicBlock *BB, unsigned NumOperands)
+ : DerivedUser(Type::getVoidTy(C), Vty, nullptr, NumOperands, DeleteValue),
+ Block(BB) {}
private:
- MemoryAccess(const MemoryAccess &);
- void operator=(const MemoryAccess &);
BasicBlock *Block;
};
@@ -189,10 +230,9 @@ inline raw_ostream &operator<<(raw_ostream &OS, const MemoryAccess &MA) {
/// This class should never be instantiated directly; make a MemoryUse or
/// MemoryDef instead.
class MemoryUseOrDef : public MemoryAccess {
- void *operator new(size_t, unsigned) = delete;
+public:
void *operator new(size_t) = delete;
-public:
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(MemoryAccess);
/// \brief Get the instruction that this MemoryUse represents.
@@ -201,21 +241,36 @@ public:
/// \brief Get the access that produces the memory state used by this Use.
MemoryAccess *getDefiningAccess() const { return getOperand(0); }
- static inline bool classof(const MemoryUseOrDef *) { return true; }
- static inline bool classof(const Value *MA) {
+ static bool classof(const Value *MA) {
return MA->getValueID() == MemoryUseVal || MA->getValueID() == MemoryDefVal;
}
+ // Sadly, these have to be public because they are needed in some of the
+ // iterators.
+ inline bool isOptimized() const;
+ inline MemoryAccess *getOptimized() const;
+ inline void setOptimized(MemoryAccess *);
+
+ /// \brief Reset the ID of what this MemoryUse was optimized to, causing it to
+ /// be rewalked by the walker if necessary.
+ /// This really should only be called by tests.
+ inline void resetOptimized();
+
protected:
friend class MemorySSA;
-
+ friend class MemorySSAUpdater;
MemoryUseOrDef(LLVMContext &C, MemoryAccess *DMA, unsigned Vty,
- Instruction *MI, BasicBlock *BB)
- : MemoryAccess(C, Vty, BB, 1), MemoryInst(MI) {
+ DeleteValueTy DeleteValue, Instruction *MI, BasicBlock *BB)
+ : MemoryAccess(C, Vty, DeleteValue, BB, 1), MemoryInst(MI) {
setDefiningAccess(DMA);
}
-
- void setDefiningAccess(MemoryAccess *DMA) { setOperand(0, DMA); }
+ void setDefiningAccess(MemoryAccess *DMA, bool Optimized = false) {
+ if (!Optimized) {
+ setOperand(0, DMA);
+ return;
+ }
+ setOptimized(DMA);
+ }
private:
Instruction *MemoryInst;
@@ -232,44 +287,44 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(MemoryUseOrDef, MemoryAccess)
/// MemoryUse's is exactly the set of Instructions for which
/// AliasAnalysis::getModRefInfo returns "Ref".
class MemoryUse final : public MemoryUseOrDef {
- void *operator new(size_t, unsigned) = delete;
-
public:
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(MemoryAccess);
+ MemoryUse(LLVMContext &C, MemoryAccess *DMA, Instruction *MI, BasicBlock *BB)
+ : MemoryUseOrDef(C, DMA, MemoryUseVal, deleteMe, MI, BB),
+ OptimizedID(0) {}
+
// allocate space for exactly one operand
void *operator new(size_t s) { return User::operator new(s, 1); }
- MemoryUse(LLVMContext &C, MemoryAccess *DMA, Instruction *MI, BasicBlock *BB)
- : MemoryUseOrDef(C, DMA, MemoryUseVal, MI, BB), OptimizedID(0) {}
-
- static inline bool classof(const MemoryUse *) { return true; }
- static inline bool classof(const Value *MA) {
+ static bool classof(const Value *MA) {
return MA->getValueID() == MemoryUseVal;
}
- void print(raw_ostream &OS) const override;
- void setDefiningAccess(MemoryAccess *DMA, bool Optimized = false) {
- if (Optimized)
- OptimizedID = DMA->getID();
- MemoryUseOrDef::setDefiningAccess(DMA);
+ void print(raw_ostream &OS) const;
+
+ void setOptimized(MemoryAccess *DMA) {
+ OptimizedID = DMA->getID();
+ setOperand(0, DMA);
}
+
bool isOptimized() const {
return getDefiningAccess() && OptimizedID == getDefiningAccess()->getID();
}
- /// \brief Reset the ID of what this MemoryUse was optimized to, causing it to
- /// be rewalked by the walker if necessary.
- /// This really should only be called by tests.
- void resetOptimized() { OptimizedID = INVALID_MEMORYACCESS_ID; }
+
+ MemoryAccess *getOptimized() const {
+ return getDefiningAccess();
+ }
+ void resetOptimized() {
+ OptimizedID = INVALID_MEMORYACCESS_ID;
+ }
protected:
friend class MemorySSA;
- unsigned getID() const override {
- llvm_unreachable("MemoryUses do not have IDs");
- }
-
private:
+ static void deleteMe(DerivedUser *Self);
+
unsigned int OptimizedID;
};
@@ -287,32 +342,46 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(MemoryUse, MemoryAccess)
/// associated with them. This use points to the nearest reaching
/// MemoryDef/MemoryPhi.
class MemoryDef final : public MemoryUseOrDef {
- void *operator new(size_t, unsigned) = delete;
-
public:
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(MemoryAccess);
- // allocate space for exactly one operand
- void *operator new(size_t s) { return User::operator new(s, 1); }
-
MemoryDef(LLVMContext &C, MemoryAccess *DMA, Instruction *MI, BasicBlock *BB,
unsigned Ver)
- : MemoryUseOrDef(C, DMA, MemoryDefVal, MI, BB), ID(Ver) {}
+ : MemoryUseOrDef(C, DMA, MemoryDefVal, deleteMe, MI, BB),
+ ID(Ver), Optimized(nullptr), OptimizedID(INVALID_MEMORYACCESS_ID) {}
+
+ // allocate space for exactly one operand
+ void *operator new(size_t s) { return User::operator new(s, 1); }
- static inline bool classof(const MemoryDef *) { return true; }
- static inline bool classof(const Value *MA) {
+ static bool classof(const Value *MA) {
return MA->getValueID() == MemoryDefVal;
}
- void print(raw_ostream &OS) const override;
+ void setOptimized(MemoryAccess *MA) {
+ Optimized = MA;
+ OptimizedID = getDefiningAccess()->getID();
+ }
+ MemoryAccess *getOptimized() const { return Optimized; }
+ bool isOptimized() const {
+ return getOptimized() && getDefiningAccess() &&
+ OptimizedID == getDefiningAccess()->getID();
+ }
+ void resetOptimized() {
+ OptimizedID = INVALID_MEMORYACCESS_ID;
+ }
+
+ void print(raw_ostream &OS) const;
-protected:
friend class MemorySSA;
- unsigned getID() const override { return ID; }
+ unsigned getID() const { return ID; }
private:
+ static void deleteMe(DerivedUser *Self);
+
const unsigned ID;
+ MemoryAccess *Optimized;
+ unsigned int OptimizedID;
};
template <>
@@ -352,7 +421,6 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(MemoryDef, MemoryAccess)
/// Because MemoryUse's do not generate new definitions, they do not have this
/// issue.
class MemoryPhi final : public MemoryAccess {
- void *operator new(size_t, unsigned) = delete;
// allocate space for exactly zero operands
void *operator new(size_t s) { return User::operator new(s); }
@@ -361,7 +429,8 @@ public:
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(MemoryAccess);
MemoryPhi(LLVMContext &C, BasicBlock *BB, unsigned Ver, unsigned NumPreds = 0)
- : MemoryAccess(C, MemoryPhiVal, BB, 0), ID(Ver), ReservedSpace(NumPreds) {
+ : MemoryAccess(C, MemoryPhiVal, deleteMe, BB, 0), ID(Ver),
+ ReservedSpace(NumPreds) {
allocHungoffUses(ReservedSpace);
}
@@ -457,15 +526,17 @@ public:
return getIncomingValue(Idx);
}
- static inline bool classof(const MemoryPhi *) { return true; }
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return V->getValueID() == MemoryPhiVal;
}
- void print(raw_ostream &OS) const override;
+ void print(raw_ostream &OS) const;
+
+ unsigned getID() const { return ID; }
protected:
friend class MemorySSA;
+
/// \brief this is more complicated than the generic
/// User::allocHungoffUses, because we have to allocate Uses for the incoming
/// values and pointers to the incoming blocks, all in one allocation.
@@ -473,8 +544,6 @@ protected:
User::allocHungoffUses(N, /* IsPhi */ true);
}
- unsigned getID() const final { return ID; }
-
private:
// For debugging only
const unsigned ID;
@@ -488,8 +557,45 @@ private:
ReservedSpace = std::max(E + E / 2, 2u);
growHungoffUses(ReservedSpace, /* IsPhi */ true);
}
+
+ static void deleteMe(DerivedUser *Self);
};
+inline unsigned MemoryAccess::getID() const {
+ assert((isa<MemoryDef>(this) || isa<MemoryPhi>(this)) &&
+ "only memory defs and phis have ids");
+ if (const auto *MD = dyn_cast<MemoryDef>(this))
+ return MD->getID();
+ return cast<MemoryPhi>(this)->getID();
+}
+
+inline bool MemoryUseOrDef::isOptimized() const {
+ if (const auto *MD = dyn_cast<MemoryDef>(this))
+ return MD->isOptimized();
+ return cast<MemoryUse>(this)->isOptimized();
+}
+
+inline MemoryAccess *MemoryUseOrDef::getOptimized() const {
+ if (const auto *MD = dyn_cast<MemoryDef>(this))
+ return MD->getOptimized();
+ return cast<MemoryUse>(this)->getOptimized();
+}
+
+inline void MemoryUseOrDef::setOptimized(MemoryAccess *MA) {
+ if (auto *MD = dyn_cast<MemoryDef>(this))
+ MD->setOptimized(MA);
+ else
+ cast<MemoryUse>(this)->setOptimized(MA);
+}
+
+inline void MemoryUseOrDef::resetOptimized() {
+ if (auto *MD = dyn_cast<MemoryDef>(this))
+ MD->resetOptimized();
+ else
+ cast<MemoryUse>(this)->resetOptimized();
+}
+
+
template <> struct OperandTraits<MemoryPhi> : public HungoffOperandTraits<2> {};
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(MemoryPhi, MemoryAccess)
@@ -529,7 +635,14 @@ public:
return LiveOnEntryDef.get();
}
- using AccessList = iplist<MemoryAccess>;
+ // Sadly, iplists, by default, owns and deletes pointers added to the
+ // list. It's not currently possible to have two iplists for the same type,
+ // where one owns the pointers, and one does not. This is because the traits
+ // are per-type, not per-tag. If this ever changes, we should make the
+ // DefList an iplist.
+ using AccessList = iplist<MemoryAccess, ilist_tag<MSSAHelpers::AllAccessTag>>;
+ using DefsList =
+ simple_ilist<MemoryAccess, ilist_tag<MSSAHelpers::DefsOnlyTag>>;
/// \brief Return the list of MemoryAccess's for a given basic block.
///
@@ -538,62 +651,13 @@ public:
return getWritableBlockAccesses(BB);
}
- /// \brief Create an empty MemoryPhi in MemorySSA for a given basic block.
- /// Only one MemoryPhi for a block exists at a time, so this function will
- /// assert if you try to create one where it already exists.
- MemoryPhi *createMemoryPhi(BasicBlock *BB);
-
- enum InsertionPlace { Beginning, End };
-
- /// \brief Create a MemoryAccess in MemorySSA at a specified point in a block,
- /// with a specified clobbering definition.
- ///
- /// Returns the new MemoryAccess.
- /// This should be called when a memory instruction is created that is being
- /// used to replace an existing memory instruction. It will *not* create PHI
- /// nodes, or verify the clobbering definition. The insertion place is used
- /// solely to determine where in the memoryssa access lists the instruction
- /// will be placed. The caller is expected to keep ordering the same as
- /// instructions.
- /// It will return the new MemoryAccess.
- /// Note: If a MemoryAccess already exists for I, this function will make it
- /// inaccessible and it *must* have removeMemoryAccess called on it.
- MemoryAccess *createMemoryAccessInBB(Instruction *I, MemoryAccess *Definition,
- const BasicBlock *BB,
- InsertionPlace Point);
- /// \brief Create a MemoryAccess in MemorySSA before or after an existing
- /// MemoryAccess.
+ /// \brief Return the list of MemoryDef's and MemoryPhi's for a given basic
+ /// block.
///
- /// Returns the new MemoryAccess.
- /// This should be called when a memory instruction is created that is being
- /// used to replace an existing memory instruction. It will *not* create PHI
- /// nodes, or verify the clobbering definition. The clobbering definition
- /// must be non-null.
- /// Note: If a MemoryAccess already exists for I, this function will make it
- /// inaccessible and it *must* have removeMemoryAccess called on it.
- MemoryUseOrDef *createMemoryAccessBefore(Instruction *I,
- MemoryAccess *Definition,
- MemoryUseOrDef *InsertPt);
- MemoryUseOrDef *createMemoryAccessAfter(Instruction *I,
- MemoryAccess *Definition,
- MemoryAccess *InsertPt);
-
- // \brief Splice \p What to just before \p Where.
- //
- // In order to be efficient, the following conditions must be met:
- // - \p Where dominates \p What,
- // - All memory accesses in [\p Where, \p What) are no-alias with \p What.
- //
- // TODO: relax the MemoryDef requirement on Where.
- void spliceMemoryAccessAbove(MemoryDef *Where, MemoryUseOrDef *What);
-
- /// \brief Remove a MemoryAccess from MemorySSA, including updating all
- /// definitions and uses.
- /// This should be called when a memory instruction that has a MemoryAccess
- /// associated with it is erased from the program. For example, if a store or
- /// load is simply erased (not replaced), removeMemoryAccess should be called
- /// on the MemoryAccess for that store/load.
- void removeMemoryAccess(MemoryAccess *);
+ /// This list is not modifiable by the user.
+ const DefsList *getBlockDefs(const BasicBlock *BB) const {
+ return getWritableBlockDefs(BB);
+ }
/// \brief Given two memory accesses in the same basic block, determine
/// whether MemoryAccess \p A dominates MemoryAccess \p B.
@@ -611,20 +675,51 @@ public:
/// all uses, uses appear in the right places). This is used by unit tests.
void verifyMemorySSA() const;
+ /// Used in various insertion functions to specify whether we are talking
+ /// about the beginning or end of a block.
+ enum InsertionPlace { Beginning, End };
+
protected:
// Used by Memory SSA annotater, dumpers, and wrapper pass
friend class MemorySSAAnnotatedWriter;
friend class MemorySSAPrinterLegacyPass;
+ friend class MemorySSAUpdater;
+
void verifyDefUses(Function &F) const;
void verifyDomination(Function &F) const;
void verifyOrdering(Function &F) const;
- // This is used by the use optimizer class
+ // This is used by the use optimizer and updater.
AccessList *getWritableBlockAccesses(const BasicBlock *BB) const {
auto It = PerBlockAccesses.find(BB);
return It == PerBlockAccesses.end() ? nullptr : It->second.get();
}
+ // This is used by the use optimizer and updater.
+ DefsList *getWritableBlockDefs(const BasicBlock *BB) const {
+ auto It = PerBlockDefs.find(BB);
+ return It == PerBlockDefs.end() ? nullptr : It->second.get();
+ }
+
+ // These is used by the updater to perform various internal MemorySSA
+ // machinsations. They do not always leave the IR in a correct state, and
+ // relies on the updater to fixup what it breaks, so it is not public.
+
+ void moveTo(MemoryUseOrDef *What, BasicBlock *BB, AccessList::iterator Where);
+ void moveTo(MemoryUseOrDef *What, BasicBlock *BB, InsertionPlace Point);
+ // Rename the dominator tree branch rooted at BB.
+ void renamePass(BasicBlock *BB, MemoryAccess *IncomingVal,
+ SmallPtrSetImpl<BasicBlock *> &Visited) {
+ renamePass(DT->getNode(BB), IncomingVal, Visited, true, true);
+ }
+ void removeFromLookups(MemoryAccess *);
+ void removeFromLists(MemoryAccess *, bool ShouldDelete = true);
+ void insertIntoListsForBlock(MemoryAccess *, const BasicBlock *,
+ InsertionPlace);
+ void insertIntoListsBefore(MemoryAccess *, const BasicBlock *,
+ AccessList::iterator);
+ MemoryUseOrDef *createDefinedAccess(Instruction *, MemoryAccess *);
+
private:
class CachingWalker;
class OptimizeUses;
@@ -635,32 +730,39 @@ private:
void verifyUseInDefs(MemoryAccess *, MemoryAccess *) const;
using AccessMap = DenseMap<const BasicBlock *, std::unique_ptr<AccessList>>;
+ using DefsMap = DenseMap<const BasicBlock *, std::unique_ptr<DefsList>>;
void
determineInsertionPoint(const SmallPtrSetImpl<BasicBlock *> &DefiningBlocks);
- void computeDomLevels(DenseMap<DomTreeNode *, unsigned> &DomLevels);
void markUnreachableAsLiveOnEntry(BasicBlock *BB);
bool dominatesUse(const MemoryAccess *, const MemoryAccess *) const;
+ MemoryPhi *createMemoryPhi(BasicBlock *BB);
MemoryUseOrDef *createNewAccess(Instruction *);
- MemoryUseOrDef *createDefinedAccess(Instruction *, MemoryAccess *);
MemoryAccess *findDominatingDef(BasicBlock *, enum InsertionPlace);
- void removeFromLookups(MemoryAccess *);
-
void placePHINodes(const SmallPtrSetImpl<BasicBlock *> &,
const DenseMap<const BasicBlock *, unsigned int> &);
- MemoryAccess *renameBlock(BasicBlock *, MemoryAccess *);
+ MemoryAccess *renameBlock(BasicBlock *, MemoryAccess *, bool);
+ void renameSuccessorPhis(BasicBlock *, MemoryAccess *, bool);
void renamePass(DomTreeNode *, MemoryAccess *IncomingVal,
- SmallPtrSet<BasicBlock *, 16> &Visited);
+ SmallPtrSetImpl<BasicBlock *> &Visited,
+ bool SkipVisited = false, bool RenameAllUses = false);
AccessList *getOrCreateAccessList(const BasicBlock *);
+ DefsList *getOrCreateDefsList(const BasicBlock *);
void renumberBlock(const BasicBlock *) const;
-
AliasAnalysis *AA;
DominatorTree *DT;
Function &F;
// Memory SSA mappings
DenseMap<const Value *, MemoryAccess *> ValueToMemoryAccess;
+ // These two mappings contain the main block to access/def mappings for
+ // MemorySSA. The list contained in PerBlockAccesses really owns all the
+ // MemoryAccesses.
+ // Both maps maintain the invariant that if a block is found in them, the
+ // corresponding list is not empty, and if a block is not found in them, the
+ // corresponding list is empty.
AccessMap PerBlockAccesses;
+ DefsMap PerBlockDefs;
std::unique_ptr<MemoryAccess> LiveOnEntryDef;
// Domination mappings
@@ -674,21 +776,33 @@ private:
unsigned NextID;
};
+// Internal MemorySSA utils, for use by MemorySSA classes and walkers
+class MemorySSAUtil {
+protected:
+ friend class MemorySSAWalker;
+ friend class GVNHoist;
+ // This function should not be used by new passes.
+ static bool defClobbersUseOrDef(MemoryDef *MD, const MemoryUseOrDef *MU,
+ AliasAnalysis &AA);
+};
+
// This pass does eager building and then printing of MemorySSA. It is used by
// the tests to be able to build, dump, and verify Memory SSA.
class MemorySSAPrinterLegacyPass : public FunctionPass {
public:
MemorySSAPrinterLegacyPass();
- static char ID;
bool runOnFunction(Function &) override;
void getAnalysisUsage(AnalysisUsage &AU) const override;
+
+ static char ID;
};
/// An analysis that produces \c MemorySSA for a function.
///
class MemorySSAAnalysis : public AnalysisInfoMixin<MemorySSAAnalysis> {
friend AnalysisInfoMixin<MemorySSAAnalysis>;
+
static AnalysisKey Key;
public:
@@ -711,6 +825,7 @@ class MemorySSAPrinterPass : public PassInfoMixin<MemorySSAPrinterPass> {
public:
explicit MemorySSAPrinterPass(raw_ostream &OS) : OS(OS) {}
+
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
};
@@ -725,6 +840,7 @@ public:
MemorySSAWrapperPass();
static char ID;
+
bool runOnFunction(Function &) override;
void releaseMemory() override;
MemorySSA &getMSSA() { return *MSSA; }
@@ -753,7 +869,7 @@ private:
class MemorySSAWalker {
public:
MemorySSAWalker(MemorySSA *);
- virtual ~MemorySSAWalker() {}
+ virtual ~MemorySSAWalker() = default;
using MemoryAccessSet = SmallVector<MemoryAccess *, 8>;
@@ -825,6 +941,7 @@ public:
// Keep the overrides below from hiding the Instruction overload of
// getClobberingMemoryAccess.
using MemorySSAWalker::getClobberingMemoryAccess;
+
MemoryAccess *getClobberingMemoryAccess(MemoryAccess *) override;
MemoryAccess *getClobberingMemoryAccess(MemoryAccess *,
const MemoryLocation &) override;
@@ -843,8 +960,9 @@ class memoryaccess_def_iterator_base
using BaseT = typename memoryaccess_def_iterator_base::iterator_facade_base;
public:
- memoryaccess_def_iterator_base(T *Start) : Access(Start), ArgNo(0) {}
- memoryaccess_def_iterator_base() : Access(nullptr), ArgNo(0) {}
+ memoryaccess_def_iterator_base(T *Start) : Access(Start) {}
+ memoryaccess_def_iterator_base() = default;
+
bool operator==(const memoryaccess_def_iterator_base &Other) const {
return Access == Other.Access && (!Access || ArgNo == Other.ArgNo);
}
@@ -883,8 +1001,8 @@ public:
}
private:
- T *Access;
- unsigned ArgNo;
+ T *Access = nullptr;
+ unsigned ArgNo = 0;
};
inline memoryaccess_def_iterator MemoryAccess::defs_begin() {
@@ -947,10 +1065,7 @@ public:
fillInCurrentPair();
}
- upward_defs_iterator()
- : DefIterator(), Location(), OriginalAccess(), WalkingPhi(false) {
- CurrentPair.first = nullptr;
- }
+ upward_defs_iterator() { CurrentPair.first = nullptr; }
bool operator==(const upward_defs_iterator &Other) const {
return DefIterator == Other.DefIterator;
@@ -995,8 +1110,8 @@ private:
MemoryAccessPair CurrentPair;
memoryaccess_def_iterator DefIterator;
MemoryLocation Location;
- MemoryAccess *OriginalAccess;
- bool WalkingPhi;
+ MemoryAccess *OriginalAccess = nullptr;
+ bool WalkingPhi = false;
};
inline upward_defs_iterator upward_defs_begin(const MemoryAccessPair &Pair) {
@@ -1005,10 +1120,69 @@ inline upward_defs_iterator upward_defs_begin(const MemoryAccessPair &Pair) {
inline upward_defs_iterator upward_defs_end() { return upward_defs_iterator(); }
-// Return true when MD may alias MU, return false otherwise.
-bool defClobbersUseOrDef(MemoryDef *MD, const MemoryUseOrDef *MU,
- AliasAnalysis &AA);
+inline iterator_range<upward_defs_iterator>
+upward_defs(const MemoryAccessPair &Pair) {
+ return make_range(upward_defs_begin(Pair), upward_defs_end());
+}
+
+/// Walks the defining accesses of MemoryDefs. Stops after we hit something that
+/// has no defining use (e.g. a MemoryPhi or liveOnEntry). Note that, when
+/// comparing against a null def_chain_iterator, this will compare equal only
+/// after walking said Phi/liveOnEntry.
+///
+/// The UseOptimizedChain flag specifies whether to walk the clobbering
+/// access chain, or all the accesses.
+///
+/// Normally, MemoryDef are all just def/use linked together, so a def_chain on
+/// a MemoryDef will walk all MemoryDefs above it in the program until it hits
+/// a phi node. The optimized chain walks the clobbering access of a store.
+/// So if you are just trying to find, given a store, what the next
+/// thing that would clobber the same memory is, you want the optimized chain.
+template <class T, bool UseOptimizedChain = false>
+struct def_chain_iterator
+ : public iterator_facade_base<def_chain_iterator<T, UseOptimizedChain>,
+ std::forward_iterator_tag, MemoryAccess *> {
+ def_chain_iterator() : MA(nullptr) {}
+ def_chain_iterator(T MA) : MA(MA) {}
+
+ T operator*() const { return MA; }
+
+ def_chain_iterator &operator++() {
+ // N.B. liveOnEntry has a null defining access.
+ if (auto *MUD = dyn_cast<MemoryUseOrDef>(MA)) {
+ if (UseOptimizedChain && MUD->isOptimized())
+ MA = MUD->getOptimized();
+ else
+ MA = MUD->getDefiningAccess();
+ } else {
+ MA = nullptr;
+ }
+
+ return *this;
+ }
+
+ bool operator==(const def_chain_iterator &O) const { return MA == O.MA; }
+
+private:
+ T MA;
+};
+
+template <class T>
+inline iterator_range<def_chain_iterator<T>>
+def_chain(T MA, MemoryAccess *UpTo = nullptr) {
+#ifdef EXPENSIVE_CHECKS
+ assert((!UpTo || find(def_chain(MA), UpTo) != def_chain_iterator<T>()) &&
+ "UpTo isn't in the def chain!");
+#endif
+ return make_range(def_chain_iterator<T>(MA), def_chain_iterator<T>(UpTo));
+}
+
+template <class T>
+inline iterator_range<def_chain_iterator<T, true>> optimized_def_chain(T MA) {
+ return make_range(def_chain_iterator<T, true>(MA),
+ def_chain_iterator<T, true>(nullptr));
+}
} // end namespace llvm
-#endif // LLVM_TRANSFORMS_UTILS_MEMORYSSA_H
+#endif // LLVM_ANALYSIS_MEMORYSSA_H
diff --git a/contrib/llvm/include/llvm/Analysis/MemorySSAUpdater.h b/contrib/llvm/include/llvm/Analysis/MemorySSAUpdater.h
new file mode 100644
index 0000000..b36b2f0
--- /dev/null
+++ b/contrib/llvm/include/llvm/Analysis/MemorySSAUpdater.h
@@ -0,0 +1,153 @@
+//===- MemorySSAUpdater.h - Memory SSA Updater-------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// \file
+// \brief An automatic updater for MemorySSA that handles arbitrary insertion,
+// deletion, and moves. It performs phi insertion where necessary, and
+// automatically updates the MemorySSA IR to be correct.
+// While updating loads or removing instructions is often easy enough to not
+// need this, updating stores should generally not be attemped outside this
+// API.
+//
+// Basic API usage:
+// Create the memory access you want for the instruction (this is mainly so
+// we know where it is, without having to duplicate the entire set of create
+// functions MemorySSA supports).
+// Call insertDef or insertUse depending on whether it's a MemoryUse or a
+// MemoryDef.
+// That's it.
+//
+// For moving, first, move the instruction itself using the normal SSA
+// instruction moving API, then just call moveBefore, moveAfter,or moveTo with
+// the right arguments.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_MEMORYSSAUPDATER_H
+#define LLVM_ANALYSIS_MEMORYSSAUPDATER_H
+
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Analysis/MemorySSA.h"
+#include "llvm/IR/BasicBlock.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/Pass.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/ErrorHandling.h"
+
+namespace llvm {
+
+class Function;
+class Instruction;
+class MemoryAccess;
+class LLVMContext;
+class raw_ostream;
+
+class MemorySSAUpdater {
+private:
+ MemorySSA *MSSA;
+ SmallVector<MemoryPhi *, 8> InsertedPHIs;
+ SmallPtrSet<BasicBlock *, 8> VisitedBlocks;
+
+public:
+ MemorySSAUpdater(MemorySSA *MSSA) : MSSA(MSSA) {}
+ /// Insert a definition into the MemorySSA IR. RenameUses will rename any use
+ /// below the new def block (and any inserted phis). RenameUses should be set
+ /// to true if the definition may cause new aliases for loads below it. This
+ /// is not the case for hoisting or sinking or other forms of code *movement*.
+ /// It *is* the case for straight code insertion.
+ /// For example:
+ /// store a
+ /// if (foo) { }
+ /// load a
+ ///
+ /// Moving the store into the if block, and calling insertDef, does not
+ /// require RenameUses.
+ /// However, changing it to:
+ /// store a
+ /// if (foo) { store b }
+ /// load a
+ /// Where a mayalias b, *does* require RenameUses be set to true.
+ void insertDef(MemoryDef *Def, bool RenameUses = false);
+ void insertUse(MemoryUse *Use);
+ void moveBefore(MemoryUseOrDef *What, MemoryUseOrDef *Where);
+ void moveAfter(MemoryUseOrDef *What, MemoryUseOrDef *Where);
+ void moveToPlace(MemoryUseOrDef *What, BasicBlock *BB,
+ MemorySSA::InsertionPlace Where);
+
+ // The below are utility functions. Other than creation of accesses to pass
+ // to insertDef, and removeAccess to remove accesses, you should generally
+ // not attempt to update memoryssa yourself. It is very non-trivial to get
+ // the edge cases right, and the above calls already operate in near-optimal
+ // time bounds.
+
+ /// \brief Create a MemoryAccess in MemorySSA at a specified point in a block,
+ /// with a specified clobbering definition.
+ ///
+ /// Returns the new MemoryAccess.
+ /// This should be called when a memory instruction is created that is being
+ /// used to replace an existing memory instruction. It will *not* create PHI
+ /// nodes, or verify the clobbering definition. The insertion place is used
+ /// solely to determine where in the memoryssa access lists the instruction
+ /// will be placed. The caller is expected to keep ordering the same as
+ /// instructions.
+ /// It will return the new MemoryAccess.
+ /// Note: If a MemoryAccess already exists for I, this function will make it
+ /// inaccessible and it *must* have removeMemoryAccess called on it.
+ MemoryAccess *createMemoryAccessInBB(Instruction *I, MemoryAccess *Definition,
+ const BasicBlock *BB,
+ MemorySSA::InsertionPlace Point);
+
+ /// \brief Create a MemoryAccess in MemorySSA before or after an existing
+ /// MemoryAccess.
+ ///
+ /// Returns the new MemoryAccess.
+ /// This should be called when a memory instruction is created that is being
+ /// used to replace an existing memory instruction. It will *not* create PHI
+ /// nodes, or verify the clobbering definition.
+ ///
+ /// Note: If a MemoryAccess already exists for I, this function will make it
+ /// inaccessible and it *must* have removeMemoryAccess called on it.
+ MemoryUseOrDef *createMemoryAccessBefore(Instruction *I,
+ MemoryAccess *Definition,
+ MemoryUseOrDef *InsertPt);
+ MemoryUseOrDef *createMemoryAccessAfter(Instruction *I,
+ MemoryAccess *Definition,
+ MemoryAccess *InsertPt);
+
+ /// \brief Remove a MemoryAccess from MemorySSA, including updating all
+ /// definitions and uses.
+ /// This should be called when a memory instruction that has a MemoryAccess
+ /// associated with it is erased from the program. For example, if a store or
+ /// load is simply erased (not replaced), removeMemoryAccess should be called
+ /// on the MemoryAccess for that store/load.
+ void removeMemoryAccess(MemoryAccess *);
+
+private:
+ // Move What before Where in the MemorySSA IR.
+ template <class WhereType>
+ void moveTo(MemoryUseOrDef *What, BasicBlock *BB, WhereType Where);
+ MemoryAccess *getPreviousDef(MemoryAccess *);
+ MemoryAccess *getPreviousDefInBlock(MemoryAccess *);
+ MemoryAccess *getPreviousDefFromEnd(BasicBlock *);
+ MemoryAccess *getPreviousDefRecursive(BasicBlock *);
+ MemoryAccess *recursePhi(MemoryAccess *Phi);
+ template <class RangeType>
+ MemoryAccess *tryRemoveTrivialPhi(MemoryPhi *Phi, RangeType &Operands);
+ void fixupDefs(const SmallVectorImpl<MemoryAccess *> &);
+};
+} // end namespace llvm
+
+#endif // LLVM_ANALYSIS_MEMORYSSAUPDATER_H
diff --git a/contrib/llvm/include/llvm/Analysis/ObjCARCAnalysisUtils.h b/contrib/llvm/include/llvm/Analysis/ObjCARCAnalysisUtils.h
index 5f4d8ec..e80412a 100644
--- a/contrib/llvm/include/llvm/Analysis/ObjCARCAnalysisUtils.h
+++ b/contrib/llvm/include/llvm/Analysis/ObjCARCAnalysisUtils.h
@@ -23,8 +23,8 @@
#ifndef LLVM_LIB_ANALYSIS_OBJCARCANALYSISUTILS_H
#define LLVM_LIB_ANALYSIS_OBJCARCANALYSISUTILS_H
-#include "llvm/ADT/StringSwitch.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"
diff --git a/contrib/llvm/include/llvm/Analysis/ObjCARCInstKind.h b/contrib/llvm/include/llvm/Analysis/ObjCARCInstKind.h
index 3b37ddf7..02ff035 100644
--- a/contrib/llvm/include/llvm/Analysis/ObjCARCInstKind.h
+++ b/contrib/llvm/include/llvm/Analysis/ObjCARCInstKind.h
@@ -10,8 +10,8 @@
#ifndef LLVM_ANALYSIS_OBJCARCINSTKIND_H
#define LLVM_ANALYSIS_OBJCARCINSTKIND_H
-#include "llvm/IR/Instructions.h"
#include "llvm/IR/Function.h"
+#include "llvm/IR/Instructions.h"
namespace llvm {
namespace objcarc {
diff --git a/contrib/llvm/include/llvm/Analysis/ObjectUtils.h b/contrib/llvm/include/llvm/Analysis/ObjectUtils.h
new file mode 100644
index 0000000..2ad3b17
--- /dev/null
+++ b/contrib/llvm/include/llvm/Analysis/ObjectUtils.h
@@ -0,0 +1,42 @@
+//===- Analysis/ObjectUtils.h - analysis utils for object files -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_OBJECT_UTILS_H
+#define LLVM_ANALYSIS_OBJECT_UTILS_H
+
+#include "llvm/IR/GlobalVariable.h"
+
+namespace llvm {
+
+/// True if GV can be left out of the object symbol table. This is the case
+/// for linkonce_odr values whose address is not significant. While legal, it is
+/// not normally profitable to omit them from the .o symbol table. Using this
+/// analysis makes sense when the information can be passed down to the linker
+/// or we are in LTO.
+inline bool canBeOmittedFromSymbolTable(const GlobalValue *GV) {
+ if (!GV->hasLinkOnceODRLinkage())
+ return false;
+
+ // We assume that anyone who sets global unnamed_addr on a non-constant knows
+ // what they're doing.
+ if (GV->hasGlobalUnnamedAddr())
+ return true;
+
+ // If it is a non constant variable, it needs to be uniqued across shared
+ // objects.
+ if (auto *Var = dyn_cast<GlobalVariable>(GV))
+ if (!Var->isConstant())
+ return false;
+
+ return GV->hasAtLeastLocalUnnamedAddr();
+}
+
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/Analysis/OptimizationDiagnosticInfo.h b/contrib/llvm/include/llvm/Analysis/OptimizationDiagnosticInfo.h
index 3926926..64dd073 100644
--- a/contrib/llvm/include/llvm/Analysis/OptimizationDiagnosticInfo.h
+++ b/contrib/llvm/include/llvm/Analysis/OptimizationDiagnosticInfo.h
@@ -34,25 +34,25 @@ class Value;
///
/// It allows reporting when optimizations are performed and when they are not
/// along with the reasons for it. Hotness information of the corresponding
-/// code region can be included in the remark if DiagnosticHotnessRequested is
+/// code region can be included in the remark if DiagnosticsHotnessRequested is
/// enabled in the LLVM context.
class OptimizationRemarkEmitter {
public:
- OptimizationRemarkEmitter(Function *F, BlockFrequencyInfo *BFI)
+ OptimizationRemarkEmitter(const Function *F, BlockFrequencyInfo *BFI)
: F(F), BFI(BFI) {}
/// \brief This variant can be used to generate ORE on demand (without the
/// analysis pass).
///
/// Note that this ctor has a very different cost depending on whether
- /// F->getContext().getDiagnosticHotnessRequested() is on or not. If it's off
+ /// F->getContext().getDiagnosticsHotnessRequested() is on or not. If it's off
/// the operation is free.
///
- /// Whereas if DiagnosticHotnessRequested is on, it is fairly expensive
+ /// Whereas if DiagnosticsHotnessRequested is on, it is fairly expensive
/// operation since BFI and all its required analyses are computed. This is
/// for example useful for CGSCC passes that can't use function analyses
/// passes in the old PM.
- OptimizationRemarkEmitter(Function *F);
+ OptimizationRemarkEmitter(const Function *F);
OptimizationRemarkEmitter(OptimizationRemarkEmitter &&Arg)
: F(Arg.F), BFI(Arg.BFI) {}
@@ -63,136 +63,16 @@ public:
return *this;
}
- /// The new interface to emit remarks.
- void emit(DiagnosticInfoOptimizationBase &OptDiag);
-
- /// Emit an optimization-applied message.
- ///
- /// \p PassName is the name of the pass emitting the message. If -Rpass= is
- /// given and \p PassName matches the regular expression in -Rpass, then the
- /// remark will be emitted. \p Fn is the function triggering the remark, \p
- /// DLoc is the debug location where the diagnostic is generated. \p V is the
- /// IR Value that identifies the code region. \p Msg is the message string to
- /// use.
- void emitOptimizationRemark(const char *PassName, const DebugLoc &DLoc,
- const Value *V, const Twine &Msg);
-
- /// \brief Same as above but derives the IR Value for the code region and the
- /// debug location from the Loop parameter \p L.
- void emitOptimizationRemark(const char *PassName, Loop *L, const Twine &Msg);
-
- /// \brief Same as above but derives the debug location and the code region
- /// from the debug location and the basic block of \p Inst, respectively.
- void emitOptimizationRemark(const char *PassName, Instruction *Inst,
- const Twine &Msg) {
- emitOptimizationRemark(PassName, Inst->getDebugLoc(), Inst->getParent(),
- Msg);
- }
-
- /// Emit an optimization-missed message.
- ///
- /// \p PassName is the name of the pass emitting the message. If
- /// -Rpass-missed= is given and the name matches the regular expression in
- /// -Rpass, then the remark will be emitted. \p DLoc is the debug location
- /// where the diagnostic is generated. \p V is the IR Value that identifies
- /// the code region. \p Msg is the message string to use. If \p IsVerbose is
- /// true, the message is considered verbose and will only be emitted when
- /// verbose output is turned on.
- void emitOptimizationRemarkMissed(const char *PassName, const DebugLoc &DLoc,
- const Value *V, const Twine &Msg,
- bool IsVerbose = false);
-
- /// \brief Same as above but derives the IR Value for the code region and the
- /// debug location from the Loop parameter \p L.
- void emitOptimizationRemarkMissed(const char *PassName, Loop *L,
- const Twine &Msg, bool IsVerbose = false);
-
- /// \brief Same as above but derives the debug location and the code region
- /// from the debug location and the basic block of \p Inst, respectively.
- void emitOptimizationRemarkMissed(const char *PassName, Instruction *Inst,
- const Twine &Msg, bool IsVerbose = false) {
- emitOptimizationRemarkMissed(PassName, Inst->getDebugLoc(),
- Inst->getParent(), Msg, IsVerbose);
- }
-
- /// Emit an optimization analysis remark message.
- ///
- /// \p PassName is the name of the pass emitting the message. If
- /// -Rpass-analysis= is given and \p PassName matches the regular expression
- /// in -Rpass, then the remark will be emitted. \p DLoc is the debug location
- /// where the diagnostic is generated. \p V is the IR Value that identifies
- /// the code region. \p Msg is the message string to use. If \p IsVerbose is
- /// true, the message is considered verbose and will only be emitted when
- /// verbose output is turned on.
- void emitOptimizationRemarkAnalysis(const char *PassName,
- const DebugLoc &DLoc, const Value *V,
- const Twine &Msg, bool IsVerbose = false);
-
- /// \brief Same as above but derives the IR Value for the code region and the
- /// debug location from the Loop parameter \p L.
- void emitOptimizationRemarkAnalysis(const char *PassName, Loop *L,
- const Twine &Msg, bool IsVerbose = false);
+ /// Handle invalidation events in the new pass manager.
+ bool invalidate(Function &F, const PreservedAnalyses &PA,
+ FunctionAnalysisManager::Invalidator &Inv);
- /// \brief Same as above but derives the debug location and the code region
- /// from the debug location and the basic block of \p Inst, respectively.
- void emitOptimizationRemarkAnalysis(const char *PassName, Instruction *Inst,
- const Twine &Msg,
- bool IsVerbose = false) {
- emitOptimizationRemarkAnalysis(PassName, Inst->getDebugLoc(),
- Inst->getParent(), Msg, IsVerbose);
- }
-
- /// \brief This variant allows specifying what should be emitted for missed
- /// and analysis remarks in one call.
- ///
- /// \p PassName is the name of the pass emitting the message. If
- /// -Rpass-missed= is given and \p PassName matches the regular expression, \p
- /// MsgForMissedRemark is emitted.
- ///
- /// If -Rpass-analysis= is given and \p PassName matches the regular
- /// expression, \p MsgForAnalysisRemark is emitted.
- ///
- /// The debug location and the code region is derived from \p Inst. If \p
- /// IsVerbose is true, the message is considered verbose and will only be
- /// emitted when verbose output is turned on.
- void emitOptimizationRemarkMissedAndAnalysis(
- const char *PassName, Instruction *Inst, const Twine &MsgForMissedRemark,
- const Twine &MsgForAnalysisRemark, bool IsVerbose = false) {
- emitOptimizationRemarkAnalysis(PassName, Inst, MsgForAnalysisRemark,
- IsVerbose);
- emitOptimizationRemarkMissed(PassName, Inst, MsgForMissedRemark, IsVerbose);
- }
-
- /// \brief Emit an optimization analysis remark related to floating-point
- /// non-commutativity.
+ /// \brief Output the remark via the diagnostic handler and to the
+ /// optimization record file.
///
- /// \p PassName is the name of the pass emitting the message. If
- /// -Rpass-analysis= is given and \p PassName matches the regular expression
- /// in -Rpass, then the remark will be emitted. \p Fn is the function
- /// triggering the remark, \p DLoc is the debug location where the diagnostic
- /// is generated.\p V is the IR Value that identifies the code region. \p Msg
- /// is the message string to use.
- void emitOptimizationRemarkAnalysisFPCommute(const char *PassName,
- const DebugLoc &DLoc,
- const Value *V,
- const Twine &Msg);
-
- /// \brief Emit an optimization analysis remark related to pointer aliasing.
- ///
- /// \p PassName is the name of the pass emitting the message. If
- /// -Rpass-analysis= is given and \p PassName matches the regular expression
- /// in -Rpass, then the remark will be emitted. \p Fn is the function
- /// triggering the remark, \p DLoc is the debug location where the diagnostic
- /// is generated.\p V is the IR Value that identifies the code region. \p Msg
- /// is the message string to use.
- void emitOptimizationRemarkAnalysisAliasing(const char *PassName,
- const DebugLoc &DLoc,
- const Value *V, const Twine &Msg);
-
- /// \brief Same as above but derives the IR Value for the code region and the
- /// debug location from the Loop parameter \p L.
- void emitOptimizationRemarkAnalysisAliasing(const char *PassName, Loop *L,
- const Twine &Msg);
+ /// This is the new interface that should be now used rather than the legacy
+ /// emit* APIs.
+ void emit(DiagnosticInfoOptimizationBase &OptDiag);
/// \brief Whether we allow for extra compile-time budget to perform more
/// analysis to produce fewer false positives.
@@ -208,7 +88,7 @@ public:
}
private:
- Function *F;
+ const Function *F;
BlockFrequencyInfo *BFI;
@@ -220,7 +100,7 @@ private:
Optional<uint64_t> computeHotness(const Value *V);
/// Similar but use value from \p OptDiag and update hotness there.
- void computeHotness(DiagnosticInfoOptimizationBase &OptDiag);
+ void computeHotness(DiagnosticInfoIROptimization &OptDiag);
/// \brief Only allow verbose messages if we know we're filtering by hotness
/// (BFI is only set in this case).
@@ -274,5 +154,11 @@ public:
/// \brief Run the analysis pass over a function and produce BFI.
Result run(Function &F, FunctionAnalysisManager &AM);
};
+
+namespace yaml {
+template <> struct MappingTraits<DiagnosticInfoOptimizationBase *> {
+ static void mapping(IO &io, DiagnosticInfoOptimizationBase *&OptDiag);
+};
+}
}
#endif // LLVM_IR_OPTIMIZATIONDIAGNOSTICINFO_H
diff --git a/contrib/llvm/include/llvm/Analysis/OrderedBasicBlock.h b/contrib/llvm/include/llvm/Analysis/OrderedBasicBlock.h
index 5aa813e..2e716af 100644
--- a/contrib/llvm/include/llvm/Analysis/OrderedBasicBlock.h
+++ b/contrib/llvm/include/llvm/Analysis/OrderedBasicBlock.h
@@ -58,6 +58,7 @@ public:
/// 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);
};
diff --git a/contrib/llvm/include/llvm/Analysis/PostDominators.h b/contrib/llvm/include/llvm/Analysis/PostDominators.h
index 34361da..17f2e8e 100644
--- a/contrib/llvm/include/llvm/Analysis/PostDominators.h
+++ b/contrib/llvm/include/llvm/Analysis/PostDominators.h
@@ -22,10 +22,12 @@ namespace llvm {
/// PostDominatorTree Class - Concrete subclass of DominatorTree that is used to
/// compute the post-dominator tree.
///
-struct PostDominatorTree : public DominatorTreeBase<BasicBlock> {
- typedef DominatorTreeBase<BasicBlock> Base;
+struct PostDominatorTree : public PostDomTreeBase<BasicBlock> {
+ typedef PostDomTreeBase<BasicBlock> Base;
- PostDominatorTree() : DominatorTreeBase<BasicBlock>(true) {}
+ /// Handle invalidation explicitly.
+ bool invalidate(Function &F, const PreservedAnalyses &PA,
+ FunctionAnalysisManager::Invalidator &);
};
/// \brief Analysis pass which computes a \c PostDominatorTree.
diff --git a/contrib/llvm/include/llvm/Analysis/ProfileSummaryInfo.h b/contrib/llvm/include/llvm/Analysis/ProfileSummaryInfo.h
index d7fe76e..6aaabe1 100644
--- a/contrib/llvm/include/llvm/Analysis/ProfileSummaryInfo.h
+++ b/contrib/llvm/include/llvm/Analysis/ProfileSummaryInfo.h
@@ -29,6 +29,7 @@
namespace llvm {
class BasicBlock;
class BlockFrequencyInfo;
+class CallSite;
class ProfileSummary;
/// \brief Analysis providing profile information.
///
@@ -44,7 +45,7 @@ class ProfileSummaryInfo {
private:
Module &M;
std::unique_ptr<ProfileSummary> Summary;
- void computeSummary();
+ bool computeSummary();
void computeThresholds();
// Count thresholds to answer isHotCount and isColdCount queries.
Optional<uint64_t> HotCountThreshold, ColdCountThreshold;
@@ -53,16 +54,56 @@ public:
ProfileSummaryInfo(Module &M) : M(M) {}
ProfileSummaryInfo(ProfileSummaryInfo &&Arg)
: M(Arg.M), Summary(std::move(Arg.Summary)) {}
+
+ /// \brief Returns true if profile summary is available.
+ bool hasProfileSummary() { return computeSummary(); }
+
+ /// \brief Returns true if module \c M has sample profile.
+ bool hasSampleProfile() {
+ return hasProfileSummary() &&
+ Summary->getKind() == ProfileSummary::PSK_Sample;
+ }
+
+ /// \brief Returns true if module \c M has instrumentation profile.
+ bool hasInstrumentationProfile() {
+ return hasProfileSummary() &&
+ Summary->getKind() == ProfileSummary::PSK_Instr;
+ }
+
+ /// Handle the invalidation of this information.
+ ///
+ /// When used as a result of \c ProfileSummaryAnalysis this method will be
+ /// called when the module this was computed for changes. Since profile
+ /// summary is immutable after it is annotated on the module, we return false
+ /// here.
+ bool invalidate(Module &, const PreservedAnalyses &,
+ ModuleAnalysisManager::Invalidator &) {
+ return false;
+ }
+
+ /// Returns the profile count for \p CallInst.
+ Optional<uint64_t> getProfileCount(const Instruction *CallInst,
+ BlockFrequencyInfo *BFI);
/// \brief Returns true if \p F has hot function entry.
bool isFunctionEntryHot(const Function *F);
+ /// Returns true if \p F has hot function entry or hot call edge.
+ bool isFunctionHotInCallGraph(const Function *F);
/// \brief Returns true if \p F has cold function entry.
bool isFunctionEntryCold(const Function *F);
+ /// Returns true if \p F has cold function entry or cold call edge.
+ bool isFunctionColdInCallGraph(const Function *F);
/// \brief Returns true if \p F is a hot function.
bool isHotCount(uint64_t C);
/// \brief Returns true if count \p C is considered cold.
bool isColdCount(uint64_t C);
/// \brief Returns true if BasicBlock \p B is considered hot.
bool isHotBB(const BasicBlock *B, BlockFrequencyInfo *BFI);
+ /// \brief Returns true if BasicBlock \p B is considered cold.
+ bool isColdBB(const BasicBlock *B, BlockFrequencyInfo *BFI);
+ /// \brief Returns true if CallSite \p CS is considered hot.
+ bool isHotCallSite(const CallSite &CS, BlockFrequencyInfo *BFI);
+ /// \brief Returns true if Callsite \p CS is considered cold.
+ bool isColdCallSite(const CallSite &CS, BlockFrequencyInfo *BFI);
};
/// An analysis pass based on legacy pass manager to deliver ProfileSummaryInfo.
diff --git a/contrib/llvm/include/llvm/Analysis/PtrUseVisitor.h b/contrib/llvm/include/llvm/Analysis/PtrUseVisitor.h
index 6e61fc3..2fe7c67 100644
--- a/contrib/llvm/include/llvm/Analysis/PtrUseVisitor.h
+++ b/contrib/llvm/include/llvm/Analysis/PtrUseVisitor.h
@@ -196,7 +196,10 @@ class PtrUseVisitor : protected InstVisitor<DerivedT>,
typedef InstVisitor<DerivedT> Base;
public:
- PtrUseVisitor(const DataLayout &DL) : PtrUseVisitorBase(DL) {}
+ PtrUseVisitor(const DataLayout &DL) : PtrUseVisitorBase(DL) {
+ static_assert(std::is_base_of<PtrUseVisitor, DerivedT>::value,
+ "Must pass the derived type to this template!");
+ }
/// \brief Recursively visit the uses of the given pointer.
/// \returns An info struct about the pointer. See \c PtrInfo for details.
diff --git a/contrib/llvm/include/llvm/Analysis/RegionInfo.h b/contrib/llvm/include/llvm/Analysis/RegionInfo.h
index f2f27a1..2e34928 100644
--- a/contrib/llvm/include/llvm/Analysis/RegionInfo.h
+++ b/contrib/llvm/include/llvm/Analysis/RegionInfo.h
@@ -37,18 +37,38 @@
#ifndef LLVM_ANALYSIS_REGIONINFO_H
#define LLVM_ANALYSIS_REGIONINFO_H
+#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DepthFirstIterator.h"
+#include "llvm/ADT/GraphTraits.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/iterator_range.h"
-#include "llvm/IR/CFG.h"
+#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/PassManager.h"
+#include "llvm/Pass.h"
+#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+#include <cassert>
#include <map>
#include <memory>
#include <set>
+#include <string>
+#include <type_traits>
+#include <vector>
namespace llvm {
+class DominanceFrontier;
+class DominatorTree;
+class Loop;
+class LoopInfo;
+struct PostDominatorTree;
+class Region;
+template <class RegionTr> class RegionBase;
+class RegionInfo;
+template <class RegionTr> class RegionInfoBase;
+class RegionNode;
+
// Class to be specialized for different users of RegionInfo
// (i.e. BasicBlocks or MachineBasicBlocks). This is only to avoid needing to
// pass around an unreasonable number of template parameters.
@@ -59,37 +79,23 @@ struct RegionTraits {
// RegionT
// RegionNodeT
// RegionInfoT
- typedef typename FuncT_::UnknownRegionTypeError BrokenT;
+ using BrokenT = typename FuncT_::UnknownRegionTypeError;
};
-class DominatorTree;
-class DominanceFrontier;
-class Loop;
-class LoopInfo;
-struct PostDominatorTree;
-class raw_ostream;
-class Region;
-template <class RegionTr>
-class RegionBase;
-class RegionNode;
-class RegionInfo;
-template <class RegionTr>
-class RegionInfoBase;
-
template <>
struct RegionTraits<Function> {
- typedef Function FuncT;
- typedef BasicBlock BlockT;
- typedef Region RegionT;
- typedef RegionNode RegionNodeT;
- typedef RegionInfo RegionInfoT;
- typedef DominatorTree DomTreeT;
- typedef DomTreeNode DomTreeNodeT;
- typedef DominanceFrontier DomFrontierT;
- typedef PostDominatorTree PostDomTreeT;
- typedef Instruction InstT;
- typedef Loop LoopT;
- typedef LoopInfo LoopInfoT;
+ using FuncT = Function;
+ using BlockT = BasicBlock;
+ using RegionT = Region;
+ using RegionNodeT = RegionNode;
+ using RegionInfoT = RegionInfo;
+ using DomTreeT = DominatorTree;
+ using DomTreeNodeT = DomTreeNode;
+ using DomFrontierT = DominanceFrontier;
+ using PostDomTreeT = PostDominatorTree;
+ using InstT = Instruction;
+ using LoopT = Loop;
+ using LoopInfoT = LoopInfo;
static unsigned getNumSuccessors(BasicBlock *BB) {
return BB->getTerminator()->getNumSuccessors();
@@ -113,13 +119,10 @@ class RegionNodeBase {
friend class RegionBase<Tr>;
public:
- typedef typename Tr::BlockT BlockT;
- typedef typename Tr::RegionT RegionT;
+ using BlockT = typename Tr::BlockT;
+ using RegionT = typename Tr::RegionT;
private:
- RegionNodeBase(const RegionNodeBase &) = delete;
- const RegionNodeBase &operator=(const RegionNodeBase &) = delete;
-
/// This is the entry basic block that starts this region node. If this is a
/// BasicBlock RegionNode, then entry is just the basic block, that this
/// RegionNode represents. Otherwise it is the entry of this (Sub)RegionNode.
@@ -150,6 +153,9 @@ protected:
: entry(Entry, isSubRegion), parent(Parent) {}
public:
+ RegionNodeBase(const RegionNodeBase &) = delete;
+ RegionNodeBase &operator=(const RegionNodeBase &) = delete;
+
/// @brief Get the parent Region of this RegionNode.
///
/// The parent Region is the Region this RegionNode belongs to. If for
@@ -247,24 +253,22 @@ public:
/// tree, the second one creates a graphical representation using graphviz.
template <class Tr>
class RegionBase : public RegionNodeBase<Tr> {
- typedef typename Tr::FuncT FuncT;
- typedef typename Tr::BlockT BlockT;
- typedef typename Tr::RegionInfoT RegionInfoT;
- typedef typename Tr::RegionT RegionT;
- typedef typename Tr::RegionNodeT RegionNodeT;
- typedef typename Tr::DomTreeT DomTreeT;
- typedef typename Tr::LoopT LoopT;
- typedef typename Tr::LoopInfoT LoopInfoT;
- typedef typename Tr::InstT InstT;
-
- typedef GraphTraits<BlockT *> BlockTraits;
- typedef GraphTraits<Inverse<BlockT *>> InvBlockTraits;
- typedef typename BlockTraits::ChildIteratorType SuccIterTy;
- typedef typename InvBlockTraits::ChildIteratorType PredIterTy;
-
friend class RegionInfoBase<Tr>;
- RegionBase(const RegionBase &) = delete;
- const RegionBase &operator=(const RegionBase &) = delete;
+
+ using FuncT = typename Tr::FuncT;
+ using BlockT = typename Tr::BlockT;
+ using RegionInfoT = typename Tr::RegionInfoT;
+ using RegionT = typename Tr::RegionT;
+ using RegionNodeT = typename Tr::RegionNodeT;
+ using DomTreeT = typename Tr::DomTreeT;
+ using LoopT = typename Tr::LoopT;
+ using LoopInfoT = typename Tr::LoopInfoT;
+ using InstT = typename Tr::InstT;
+
+ using BlockTraits = GraphTraits<BlockT *>;
+ using InvBlockTraits = GraphTraits<Inverse<BlockT *>>;
+ using SuccIterTy = typename BlockTraits::ChildIteratorType;
+ using PredIterTy = typename InvBlockTraits::ChildIteratorType;
// Information necessary to manage this Region.
RegionInfoT *RI;
@@ -274,12 +278,12 @@ class RegionBase : public RegionNodeBase<Tr> {
// (The entry BasicBlock is part of RegionNode)
BlockT *exit;
- typedef std::vector<std::unique_ptr<RegionT>> RegionSet;
+ using RegionSet = std::vector<std::unique_ptr<RegionT>>;
// The subregions of this region.
RegionSet children;
- typedef std::map<BlockT *, std::unique_ptr<RegionNodeT>> BBNodeMapT;
+ using BBNodeMapT = std::map<BlockT *, std::unique_ptr<RegionNodeT>>;
// Save the BasicBlock RegionNodes that are element of this Region.
mutable BBNodeMapT BBNodeMap;
@@ -308,6 +312,9 @@ public:
RegionBase(BlockT *Entry, BlockT *Exit, RegionInfoT *RI, DomTreeT *DT,
RegionT *Parent = nullptr);
+ RegionBase(const RegionBase &) = delete;
+ RegionBase &operator=(const RegionBase &) = delete;
+
/// Delete the Region and all its subregions.
~RegionBase();
@@ -543,8 +550,8 @@ public:
///
/// These iterators iterator over all subregions of this Region.
//@{
- typedef typename RegionSet::iterator iterator;
- typedef typename RegionSet::const_iterator const_iterator;
+ using iterator = typename RegionSet::iterator;
+ using const_iterator = typename RegionSet::const_iterator;
iterator begin() { return children.begin(); }
iterator end() { return children.end(); }
@@ -563,12 +570,13 @@ public:
class block_iterator_wrapper
: public df_iterator<
typename std::conditional<IsConst, const BlockT, BlockT>::type *> {
- typedef df_iterator<
- typename std::conditional<IsConst, const BlockT, BlockT>::type *> super;
+ using super =
+ df_iterator<
+ typename std::conditional<IsConst, const BlockT, BlockT>::type *>;
public:
- typedef block_iterator_wrapper<IsConst> Self;
- typedef typename super::value_type value_type;
+ using Self = block_iterator_wrapper<IsConst>;
+ using value_type = typename super::value_type;
// Construct the begin iterator.
block_iterator_wrapper(value_type Entry, value_type Exit)
@@ -592,8 +600,8 @@ public:
}
};
- typedef block_iterator_wrapper<false> block_iterator;
- typedef block_iterator_wrapper<true> const_block_iterator;
+ using block_iterator = block_iterator_wrapper<false>;
+ using const_block_iterator = block_iterator_wrapper<true>;
block_iterator block_begin() { return block_iterator(getEntry(), getExit()); }
@@ -604,8 +612,8 @@ public:
}
const_block_iterator block_end() const { return const_block_iterator(); }
- typedef iterator_range<block_iterator> block_range;
- typedef iterator_range<const_block_iterator> const_block_range;
+ using block_range = iterator_range<block_iterator>;
+ using const_block_range = iterator_range<const_block_iterator>;
/// @brief Returns a range view of the basic blocks in the region.
inline block_range blocks() {
@@ -626,14 +634,14 @@ public:
/// are direct children of this Region. It does not iterate over any
/// RegionNodes that are also element of a subregion of this Region.
//@{
- typedef df_iterator<RegionNodeT *, df_iterator_default_set<RegionNodeT *>,
- false, GraphTraits<RegionNodeT *>>
- element_iterator;
+ using element_iterator =
+ df_iterator<RegionNodeT *, df_iterator_default_set<RegionNodeT *>, false,
+ GraphTraits<RegionNodeT *>>;
- typedef df_iterator<const RegionNodeT *,
- df_iterator_default_set<const RegionNodeT *>, false,
- GraphTraits<const RegionNodeT *>>
- const_element_iterator;
+ using const_element_iterator =
+ df_iterator<const RegionNodeT *,
+ df_iterator_default_set<const RegionNodeT *>, false,
+ GraphTraits<const RegionNodeT *>>;
element_iterator element_begin();
element_iterator element_end();
@@ -661,29 +669,26 @@ inline raw_ostream &operator<<(raw_ostream &OS, const RegionNodeBase<Tr> &Node);
/// Tree.
template <class Tr>
class RegionInfoBase {
- typedef typename Tr::BlockT BlockT;
- typedef typename Tr::FuncT FuncT;
- typedef typename Tr::RegionT RegionT;
- typedef typename Tr::RegionInfoT RegionInfoT;
- typedef typename Tr::DomTreeT DomTreeT;
- typedef typename Tr::DomTreeNodeT DomTreeNodeT;
- typedef typename Tr::PostDomTreeT PostDomTreeT;
- typedef typename Tr::DomFrontierT DomFrontierT;
- typedef GraphTraits<BlockT *> BlockTraits;
- typedef GraphTraits<Inverse<BlockT *>> InvBlockTraits;
- typedef typename BlockTraits::ChildIteratorType SuccIterTy;
- typedef typename InvBlockTraits::ChildIteratorType PredIterTy;
-
friend class RegionInfo;
friend class MachineRegionInfo;
- typedef DenseMap<BlockT *, BlockT *> BBtoBBMap;
- typedef DenseMap<BlockT *, RegionT *> BBtoRegionMap;
- RegionInfoBase();
- virtual ~RegionInfoBase();
+ using BlockT = typename Tr::BlockT;
+ using FuncT = typename Tr::FuncT;
+ using RegionT = typename Tr::RegionT;
+ using RegionInfoT = typename Tr::RegionInfoT;
+ using DomTreeT = typename Tr::DomTreeT;
+ using DomTreeNodeT = typename Tr::DomTreeNodeT;
+ using PostDomTreeT = typename Tr::PostDomTreeT;
+ using DomFrontierT = typename Tr::DomFrontierT;
+ using BlockTraits = GraphTraits<BlockT *>;
+ using InvBlockTraits = GraphTraits<Inverse<BlockT *>>;
+ using SuccIterTy = typename BlockTraits::ChildIteratorType;
+ using PredIterTy = typename InvBlockTraits::ChildIteratorType;
+
+ using BBtoBBMap = DenseMap<BlockT *, BlockT *>;
+ using BBtoRegionMap = DenseMap<BlockT *, RegionT *>;
- RegionInfoBase(const RegionInfoBase &) = delete;
- const RegionInfoBase &operator=(const RegionInfoBase &) = delete;
+ RegionInfoBase();
RegionInfoBase(RegionInfoBase &&Arg)
: DT(std::move(Arg.DT)), PDT(std::move(Arg.PDT)), DF(std::move(Arg.DF)),
@@ -691,6 +696,7 @@ class RegionInfoBase {
BBtoRegion(std::move(Arg.BBtoRegion)) {
Arg.wipe();
}
+
RegionInfoBase &operator=(RegionInfoBase &&RHS) {
DT = std::move(RHS.DT);
PDT = std::move(RHS.PDT);
@@ -701,17 +707,33 @@ class RegionInfoBase {
return *this;
}
+ virtual ~RegionInfoBase();
+
DomTreeT *DT;
PostDomTreeT *PDT;
DomFrontierT *DF;
/// The top level region.
- RegionT *TopLevelRegion;
+ RegionT *TopLevelRegion = nullptr;
-private:
/// Map every BB to the smallest region, that contains BB.
BBtoRegionMap BBtoRegion;
+protected:
+ /// \brief Update refences to a RegionInfoT held by the RegionT managed here
+ ///
+ /// This is a post-move helper. Regions hold references to the owning
+ /// RegionInfo object. After a move these need to be fixed.
+ template<typename TheRegionT>
+ void updateRegionTree(RegionInfoT &RI, TheRegionT *R) {
+ if (!R)
+ return;
+ R->RI = &RI;
+ for (auto &SubR : *R)
+ updateRegionTree(RI, SubR.get());
+ }
+
+private:
/// \brief Wipe this region tree's state without releasing any resources.
///
/// This is essentially a post-move helper only. It leaves the object in an
@@ -771,6 +793,9 @@ private:
void calculate(FuncT &F);
public:
+ RegionInfoBase(const RegionInfoBase &) = delete;
+ RegionInfoBase &operator=(const RegionInfoBase &) = delete;
+
static bool VerifyRegionInfo;
static typename RegionT::PrintStyle printStyle;
@@ -873,19 +898,26 @@ public:
class RegionInfo : public RegionInfoBase<RegionTraits<Function>> {
public:
- typedef RegionInfoBase<RegionTraits<Function>> Base;
+ using Base = RegionInfoBase<RegionTraits<Function>>;
explicit RegionInfo();
- ~RegionInfo() override;
+ RegionInfo(RegionInfo &&Arg) : Base(std::move(static_cast<Base &>(Arg))) {
+ updateRegionTree(*this, TopLevelRegion);
+ }
- RegionInfo(RegionInfo &&Arg)
- : Base(std::move(static_cast<Base &>(Arg))) {}
RegionInfo &operator=(RegionInfo &&RHS) {
Base::operator=(std::move(static_cast<Base &>(RHS)));
+ updateRegionTree(*this, TopLevelRegion);
return *this;
}
+ ~RegionInfo() override;
+
+ /// Handle invalidation explicitly.
+ bool invalidate(Function &F, const PreservedAnalyses &PA,
+ FunctionAnalysisManager::Invalidator &);
+
// updateStatistics - Update statistic about created regions.
void updateStatistics(Region *R) final;
@@ -911,8 +943,8 @@ class RegionInfoPass : public FunctionPass {
public:
static char ID;
- explicit RegionInfoPass();
+ explicit RegionInfoPass();
~RegionInfoPass() override;
RegionInfo &getRegionInfo() { return RI; }
@@ -933,10 +965,11 @@ public:
/// \brief Analysis pass that exposes the \c RegionInfo for a function.
class RegionInfoAnalysis : public AnalysisInfoMixin<RegionInfoAnalysis> {
friend AnalysisInfoMixin<RegionInfoAnalysis>;
+
static AnalysisKey Key;
public:
- typedef RegionInfo Result;
+ using Result = RegionInfo;
RegionInfo run(Function &F, FunctionAnalysisManager &AM);
};
@@ -947,6 +980,7 @@ class RegionInfoPrinterPass : public PassInfoMixin<RegionInfoPrinterPass> {
public:
explicit RegionInfoPrinterPass(raw_ostream &OS);
+
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
};
@@ -975,8 +1009,8 @@ RegionNodeBase<RegionTraits<Function>>::getNodeAs<Region>() const {
template <class Tr>
inline raw_ostream &operator<<(raw_ostream &OS,
const RegionNodeBase<Tr> &Node) {
- typedef typename Tr::BlockT BlockT;
- typedef typename Tr::RegionT RegionT;
+ using BlockT = typename Tr::BlockT;
+ using RegionT = typename Tr::RegionT;
if (Node.isSubRegion())
return OS << Node.template getNodeAs<RegionT>()->getNameStr();
@@ -988,5 +1022,6 @@ extern template class RegionBase<RegionTraits<Function>>;
extern template class RegionNodeBase<RegionTraits<Function>>;
extern template class RegionInfoBase<RegionTraits<Function>>;
-} // End llvm namespace
-#endif
+} // end namespace llvm
+
+#endif // LLVM_ANALYSIS_REGIONINFO_H
diff --git a/contrib/llvm/include/llvm/Analysis/RegionInfoImpl.h b/contrib/llvm/include/llvm/Analysis/RegionInfoImpl.h
index a16c534..cd4ec0a 100644
--- a/contrib/llvm/include/llvm/Analysis/RegionInfoImpl.h
+++ b/contrib/llvm/include/llvm/Analysis/RegionInfoImpl.h
@@ -12,7 +12,11 @@
#ifndef LLVM_ANALYSIS_REGIONINFOIMPL_H
#define LLVM_ANALYSIS_REGIONINFOIMPL_H
+#include "llvm/ADT/GraphTraits.h"
#include "llvm/ADT/PostOrderIterator.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/iterator_range.h"
#include "llvm/Analysis/DominanceFrontier.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/PostDominators.h"
@@ -20,14 +24,20 @@
#include "llvm/Analysis/RegionIterator.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/raw_ostream.h"
#include <algorithm>
+#include <cassert>
#include <iterator>
+#include <memory>
#include <set>
-
-namespace llvm {
+#include <string>
+#include <type_traits>
+#include <vector>
#define DEBUG_TYPE "region"
+namespace llvm {
+
//===----------------------------------------------------------------------===//
/// RegionBase Implementation
template <class Tr>
@@ -303,7 +313,8 @@ RegionBase<Tr>::element_end() const {
template <class Tr>
typename Tr::RegionT *RegionBase<Tr>::getSubRegionNode(BlockT *BB) const {
- typedef typename Tr::RegionT RegionT;
+ using RegionT = typename Tr::RegionT;
+
RegionT *R = RI->getRegionFor(BB);
if (!R || R == this)
@@ -330,7 +341,8 @@ typename Tr::RegionNodeT *RegionBase<Tr>::getBBNode(BlockT *BB) const {
if (at == BBNodeMap.end()) {
auto Deconst = const_cast<RegionBase<Tr> *>(this);
typename BBNodeMapT::value_type V = {
- BB, make_unique<RegionNodeT>(static_cast<RegionT *>(Deconst), BB)};
+ BB,
+ llvm::make_unique<RegionNodeT>(static_cast<RegionT *>(Deconst), BB)};
at = BBNodeMap.insert(std::move(V)).first;
}
return at->second.get();
@@ -357,10 +369,10 @@ void RegionBase<Tr>::transferChildrenTo(RegionT *To) {
template <class Tr>
void RegionBase<Tr>::addSubRegion(RegionT *SubRegion, bool moveChildren) {
assert(!SubRegion->parent && "SubRegion already has a parent!");
- assert(find_if(*this,
- [&](const std::unique_ptr<RegionT> &R) {
- return R.get() == SubRegion;
- }) == children.end() &&
+ assert(llvm::find_if(*this,
+ [&](const std::unique_ptr<RegionT> &R) {
+ return R.get() == SubRegion;
+ }) == children.end() &&
"Subregion already exists!");
SubRegion->parent = static_cast<RegionT *>(this);
@@ -402,7 +414,7 @@ typename Tr::RegionT *RegionBase<Tr>::removeSubRegion(RegionT *Child) {
assert(Child->parent == this && "Child is not a child of this region!");
Child->parent = nullptr;
typename RegionSet::iterator I =
- find_if(children, [&](const std::unique_ptr<RegionT> &R) {
+ llvm::find_if(children, [&](const std::unique_ptr<RegionT> &R) {
return R.get() == Child;
});
assert(I != children.end() && "Region does not exit. Unable to remove.");
@@ -505,8 +517,7 @@ void RegionBase<Tr>::clearNodeCache() {
//
template <class Tr>
-RegionInfoBase<Tr>::RegionInfoBase()
- : TopLevelRegion(nullptr) {}
+RegionInfoBase<Tr>::RegionInfoBase() = default;
template <class Tr>
RegionInfoBase<Tr>::~RegionInfoBase() {
@@ -543,7 +554,8 @@ bool RegionInfoBase<Tr>::isCommonDomFrontier(BlockT *BB, BlockT *entry,
template <class Tr>
bool RegionInfoBase<Tr>::isRegion(BlockT *entry, BlockT *exit) const {
assert(entry && exit && "entry and exit must not be null!");
- typedef typename DomFrontierT::DomSetType DST;
+
+ using DST = typename DomFrontierT::DomSetType;
DST *entrySuccs = &DF->find(entry)->second;
@@ -689,7 +701,8 @@ void RegionInfoBase<Tr>::findRegionsWithEntry(BlockT *entry,
template <class Tr>
void RegionInfoBase<Tr>::scanForRegions(FuncT &F, BBtoBBMap *ShortCut) {
- typedef typename std::add_pointer<FuncT>::type FuncPtrT;
+ using FuncPtrT = typename std::add_pointer<FuncT>::type;
+
BlockT *entry = GraphTraits<FuncPtrT>::getEntryNode(&F);
DomTreeNodeT *N = DT->getNode(entry);
@@ -876,7 +889,7 @@ RegionInfoBase<Tr>::getCommonRegion(SmallVectorImpl<BlockT *> &BBs) const {
template <class Tr>
void RegionInfoBase<Tr>::calculate(FuncT &F) {
- typedef typename std::add_pointer<FuncT>::type FuncPtrT;
+ using FuncPtrT = typename std::add_pointer<FuncT>::type;
// 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.
@@ -888,8 +901,8 @@ void RegionInfoBase<Tr>::calculate(FuncT &F) {
buildRegionsTree(DT->getNode(BB), TopLevelRegion);
}
-#undef DEBUG_TYPE
-
} // end namespace llvm
-#endif
+#undef DEBUG_TYPE
+
+#endif // LLVM_ANALYSIS_REGIONINFOIMPL_H
diff --git a/contrib/llvm/include/llvm/Analysis/RegionIterator.h b/contrib/llvm/include/llvm/Analysis/RegionIterator.h
index de2f3bf..4f823cc 100644
--- a/contrib/llvm/include/llvm/Analysis/RegionIterator.h
+++ b/contrib/llvm/include/llvm/Analysis/RegionIterator.h
@@ -8,17 +8,23 @@
//===----------------------------------------------------------------------===//
// This file defines the iterators to iterate over the elements of a Region.
//===----------------------------------------------------------------------===//
+
#ifndef LLVM_ANALYSIS_REGIONITERATOR_H
#define LLVM_ANALYSIS_REGIONITERATOR_H
+#include "llvm/ADT/DepthFirstIterator.h"
#include "llvm/ADT/GraphTraits.h"
#include "llvm/ADT/PointerIntPair.h"
-#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Analysis/RegionInfo.h"
#include "llvm/IR/CFG.h"
-#include "llvm/Support/raw_ostream.h"
+#include <cassert>
+#include <iterator>
+#include <type_traits>
namespace llvm {
+
+class BasicBlock;
+
//===----------------------------------------------------------------------===//
/// @brief Hierarchical RegionNode successor iterator.
///
@@ -33,10 +39,9 @@ namespace llvm {
template <class NodeRef, class BlockT, class RegionT>
class RNSuccIterator
: public std::iterator<std::forward_iterator_tag, NodeRef> {
- typedef std::iterator<std::forward_iterator_tag, NodeRef> super;
-
- typedef GraphTraits<BlockT*> BlockTraits;
- typedef typename BlockTraits::ChildIteratorType SuccIterTy;
+ using super = std::iterator<std::forward_iterator_tag, NodeRef>;
+ using BlockTraits = GraphTraits<BlockT *>;
+ using SuccIterTy = typename BlockTraits::ChildIteratorType;
// The iterator works in two modes, bb mode or region mode.
enum ItMode {
@@ -92,16 +97,15 @@ class RNSuccIterator
inline bool isExit(BlockT* BB) const {
return getNode()->getParent()->getExit() == BB;
}
-public:
- typedef RNSuccIterator<NodeRef, BlockT, RegionT> Self;
- typedef typename super::value_type value_type;
+public:
+ using Self = RNSuccIterator<NodeRef, BlockT, RegionT>;
+ using value_type = typename super::value_type;
/// @brief Create begin iterator of a RegionNode.
inline RNSuccIterator(NodeRef node)
: Node(node, node->isSubRegion() ? ItRgBegin : ItBB),
BItor(BlockTraits::child_begin(node->getEntry())) {
-
// Skip the exit block
if (!isRegionMode())
while (BlockTraits::child_end(node->getEntry()) != BItor && isExit(*BItor))
@@ -153,7 +157,6 @@ public:
}
};
-
//===----------------------------------------------------------------------===//
/// @brief Flat RegionNode iterator.
///
@@ -163,16 +166,16 @@ public:
template <class NodeRef, class BlockT, class RegionT>
class RNSuccIterator<FlatIt<NodeRef>, BlockT, RegionT>
: public std::iterator<std::forward_iterator_tag, NodeRef> {
- typedef std::iterator<std::forward_iterator_tag, NodeRef> super;
- typedef GraphTraits<BlockT*> BlockTraits;
- typedef typename BlockTraits::ChildIteratorType SuccIterTy;
+ using super = std::iterator<std::forward_iterator_tag, NodeRef>;
+ using BlockTraits = GraphTraits<BlockT *>;
+ using SuccIterTy = typename BlockTraits::ChildIteratorType;
NodeRef Node;
SuccIterTy Itor;
public:
- typedef RNSuccIterator<FlatIt<NodeRef>, BlockT, RegionT> Self;
- typedef typename super::value_type value_type;
+ using Self = RNSuccIterator<FlatIt<NodeRef>, BlockT, RegionT>;
+ using value_type = typename super::value_type;
/// @brief Create the iterator from a RegionNode.
///
@@ -255,8 +258,8 @@ inline RNSuccIterator<NodeRef, BlockT, RegionT> succ_end(NodeRef Node) {
#define RegionNodeGraphTraits(NodeT, BlockT, RegionT) \
template <> struct GraphTraits<NodeT *> { \
- typedef NodeT *NodeRef; \
- typedef RNSuccIterator<NodeRef, BlockT, RegionT> ChildIteratorType; \
+ using NodeRef = NodeT *; \
+ using ChildIteratorType = RNSuccIterator<NodeRef, BlockT, RegionT>; \
static NodeRef getEntryNode(NodeRef N) { return N; } \
static inline ChildIteratorType child_begin(NodeRef N) { \
return RNSuccIterator<NodeRef, BlockT, RegionT>(N); \
@@ -266,9 +269,9 @@ inline RNSuccIterator<NodeRef, BlockT, RegionT> succ_end(NodeRef Node) {
} \
}; \
template <> struct GraphTraits<FlatIt<NodeT *>> { \
- typedef NodeT *NodeRef; \
- typedef RNSuccIterator<FlatIt<NodeRef>, BlockT, RegionT> \
- ChildIteratorType; \
+ using NodeRef = NodeT *; \
+ using ChildIteratorType = \
+ RNSuccIterator<FlatIt<NodeRef>, BlockT, RegionT>; \
static NodeRef getEntryNode(NodeRef N) { return N; } \
static inline ChildIteratorType child_begin(NodeRef N) { \
return RNSuccIterator<FlatIt<NodeRef>, BlockT, RegionT>(N); \
@@ -280,7 +283,7 @@ inline RNSuccIterator<NodeRef, BlockT, RegionT> succ_end(NodeRef Node) {
#define RegionGraphTraits(RegionT, NodeT) \
template <> struct GraphTraits<RegionT *> : public GraphTraits<NodeT *> { \
- typedef df_iterator<NodeRef> nodes_iterator; \
+ using nodes_iterator = df_iterator<NodeRef>; \
static NodeRef getEntryNode(RegionT *R) { \
return R->getNode(R->getEntry()); \
} \
@@ -294,9 +297,9 @@ inline RNSuccIterator<NodeRef, BlockT, RegionT> succ_end(NodeRef Node) {
template <> \
struct GraphTraits<FlatIt<RegionT *>> \
: public GraphTraits<FlatIt<NodeT *>> { \
- typedef df_iterator<NodeRef, df_iterator_default_set<NodeRef>, false, \
- GraphTraits<FlatIt<NodeRef>>> \
- nodes_iterator; \
+ using nodes_iterator = \
+ df_iterator<NodeRef, df_iterator_default_set<NodeRef>, false, \
+ GraphTraits<FlatIt<NodeRef>>>; \
static NodeRef getEntryNode(RegionT *R) { \
return R->getBBNode(R->getEntry()); \
} \
@@ -315,17 +318,19 @@ RegionGraphTraits(Region, RegionNode);
RegionGraphTraits(const Region, const RegionNode);
template <> struct GraphTraits<RegionInfo*>
- : public GraphTraits<FlatIt<RegionNode*> > {
- typedef df_iterator<NodeRef, df_iterator_default_set<NodeRef>, false,
- GraphTraits<FlatIt<NodeRef>>>
- nodes_iterator;
+ : public GraphTraits<FlatIt<RegionNode*>> {
+ using nodes_iterator =
+ df_iterator<NodeRef, df_iterator_default_set<NodeRef>, false,
+ GraphTraits<FlatIt<NodeRef>>>;
static NodeRef getEntryNode(RegionInfo *RI) {
- return GraphTraits<FlatIt<Region*> >::getEntryNode(RI->getTopLevelRegion());
+ return GraphTraits<FlatIt<Region*>>::getEntryNode(RI->getTopLevelRegion());
}
+
static nodes_iterator nodes_begin(RegionInfo* RI) {
return nodes_iterator::begin(getEntryNode(RI));
}
+
static nodes_iterator nodes_end(RegionInfo *RI) {
return nodes_iterator::end(getEntryNode(RI));
}
@@ -333,21 +338,23 @@ template <> struct GraphTraits<RegionInfo*>
template <> struct GraphTraits<RegionInfoPass*>
: public GraphTraits<RegionInfo *> {
- typedef df_iterator<NodeRef, df_iterator_default_set<NodeRef>, false,
- GraphTraits<FlatIt<NodeRef>>>
- nodes_iterator;
+ using nodes_iterator =
+ df_iterator<NodeRef, df_iterator_default_set<NodeRef>, false,
+ GraphTraits<FlatIt<NodeRef>>>;
static NodeRef getEntryNode(RegionInfoPass *RI) {
return GraphTraits<RegionInfo*>::getEntryNode(&RI->getRegionInfo());
}
+
static nodes_iterator nodes_begin(RegionInfoPass* RI) {
return GraphTraits<RegionInfo*>::nodes_begin(&RI->getRegionInfo());
}
+
static nodes_iterator nodes_end(RegionInfoPass *RI) {
return GraphTraits<RegionInfo*>::nodes_end(&RI->getRegionInfo());
}
};
-} // End namespace llvm
+} // end namespace llvm
-#endif
+#endif // LLVM_ANALYSIS_REGIONITERATOR_H
diff --git a/contrib/llvm/include/llvm/Analysis/RegionPass.h b/contrib/llvm/include/llvm/Analysis/RegionPass.h
index b5f3813..515b362 100644
--- a/contrib/llvm/include/llvm/Analysis/RegionPass.h
+++ b/contrib/llvm/include/llvm/Analysis/RegionPass.h
@@ -78,6 +78,11 @@ public:
return PMT_RegionPassManager;
}
//@}
+
+protected:
+ /// Optional passes call this function to check whether the pass should be
+ /// skipped. This is the case when optimization bisect is over the limit.
+ bool skipRegion(Region &R) const;
};
/// @brief The pass manager to schedule RegionPasses.
diff --git a/contrib/llvm/include/llvm/Analysis/ScalarEvolution.h b/contrib/llvm/include/llvm/Analysis/ScalarEvolution.h
index 1a93f9a..d1b1827 100644
--- a/contrib/llvm/include/llvm/Analysis/ScalarEvolution.h
+++ b/contrib/llvm/include/llvm/Analysis/ScalarEvolution.h
@@ -237,17 +237,15 @@ struct FoldingSetTrait<SCEVPredicate> : DefaultFoldingSetTrait<SCEVPredicate> {
};
/// This class represents an assumption that two SCEV expressions are equal,
-/// and this can be checked at run-time. We assume that the left hand side is
-/// a SCEVUnknown and the right hand side a constant.
+/// and this can be checked at run-time.
class SCEVEqualPredicate final : public SCEVPredicate {
- /// We assume that LHS == RHS, where LHS is a SCEVUnknown and RHS a
- /// constant.
- const SCEVUnknown *LHS;
- const SCEVConstant *RHS;
+ /// We assume that LHS == RHS.
+ const SCEV *LHS;
+ const SCEV *RHS;
public:
- SCEVEqualPredicate(const FoldingSetNodeIDRef ID, const SCEVUnknown *LHS,
- const SCEVConstant *RHS);
+ SCEVEqualPredicate(const FoldingSetNodeIDRef ID, const SCEV *LHS,
+ const SCEV *RHS);
/// Implementation of the SCEVPredicate interface
bool implies(const SCEVPredicate *N) const override;
@@ -256,13 +254,13 @@ public:
const SCEV *getExpr() const override;
/// Returns the left hand side of the equality.
- const SCEVUnknown *getLHS() const { return LHS; }
+ const SCEV *getLHS() const { return LHS; }
/// Returns the right hand side of the equality.
- const SCEVConstant *getRHS() const { return RHS; }
+ const SCEV *getRHS() const { return RHS; }
/// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const SCEVPredicate *P) {
+ static bool classof(const SCEVPredicate *P) {
return P->getKind() == P_Equal;
}
};
@@ -360,7 +358,7 @@ public:
bool isAlwaysTrue() const override;
/// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const SCEVPredicate *P) {
+ static bool classof(const SCEVPredicate *P) {
return P->getKind() == P_Wrap;
}
};
@@ -406,7 +404,7 @@ public:
unsigned getComplexity() const override { return Preds.size(); }
/// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const SCEVPredicate *P) {
+ static bool classof(const SCEVPredicate *P) {
return P->getKind() == P_Union;
}
};
@@ -543,6 +541,12 @@ private:
/// predicate by splitting it into a set of independent predicates.
bool ProvingSplitPredicate;
+ /// Memoized values for the GetMinTrailingZeros
+ DenseMap<const SCEV *, uint32_t> MinTrailingZerosCache;
+
+ /// Private helper method for the GetMinTrailingZeros method
+ uint32_t GetMinTrailingZerosImpl(const SCEV *S);
+
/// Information about the number of loop iterations for which a loop exit's
/// branch condition evaluates to the not-taken path. This is a temporary
/// pair of exact and max expressions that are eventually summarized in
@@ -562,27 +566,16 @@ private:
Predicates.insert(P);
}
- /*implicit*/ ExitLimit(const SCEV *E)
- : ExactNotTaken(E), MaxNotTaken(E), MaxOrZero(false) {}
+ /*implicit*/ ExitLimit(const SCEV *E);
ExitLimit(
const SCEV *E, const SCEV *M, bool MaxOrZero,
- ArrayRef<const SmallPtrSetImpl<const SCEVPredicate *> *> PredSetList)
- : ExactNotTaken(E), MaxNotTaken(M), MaxOrZero(MaxOrZero) {
- assert((isa<SCEVCouldNotCompute>(ExactNotTaken) ||
- !isa<SCEVCouldNotCompute>(MaxNotTaken)) &&
- "Exact is not allowed to be less precise than Max");
- for (auto *PredSet : PredSetList)
- for (auto *P : *PredSet)
- addPredicate(P);
- }
+ ArrayRef<const SmallPtrSetImpl<const SCEVPredicate *> *> PredSetList);
ExitLimit(const SCEV *E, const SCEV *M, bool MaxOrZero,
- const SmallPtrSetImpl<const SCEVPredicate *> &PredSet)
- : ExitLimit(E, M, MaxOrZero, {&PredSet}) {}
+ const SmallPtrSetImpl<const SCEVPredicate *> &PredSet);
- ExitLimit(const SCEV *E, const SCEV *M, bool MaxOrZero)
- : ExitLimit(E, M, MaxOrZero, None) {}
+ ExitLimit(const SCEV *E, const SCEV *M, bool MaxOrZero);
/// Test whether this ExitLimit contains any computed information, or
/// whether it's all SCEVCouldNotCompute values.
@@ -600,14 +593,14 @@ private:
/// Information about the number of times a particular loop exit may be
/// reached before exiting the loop.
struct ExitNotTakenInfo {
- AssertingVH<BasicBlock> ExitingBlock;
+ PoisoningVH<BasicBlock> ExitingBlock;
const SCEV *ExactNotTaken;
std::unique_ptr<SCEVUnionPredicate> Predicate;
bool hasAlwaysTruePredicate() const {
return !Predicate || Predicate->isAlwaysTrue();
}
- explicit ExitNotTakenInfo(AssertingVH<BasicBlock> ExitingBlock,
+ explicit ExitNotTakenInfo(PoisoningVH<BasicBlock> ExitingBlock,
const SCEV *ExactNotTaken,
std::unique_ptr<SCEVUnionPredicate> Predicate)
: ExitingBlock(ExitingBlock), ExactNotTaken(ExactNotTaken),
@@ -641,7 +634,7 @@ private:
/// @}
public:
- BackedgeTakenInfo() : MaxAndComplete(nullptr, 0) {}
+ BackedgeTakenInfo() : MaxAndComplete(nullptr, 0), MaxOrZero(false) {}
BackedgeTakenInfo(BackedgeTakenInfo &&) = default;
BackedgeTakenInfo &operator=(BackedgeTakenInfo &&) = default;
@@ -661,10 +654,12 @@ private:
/// Test whether this BackedgeTakenInfo contains complete information.
bool hasFullInfo() const { return isComplete(); }
- /// Return an expression indicating the exact backedge-taken count of the
- /// loop if it is known or SCEVCouldNotCompute otherwise. This is the
- /// number of times the loop header can be guaranteed to execute, minus
- /// one.
+ /// Return an expression indicating the exact *backedge-taken*
+ /// count of the loop if it is known or SCEVCouldNotCompute
+ /// otherwise. If execution makes it to the backedge on every
+ /// iteration (i.e. there are no abnormal exists like exception
+ /// throws and thread exits) then this is the number of times the
+ /// loop header will execute minus one.
///
/// If the SCEV predicate associated with the answer can be different
/// from AlwaysTrue, we must add a (non null) Predicates argument.
@@ -776,18 +771,20 @@ private:
/// Set the memoized range for the given SCEV.
const ConstantRange &setRange(const SCEV *S, RangeSignHint Hint,
- const ConstantRange &CR) {
+ ConstantRange CR) {
DenseMap<const SCEV *, ConstantRange> &Cache =
Hint == HINT_RANGE_UNSIGNED ? UnsignedRanges : SignedRanges;
- auto Pair = Cache.insert({S, CR});
+ auto Pair = Cache.try_emplace(S, std::move(CR));
if (!Pair.second)
- Pair.first->second = CR;
+ Pair.first->second = std::move(CR);
return Pair.first->second;
}
/// Determine the range for a particular SCEV.
- ConstantRange getRange(const SCEV *S, RangeSignHint Hint);
+ /// NOTE: This returns a reference to an entry in a cache. It must be
+ /// copied if its needed for longer.
+ const ConstantRange &getRangeRef(const SCEV *S, RangeSignHint Hint);
/// Determines the range for the affine SCEVAddRecExpr {\p Start,+,\p Stop}.
/// Helper for \c getRange.
@@ -810,6 +807,10 @@ private:
/// Helper function called from createNodeForPHI.
const SCEV *createAddRecFromPHI(PHINode *PN);
+ /// A helper function for createAddRecFromPHI to handle simple cases.
+ const SCEV *createSimpleAffineAddRec(PHINode *PN, Value *BEValueV,
+ Value *StartValueV);
+
/// Helper function called from createNodeForPHI.
const SCEV *createNodeFromSelectLikePHI(PHINode *PN);
@@ -871,6 +872,47 @@ private:
bool ControlsExit,
bool AllowPredicates = false);
+ // Helper functions for computeExitLimitFromCond to avoid exponential time
+ // complexity.
+
+ class ExitLimitCache {
+ // It may look like we need key on the whole (L, TBB, FBB, ControlsExit,
+ // AllowPredicates) tuple, but recursive calls to
+ // computeExitLimitFromCondCached from computeExitLimitFromCondImpl only
+ // vary the in \c ExitCond and \c ControlsExit parameters. We remember the
+ // initial values of the other values to assert our assumption.
+ SmallDenseMap<PointerIntPair<Value *, 1>, ExitLimit> TripCountMap;
+
+ const Loop *L;
+ BasicBlock *TBB;
+ BasicBlock *FBB;
+ bool AllowPredicates;
+
+ public:
+ ExitLimitCache(const Loop *L, BasicBlock *TBB, BasicBlock *FBB,
+ bool AllowPredicates)
+ : L(L), TBB(TBB), FBB(FBB), AllowPredicates(AllowPredicates) {}
+
+ Optional<ExitLimit> find(const Loop *L, Value *ExitCond, BasicBlock *TBB,
+ BasicBlock *FBB, bool ControlsExit,
+ bool AllowPredicates);
+
+ void insert(const Loop *L, Value *ExitCond, BasicBlock *TBB,
+ BasicBlock *FBB, bool ControlsExit, bool AllowPredicates,
+ const ExitLimit &EL);
+ };
+
+ typedef ExitLimitCache ExitLimitCacheTy;
+ ExitLimit computeExitLimitFromCondCached(ExitLimitCacheTy &Cache,
+ const Loop *L, Value *ExitCond,
+ BasicBlock *TBB, BasicBlock *FBB,
+ bool ControlsExit,
+ bool AllowPredicates);
+ ExitLimit computeExitLimitFromCondImpl(ExitLimitCacheTy &Cache, const Loop *L,
+ Value *ExitCond, BasicBlock *TBB,
+ BasicBlock *FBB, bool ControlsExit,
+ bool AllowPredicates);
+
/// Compute the number of times the backedge of the specified loop will
/// execute if its exit condition were a conditional branch of the ICmpInst
/// ExitCond, TBB, and FBB. If AllowPredicates is set, this call will try
@@ -972,6 +1014,20 @@ private:
/// Test whether the condition described by Pred, LHS, and RHS is true
/// whenever the condition described by Pred, FoundLHS, and FoundRHS is
+ /// true. Here LHS is an operation that includes FoundLHS as one of its
+ /// arguments.
+ bool isImpliedViaOperations(ICmpInst::Predicate Pred,
+ const SCEV *LHS, const SCEV *RHS,
+ const SCEV *FoundLHS, const SCEV *FoundRHS,
+ unsigned Depth = 0);
+
+ /// Test whether the condition described by Pred, LHS, and RHS is true.
+ /// Use only simple non-recursive types of checks, such as range analysis etc.
+ bool isKnownViaSimpleReasoning(ICmpInst::Predicate Pred,
+ const SCEV *LHS, const SCEV *RHS);
+
+ /// Test whether the condition described by Pred, LHS, and RHS is true
+ /// whenever the condition described by Pred, FoundLHS, and FoundRHS is
/// true.
bool isImpliedCondOperandsHelper(ICmpInst::Predicate Pred, const SCEV *LHS,
const SCEV *RHS, const SCEV *FoundLHS,
@@ -1065,18 +1121,6 @@ private:
bool isMonotonicPredicateImpl(const SCEVAddRecExpr *LHS,
ICmpInst::Predicate Pred, bool &Increasing);
- /// Return true if, for all loop invariant X, the predicate "LHS `Pred` X"
- /// is monotonically increasing or decreasing. In the former case set
- /// `Increasing` to true and in the latter case set `Increasing` to false.
- ///
- /// A predicate is said to be monotonically increasing if may go from being
- /// false to being true as the loop iterates, but never the other way
- /// around. A predicate is said to be monotonically decreasing if may go
- /// from being true to being false as the loop iterates, but never the other
- /// way around.
- bool isMonotonicPredicate(const SCEVAddRecExpr *LHS, ICmpInst::Predicate Pred,
- bool &Increasing);
-
/// Return SCEV no-wrap flags that can be proven based on reasoning about
/// how poison produced from no-wrap flags on this value (e.g. a nuw add)
/// would trigger undefined behavior on overflow.
@@ -1129,6 +1173,9 @@ public:
/// return true. For pointer types, this is the pointer-sized integer type.
Type *getEffectiveSCEVType(Type *Ty) const;
+ // Returns a wider type among {Ty1, Ty2}.
+ Type *getWiderType(Type *Ty1, Type *Ty2) const;
+
/// Return true if the SCEV is a scAddRecExpr or it contains
/// scAddRecExpr. The result will be cached in HasRecMap.
///
@@ -1148,32 +1195,38 @@ public:
const SCEV *getConstant(const APInt &Val);
const SCEV *getConstant(Type *Ty, uint64_t V, bool isSigned = false);
const SCEV *getTruncateExpr(const SCEV *Op, Type *Ty);
- const SCEV *getZeroExtendExpr(const SCEV *Op, Type *Ty);
- const SCEV *getSignExtendExpr(const SCEV *Op, Type *Ty);
+ const SCEV *getZeroExtendExpr(const SCEV *Op, Type *Ty, unsigned Depth = 0);
+ const SCEV *getSignExtendExpr(const SCEV *Op, Type *Ty, unsigned Depth = 0);
const SCEV *getAnyExtendExpr(const SCEV *Op, Type *Ty);
const SCEV *getAddExpr(SmallVectorImpl<const SCEV *> &Ops,
- SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap);
+ SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap,
+ unsigned Depth = 0);
const SCEV *getAddExpr(const SCEV *LHS, const SCEV *RHS,
- SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap) {
+ SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap,
+ unsigned Depth = 0) {
SmallVector<const SCEV *, 2> Ops = {LHS, RHS};
- return getAddExpr(Ops, Flags);
+ return getAddExpr(Ops, Flags, Depth);
}
const SCEV *getAddExpr(const SCEV *Op0, const SCEV *Op1, const SCEV *Op2,
- SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap) {
+ SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap,
+ unsigned Depth = 0) {
SmallVector<const SCEV *, 3> Ops = {Op0, Op1, Op2};
- return getAddExpr(Ops, Flags);
+ return getAddExpr(Ops, Flags, Depth);
}
const SCEV *getMulExpr(SmallVectorImpl<const SCEV *> &Ops,
- SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap);
+ SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap,
+ unsigned Depth = 0);
const SCEV *getMulExpr(const SCEV *LHS, const SCEV *RHS,
- SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap) {
+ SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap,
+ unsigned Depth = 0) {
SmallVector<const SCEV *, 2> Ops = {LHS, RHS};
- return getMulExpr(Ops, Flags);
+ return getMulExpr(Ops, Flags, Depth);
}
const SCEV *getMulExpr(const SCEV *Op0, const SCEV *Op1, const SCEV *Op2,
- SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap) {
+ SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap,
+ unsigned Depth = 0) {
SmallVector<const SCEV *, 3> Ops = {Op0, Op1, Op2};
- return getMulExpr(Ops, Flags);
+ return getMulExpr(Ops, Flags, Depth);
}
const SCEV *getUDivExpr(const SCEV *LHS, const SCEV *RHS);
const SCEV *getUDivExactExpr(const SCEV *LHS, const SCEV *RHS);
@@ -1186,6 +1239,14 @@ public:
SmallVector<const SCEV *, 4> NewOp(Operands.begin(), Operands.end());
return getAddRecExpr(NewOp, L, Flags);
}
+
+ /// Checks if \p SymbolicPHI can be rewritten as an AddRecExpr under some
+ /// Predicates. If successful return these <AddRecExpr, Predicates>;
+ /// The function is intended to be called from PSCEV (the caller will decide
+ /// whether to actually add the predicates and carry out the rewrites).
+ Optional<std::pair<const SCEV *, SmallVector<const SCEVPredicate *, 3>>>
+ createAddRecFromPHIWithCasts(const SCEVUnknown *SymbolicPHI);
+
/// Returns an expression for a GEP
///
/// \p GEP The GEP. The indices contained in the GEP itself are ignored,
@@ -1227,7 +1288,8 @@ public:
/// Return LHS-RHS. Minus is represented in SCEV as A+B*-1.
const SCEV *getMinusSCEV(const SCEV *LHS, const SCEV *RHS,
- SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap);
+ SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap,
+ unsigned Depth = 0);
/// Return a SCEV corresponding to a conversion of the input value to the
/// specified type. If the type must be extended, it is zero extended.
@@ -1301,7 +1363,7 @@ public:
///
/// Implemented in terms of the \c getSmallConstantTripCount overload with
/// the single exiting block passed to it. See that routine for details.
- unsigned getSmallConstantTripCount(Loop *L);
+ unsigned getSmallConstantTripCount(const Loop *L);
/// Returns the maximum trip count of this loop as a normal unsigned
/// value. Returns 0 if the trip count is unknown or not constant. This
@@ -1310,12 +1372,12 @@ public:
/// before taking the branch. For loops with multiple exits, it may not be
/// the number times that the loop header executes if the loop exits
/// prematurely via another branch.
- unsigned getSmallConstantTripCount(Loop *L, BasicBlock *ExitingBlock);
+ unsigned getSmallConstantTripCount(const Loop *L, BasicBlock *ExitingBlock);
/// Returns the upper bound of the loop trip count as a normal unsigned
/// value.
/// Returns 0 if the trip count is unknown or not constant.
- unsigned getSmallConstantMaxTripCount(Loop *L);
+ unsigned getSmallConstantMaxTripCount(const Loop *L);
/// Returns the largest constant divisor of the trip count of the
/// loop if it is a single-exit loop and we can compute a small maximum for
@@ -1323,7 +1385,7 @@ public:
///
/// Implemented in terms of the \c getSmallConstantTripMultiple overload with
/// the single exiting block passed to it. See that routine for details.
- unsigned getSmallConstantTripMultiple(Loop *L);
+ unsigned getSmallConstantTripMultiple(const Loop *L);
/// Returns the largest constant divisor of the trip count of this loop as a
/// normal unsigned value, if possible. This means that the actual trip
@@ -1331,19 +1393,20 @@ public:
/// count could very well be zero as well!). As explained in the comments
/// for getSmallConstantTripCount, this assumes that control exits the loop
/// via ExitingBlock.
- unsigned getSmallConstantTripMultiple(Loop *L, BasicBlock *ExitingBlock);
+ unsigned getSmallConstantTripMultiple(const Loop *L,
+ BasicBlock *ExitingBlock);
/// Get the expression for the number of loop iterations for which this loop
/// is guaranteed not to exit via ExitingBlock. Otherwise return
/// SCEVCouldNotCompute.
- const SCEV *getExitCount(Loop *L, BasicBlock *ExitingBlock);
+ const SCEV *getExitCount(const Loop *L, BasicBlock *ExitingBlock);
/// If the specified loop has a predictable backedge-taken count, return it,
- /// otherwise return a SCEVCouldNotCompute object. The backedge-taken count
- /// is the number of times the loop header will be branched to from within
- /// the loop. This is one less than the trip count of the loop, since it
- /// doesn't count the first iteration, when the header is branched to from
- /// outside the loop.
+ /// otherwise return a SCEVCouldNotCompute object. The backedge-taken count is
+ /// the number of times the loop header will be branched to from within the
+ /// loop, assuming there are no abnormal exists like exception throws. This is
+ /// one less than the trip count of the loop, since it doesn't count the first
+ /// iteration, when the header is branched to from outside the loop.
///
/// Note that it is not valid to call this method on a loop without a
/// loop-invariant backedge-taken count (see
@@ -1358,8 +1421,10 @@ public:
const SCEV *getPredicatedBackedgeTakenCount(const Loop *L,
SCEVUnionPredicate &Predicates);
- /// Similar to getBackedgeTakenCount, except return the least SCEV value
- /// that is known never to be less than the actual backedge taken count.
+ /// When successful, this returns a SCEVConstant that is greater than or equal
+ /// to (i.e. a "conservative over-approximation") of the value returend by
+ /// getBackedgeTakenCount. If such a value cannot be computed, it returns the
+ /// SCEVCouldNotCompute object.
const SCEV *getMaxBackedgeTakenCount(const Loop *L);
/// Return true if the backedge taken count is either the value returned by
@@ -1395,15 +1460,35 @@ public:
uint32_t GetMinTrailingZeros(const SCEV *S);
/// Determine the unsigned range for a particular SCEV.
- ///
+ /// NOTE: This returns a copy of the reference returned by getRangeRef.
ConstantRange getUnsignedRange(const SCEV *S) {
- return getRange(S, HINT_RANGE_UNSIGNED);
+ return getRangeRef(S, HINT_RANGE_UNSIGNED);
+ }
+
+ /// Determine the min of the unsigned range for a particular SCEV.
+ APInt getUnsignedRangeMin(const SCEV *S) {
+ return getRangeRef(S, HINT_RANGE_UNSIGNED).getUnsignedMin();
+ }
+
+ /// Determine the max of the unsigned range for a particular SCEV.
+ APInt getUnsignedRangeMax(const SCEV *S) {
+ return getRangeRef(S, HINT_RANGE_UNSIGNED).getUnsignedMax();
}
/// Determine the signed range for a particular SCEV.
- ///
+ /// NOTE: This returns a copy of the reference returned by getRangeRef.
ConstantRange getSignedRange(const SCEV *S) {
- return getRange(S, HINT_RANGE_SIGNED);
+ return getRangeRef(S, HINT_RANGE_SIGNED);
+ }
+
+ /// Determine the min of the signed range for a particular SCEV.
+ APInt getSignedRangeMin(const SCEV *S) {
+ return getRangeRef(S, HINT_RANGE_SIGNED).getSignedMin();
+ }
+
+ /// Determine the max of the signed range for a particular SCEV.
+ APInt getSignedRangeMax(const SCEV *S) {
+ return getRangeRef(S, HINT_RANGE_SIGNED).getSignedMax();
}
/// Test if the given expression is known to be negative.
@@ -1432,6 +1517,18 @@ public:
bool isKnownPredicate(ICmpInst::Predicate Pred, const SCEV *LHS,
const SCEV *RHS);
+ /// Return true if, for all loop invariant X, the predicate "LHS `Pred` X"
+ /// is monotonically increasing or decreasing. In the former case set
+ /// `Increasing` to true and in the latter case set `Increasing` to false.
+ ///
+ /// A predicate is said to be monotonically increasing if may go from being
+ /// false to being true as the loop iterates, but never the other way
+ /// around. A predicate is said to be monotonically decreasing if may go
+ /// from being true to being false as the loop iterates, but never the other
+ /// way around.
+ bool isMonotonicPredicate(const SCEVAddRecExpr *LHS, ICmpInst::Predicate Pred,
+ bool &Increasing);
+
/// Return true if the result of the predicate LHS `Pred` RHS is loop
/// invariant with respect to L. Set InvariantPred, InvariantLHS and
/// InvariantLHS so that InvariantLHS `InvariantPred` InvariantRHS is the
@@ -1458,6 +1555,11 @@ public:
/// specified loop.
bool isLoopInvariant(const SCEV *S, const Loop *L);
+ /// Determine if the SCEV can be evaluated at loop's entry. It is true if it
+ /// doesn't depend on a SCEVUnknown of an instruction which is dominated by
+ /// the header of loop L.
+ bool isAvailableAtLoopEntry(const SCEV *S, const Loop *L);
+
/// Return true if the given SCEV changes value in a known way in the
/// specified loop. This property being true implies that the value is
/// variant in the loop AND that we can emit an expression to compute the
@@ -1487,7 +1589,7 @@ public:
/// delinearization).
void findArrayDimensions(SmallVectorImpl<const SCEV *> &Terms,
SmallVectorImpl<const SCEV *> &Sizes,
- const SCEV *ElementSize) const;
+ const SCEV *ElementSize);
void print(raw_ostream &OS) const;
void verify() const;
@@ -1579,8 +1681,7 @@ public:
return F.getParent()->getDataLayout();
}
- const SCEVPredicate *getEqualPredicate(const SCEVUnknown *LHS,
- const SCEVConstant *RHS);
+ const SCEVPredicate *getEqualPredicate(const SCEV *LHS, const SCEV *RHS);
const SCEVPredicate *
getWrapPredicate(const SCEVAddRecExpr *AR,
@@ -1596,6 +1697,19 @@ public:
SmallPtrSetImpl<const SCEVPredicate *> &Preds);
private:
+ /// Similar to createAddRecFromPHI, but with the additional flexibility of
+ /// suggesting runtime overflow checks in case casts are encountered.
+ /// If successful, the analysis records that for this loop, \p SymbolicPHI,
+ /// which is the UnknownSCEV currently representing the PHI, can be rewritten
+ /// into an AddRec, assuming some predicates; The function then returns the
+ /// AddRec and the predicates as a pair, and caches this pair in
+ /// PredicatedSCEVRewrites.
+ /// If the analysis is not successful, a mapping from the \p SymbolicPHI to
+ /// itself (with no predicates) is recorded, and a nullptr with an empty
+ /// predicates vector is returned as a pair.
+ Optional<std::pair<const SCEV *, SmallVector<const SCEVPredicate *, 3>>>
+ createAddRecFromPHIWithCastsImpl(const SCEVUnknown *SymbolicPHI);
+
/// Compute the backedge taken count knowing the interval difference, the
/// stride and presence of the equality in the comparison.
const SCEV *computeBECount(const SCEV *Delta, const SCEV *Stride,
@@ -1613,11 +1727,25 @@ private:
bool doesIVOverflowOnGT(const SCEV *RHS, const SCEV *Stride, bool IsSigned,
bool NoWrap);
+ /// Get add expr already created or create a new one.
+ const SCEV *getOrCreateAddExpr(SmallVectorImpl<const SCEV *> &Ops,
+ SCEV::NoWrapFlags Flags);
+
+ /// Get mul expr already created or create a new one.
+ const SCEV *getOrCreateMulExpr(SmallVectorImpl<const SCEV *> &Ops,
+ SCEV::NoWrapFlags Flags);
+
private:
FoldingSet<SCEV> UniqueSCEVs;
FoldingSet<SCEVPredicate> UniquePreds;
BumpPtrAllocator SCEVAllocator;
+ /// Cache tentative mappings from UnknownSCEVs in a Loop, to a SCEV expression
+ /// they can be rewritten into under certain predicates.
+ DenseMap<std::pair<const SCEVUnknown *, const Loop *>,
+ std::pair<const SCEV *, SmallVector<const SCEVPredicate *, 3>>>
+ PredicatedSCEVRewrites;
+
/// The head of a linked list of all SCEVUnknown values that have been
/// allocated. This is used by releaseMemory to locate them all and call
/// their destructors.
diff --git a/contrib/llvm/include/llvm/Analysis/ScalarEvolutionExpander.h b/contrib/llvm/include/llvm/Analysis/ScalarEvolutionExpander.h
index 517592a..7d16f34 100644
--- a/contrib/llvm/include/llvm/Analysis/ScalarEvolutionExpander.h
+++ b/contrib/llvm/include/llvm/Analysis/ScalarEvolutionExpander.h
@@ -189,7 +189,7 @@ namespace llvm {
/// replace congruent phis with their most canonical representative. Return
/// the number of phis eliminated.
unsigned replaceCongruentIVs(Loop *L, const DominatorTree *DT,
- SmallVectorImpl<WeakVH> &DeadInsts,
+ SmallVectorImpl<WeakTrackingVH> &DeadInsts,
const TargetTransformInfo *TTI = nullptr);
/// Insert code to directly compute the specified SCEV expression into the
diff --git a/contrib/llvm/include/llvm/Analysis/ScalarEvolutionExpressions.h b/contrib/llvm/include/llvm/Analysis/ScalarEvolutionExpressions.h
index fdcd8be..56ddb50 100644
--- a/contrib/llvm/include/llvm/Analysis/ScalarEvolutionExpressions.h
+++ b/contrib/llvm/include/llvm/Analysis/ScalarEvolutionExpressions.h
@@ -46,7 +46,7 @@ namespace llvm {
Type *getType() const { return V->getType(); }
/// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const SCEV *S) {
+ static bool classof(const SCEV *S) {
return S->getSCEVType() == scConstant;
}
};
@@ -65,7 +65,7 @@ namespace llvm {
Type *getType() const { return Ty; }
/// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const SCEV *S) {
+ static bool classof(const SCEV *S) {
return S->getSCEVType() == scTruncate ||
S->getSCEVType() == scZeroExtend ||
S->getSCEVType() == scSignExtend;
@@ -82,7 +82,7 @@ namespace llvm {
public:
/// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const SCEV *S) {
+ static bool classof(const SCEV *S) {
return S->getSCEVType() == scTruncate;
}
};
@@ -97,7 +97,7 @@ namespace llvm {
public:
/// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const SCEV *S) {
+ static bool classof(const SCEV *S) {
return S->getSCEVType() == scZeroExtend;
}
};
@@ -112,7 +112,7 @@ namespace llvm {
public:
/// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const SCEV *S) {
+ static bool classof(const SCEV *S) {
return S->getSCEVType() == scSignExtend;
}
};
@@ -167,7 +167,7 @@ namespace llvm {
}
/// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const SCEV *S) {
+ static bool classof(const SCEV *S) {
return S->getSCEVType() == scAddExpr ||
S->getSCEVType() == scMulExpr ||
S->getSCEVType() == scSMaxExpr ||
@@ -185,7 +185,7 @@ namespace llvm {
public:
/// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const SCEV *S) {
+ static bool classof(const SCEV *S) {
return S->getSCEVType() == scAddExpr ||
S->getSCEVType() == scMulExpr ||
S->getSCEVType() == scSMaxExpr ||
@@ -217,7 +217,7 @@ namespace llvm {
}
/// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const SCEV *S) {
+ static bool classof(const SCEV *S) {
return S->getSCEVType() == scAddExpr;
}
};
@@ -234,7 +234,7 @@ namespace llvm {
public:
/// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const SCEV *S) {
+ static bool classof(const SCEV *S) {
return S->getSCEVType() == scMulExpr;
}
};
@@ -263,7 +263,7 @@ namespace llvm {
}
/// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const SCEV *S) {
+ static bool classof(const SCEV *S) {
return S->getSCEVType() == scUDivExpr;
}
};
@@ -345,7 +345,7 @@ namespace llvm {
}
/// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const SCEV *S) {
+ static bool classof(const SCEV *S) {
return S->getSCEVType() == scAddRecExpr;
}
};
@@ -363,7 +363,7 @@ namespace llvm {
public:
/// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const SCEV *S) {
+ static bool classof(const SCEV *S) {
return S->getSCEVType() == scSMaxExpr;
}
};
@@ -382,7 +382,7 @@ namespace llvm {
public:
/// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const SCEV *S) {
+ static bool classof(const SCEV *S) {
return S->getSCEVType() == scUMaxExpr;
}
};
@@ -428,7 +428,7 @@ namespace llvm {
Type *getType() const { return getValPtr()->getType(); }
/// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const SCEV *S) {
+ static bool classof(const SCEV *S) {
return S->getSCEVType() == scUnknown;
}
};
@@ -595,58 +595,82 @@ namespace llvm {
const SCEV *visitTruncateExpr(const SCEVTruncateExpr *Expr) {
const SCEV *Operand = ((SC*)this)->visit(Expr->getOperand());
- return SE.getTruncateExpr(Operand, Expr->getType());
+ return Operand == Expr->getOperand()
+ ? Expr
+ : SE.getTruncateExpr(Operand, Expr->getType());
}
const SCEV *visitZeroExtendExpr(const SCEVZeroExtendExpr *Expr) {
const SCEV *Operand = ((SC*)this)->visit(Expr->getOperand());
- return SE.getZeroExtendExpr(Operand, Expr->getType());
+ return Operand == Expr->getOperand()
+ ? Expr
+ : SE.getZeroExtendExpr(Operand, Expr->getType());
}
const SCEV *visitSignExtendExpr(const SCEVSignExtendExpr *Expr) {
const SCEV *Operand = ((SC*)this)->visit(Expr->getOperand());
- return SE.getSignExtendExpr(Operand, Expr->getType());
+ return Operand == Expr->getOperand()
+ ? Expr
+ : SE.getSignExtendExpr(Operand, Expr->getType());
}
const SCEV *visitAddExpr(const SCEVAddExpr *Expr) {
SmallVector<const SCEV *, 2> Operands;
- for (int i = 0, e = Expr->getNumOperands(); i < e; ++i)
- Operands.push_back(((SC*)this)->visit(Expr->getOperand(i)));
- return SE.getAddExpr(Operands);
+ bool Changed = false;
+ for (auto *Op : Expr->operands()) {
+ Operands.push_back(((SC*)this)->visit(Op));
+ Changed |= Op != Operands.back();
+ }
+ return !Changed ? Expr : SE.getAddExpr(Operands);
}
const SCEV *visitMulExpr(const SCEVMulExpr *Expr) {
SmallVector<const SCEV *, 2> Operands;
- for (int i = 0, e = Expr->getNumOperands(); i < e; ++i)
- Operands.push_back(((SC*)this)->visit(Expr->getOperand(i)));
- return SE.getMulExpr(Operands);
+ bool Changed = false;
+ for (auto *Op : Expr->operands()) {
+ Operands.push_back(((SC*)this)->visit(Op));
+ Changed |= Op != Operands.back();
+ }
+ return !Changed ? Expr : SE.getMulExpr(Operands);
}
const SCEV *visitUDivExpr(const SCEVUDivExpr *Expr) {
- return SE.getUDivExpr(((SC*)this)->visit(Expr->getLHS()),
- ((SC*)this)->visit(Expr->getRHS()));
+ auto *LHS = ((SC *)this)->visit(Expr->getLHS());
+ auto *RHS = ((SC *)this)->visit(Expr->getRHS());
+ bool Changed = LHS != Expr->getLHS() || RHS != Expr->getRHS();
+ return !Changed ? Expr : SE.getUDivExpr(LHS, RHS);
}
const SCEV *visitAddRecExpr(const SCEVAddRecExpr *Expr) {
SmallVector<const SCEV *, 2> Operands;
- for (int i = 0, e = Expr->getNumOperands(); i < e; ++i)
- Operands.push_back(((SC*)this)->visit(Expr->getOperand(i)));
- return SE.getAddRecExpr(Operands, Expr->getLoop(),
- Expr->getNoWrapFlags());
+ bool Changed = false;
+ for (auto *Op : Expr->operands()) {
+ Operands.push_back(((SC*)this)->visit(Op));
+ Changed |= Op != Operands.back();
+ }
+ return !Changed ? Expr
+ : SE.getAddRecExpr(Operands, Expr->getLoop(),
+ Expr->getNoWrapFlags());
}
const SCEV *visitSMaxExpr(const SCEVSMaxExpr *Expr) {
SmallVector<const SCEV *, 2> Operands;
- for (int i = 0, e = Expr->getNumOperands(); i < e; ++i)
- Operands.push_back(((SC*)this)->visit(Expr->getOperand(i)));
- return SE.getSMaxExpr(Operands);
+ bool Changed = false;
+ for (auto *Op : Expr->operands()) {
+ Operands.push_back(((SC *)this)->visit(Op));
+ Changed |= Op != Operands.back();
+ }
+ return !Changed ? Expr : SE.getSMaxExpr(Operands);
}
const SCEV *visitUMaxExpr(const SCEVUMaxExpr *Expr) {
SmallVector<const SCEV *, 2> Operands;
- for (int i = 0, e = Expr->getNumOperands(); i < e; ++i)
- Operands.push_back(((SC*)this)->visit(Expr->getOperand(i)));
- return SE.getUMaxExpr(Operands);
+ bool Changed = false;
+ for (auto *Op : Expr->operands()) {
+ Operands.push_back(((SC*)this)->visit(Op));
+ Changed |= Op != Operands.back();
+ }
+ return !Changed ? Expr : SE.getUMaxExpr(Operands);
}
const SCEV *visitUnknown(const SCEVUnknown *Expr) {
diff --git a/contrib/llvm/include/llvm/Analysis/ScalarEvolutionNormalization.h b/contrib/llvm/include/llvm/Analysis/ScalarEvolutionNormalization.h
index 7c6423a..51c9212 100644
--- a/contrib/llvm/include/llvm/Analysis/ScalarEvolutionNormalization.h
+++ b/contrib/llvm/include/llvm/Analysis/ScalarEvolutionNormalization.h
@@ -36,43 +36,34 @@
#ifndef LLVM_ANALYSIS_SCALAREVOLUTIONNORMALIZATION_H
#define LLVM_ANALYSIS_SCALAREVOLUTIONNORMALIZATION_H
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/Analysis/ScalarEvolutionExpressions.h"
namespace llvm {
-class Instruction;
-class DominatorTree;
class Loop;
class ScalarEvolution;
class SCEV;
-class Value;
-/// TransformKind - Different types of transformations that
-/// TransformForPostIncUse can do.
-enum TransformKind {
- /// Normalize - Normalize according to the given loops.
- Normalize,
- /// NormalizeAutodetect - Detect post-inc opportunities on new expressions,
- /// update the given loop set, and normalize.
- NormalizeAutodetect,
- /// Denormalize - Perform the inverse transform on the expression with the
- /// given loop set.
- Denormalize
-};
-
-/// PostIncLoopSet - A set of loops.
typedef SmallPtrSet<const Loop *, 2> PostIncLoopSet;
-/// TransformForPostIncUse - Transform the given expression according to the
-/// given transformation kind.
-const SCEV *TransformForPostIncUse(TransformKind Kind,
- const SCEV *S,
- Instruction *User,
- Value *OperandValToReplace,
- PostIncLoopSet &Loops,
- ScalarEvolution &SE,
- DominatorTree &DT);
+typedef function_ref<bool(const SCEVAddRecExpr *)> NormalizePredTy;
+
+/// Normalize \p S to be post-increment for all loops present in \p
+/// Loops.
+const SCEV *normalizeForPostIncUse(const SCEV *S, const PostIncLoopSet &Loops,
+ ScalarEvolution &SE);
+
+/// Normalize \p S for all add recurrence sub-expressions for which \p
+/// Pred returns true.
+const SCEV *normalizeForPostIncUseIf(const SCEV *S, NormalizePredTy Pred,
+ ScalarEvolution &SE);
-}
+/// Denormalize \p S to be post-increment for all loops present in \p
+/// Loops.
+const SCEV *denormalizeForPostIncUse(const SCEV *S, const PostIncLoopSet &Loops,
+ ScalarEvolution &SE);
+} // namespace llvm
#endif
diff --git a/contrib/llvm/include/llvm/Analysis/TargetLibraryInfo.def b/contrib/llvm/include/llvm/Analysis/TargetLibraryInfo.def
index 5d5e5b1..9cbe917 100644
--- a/contrib/llvm/include/llvm/Analysis/TargetLibraryInfo.def
+++ b/contrib/llvm/include/llvm/Analysis/TargetLibraryInfo.def
@@ -20,7 +20,7 @@
// One of TLI_DEFINE_ENUM/STRING are defined.
#if defined(TLI_DEFINE_ENUM)
-#define TLI_DEFINE_ENUM_INTERNAL(enum_variant) enum_variant,
+#define TLI_DEFINE_ENUM_INTERNAL(enum_variant) LibFunc_##enum_variant,
#define TLI_DEFINE_STRING_INTERNAL(string_repr)
#else
#define TLI_DEFINE_ENUM_INTERNAL(enum_variant)
@@ -161,6 +161,60 @@ TLI_DEFINE_STRING_INTERNAL("_Znwm")
/// void *new(unsigned long, nothrow);
TLI_DEFINE_ENUM_INTERNAL(ZnwmRKSt9nothrow_t)
TLI_DEFINE_STRING_INTERNAL("_ZnwmRKSt9nothrow_t")
+/// double __acos_finite(double x);
+TLI_DEFINE_ENUM_INTERNAL(acos_finite)
+TLI_DEFINE_STRING_INTERNAL("__acos_finite")
+/// float __acosf_finite(float x);
+TLI_DEFINE_ENUM_INTERNAL(acosf_finite)
+TLI_DEFINE_STRING_INTERNAL("__acosf_finite")
+/// double __acosh_finite(double x);
+TLI_DEFINE_ENUM_INTERNAL(acosh_finite)
+TLI_DEFINE_STRING_INTERNAL("__acosh_finite")
+/// float __acoshf_finite(float x);
+TLI_DEFINE_ENUM_INTERNAL(acoshf_finite)
+TLI_DEFINE_STRING_INTERNAL("__acoshf_finite")
+/// long double __acoshl_finite(long double x);
+TLI_DEFINE_ENUM_INTERNAL(acoshl_finite)
+TLI_DEFINE_STRING_INTERNAL("__acoshl_finite")
+/// long double __acosl_finite(long double x);
+TLI_DEFINE_ENUM_INTERNAL(acosl_finite)
+TLI_DEFINE_STRING_INTERNAL("__acosl_finite")
+/// double __asin_finite(double x);
+TLI_DEFINE_ENUM_INTERNAL(asin_finite)
+TLI_DEFINE_STRING_INTERNAL("__asin_finite")
+/// float __asinf_finite(float x);
+TLI_DEFINE_ENUM_INTERNAL(asinf_finite)
+TLI_DEFINE_STRING_INTERNAL("__asinf_finite")
+/// long double __asinl_finite(long double x);
+TLI_DEFINE_ENUM_INTERNAL(asinl_finite)
+TLI_DEFINE_STRING_INTERNAL("__asinl_finite")
+/// double atan2_finite(double y, double x);
+TLI_DEFINE_ENUM_INTERNAL(atan2_finite)
+TLI_DEFINE_STRING_INTERNAL("__atan2_finite")
+/// float atan2f_finite(float y, float x);
+TLI_DEFINE_ENUM_INTERNAL(atan2f_finite)
+TLI_DEFINE_STRING_INTERNAL("__atan2f_finite")
+/// long double atan2l_finite(long double y, long double x);
+TLI_DEFINE_ENUM_INTERNAL(atan2l_finite)
+TLI_DEFINE_STRING_INTERNAL("__atan2l_finite")
+/// double __atanh_finite(double x);
+TLI_DEFINE_ENUM_INTERNAL(atanh_finite)
+TLI_DEFINE_STRING_INTERNAL("__atanh_finite")
+/// float __atanhf_finite(float x);
+TLI_DEFINE_ENUM_INTERNAL(atanhf_finite)
+TLI_DEFINE_STRING_INTERNAL("__atanhf_finite")
+/// long double __atanhl_finite(long double x);
+TLI_DEFINE_ENUM_INTERNAL(atanhl_finite)
+TLI_DEFINE_STRING_INTERNAL("__atanhl_finite")
+/// double __cosh_finite(double x);
+TLI_DEFINE_ENUM_INTERNAL(cosh_finite)
+TLI_DEFINE_STRING_INTERNAL("__cosh_finite")
+/// float __coshf_finite(float x);
+TLI_DEFINE_ENUM_INTERNAL(coshf_finite)
+TLI_DEFINE_STRING_INTERNAL("__coshf_finite")
+/// long double __coshl_finite(long double x);
+TLI_DEFINE_ENUM_INTERNAL(coshl_finite)
+TLI_DEFINE_STRING_INTERNAL("__coshl_finite")
/// double __cospi(double x);
TLI_DEFINE_ENUM_INTERNAL(cospi)
TLI_DEFINE_STRING_INTERNAL("__cospi")
@@ -180,12 +234,66 @@ TLI_DEFINE_STRING_INTERNAL("__cxa_guard_acquire")
/// void __cxa_guard_release(guard_t *guard);
TLI_DEFINE_ENUM_INTERNAL(cxa_guard_release)
TLI_DEFINE_STRING_INTERNAL("__cxa_guard_release")
+/// double __exp10_finite(double x);
+TLI_DEFINE_ENUM_INTERNAL(exp10_finite)
+TLI_DEFINE_STRING_INTERNAL("__exp10_finite")
+/// float __exp10f_finite(float x);
+TLI_DEFINE_ENUM_INTERNAL(exp10f_finite)
+TLI_DEFINE_STRING_INTERNAL("__exp10f_finite")
+/// long double __exp10l_finite(long double x);
+TLI_DEFINE_ENUM_INTERNAL(exp10l_finite)
+TLI_DEFINE_STRING_INTERNAL("__exp10l_finite")
+/// double __exp2_finite(double x);
+TLI_DEFINE_ENUM_INTERNAL(exp2_finite)
+TLI_DEFINE_STRING_INTERNAL("__exp2_finite")
+/// float __exp2f_finite(float x);
+TLI_DEFINE_ENUM_INTERNAL(exp2f_finite)
+TLI_DEFINE_STRING_INTERNAL("__exp2f_finite")
+/// long double __exp2l_finite(long double x);
+TLI_DEFINE_ENUM_INTERNAL(exp2l_finite)
+TLI_DEFINE_STRING_INTERNAL("__exp2l_finite")
+/// double __exp_finite(double x);
+TLI_DEFINE_ENUM_INTERNAL(exp_finite)
+TLI_DEFINE_STRING_INTERNAL("__exp_finite")
+/// float __expf_finite(float x);
+TLI_DEFINE_ENUM_INTERNAL(expf_finite)
+TLI_DEFINE_STRING_INTERNAL("__expf_finite")
+/// long double __expl_finite(long double x);
+TLI_DEFINE_ENUM_INTERNAL(expl_finite)
+TLI_DEFINE_STRING_INTERNAL("__expl_finite")
/// int __isoc99_scanf (const char *format, ...)
TLI_DEFINE_ENUM_INTERNAL(dunder_isoc99_scanf)
TLI_DEFINE_STRING_INTERNAL("__isoc99_scanf")
/// int __isoc99_sscanf(const char *s, const char *format, ...)
TLI_DEFINE_ENUM_INTERNAL(dunder_isoc99_sscanf)
TLI_DEFINE_STRING_INTERNAL("__isoc99_sscanf")
+/// double __log10_finite(double x);
+TLI_DEFINE_ENUM_INTERNAL(log10_finite)
+TLI_DEFINE_STRING_INTERNAL("__log10_finite")
+/// float __log10f_finite(float x);
+TLI_DEFINE_ENUM_INTERNAL(log10f_finite)
+TLI_DEFINE_STRING_INTERNAL("__log10f_finite")
+/// long double __log10l_finite(long double x);
+TLI_DEFINE_ENUM_INTERNAL(log10l_finite)
+TLI_DEFINE_STRING_INTERNAL("__log10l_finite")
+/// double __log2_finite(double x);
+TLI_DEFINE_ENUM_INTERNAL(log2_finite)
+TLI_DEFINE_STRING_INTERNAL("__log2_finite")
+/// float __log2f_finite(float x);
+TLI_DEFINE_ENUM_INTERNAL(log2f_finite)
+TLI_DEFINE_STRING_INTERNAL("__log2f_finite")
+/// long double __log2l_finite(long double x);
+TLI_DEFINE_ENUM_INTERNAL(log2l_finite)
+TLI_DEFINE_STRING_INTERNAL("__log2l_finite")
+/// double __log_finite(double x);
+TLI_DEFINE_ENUM_INTERNAL(log_finite)
+TLI_DEFINE_STRING_INTERNAL("__log_finite")
+/// float __logf_finite(float x);
+TLI_DEFINE_ENUM_INTERNAL(logf_finite)
+TLI_DEFINE_STRING_INTERNAL("__logf_finite")
+/// long double __logl_finite(long double x);
+TLI_DEFINE_ENUM_INTERNAL(logl_finite)
+TLI_DEFINE_STRING_INTERNAL("__logl_finite")
/// void *__memcpy_chk(void *s1, const void *s2, size_t n, size_t s1size);
TLI_DEFINE_ENUM_INTERNAL(memcpy_chk)
TLI_DEFINE_STRING_INTERNAL("__memcpy_chk")
@@ -199,13 +307,30 @@ TLI_DEFINE_STRING_INTERNAL("__memset_chk")
// int __nvvm_reflect(const char *)
TLI_DEFINE_ENUM_INTERNAL(nvvm_reflect)
TLI_DEFINE_STRING_INTERNAL("__nvvm_reflect")
-
+/// double __pow_finite(double x, double y);
+TLI_DEFINE_ENUM_INTERNAL(pow_finite)
+TLI_DEFINE_STRING_INTERNAL("__pow_finite")
+/// float _powf_finite(float x, float y);
+TLI_DEFINE_ENUM_INTERNAL(powf_finite)
+TLI_DEFINE_STRING_INTERNAL("__powf_finite")
+/// long double __powl_finite(long double x, long double y);
+TLI_DEFINE_ENUM_INTERNAL(powl_finite)
+TLI_DEFINE_STRING_INTERNAL("__powl_finite")
/// double __sincospi_stret(double x);
TLI_DEFINE_ENUM_INTERNAL(sincospi_stret)
TLI_DEFINE_STRING_INTERNAL("__sincospi_stret")
/// float __sincospif_stret(float x);
TLI_DEFINE_ENUM_INTERNAL(sincospif_stret)
TLI_DEFINE_STRING_INTERNAL("__sincospif_stret")
+/// double __sinh_finite(double x);
+TLI_DEFINE_ENUM_INTERNAL(sinh_finite)
+TLI_DEFINE_STRING_INTERNAL("__sinh_finite")
+/// float _sinhf_finite(float x);
+TLI_DEFINE_ENUM_INTERNAL(sinhf_finite)
+TLI_DEFINE_STRING_INTERNAL("__sinhf_finite")
+/// long double __sinhl_finite(long double x);
+TLI_DEFINE_ENUM_INTERNAL(sinhl_finite)
+TLI_DEFINE_STRING_INTERNAL("__sinhl_finite")
/// double __sinpi(double x);
TLI_DEFINE_ENUM_INTERNAL(sinpi)
TLI_DEFINE_STRING_INTERNAL("__sinpi")
@@ -1115,6 +1240,9 @@ TLI_DEFINE_STRING_INTERNAL("vsprintf")
/// int vsscanf(const char *s, const char *format, va_list arg);
TLI_DEFINE_ENUM_INTERNAL(vsscanf)
TLI_DEFINE_STRING_INTERNAL("vsscanf")
+/// size_t wcslen (const wchar_t* wcs);
+TLI_DEFINE_ENUM_INTERNAL(wcslen)
+TLI_DEFINE_STRING_INTERNAL("wcslen")
/// ssize_t write(int fildes, const void *buf, size_t nbyte);
TLI_DEFINE_ENUM_INTERNAL(write)
TLI_DEFINE_STRING_INTERNAL("write")
diff --git a/contrib/llvm/include/llvm/Analysis/TargetLibraryInfo.h b/contrib/llvm/include/llvm/Analysis/TargetLibraryInfo.h
index 8675882..d75e783 100644
--- a/contrib/llvm/include/llvm/Analysis/TargetLibraryInfo.h
+++ b/contrib/llvm/include/llvm/Analysis/TargetLibraryInfo.h
@@ -13,6 +13,7 @@
#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/Module.h"
#include "llvm/IR/PassManager.h"
@@ -30,14 +31,12 @@ struct VecDesc {
unsigned VectorizationFactor;
};
- namespace LibFunc {
- enum Func {
+ enum LibFunc {
#define TLI_DEFINE_ENUM
#include "llvm/Analysis/TargetLibraryInfo.def"
- NumLibFuncs
- };
- }
+ NumLibFuncs
+ };
/// Implementation of the target library information.
///
@@ -48,9 +47,9 @@ struct VecDesc {
class TargetLibraryInfoImpl {
friend class TargetLibraryInfo;
- unsigned char AvailableArray[(LibFunc::NumLibFuncs+3)/4];
+ unsigned char AvailableArray[(NumLibFuncs+3)/4];
llvm::DenseMap<unsigned, std::string> CustomNames;
- static StringRef const StandardNames[LibFunc::NumLibFuncs];
+ static StringRef const StandardNames[NumLibFuncs];
bool ShouldExtI32Param, ShouldExtI32Return, ShouldSignExtI32Param;
enum AvailabilityState {
@@ -58,11 +57,11 @@ class TargetLibraryInfoImpl {
CustomName = 1,
Unavailable = 0 // (memset to all zeros)
};
- void setState(LibFunc::Func F, AvailabilityState State) {
+ void setState(LibFunc F, AvailabilityState State) {
AvailableArray[F/4] &= ~(3 << 2*(F&3));
AvailableArray[F/4] |= State << 2*(F&3);
}
- AvailabilityState getState(LibFunc::Func F) const {
+ AvailabilityState getState(LibFunc F) const {
return static_cast<AvailabilityState>((AvailableArray[F/4] >> 2*(F&3)) & 3);
}
@@ -74,7 +73,7 @@ class TargetLibraryInfoImpl {
/// Return true if the function type FTy is valid for the library function
/// F, regardless of whether the function is available.
- bool isValidProtoForLibFunc(const FunctionType &FTy, LibFunc::Func F,
+ bool isValidProtoForLibFunc(const FunctionType &FTy, LibFunc F,
const DataLayout *DL) const;
public:
@@ -104,28 +103,28 @@ public:
///
/// If it is one of the known library functions, return true and set F to the
/// corresponding value.
- bool getLibFunc(StringRef funcName, LibFunc::Func &F) const;
+ bool getLibFunc(StringRef funcName, LibFunc &F) const;
/// Searches for a particular function name, also checking that its type is
/// valid for the library function matching that name.
///
/// If it is one of the known library functions, return true and set F to the
/// corresponding value.
- bool getLibFunc(const Function &FDecl, LibFunc::Func &F) const;
+ bool getLibFunc(const Function &FDecl, LibFunc &F) const;
/// Forces a function to be marked as unavailable.
- void setUnavailable(LibFunc::Func F) {
+ void setUnavailable(LibFunc F) {
setState(F, Unavailable);
}
/// Forces a function to be marked as available.
- void setAvailable(LibFunc::Func F) {
+ void setAvailable(LibFunc F) {
setState(F, StandardName);
}
/// Forces a function to be marked as available and provide an alternate name
/// that must be used.
- void setAvailableWithName(LibFunc::Func F, StringRef Name) {
+ void setAvailableWithName(LibFunc F, StringRef Name) {
if (StandardNames[F] != Name) {
setState(F, CustomName);
CustomNames[F] = Name;
@@ -193,6 +192,14 @@ public:
void setShouldSignExtI32Param(bool Val) {
ShouldSignExtI32Param = Val;
}
+
+ /// Returns the size of the wchar_t type in bytes.
+ unsigned getWCharSize(const Module &M) const;
+
+ /// Returns size of the default wchar_t type on target \p T. This is mostly
+ /// intended to verify that the size in the frontend matches LLVM. All other
+ /// queries should use getWCharSize() instead.
+ static unsigned getTargetWCharSize(const Triple &T);
};
/// Provides information about what library functions are available for
@@ -225,16 +232,23 @@ public:
///
/// If it is one of the known library functions, return true and set F to the
/// corresponding value.
- bool getLibFunc(StringRef funcName, LibFunc::Func &F) const {
+ bool getLibFunc(StringRef funcName, LibFunc &F) const {
return Impl->getLibFunc(funcName, F);
}
- bool getLibFunc(const Function &FDecl, LibFunc::Func &F) const {
+ bool getLibFunc(const Function &FDecl, LibFunc &F) const {
return Impl->getLibFunc(FDecl, F);
}
+ /// If a callsite 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);
+ }
+
/// Tests whether a library function is available.
- bool has(LibFunc::Func F) const {
+ bool has(LibFunc F) const {
return Impl->getState(F) != TargetLibraryInfoImpl::Unavailable;
}
bool isFunctionVectorizable(StringRef F, unsigned VF) const {
@@ -249,37 +263,37 @@ public:
/// Tests if the function is both available and a candidate for optimized code
/// generation.
- bool hasOptimizedCodeGen(LibFunc::Func F) const {
+ bool hasOptimizedCodeGen(LibFunc F) const {
if (Impl->getState(F) == TargetLibraryInfoImpl::Unavailable)
return false;
switch (F) {
default: break;
- case LibFunc::copysign: case LibFunc::copysignf: case LibFunc::copysignl:
- case LibFunc::fabs: case LibFunc::fabsf: case LibFunc::fabsl:
- case LibFunc::sin: case LibFunc::sinf: case LibFunc::sinl:
- case LibFunc::cos: case LibFunc::cosf: case LibFunc::cosl:
- case LibFunc::sqrt: case LibFunc::sqrtf: case LibFunc::sqrtl:
- case LibFunc::sqrt_finite: case LibFunc::sqrtf_finite:
- case LibFunc::sqrtl_finite:
- case LibFunc::fmax: case LibFunc::fmaxf: case LibFunc::fmaxl:
- case LibFunc::fmin: case LibFunc::fminf: case LibFunc::fminl:
- case LibFunc::floor: case LibFunc::floorf: case LibFunc::floorl:
- case LibFunc::nearbyint: case LibFunc::nearbyintf: case LibFunc::nearbyintl:
- case LibFunc::ceil: case LibFunc::ceilf: case LibFunc::ceill:
- case LibFunc::rint: case LibFunc::rintf: case LibFunc::rintl:
- case LibFunc::round: case LibFunc::roundf: case LibFunc::roundl:
- 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::memcmp: case LibFunc::strcmp: case LibFunc::strcpy:
- case LibFunc::stpcpy: case LibFunc::strlen: case LibFunc::strnlen:
- case LibFunc::memchr: case LibFunc::mempcpy:
+ case LibFunc_copysign: case LibFunc_copysignf: case LibFunc_copysignl:
+ case LibFunc_fabs: case LibFunc_fabsf: case LibFunc_fabsl:
+ case LibFunc_sin: case LibFunc_sinf: case LibFunc_sinl:
+ case LibFunc_cos: case LibFunc_cosf: case LibFunc_cosl:
+ case LibFunc_sqrt: case LibFunc_sqrtf: case LibFunc_sqrtl:
+ case LibFunc_sqrt_finite: case LibFunc_sqrtf_finite:
+ case LibFunc_sqrtl_finite:
+ case LibFunc_fmax: case LibFunc_fmaxf: case LibFunc_fmaxl:
+ case LibFunc_fmin: case LibFunc_fminf: case LibFunc_fminl:
+ case LibFunc_floor: case LibFunc_floorf: case LibFunc_floorl:
+ case LibFunc_nearbyint: case LibFunc_nearbyintf: case LibFunc_nearbyintl:
+ case LibFunc_ceil: case LibFunc_ceilf: case LibFunc_ceill:
+ case LibFunc_rint: case LibFunc_rintf: case LibFunc_rintl:
+ case LibFunc_round: case LibFunc_roundf: case LibFunc_roundl:
+ 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_memcmp: case LibFunc_strcmp: case LibFunc_strcpy:
+ case LibFunc_stpcpy: case LibFunc_strlen: case LibFunc_strnlen:
+ case LibFunc_memchr: case LibFunc_mempcpy:
return true;
}
return false;
}
- StringRef getName(LibFunc::Func F) const {
+ StringRef getName(LibFunc F) const {
auto State = Impl->getState(F);
if (State == TargetLibraryInfoImpl::Unavailable)
return StringRef();
@@ -309,6 +323,11 @@ public:
return Attribute::None;
}
+ /// \copydoc TargetLibraryInfoImpl::getWCharSize()
+ unsigned getWCharSize(const Module &M) const {
+ return Impl->getWCharSize(M);
+ }
+
/// Handle invalidation from the pass manager.
///
/// If we try to invalidate this info, just return false. It cannot become
diff --git a/contrib/llvm/include/llvm/Analysis/TargetTransformInfo.h b/contrib/llvm/include/llvm/Analysis/TargetTransformInfo.h
index 209f05c..24edd38 100644
--- a/contrib/llvm/include/llvm/Analysis/TargetTransformInfo.h
+++ b/contrib/llvm/include/llvm/Analysis/TargetTransformInfo.h
@@ -44,23 +44,26 @@ class Value;
/// \brief Information about a load/store intrinsic defined by the target.
struct MemIntrinsicInfo {
- MemIntrinsicInfo()
- : ReadMem(false), WriteMem(false), IsSimple(false), MatchingId(0),
- NumMemRefs(0), PtrVal(nullptr) {}
- bool ReadMem;
- bool WriteMem;
- /// True only if this memory operation is non-volatile, non-atomic, and
- /// unordered. (See LoadInst/StoreInst for details on each)
- bool IsSimple;
- // Same Id is set by the target for corresponding load/store intrinsics.
- unsigned short MatchingId;
- int NumMemRefs;
-
/// This is the pointer that the intrinsic is loading from or storing to.
/// If this is non-null, then analysis/optimization passes can assume that
/// this intrinsic is functionally equivalent to a load/store from this
/// pointer.
- Value *PtrVal;
+ Value *PtrVal = nullptr;
+
+ // Ordering for atomic operations.
+ AtomicOrdering Ordering = AtomicOrdering::NotAtomic;
+
+ // Same Id is set by the target for corresponding load/store intrinsics.
+ unsigned short MatchingId = 0;
+
+ bool ReadMem = false;
+ bool WriteMem = false;
+ bool IsVolatile = false;
+
+ bool isUnordered() const {
+ return (Ordering == AtomicOrdering::NotAtomic ||
+ Ordering == AtomicOrdering::Unordered) && !IsVolatile;
+ }
};
/// \brief This pass provides access to the codegen interfaces that are needed
@@ -152,6 +155,13 @@ public:
int getGEPCost(Type *PointeeType, const Value *Ptr,
ArrayRef<const Value *> Operands) const;
+ /// \brief 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;
+
/// \brief Estimate the cost of a function call when lowered.
///
/// The contract for this is the same as \c getOperationCost except that it
@@ -194,6 +204,12 @@ public:
int getIntrinsicCost(Intrinsic::ID IID, Type *RetTy,
ArrayRef<const Value *> Arguments) const;
+ /// \return The estimated number of case clusters when lowering \p 'SI'.
+ /// \p JTSize Set a jump table size only when \p SI is suitable for a jump
+ /// table.
+ unsigned getEstimatedNumberOfCaseClusters(const SwitchInst &SI,
+ unsigned &JTSize) const;
+
/// \brief Estimate the cost of a given IR user when lowered.
///
/// This can estimate the cost of either a ConstantExpr or Instruction when
@@ -207,9 +223,23 @@ public:
/// other context they may not be folded. This routine can distinguish such
/// cases.
///
+ /// \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
+ /// to the number of the current operands the IR user has. Their order on the
+ /// list must be the same as the order of the current operands the IR user
+ /// has.
+ ///
/// 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) const;
+ int getUserCost(const User *U, ArrayRef<const Value *> Operands) const;
+
+ /// \brief 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 {
+ SmallVector<const Value *, 4> Operands(U->value_op_begin(),
+ U->value_op_end());
+ return getUserCost(U, Operands);
+ }
/// \brief Return true if branch divergence exists.
///
@@ -226,6 +256,29 @@ public:
/// starting with the sources of divergence.
bool isSourceOfDivergence(const Value *V) const;
+ // \brief Returns true for the target specific
+ // set of operations which produce uniform result
+ // even taking non-unform arguments
+ bool isAlwaysUniform(const Value *V) const;
+
+ /// Returns the address space ID for a target's 'flat' address space. Note
+ /// this is not necessarily the same as addrspace(0), which LLVM sometimes
+ /// refers to as the generic address space. The flat address space is a
+ /// generic address space that can be used access multiple segments of memory
+ /// with different address spaces. Access of a memory location through a
+ /// pointer with this address space is expected to be legal but slower
+ /// compared to the same memory location accessed through a pointer with a
+ /// different address space.
+ //
+ /// This is for for targets with different pointer representations which can
+ /// be converted with the addrspacecast instruction. If a pointer is converted
+ /// to this address space, optimizations should attempt to replace the access
+ /// with the source address space.
+ ///
+ /// \returns ~0u if the target does not have such a flat address space to
+ /// optimize away.
+ unsigned getFlatAddressSpace() const;
+
/// \brief Test whether calls to a function lower to actual program function
/// calls.
///
@@ -240,6 +293,19 @@ public:
/// incurs significant execution cost.
bool isLoweredToCall(const Function *F) const;
+ struct LSRCost {
+ /// TODO: Some of these could be merged. Also, a lexical ordering
+ /// isn't always optimal.
+ unsigned Insns;
+ unsigned NumRegs;
+ unsigned AddRecCost;
+ unsigned NumIVMuls;
+ unsigned NumBaseAdds;
+ unsigned ImmCost;
+ unsigned SetupCost;
+ unsigned ScaleCost;
+ };
+
/// Parameters that control the generic loop unrolling transformation.
struct UnrollingPreferences {
/// The cost threshold for the unrolled loop. Should be relative to the
@@ -321,7 +387,8 @@ public:
/// \brief Get target-customized preferences for the generic loop unrolling
/// transformation. The caller will initialize UP with the current
/// target-independent defaults.
- void getUnrollingPreferences(Loop *L, UnrollingPreferences &UP) const;
+ void getUnrollingPreferences(Loop *L, ScalarEvolution &,
+ UnrollingPreferences &UP) const;
/// @}
@@ -358,6 +425,10 @@ public:
bool HasBaseReg, int64_t Scale,
unsigned AddrSpace = 0) const;
+ /// \brief Return true if LSR cost of C1 is lower than C1.
+ bool isLSRCostLess(TargetTransformInfo::LSRCost &C1,
+ TargetTransformInfo::LSRCost &C2) const;
+
/// \brief Return true if the target supports masked load/store
/// AVX2 and AVX-512 targets allow masks for consecutive load and store
bool isLegalMaskedStore(Type *DataType) const;
@@ -369,6 +440,9 @@ public:
bool isLegalMaskedScatter(Type *DataType) const;
bool isLegalMaskedGather(Type *DataType) const;
+ /// Return true if target doesn't mind addresses in vectors.
+ bool prefersVectorizedAddressing() const;
+
/// \brief Return the cost of the scaling factor used in the addressing
/// mode represented by AM for this target, for a load/store
/// of the specified type.
@@ -411,9 +485,22 @@ public:
/// containing this constant value for the target.
bool shouldBuildLookupTablesForConstant(Constant *C) const;
+ unsigned getScalarizationOverhead(Type *Ty, bool Insert, bool Extract) const;
+
+ unsigned getOperandsScalarizationOverhead(ArrayRef<const Value *> Args,
+ unsigned VF) const;
+
+ /// If target has efficient vector element load/store instructions, it can
+ /// return true here so that insertion/extraction costs are not added to
+ /// the scalarization cost of a load/store.
+ bool supportsEfficientVectorElementLoadStore() const;
+
/// \brief Don't restrict interleaved unrolling to small loops.
bool enableAggressiveInterleaving(bool LoopHasReductions) const;
+ /// \brief Enable inline expansion of memcmp
+ bool expandMemCmp(Instruction *I, unsigned &MaxLoadSize) const;
+
/// \brief Enable matching of interleaved access groups.
bool enableInterleavedAccessVectorization() const;
@@ -500,6 +587,15 @@ public:
/// \return The width of the largest scalar or vector register type.
unsigned getRegisterBitWidth(bool Vector) const;
+ /// \return The width of the smallest vector register type.
+ unsigned getMinVectorRegisterBitWidth() const;
+
+ /// \return True if it should be considered for address type promotion.
+ /// \p AllowPromotionWithoutCommonHeader Set true if promoting \p I is
+ /// profitable without finding other extensions fed by the same input.
+ bool shouldConsiderAddressTypePromotion(
+ const Instruction &I, bool &AllowPromotionWithoutCommonHeader) const;
+
/// \return The size of a cache line in bytes.
unsigned getCacheLineSize() const;
@@ -540,8 +636,10 @@ public:
Type *SubTp = nullptr) const;
/// \return The expected cost of cast instructions, such as bitcast, trunc,
- /// zext, etc.
- int getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src) const;
+ /// 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,
+ const Instruction *I = nullptr) const;
/// \return The expected cost of a sign- or zero-extended vector extract. Use
/// -1 to indicate that there is no information about the index value.
@@ -552,9 +650,11 @@ public:
/// Phi, Ret, Br.
int getCFInstrCost(unsigned Opcode) const;
- /// \returns The expected cost of compare and select instructions.
+ /// \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;
+ Type *CondTy = nullptr, 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.
@@ -562,7 +662,7 @@ public:
/// \return The cost of Load and Store instructions.
int getMemoryOpCost(unsigned Opcode, Type *Src, unsigned Alignment,
- unsigned AddressSpace) const;
+ unsigned AddressSpace, const Instruction *I = nullptr) const;
/// \return The cost of masked Load and Store instructions.
int getMaskedMemoryOpCost(unsigned Opcode, Type *Src, unsigned Alignment,
@@ -605,13 +705,19 @@ public:
/// ((v0+v2), (v1+v3), undef, undef)
int getReductionCost(unsigned Opcode, Type *Ty, bool IsPairwiseForm) const;
- /// \returns The cost of Intrinsic instructions. Types analysis only.
+ /// \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<Type *> Tys, FastMathFlags FMF) const;
+ ArrayRef<Value *> Args, FastMathFlags FMF,
+ unsigned VF = 1) const;
- /// \returns The cost of Intrinsic instructions. Analyses the real arguments.
+ /// \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<Value *> Args, FastMathFlags FMF) const;
+ ArrayRef<Type *> Tys, FastMathFlags FMF,
+ unsigned ScalarizationCostPassed = UINT_MAX) const;
/// \returns The cost of Call instructions.
int getCallInstrCost(Function *F, Type *RetTy, ArrayRef<Type *> Tys) const;
@@ -643,6 +749,10 @@ public:
/// if false is returned.
bool getTgtMemIntrinsic(IntrinsicInst *Inst, MemIntrinsicInfo &Info) const;
+ /// \returns The maximum element size, in bytes, for an element
+ /// unordered-atomic memory intrinsic.
+ unsigned getAtomicMemIntrinsicMaxElementSize() const;
+
/// \returns A value which is the result of the given memory intrinsic. New
/// instructions may be created to extract the result from the given intrinsic
/// memory operation. Returns nullptr if the target cannot create a result
@@ -650,6 +760,28 @@ public:
Value *getOrCreateResultFromMemIntrinsic(IntrinsicInst *Inst,
Type *ExpectedType) const;
+ /// \returns The type to use in a loop expansion of a memcpy call.
+ Type *getMemcpyLoopLoweringType(LLVMContext &Context, Value *Length,
+ unsigned SrcAlign, unsigned DestAlign) const;
+
+ /// \param[out] OpsOut The operand types to copy RemainingBytes of memory.
+ /// \param RemainingBytes The number of bytes to copy.
+ ///
+ /// 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;
+
+ /// \returns True if we want to test the new memcpy lowering functionality in
+ /// Transform/Utils.
+ /// Temporary. Will be removed once we move to the new functionality and
+ /// remove the old.
+ bool useWideIRMemcpyLoopLowering() const;
+
/// \returns True if the two functions have compatible attributes for inlining
/// purposes.
bool areInlineCompatible(const Function *Caller,
@@ -687,6 +819,22 @@ public:
unsigned ChainSizeInBytes,
VectorType *VecTy) const;
+ /// Flags describing the kind of vector reduction.
+ struct ReductionFlags {
+ ReductionFlags() : IsMaxOp(false), IsSigned(false), NoNaN(false) {}
+ bool IsMaxOp; ///< If the op a min/max kind, true if it's a max operation.
+ bool IsSigned; ///< Whether the operation is a signed int reduction.
+ bool NoNaN; ///< If op is an fp min/max, whether NaNs may be present.
+ };
+
+ /// \returns True if the target wants to handle the given reduction idiom in
+ /// the intrinsics form instead of the shuffle form.
+ bool useReductionIntrinsic(unsigned Opcode, Type *Ty,
+ ReductionFlags Flags) const;
+
+ /// \returns True if the target wants to expand the given reduction intrinsic
+ /// into a shuffle sequence.
+ bool shouldExpandReduction(const IntrinsicInst *II) const;
/// @}
private:
@@ -708,6 +856,7 @@ public:
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) = 0;
virtual int getCallCost(const Function *F, int NumArgs) = 0;
virtual int getCallCost(const Function *F,
@@ -717,21 +866,30 @@ public:
ArrayRef<Type *> ParamTys) = 0;
virtual int getIntrinsicCost(Intrinsic::ID IID, Type *RetTy,
ArrayRef<const Value *> Arguments) = 0;
- virtual int getUserCost(const User *U) = 0;
+ virtual unsigned getEstimatedNumberOfCaseClusters(const SwitchInst &SI,
+ unsigned &JTSize) = 0;
+ virtual int
+ getUserCost(const User *U, ArrayRef<const Value *> Operands) = 0;
virtual bool hasBranchDivergence() = 0;
virtual bool isSourceOfDivergence(const Value *V) = 0;
+ virtual bool isAlwaysUniform(const Value *V) = 0;
+ virtual unsigned getFlatAddressSpace() = 0;
virtual bool isLoweredToCall(const Function *F) = 0;
- virtual void getUnrollingPreferences(Loop *L, UnrollingPreferences &UP) = 0;
+ virtual void getUnrollingPreferences(Loop *L, ScalarEvolution &,
+ UnrollingPreferences &UP) = 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) = 0;
+ virtual bool isLSRCostLess(TargetTransformInfo::LSRCost &C1,
+ TargetTransformInfo::LSRCost &C2) = 0;
virtual bool isLegalMaskedStore(Type *DataType) = 0;
virtual bool isLegalMaskedLoad(Type *DataType) = 0;
virtual bool isLegalMaskedScatter(Type *DataType) = 0;
virtual bool isLegalMaskedGather(Type *DataType) = 0;
+ virtual bool prefersVectorizedAddressing() = 0;
virtual int getScalingFactorCost(Type *Ty, GlobalValue *BaseGV,
int64_t BaseOffset, bool HasBaseReg,
int64_t Scale, unsigned AddrSpace) = 0;
@@ -743,7 +901,13 @@ public:
virtual unsigned getJumpBufSize() = 0;
virtual bool shouldBuildLookupTables() = 0;
virtual bool shouldBuildLookupTablesForConstant(Constant *C) = 0;
+ virtual unsigned
+ getScalarizationOverhead(Type *Ty, bool Insert, bool Extract) = 0;
+ virtual unsigned getOperandsScalarizationOverhead(ArrayRef<const Value *> Args,
+ unsigned VF) = 0;
+ virtual bool supportsEfficientVectorElementLoadStore() = 0;
virtual bool enableAggressiveInterleaving(bool LoopHasReductions) = 0;
+ virtual bool expandMemCmp(Instruction *I, unsigned &MaxLoadSize) = 0;
virtual bool enableInterleavedAccessVectorization() = 0;
virtual bool isFPVectorizationPotentiallyUnsafe() = 0;
virtual bool allowsMisalignedMemoryAccesses(LLVMContext &Context,
@@ -762,7 +926,10 @@ public:
virtual int getIntImmCost(Intrinsic::ID IID, unsigned Idx, const APInt &Imm,
Type *Ty) = 0;
virtual unsigned getNumberOfRegisters(bool Vector) = 0;
- virtual unsigned getRegisterBitWidth(bool Vector) = 0;
+ virtual unsigned getRegisterBitWidth(bool Vector) const = 0;
+ virtual unsigned getMinVectorRegisterBitWidth() = 0;
+ virtual bool shouldConsiderAddressTypePromotion(
+ const Instruction &I, bool &AllowPromotionWithoutCommonHeader) = 0;
virtual unsigned getCacheLineSize() = 0;
virtual unsigned getPrefetchDistance() = 0;
virtual unsigned getMinPrefetchStride() = 0;
@@ -776,16 +943,17 @@ public:
ArrayRef<const Value *> Args) = 0;
virtual int getShuffleCost(ShuffleKind Kind, Type *Tp, int Index,
Type *SubTp) = 0;
- virtual int getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src) = 0;
+ virtual int getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src,
+ 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) = 0;
+ Type *CondTy, const Instruction *I) = 0;
virtual int getVectorInstrCost(unsigned Opcode, Type *Val,
unsigned Index) = 0;
virtual int getMemoryOpCost(unsigned Opcode, Type *Src, unsigned Alignment,
- unsigned AddressSpace) = 0;
+ unsigned AddressSpace, const Instruction *I) = 0;
virtual int getMaskedMemoryOpCost(unsigned Opcode, Type *Src,
unsigned Alignment,
unsigned AddressSpace) = 0;
@@ -800,11 +968,10 @@ public:
virtual int getReductionCost(unsigned Opcode, Type *Ty,
bool IsPairwiseForm) = 0;
virtual int getIntrinsicInstrCost(Intrinsic::ID ID, Type *RetTy,
- ArrayRef<Type *> Tys,
- FastMathFlags FMF) = 0;
+ ArrayRef<Type *> Tys, FastMathFlags FMF,
+ unsigned ScalarizationCostPassed) = 0;
virtual int getIntrinsicInstrCost(Intrinsic::ID ID, Type *RetTy,
- ArrayRef<Value *> Args,
- FastMathFlags FMF) = 0;
+ ArrayRef<Value *> Args, FastMathFlags FMF, unsigned VF) = 0;
virtual int getCallInstrCost(Function *F, Type *RetTy,
ArrayRef<Type *> Tys) = 0;
virtual unsigned getNumberOfParts(Type *Tp) = 0;
@@ -813,8 +980,15 @@ public:
virtual unsigned getCostOfKeepingLiveOverCall(ArrayRef<Type *> Tys) = 0;
virtual bool getTgtMemIntrinsic(IntrinsicInst *Inst,
MemIntrinsicInfo &Info) = 0;
+ virtual unsigned getAtomicMemIntrinsicMaxElementSize() const = 0;
virtual Value *getOrCreateResultFromMemIntrinsic(IntrinsicInst *Inst,
Type *ExpectedType) = 0;
+ virtual Type *getMemcpyLoopLoweringType(LLVMContext &Context, Value *Length,
+ unsigned SrcAlign,
+ unsigned DestAlign) const = 0;
+ virtual void getMemcpyLoopResidualLoweringType(
+ SmallVectorImpl<Type *> &OpsOut, LLVMContext &Context,
+ unsigned RemainingBytes, unsigned SrcAlign, unsigned DestAlign) const = 0;
virtual bool areInlineCompatible(const Function *Caller,
const Function *Callee) const = 0;
virtual unsigned getLoadStoreVecRegBitWidth(unsigned AddrSpace) const = 0;
@@ -832,6 +1006,9 @@ public:
virtual unsigned getStoreVectorFactor(unsigned VF, unsigned StoreSize,
unsigned ChainSizeInBytes,
VectorType *VecTy) const = 0;
+ virtual bool useReductionIntrinsic(unsigned Opcode, Type *Ty,
+ ReductionFlags) const = 0;
+ virtual bool shouldExpandReduction(const IntrinsicInst *II) const = 0;
};
template <typename T>
@@ -853,6 +1030,9 @@ public:
ArrayRef<const Value *> Operands) 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) override {
return Impl.getCallCost(FTy, NumArgs);
}
@@ -874,16 +1054,28 @@ public:
ArrayRef<const Value *> Arguments) override {
return Impl.getIntrinsicCost(IID, RetTy, Arguments);
}
- int getUserCost(const User *U) override { return Impl.getUserCost(U); }
+ int getUserCost(const User *U, ArrayRef<const Value *> Operands) override {
+ return Impl.getUserCost(U, Operands);
+ }
bool hasBranchDivergence() override { return Impl.hasBranchDivergence(); }
bool isSourceOfDivergence(const Value *V) override {
return Impl.isSourceOfDivergence(V);
}
+
+ bool isAlwaysUniform(const Value *V) override {
+ return Impl.isAlwaysUniform(V);
+ }
+
+ unsigned getFlatAddressSpace() override {
+ return Impl.getFlatAddressSpace();
+ }
+
bool isLoweredToCall(const Function *F) override {
return Impl.isLoweredToCall(F);
}
- void getUnrollingPreferences(Loop *L, UnrollingPreferences &UP) override {
- return Impl.getUnrollingPreferences(L, UP);
+ void getUnrollingPreferences(Loop *L, ScalarEvolution &SE,
+ UnrollingPreferences &UP) override {
+ return Impl.getUnrollingPreferences(L, SE, UP);
}
bool isLegalAddImmediate(int64_t Imm) override {
return Impl.isLegalAddImmediate(Imm);
@@ -897,6 +1089,10 @@ public:
return Impl.isLegalAddressingMode(Ty, BaseGV, BaseOffset, HasBaseReg,
Scale, AddrSpace);
}
+ bool isLSRCostLess(TargetTransformInfo::LSRCost &C1,
+ TargetTransformInfo::LSRCost &C2) override {
+ return Impl.isLSRCostLess(C1, C2);
+ }
bool isLegalMaskedStore(Type *DataType) override {
return Impl.isLegalMaskedStore(DataType);
}
@@ -909,6 +1105,9 @@ public:
bool isLegalMaskedGather(Type *DataType) override {
return Impl.isLegalMaskedGather(DataType);
}
+ bool prefersVectorizedAddressing() override {
+ return Impl.prefersVectorizedAddressing();
+ }
int getScalingFactorCost(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset,
bool HasBaseReg, int64_t Scale,
unsigned AddrSpace) override {
@@ -933,9 +1132,25 @@ public:
bool shouldBuildLookupTablesForConstant(Constant *C) override {
return Impl.shouldBuildLookupTablesForConstant(C);
}
+ unsigned getScalarizationOverhead(Type *Ty, bool Insert,
+ bool Extract) override {
+ return Impl.getScalarizationOverhead(Ty, Insert, Extract);
+ }
+ unsigned getOperandsScalarizationOverhead(ArrayRef<const Value *> Args,
+ unsigned VF) override {
+ return Impl.getOperandsScalarizationOverhead(Args, VF);
+ }
+
+ bool supportsEfficientVectorElementLoadStore() override {
+ return Impl.supportsEfficientVectorElementLoadStore();
+ }
+
bool enableAggressiveInterleaving(bool LoopHasReductions) override {
return Impl.enableAggressiveInterleaving(LoopHasReductions);
}
+ bool expandMemCmp(Instruction *I, unsigned &MaxLoadSize) override {
+ return Impl.expandMemCmp(I, MaxLoadSize);
+ }
bool enableInterleavedAccessVectorization() override {
return Impl.enableInterleavedAccessVectorization();
}
@@ -973,10 +1188,17 @@ public:
unsigned getNumberOfRegisters(bool Vector) override {
return Impl.getNumberOfRegisters(Vector);
}
- unsigned getRegisterBitWidth(bool Vector) override {
+ unsigned getRegisterBitWidth(bool Vector) const override {
return Impl.getRegisterBitWidth(Vector);
}
-
+ unsigned getMinVectorRegisterBitWidth() override {
+ return Impl.getMinVectorRegisterBitWidth();
+ }
+ bool shouldConsiderAddressTypePromotion(
+ const Instruction &I, bool &AllowPromotionWithoutCommonHeader) override {
+ return Impl.shouldConsiderAddressTypePromotion(
+ I, AllowPromotionWithoutCommonHeader);
+ }
unsigned getCacheLineSize() override {
return Impl.getCacheLineSize();
}
@@ -990,6 +1212,10 @@ public:
unsigned getMaxInterleaveFactor(unsigned VF) override {
return Impl.getMaxInterleaveFactor(VF);
}
+ unsigned getEstimatedNumberOfCaseClusters(const SwitchInst &SI,
+ unsigned &JTSize) override {
+ return Impl.getEstimatedNumberOfCaseClusters(SI, JTSize);
+ }
unsigned
getArithmeticInstrCost(unsigned Opcode, Type *Ty, OperandValueKind Opd1Info,
OperandValueKind Opd2Info,
@@ -1003,8 +1229,9 @@ public:
Type *SubTp) override {
return Impl.getShuffleCost(Kind, Tp, Index, SubTp);
}
- int getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src) override {
- return Impl.getCastInstrCost(Opcode, Dst, Src);
+ int getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src,
+ const Instruction *I) override {
+ return Impl.getCastInstrCost(Opcode, Dst, Src, I);
}
int getExtractWithExtendCost(unsigned Opcode, Type *Dst, VectorType *VecTy,
unsigned Index) override {
@@ -1013,15 +1240,16 @@ public:
int getCFInstrCost(unsigned Opcode) override {
return Impl.getCFInstrCost(Opcode);
}
- int getCmpSelInstrCost(unsigned Opcode, Type *ValTy, Type *CondTy) override {
- return Impl.getCmpSelInstrCost(Opcode, ValTy, CondTy);
+ int getCmpSelInstrCost(unsigned Opcode, Type *ValTy, Type *CondTy,
+ const Instruction *I) override {
+ return Impl.getCmpSelInstrCost(Opcode, ValTy, CondTy, I);
}
int getVectorInstrCost(unsigned Opcode, Type *Val, unsigned Index) override {
return Impl.getVectorInstrCost(Opcode, Val, Index);
}
int getMemoryOpCost(unsigned Opcode, Type *Src, unsigned Alignment,
- unsigned AddressSpace) override {
- return Impl.getMemoryOpCost(Opcode, Src, Alignment, AddressSpace);
+ 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 {
@@ -1044,13 +1272,13 @@ public:
return Impl.getReductionCost(Opcode, Ty, IsPairwiseForm);
}
int getIntrinsicInstrCost(Intrinsic::ID ID, Type *RetTy, ArrayRef<Type *> Tys,
- FastMathFlags FMF) override {
- return Impl.getIntrinsicInstrCost(ID, RetTy, Tys, FMF);
+ FastMathFlags FMF, unsigned ScalarizationCostPassed) override {
+ return Impl.getIntrinsicInstrCost(ID, RetTy, Tys, FMF,
+ ScalarizationCostPassed);
}
int getIntrinsicInstrCost(Intrinsic::ID ID, Type *RetTy,
- ArrayRef<Value *> Args,
- FastMathFlags FMF) override {
- return Impl.getIntrinsicInstrCost(ID, RetTy, Args, FMF);
+ ArrayRef<Value *> Args, FastMathFlags FMF, unsigned VF) override {
+ return Impl.getIntrinsicInstrCost(ID, RetTy, Args, FMF, VF);
}
int getCallInstrCost(Function *F, Type *RetTy,
ArrayRef<Type *> Tys) override {
@@ -1070,10 +1298,26 @@ public:
MemIntrinsicInfo &Info) override {
return Impl.getTgtMemIntrinsic(Inst, Info);
}
+ unsigned getAtomicMemIntrinsicMaxElementSize() const override {
+ return Impl.getAtomicMemIntrinsicMaxElementSize();
+ }
Value *getOrCreateResultFromMemIntrinsic(IntrinsicInst *Inst,
Type *ExpectedType) override {
return Impl.getOrCreateResultFromMemIntrinsic(Inst, ExpectedType);
}
+ Type *getMemcpyLoopLoweringType(LLVMContext &Context, Value *Length,
+ unsigned SrcAlign,
+ unsigned DestAlign) const override {
+ return Impl.getMemcpyLoopLoweringType(Context, Length, SrcAlign, DestAlign);
+ }
+ void getMemcpyLoopResidualLoweringType(SmallVectorImpl<Type *> &OpsOut,
+ LLVMContext &Context,
+ unsigned RemainingBytes,
+ unsigned SrcAlign,
+ unsigned DestAlign) const override {
+ Impl.getMemcpyLoopResidualLoweringType(OpsOut, Context, RemainingBytes,
+ SrcAlign, DestAlign);
+ }
bool areInlineCompatible(const Function *Caller,
const Function *Callee) const override {
return Impl.areInlineCompatible(Caller, Callee);
@@ -1109,6 +1353,13 @@ public:
VectorType *VecTy) const override {
return Impl.getStoreVectorFactor(VF, StoreSize, ChainSizeInBytes, VecTy);
}
+ bool useReductionIntrinsic(unsigned Opcode, Type *Ty,
+ ReductionFlags Flags) const override {
+ return Impl.useReductionIntrinsic(Opcode, Ty, Flags);
+ }
+ bool shouldExpandReduction(const IntrinsicInst *II) const override {
+ return Impl.shouldExpandReduction(II);
+ }
};
template <typename T>
diff --git a/contrib/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h b/contrib/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h
index cafc407..0b07fe9 100644
--- a/contrib/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h
+++ b/contrib/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h
@@ -17,13 +17,13 @@
#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/Operator.h"
#include "llvm/IR/Type.h"
-#include "llvm/Analysis/VectorUtils.h"
namespace llvm {
@@ -114,6 +114,16 @@ public:
return TTI::TCC_Free;
}
+ unsigned getEstimatedNumberOfCaseClusters(const SwitchInst &SI,
+ unsigned &JTSize) {
+ JTSize = 0;
+ return SI.getNumCases();
+ }
+
+ int getExtCost(const Instruction *I, const Value *Src) {
+ return TTI::TCC_Basic;
+ }
+
unsigned getCallCost(FunctionType *FTy, int NumArgs) {
assert(FTy && "FunctionType must be provided to this routine.");
@@ -171,6 +181,12 @@ public:
bool isSourceOfDivergence(const Value *V) { return false; }
+ bool isAlwaysUniform(const Value *V) { return false; }
+
+ unsigned getFlatAddressSpace () {
+ return -1;
+ }
+
bool isLoweredToCall(const Function *F) {
// FIXME: These should almost certainly not be handled here, and instead
// handled with the help of TLI or the target itself. This was largely
@@ -205,7 +221,8 @@ public:
return true;
}
- void getUnrollingPreferences(Loop *, TTI::UnrollingPreferences &) {}
+ void getUnrollingPreferences(Loop *, ScalarEvolution &,
+ TTI::UnrollingPreferences &) {}
bool isLegalAddImmediate(int64_t Imm) { return false; }
@@ -219,6 +236,13 @@ public:
return !BaseGV && BaseOffset == 0 && (Scale == 0 || Scale == 1);
}
+ bool isLSRCostLess(TTI::LSRCost &C1, TTI::LSRCost &C2) {
+ return std::tie(C1.NumRegs, C1.AddRecCost, C1.NumIVMuls, C1.NumBaseAdds,
+ C1.ScaleCost, C1.ImmCost, C1.SetupCost) <
+ std::tie(C2.NumRegs, C2.AddRecCost, C2.NumIVMuls, C2.NumBaseAdds,
+ C2.ScaleCost, C2.ImmCost, C2.SetupCost);
+ }
+
bool isLegalMaskedStore(Type *DataType) { return false; }
bool isLegalMaskedLoad(Type *DataType) { return false; }
@@ -227,6 +251,8 @@ public:
bool isLegalMaskedGather(Type *DataType) { return false; }
+ bool prefersVectorizedAddressing() { return true; }
+
int getScalingFactorCost(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset,
bool HasBaseReg, int64_t Scale, unsigned AddrSpace) {
// Guess that all legal addressing mode are free.
@@ -251,8 +277,19 @@ public:
bool shouldBuildLookupTables() { return true; }
bool shouldBuildLookupTablesForConstant(Constant *C) { return true; }
+ unsigned getScalarizationOverhead(Type *Ty, bool Insert, bool Extract) {
+ return 0;
+ }
+
+ unsigned getOperandsScalarizationOverhead(ArrayRef<const Value *> Args,
+ unsigned VF) { return 0; }
+
+ bool supportsEfficientVectorElementLoadStore() { return false; }
+
bool enableAggressiveInterleaving(bool LoopHasReductions) { return false; }
+ bool expandMemCmp(Instruction *I, unsigned &MaxLoadSize) { return false; }
+
bool enableInterleavedAccessVectorization() { return false; }
bool isFPVectorizationPotentiallyUnsafe() { return false; }
@@ -290,7 +327,16 @@ public:
unsigned getNumberOfRegisters(bool Vector) { return 8; }
- unsigned getRegisterBitWidth(bool Vector) { return 32; }
+ unsigned getRegisterBitWidth(bool Vector) const { return 32; }
+
+ unsigned getMinVectorRegisterBitWidth() { return 128; }
+
+ bool
+ shouldConsiderAddressTypePromotion(const Instruction &I,
+ bool &AllowPromotionWithoutCommonHeader) {
+ AllowPromotionWithoutCommonHeader = false;
+ return false;
+ }
unsigned getCacheLineSize() { return 0; }
@@ -316,7 +362,8 @@ public:
return 1;
}
- unsigned getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src) { return 1; }
+ unsigned getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src,
+ const Instruction *I) { return 1; }
unsigned getExtractWithExtendCost(unsigned Opcode, Type *Dst,
VectorType *VecTy, unsigned Index) {
@@ -325,7 +372,8 @@ public:
unsigned getCFInstrCost(unsigned Opcode) { return 1; }
- unsigned getCmpSelInstrCost(unsigned Opcode, Type *ValTy, Type *CondTy) {
+ unsigned getCmpSelInstrCost(unsigned Opcode, Type *ValTy, Type *CondTy,
+ const Instruction *I) {
return 1;
}
@@ -334,7 +382,7 @@ public:
}
unsigned getMemoryOpCost(unsigned Opcode, Type *Src, unsigned Alignment,
- unsigned AddressSpace) {
+ unsigned AddressSpace, const Instruction *I) {
return 1;
}
@@ -358,11 +406,12 @@ public:
}
unsigned getIntrinsicInstrCost(Intrinsic::ID ID, Type *RetTy,
- ArrayRef<Type *> Tys, FastMathFlags FMF) {
+ ArrayRef<Type *> Tys, FastMathFlags FMF,
+ unsigned ScalarizationCostPassed) {
return 1;
}
unsigned getIntrinsicInstrCost(Intrinsic::ID ID, Type *RetTy,
- ArrayRef<Value *> Args, FastMathFlags FMF) {
+ ArrayRef<Value *> Args, FastMathFlags FMF, unsigned VF) {
return 1;
}
@@ -385,11 +434,34 @@ public:
return false;
}
+ unsigned getAtomicMemIntrinsicMaxElementSize() const {
+ // Note for overrides: You must ensure for all element unordered-atomic
+ // memory intrinsics that all power-of-2 element sizes up to, and
+ // including, the return value of this method have a corresponding
+ // runtime lib call. These runtime lib call definitions can be found
+ // in RuntimeLibcalls.h
+ return 0;
+ }
+
Value *getOrCreateResultFromMemIntrinsic(IntrinsicInst *Inst,
Type *ExpectedType) {
return nullptr;
}
+ Type *getMemcpyLoopLoweringType(LLVMContext &Context, Value *Length,
+ unsigned SrcAlign, unsigned DestAlign) const {
+ return Type::getInt8Ty(Context);
+ }
+
+ void getMemcpyLoopResidualLoweringType(SmallVectorImpl<Type *> &OpsOut,
+ LLVMContext &Context,
+ unsigned RemainingBytes,
+ unsigned SrcAlign,
+ unsigned DestAlign) const {
+ for (unsigned i = 0; i != RemainingBytes; ++i)
+ OpsOut.push_back(Type::getInt8Ty(Context));
+ }
+
bool areInlineCompatible(const Function *Caller,
const Function *Callee) const {
return (Caller->getFnAttribute("target-cpu") ==
@@ -427,6 +499,16 @@ public:
VectorType *VecTy) const {
return VF;
}
+
+ bool useReductionIntrinsic(unsigned Opcode, Type *Ty,
+ TTI::ReductionFlags Flags) const {
+ return false;
+ }
+
+ bool shouldExpandReduction(const IntrinsicInst *II) const {
+ return true;
+ }
+
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.
@@ -621,14 +703,14 @@ public:
return static_cast<T *>(this)->getIntrinsicCost(IID, RetTy, ParamTys);
}
- unsigned getUserCost(const User *U) {
+ unsigned getUserCost(const User *U, ArrayRef<const Value *> Operands) {
if (isa<PHINode>(U))
return TTI::TCC_Free; // Model all PHI nodes as free.
if (const GEPOperator *GEP = dyn_cast<GEPOperator>(U)) {
- SmallVector<Value *, 4> Indices(GEP->idx_begin(), GEP->idx_end());
- return static_cast<T *>(this)->getGEPCost(
- GEP->getSourceElementType(), GEP->getPointerOperand(), Indices);
+ return static_cast<T *>(this)->getGEPCost(GEP->getSourceElementType(),
+ GEP->getPointerOperand(),
+ Operands.drop_front());
}
if (auto CS = ImmutableCallSite(U)) {
@@ -650,6 +732,8 @@ public:
// nop on most sane targets.
if (isa<CmpInst>(CI->getOperand(0)))
return TTI::TCC_Free;
+ if (isa<SExtInst>(CI) || isa<ZExtInst>(CI) || isa<FPExtInst>(CI))
+ return static_cast<T *>(this)->getExtCost(CI, Operands.back());
}
return static_cast<T *>(this)->getOperationCost(
diff --git a/contrib/llvm/include/llvm/Analysis/TypeMetadataUtils.h b/contrib/llvm/include/llvm/Analysis/TypeMetadataUtils.h
index c3f688f..422e153 100644
--- a/contrib/llvm/include/llvm/Analysis/TypeMetadataUtils.h
+++ b/contrib/llvm/include/llvm/Analysis/TypeMetadataUtils.h
@@ -20,6 +20,13 @@
namespace llvm {
+/// The type of CFI jumptable needed for a function.
+enum CfiFunctionLinkage {
+ CFL_Definition = 0,
+ CFL_Declaration = 1,
+ CFL_WeakDeclaration = 2
+};
+
/// A call site that could be devirtualized.
struct DevirtCallSite {
/// The offset from the address point to the virtual function.
@@ -32,14 +39,15 @@ struct DevirtCallSite {
/// call sites based on the call and return them in DevirtCalls.
void findDevirtualizableCallsForTypeTest(
SmallVectorImpl<DevirtCallSite> &DevirtCalls,
- SmallVectorImpl<CallInst *> &Assumes, CallInst *CI);
+ SmallVectorImpl<CallInst *> &Assumes, const CallInst *CI);
/// Given a call to the intrinsic @llvm.type.checked.load, find all
/// devirtualizable call sites based on the call and return them in DevirtCalls.
void findDevirtualizableCallsForTypeCheckedLoad(
SmallVectorImpl<DevirtCallSite> &DevirtCalls,
SmallVectorImpl<Instruction *> &LoadedPtrs,
- SmallVectorImpl<Instruction *> &Preds, bool &HasNonCallUses, CallInst *CI);
+ SmallVectorImpl<Instruction *> &Preds, bool &HasNonCallUses,
+ const CallInst *CI);
}
#endif
diff --git a/contrib/llvm/include/llvm/Analysis/ValueTracking.h b/contrib/llvm/include/llvm/Analysis/ValueTracking.h
index aaf6f88..da058b1 100644
--- a/contrib/llvm/include/llvm/Analysis/ValueTracking.h
+++ b/contrib/llvm/include/llvm/Analysis/ValueTracking.h
@@ -29,8 +29,10 @@ template <typename T> class ArrayRef;
class DominatorTree;
class GEPOperator;
class Instruction;
+ struct KnownBits;
class Loop;
class LoopInfo;
+ class OptimizationRemarkEmitter;
class MDNode;
class StringRef;
class TargetLibraryInfo;
@@ -48,16 +50,23 @@ template <typename T> class ArrayRef;
/// 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 elements in the vector.
- void computeKnownBits(const Value *V, APInt &KnownZero, APInt &KnownOne,
+ void computeKnownBits(const Value *V, KnownBits &Known,
const DataLayout &DL, unsigned Depth = 0,
AssumptionCache *AC = nullptr,
const Instruction *CxtI = nullptr,
- const DominatorTree *DT = nullptr);
+ const DominatorTree *DT = nullptr,
+ OptimizationRemarkEmitter *ORE = nullptr);
+ /// Returns the known bits rather than passing by reference.
+ KnownBits computeKnownBits(const Value *V, const DataLayout &DL,
+ unsigned Depth = 0, AssumptionCache *AC = nullptr,
+ const Instruction *CxtI = nullptr,
+ const DominatorTree *DT = nullptr,
+ OptimizationRemarkEmitter *ORE = nullptr);
/// 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
void computeKnownBitsFromRangeMetadata(const MDNode &Ranges,
- APInt &KnownZero, APInt &KnownOne);
+ KnownBits &Known);
/// Return true if LHS and RHS have no common bits set.
bool haveNoCommonBitsSet(const Value *LHS, const Value *RHS,
const DataLayout &DL,
@@ -65,14 +74,6 @@ template <typename T> class ArrayRef;
const Instruction *CxtI = nullptr,
const DominatorTree *DT = nullptr);
- /// Determine whether the sign bit is known to be zero or one. Convenience
- /// wrapper around computeKnownBits.
- void ComputeSignBit(const Value *V, bool &KnownZero, bool &KnownOne,
- const DataLayout &DL, unsigned Depth = 0,
- AssumptionCache *AC = nullptr,
- const Instruction *CxtI = nullptr,
- const DominatorTree *DT = nullptr);
-
/// Return true if the given value is known to have exactly one bit set when
/// defined. For vectors return true if every element is known to be a power
/// of two when defined. Supports values with integer or pointer type and
@@ -84,10 +85,14 @@ template <typename T> class ArrayRef;
const Instruction *CxtI = nullptr,
const DominatorTree *DT = nullptr);
+ bool isOnlyUsedInZeroEqualityComparison(const Instruction *CxtI);
+
/// Return true if the given value is known to be non-zero when defined. For
/// vectors, return true if every element is known to be non-zero when
- /// defined. Supports values with integer or pointer type and vectors of
- /// integers.
+ /// defined. For pointers, if the context instruction and dominator tree are
+ /// specified, perform context-sensitive analysis and return true if the
+ /// pointer couldn't possibly be null at the specified instruction.
+ /// Supports values with integer or pointer type and vectors of integers.
bool isKnownNonZero(const Value *V, const DataLayout &DL, unsigned Depth = 0,
AssumptionCache *AC = nullptr,
const Instruction *CxtI = nullptr,
@@ -167,13 +172,25 @@ template <typename T> class ArrayRef;
bool CannotBeNegativeZero(const Value *V, const TargetLibraryInfo *TLI,
unsigned Depth = 0);
- /// Return true if we can prove that the specified FP value is either a NaN or
- /// never less than 0.0.
- /// If \p IncludeNeg0 is false, -0.0 is considered less than 0.0.
+ /// Return true if we can prove that the specified FP value is either NaN or
+ /// never less than -0.0.
+ ///
+ /// NaN --> true
+ /// +0 --> true
+ /// -0 --> true
+ /// x > +0 --> true
+ /// x < -0 --> false
+ ///
bool CannotBeOrderedLessThanZero(const Value *V, const TargetLibraryInfo *TLI);
- /// \returns true if we can prove that the specified FP value has a 0 sign
- /// bit.
+ /// Return true if we can prove that the specified FP value's sign bit is 0.
+ ///
+ /// NaN --> true/false (depending on the NaN's sign bit)
+ /// +0 --> true
+ /// -0 --> false
+ /// x > +0 --> true
+ /// x < -0 --> false
+ ///
bool SignBitMustBeZero(const Value *V, const TargetLibraryInfo *TLI);
/// If the specified value can be set by repeating the same byte in memory,
@@ -204,9 +221,38 @@ template <typename T> class ArrayRef;
DL);
}
- /// Returns true if the GEP is based on a pointer to a string (array of i8),
- /// and is indexing into this string.
- bool isGEPBasedOnPointerToString(const GEPOperator *GEP);
+ /// Returns true if the GEP is based on a pointer to a string (array of
+ // \p CharSize integers) and is indexing into this string.
+ bool isGEPBasedOnPointerToString(const GEPOperator *GEP,
+ unsigned CharSize = 8);
+
+ /// Represents offset+length into a ConstantDataArray.
+ struct ConstantDataArraySlice {
+ /// ConstantDataArray pointer. nullptr indicates a zeroinitializer (a valid
+ /// initializer, it just doesn't fit the ConstantDataArray interface).
+ const ConstantDataArray *Array;
+ /// Slice starts at this Offset.
+ uint64_t Offset;
+ /// Length of the slice.
+ uint64_t Length;
+
+ /// Moves the Offset and adjusts Length accordingly.
+ void move(uint64_t Delta) {
+ assert(Delta < Length);
+ Offset += Delta;
+ Length -= Delta;
+ }
+ /// Convenience accessor for elements in the slice.
+ uint64_t operator[](unsigned I) const {
+ return Array==nullptr ? 0 : Array->getElementAsInteger(I + Offset);
+ }
+ };
+
+ /// Returns true if the value \p V is a pointer into a ContantDataArray.
+ /// If successful \p Index will point to a ConstantDataArray info object
+ /// with an appropriate offset.
+ bool getConstantDataArrayInfo(const Value *V, ConstantDataArraySlice &Slice,
+ unsigned ElementSize, uint64_t Offset = 0);
/// This function computes the length of a null-terminated C string pointed to
/// by V. If successful, it returns true and returns the string in Str. If
@@ -219,7 +265,7 @@ template <typename T> class ArrayRef;
/// If we can compute the length of the string pointed to by the specified
/// pointer, return 'len+1'. If we can't, return 0.
- uint64_t GetStringLength(const Value *V);
+ uint64_t GetStringLength(const Value *V, unsigned CharSize = 8);
/// This method strips off any GEP address adjustments and pointer casts from
/// the specified value, returning the original object being addressed. Note
@@ -266,6 +312,12 @@ template <typename T> class ArrayRef;
const DataLayout &DL, LoopInfo *LI = nullptr,
unsigned MaxLookup = 6);
+ /// This is a wrapper around GetUnderlyingObjects and adds support for basic
+ /// ptrtoint+arithmetic+inttoptr sequences.
+ void getUnderlyingObjectsForCodeGen(const Value *V,
+ SmallVectorImpl<Value *> &Objects,
+ const DataLayout &DL);
+
/// Return true if the only users of this pointer are lifetime markers.
bool onlyUsedByLifetimeMarkers(const Value *V);
@@ -400,7 +452,7 @@ template <typename T> class ArrayRef;
///
/// Note that this currently only considers the basic block that is
/// the parent of I.
- bool isKnownNotFullPoison(const Instruction *PoisonI);
+ bool programUndefinedIfFullPoison(const Instruction *PoisonI);
/// \brief Specific patterns of select instructions we can match.
enum SelectPatternFlavor {
@@ -477,8 +529,7 @@ template <typename T> class ArrayRef;
/// (A)
Optional<bool> isImpliedCondition(const Value *LHS, const Value *RHS,
const DataLayout &DL,
- bool InvertAPred = false,
- unsigned Depth = 0,
+ bool LHSIsFalse = false, unsigned Depth = 0,
AssumptionCache *AC = nullptr,
const Instruction *CxtI = nullptr,
const DominatorTree *DT = nullptr);
diff --git a/contrib/llvm/include/llvm/Analysis/VectorUtils.h b/contrib/llvm/include/llvm/Analysis/VectorUtils.h
index eaa068b..6315e84 100644
--- a/contrib/llvm/include/llvm/Analysis/VectorUtils.h
+++ b/contrib/llvm/include/llvm/Analysis/VectorUtils.h
@@ -1,4 +1,4 @@
-//===- llvm/Transforms/Utils/VectorUtils.h - Vector utilities -*- C++ -*-=====//
+//===- llvm/Analysis/VectorUtils.h - Vector utilities -----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -11,11 +11,12 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_TRANSFORMS_UTILS_VECTORUTILS_H
-#define LLVM_TRANSFORMS_UTILS_VECTORUTILS_H
+#ifndef LLVM_ANALYSIS_VECTORUTILS_H
+#define LLVM_ANALYSIS_VECTORUTILS_H
#include "llvm/ADT/MapVector.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
+#include "llvm/IR/IRBuilder.h"
namespace llvm {
@@ -123,6 +124,58 @@ computeMinimumValueSizes(ArrayRef<BasicBlock*> Blocks,
/// This function always sets a (possibly null) value for each K in Kinds.
Instruction *propagateMetadata(Instruction *I, ArrayRef<Value *> VL);
+/// \brief Create an interleave shuffle mask.
+///
+/// This function creates a shuffle mask for interleaving \p NumVecs vectors of
+/// vectorization factor \p VF into a single wide vector. The mask is of the
+/// form:
+///
+/// <0, VF, VF * 2, ..., VF * (NumVecs - 1), 1, VF + 1, VF * 2 + 1, ...>
+///
+/// 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);
+
+/// \brief Create a stride shuffle mask.
+///
+/// This function creates a shuffle mask whose elements begin at \p Start and
+/// are incremented by \p Stride. The mask can be used to deinterleave an
+/// interleaved vector into separate vectors of vectorization factor \p VF. The
+/// mask is of the form:
+///
+/// <Start, Start + Stride, ..., Start + Stride * (VF - 1)>
+///
+/// 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);
+
+/// \brief Create a sequential shuffle mask.
+///
+/// This function creates shuffle mask whose elements are sequential and begin
+/// at \p Start. The mask contains \p NumInts integers and is padded with \p
+/// NumUndefs undef values. The mask is of the form:
+///
+/// <Start, Start + 1, ... Start + NumInts - 1, undef_1, ... undef_NumUndefs>
+///
+/// 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);
+
+/// \brief Concatenate a list of vectors.
+///
+/// This function generates code that concatenate the vectors in \p Vecs into a
+/// single large vector. The number of vectors should be greater than one, and
+/// 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);
+
} // llvm namespace
#endif
diff --git a/contrib/llvm/include/llvm/BinaryFormat/COFF.h b/contrib/llvm/include/llvm/BinaryFormat/COFF.h
new file mode 100644
index 0000000..b395db6
--- /dev/null
+++ b/contrib/llvm/include/llvm/BinaryFormat/COFF.h
@@ -0,0 +1,719 @@
+//===-- llvm/BinaryFormat/COFF.h --------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains an definitions used in Windows COFF Files.
+//
+// Structures and enums defined within this file where created using
+// information from Microsoft's publicly available PE/COFF format document:
+//
+// Microsoft Portable Executable and Common Object File Format Specification
+// Revision 8.1 - February 15, 2008
+//
+// As of 5/2/2010, hosted by Microsoft at:
+// http://www.microsoft.com/whdc/system/platform/firmware/pecoff.mspx
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_BINARYFORMAT_COFF_H
+#define LLVM_BINARYFORMAT_COFF_H
+
+#include "llvm/Support/DataTypes.h"
+#include <cassert>
+#include <cstring>
+
+namespace llvm {
+namespace COFF {
+
+// The maximum number of sections that a COFF object can have (inclusive).
+const int32_t MaxNumberOfSections16 = 65279;
+
+// The PE signature bytes that follows the DOS stub header.
+static const char PEMagic[] = {'P', 'E', '\0', '\0'};
+
+static const char BigObjMagic[] = {
+ '\xc7', '\xa1', '\xba', '\xd1', '\xee', '\xba', '\xa9', '\x4b',
+ '\xaf', '\x20', '\xfa', '\xf6', '\x6a', '\xa4', '\xdc', '\xb8',
+};
+
+static const char ClGlObjMagic[] = {
+ '\x38', '\xfe', '\xb3', '\x0c', '\xa5', '\xd9', '\xab', '\x4d',
+ '\xac', '\x9b', '\xd6', '\xb6', '\x22', '\x26', '\x53', '\xc2',
+};
+
+// The signature bytes that start a .res file.
+static const char WinResMagic[] = {
+ '\x00', '\x00', '\x00', '\x00', '\x20', '\x00', '\x00', '\x00',
+ '\xff', '\xff', '\x00', '\x00', '\xff', '\xff', '\x00', '\x00',
+};
+
+// Sizes in bytes of various things in the COFF format.
+enum {
+ Header16Size = 20,
+ Header32Size = 56,
+ NameSize = 8,
+ Symbol16Size = 18,
+ Symbol32Size = 20,
+ SectionSize = 40,
+ RelocationSize = 10
+};
+
+struct header {
+ uint16_t Machine;
+ int32_t NumberOfSections;
+ uint32_t TimeDateStamp;
+ uint32_t PointerToSymbolTable;
+ uint32_t NumberOfSymbols;
+ uint16_t SizeOfOptionalHeader;
+ uint16_t Characteristics;
+};
+
+struct BigObjHeader {
+ enum : uint16_t { MinBigObjectVersion = 2 };
+
+ uint16_t Sig1; ///< Must be IMAGE_FILE_MACHINE_UNKNOWN (0).
+ uint16_t Sig2; ///< Must be 0xFFFF.
+ uint16_t Version;
+ uint16_t Machine;
+ uint32_t TimeDateStamp;
+ uint8_t UUID[16];
+ uint32_t unused1;
+ uint32_t unused2;
+ uint32_t unused3;
+ uint32_t unused4;
+ uint32_t NumberOfSections;
+ uint32_t PointerToSymbolTable;
+ uint32_t NumberOfSymbols;
+};
+
+enum MachineTypes {
+ MT_Invalid = 0xffff,
+
+ IMAGE_FILE_MACHINE_UNKNOWN = 0x0,
+ IMAGE_FILE_MACHINE_AM33 = 0x13,
+ IMAGE_FILE_MACHINE_AMD64 = 0x8664,
+ IMAGE_FILE_MACHINE_ARM = 0x1C0,
+ IMAGE_FILE_MACHINE_ARMNT = 0x1C4,
+ IMAGE_FILE_MACHINE_ARM64 = 0xAA64,
+ IMAGE_FILE_MACHINE_EBC = 0xEBC,
+ IMAGE_FILE_MACHINE_I386 = 0x14C,
+ IMAGE_FILE_MACHINE_IA64 = 0x200,
+ IMAGE_FILE_MACHINE_M32R = 0x9041,
+ IMAGE_FILE_MACHINE_MIPS16 = 0x266,
+ IMAGE_FILE_MACHINE_MIPSFPU = 0x366,
+ IMAGE_FILE_MACHINE_MIPSFPU16 = 0x466,
+ IMAGE_FILE_MACHINE_POWERPC = 0x1F0,
+ IMAGE_FILE_MACHINE_POWERPCFP = 0x1F1,
+ IMAGE_FILE_MACHINE_R4000 = 0x166,
+ IMAGE_FILE_MACHINE_SH3 = 0x1A2,
+ IMAGE_FILE_MACHINE_SH3DSP = 0x1A3,
+ IMAGE_FILE_MACHINE_SH4 = 0x1A6,
+ IMAGE_FILE_MACHINE_SH5 = 0x1A8,
+ IMAGE_FILE_MACHINE_THUMB = 0x1C2,
+ IMAGE_FILE_MACHINE_WCEMIPSV2 = 0x169
+};
+
+enum Characteristics {
+ C_Invalid = 0,
+
+ /// The file does not contain base relocations and must be loaded at its
+ /// preferred base. If this cannot be done, the loader will error.
+ IMAGE_FILE_RELOCS_STRIPPED = 0x0001,
+ /// The file is valid and can be run.
+ IMAGE_FILE_EXECUTABLE_IMAGE = 0x0002,
+ /// COFF line numbers have been stripped. This is deprecated and should be
+ /// 0.
+ IMAGE_FILE_LINE_NUMS_STRIPPED = 0x0004,
+ /// COFF symbol table entries for local symbols have been removed. This is
+ /// deprecated and should be 0.
+ IMAGE_FILE_LOCAL_SYMS_STRIPPED = 0x0008,
+ /// Aggressively trim working set. This is deprecated and must be 0.
+ IMAGE_FILE_AGGRESSIVE_WS_TRIM = 0x0010,
+ /// Image can handle > 2GiB addresses.
+ IMAGE_FILE_LARGE_ADDRESS_AWARE = 0x0020,
+ /// Little endian: the LSB precedes the MSB in memory. This is deprecated
+ /// and should be 0.
+ IMAGE_FILE_BYTES_REVERSED_LO = 0x0080,
+ /// Machine is based on a 32bit word architecture.
+ IMAGE_FILE_32BIT_MACHINE = 0x0100,
+ /// Debugging info has been removed.
+ IMAGE_FILE_DEBUG_STRIPPED = 0x0200,
+ /// If the image is on removable media, fully load it and copy it to swap.
+ IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP = 0x0400,
+ /// If the image is on network media, fully load it and copy it to swap.
+ IMAGE_FILE_NET_RUN_FROM_SWAP = 0x0800,
+ /// The image file is a system file, not a user program.
+ IMAGE_FILE_SYSTEM = 0x1000,
+ /// The image file is a DLL.
+ IMAGE_FILE_DLL = 0x2000,
+ /// This file should only be run on a uniprocessor machine.
+ IMAGE_FILE_UP_SYSTEM_ONLY = 0x4000,
+ /// Big endian: the MSB precedes the LSB in memory. This is deprecated
+ /// and should be 0.
+ IMAGE_FILE_BYTES_REVERSED_HI = 0x8000
+};
+
+enum ResourceTypeID {
+ RID_Cursor = 1,
+ RID_Bitmap = 2,
+ RID_Icon = 3,
+ RID_Menu = 4,
+ RID_Dialog = 5,
+ RID_String = 6,
+ RID_FontDir = 7,
+ RID_Font = 8,
+ RID_Accelerator = 9,
+ RID_RCData = 10,
+ RID_MessageTable = 11,
+ RID_Group_Cursor = 12,
+ RID_Group_Icon = 14,
+ RID_Version = 16,
+ RID_DLGInclude = 17,
+ RID_PlugPlay = 19,
+ RID_VXD = 20,
+ RID_AniCursor = 21,
+ RID_AniIcon = 22,
+ RID_HTML = 23,
+ RID_Manifest = 24,
+};
+
+struct symbol {
+ char Name[NameSize];
+ uint32_t Value;
+ int32_t SectionNumber;
+ uint16_t Type;
+ uint8_t StorageClass;
+ uint8_t NumberOfAuxSymbols;
+};
+
+enum SymbolSectionNumber : int32_t {
+ IMAGE_SYM_DEBUG = -2,
+ IMAGE_SYM_ABSOLUTE = -1,
+ IMAGE_SYM_UNDEFINED = 0
+};
+
+/// Storage class tells where and what the symbol represents
+enum SymbolStorageClass {
+ SSC_Invalid = 0xff,
+
+ IMAGE_SYM_CLASS_END_OF_FUNCTION = -1, ///< Physical end of function
+ IMAGE_SYM_CLASS_NULL = 0, ///< No symbol
+ IMAGE_SYM_CLASS_AUTOMATIC = 1, ///< Stack variable
+ IMAGE_SYM_CLASS_EXTERNAL = 2, ///< External symbol
+ IMAGE_SYM_CLASS_STATIC = 3, ///< Static
+ IMAGE_SYM_CLASS_REGISTER = 4, ///< Register variable
+ IMAGE_SYM_CLASS_EXTERNAL_DEF = 5, ///< External definition
+ IMAGE_SYM_CLASS_LABEL = 6, ///< Label
+ IMAGE_SYM_CLASS_UNDEFINED_LABEL = 7, ///< Undefined label
+ IMAGE_SYM_CLASS_MEMBER_OF_STRUCT = 8, ///< Member of structure
+ IMAGE_SYM_CLASS_ARGUMENT = 9, ///< Function argument
+ IMAGE_SYM_CLASS_STRUCT_TAG = 10, ///< Structure tag
+ IMAGE_SYM_CLASS_MEMBER_OF_UNION = 11, ///< Member of union
+ IMAGE_SYM_CLASS_UNION_TAG = 12, ///< Union tag
+ IMAGE_SYM_CLASS_TYPE_DEFINITION = 13, ///< Type definition
+ IMAGE_SYM_CLASS_UNDEFINED_STATIC = 14, ///< Undefined static
+ IMAGE_SYM_CLASS_ENUM_TAG = 15, ///< Enumeration tag
+ IMAGE_SYM_CLASS_MEMBER_OF_ENUM = 16, ///< Member of enumeration
+ IMAGE_SYM_CLASS_REGISTER_PARAM = 17, ///< Register parameter
+ IMAGE_SYM_CLASS_BIT_FIELD = 18, ///< Bit field
+ /// ".bb" or ".eb" - beginning or end of block
+ IMAGE_SYM_CLASS_BLOCK = 100,
+ /// ".bf" or ".ef" - beginning or end of function
+ IMAGE_SYM_CLASS_FUNCTION = 101,
+ IMAGE_SYM_CLASS_END_OF_STRUCT = 102, ///< End of structure
+ IMAGE_SYM_CLASS_FILE = 103, ///< File name
+ /// Line number, reformatted as symbol
+ IMAGE_SYM_CLASS_SECTION = 104,
+ IMAGE_SYM_CLASS_WEAK_EXTERNAL = 105, ///< Duplicate tag
+ /// External symbol in dmert public lib
+ IMAGE_SYM_CLASS_CLR_TOKEN = 107
+};
+
+enum SymbolBaseType {
+ IMAGE_SYM_TYPE_NULL = 0, ///< No type information or unknown base type.
+ IMAGE_SYM_TYPE_VOID = 1, ///< Used with void pointers and functions.
+ IMAGE_SYM_TYPE_CHAR = 2, ///< A character (signed byte).
+ IMAGE_SYM_TYPE_SHORT = 3, ///< A 2-byte signed integer.
+ IMAGE_SYM_TYPE_INT = 4, ///< A natural integer type on the target.
+ IMAGE_SYM_TYPE_LONG = 5, ///< A 4-byte signed integer.
+ IMAGE_SYM_TYPE_FLOAT = 6, ///< A 4-byte floating-point number.
+ IMAGE_SYM_TYPE_DOUBLE = 7, ///< An 8-byte floating-point number.
+ IMAGE_SYM_TYPE_STRUCT = 8, ///< A structure.
+ IMAGE_SYM_TYPE_UNION = 9, ///< An union.
+ IMAGE_SYM_TYPE_ENUM = 10, ///< An enumerated type.
+ IMAGE_SYM_TYPE_MOE = 11, ///< A member of enumeration (a specific value).
+ IMAGE_SYM_TYPE_BYTE = 12, ///< A byte; unsigned 1-byte integer.
+ IMAGE_SYM_TYPE_WORD = 13, ///< A word; unsigned 2-byte integer.
+ IMAGE_SYM_TYPE_UINT = 14, ///< An unsigned integer of natural size.
+ IMAGE_SYM_TYPE_DWORD = 15 ///< An unsigned 4-byte integer.
+};
+
+enum SymbolComplexType {
+ IMAGE_SYM_DTYPE_NULL = 0, ///< No complex type; simple scalar variable.
+ IMAGE_SYM_DTYPE_POINTER = 1, ///< A pointer to base type.
+ IMAGE_SYM_DTYPE_FUNCTION = 2, ///< A function that returns a base type.
+ IMAGE_SYM_DTYPE_ARRAY = 3, ///< An array of base type.
+
+ /// Type is formed as (base + (derived << SCT_COMPLEX_TYPE_SHIFT))
+ SCT_COMPLEX_TYPE_SHIFT = 4
+};
+
+enum AuxSymbolType { IMAGE_AUX_SYMBOL_TYPE_TOKEN_DEF = 1 };
+
+struct section {
+ char Name[NameSize];
+ uint32_t VirtualSize;
+ uint32_t VirtualAddress;
+ uint32_t SizeOfRawData;
+ uint32_t PointerToRawData;
+ uint32_t PointerToRelocations;
+ uint32_t PointerToLineNumbers;
+ uint16_t NumberOfRelocations;
+ uint16_t NumberOfLineNumbers;
+ uint32_t Characteristics;
+};
+
+enum SectionCharacteristics : uint32_t {
+ SC_Invalid = 0xffffffff,
+
+ IMAGE_SCN_TYPE_NOLOAD = 0x00000002,
+ IMAGE_SCN_TYPE_NO_PAD = 0x00000008,
+ IMAGE_SCN_CNT_CODE = 0x00000020,
+ IMAGE_SCN_CNT_INITIALIZED_DATA = 0x00000040,
+ IMAGE_SCN_CNT_UNINITIALIZED_DATA = 0x00000080,
+ IMAGE_SCN_LNK_OTHER = 0x00000100,
+ IMAGE_SCN_LNK_INFO = 0x00000200,
+ IMAGE_SCN_LNK_REMOVE = 0x00000800,
+ IMAGE_SCN_LNK_COMDAT = 0x00001000,
+ IMAGE_SCN_GPREL = 0x00008000,
+ IMAGE_SCN_MEM_PURGEABLE = 0x00020000,
+ IMAGE_SCN_MEM_16BIT = 0x00020000,
+ IMAGE_SCN_MEM_LOCKED = 0x00040000,
+ IMAGE_SCN_MEM_PRELOAD = 0x00080000,
+ IMAGE_SCN_ALIGN_1BYTES = 0x00100000,
+ IMAGE_SCN_ALIGN_2BYTES = 0x00200000,
+ IMAGE_SCN_ALIGN_4BYTES = 0x00300000,
+ IMAGE_SCN_ALIGN_8BYTES = 0x00400000,
+ IMAGE_SCN_ALIGN_16BYTES = 0x00500000,
+ IMAGE_SCN_ALIGN_32BYTES = 0x00600000,
+ IMAGE_SCN_ALIGN_64BYTES = 0x00700000,
+ IMAGE_SCN_ALIGN_128BYTES = 0x00800000,
+ IMAGE_SCN_ALIGN_256BYTES = 0x00900000,
+ IMAGE_SCN_ALIGN_512BYTES = 0x00A00000,
+ IMAGE_SCN_ALIGN_1024BYTES = 0x00B00000,
+ IMAGE_SCN_ALIGN_2048BYTES = 0x00C00000,
+ IMAGE_SCN_ALIGN_4096BYTES = 0x00D00000,
+ IMAGE_SCN_ALIGN_8192BYTES = 0x00E00000,
+ IMAGE_SCN_LNK_NRELOC_OVFL = 0x01000000,
+ IMAGE_SCN_MEM_DISCARDABLE = 0x02000000,
+ IMAGE_SCN_MEM_NOT_CACHED = 0x04000000,
+ IMAGE_SCN_MEM_NOT_PAGED = 0x08000000,
+ IMAGE_SCN_MEM_SHARED = 0x10000000,
+ IMAGE_SCN_MEM_EXECUTE = 0x20000000,
+ IMAGE_SCN_MEM_READ = 0x40000000,
+ IMAGE_SCN_MEM_WRITE = 0x80000000
+};
+
+struct relocation {
+ uint32_t VirtualAddress;
+ uint32_t SymbolTableIndex;
+ uint16_t Type;
+};
+
+enum RelocationTypeI386 {
+ IMAGE_REL_I386_ABSOLUTE = 0x0000,
+ IMAGE_REL_I386_DIR16 = 0x0001,
+ IMAGE_REL_I386_REL16 = 0x0002,
+ IMAGE_REL_I386_DIR32 = 0x0006,
+ IMAGE_REL_I386_DIR32NB = 0x0007,
+ IMAGE_REL_I386_SEG12 = 0x0009,
+ IMAGE_REL_I386_SECTION = 0x000A,
+ IMAGE_REL_I386_SECREL = 0x000B,
+ IMAGE_REL_I386_TOKEN = 0x000C,
+ IMAGE_REL_I386_SECREL7 = 0x000D,
+ IMAGE_REL_I386_REL32 = 0x0014
+};
+
+enum RelocationTypeAMD64 {
+ IMAGE_REL_AMD64_ABSOLUTE = 0x0000,
+ IMAGE_REL_AMD64_ADDR64 = 0x0001,
+ IMAGE_REL_AMD64_ADDR32 = 0x0002,
+ IMAGE_REL_AMD64_ADDR32NB = 0x0003,
+ IMAGE_REL_AMD64_REL32 = 0x0004,
+ IMAGE_REL_AMD64_REL32_1 = 0x0005,
+ IMAGE_REL_AMD64_REL32_2 = 0x0006,
+ IMAGE_REL_AMD64_REL32_3 = 0x0007,
+ IMAGE_REL_AMD64_REL32_4 = 0x0008,
+ IMAGE_REL_AMD64_REL32_5 = 0x0009,
+ IMAGE_REL_AMD64_SECTION = 0x000A,
+ IMAGE_REL_AMD64_SECREL = 0x000B,
+ IMAGE_REL_AMD64_SECREL7 = 0x000C,
+ IMAGE_REL_AMD64_TOKEN = 0x000D,
+ IMAGE_REL_AMD64_SREL32 = 0x000E,
+ IMAGE_REL_AMD64_PAIR = 0x000F,
+ IMAGE_REL_AMD64_SSPAN32 = 0x0010
+};
+
+enum RelocationTypesARM {
+ IMAGE_REL_ARM_ABSOLUTE = 0x0000,
+ IMAGE_REL_ARM_ADDR32 = 0x0001,
+ IMAGE_REL_ARM_ADDR32NB = 0x0002,
+ IMAGE_REL_ARM_BRANCH24 = 0x0003,
+ IMAGE_REL_ARM_BRANCH11 = 0x0004,
+ IMAGE_REL_ARM_TOKEN = 0x0005,
+ IMAGE_REL_ARM_BLX24 = 0x0008,
+ IMAGE_REL_ARM_BLX11 = 0x0009,
+ IMAGE_REL_ARM_SECTION = 0x000E,
+ IMAGE_REL_ARM_SECREL = 0x000F,
+ IMAGE_REL_ARM_MOV32A = 0x0010,
+ IMAGE_REL_ARM_MOV32T = 0x0011,
+ IMAGE_REL_ARM_BRANCH20T = 0x0012,
+ IMAGE_REL_ARM_BRANCH24T = 0x0014,
+ IMAGE_REL_ARM_BLX23T = 0x0015
+};
+
+enum RelocationTypesARM64 {
+ IMAGE_REL_ARM64_ABSOLUTE = 0x0000,
+ IMAGE_REL_ARM64_ADDR32 = 0x0001,
+ IMAGE_REL_ARM64_ADDR32NB = 0x0002,
+ IMAGE_REL_ARM64_BRANCH26 = 0x0003,
+ IMAGE_REL_ARM64_PAGEBASE_REL21 = 0x0004,
+ IMAGE_REL_ARM64_REL21 = 0x0005,
+ IMAGE_REL_ARM64_PAGEOFFSET_12A = 0x0006,
+ IMAGE_REL_ARM64_PAGEOFFSET_12L = 0x0007,
+ IMAGE_REL_ARM64_SECREL = 0x0008,
+ IMAGE_REL_ARM64_SECREL_LOW12A = 0x0009,
+ IMAGE_REL_ARM64_SECREL_HIGH12A = 0x000A,
+ IMAGE_REL_ARM64_SECREL_LOW12L = 0x000B,
+ IMAGE_REL_ARM64_TOKEN = 0x000C,
+ IMAGE_REL_ARM64_SECTION = 0x000D,
+ IMAGE_REL_ARM64_ADDR64 = 0x000E,
+ IMAGE_REL_ARM64_BRANCH19 = 0x000F,
+ IMAGE_REL_ARM64_BRANCH14 = 0x0010,
+};
+
+enum COMDATType {
+ IMAGE_COMDAT_SELECT_NODUPLICATES = 1,
+ IMAGE_COMDAT_SELECT_ANY,
+ IMAGE_COMDAT_SELECT_SAME_SIZE,
+ IMAGE_COMDAT_SELECT_EXACT_MATCH,
+ IMAGE_COMDAT_SELECT_ASSOCIATIVE,
+ IMAGE_COMDAT_SELECT_LARGEST,
+ IMAGE_COMDAT_SELECT_NEWEST
+};
+
+// Auxiliary Symbol Formats
+struct AuxiliaryFunctionDefinition {
+ uint32_t TagIndex;
+ uint32_t TotalSize;
+ uint32_t PointerToLinenumber;
+ uint32_t PointerToNextFunction;
+ char unused[2];
+};
+
+struct AuxiliarybfAndefSymbol {
+ uint8_t unused1[4];
+ uint16_t Linenumber;
+ uint8_t unused2[6];
+ uint32_t PointerToNextFunction;
+ uint8_t unused3[2];
+};
+
+struct AuxiliaryWeakExternal {
+ uint32_t TagIndex;
+ uint32_t Characteristics;
+ uint8_t unused[10];
+};
+
+enum WeakExternalCharacteristics {
+ IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY = 1,
+ IMAGE_WEAK_EXTERN_SEARCH_LIBRARY = 2,
+ IMAGE_WEAK_EXTERN_SEARCH_ALIAS = 3
+};
+
+struct AuxiliarySectionDefinition {
+ uint32_t Length;
+ uint16_t NumberOfRelocations;
+ uint16_t NumberOfLinenumbers;
+ uint32_t CheckSum;
+ uint32_t Number;
+ uint8_t Selection;
+ char unused;
+};
+
+struct AuxiliaryCLRToken {
+ uint8_t AuxType;
+ uint8_t unused1;
+ uint32_t SymbolTableIndex;
+ char unused2[12];
+};
+
+union Auxiliary {
+ AuxiliaryFunctionDefinition FunctionDefinition;
+ AuxiliarybfAndefSymbol bfAndefSymbol;
+ AuxiliaryWeakExternal WeakExternal;
+ AuxiliarySectionDefinition SectionDefinition;
+};
+
+/// @brief The Import Directory Table.
+///
+/// There is a single array of these and one entry per imported DLL.
+struct ImportDirectoryTableEntry {
+ uint32_t ImportLookupTableRVA;
+ uint32_t TimeDateStamp;
+ uint32_t ForwarderChain;
+ uint32_t NameRVA;
+ uint32_t ImportAddressTableRVA;
+};
+
+/// @brief The PE32 Import Lookup Table.
+///
+/// There is an array of these for each imported DLL. It represents either
+/// the ordinal to import from the target DLL, or a name to lookup and import
+/// from the target DLL.
+///
+/// This also happens to be the same format used by the Import Address Table
+/// when it is initially written out to the image.
+struct ImportLookupTableEntry32 {
+ uint32_t data;
+
+ /// @brief Is this entry specified by ordinal, or name?
+ bool isOrdinal() const { return data & 0x80000000; }
+
+ /// @brief Get the ordinal value of this entry. isOrdinal must be true.
+ uint16_t getOrdinal() const {
+ assert(isOrdinal() && "ILT entry is not an ordinal!");
+ return data & 0xFFFF;
+ }
+
+ /// @brief Set the ordinal value and set isOrdinal to true.
+ void setOrdinal(uint16_t o) {
+ data = o;
+ data |= 0x80000000;
+ }
+
+ /// @brief Get the Hint/Name entry RVA. isOrdinal must be false.
+ uint32_t getHintNameRVA() const {
+ assert(!isOrdinal() && "ILT entry is not a Hint/Name RVA!");
+ return data;
+ }
+
+ /// @brief Set the Hint/Name entry RVA and set isOrdinal to false.
+ void setHintNameRVA(uint32_t rva) { data = rva; }
+};
+
+/// @brief The DOS compatible header at the front of all PEs.
+struct DOSHeader {
+ uint16_t Magic;
+ uint16_t UsedBytesInTheLastPage;
+ uint16_t FileSizeInPages;
+ uint16_t NumberOfRelocationItems;
+ uint16_t HeaderSizeInParagraphs;
+ uint16_t MinimumExtraParagraphs;
+ uint16_t MaximumExtraParagraphs;
+ uint16_t InitialRelativeSS;
+ uint16_t InitialSP;
+ uint16_t Checksum;
+ uint16_t InitialIP;
+ uint16_t InitialRelativeCS;
+ uint16_t AddressOfRelocationTable;
+ uint16_t OverlayNumber;
+ uint16_t Reserved[4];
+ uint16_t OEMid;
+ uint16_t OEMinfo;
+ uint16_t Reserved2[10];
+ uint32_t AddressOfNewExeHeader;
+};
+
+struct PE32Header {
+ enum { PE32 = 0x10b, PE32_PLUS = 0x20b };
+
+ uint16_t Magic;
+ uint8_t MajorLinkerVersion;
+ uint8_t MinorLinkerVersion;
+ uint32_t SizeOfCode;
+ uint32_t SizeOfInitializedData;
+ uint32_t SizeOfUninitializedData;
+ uint32_t AddressOfEntryPoint; // RVA
+ uint32_t BaseOfCode; // RVA
+ uint32_t BaseOfData; // RVA
+ uint32_t ImageBase;
+ uint32_t SectionAlignment;
+ uint32_t FileAlignment;
+ uint16_t MajorOperatingSystemVersion;
+ uint16_t MinorOperatingSystemVersion;
+ uint16_t MajorImageVersion;
+ uint16_t MinorImageVersion;
+ uint16_t MajorSubsystemVersion;
+ uint16_t MinorSubsystemVersion;
+ uint32_t Win32VersionValue;
+ uint32_t SizeOfImage;
+ uint32_t SizeOfHeaders;
+ uint32_t CheckSum;
+ uint16_t Subsystem;
+ // FIXME: This should be DllCharacteristics to match the COFF spec.
+ uint16_t DLLCharacteristics;
+ uint32_t SizeOfStackReserve;
+ uint32_t SizeOfStackCommit;
+ uint32_t SizeOfHeapReserve;
+ uint32_t SizeOfHeapCommit;
+ uint32_t LoaderFlags;
+ // FIXME: This should be NumberOfRvaAndSizes to match the COFF spec.
+ uint32_t NumberOfRvaAndSize;
+};
+
+struct DataDirectory {
+ uint32_t RelativeVirtualAddress;
+ uint32_t Size;
+};
+
+enum DataDirectoryIndex {
+ EXPORT_TABLE = 0,
+ IMPORT_TABLE,
+ RESOURCE_TABLE,
+ EXCEPTION_TABLE,
+ CERTIFICATE_TABLE,
+ BASE_RELOCATION_TABLE,
+ DEBUG_DIRECTORY,
+ ARCHITECTURE,
+ GLOBAL_PTR,
+ TLS_TABLE,
+ LOAD_CONFIG_TABLE,
+ BOUND_IMPORT,
+ IAT,
+ DELAY_IMPORT_DESCRIPTOR,
+ CLR_RUNTIME_HEADER,
+
+ NUM_DATA_DIRECTORIES
+};
+
+enum WindowsSubsystem {
+ IMAGE_SUBSYSTEM_UNKNOWN = 0, ///< An unknown subsystem.
+ IMAGE_SUBSYSTEM_NATIVE = 1, ///< Device drivers and native Windows processes
+ IMAGE_SUBSYSTEM_WINDOWS_GUI = 2, ///< The Windows GUI subsystem.
+ IMAGE_SUBSYSTEM_WINDOWS_CUI = 3, ///< The Windows character subsystem.
+ IMAGE_SUBSYSTEM_OS2_CUI = 5, ///< The OS/2 character subsytem.
+ IMAGE_SUBSYSTEM_POSIX_CUI = 7, ///< The POSIX character subsystem.
+ IMAGE_SUBSYSTEM_NATIVE_WINDOWS = 8, ///< Native Windows 9x driver.
+ IMAGE_SUBSYSTEM_WINDOWS_CE_GUI = 9, ///< Windows CE.
+ IMAGE_SUBSYSTEM_EFI_APPLICATION = 10, ///< An EFI application.
+ IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER = 11, ///< An EFI driver with boot
+ /// services.
+ IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER = 12, ///< An EFI driver with run-time
+ /// services.
+ IMAGE_SUBSYSTEM_EFI_ROM = 13, ///< An EFI ROM image.
+ IMAGE_SUBSYSTEM_XBOX = 14, ///< XBOX.
+ IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION = 16 ///< A BCD application.
+};
+
+enum DLLCharacteristics {
+ /// ASLR with 64 bit address space.
+ IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA = 0x0020,
+ /// DLL can be relocated at load time.
+ IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE = 0x0040,
+ /// Code integrity checks are enforced.
+ IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY = 0x0080,
+ ///< Image is NX compatible.
+ IMAGE_DLL_CHARACTERISTICS_NX_COMPAT = 0x0100,
+ /// Isolation aware, but do not isolate the image.
+ IMAGE_DLL_CHARACTERISTICS_NO_ISOLATION = 0x0200,
+ /// Does not use structured exception handling (SEH). No SEH handler may be
+ /// called in this image.
+ IMAGE_DLL_CHARACTERISTICS_NO_SEH = 0x0400,
+ /// Do not bind the image.
+ IMAGE_DLL_CHARACTERISTICS_NO_BIND = 0x0800,
+ ///< Image should execute in an AppContainer.
+ IMAGE_DLL_CHARACTERISTICS_APPCONTAINER = 0x1000,
+ ///< A WDM driver.
+ IMAGE_DLL_CHARACTERISTICS_WDM_DRIVER = 0x2000,
+ ///< Image supports Control Flow Guard.
+ IMAGE_DLL_CHARACTERISTICS_GUARD_CF = 0x4000,
+ /// Terminal Server aware.
+ IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE = 0x8000
+};
+
+enum DebugType {
+ IMAGE_DEBUG_TYPE_UNKNOWN = 0,
+ IMAGE_DEBUG_TYPE_COFF = 1,
+ IMAGE_DEBUG_TYPE_CODEVIEW = 2,
+ IMAGE_DEBUG_TYPE_FPO = 3,
+ IMAGE_DEBUG_TYPE_MISC = 4,
+ IMAGE_DEBUG_TYPE_EXCEPTION = 5,
+ IMAGE_DEBUG_TYPE_FIXUP = 6,
+ IMAGE_DEBUG_TYPE_OMAP_TO_SRC = 7,
+ IMAGE_DEBUG_TYPE_OMAP_FROM_SRC = 8,
+ IMAGE_DEBUG_TYPE_BORLAND = 9,
+ IMAGE_DEBUG_TYPE_RESERVED10 = 10,
+ IMAGE_DEBUG_TYPE_CLSID = 11,
+ IMAGE_DEBUG_TYPE_VC_FEATURE = 12,
+ IMAGE_DEBUG_TYPE_POGO = 13,
+ IMAGE_DEBUG_TYPE_ILTCG = 14,
+ IMAGE_DEBUG_TYPE_MPX = 15,
+ IMAGE_DEBUG_TYPE_REPRO = 16,
+};
+
+enum BaseRelocationType {
+ IMAGE_REL_BASED_ABSOLUTE = 0,
+ IMAGE_REL_BASED_HIGH = 1,
+ IMAGE_REL_BASED_LOW = 2,
+ IMAGE_REL_BASED_HIGHLOW = 3,
+ IMAGE_REL_BASED_HIGHADJ = 4,
+ IMAGE_REL_BASED_MIPS_JMPADDR = 5,
+ IMAGE_REL_BASED_ARM_MOV32A = 5,
+ IMAGE_REL_BASED_ARM_MOV32T = 7,
+ IMAGE_REL_BASED_MIPS_JMPADDR16 = 9,
+ IMAGE_REL_BASED_DIR64 = 10
+};
+
+enum ImportType { IMPORT_CODE = 0, IMPORT_DATA = 1, IMPORT_CONST = 2 };
+
+enum ImportNameType {
+ /// Import is by ordinal. This indicates that the value in the Ordinal/Hint
+ /// field of the import header is the import's ordinal. If this constant is
+ /// not specified, then the Ordinal/Hint field should always be interpreted
+ /// as the import's hint.
+ IMPORT_ORDINAL = 0,
+ /// The import name is identical to the public symbol name
+ IMPORT_NAME = 1,
+ /// The import name is the public symbol name, but skipping the leading ?,
+ /// @, or optionally _.
+ IMPORT_NAME_NOPREFIX = 2,
+ /// The import name is the public symbol name, but skipping the leading ?,
+ /// @, or optionally _, and truncating at the first @.
+ IMPORT_NAME_UNDECORATE = 3
+};
+
+struct ImportHeader {
+ uint16_t Sig1; ///< Must be IMAGE_FILE_MACHINE_UNKNOWN (0).
+ uint16_t Sig2; ///< Must be 0xFFFF.
+ uint16_t Version;
+ uint16_t Machine;
+ uint32_t TimeDateStamp;
+ uint32_t SizeOfData;
+ uint16_t OrdinalHint;
+ uint16_t TypeInfo;
+
+ ImportType getType() const { return static_cast<ImportType>(TypeInfo & 0x3); }
+
+ ImportNameType getNameType() const {
+ return static_cast<ImportNameType>((TypeInfo & 0x1C) >> 2);
+ }
+};
+
+enum CodeViewIdentifiers {
+ DEBUG_SECTION_MAGIC = 0x4,
+};
+
+inline bool isReservedSectionNumber(int32_t SectionNumber) {
+ return SectionNumber <= 0;
+}
+
+} // End namespace COFF.
+} // End namespace llvm.
+
+#endif
diff --git a/contrib/llvm/include/llvm/BinaryFormat/Dwarf.def b/contrib/llvm/include/llvm/BinaryFormat/Dwarf.def
new file mode 100644
index 0000000..3df3300
--- /dev/null
+++ b/contrib/llvm/include/llvm/BinaryFormat/Dwarf.def
@@ -0,0 +1,838 @@
+//===- llvm/Support/Dwarf.def - Dwarf definitions ---------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Macros for running through Dwarf enumerators.
+//
+//===----------------------------------------------------------------------===//
+
+// TODO: Add other DW-based macros.
+#if !(defined HANDLE_DW_TAG || defined HANDLE_DW_AT || \
+ defined HANDLE_DW_FORM || defined HANDLE_DW_OP || \
+ defined HANDLE_DW_LANG || defined HANDLE_DW_ATE || \
+ 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_DW_RLE || \
+ defined HANDLE_DW_CFA || defined HANDLE_DW_APPLE_PROPERTY || \
+ defined HANDLE_DW_UT)
+#error "Missing macro definition of HANDLE_DW*"
+#endif
+
+#ifndef HANDLE_DW_TAG
+#define HANDLE_DW_TAG(ID, NAME, VERSION, VENDOR)
+#endif
+
+#ifndef HANDLE_DW_AT
+#define HANDLE_DW_AT(ID, NAME, VERSION, VENDOR)
+#endif
+
+#ifndef HANDLE_DW_FORM
+#define HANDLE_DW_FORM(ID, NAME, VERSION, VENDOR)
+#endif
+
+#ifndef HANDLE_DW_OP
+#define HANDLE_DW_OP(ID, NAME, VERSION, VENDOR)
+#endif
+
+#ifndef HANDLE_DW_LANG
+#define HANDLE_DW_LANG(ID, NAME, VERSION, VENDOR)
+#endif
+
+#ifndef HANDLE_DW_ATE
+#define HANDLE_DW_ATE(ID, NAME, VERSION, VENDOR)
+#endif
+
+#ifndef HANDLE_DW_VIRTUALITY
+#define HANDLE_DW_VIRTUALITY(ID, NAME)
+#endif
+
+#ifndef HANDLE_DW_DEFAULTED
+#define HANDLE_DW_DEFAULTED(ID, NAME)
+#endif
+
+#ifndef HANDLE_DW_CC
+#define HANDLE_DW_CC(ID, NAME)
+#endif
+
+#ifndef HANDLE_DW_LNS
+#define HANDLE_DW_LNS(ID, NAME)
+#endif
+
+#ifndef HANDLE_DW_LNE
+#define HANDLE_DW_LNE(ID, NAME)
+#endif
+
+#ifndef HANDLE_DW_LNCT
+#define HANDLE_DW_LNCT(ID, NAME)
+#endif
+
+#ifndef HANDLE_DW_MACRO
+#define HANDLE_DW_MACRO(ID, NAME)
+#endif
+
+#ifndef HANDLE_DW_RLE
+#define HANDLE_DW_RLE(ID, NAME)
+#endif
+
+#ifndef HANDLE_DW_CFA
+#define HANDLE_DW_CFA(ID, NAME)
+#endif
+
+#ifndef HANDLE_DW_APPLE_PROPERTY
+#define HANDLE_DW_APPLE_PROPERTY(ID, NAME)
+#endif
+
+#ifndef HANDLE_DW_UT
+#define HANDLE_DW_UT(ID, NAME)
+#endif
+
+HANDLE_DW_TAG(0x0000, null, 2, DWARF)
+HANDLE_DW_TAG(0x0001, array_type, 2, DWARF)
+HANDLE_DW_TAG(0x0002, class_type, 2, DWARF)
+HANDLE_DW_TAG(0x0003, entry_point, 2, DWARF)
+HANDLE_DW_TAG(0x0004, enumeration_type, 2, DWARF)
+HANDLE_DW_TAG(0x0005, formal_parameter, 2, DWARF)
+HANDLE_DW_TAG(0x0008, imported_declaration, 2, DWARF)
+HANDLE_DW_TAG(0x000a, label, 2, DWARF)
+HANDLE_DW_TAG(0x000b, lexical_block, 2, DWARF)
+HANDLE_DW_TAG(0x000d, member, 2, DWARF)
+HANDLE_DW_TAG(0x000f, pointer_type, 2, DWARF)
+HANDLE_DW_TAG(0x0010, reference_type, 2, DWARF)
+HANDLE_DW_TAG(0x0011, compile_unit, 2, DWARF)
+HANDLE_DW_TAG(0x0012, string_type, 2, DWARF)
+HANDLE_DW_TAG(0x0013, structure_type, 2, DWARF)
+HANDLE_DW_TAG(0x0015, subroutine_type, 2, DWARF)
+HANDLE_DW_TAG(0x0016, typedef, 2, DWARF)
+HANDLE_DW_TAG(0x0017, union_type, 2, DWARF)
+HANDLE_DW_TAG(0x0018, unspecified_parameters, 2, DWARF)
+HANDLE_DW_TAG(0x0019, variant, 2, DWARF)
+HANDLE_DW_TAG(0x001a, common_block, 2, DWARF)
+HANDLE_DW_TAG(0x001b, common_inclusion, 2, DWARF)
+HANDLE_DW_TAG(0x001c, inheritance, 2, DWARF)
+HANDLE_DW_TAG(0x001d, inlined_subroutine, 2, DWARF)
+HANDLE_DW_TAG(0x001e, module, 2, DWARF)
+HANDLE_DW_TAG(0x001f, ptr_to_member_type, 2, DWARF)
+HANDLE_DW_TAG(0x0020, set_type, 2, DWARF)
+HANDLE_DW_TAG(0x0021, subrange_type, 2, DWARF)
+HANDLE_DW_TAG(0x0022, with_stmt, 2, DWARF)
+HANDLE_DW_TAG(0x0023, access_declaration, 2, DWARF)
+HANDLE_DW_TAG(0x0024, base_type, 2, DWARF)
+HANDLE_DW_TAG(0x0025, catch_block, 2, DWARF)
+HANDLE_DW_TAG(0x0026, const_type, 2, DWARF)
+HANDLE_DW_TAG(0x0027, constant, 2, DWARF)
+HANDLE_DW_TAG(0x0028, enumerator, 2, DWARF)
+HANDLE_DW_TAG(0x0029, file_type, 2, DWARF)
+HANDLE_DW_TAG(0x002a, friend, 2, DWARF)
+HANDLE_DW_TAG(0x002b, namelist, 2, DWARF)
+HANDLE_DW_TAG(0x002c, namelist_item, 2, DWARF)
+HANDLE_DW_TAG(0x002d, packed_type, 2, DWARF)
+HANDLE_DW_TAG(0x002e, subprogram, 2, DWARF)
+HANDLE_DW_TAG(0x002f, template_type_parameter, 2, DWARF)
+HANDLE_DW_TAG(0x0030, template_value_parameter, 2, DWARF)
+HANDLE_DW_TAG(0x0031, thrown_type, 2, DWARF)
+HANDLE_DW_TAG(0x0032, try_block, 2, DWARF)
+HANDLE_DW_TAG(0x0033, variant_part, 2, DWARF)
+HANDLE_DW_TAG(0x0034, variable, 2, DWARF)
+HANDLE_DW_TAG(0x0035, volatile_type, 2, DWARF)
+// New in DWARF v3:
+HANDLE_DW_TAG(0x0036, dwarf_procedure, 3, DWARF)
+HANDLE_DW_TAG(0x0037, restrict_type, 3, DWARF)
+HANDLE_DW_TAG(0x0038, interface_type, 3, DWARF)
+HANDLE_DW_TAG(0x0039, namespace, 3, DWARF)
+HANDLE_DW_TAG(0x003a, imported_module, 3, DWARF)
+HANDLE_DW_TAG(0x003b, unspecified_type, 3, DWARF)
+HANDLE_DW_TAG(0x003c, partial_unit, 3, DWARF)
+HANDLE_DW_TAG(0x003d, imported_unit, 3, DWARF)
+HANDLE_DW_TAG(0x003f, condition, 3, DWARF)
+HANDLE_DW_TAG(0x0040, shared_type, 3, DWARF)
+// New in DWARF v4:
+HANDLE_DW_TAG(0x0041, type_unit, 4, DWARF)
+HANDLE_DW_TAG(0x0042, rvalue_reference_type, 4, DWARF)
+HANDLE_DW_TAG(0x0043, template_alias, 4, DWARF)
+// New in DWARF v5:
+HANDLE_DW_TAG(0x0044, coarray_type, 5, DWARF)
+HANDLE_DW_TAG(0x0045, generic_subrange, 5, DWARF)
+HANDLE_DW_TAG(0x0046, dynamic_type, 5, DWARF)
+HANDLE_DW_TAG(0x0047, atomic_type, 5, DWARF)
+HANDLE_DW_TAG(0x0048, call_site, 5, DWARF)
+HANDLE_DW_TAG(0x0049, call_site_parameter, 5, DWARF)
+HANDLE_DW_TAG(0x004a, skeleton_unit, 5, DWARF)
+HANDLE_DW_TAG(0x004b, immutable_type, 5, DWARF)
+// Vendor extensions:
+HANDLE_DW_TAG(0x4081, MIPS_loop, 0, MIPS)
+HANDLE_DW_TAG(0x4101, format_label, 0, GNU)
+HANDLE_DW_TAG(0x4102, function_template, 0, GNU)
+HANDLE_DW_TAG(0x4103, class_template, 0, GNU)
+HANDLE_DW_TAG(0x4106, GNU_template_template_param, 0, GNU)
+HANDLE_DW_TAG(0x4107, GNU_template_parameter_pack, 0, GNU)
+HANDLE_DW_TAG(0x4108, GNU_formal_parameter_pack, 0, GNU)
+HANDLE_DW_TAG(0x4200, APPLE_property, 0, APPLE)
+HANDLE_DW_TAG(0xb000, BORLAND_property, 0, BORLAND)
+HANDLE_DW_TAG(0xb001, BORLAND_Delphi_string, 0, BORLAND)
+HANDLE_DW_TAG(0xb002, BORLAND_Delphi_dynamic_array, 0, BORLAND)
+HANDLE_DW_TAG(0xb003, BORLAND_Delphi_set, 0, BORLAND)
+HANDLE_DW_TAG(0xb004, BORLAND_Delphi_variant, 0, BORLAND)
+
+// Attributes.
+HANDLE_DW_AT(0x01, sibling, 2, DWARF)
+HANDLE_DW_AT(0x02, location, 2, DWARF)
+HANDLE_DW_AT(0x03, name, 2, DWARF)
+HANDLE_DW_AT(0x09, ordering, 2, DWARF)
+HANDLE_DW_AT(0x0b, byte_size, 2, DWARF)
+HANDLE_DW_AT(0x0c, bit_offset, 2, DWARF)
+HANDLE_DW_AT(0x0d, bit_size, 2, DWARF)
+HANDLE_DW_AT(0x10, stmt_list, 2, DWARF)
+HANDLE_DW_AT(0x11, low_pc, 2, DWARF)
+HANDLE_DW_AT(0x12, high_pc, 2, DWARF)
+HANDLE_DW_AT(0x13, language, 2, DWARF)
+HANDLE_DW_AT(0x15, discr, 2, DWARF)
+HANDLE_DW_AT(0x16, discr_value, 2, DWARF)
+HANDLE_DW_AT(0x17, visibility, 2, DWARF)
+HANDLE_DW_AT(0x18, import, 2, DWARF)
+HANDLE_DW_AT(0x19, string_length, 2, DWARF)
+HANDLE_DW_AT(0x1a, common_reference, 2, DWARF)
+HANDLE_DW_AT(0x1b, comp_dir, 2, DWARF)
+HANDLE_DW_AT(0x1c, const_value, 2, DWARF)
+HANDLE_DW_AT(0x1d, containing_type, 2, DWARF)
+HANDLE_DW_AT(0x1e, default_value, 2, DWARF)
+HANDLE_DW_AT(0x20, inline, 2, DWARF)
+HANDLE_DW_AT(0x21, is_optional, 2, DWARF)
+HANDLE_DW_AT(0x22, lower_bound, 2, DWARF)
+HANDLE_DW_AT(0x25, producer, 2, DWARF)
+HANDLE_DW_AT(0x27, prototyped, 2, DWARF)
+HANDLE_DW_AT(0x2a, return_addr, 2, DWARF)
+HANDLE_DW_AT(0x2c, start_scope, 2, DWARF)
+HANDLE_DW_AT(0x2e, bit_stride, 2, DWARF)
+HANDLE_DW_AT(0x2f, upper_bound, 2, DWARF)
+HANDLE_DW_AT(0x31, abstract_origin, 2, DWARF)
+HANDLE_DW_AT(0x32, accessibility, 2, DWARF)
+HANDLE_DW_AT(0x33, address_class, 2, DWARF)
+HANDLE_DW_AT(0x34, artificial, 2, DWARF)
+HANDLE_DW_AT(0x35, base_types, 2, DWARF)
+HANDLE_DW_AT(0x36, calling_convention, 2, DWARF)
+HANDLE_DW_AT(0x37, count, 2, DWARF)
+HANDLE_DW_AT(0x38, data_member_location, 2, DWARF)
+HANDLE_DW_AT(0x39, decl_column, 2, DWARF)
+HANDLE_DW_AT(0x3a, decl_file, 2, DWARF)
+HANDLE_DW_AT(0x3b, decl_line, 2, DWARF)
+HANDLE_DW_AT(0x3c, declaration, 2, DWARF)
+HANDLE_DW_AT(0x3d, discr_list, 2, DWARF)
+HANDLE_DW_AT(0x3e, encoding, 2, DWARF)
+HANDLE_DW_AT(0x3f, external, 2, DWARF)
+HANDLE_DW_AT(0x40, frame_base, 2, DWARF)
+HANDLE_DW_AT(0x41, friend, 2, DWARF)
+HANDLE_DW_AT(0x42, identifier_case, 2, DWARF)
+HANDLE_DW_AT(0x43, macro_info, 2, DWARF)
+HANDLE_DW_AT(0x44, namelist_item, 2, DWARF)
+HANDLE_DW_AT(0x45, priority, 2, DWARF)
+HANDLE_DW_AT(0x46, segment, 2, DWARF)
+HANDLE_DW_AT(0x47, specification, 2, DWARF)
+HANDLE_DW_AT(0x48, static_link, 2, DWARF)
+HANDLE_DW_AT(0x49, type, 2, DWARF)
+HANDLE_DW_AT(0x4a, use_location, 2, DWARF)
+HANDLE_DW_AT(0x4b, variable_parameter, 2, DWARF)
+HANDLE_DW_AT(0x4c, virtuality, 2, DWARF)
+HANDLE_DW_AT(0x4d, vtable_elem_location, 2, DWARF)
+// New in DWARF v3:
+HANDLE_DW_AT(0x4e, allocated, 3, DWARF)
+HANDLE_DW_AT(0x4f, associated, 3, DWARF)
+HANDLE_DW_AT(0x50, data_location, 3, DWARF)
+HANDLE_DW_AT(0x51, byte_stride, 3, DWARF)
+HANDLE_DW_AT(0x52, entry_pc, 3, DWARF)
+HANDLE_DW_AT(0x53, use_UTF8, 3, DWARF)
+HANDLE_DW_AT(0x54, extension, 3, DWARF)
+HANDLE_DW_AT(0x55, ranges, 3, DWARF)
+HANDLE_DW_AT(0x56, trampoline, 3, DWARF)
+HANDLE_DW_AT(0x57, call_column, 3, DWARF)
+HANDLE_DW_AT(0x58, call_file, 3, DWARF)
+HANDLE_DW_AT(0x59, call_line, 3, DWARF)
+HANDLE_DW_AT(0x5a, description, 3, DWARF)
+HANDLE_DW_AT(0x5b, binary_scale, 3, DWARF)
+HANDLE_DW_AT(0x5c, decimal_scale, 3, DWARF)
+HANDLE_DW_AT(0x5d, small, 3, DWARF)
+HANDLE_DW_AT(0x5e, decimal_sign, 3, DWARF)
+HANDLE_DW_AT(0x5f, digit_count, 3, DWARF)
+HANDLE_DW_AT(0x60, picture_string, 3, DWARF)
+HANDLE_DW_AT(0x61, mutable, 3, DWARF)
+HANDLE_DW_AT(0x62, threads_scaled, 3, DWARF)
+HANDLE_DW_AT(0x63, explicit, 3, DWARF)
+HANDLE_DW_AT(0x64, object_pointer, 3, DWARF)
+HANDLE_DW_AT(0x65, endianity, 3, DWARF)
+HANDLE_DW_AT(0x66, elemental, 3, DWARF)
+HANDLE_DW_AT(0x67, pure, 3, DWARF)
+HANDLE_DW_AT(0x68, recursive, 3, DWARF)
+// New in DWARF v4:
+HANDLE_DW_AT(0x69, signature, 4, DWARF)
+HANDLE_DW_AT(0x6a, main_subprogram, 4, DWARF)
+HANDLE_DW_AT(0x6b, data_bit_offset, 4, DWARF)
+HANDLE_DW_AT(0x6c, const_expr, 4, DWARF)
+HANDLE_DW_AT(0x6d, enum_class, 4, DWARF)
+HANDLE_DW_AT(0x6e, linkage_name, 4, DWARF)
+// New in DWARF v5:
+HANDLE_DW_AT(0x6f, string_length_bit_size, 5, DWARF)
+HANDLE_DW_AT(0x70, string_length_byte_size, 5, DWARF)
+HANDLE_DW_AT(0x71, rank, 5, DWARF)
+HANDLE_DW_AT(0x72, str_offsets_base, 5, DWARF)
+HANDLE_DW_AT(0x73, addr_base, 5, DWARF)
+HANDLE_DW_AT(0x74, rnglists_base, 5, DWARF)
+HANDLE_DW_AT(0x75, dwo_id, 0, DWARF) ///< Retracted from DWARF v5.
+HANDLE_DW_AT(0x76, dwo_name, 5, DWARF)
+HANDLE_DW_AT(0x77, reference, 5, DWARF)
+HANDLE_DW_AT(0x78, rvalue_reference, 5, DWARF)
+HANDLE_DW_AT(0x79, macros, 5, DWARF)
+HANDLE_DW_AT(0x7a, call_all_calls, 5, DWARF)
+HANDLE_DW_AT(0x7b, call_all_source_calls, 5, DWARF)
+HANDLE_DW_AT(0x7c, call_all_tail_calls, 5, DWARF)
+HANDLE_DW_AT(0x7d, call_return_pc, 5, DWARF)
+HANDLE_DW_AT(0x7e, call_value, 5, DWARF)
+HANDLE_DW_AT(0x7f, call_origin, 5, DWARF)
+HANDLE_DW_AT(0x80, call_parameter, 5, DWARF)
+HANDLE_DW_AT(0x81, call_pc, 5, DWARF)
+HANDLE_DW_AT(0x82, call_tail_call, 5, DWARF)
+HANDLE_DW_AT(0x83, call_target, 5, DWARF)
+HANDLE_DW_AT(0x84, call_target_clobbered, 5, DWARF)
+HANDLE_DW_AT(0x85, call_data_location, 5, DWARF)
+HANDLE_DW_AT(0x86, call_data_value, 5, DWARF)
+HANDLE_DW_AT(0x87, noreturn, 5, DWARF)
+HANDLE_DW_AT(0x88, alignment, 5, DWARF)
+HANDLE_DW_AT(0x89, export_symbols, 5, DWARF)
+HANDLE_DW_AT(0x8a, deleted, 5, DWARF)
+HANDLE_DW_AT(0x8b, defaulted, 5, DWARF)
+HANDLE_DW_AT(0x8c, loclists_base, 5, DWARF)
+// Vendor extensions:
+HANDLE_DW_AT(0x2002, MIPS_loop_begin, 0, MIPS)
+HANDLE_DW_AT(0x2003, MIPS_tail_loop_begin, 0, MIPS)
+HANDLE_DW_AT(0x2004, MIPS_epilog_begin, 0, MIPS)
+HANDLE_DW_AT(0x2005, MIPS_loop_unroll_factor, 0, MIPS)
+HANDLE_DW_AT(0x2006, MIPS_software_pipeline_depth, 0, MIPS)
+HANDLE_DW_AT(0x2007, MIPS_linkage_name, 0, MIPS)
+HANDLE_DW_AT(0x2008, MIPS_stride, 0, MIPS)
+HANDLE_DW_AT(0x2009, MIPS_abstract_name, 0, MIPS)
+HANDLE_DW_AT(0x200a, MIPS_clone_origin, 0, MIPS)
+HANDLE_DW_AT(0x200b, MIPS_has_inlines, 0, MIPS)
+HANDLE_DW_AT(0x200c, MIPS_stride_byte, 0, MIPS)
+HANDLE_DW_AT(0x200d, MIPS_stride_elem, 0, MIPS)
+HANDLE_DW_AT(0x200e, MIPS_ptr_dopetype, 0, MIPS)
+HANDLE_DW_AT(0x200f, MIPS_allocatable_dopetype, 0, MIPS)
+HANDLE_DW_AT(0x2010, MIPS_assumed_shape_dopetype, 0, MIPS)
+// This one appears to have only been implemented by Open64 for
+// fortran and may conflict with other extensions.
+HANDLE_DW_AT(0x2011, MIPS_assumed_size, 0, MIPS)
+// GNU extensions
+HANDLE_DW_AT(0x2101, sf_names, 0, GNU)
+HANDLE_DW_AT(0x2102, src_info, 0, GNU)
+HANDLE_DW_AT(0x2103, mac_info, 0, GNU)
+HANDLE_DW_AT(0x2104, src_coords, 0, GNU)
+HANDLE_DW_AT(0x2105, body_begin, 0, GNU)
+HANDLE_DW_AT(0x2106, body_end, 0, GNU)
+HANDLE_DW_AT(0x2107, GNU_vector, 0, GNU)
+HANDLE_DW_AT(0x2110, GNU_template_name, 0, GNU)
+HANDLE_DW_AT(0x210f, GNU_odr_signature, 0, GNU)
+HANDLE_DW_AT(0x2119, GNU_macros, 0, GNU)
+// Extensions for Fission proposal.
+HANDLE_DW_AT(0x2130, GNU_dwo_name, 0, GNU)
+HANDLE_DW_AT(0x2131, GNU_dwo_id, 0, GNU)
+HANDLE_DW_AT(0x2132, GNU_ranges_base, 0, GNU)
+HANDLE_DW_AT(0x2133, GNU_addr_base, 0, GNU)
+HANDLE_DW_AT(0x2134, GNU_pubnames, 0, GNU)
+HANDLE_DW_AT(0x2135, GNU_pubtypes, 0, GNU)
+HANDLE_DW_AT(0x2136, GNU_discriminator, 0, GNU)
+// Borland extensions.
+HANDLE_DW_AT(0x3b11, BORLAND_property_read, 0, BORLAND)
+HANDLE_DW_AT(0x3b12, BORLAND_property_write, 0, BORLAND)
+HANDLE_DW_AT(0x3b13, BORLAND_property_implements, 0, BORLAND)
+HANDLE_DW_AT(0x3b14, BORLAND_property_index, 0, BORLAND)
+HANDLE_DW_AT(0x3b15, BORLAND_property_default, 0, BORLAND)
+HANDLE_DW_AT(0x3b20, BORLAND_Delphi_unit, 0, BORLAND)
+HANDLE_DW_AT(0x3b21, BORLAND_Delphi_class, 0, BORLAND)
+HANDLE_DW_AT(0x3b22, BORLAND_Delphi_record, 0, BORLAND)
+HANDLE_DW_AT(0x3b23, BORLAND_Delphi_metaclass, 0, BORLAND)
+HANDLE_DW_AT(0x3b24, BORLAND_Delphi_constructor, 0, BORLAND)
+HANDLE_DW_AT(0x3b25, BORLAND_Delphi_destructor, 0, BORLAND)
+HANDLE_DW_AT(0x3b26, BORLAND_Delphi_anonymous_method, 0, BORLAND)
+HANDLE_DW_AT(0x3b27, BORLAND_Delphi_interface, 0, BORLAND)
+HANDLE_DW_AT(0x3b28, BORLAND_Delphi_ABI, 0, BORLAND)
+HANDLE_DW_AT(0x3b29, BORLAND_Delphi_return, 0, BORLAND)
+HANDLE_DW_AT(0x3b30, BORLAND_Delphi_frameptr, 0, BORLAND)
+HANDLE_DW_AT(0x3b31, BORLAND_closure, 0, BORLAND)
+// LLVM project extensions.
+HANDLE_DW_AT(0x3e00, LLVM_include_path, 0, LLVM)
+HANDLE_DW_AT(0x3e01, LLVM_config_macros, 0, LLVM)
+HANDLE_DW_AT(0x3e02, LLVM_isysroot, 0, LLVM)
+// 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)
+HANDLE_DW_AT(0x3fe4, APPLE_block, 0, APPLE)
+HANDLE_DW_AT(0x3fe5, APPLE_major_runtime_vers, 0, APPLE)
+HANDLE_DW_AT(0x3fe6, APPLE_runtime_class, 0, APPLE)
+HANDLE_DW_AT(0x3fe7, APPLE_omit_frame_ptr, 0, APPLE)
+HANDLE_DW_AT(0x3fe8, APPLE_property_name, 0, APPLE)
+HANDLE_DW_AT(0x3fe9, APPLE_property_getter, 0, APPLE)
+HANDLE_DW_AT(0x3fea, APPLE_property_setter, 0, APPLE)
+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)
+
+// Attribute form encodings.
+HANDLE_DW_FORM(0x01, addr, 2, DWARF)
+HANDLE_DW_FORM(0x03, block2, 2, DWARF)
+HANDLE_DW_FORM(0x04, block4, 2, DWARF)
+HANDLE_DW_FORM(0x05, data2, 2, DWARF)
+HANDLE_DW_FORM(0x06, data4, 2, DWARF)
+HANDLE_DW_FORM(0x07, data8, 2, DWARF)
+HANDLE_DW_FORM(0x08, string, 2, DWARF)
+HANDLE_DW_FORM(0x09, block, 2, DWARF)
+HANDLE_DW_FORM(0x0a, block1, 2, DWARF)
+HANDLE_DW_FORM(0x0b, data1, 2, DWARF)
+HANDLE_DW_FORM(0x0c, flag, 2, DWARF)
+HANDLE_DW_FORM(0x0d, sdata, 2, DWARF)
+HANDLE_DW_FORM(0x0e, strp, 2, DWARF)
+HANDLE_DW_FORM(0x0f, udata, 2, DWARF)
+HANDLE_DW_FORM(0x10, ref_addr, 2, DWARF)
+HANDLE_DW_FORM(0x11, ref1, 2, DWARF)
+HANDLE_DW_FORM(0x12, ref2, 2, DWARF)
+HANDLE_DW_FORM(0x13, ref4, 2, DWARF)
+HANDLE_DW_FORM(0x14, ref8, 2, DWARF)
+HANDLE_DW_FORM(0x15, ref_udata, 2, DWARF)
+HANDLE_DW_FORM(0x16, indirect, 2, DWARF)
+// New in DWARF v4:
+HANDLE_DW_FORM(0x17, sec_offset, 4, DWARF)
+HANDLE_DW_FORM(0x18, exprloc, 4, DWARF)
+HANDLE_DW_FORM(0x19, flag_present, 4, DWARF)
+// This was defined out of sequence.
+HANDLE_DW_FORM(0x20, ref_sig8, 4, DWARF)
+// New in DWARF v5:
+HANDLE_DW_FORM(0x1a, strx, 5, DWARF)
+HANDLE_DW_FORM(0x1b, addrx, 5, DWARF)
+HANDLE_DW_FORM(0x1c, ref_sup4, 5, DWARF)
+HANDLE_DW_FORM(0x1d, strp_sup, 5, DWARF)
+HANDLE_DW_FORM(0x1e, data16, 5, DWARF)
+HANDLE_DW_FORM(0x1f, line_strp, 5, DWARF)
+HANDLE_DW_FORM(0x21, implicit_const, 5, DWARF)
+HANDLE_DW_FORM(0x22, loclistx, 5, DWARF)
+HANDLE_DW_FORM(0x23, rnglistx, 5, DWARF)
+HANDLE_DW_FORM(0x24, ref_sup8, 5, DWARF)
+HANDLE_DW_FORM(0x25, strx1, 5, DWARF)
+HANDLE_DW_FORM(0x26, strx2, 5, DWARF)
+HANDLE_DW_FORM(0x27, strx3, 5, DWARF)
+HANDLE_DW_FORM(0x28, strx4, 5, DWARF)
+HANDLE_DW_FORM(0x29, addrx1, 5, DWARF)
+HANDLE_DW_FORM(0x2a, addrx2, 5, DWARF)
+HANDLE_DW_FORM(0x2b, addrx3, 5, DWARF)
+HANDLE_DW_FORM(0x2c, addrx4, 5, DWARF)
+// Extensions for Fission proposal
+HANDLE_DW_FORM(0x1f01, GNU_addr_index, 0, GNU)
+HANDLE_DW_FORM(0x1f02, GNU_str_index, 0, GNU)
+// Alternate debug sections proposal (output of "dwz" tool).
+HANDLE_DW_FORM(0x1f20, GNU_ref_alt, 0, GNU)
+HANDLE_DW_FORM(0x1f21, GNU_strp_alt, 0, GNU)
+
+// DWARF Expression operators.
+HANDLE_DW_OP(0x03, addr, 2, DWARF)
+HANDLE_DW_OP(0x06, deref, 2, DWARF)
+HANDLE_DW_OP(0x08, const1u, 2, DWARF)
+HANDLE_DW_OP(0x09, const1s, 2, DWARF)
+HANDLE_DW_OP(0x0a, const2u, 2, DWARF)
+HANDLE_DW_OP(0x0b, const2s, 2, DWARF)
+HANDLE_DW_OP(0x0c, const4u, 2, DWARF)
+HANDLE_DW_OP(0x0d, const4s, 2, DWARF)
+HANDLE_DW_OP(0x0e, const8u, 2, DWARF)
+HANDLE_DW_OP(0x0f, const8s, 2, DWARF)
+HANDLE_DW_OP(0x10, constu, 2, DWARF)
+HANDLE_DW_OP(0x11, consts, 2, DWARF)
+HANDLE_DW_OP(0x12, dup, 2, DWARF)
+HANDLE_DW_OP(0x13, drop, 2, DWARF)
+HANDLE_DW_OP(0x14, over, 2, DWARF)
+HANDLE_DW_OP(0x15, pick, 2, DWARF)
+HANDLE_DW_OP(0x16, swap, 2, DWARF)
+HANDLE_DW_OP(0x17, rot, 2, DWARF)
+HANDLE_DW_OP(0x18, xderef, 2, DWARF)
+HANDLE_DW_OP(0x19, abs, 2, DWARF)
+HANDLE_DW_OP(0x1a, and, 2, DWARF)
+HANDLE_DW_OP(0x1b, div, 2, DWARF)
+HANDLE_DW_OP(0x1c, minus, 2, DWARF)
+HANDLE_DW_OP(0x1d, mod, 2, DWARF)
+HANDLE_DW_OP(0x1e, mul, 2, DWARF)
+HANDLE_DW_OP(0x1f, neg, 2, DWARF)
+HANDLE_DW_OP(0x20, not, 2, DWARF)
+HANDLE_DW_OP(0x21, or, 2, DWARF)
+HANDLE_DW_OP(0x22, plus, 2, DWARF)
+HANDLE_DW_OP(0x23, plus_uconst, 2, DWARF)
+HANDLE_DW_OP(0x24, shl, 2, DWARF)
+HANDLE_DW_OP(0x25, shr, 2, DWARF)
+HANDLE_DW_OP(0x26, shra, 2, DWARF)
+HANDLE_DW_OP(0x27, xor, 2, DWARF)
+HANDLE_DW_OP(0x28, bra, 2, DWARF)
+HANDLE_DW_OP(0x29, eq, 2, DWARF)
+HANDLE_DW_OP(0x2a, ge, 2, DWARF)
+HANDLE_DW_OP(0x2b, gt, 2, DWARF)
+HANDLE_DW_OP(0x2c, le, 2, DWARF)
+HANDLE_DW_OP(0x2d, lt, 2, DWARF)
+HANDLE_DW_OP(0x2e, ne, 2, DWARF)
+HANDLE_DW_OP(0x2f, skip, 2, DWARF)
+HANDLE_DW_OP(0x30, lit0, 2, DWARF)
+HANDLE_DW_OP(0x31, lit1, 2, DWARF)
+HANDLE_DW_OP(0x32, lit2, 2, DWARF)
+HANDLE_DW_OP(0x33, lit3, 2, DWARF)
+HANDLE_DW_OP(0x34, lit4, 2, DWARF)
+HANDLE_DW_OP(0x35, lit5, 2, DWARF)
+HANDLE_DW_OP(0x36, lit6, 2, DWARF)
+HANDLE_DW_OP(0x37, lit7, 2, DWARF)
+HANDLE_DW_OP(0x38, lit8, 2, DWARF)
+HANDLE_DW_OP(0x39, lit9, 2, DWARF)
+HANDLE_DW_OP(0x3a, lit10, 2, DWARF)
+HANDLE_DW_OP(0x3b, lit11, 2, DWARF)
+HANDLE_DW_OP(0x3c, lit12, 2, DWARF)
+HANDLE_DW_OP(0x3d, lit13, 2, DWARF)
+HANDLE_DW_OP(0x3e, lit14, 2, DWARF)
+HANDLE_DW_OP(0x3f, lit15, 2, DWARF)
+HANDLE_DW_OP(0x40, lit16, 2, DWARF)
+HANDLE_DW_OP(0x41, lit17, 2, DWARF)
+HANDLE_DW_OP(0x42, lit18, 2, DWARF)
+HANDLE_DW_OP(0x43, lit19, 2, DWARF)
+HANDLE_DW_OP(0x44, lit20, 2, DWARF)
+HANDLE_DW_OP(0x45, lit21, 2, DWARF)
+HANDLE_DW_OP(0x46, lit22, 2, DWARF)
+HANDLE_DW_OP(0x47, lit23, 2, DWARF)
+HANDLE_DW_OP(0x48, lit24, 2, DWARF)
+HANDLE_DW_OP(0x49, lit25, 2, DWARF)
+HANDLE_DW_OP(0x4a, lit26, 2, DWARF)
+HANDLE_DW_OP(0x4b, lit27, 2, DWARF)
+HANDLE_DW_OP(0x4c, lit28, 2, DWARF)
+HANDLE_DW_OP(0x4d, lit29, 2, DWARF)
+HANDLE_DW_OP(0x4e, lit30, 2, DWARF)
+HANDLE_DW_OP(0x4f, lit31, 2, DWARF)
+HANDLE_DW_OP(0x50, reg0, 2, DWARF)
+HANDLE_DW_OP(0x51, reg1, 2, DWARF)
+HANDLE_DW_OP(0x52, reg2, 2, DWARF)
+HANDLE_DW_OP(0x53, reg3, 2, DWARF)
+HANDLE_DW_OP(0x54, reg4, 2, DWARF)
+HANDLE_DW_OP(0x55, reg5, 2, DWARF)
+HANDLE_DW_OP(0x56, reg6, 2, DWARF)
+HANDLE_DW_OP(0x57, reg7, 2, DWARF)
+HANDLE_DW_OP(0x58, reg8, 2, DWARF)
+HANDLE_DW_OP(0x59, reg9, 2, DWARF)
+HANDLE_DW_OP(0x5a, reg10, 2, DWARF)
+HANDLE_DW_OP(0x5b, reg11, 2, DWARF)
+HANDLE_DW_OP(0x5c, reg12, 2, DWARF)
+HANDLE_DW_OP(0x5d, reg13, 2, DWARF)
+HANDLE_DW_OP(0x5e, reg14, 2, DWARF)
+HANDLE_DW_OP(0x5f, reg15, 2, DWARF)
+HANDLE_DW_OP(0x60, reg16, 2, DWARF)
+HANDLE_DW_OP(0x61, reg17, 2, DWARF)
+HANDLE_DW_OP(0x62, reg18, 2, DWARF)
+HANDLE_DW_OP(0x63, reg19, 2, DWARF)
+HANDLE_DW_OP(0x64, reg20, 2, DWARF)
+HANDLE_DW_OP(0x65, reg21, 2, DWARF)
+HANDLE_DW_OP(0x66, reg22, 2, DWARF)
+HANDLE_DW_OP(0x67, reg23, 2, DWARF)
+HANDLE_DW_OP(0x68, reg24, 2, DWARF)
+HANDLE_DW_OP(0x69, reg25, 2, DWARF)
+HANDLE_DW_OP(0x6a, reg26, 2, DWARF)
+HANDLE_DW_OP(0x6b, reg27, 2, DWARF)
+HANDLE_DW_OP(0x6c, reg28, 2, DWARF)
+HANDLE_DW_OP(0x6d, reg29, 2, DWARF)
+HANDLE_DW_OP(0x6e, reg30, 2, DWARF)
+HANDLE_DW_OP(0x6f, reg31, 2, DWARF)
+HANDLE_DW_OP(0x70, breg0, 2, DWARF)
+HANDLE_DW_OP(0x71, breg1, 2, DWARF)
+HANDLE_DW_OP(0x72, breg2, 2, DWARF)
+HANDLE_DW_OP(0x73, breg3, 2, DWARF)
+HANDLE_DW_OP(0x74, breg4, 2, DWARF)
+HANDLE_DW_OP(0x75, breg5, 2, DWARF)
+HANDLE_DW_OP(0x76, breg6, 2, DWARF)
+HANDLE_DW_OP(0x77, breg7, 2, DWARF)
+HANDLE_DW_OP(0x78, breg8, 2, DWARF)
+HANDLE_DW_OP(0x79, breg9, 2, DWARF)
+HANDLE_DW_OP(0x7a, breg10, 2, DWARF)
+HANDLE_DW_OP(0x7b, breg11, 2, DWARF)
+HANDLE_DW_OP(0x7c, breg12, 2, DWARF)
+HANDLE_DW_OP(0x7d, breg13, 2, DWARF)
+HANDLE_DW_OP(0x7e, breg14, 2, DWARF)
+HANDLE_DW_OP(0x7f, breg15, 2, DWARF)
+HANDLE_DW_OP(0x80, breg16, 2, DWARF)
+HANDLE_DW_OP(0x81, breg17, 2, DWARF)
+HANDLE_DW_OP(0x82, breg18, 2, DWARF)
+HANDLE_DW_OP(0x83, breg19, 2, DWARF)
+HANDLE_DW_OP(0x84, breg20, 2, DWARF)
+HANDLE_DW_OP(0x85, breg21, 2, DWARF)
+HANDLE_DW_OP(0x86, breg22, 2, DWARF)
+HANDLE_DW_OP(0x87, breg23, 2, DWARF)
+HANDLE_DW_OP(0x88, breg24, 2, DWARF)
+HANDLE_DW_OP(0x89, breg25, 2, DWARF)
+HANDLE_DW_OP(0x8a, breg26, 2, DWARF)
+HANDLE_DW_OP(0x8b, breg27, 2, DWARF)
+HANDLE_DW_OP(0x8c, breg28, 2, DWARF)
+HANDLE_DW_OP(0x8d, breg29, 2, DWARF)
+HANDLE_DW_OP(0x8e, breg30, 2, DWARF)
+HANDLE_DW_OP(0x8f, breg31, 2, DWARF)
+HANDLE_DW_OP(0x90, regx, 2, DWARF)
+HANDLE_DW_OP(0x91, fbreg, 2, DWARF)
+HANDLE_DW_OP(0x92, bregx, 2, DWARF)
+HANDLE_DW_OP(0x93, piece, 2, DWARF)
+HANDLE_DW_OP(0x94, deref_size, 2, DWARF)
+HANDLE_DW_OP(0x95, xderef_size, 2, DWARF)
+HANDLE_DW_OP(0x96, nop, 2, DWARF)
+// New in DWARF v3:
+HANDLE_DW_OP(0x97, push_object_address, 3, DWARF)
+HANDLE_DW_OP(0x98, call2, 3, DWARF)
+HANDLE_DW_OP(0x99, call4, 3, DWARF)
+HANDLE_DW_OP(0x9a, call_ref, 3, DWARF)
+HANDLE_DW_OP(0x9b, form_tls_address, 3, DWARF)
+HANDLE_DW_OP(0x9c, call_frame_cfa, 3, DWARF)
+HANDLE_DW_OP(0x9d, bit_piece, 3, DWARF)
+// New in DWARF v4:
+HANDLE_DW_OP(0x9e, implicit_value, 4, DWARF)
+HANDLE_DW_OP(0x9f, stack_value, 4, DWARF)
+// New in DWARF v5:
+HANDLE_DW_OP(0xa0, implicit_pointer, 5, DWARF)
+HANDLE_DW_OP(0xa1, addrx, 5, DWARF)
+HANDLE_DW_OP(0xa2, constx, 5, DWARF)
+HANDLE_DW_OP(0xa3, entry_value, 5, DWARF)
+HANDLE_DW_OP(0xa4, const_type, 5, DWARF)
+HANDLE_DW_OP(0xa5, regval_type, 5, DWARF)
+HANDLE_DW_OP(0xa6, deref_type, 5, DWARF)
+HANDLE_DW_OP(0xa7, xderef_type, 5, DWARF)
+HANDLE_DW_OP(0xa8, convert, 5, DWARF)
+HANDLE_DW_OP(0xa9, reinterpret, 5, DWARF)
+// Vendor extensions:
+// Extensions for GNU-style thread-local storage.
+HANDLE_DW_OP(0xe0, GNU_push_tls_address, 0, GNU)
+// Extensions for Fission proposal.
+HANDLE_DW_OP(0xfb, GNU_addr_index, 0, GNU)
+HANDLE_DW_OP(0xfc, GNU_const_index, 0, GNU)
+
+// DWARF languages.
+HANDLE_DW_LANG(0x0001, C89, 2, DWARF)
+HANDLE_DW_LANG(0x0002, C, 2, DWARF)
+HANDLE_DW_LANG(0x0003, Ada83, 2, DWARF)
+HANDLE_DW_LANG(0x0004, C_plus_plus, 2, DWARF)
+HANDLE_DW_LANG(0x0005, Cobol74, 2, DWARF)
+HANDLE_DW_LANG(0x0006, Cobol85, 2, DWARF)
+HANDLE_DW_LANG(0x0007, Fortran77, 2, DWARF)
+HANDLE_DW_LANG(0x0008, Fortran90, 2, DWARF)
+HANDLE_DW_LANG(0x0009, Pascal83, 2, DWARF)
+HANDLE_DW_LANG(0x000a, Modula2, 2, DWARF)
+// New in DWARF v3:
+HANDLE_DW_LANG(0x000b, Java, 3, DWARF)
+HANDLE_DW_LANG(0x000c, C99, 3, DWARF)
+HANDLE_DW_LANG(0x000d, Ada95, 3, DWARF)
+HANDLE_DW_LANG(0x000e, Fortran95, 3, DWARF)
+HANDLE_DW_LANG(0x000f, PLI, 3, DWARF)
+HANDLE_DW_LANG(0x0010, ObjC, 3, DWARF)
+HANDLE_DW_LANG(0x0011, ObjC_plus_plus, 3, DWARF)
+HANDLE_DW_LANG(0x0012, UPC, 3, DWARF)
+HANDLE_DW_LANG(0x0013, D, 3, DWARF)
+// New in DWARF v4:
+HANDLE_DW_LANG(0x0014, Python, 4, DWARF)
+// New in DWARF v5:
+HANDLE_DW_LANG(0x0015, OpenCL, 5, DWARF)
+HANDLE_DW_LANG(0x0016, Go, 5, DWARF)
+HANDLE_DW_LANG(0x0017, Modula3, 5, DWARF)
+HANDLE_DW_LANG(0x0018, Haskell, 5, DWARF)
+HANDLE_DW_LANG(0x0019, C_plus_plus_03, 5, DWARF)
+HANDLE_DW_LANG(0x001a, C_plus_plus_11, 5, DWARF)
+HANDLE_DW_LANG(0x001b, OCaml, 5, DWARF)
+HANDLE_DW_LANG(0x001c, Rust, 5, DWARF)
+HANDLE_DW_LANG(0x001d, C11, 5, DWARF)
+HANDLE_DW_LANG(0x001e, Swift, 5, DWARF)
+HANDLE_DW_LANG(0x001f, Julia, 5, DWARF)
+HANDLE_DW_LANG(0x0020, Dylan, 5, DWARF)
+HANDLE_DW_LANG(0x0021, C_plus_plus_14, 5, DWARF)
+HANDLE_DW_LANG(0x0022, Fortran03, 5, DWARF)
+HANDLE_DW_LANG(0x0023, Fortran08, 5, DWARF)
+HANDLE_DW_LANG(0x0024, RenderScript, 5, DWARF)
+HANDLE_DW_LANG(0x0025, BLISS, 5, DWARF)
+// Vendor extensions:
+HANDLE_DW_LANG(0x8001, Mips_Assembler, 0, MIPS)
+HANDLE_DW_LANG(0x8e57, GOOGLE_RenderScript, 0, GOOGLE)
+HANDLE_DW_LANG(0xb000, BORLAND_Delphi, 0, BORLAND)
+
+// DWARF attribute type encodings.
+HANDLE_DW_ATE(0x01, address, 2, DWARF)
+HANDLE_DW_ATE(0x02, boolean, 2, DWARF)
+HANDLE_DW_ATE(0x03, complex_float, 2, DWARF)
+HANDLE_DW_ATE(0x04, float, 2, DWARF)
+HANDLE_DW_ATE(0x05, signed, 2, DWARF)
+HANDLE_DW_ATE(0x06, signed_char, 2, DWARF)
+HANDLE_DW_ATE(0x07, unsigned, 2, DWARF)
+HANDLE_DW_ATE(0x08, unsigned_char, 2, DWARF)
+// New in DWARF v3:
+HANDLE_DW_ATE(0x09, imaginary_float, 3, DWARF)
+HANDLE_DW_ATE(0x0a, packed_decimal, 3, DWARF)
+HANDLE_DW_ATE(0x0b, numeric_string, 3, DWARF)
+HANDLE_DW_ATE(0x0c, edited, 3, DWARF)
+HANDLE_DW_ATE(0x0d, signed_fixed, 3, DWARF)
+HANDLE_DW_ATE(0x0e, unsigned_fixed, 3, DWARF)
+HANDLE_DW_ATE(0x0f, decimal_float, 3, DWARF)
+// New in DWARF v4:
+HANDLE_DW_ATE(0x10, UTF, 4, DWARF)
+// New in DWARF v5:
+HANDLE_DW_ATE(0x11, UCS, 5, DWARF)
+HANDLE_DW_ATE(0x12, ASCII, 5, DWARF)
+
+// DWARF virtuality codes.
+HANDLE_DW_VIRTUALITY(0x00, none)
+HANDLE_DW_VIRTUALITY(0x01, virtual)
+HANDLE_DW_VIRTUALITY(0x02, pure_virtual)
+
+// DWARF v5 Defaulted Member Encodings.
+HANDLE_DW_DEFAULTED(0x00, no)
+HANDLE_DW_DEFAULTED(0x01, in_class)
+HANDLE_DW_DEFAULTED(0x02, out_of_class)
+
+// DWARF calling convention codes.
+HANDLE_DW_CC(0x01, normal)
+HANDLE_DW_CC(0x02, program)
+HANDLE_DW_CC(0x03, nocall)
+// New in DWARF v5:
+HANDLE_DW_CC(0x04, pass_by_reference)
+HANDLE_DW_CC(0x05, pass_by_value)
+// Vendor extensions:
+HANDLE_DW_CC(0x41, GNU_borland_fastcall_i386)
+HANDLE_DW_CC(0xb0, BORLAND_safecall)
+HANDLE_DW_CC(0xb1, BORLAND_stdcall)
+HANDLE_DW_CC(0xb2, BORLAND_pascal)
+HANDLE_DW_CC(0xb3, BORLAND_msfastcall)
+HANDLE_DW_CC(0xb4, BORLAND_msreturn)
+HANDLE_DW_CC(0xb5, BORLAND_thiscall)
+HANDLE_DW_CC(0xb6, BORLAND_fastcall)
+HANDLE_DW_CC(0xc0, LLVM_vectorcall)
+
+// Line Number Extended Opcode Encodings
+HANDLE_DW_LNE(0x01, end_sequence)
+HANDLE_DW_LNE(0x02, set_address)
+HANDLE_DW_LNE(0x03, define_file)
+// New in DWARF v4:
+HANDLE_DW_LNE(0x04, set_discriminator)
+
+// Line Number Standard Opcode Encodings.
+HANDLE_DW_LNS(0x00, extended_op)
+HANDLE_DW_LNS(0x01, copy)
+HANDLE_DW_LNS(0x02, advance_pc)
+HANDLE_DW_LNS(0x03, advance_line)
+HANDLE_DW_LNS(0x04, set_file)
+HANDLE_DW_LNS(0x05, set_column)
+HANDLE_DW_LNS(0x06, negate_stmt)
+HANDLE_DW_LNS(0x07, set_basic_block)
+HANDLE_DW_LNS(0x08, const_add_pc)
+HANDLE_DW_LNS(0x09, fixed_advance_pc)
+// New in DWARF v3:
+HANDLE_DW_LNS(0x0a, set_prologue_end)
+HANDLE_DW_LNS(0x0b, set_epilogue_begin)
+HANDLE_DW_LNS(0x0c, set_isa)
+
+// DWARF v5 Line number header entry format.
+HANDLE_DW_LNCT(0x01, path)
+HANDLE_DW_LNCT(0x02, directory_index)
+HANDLE_DW_LNCT(0x03, timestamp)
+HANDLE_DW_LNCT(0x04, size)
+HANDLE_DW_LNCT(0x05, MD5)
+
+// DWARF v5 Macro information.
+HANDLE_DW_MACRO(0x01, define)
+HANDLE_DW_MACRO(0x02, undef)
+HANDLE_DW_MACRO(0x03, start_file)
+HANDLE_DW_MACRO(0x04, end_file)
+HANDLE_DW_MACRO(0x05, define_strp)
+HANDLE_DW_MACRO(0x06, undef_strp)
+HANDLE_DW_MACRO(0x07, import)
+HANDLE_DW_MACRO(0x08, define_sup)
+HANDLE_DW_MACRO(0x09, undef_sup)
+HANDLE_DW_MACRO(0x0a, import_sup)
+HANDLE_DW_MACRO(0x0b, define_strx)
+HANDLE_DW_MACRO(0x0c, undef_strx)
+
+// DWARF v5 Range List Entry encoding values.
+HANDLE_DW_RLE(0x00, end_of_list)
+HANDLE_DW_RLE(0x01, base_addressx)
+HANDLE_DW_RLE(0x02, startx_endx)
+HANDLE_DW_RLE(0x03, startx_length)
+HANDLE_DW_RLE(0x04, offset_pair)
+HANDLE_DW_RLE(0x05, base_address)
+HANDLE_DW_RLE(0x06, start_end)
+HANDLE_DW_RLE(0x07, start_length)
+
+// Call frame instruction encodings.
+HANDLE_DW_CFA(0x00, nop)
+HANDLE_DW_CFA(0x40, advance_loc)
+HANDLE_DW_CFA(0x80, offset)
+HANDLE_DW_CFA(0xc0, restore)
+HANDLE_DW_CFA(0x01, set_loc)
+HANDLE_DW_CFA(0x02, advance_loc1)
+HANDLE_DW_CFA(0x03, advance_loc2)
+HANDLE_DW_CFA(0x04, advance_loc4)
+HANDLE_DW_CFA(0x05, offset_extended)
+HANDLE_DW_CFA(0x06, restore_extended)
+HANDLE_DW_CFA(0x07, undefined)
+HANDLE_DW_CFA(0x08, same_value)
+HANDLE_DW_CFA(0x09, register)
+HANDLE_DW_CFA(0x0a, remember_state)
+HANDLE_DW_CFA(0x0b, restore_state)
+HANDLE_DW_CFA(0x0c, def_cfa)
+HANDLE_DW_CFA(0x0d, def_cfa_register)
+HANDLE_DW_CFA(0x0e, def_cfa_offset)
+// New in DWARF v3:
+HANDLE_DW_CFA(0x0f, def_cfa_expression)
+HANDLE_DW_CFA(0x10, expression)
+HANDLE_DW_CFA(0x11, offset_extended_sf)
+HANDLE_DW_CFA(0x12, def_cfa_sf)
+HANDLE_DW_CFA(0x13, def_cfa_offset_sf)
+HANDLE_DW_CFA(0x14, val_offset)
+HANDLE_DW_CFA(0x15, val_offset_sf)
+HANDLE_DW_CFA(0x16, val_expression)
+// Vendor extensions:
+HANDLE_DW_CFA(0x1d, MIPS_advance_loc8)
+HANDLE_DW_CFA(0x2d, GNU_window_save)
+HANDLE_DW_CFA(0x2e, GNU_args_size)
+
+// Apple Objective-C Property Attributes.
+// Keep this list in sync with clang's DeclSpec.h ObjCPropertyAttributeKind!
+HANDLE_DW_APPLE_PROPERTY(0x01, readonly)
+HANDLE_DW_APPLE_PROPERTY(0x02, getter)
+HANDLE_DW_APPLE_PROPERTY(0x04, assign)
+HANDLE_DW_APPLE_PROPERTY(0x08, readwrite)
+HANDLE_DW_APPLE_PROPERTY(0x10, retain)
+HANDLE_DW_APPLE_PROPERTY(0x20, copy)
+HANDLE_DW_APPLE_PROPERTY(0x40, nonatomic)
+HANDLE_DW_APPLE_PROPERTY(0x80, setter)
+HANDLE_DW_APPLE_PROPERTY(0x100, atomic)
+HANDLE_DW_APPLE_PROPERTY(0x200, weak)
+HANDLE_DW_APPLE_PROPERTY(0x400, strong)
+HANDLE_DW_APPLE_PROPERTY(0x800, unsafe_unretained)
+HANDLE_DW_APPLE_PROPERTY(0x1000, nullability)
+HANDLE_DW_APPLE_PROPERTY(0x2000, null_resettable)
+HANDLE_DW_APPLE_PROPERTY(0x4000, class)
+
+// DWARF v5 Unit Types.
+HANDLE_DW_UT(0x01, compile)
+HANDLE_DW_UT(0x02, type)
+HANDLE_DW_UT(0x03, partial)
+HANDLE_DW_UT(0x04, skeleton)
+HANDLE_DW_UT(0x05, split_compile)
+HANDLE_DW_UT(0x06, split_type)
+
+#undef HANDLE_DW_TAG
+#undef HANDLE_DW_AT
+#undef HANDLE_DW_FORM
+#undef HANDLE_DW_OP
+#undef HANDLE_DW_LANG
+#undef HANDLE_DW_ATE
+#undef HANDLE_DW_VIRTUALITY
+#undef HANDLE_DW_DEFAULTED
+#undef HANDLE_DW_CC
+#undef HANDLE_DW_LNS
+#undef HANDLE_DW_LNE
+#undef HANDLE_DW_LNCT
+#undef HANDLE_DW_MACRO
+#undef HANDLE_DW_RLE
+#undef HANDLE_DW_CFA
+#undef HANDLE_DW_APPLE_PROPERTY
+#undef HANDLE_DW_UT
diff --git a/contrib/llvm/include/llvm/Support/Dwarf.h b/contrib/llvm/include/llvm/BinaryFormat/Dwarf.h
index 8336b9d..80456a0 100644
--- a/contrib/llvm/include/llvm/Support/Dwarf.h
+++ b/contrib/llvm/include/llvm/BinaryFormat/Dwarf.h
@@ -1,4 +1,4 @@
-//===-- llvm/Support/Dwarf.h ---Dwarf Constants------------------*- C++ -*-===//
+//===-- llvm/BinaryFormat/Dwarf.h ---Dwarf Constants-------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -17,8 +17,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SUPPORT_DWARF_H
-#define LLVM_SUPPORT_DWARF_H
+#ifndef LLVM_BINARYFORMAT_DWARF_H
+#define LLVM_BINARYFORMAT_DWARF_H
#include "llvm/Support/Compiler.h"
#include "llvm/Support/DataTypes.h"
@@ -29,7 +29,7 @@ class StringRef;
namespace dwarf {
//===----------------------------------------------------------------------===//
-// Dwarf constants as gleaned from the DWARF Debugging Information Format V.4
+// DWARF constants as gleaned from the DWARF Debugging Information Format V.5
// reference manual http://www.dwarfstd.org/.
//
@@ -37,7 +37,7 @@ namespace dwarf {
// enumeration base type.
enum LLVMConstants : uint32_t {
- // LLVM mock tags (see also llvm/Support/Dwarf.def).
+ // LLVM mock tags (see also llvm/BinaryFormat/Dwarf.def).
DW_TAG_invalid = ~0U, // Tag for invalid results.
DW_VIRTUALITY_invalid = ~0U, // Virtuality for invalid results.
DW_MACINFO_invalid = ~0U, // Macinfo type for invalid results.
@@ -46,7 +46,15 @@ enum LLVMConstants : uint32_t {
DWARF_VERSION = 4, // Default dwarf version we output.
DW_PUBTYPES_VERSION = 2, // Section version number for .debug_pubtypes.
DW_PUBNAMES_VERSION = 2, // Section version number for .debug_pubnames.
- DW_ARANGES_VERSION = 2 // Section version number for .debug_aranges.
+ DW_ARANGES_VERSION = 2, // Section version number for .debug_aranges.
+ // Identifiers we use to distinguish vendor extensions.
+ DWARF_VENDOR_DWARF = 0, // Defined in v2 or later of the DWARF standard.
+ DWARF_VENDOR_APPLE = 1,
+ DWARF_VENDOR_BORLAND = 2,
+ DWARF_VENDOR_GNU = 3,
+ DWARF_VENDOR_GOOGLE = 4,
+ DWARF_VENDOR_LLVM = 5,
+ DWARF_VENDOR_MIPS = 6
};
// Special ID values that distinguish a CIE from a FDE in DWARF CFI.
@@ -54,9 +62,12 @@ enum LLVMConstants : uint32_t {
const uint32_t DW_CIE_ID = UINT32_MAX;
const uint64_t DW64_CIE_ID = UINT64_MAX;
+// Identifier of an invalid DIE offset in the .debug_info section.
+const uint32_t DW_INVALID_OFFSET = UINT32_MAX;
+
enum Tag : uint16_t {
-#define HANDLE_DW_TAG(ID, NAME) DW_TAG_##NAME = ID,
-#include "llvm/Support/Dwarf.def"
+#define HANDLE_DW_TAG(ID, NAME, VERSION, VENDOR) DW_TAG_##NAME = ID,
+#include "llvm/BinaryFormat/Dwarf.def"
DW_TAG_lo_user = 0x4080,
DW_TAG_hi_user = 0xffff,
DW_TAG_user_base = 0x1000 // Recommended base for user tags.
@@ -92,29 +103,29 @@ inline bool isType(Tag T) {
/// Attributes.
enum Attribute : uint16_t {
-#define HANDLE_DW_AT(ID, NAME) DW_AT_##NAME = ID,
-#include "llvm/Support/Dwarf.def"
+#define HANDLE_DW_AT(ID, NAME, VERSION, VENDOR) DW_AT_##NAME = ID,
+#include "llvm/BinaryFormat/Dwarf.def"
DW_AT_lo_user = 0x2000,
DW_AT_hi_user = 0x3fff,
};
enum Form : uint16_t {
-#define HANDLE_DW_FORM(ID, NAME) DW_FORM_##NAME = ID,
-#include "llvm/Support/Dwarf.def"
- DW_FORM_lo_user = 0x1f00, ///< Not specified by DWARF.
+#define HANDLE_DW_FORM(ID, NAME, VERSION, VENDOR) DW_FORM_##NAME = ID,
+#include "llvm/BinaryFormat/Dwarf.def"
+ DW_FORM_lo_user = 0x1f00, ///< Not specified by DWARF.
};
enum LocationAtom {
-#define HANDLE_DW_OP(ID, NAME) DW_OP_##NAME = ID,
-#include "llvm/Support/Dwarf.def"
+#define HANDLE_DW_OP(ID, NAME, VERSION, VENDOR) DW_OP_##NAME = ID,
+#include "llvm/BinaryFormat/Dwarf.def"
DW_OP_lo_user = 0xe0,
DW_OP_hi_user = 0xff,
DW_OP_LLVM_fragment = 0x1000 ///< Only used in LLVM metadata.
};
enum TypeKind {
-#define HANDLE_DW_ATE(ID, NAME) DW_ATE_##NAME = ID,
-#include "llvm/Support/Dwarf.def"
+#define HANDLE_DW_ATE(ID, NAME, VERSION, VENDOR) DW_ATE_##NAME = ID,
+#include "llvm/BinaryFormat/Dwarf.def"
DW_ATE_lo_user = 0x80,
DW_ATE_hi_user = 0xff
};
@@ -153,19 +164,19 @@ enum VisibilityAttribute {
enum VirtualityAttribute {
#define HANDLE_DW_VIRTUALITY(ID, NAME) DW_VIRTUALITY_##NAME = ID,
-#include "llvm/Support/Dwarf.def"
+#include "llvm/BinaryFormat/Dwarf.def"
DW_VIRTUALITY_max = 0x02
};
enum DefaultedMemberAttribute {
#define HANDLE_DW_DEFAULTED(ID, NAME) DW_DEFAULTED_##NAME = ID,
-#include "llvm/Support/Dwarf.def"
+#include "llvm/BinaryFormat/Dwarf.def"
DW_DEFAULTED_max = 0x02
};
enum SourceLanguage {
-#define HANDLE_DW_LANG(ID, NAME) DW_LANG_##NAME = ID,
-#include "llvm/Support/Dwarf.def"
+#define HANDLE_DW_LANG(ID, NAME, VERSION, VENDOR) DW_LANG_##NAME = ID,
+#include "llvm/BinaryFormat/Dwarf.def"
DW_LANG_lo_user = 0x8000,
DW_LANG_hi_user = 0xffff
};
@@ -179,9 +190,9 @@ enum CaseSensitivity {
};
enum CallingConvention {
- // Calling convention codes
+// Calling convention codes
#define HANDLE_DW_CC(ID, NAME) DW_CC_##NAME = ID,
-#include "llvm/Support/Dwarf.def"
+#include "llvm/BinaryFormat/Dwarf.def"
DW_CC_lo_user = 0x40,
DW_CC_hi_user = 0xff
};
@@ -209,20 +220,20 @@ enum DiscriminantList {
/// Line Number Standard Opcode Encodings.
enum LineNumberOps : uint8_t {
#define HANDLE_DW_LNS(ID, NAME) DW_LNS_##NAME = ID,
-#include "llvm/Support/Dwarf.def"
+#include "llvm/BinaryFormat/Dwarf.def"
};
/// Line Number Extended Opcode Encodings.
enum LineNumberExtendedOps {
#define HANDLE_DW_LNE(ID, NAME) DW_LNE_##NAME = ID,
-#include "llvm/Support/Dwarf.def"
+#include "llvm/BinaryFormat/Dwarf.def"
DW_LNE_lo_user = 0x80,
DW_LNE_hi_user = 0xff
};
-enum LinerNumberEntryFormat {
-#define HANDLE_DW_LNCT(ID, NAME) DW_DEFAULTED_##NAME = ID,
-#include "llvm/Support/Dwarf.def"
+enum LineNumberEntryFormat {
+#define HANDLE_DW_LNCT(ID, NAME) DW_LNCT_##NAME = ID,
+#include "llvm/BinaryFormat/Dwarf.def"
DW_LNCT_lo_user = 0x2000,
DW_LNCT_hi_user = 0x3fff,
};
@@ -239,7 +250,7 @@ enum MacinfoRecordType {
/// DWARF v5 macro information entry type encodings.
enum MacroEntryType {
#define HANDLE_DW_MACRO(ID, NAME) DW_MACRO_##NAME = ID,
-#include "llvm/Support/Dwarf.def"
+#include "llvm/BinaryFormat/Dwarf.def"
DW_MACRO_lo_user = 0xe0,
DW_MACRO_hi_user = 0xff
};
@@ -247,14 +258,13 @@ enum MacroEntryType {
/// DWARF v5 range list entry encoding values.
enum RangeListEntries {
#define HANDLE_DW_RLE(ID, NAME) DW_RLE_##NAME = ID,
-#include "llvm/Support/Dwarf.def"
+#include "llvm/BinaryFormat/Dwarf.def"
};
-
/// Call frame instruction encodings.
enum CallFrameInfo {
#define HANDLE_DW_CFA(ID, NAME) DW_CFA_##NAME = ID,
-#include "llvm/Support/Dwarf.def"
+#include "llvm/BinaryFormat/Dwarf.def"
DW_CFA_extended = 0x00,
DW_CFA_lo_user = 0x1c,
@@ -302,10 +312,18 @@ enum LocationListEntry : unsigned char {
/// Keep this list in sync with clang's DeclSpec.h ObjCPropertyAttributeKind!
enum ApplePropertyAttributes {
#define HANDLE_DW_APPLE_PROPERTY(ID, NAME) DW_APPLE_PROPERTY_##NAME = ID,
-#include "llvm/Support/Dwarf.def"
+#include "llvm/BinaryFormat/Dwarf.def"
+};
+
+/// Constants for unit types in DWARF v5.
+enum UnitType : unsigned char {
+#define HANDLE_DW_UT(ID, NAME) DW_UT_##NAME = ID,
+#include "llvm/BinaryFormat/Dwarf.def"
+ DW_UT_lo_user = 0x80,
+ DW_UT_hi_user = 0xff
};
-// Constants for the DWARF5 Accelerator Table Proposal
+// Constants for the DWARF v5 Accelerator Table Proposal
enum AcceleratorTable {
// Data layout descriptors.
DW_ATOM_null = 0u, // Marker as the end of a list of atoms.
@@ -339,10 +357,7 @@ enum GDBIndexEntryKind {
GIEK_UNUSED7
};
-enum GDBIndexEntryLinkage {
- GIEL_EXTERNAL,
- GIEL_STATIC
-};
+enum GDBIndexEntryLinkage { GIEL_EXTERNAL, GIEL_STATIC };
/// \defgroup DwarfConstantsDumping Dwarf constants dumping functions
///
@@ -373,6 +388,7 @@ StringRef LNExtendedString(unsigned Encoding);
StringRef MacinfoString(unsigned Encoding);
StringRef CallFrameString(unsigned Encoding);
StringRef ApplePropertyString(unsigned);
+StringRef UnitTypeString(unsigned);
StringRef AtomTypeString(unsigned Atom);
StringRef GDBIndexEntryKindString(GDBIndexEntryKind Kind);
StringRef GDBIndexEntryLinkageString(GDBIndexEntryLinkage Linkage);
@@ -397,6 +413,40 @@ unsigned getAttributeEncoding(StringRef EncodingString);
unsigned getMacinfo(StringRef MacinfoString);
/// @}
+/// \defgroup DwarfConstantsVersioning Dwarf version for constants
+///
+/// For constants defined by DWARF, returns the DWARF version when the constant
+/// was first defined. For vendor extensions, if there is a version-related
+/// policy for when to emit it, returns a version number for that policy.
+/// Otherwise returns 0.
+///
+/// @{
+unsigned TagVersion(Tag T);
+unsigned AttributeVersion(Attribute A);
+unsigned FormVersion(Form F);
+unsigned OperationVersion(LocationAtom O);
+unsigned AttributeEncodingVersion(TypeKind E);
+unsigned LanguageVersion(SourceLanguage L);
+/// @}
+
+/// \defgroup DwarfConstantsVendor Dwarf "vendor" for constants
+///
+/// These functions return an identifier describing "who" defined the constant,
+/// either the DWARF standard itself or the vendor who defined the extension.
+///
+/// @{
+unsigned TagVendor(Tag T);
+unsigned AttributeVendor(Attribute A);
+unsigned FormVendor(Form F);
+unsigned OperationVendor(LocationAtom O);
+unsigned AttributeEncodingVendor(TypeKind E);
+unsigned LanguageVendor(SourceLanguage L);
+/// @}
+
+/// Tells whether the specified form is defined in the specified version,
+/// or is an extension if extensions are allowed.
+bool isValidFormForVersion(Form F, unsigned Version, bool ExtensionsOk = true);
+
/// \brief Returns the symbolic string representing Val when used as a value
/// for attribute Attr.
StringRef AttributeValueString(uint16_t Attr, unsigned Val);
@@ -419,8 +469,8 @@ struct PubIndexEntryDescriptor {
/* implicit */ PubIndexEntryDescriptor(GDBIndexEntryKind Kind)
: Kind(Kind), Linkage(GIEL_EXTERNAL) {}
explicit PubIndexEntryDescriptor(uint8_t Value)
- : Kind(static_cast<GDBIndexEntryKind>((Value & KIND_MASK) >>
- KIND_OFFSET)),
+ : Kind(
+ static_cast<GDBIndexEntryKind>((Value & KIND_MASK) >> KIND_OFFSET)),
Linkage(static_cast<GDBIndexEntryLinkage>((Value & LINKAGE_MASK) >>
LINKAGE_OFFSET)) {}
uint8_t toBits() const {
@@ -437,7 +487,7 @@ private:
};
/// Constants that define the DWARF format as 32 or 64 bit.
-enum DwarfFormat { DWARF32, DWARF64 };
+enum DwarfFormat : uint8_t { DWARF32, DWARF64 };
} // End of namespace dwarf
diff --git a/contrib/llvm/include/llvm/Support/ELF.h b/contrib/llvm/include/llvm/BinaryFormat/ELF.h
index 3ea4da8..a4450ee 100644
--- a/contrib/llvm/include/llvm/Support/ELF.h
+++ b/contrib/llvm/include/llvm/BinaryFormat/ELF.h
@@ -1,4 +1,4 @@
-//===-- llvm/Support/ELF.h - ELF constants and data structures --*- C++ -*-===//
+//===- llvm/BinaryFormat/ELF.h - ELF constants and structures ---*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -17,30 +17,28 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SUPPORT_ELF_H
-#define LLVM_SUPPORT_ELF_H
+#ifndef LLVM_BINARYFORMAT_ELF_H
+#define LLVM_BINARYFORMAT_ELF_H
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/DataTypes.h"
+#include <cstdint>
#include <cstring>
namespace llvm {
-
namespace ELF {
-typedef uint32_t Elf32_Addr; // Program address
-typedef uint32_t Elf32_Off; // File offset
-typedef uint16_t Elf32_Half;
-typedef uint32_t Elf32_Word;
-typedef int32_t Elf32_Sword;
+using Elf32_Addr = uint32_t; // Program address
+using Elf32_Off = uint32_t; // File offset
+using Elf32_Half = uint16_t;
+using Elf32_Word = uint32_t;
+using Elf32_Sword = int32_t;
-typedef uint64_t Elf64_Addr;
-typedef uint64_t Elf64_Off;
-typedef uint16_t Elf64_Half;
-typedef uint32_t Elf64_Word;
-typedef int32_t Elf64_Sword;
-typedef uint64_t Elf64_Xword;
-typedef int64_t Elf64_Sxword;
+using Elf64_Addr = uint64_t;
+using Elf64_Off = uint64_t;
+using Elf64_Half = uint16_t;
+using Elf64_Word = uint32_t;
+using Elf64_Sword = int32_t;
+using Elf64_Xword = uint64_t;
+using Elf64_Sxword = int64_t;
// Object file magic string.
static const char ElfMagic[] = {0x7f, 'E', 'L', 'F', '\0'};
@@ -75,9 +73,11 @@ struct Elf32_Ehdr {
Elf32_Half e_shentsize; // Size of an entry in the section header table
Elf32_Half e_shnum; // Number of entries in the section header table
Elf32_Half e_shstrndx; // Sect hdr table index of sect name string table
+
bool checkMagic() const {
return (memcmp(e_ident, ElfMagic, strlen(ElfMagic))) == 0;
}
+
unsigned char getFileClass() const { return e_ident[EI_CLASS]; }
unsigned char getDataEncoding() const { return e_ident[EI_DATA]; }
};
@@ -99,9 +99,11 @@ struct Elf64_Ehdr {
Elf64_Half e_shentsize;
Elf64_Half e_shnum;
Elf64_Half e_shstrndx;
+
bool checkMagic() const {
return (memcmp(e_ident, ElfMagic, strlen(ElfMagic))) == 0;
}
+
unsigned char getFileClass() const { return e_ident[EI_CLASS]; }
unsigned char getDataEncoding() const { return e_ident[EI_DATA]; }
};
@@ -556,6 +558,7 @@ enum {
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
// Highest ISA version flags
EF_HEXAGON_ISA_MACH = 0x00000000, // Same as specified in bits[11:0]
@@ -566,6 +569,7 @@ enum {
EF_HEXAGON_ISA_V5 = 0x00000040, // Hexagon V5 ISA
EF_HEXAGON_ISA_V55 = 0x00000050, // Hexagon V55 ISA
EF_HEXAGON_ISA_V60 = 0x00000060, // Hexagon V60 ISA
+ EF_HEXAGON_ISA_V62 = 0x00000062, // Hexagon V62 ISA
};
// Hexagon-specific section indexes for common small data
@@ -681,6 +685,7 @@ enum : unsigned {
SHT_GROUP = 17, // Section group.
SHT_SYMTAB_SHNDX = 18, // Indices for SHN_XINDEX entries.
SHT_LOOS = 0x60000000, // Lowest operating system-specific type.
+ SHT_LLVM_ODRTAB = 0x6fff4c00, // LLVM ODR table.
SHT_GNU_ATTRIBUTES = 0x6ffffff5, // Object attributes.
SHT_GNU_HASH = 0x6ffffff6, // GNU-style hash table.
SHT_GNU_verdef = 0x6ffffffd, // GNU version definitions.
@@ -703,6 +708,7 @@ enum : unsigned {
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_HIPROC = 0x7fffffff, // Highest processor arch-specific type.
@@ -751,21 +757,21 @@ enum : unsigned {
// Start of target-specific flags.
- /// XCORE_SHF_CP_SECTION - All sections with the "c" flag are grouped
- /// together by the linker to form the constant pool and the cp register is
- /// set to the start of the constant pool by the boot code.
- XCORE_SHF_CP_SECTION = 0x800U,
-
- /// XCORE_SHF_DP_SECTION - All sections with the "d" flag are grouped
- /// together by the linker to form the data section and the dp register is
- /// set to the start of the section by the boot code.
- XCORE_SHF_DP_SECTION = 0x1000U,
-
SHF_MASKOS = 0x0ff00000,
// Bits indicating processor-specific flags.
SHF_MASKPROC = 0xf0000000,
+ /// All sections with the "d" flag are grouped together by the linker to form
+ /// the data section and the dp register is set to the start of the section by
+ /// the boot code.
+ XCORE_SHF_DP_SECTION = 0x10000000,
+
+ /// All sections with the "c" flag are grouped together by the linker to form
+ /// the constant pool and the cp register is set to the start of the constant
+ /// pool by the boot code.
+ XCORE_SHF_CP_SECTION = 0x20000000,
+
// If an object file section does not have this flag set, then it may not hold
// more than 2GB and can be freely referred to in objects using smaller code
// models. Otherwise, only objects using larger code models can refer to them.
@@ -805,12 +811,7 @@ enum : unsigned {
SHF_MIPS_STRING = 0x80000000,
// Make code section unreadable when in execute-only mode
- SHF_ARM_PURECODE = 0x20000000,
-
- SHF_AMDGPU_HSA_GLOBAL = 0x00100000,
- SHF_AMDGPU_HSA_READONLY = 0x00200000,
- SHF_AMDGPU_HSA_CODE = 0x00400000,
- SHF_AMDGPU_HSA_AGENT = 0x00800000
+ SHF_ARM_PURECODE = 0x20000000
};
// Section Group Flags
@@ -894,9 +895,7 @@ enum {
STT_HIPROC = 15, // Highest processor-specific symbol type
// AMDGPU symbol types
- STT_AMDGPU_HSA_KERNEL = 10,
- STT_AMDGPU_HSA_INDIRECT_FUNCTION = 11,
- STT_AMDGPU_HSA_METADATA = 12
+ STT_AMDGPU_HSA_KERNEL = 10
};
enum {
@@ -1047,12 +1046,6 @@ enum {
PT_MIPS_OPTIONS = 0x70000002, // Options segment.
PT_MIPS_ABIFLAGS = 0x70000003, // Abiflags segment.
- // AMDGPU program header types.
- PT_AMDGPU_HSA_LOAD_GLOBAL_PROGRAM = 0x60000000,
- PT_AMDGPU_HSA_LOAD_GLOBAL_AGENT = 0x60000001,
- PT_AMDGPU_HSA_LOAD_READONLY_AGENT = 0x60000002,
- PT_AMDGPU_HSA_LOAD_CODE_AGENT = 0x60000003,
-
// WebAssembly program header types.
PT_WEBASSEMBLY_FUNCTIONS = PT_LOPROC + 0, // Function definitions.
};
@@ -1312,6 +1305,19 @@ enum { VER_NEED_NONE = 0, VER_NEED_CURRENT = 1 };
// SHT_NOTE section types
enum {
+ NT_FREEBSD_THRMISC = 7,
+ NT_FREEBSD_PROCSTAT_PROC = 8,
+ NT_FREEBSD_PROCSTAT_FILES = 9,
+ NT_FREEBSD_PROCSTAT_VMMAP = 10,
+ NT_FREEBSD_PROCSTAT_GROUPS = 11,
+ NT_FREEBSD_PROCSTAT_UMASK = 12,
+ NT_FREEBSD_PROCSTAT_RLIMIT = 13,
+ NT_FREEBSD_PROCSTAT_OSREL = 14,
+ NT_FREEBSD_PROCSTAT_PSSTRINGS = 15,
+ NT_FREEBSD_PROCSTAT_AUXV = 16,
+};
+
+enum {
NT_GNU_ABI_TAG = 1,
NT_GNU_HWCAP = 2,
NT_GNU_BUILD_ID = 3,
@@ -1353,7 +1359,6 @@ enum {
};
} // end namespace ELF
-
} // end namespace llvm
-#endif
+#endif // LLVM_BINARYFORMAT_ELF_H
diff --git a/contrib/llvm/include/llvm/Support/ELFRelocs/AArch64.def b/contrib/llvm/include/llvm/BinaryFormat/ELFRelocs/AArch64.def
index c21df07..4afcd7d 100644
--- a/contrib/llvm/include/llvm/Support/ELFRelocs/AArch64.def
+++ b/contrib/llvm/include/llvm/BinaryFormat/ELFRelocs/AArch64.def
@@ -109,8 +109,8 @@ ELF_RELOC(R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC, 0x22f)
ELF_RELOC(R_AARCH64_TLSDESC_LD_PREL19, 0x230)
ELF_RELOC(R_AARCH64_TLSDESC_ADR_PREL21, 0x231)
ELF_RELOC(R_AARCH64_TLSDESC_ADR_PAGE21, 0x232)
-ELF_RELOC(R_AARCH64_TLSDESC_LD64_LO12_NC, 0x233)
-ELF_RELOC(R_AARCH64_TLSDESC_ADD_LO12_NC, 0x234)
+ELF_RELOC(R_AARCH64_TLSDESC_LD64_LO12, 0x233)
+ELF_RELOC(R_AARCH64_TLSDESC_ADD_LO12, 0x234)
ELF_RELOC(R_AARCH64_TLSDESC_OFF_G1, 0x235)
ELF_RELOC(R_AARCH64_TLSDESC_OFF_G0_NC, 0x236)
ELF_RELOC(R_AARCH64_TLSDESC_LDR, 0x237)
@@ -144,21 +144,28 @@ ELF_RELOC(R_AARCH64_P32_ADR_PREL_LO21, 0x00a)
ELF_RELOC(R_AARCH64_P32_ADR_PREL_PG_HI21, 0x00b)
ELF_RELOC(R_AARCH64_P32_ADD_ABS_LO12_NC, 0x00c)
ELF_RELOC(R_AARCH64_P32_LDST8_ABS_LO12_NC, 0x00d)
+ELF_RELOC(R_AARCH64_P32_LDST16_ABS_LO12_NC, 0x00e)
+ELF_RELOC(R_AARCH64_P32_LDST32_ABS_LO12_NC, 0x00f)
+ELF_RELOC(R_AARCH64_P32_LDST64_ABS_LO12_NC, 0x010)
+ELF_RELOC(R_AARCH64_P32_LDST128_ABS_LO12_NC, 0x011)
ELF_RELOC(R_AARCH64_P32_TSTBR14, 0x012)
ELF_RELOC(R_AARCH64_P32_CONDBR19, 0x013)
ELF_RELOC(R_AARCH64_P32_JUMP26, 0x014)
ELF_RELOC(R_AARCH64_P32_CALL26, 0x015)
-ELF_RELOC(R_AARCH64_P32_LDST16_ABS_LO12_NC, 0x00e)
-ELF_RELOC(R_AARCH64_P32_LDST32_ABS_LO12_NC, 0x00f)
-ELF_RELOC(R_AARCH64_P32_LDST64_ABS_LO12_NC, 0x010)
ELF_RELOC(R_AARCH64_P32_MOVW_PREL_G0, 0x016)
ELF_RELOC(R_AARCH64_P32_MOVW_PREL_G0_NC, 0x017)
ELF_RELOC(R_AARCH64_P32_MOVW_PREL_G1, 0x018)
-ELF_RELOC(R_AARCH64_P32_LDST128_ABS_LO12_NC, 0x011)
ELF_RELOC(R_AARCH64_P32_GOT_LD_PREL19, 0x019)
ELF_RELOC(R_AARCH64_P32_ADR_GOT_PAGE, 0x01a)
-ELF_RELOC(R_AARCH64_P32_LD64_GOT_LO12_NC, 0x01b)
+ELF_RELOC(R_AARCH64_P32_LD32_GOT_LO12_NC, 0x01b)
ELF_RELOC(R_AARCH64_P32_LD32_GOTPAGE_LO14, 0x01c)
+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)
+ELF_RELOC(R_AARCH64_P32_TLSLD_ADR_PREL21, 0x053)
+ELF_RELOC(R_AARCH64_P32_TLSLD_ADR_PAGE21, 0x054)
+ELF_RELOC(R_AARCH64_P32_TLSLD_ADD_LO12_NC, 0x055)
+ELF_RELOC(R_AARCH64_P32_TLSLD_LD_PREL19, 0x056)
ELF_RELOC(R_AARCH64_P32_TLSLD_MOVW_DTPREL_G1, 0x057)
ELF_RELOC(R_AARCH64_P32_TLSLD_MOVW_DTPREL_G0, 0x058)
ELF_RELOC(R_AARCH64_P32_TLSLD_MOVW_DTPREL_G0_NC, 0x059)
@@ -173,6 +180,8 @@ ELF_RELOC(R_AARCH64_P32_TLSLD_LDST32_DTPREL_LO12, 0x061)
ELF_RELOC(R_AARCH64_P32_TLSLD_LDST32_DTPREL_LO12_NC, 0x062)
ELF_RELOC(R_AARCH64_P32_TLSLD_LDST64_DTPREL_LO12, 0x063)
ELF_RELOC(R_AARCH64_P32_TLSLD_LDST64_DTPREL_LO12_NC, 0x064)
+ELF_RELOC(R_AARCH64_P32_TLSLD_LDST128_DTPREL_LO12, 0x065)
+ELF_RELOC(R_AARCH64_P32_TLSLD_LDST128_DTPREL_LO12_NC,0x066)
ELF_RELOC(R_AARCH64_P32_TLSIE_ADR_GOTTPREL_PAGE21, 0x067)
ELF_RELOC(R_AARCH64_P32_TLSIE_LD32_GOTTPREL_LO12_NC, 0x068)
ELF_RELOC(R_AARCH64_P32_TLSIE_LD_GOTTPREL_PREL19, 0x069)
@@ -190,12 +199,20 @@ ELF_RELOC(R_AARCH64_P32_TLSLE_LDST32_TPREL_LO12, 0x074)
ELF_RELOC(R_AARCH64_P32_TLSLE_LDST32_TPREL_LO12_NC, 0x075)
ELF_RELOC(R_AARCH64_P32_TLSLE_LDST64_TPREL_LO12, 0x076)
ELF_RELOC(R_AARCH64_P32_TLSLE_LDST64_TPREL_LO12_NC, 0x077)
-ELF_RELOC(R_AARCH64_P32_TLSDESC_ADR_PAGE21, 0x051)
-ELF_RELOC(R_AARCH64_P32_TLSDESC_LD32_LO12_NC, 0x07d)
-ELF_RELOC(R_AARCH64_P32_TLSDESC_ADD_LO12_NC, 0x034)
+ELF_RELOC(R_AARCH64_P32_TLSLE_LDST128_TPREL_LO12, 0x078)
+ELF_RELOC(R_AARCH64_P32_TLSLE_LDST128_TPREL_LO12_NC, 0x079)
+ELF_RELOC(R_AARCH64_P32_TLSDESC_LD_PREL19, 0x07a)
+ELF_RELOC(R_AARCH64_P32_TLSDESC_ADR_PREL21, 0x07b)
+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)
ELF_RELOC(R_AARCH64_P32_COPY, 0x0b4)
ELF_RELOC(R_AARCH64_P32_GLOB_DAT, 0x0b5)
ELF_RELOC(R_AARCH64_P32_JUMP_SLOT, 0x0b6)
ELF_RELOC(R_AARCH64_P32_RELATIVE, 0x0b7)
+ELF_RELOC(R_AARCH64_P32_TLS_DTPREL, 0x0b8)
+ELF_RELOC(R_AARCH64_P32_TLS_DTPMOD, 0x0b9)
+ELF_RELOC(R_AARCH64_P32_TLS_TPREL, 0x0ba)
+ELF_RELOC(R_AARCH64_P32_TLSDESC, 0x0bb)
ELF_RELOC(R_AARCH64_P32_IRELATIVE, 0x0bc)
diff --git a/contrib/llvm/include/llvm/Support/ELFRelocs/AMDGPU.def b/contrib/llvm/include/llvm/BinaryFormat/ELFRelocs/AMDGPU.def
index c66f88d1..c66f88d1 100644
--- a/contrib/llvm/include/llvm/Support/ELFRelocs/AMDGPU.def
+++ b/contrib/llvm/include/llvm/BinaryFormat/ELFRelocs/AMDGPU.def
diff --git a/contrib/llvm/include/llvm/Support/ELFRelocs/ARM.def b/contrib/llvm/include/llvm/BinaryFormat/ELFRelocs/ARM.def
index 730fc5b..730fc5b 100644
--- a/contrib/llvm/include/llvm/Support/ELFRelocs/ARM.def
+++ b/contrib/llvm/include/llvm/BinaryFormat/ELFRelocs/ARM.def
diff --git a/contrib/llvm/include/llvm/Support/ELFRelocs/AVR.def b/contrib/llvm/include/llvm/BinaryFormat/ELFRelocs/AVR.def
index 5692d6c..5692d6c 100644
--- a/contrib/llvm/include/llvm/Support/ELFRelocs/AVR.def
+++ b/contrib/llvm/include/llvm/BinaryFormat/ELFRelocs/AVR.def
diff --git a/contrib/llvm/include/llvm/Support/ELFRelocs/BPF.def b/contrib/llvm/include/llvm/BinaryFormat/ELFRelocs/BPF.def
index 5dd7f70..5dd7f70 100644
--- a/contrib/llvm/include/llvm/Support/ELFRelocs/BPF.def
+++ b/contrib/llvm/include/llvm/BinaryFormat/ELFRelocs/BPF.def
diff --git a/contrib/llvm/include/llvm/Support/ELFRelocs/Hexagon.def b/contrib/llvm/include/llvm/BinaryFormat/ELFRelocs/Hexagon.def
index 74e1d40..5021e2b 100644
--- a/contrib/llvm/include/llvm/Support/ELFRelocs/Hexagon.def
+++ b/contrib/llvm/include/llvm/BinaryFormat/ELFRelocs/Hexagon.def
@@ -99,3 +99,8 @@ ELF_RELOC(R_HEX_LD_GOT_32_6_X, 91)
ELF_RELOC(R_HEX_LD_GOT_16_X, 92)
ELF_RELOC(R_HEX_LD_GOT_11_X, 93)
ELF_RELOC(R_HEX_23_REG, 94)
+ELF_RELOC(R_HEX_GD_PLT_B22_PCREL_X, 95)
+ELF_RELOC(R_HEX_GD_PLT_B32_PCREL_X, 96)
+ELF_RELOC(R_HEX_LD_PLT_B22_PCREL_X, 97)
+ELF_RELOC(R_HEX_LD_PLT_B32_PCREL_X, 98)
+ELF_RELOC(R_HEX_27_REG, 99)
diff --git a/contrib/llvm/include/llvm/Support/ELFRelocs/Lanai.def b/contrib/llvm/include/llvm/BinaryFormat/ELFRelocs/Lanai.def
index 77ecb04..77ecb04 100644
--- a/contrib/llvm/include/llvm/Support/ELFRelocs/Lanai.def
+++ b/contrib/llvm/include/llvm/BinaryFormat/ELFRelocs/Lanai.def
diff --git a/contrib/llvm/include/llvm/Support/ELFRelocs/Mips.def b/contrib/llvm/include/llvm/BinaryFormat/ELFRelocs/Mips.def
index bc0088d..bc0088d 100644
--- a/contrib/llvm/include/llvm/Support/ELFRelocs/Mips.def
+++ b/contrib/llvm/include/llvm/BinaryFormat/ELFRelocs/Mips.def
diff --git a/contrib/llvm/include/llvm/Support/ELFRelocs/PowerPC.def b/contrib/llvm/include/llvm/BinaryFormat/ELFRelocs/PowerPC.def
index e4f8ee0..e4f8ee0 100644
--- a/contrib/llvm/include/llvm/Support/ELFRelocs/PowerPC.def
+++ b/contrib/llvm/include/llvm/BinaryFormat/ELFRelocs/PowerPC.def
diff --git a/contrib/llvm/include/llvm/Support/ELFRelocs/PowerPC64.def b/contrib/llvm/include/llvm/BinaryFormat/ELFRelocs/PowerPC64.def
index 3a47c5a..3a47c5a 100644
--- a/contrib/llvm/include/llvm/Support/ELFRelocs/PowerPC64.def
+++ b/contrib/llvm/include/llvm/BinaryFormat/ELFRelocs/PowerPC64.def
diff --git a/contrib/llvm/include/llvm/Support/ELFRelocs/RISCV.def b/contrib/llvm/include/llvm/BinaryFormat/ELFRelocs/RISCV.def
index 9ec4955..9ec4955 100644
--- a/contrib/llvm/include/llvm/Support/ELFRelocs/RISCV.def
+++ b/contrib/llvm/include/llvm/BinaryFormat/ELFRelocs/RISCV.def
diff --git a/contrib/llvm/include/llvm/Support/ELFRelocs/Sparc.def b/contrib/llvm/include/llvm/BinaryFormat/ELFRelocs/Sparc.def
index 7e01a4a..7e01a4a 100644
--- a/contrib/llvm/include/llvm/Support/ELFRelocs/Sparc.def
+++ b/contrib/llvm/include/llvm/BinaryFormat/ELFRelocs/Sparc.def
diff --git a/contrib/llvm/include/llvm/Support/ELFRelocs/SystemZ.def b/contrib/llvm/include/llvm/BinaryFormat/ELFRelocs/SystemZ.def
index d6c0b79..d6c0b79 100644
--- a/contrib/llvm/include/llvm/Support/ELFRelocs/SystemZ.def
+++ b/contrib/llvm/include/llvm/BinaryFormat/ELFRelocs/SystemZ.def
diff --git a/contrib/llvm/include/llvm/Support/ELFRelocs/WebAssembly.def b/contrib/llvm/include/llvm/BinaryFormat/ELFRelocs/WebAssembly.def
index 9a34349..9a34349 100644
--- a/contrib/llvm/include/llvm/Support/ELFRelocs/WebAssembly.def
+++ b/contrib/llvm/include/llvm/BinaryFormat/ELFRelocs/WebAssembly.def
diff --git a/contrib/llvm/include/llvm/Support/ELFRelocs/i386.def b/contrib/llvm/include/llvm/BinaryFormat/ELFRelocs/i386.def
index 1d28cf5..1d28cf5 100644
--- a/contrib/llvm/include/llvm/Support/ELFRelocs/i386.def
+++ b/contrib/llvm/include/llvm/BinaryFormat/ELFRelocs/i386.def
diff --git a/contrib/llvm/include/llvm/Support/ELFRelocs/x86_64.def b/contrib/llvm/include/llvm/BinaryFormat/ELFRelocs/x86_64.def
index 18fdcf9..18fdcf9 100644
--- a/contrib/llvm/include/llvm/Support/ELFRelocs/x86_64.def
+++ b/contrib/llvm/include/llvm/BinaryFormat/ELFRelocs/x86_64.def
diff --git a/contrib/llvm/include/llvm/Support/MachO.def b/contrib/llvm/include/llvm/BinaryFormat/MachO.def
index 5752289..95de48d 100644
--- a/contrib/llvm/include/llvm/Support/MachO.def
+++ b/contrib/llvm/include/llvm/BinaryFormat/MachO.def
@@ -73,6 +73,8 @@ HANDLE_LOAD_COMMAND(LC_LINKER_OPTION, 0x0000002Du, linker_option_command)
HANDLE_LOAD_COMMAND(LC_LINKER_OPTIMIZATION_HINT, 0x0000002Eu, linkedit_data_command)
HANDLE_LOAD_COMMAND(LC_VERSION_MIN_TVOS, 0x0000002Fu, version_min_command)
HANDLE_LOAD_COMMAND(LC_VERSION_MIN_WATCHOS, 0x00000030u, version_min_command)
+HANDLE_LOAD_COMMAND(LC_NOTE, 0x00000031u, note_command)
+HANDLE_LOAD_COMMAND(LC_BUILD_VERSION, 0x00000032u, build_version_command)
#endif
@@ -109,6 +111,8 @@ LOAD_COMMAND_STRUCT(thread_command)
LOAD_COMMAND_STRUCT(twolevel_hints_command)
LOAD_COMMAND_STRUCT(uuid_command)
LOAD_COMMAND_STRUCT(version_min_command)
+LOAD_COMMAND_STRUCT(note_command)
+LOAD_COMMAND_STRUCT(build_version_command)
#endif
diff --git a/contrib/llvm/include/llvm/BinaryFormat/MachO.h b/contrib/llvm/include/llvm/BinaryFormat/MachO.h
new file mode 100644
index 0000000..3529c72
--- /dev/null
+++ b/contrib/llvm/include/llvm/BinaryFormat/MachO.h
@@ -0,0 +1,1985 @@
+//===-- llvm/BinaryFormat/MachO.h - The MachO file format -------*- C++/-*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines manifest constants for the MachO object file format.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_BINARYFORMAT_MACHO_H
+#define LLVM_BINARYFORMAT_MACHO_H
+
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/Host.h"
+
+namespace llvm {
+namespace MachO {
+// Enums from <mach-o/loader.h>
+enum : uint32_t {
+ // Constants for the "magic" field in llvm::MachO::mach_header and
+ // llvm::MachO::mach_header_64
+ MH_MAGIC = 0xFEEDFACEu,
+ MH_CIGAM = 0xCEFAEDFEu,
+ MH_MAGIC_64 = 0xFEEDFACFu,
+ MH_CIGAM_64 = 0xCFFAEDFEu,
+ FAT_MAGIC = 0xCAFEBABEu,
+ FAT_CIGAM = 0xBEBAFECAu,
+ FAT_MAGIC_64 = 0xCAFEBABFu,
+ FAT_CIGAM_64 = 0xBFBAFECAu
+};
+
+enum HeaderFileType {
+ // Constants for the "filetype" field in llvm::MachO::mach_header and
+ // llvm::MachO::mach_header_64
+ MH_OBJECT = 0x1u,
+ MH_EXECUTE = 0x2u,
+ MH_FVMLIB = 0x3u,
+ MH_CORE = 0x4u,
+ MH_PRELOAD = 0x5u,
+ MH_DYLIB = 0x6u,
+ MH_DYLINKER = 0x7u,
+ MH_BUNDLE = 0x8u,
+ MH_DYLIB_STUB = 0x9u,
+ MH_DSYM = 0xAu,
+ MH_KEXT_BUNDLE = 0xBu
+};
+
+enum {
+ // Constant bits for the "flags" field in llvm::MachO::mach_header and
+ // llvm::MachO::mach_header_64
+ MH_NOUNDEFS = 0x00000001u,
+ MH_INCRLINK = 0x00000002u,
+ MH_DYLDLINK = 0x00000004u,
+ MH_BINDATLOAD = 0x00000008u,
+ MH_PREBOUND = 0x00000010u,
+ MH_SPLIT_SEGS = 0x00000020u,
+ MH_LAZY_INIT = 0x00000040u,
+ MH_TWOLEVEL = 0x00000080u,
+ MH_FORCE_FLAT = 0x00000100u,
+ MH_NOMULTIDEFS = 0x00000200u,
+ MH_NOFIXPREBINDING = 0x00000400u,
+ MH_PREBINDABLE = 0x00000800u,
+ MH_ALLMODSBOUND = 0x00001000u,
+ MH_SUBSECTIONS_VIA_SYMBOLS = 0x00002000u,
+ MH_CANONICAL = 0x00004000u,
+ MH_WEAK_DEFINES = 0x00008000u,
+ MH_BINDS_TO_WEAK = 0x00010000u,
+ MH_ALLOW_STACK_EXECUTION = 0x00020000u,
+ MH_ROOT_SAFE = 0x00040000u,
+ MH_SETUID_SAFE = 0x00080000u,
+ MH_NO_REEXPORTED_DYLIBS = 0x00100000u,
+ MH_PIE = 0x00200000u,
+ MH_DEAD_STRIPPABLE_DYLIB = 0x00400000u,
+ MH_HAS_TLV_DESCRIPTORS = 0x00800000u,
+ MH_NO_HEAP_EXECUTION = 0x01000000u,
+ MH_APP_EXTENSION_SAFE = 0x02000000u,
+ MH_NLIST_OUTOFSYNC_WITH_DYLDINFO = 0x04000000u
+};
+
+enum : uint32_t {
+ // Flags for the "cmd" field in llvm::MachO::load_command
+ LC_REQ_DYLD = 0x80000000u
+};
+
+#define HANDLE_LOAD_COMMAND(LCName, LCValue, LCStruct) LCName = LCValue,
+
+enum LoadCommandType : uint32_t {
+#include "llvm/BinaryFormat/MachO.def"
+};
+
+#undef HANDLE_LOAD_COMMAND
+
+enum : uint32_t {
+ // Constant bits for the "flags" field in llvm::MachO::segment_command
+ SG_HIGHVM = 0x1u,
+ SG_FVMLIB = 0x2u,
+ SG_NORELOC = 0x4u,
+ SG_PROTECTED_VERSION_1 = 0x8u,
+
+ // Constant masks for the "flags" field in llvm::MachO::section and
+ // llvm::MachO::section_64
+ SECTION_TYPE = 0x000000ffu, // SECTION_TYPE
+ SECTION_ATTRIBUTES = 0xffffff00u, // SECTION_ATTRIBUTES
+ SECTION_ATTRIBUTES_USR = 0xff000000u, // SECTION_ATTRIBUTES_USR
+ SECTION_ATTRIBUTES_SYS = 0x00ffff00u // SECTION_ATTRIBUTES_SYS
+};
+
+/// These are the section type and attributes fields. A MachO section can
+/// have only one Type, but can have any of the attributes specified.
+enum SectionType : uint32_t {
+ // Constant masks for the "flags[7:0]" field in llvm::MachO::section and
+ // llvm::MachO::section_64 (mask "flags" with SECTION_TYPE)
+
+ /// S_REGULAR - Regular section.
+ S_REGULAR = 0x00u,
+ /// S_ZEROFILL - Zero fill on demand section.
+ S_ZEROFILL = 0x01u,
+ /// S_CSTRING_LITERALS - Section with literal C strings.
+ S_CSTRING_LITERALS = 0x02u,
+ /// S_4BYTE_LITERALS - Section with 4 byte literals.
+ S_4BYTE_LITERALS = 0x03u,
+ /// S_8BYTE_LITERALS - Section with 8 byte literals.
+ S_8BYTE_LITERALS = 0x04u,
+ /// S_LITERAL_POINTERS - Section with pointers to literals.
+ S_LITERAL_POINTERS = 0x05u,
+ /// S_NON_LAZY_SYMBOL_POINTERS - Section with non-lazy symbol pointers.
+ S_NON_LAZY_SYMBOL_POINTERS = 0x06u,
+ /// S_LAZY_SYMBOL_POINTERS - Section with lazy symbol pointers.
+ S_LAZY_SYMBOL_POINTERS = 0x07u,
+ /// S_SYMBOL_STUBS - Section with symbol stubs, byte size of stub in
+ /// the Reserved2 field.
+ S_SYMBOL_STUBS = 0x08u,
+ /// S_MOD_INIT_FUNC_POINTERS - Section with only function pointers for
+ /// initialization.
+ S_MOD_INIT_FUNC_POINTERS = 0x09u,
+ /// S_MOD_TERM_FUNC_POINTERS - Section with only function pointers for
+ /// termination.
+ S_MOD_TERM_FUNC_POINTERS = 0x0au,
+ /// S_COALESCED - Section contains symbols that are to be coalesced.
+ S_COALESCED = 0x0bu,
+ /// S_GB_ZEROFILL - Zero fill on demand section (that can be larger than 4
+ /// gigabytes).
+ S_GB_ZEROFILL = 0x0cu,
+ /// S_INTERPOSING - Section with only pairs of function pointers for
+ /// interposing.
+ S_INTERPOSING = 0x0du,
+ /// S_16BYTE_LITERALS - Section with only 16 byte literals.
+ S_16BYTE_LITERALS = 0x0eu,
+ /// S_DTRACE_DOF - Section contains DTrace Object Format.
+ S_DTRACE_DOF = 0x0fu,
+ /// S_LAZY_DYLIB_SYMBOL_POINTERS - Section with lazy symbol pointers to
+ /// lazy loaded dylibs.
+ S_LAZY_DYLIB_SYMBOL_POINTERS = 0x10u,
+ /// S_THREAD_LOCAL_REGULAR - Thread local data section.
+ S_THREAD_LOCAL_REGULAR = 0x11u,
+ /// S_THREAD_LOCAL_ZEROFILL - Thread local zerofill section.
+ S_THREAD_LOCAL_ZEROFILL = 0x12u,
+ /// S_THREAD_LOCAL_VARIABLES - Section with thread local variable
+ /// structure data.
+ S_THREAD_LOCAL_VARIABLES = 0x13u,
+ /// S_THREAD_LOCAL_VARIABLE_POINTERS - Section with pointers to thread
+ /// local structures.
+ S_THREAD_LOCAL_VARIABLE_POINTERS = 0x14u,
+ /// S_THREAD_LOCAL_INIT_FUNCTION_POINTERS - Section with thread local
+ /// variable initialization pointers to functions.
+ S_THREAD_LOCAL_INIT_FUNCTION_POINTERS = 0x15u,
+
+ LAST_KNOWN_SECTION_TYPE = S_THREAD_LOCAL_INIT_FUNCTION_POINTERS
+};
+
+enum : uint32_t {
+ // Constant masks for the "flags[31:24]" field in llvm::MachO::section and
+ // llvm::MachO::section_64 (mask "flags" with SECTION_ATTRIBUTES_USR)
+
+ /// S_ATTR_PURE_INSTRUCTIONS - Section contains only true machine
+ /// instructions.
+ S_ATTR_PURE_INSTRUCTIONS = 0x80000000u,
+ /// S_ATTR_NO_TOC - Section contains coalesced symbols that are not to be
+ /// in a ranlib table of contents.
+ S_ATTR_NO_TOC = 0x40000000u,
+ /// S_ATTR_STRIP_STATIC_SYMS - Ok to strip static symbols in this section
+ /// in files with the MY_DYLDLINK flag.
+ S_ATTR_STRIP_STATIC_SYMS = 0x20000000u,
+ /// S_ATTR_NO_DEAD_STRIP - No dead stripping.
+ S_ATTR_NO_DEAD_STRIP = 0x10000000u,
+ /// S_ATTR_LIVE_SUPPORT - Blocks are live if they reference live blocks.
+ S_ATTR_LIVE_SUPPORT = 0x08000000u,
+ /// S_ATTR_SELF_MODIFYING_CODE - Used with i386 code stubs written on by
+ /// dyld.
+ S_ATTR_SELF_MODIFYING_CODE = 0x04000000u,
+ /// S_ATTR_DEBUG - A debug section.
+ S_ATTR_DEBUG = 0x02000000u,
+
+ // Constant masks for the "flags[23:8]" field in llvm::MachO::section and
+ // llvm::MachO::section_64 (mask "flags" with SECTION_ATTRIBUTES_SYS)
+
+ /// S_ATTR_SOME_INSTRUCTIONS - Section contains some machine instructions.
+ S_ATTR_SOME_INSTRUCTIONS = 0x00000400u,
+ /// S_ATTR_EXT_RELOC - Section has external relocation entries.
+ S_ATTR_EXT_RELOC = 0x00000200u,
+ /// S_ATTR_LOC_RELOC - Section has local relocation entries.
+ S_ATTR_LOC_RELOC = 0x00000100u,
+
+ // Constant masks for the value of an indirect symbol in an indirect
+ // symbol table
+ INDIRECT_SYMBOL_LOCAL = 0x80000000u,
+ INDIRECT_SYMBOL_ABS = 0x40000000u
+};
+
+enum DataRegionType {
+ // Constants for the "kind" field in a data_in_code_entry structure
+ DICE_KIND_DATA = 1u,
+ DICE_KIND_JUMP_TABLE8 = 2u,
+ DICE_KIND_JUMP_TABLE16 = 3u,
+ DICE_KIND_JUMP_TABLE32 = 4u,
+ DICE_KIND_ABS_JUMP_TABLE32 = 5u
+};
+
+enum RebaseType {
+ REBASE_TYPE_POINTER = 1u,
+ REBASE_TYPE_TEXT_ABSOLUTE32 = 2u,
+ REBASE_TYPE_TEXT_PCREL32 = 3u
+};
+
+enum { REBASE_OPCODE_MASK = 0xF0u, REBASE_IMMEDIATE_MASK = 0x0Fu };
+
+enum RebaseOpcode {
+ REBASE_OPCODE_DONE = 0x00u,
+ REBASE_OPCODE_SET_TYPE_IMM = 0x10u,
+ REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB = 0x20u,
+ REBASE_OPCODE_ADD_ADDR_ULEB = 0x30u,
+ REBASE_OPCODE_ADD_ADDR_IMM_SCALED = 0x40u,
+ REBASE_OPCODE_DO_REBASE_IMM_TIMES = 0x50u,
+ REBASE_OPCODE_DO_REBASE_ULEB_TIMES = 0x60u,
+ REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB = 0x70u,
+ REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB = 0x80u
+};
+
+enum BindType {
+ BIND_TYPE_POINTER = 1u,
+ BIND_TYPE_TEXT_ABSOLUTE32 = 2u,
+ BIND_TYPE_TEXT_PCREL32 = 3u
+};
+
+enum BindSpecialDylib {
+ BIND_SPECIAL_DYLIB_SELF = 0,
+ BIND_SPECIAL_DYLIB_MAIN_EXECUTABLE = -1,
+ BIND_SPECIAL_DYLIB_FLAT_LOOKUP = -2
+};
+
+enum {
+ BIND_SYMBOL_FLAGS_WEAK_IMPORT = 0x1u,
+ BIND_SYMBOL_FLAGS_NON_WEAK_DEFINITION = 0x8u,
+
+ BIND_OPCODE_MASK = 0xF0u,
+ BIND_IMMEDIATE_MASK = 0x0Fu
+};
+
+enum BindOpcode {
+ BIND_OPCODE_DONE = 0x00u,
+ BIND_OPCODE_SET_DYLIB_ORDINAL_IMM = 0x10u,
+ BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB = 0x20u,
+ BIND_OPCODE_SET_DYLIB_SPECIAL_IMM = 0x30u,
+ BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM = 0x40u,
+ BIND_OPCODE_SET_TYPE_IMM = 0x50u,
+ BIND_OPCODE_SET_ADDEND_SLEB = 0x60u,
+ BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB = 0x70u,
+ BIND_OPCODE_ADD_ADDR_ULEB = 0x80u,
+ BIND_OPCODE_DO_BIND = 0x90u,
+ BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB = 0xA0u,
+ BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED = 0xB0u,
+ BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB = 0xC0u
+};
+
+enum {
+ EXPORT_SYMBOL_FLAGS_KIND_MASK = 0x03u,
+ EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION = 0x04u,
+ EXPORT_SYMBOL_FLAGS_REEXPORT = 0x08u,
+ EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER = 0x10u
+};
+
+enum ExportSymbolKind {
+ EXPORT_SYMBOL_FLAGS_KIND_REGULAR = 0x00u,
+ EXPORT_SYMBOL_FLAGS_KIND_THREAD_LOCAL = 0x01u,
+ EXPORT_SYMBOL_FLAGS_KIND_ABSOLUTE = 0x02u
+};
+
+enum {
+ // Constant masks for the "n_type" field in llvm::MachO::nlist and
+ // llvm::MachO::nlist_64
+ N_STAB = 0xe0,
+ N_PEXT = 0x10,
+ N_TYPE = 0x0e,
+ N_EXT = 0x01
+};
+
+enum NListType : uint8_t {
+ // Constants for the "n_type & N_TYPE" llvm::MachO::nlist and
+ // llvm::MachO::nlist_64
+ N_UNDF = 0x0u,
+ N_ABS = 0x2u,
+ N_SECT = 0xeu,
+ N_PBUD = 0xcu,
+ N_INDR = 0xau
+};
+
+enum SectionOrdinal {
+ // Constants for the "n_sect" field in llvm::MachO::nlist and
+ // llvm::MachO::nlist_64
+ NO_SECT = 0u,
+ MAX_SECT = 0xffu
+};
+
+enum {
+ // Constant masks for the "n_desc" field in llvm::MachO::nlist and
+ // llvm::MachO::nlist_64
+ // The low 3 bits are the for the REFERENCE_TYPE.
+ REFERENCE_TYPE = 0x7,
+ REFERENCE_FLAG_UNDEFINED_NON_LAZY = 0,
+ REFERENCE_FLAG_UNDEFINED_LAZY = 1,
+ REFERENCE_FLAG_DEFINED = 2,
+ REFERENCE_FLAG_PRIVATE_DEFINED = 3,
+ REFERENCE_FLAG_PRIVATE_UNDEFINED_NON_LAZY = 4,
+ REFERENCE_FLAG_PRIVATE_UNDEFINED_LAZY = 5,
+ // Flag bits (some overlap with the library ordinal bits).
+ N_ARM_THUMB_DEF = 0x0008u,
+ REFERENCED_DYNAMICALLY = 0x0010u,
+ N_NO_DEAD_STRIP = 0x0020u,
+ N_WEAK_REF = 0x0040u,
+ N_WEAK_DEF = 0x0080u,
+ N_SYMBOL_RESOLVER = 0x0100u,
+ N_ALT_ENTRY = 0x0200u,
+ // For undefined symbols coming from libraries, see GET_LIBRARY_ORDINAL()
+ // as these are in the top 8 bits.
+ SELF_LIBRARY_ORDINAL = 0x0,
+ MAX_LIBRARY_ORDINAL = 0xfd,
+ DYNAMIC_LOOKUP_ORDINAL = 0xfe,
+ EXECUTABLE_ORDINAL = 0xff
+};
+
+enum StabType {
+ // Constant values for the "n_type" field in llvm::MachO::nlist and
+ // llvm::MachO::nlist_64 when "(n_type & N_STAB) != 0"
+ N_GSYM = 0x20u,
+ N_FNAME = 0x22u,
+ N_FUN = 0x24u,
+ N_STSYM = 0x26u,
+ N_LCSYM = 0x28u,
+ N_BNSYM = 0x2Eu,
+ N_PC = 0x30u,
+ N_AST = 0x32u,
+ N_OPT = 0x3Cu,
+ N_RSYM = 0x40u,
+ N_SLINE = 0x44u,
+ N_ENSYM = 0x4Eu,
+ N_SSYM = 0x60u,
+ N_SO = 0x64u,
+ N_OSO = 0x66u,
+ N_LSYM = 0x80u,
+ N_BINCL = 0x82u,
+ N_SOL = 0x84u,
+ N_PARAMS = 0x86u,
+ N_VERSION = 0x88u,
+ N_OLEVEL = 0x8Au,
+ N_PSYM = 0xA0u,
+ N_EINCL = 0xA2u,
+ N_ENTRY = 0xA4u,
+ N_LBRAC = 0xC0u,
+ N_EXCL = 0xC2u,
+ N_RBRAC = 0xE0u,
+ N_BCOMM = 0xE2u,
+ N_ECOMM = 0xE4u,
+ N_ECOML = 0xE8u,
+ N_LENG = 0xFEu
+};
+
+enum : uint32_t {
+ // Constant values for the r_symbolnum field in an
+ // llvm::MachO::relocation_info structure when r_extern is 0.
+ R_ABS = 0,
+
+ // Constant bits for the r_address field in an
+ // llvm::MachO::relocation_info structure.
+ R_SCATTERED = 0x80000000
+};
+
+enum RelocationInfoType {
+ // Constant values for the r_type field in an
+ // llvm::MachO::relocation_info or llvm::MachO::scattered_relocation_info
+ // structure.
+ GENERIC_RELOC_VANILLA = 0,
+ GENERIC_RELOC_PAIR = 1,
+ GENERIC_RELOC_SECTDIFF = 2,
+ GENERIC_RELOC_PB_LA_PTR = 3,
+ GENERIC_RELOC_LOCAL_SECTDIFF = 4,
+ GENERIC_RELOC_TLV = 5,
+
+ // Constant values for the r_type field in a PowerPC architecture
+ // llvm::MachO::relocation_info or llvm::MachO::scattered_relocation_info
+ // structure.
+ PPC_RELOC_VANILLA = GENERIC_RELOC_VANILLA,
+ PPC_RELOC_PAIR = GENERIC_RELOC_PAIR,
+ PPC_RELOC_BR14 = 2,
+ PPC_RELOC_BR24 = 3,
+ PPC_RELOC_HI16 = 4,
+ PPC_RELOC_LO16 = 5,
+ PPC_RELOC_HA16 = 6,
+ PPC_RELOC_LO14 = 7,
+ PPC_RELOC_SECTDIFF = 8,
+ PPC_RELOC_PB_LA_PTR = 9,
+ PPC_RELOC_HI16_SECTDIFF = 10,
+ PPC_RELOC_LO16_SECTDIFF = 11,
+ PPC_RELOC_HA16_SECTDIFF = 12,
+ PPC_RELOC_JBSR = 13,
+ PPC_RELOC_LO14_SECTDIFF = 14,
+ PPC_RELOC_LOCAL_SECTDIFF = 15,
+
+ // Constant values for the r_type field in an ARM architecture
+ // llvm::MachO::relocation_info or llvm::MachO::scattered_relocation_info
+ // structure.
+ ARM_RELOC_VANILLA = GENERIC_RELOC_VANILLA,
+ ARM_RELOC_PAIR = GENERIC_RELOC_PAIR,
+ ARM_RELOC_SECTDIFF = GENERIC_RELOC_SECTDIFF,
+ ARM_RELOC_LOCAL_SECTDIFF = 3,
+ ARM_RELOC_PB_LA_PTR = 4,
+ ARM_RELOC_BR24 = 5,
+ ARM_THUMB_RELOC_BR22 = 6,
+ ARM_THUMB_32BIT_BRANCH = 7, // obsolete
+ ARM_RELOC_HALF = 8,
+ ARM_RELOC_HALF_SECTDIFF = 9,
+
+ // Constant values for the r_type field in an ARM64 architecture
+ // llvm::MachO::relocation_info or llvm::MachO::scattered_relocation_info
+ // structure.
+
+ // For pointers.
+ ARM64_RELOC_UNSIGNED = 0,
+ // Must be followed by an ARM64_RELOC_UNSIGNED
+ ARM64_RELOC_SUBTRACTOR = 1,
+ // A B/BL instruction with 26-bit displacement.
+ ARM64_RELOC_BRANCH26 = 2,
+ // PC-rel distance to page of target.
+ ARM64_RELOC_PAGE21 = 3,
+ // Offset within page, scaled by r_length.
+ ARM64_RELOC_PAGEOFF12 = 4,
+ // PC-rel distance to page of GOT slot.
+ ARM64_RELOC_GOT_LOAD_PAGE21 = 5,
+ // Offset within page of GOT slot, scaled by r_length.
+ ARM64_RELOC_GOT_LOAD_PAGEOFF12 = 6,
+ // For pointers to GOT slots.
+ ARM64_RELOC_POINTER_TO_GOT = 7,
+ // PC-rel distance to page of TLVP slot.
+ ARM64_RELOC_TLVP_LOAD_PAGE21 = 8,
+ // Offset within page of TLVP slot, scaled by r_length.
+ ARM64_RELOC_TLVP_LOAD_PAGEOFF12 = 9,
+ // Must be followed by ARM64_RELOC_PAGE21 or ARM64_RELOC_PAGEOFF12.
+ ARM64_RELOC_ADDEND = 10,
+
+ // Constant values for the r_type field in an x86_64 architecture
+ // llvm::MachO::relocation_info or llvm::MachO::scattered_relocation_info
+ // structure
+ X86_64_RELOC_UNSIGNED = 0,
+ X86_64_RELOC_SIGNED = 1,
+ X86_64_RELOC_BRANCH = 2,
+ X86_64_RELOC_GOT_LOAD = 3,
+ X86_64_RELOC_GOT = 4,
+ X86_64_RELOC_SUBTRACTOR = 5,
+ X86_64_RELOC_SIGNED_1 = 6,
+ X86_64_RELOC_SIGNED_2 = 7,
+ X86_64_RELOC_SIGNED_4 = 8,
+ X86_64_RELOC_TLV = 9
+};
+
+// Values for segment_command.initprot.
+// From <mach/vm_prot.h>
+enum { VM_PROT_READ = 0x1, VM_PROT_WRITE = 0x2, VM_PROT_EXECUTE = 0x4 };
+
+// Values for platform field in build_version_command.
+enum {
+ PLATFORM_MACOS = 1,
+ PLATFORM_IOS = 2,
+ PLATFORM_TVOS = 3,
+ PLATFORM_WATCHOS = 4,
+ PLATFORM_BRIDGEOS = 5
+};
+
+// Values for tools enum in build_tool_version.
+enum { TOOL_CLANG = 1, TOOL_SWIFT = 2, TOOL_LD = 3 };
+
+// Structs from <mach-o/loader.h>
+
+struct mach_header {
+ uint32_t magic;
+ uint32_t cputype;
+ uint32_t cpusubtype;
+ uint32_t filetype;
+ uint32_t ncmds;
+ uint32_t sizeofcmds;
+ uint32_t flags;
+};
+
+struct mach_header_64 {
+ uint32_t magic;
+ uint32_t cputype;
+ uint32_t cpusubtype;
+ uint32_t filetype;
+ uint32_t ncmds;
+ uint32_t sizeofcmds;
+ uint32_t flags;
+ uint32_t reserved;
+};
+
+struct load_command {
+ uint32_t cmd;
+ uint32_t cmdsize;
+};
+
+struct segment_command {
+ uint32_t cmd;
+ uint32_t cmdsize;
+ char segname[16];
+ uint32_t vmaddr;
+ uint32_t vmsize;
+ uint32_t fileoff;
+ uint32_t filesize;
+ uint32_t maxprot;
+ uint32_t initprot;
+ uint32_t nsects;
+ uint32_t flags;
+};
+
+struct segment_command_64 {
+ uint32_t cmd;
+ uint32_t cmdsize;
+ char segname[16];
+ uint64_t vmaddr;
+ uint64_t vmsize;
+ uint64_t fileoff;
+ uint64_t filesize;
+ uint32_t maxprot;
+ uint32_t initprot;
+ uint32_t nsects;
+ uint32_t flags;
+};
+
+struct section {
+ char sectname[16];
+ char segname[16];
+ uint32_t addr;
+ uint32_t size;
+ uint32_t offset;
+ uint32_t align;
+ uint32_t reloff;
+ uint32_t nreloc;
+ uint32_t flags;
+ uint32_t reserved1;
+ uint32_t reserved2;
+};
+
+struct section_64 {
+ char sectname[16];
+ char segname[16];
+ uint64_t addr;
+ uint64_t size;
+ uint32_t offset;
+ uint32_t align;
+ uint32_t reloff;
+ uint32_t nreloc;
+ uint32_t flags;
+ uint32_t reserved1;
+ uint32_t reserved2;
+ uint32_t reserved3;
+};
+
+struct fvmlib {
+ uint32_t name;
+ uint32_t minor_version;
+ uint32_t header_addr;
+};
+
+// The fvmlib_command is obsolete and no longer supported.
+struct fvmlib_command {
+ uint32_t cmd;
+ uint32_t cmdsize;
+ struct fvmlib fvmlib;
+};
+
+struct dylib {
+ uint32_t name;
+ uint32_t timestamp;
+ uint32_t current_version;
+ uint32_t compatibility_version;
+};
+
+struct dylib_command {
+ uint32_t cmd;
+ uint32_t cmdsize;
+ struct dylib dylib;
+};
+
+struct sub_framework_command {
+ uint32_t cmd;
+ uint32_t cmdsize;
+ uint32_t umbrella;
+};
+
+struct sub_client_command {
+ uint32_t cmd;
+ uint32_t cmdsize;
+ uint32_t client;
+};
+
+struct sub_umbrella_command {
+ uint32_t cmd;
+ uint32_t cmdsize;
+ uint32_t sub_umbrella;
+};
+
+struct sub_library_command {
+ uint32_t cmd;
+ uint32_t cmdsize;
+ uint32_t sub_library;
+};
+
+// The prebound_dylib_command is obsolete and no longer supported.
+struct prebound_dylib_command {
+ uint32_t cmd;
+ uint32_t cmdsize;
+ uint32_t name;
+ uint32_t nmodules;
+ uint32_t linked_modules;
+};
+
+struct dylinker_command {
+ uint32_t cmd;
+ uint32_t cmdsize;
+ uint32_t name;
+};
+
+struct thread_command {
+ uint32_t cmd;
+ uint32_t cmdsize;
+};
+
+struct routines_command {
+ uint32_t cmd;
+ uint32_t cmdsize;
+ uint32_t init_address;
+ uint32_t init_module;
+ uint32_t reserved1;
+ uint32_t reserved2;
+ uint32_t reserved3;
+ uint32_t reserved4;
+ uint32_t reserved5;
+ uint32_t reserved6;
+};
+
+struct routines_command_64 {
+ uint32_t cmd;
+ uint32_t cmdsize;
+ uint64_t init_address;
+ uint64_t init_module;
+ uint64_t reserved1;
+ uint64_t reserved2;
+ uint64_t reserved3;
+ uint64_t reserved4;
+ uint64_t reserved5;
+ uint64_t reserved6;
+};
+
+struct symtab_command {
+ uint32_t cmd;
+ uint32_t cmdsize;
+ uint32_t symoff;
+ uint32_t nsyms;
+ uint32_t stroff;
+ uint32_t strsize;
+};
+
+struct dysymtab_command {
+ uint32_t cmd;
+ uint32_t cmdsize;
+ uint32_t ilocalsym;
+ uint32_t nlocalsym;
+ uint32_t iextdefsym;
+ uint32_t nextdefsym;
+ uint32_t iundefsym;
+ uint32_t nundefsym;
+ uint32_t tocoff;
+ uint32_t ntoc;
+ uint32_t modtaboff;
+ uint32_t nmodtab;
+ uint32_t extrefsymoff;
+ uint32_t nextrefsyms;
+ uint32_t indirectsymoff;
+ uint32_t nindirectsyms;
+ uint32_t extreloff;
+ uint32_t nextrel;
+ uint32_t locreloff;
+ uint32_t nlocrel;
+};
+
+struct dylib_table_of_contents {
+ uint32_t symbol_index;
+ uint32_t module_index;
+};
+
+struct dylib_module {
+ uint32_t module_name;
+ uint32_t iextdefsym;
+ uint32_t nextdefsym;
+ uint32_t irefsym;
+ uint32_t nrefsym;
+ uint32_t ilocalsym;
+ uint32_t nlocalsym;
+ uint32_t iextrel;
+ uint32_t nextrel;
+ uint32_t iinit_iterm;
+ uint32_t ninit_nterm;
+ uint32_t objc_module_info_addr;
+ uint32_t objc_module_info_size;
+};
+
+struct dylib_module_64 {
+ uint32_t module_name;
+ uint32_t iextdefsym;
+ uint32_t nextdefsym;
+ uint32_t irefsym;
+ uint32_t nrefsym;
+ uint32_t ilocalsym;
+ uint32_t nlocalsym;
+ uint32_t iextrel;
+ uint32_t nextrel;
+ uint32_t iinit_iterm;
+ uint32_t ninit_nterm;
+ uint32_t objc_module_info_size;
+ uint64_t objc_module_info_addr;
+};
+
+struct dylib_reference {
+ uint32_t isym : 24, flags : 8;
+};
+
+// The twolevel_hints_command is obsolete and no longer supported.
+struct twolevel_hints_command {
+ uint32_t cmd;
+ uint32_t cmdsize;
+ uint32_t offset;
+ uint32_t nhints;
+};
+
+// The twolevel_hints_command is obsolete and no longer supported.
+struct twolevel_hint {
+ uint32_t isub_image : 8, itoc : 24;
+};
+
+// The prebind_cksum_command is obsolete and no longer supported.
+struct prebind_cksum_command {
+ uint32_t cmd;
+ uint32_t cmdsize;
+ uint32_t cksum;
+};
+
+struct uuid_command {
+ uint32_t cmd;
+ uint32_t cmdsize;
+ uint8_t uuid[16];
+};
+
+struct rpath_command {
+ uint32_t cmd;
+ uint32_t cmdsize;
+ uint32_t path;
+};
+
+struct linkedit_data_command {
+ uint32_t cmd;
+ uint32_t cmdsize;
+ uint32_t dataoff;
+ uint32_t datasize;
+};
+
+struct data_in_code_entry {
+ uint32_t offset;
+ uint16_t length;
+ uint16_t kind;
+};
+
+struct source_version_command {
+ uint32_t cmd;
+ uint32_t cmdsize;
+ uint64_t version;
+};
+
+struct encryption_info_command {
+ uint32_t cmd;
+ uint32_t cmdsize;
+ uint32_t cryptoff;
+ uint32_t cryptsize;
+ uint32_t cryptid;
+};
+
+struct encryption_info_command_64 {
+ uint32_t cmd;
+ uint32_t cmdsize;
+ uint32_t cryptoff;
+ uint32_t cryptsize;
+ uint32_t cryptid;
+ uint32_t pad;
+};
+
+struct version_min_command {
+ uint32_t cmd; // LC_VERSION_MIN_MACOSX or
+ // LC_VERSION_MIN_IPHONEOS
+ uint32_t cmdsize; // sizeof(struct version_min_command)
+ uint32_t version; // X.Y.Z is encoded in nibbles xxxx.yy.zz
+ uint32_t sdk; // X.Y.Z is encoded in nibbles xxxx.yy.zz
+};
+
+struct note_command {
+ uint32_t cmd; // LC_NOTE
+ uint32_t cmdsize; // sizeof(struct note_command)
+ char data_owner[16]; // owner name for this LC_NOTE
+ uint64_t offset; // file offset of this data
+ uint64_t size; // length of data region
+};
+
+struct build_tool_version {
+ uint32_t tool; // enum for the tool
+ uint32_t version; // version of the tool
+};
+
+struct build_version_command {
+ uint32_t cmd; // LC_BUILD_VERSION
+ uint32_t cmdsize; // sizeof(struct build_version_command) +
+ // ntools * sizeof(struct build_tool_version)
+ uint32_t platform; // platform
+ uint32_t minos; // X.Y.Z is encoded in nibbles xxxx.yy.zz
+ uint32_t sdk; // X.Y.Z is encoded in nibbles xxxx.yy.zz
+ uint32_t ntools; // number of tool entries following this
+};
+
+struct dyld_info_command {
+ uint32_t cmd;
+ uint32_t cmdsize;
+ uint32_t rebase_off;
+ uint32_t rebase_size;
+ uint32_t bind_off;
+ uint32_t bind_size;
+ uint32_t weak_bind_off;
+ uint32_t weak_bind_size;
+ uint32_t lazy_bind_off;
+ uint32_t lazy_bind_size;
+ uint32_t export_off;
+ uint32_t export_size;
+};
+
+struct linker_option_command {
+ uint32_t cmd;
+ uint32_t cmdsize;
+ uint32_t count;
+};
+
+// The symseg_command is obsolete and no longer supported.
+struct symseg_command {
+ uint32_t cmd;
+ uint32_t cmdsize;
+ uint32_t offset;
+ uint32_t size;
+};
+
+// The ident_command is obsolete and no longer supported.
+struct ident_command {
+ uint32_t cmd;
+ uint32_t cmdsize;
+};
+
+// The fvmfile_command is obsolete and no longer supported.
+struct fvmfile_command {
+ uint32_t cmd;
+ uint32_t cmdsize;
+ uint32_t name;
+ uint32_t header_addr;
+};
+
+struct tlv_descriptor_32 {
+ uint32_t thunk;
+ uint32_t key;
+ uint32_t offset;
+};
+
+struct tlv_descriptor_64 {
+ uint64_t thunk;
+ uint64_t key;
+ uint64_t offset;
+};
+
+struct tlv_descriptor {
+ uintptr_t thunk;
+ uintptr_t key;
+ uintptr_t offset;
+};
+
+struct entry_point_command {
+ uint32_t cmd;
+ uint32_t cmdsize;
+ uint64_t entryoff;
+ uint64_t stacksize;
+};
+
+// Structs from <mach-o/fat.h>
+struct fat_header {
+ uint32_t magic;
+ uint32_t nfat_arch;
+};
+
+struct fat_arch {
+ uint32_t cputype;
+ uint32_t cpusubtype;
+ uint32_t offset;
+ uint32_t size;
+ uint32_t align;
+};
+
+struct fat_arch_64 {
+ uint32_t cputype;
+ uint32_t cpusubtype;
+ uint64_t offset;
+ uint64_t size;
+ uint32_t align;
+ uint32_t reserved;
+};
+
+// Structs from <mach-o/reloc.h>
+struct relocation_info {
+ int32_t r_address;
+ uint32_t r_symbolnum : 24, r_pcrel : 1, r_length : 2, r_extern : 1,
+ r_type : 4;
+};
+
+struct scattered_relocation_info {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && (BYTE_ORDER == BIG_ENDIAN)
+ uint32_t r_scattered : 1, r_pcrel : 1, r_length : 2, r_type : 4,
+ r_address : 24;
+#else
+ uint32_t r_address : 24, r_type : 4, r_length : 2, r_pcrel : 1,
+ r_scattered : 1;
+#endif
+ int32_t r_value;
+};
+
+// Structs NOT from <mach-o/reloc.h>, but that make LLVM's life easier
+struct any_relocation_info {
+ uint32_t r_word0, r_word1;
+};
+
+// Structs from <mach-o/nlist.h>
+struct nlist_base {
+ uint32_t n_strx;
+ uint8_t n_type;
+ uint8_t n_sect;
+ uint16_t n_desc;
+};
+
+struct nlist {
+ uint32_t n_strx;
+ uint8_t n_type;
+ uint8_t n_sect;
+ int16_t n_desc;
+ uint32_t n_value;
+};
+
+struct nlist_64 {
+ uint32_t n_strx;
+ uint8_t n_type;
+ uint8_t n_sect;
+ uint16_t n_desc;
+ uint64_t n_value;
+};
+
+// Byte order swapping functions for MachO structs
+
+inline void swapStruct(fat_header &mh) {
+ sys::swapByteOrder(mh.magic);
+ sys::swapByteOrder(mh.nfat_arch);
+}
+
+inline void swapStruct(fat_arch &mh) {
+ sys::swapByteOrder(mh.cputype);
+ sys::swapByteOrder(mh.cpusubtype);
+ sys::swapByteOrder(mh.offset);
+ sys::swapByteOrder(mh.size);
+ sys::swapByteOrder(mh.align);
+}
+
+inline void swapStruct(fat_arch_64 &mh) {
+ sys::swapByteOrder(mh.cputype);
+ sys::swapByteOrder(mh.cpusubtype);
+ sys::swapByteOrder(mh.offset);
+ sys::swapByteOrder(mh.size);
+ sys::swapByteOrder(mh.align);
+ sys::swapByteOrder(mh.reserved);
+}
+
+inline void swapStruct(mach_header &mh) {
+ sys::swapByteOrder(mh.magic);
+ sys::swapByteOrder(mh.cputype);
+ sys::swapByteOrder(mh.cpusubtype);
+ sys::swapByteOrder(mh.filetype);
+ sys::swapByteOrder(mh.ncmds);
+ sys::swapByteOrder(mh.sizeofcmds);
+ sys::swapByteOrder(mh.flags);
+}
+
+inline void swapStruct(mach_header_64 &H) {
+ sys::swapByteOrder(H.magic);
+ sys::swapByteOrder(H.cputype);
+ sys::swapByteOrder(H.cpusubtype);
+ sys::swapByteOrder(H.filetype);
+ sys::swapByteOrder(H.ncmds);
+ sys::swapByteOrder(H.sizeofcmds);
+ sys::swapByteOrder(H.flags);
+ sys::swapByteOrder(H.reserved);
+}
+
+inline void swapStruct(load_command &lc) {
+ sys::swapByteOrder(lc.cmd);
+ sys::swapByteOrder(lc.cmdsize);
+}
+
+inline void swapStruct(symtab_command &lc) {
+ sys::swapByteOrder(lc.cmd);
+ sys::swapByteOrder(lc.cmdsize);
+ sys::swapByteOrder(lc.symoff);
+ sys::swapByteOrder(lc.nsyms);
+ sys::swapByteOrder(lc.stroff);
+ sys::swapByteOrder(lc.strsize);
+}
+
+inline void swapStruct(segment_command_64 &seg) {
+ sys::swapByteOrder(seg.cmd);
+ sys::swapByteOrder(seg.cmdsize);
+ sys::swapByteOrder(seg.vmaddr);
+ sys::swapByteOrder(seg.vmsize);
+ sys::swapByteOrder(seg.fileoff);
+ sys::swapByteOrder(seg.filesize);
+ sys::swapByteOrder(seg.maxprot);
+ sys::swapByteOrder(seg.initprot);
+ sys::swapByteOrder(seg.nsects);
+ sys::swapByteOrder(seg.flags);
+}
+
+inline void swapStruct(segment_command &seg) {
+ sys::swapByteOrder(seg.cmd);
+ sys::swapByteOrder(seg.cmdsize);
+ sys::swapByteOrder(seg.vmaddr);
+ sys::swapByteOrder(seg.vmsize);
+ sys::swapByteOrder(seg.fileoff);
+ sys::swapByteOrder(seg.filesize);
+ sys::swapByteOrder(seg.maxprot);
+ sys::swapByteOrder(seg.initprot);
+ sys::swapByteOrder(seg.nsects);
+ sys::swapByteOrder(seg.flags);
+}
+
+inline void swapStruct(section_64 &sect) {
+ sys::swapByteOrder(sect.addr);
+ sys::swapByteOrder(sect.size);
+ sys::swapByteOrder(sect.offset);
+ sys::swapByteOrder(sect.align);
+ sys::swapByteOrder(sect.reloff);
+ sys::swapByteOrder(sect.nreloc);
+ sys::swapByteOrder(sect.flags);
+ sys::swapByteOrder(sect.reserved1);
+ sys::swapByteOrder(sect.reserved2);
+}
+
+inline void swapStruct(section &sect) {
+ sys::swapByteOrder(sect.addr);
+ sys::swapByteOrder(sect.size);
+ sys::swapByteOrder(sect.offset);
+ sys::swapByteOrder(sect.align);
+ sys::swapByteOrder(sect.reloff);
+ sys::swapByteOrder(sect.nreloc);
+ sys::swapByteOrder(sect.flags);
+ sys::swapByteOrder(sect.reserved1);
+ sys::swapByteOrder(sect.reserved2);
+}
+
+inline void swapStruct(dyld_info_command &info) {
+ sys::swapByteOrder(info.cmd);
+ sys::swapByteOrder(info.cmdsize);
+ sys::swapByteOrder(info.rebase_off);
+ sys::swapByteOrder(info.rebase_size);
+ sys::swapByteOrder(info.bind_off);
+ sys::swapByteOrder(info.bind_size);
+ sys::swapByteOrder(info.weak_bind_off);
+ sys::swapByteOrder(info.weak_bind_size);
+ sys::swapByteOrder(info.lazy_bind_off);
+ sys::swapByteOrder(info.lazy_bind_size);
+ sys::swapByteOrder(info.export_off);
+ sys::swapByteOrder(info.export_size);
+}
+
+inline void swapStruct(dylib_command &d) {
+ sys::swapByteOrder(d.cmd);
+ sys::swapByteOrder(d.cmdsize);
+ sys::swapByteOrder(d.dylib.name);
+ sys::swapByteOrder(d.dylib.timestamp);
+ sys::swapByteOrder(d.dylib.current_version);
+ sys::swapByteOrder(d.dylib.compatibility_version);
+}
+
+inline void swapStruct(sub_framework_command &s) {
+ sys::swapByteOrder(s.cmd);
+ sys::swapByteOrder(s.cmdsize);
+ sys::swapByteOrder(s.umbrella);
+}
+
+inline void swapStruct(sub_umbrella_command &s) {
+ sys::swapByteOrder(s.cmd);
+ sys::swapByteOrder(s.cmdsize);
+ sys::swapByteOrder(s.sub_umbrella);
+}
+
+inline void swapStruct(sub_library_command &s) {
+ sys::swapByteOrder(s.cmd);
+ sys::swapByteOrder(s.cmdsize);
+ sys::swapByteOrder(s.sub_library);
+}
+
+inline void swapStruct(sub_client_command &s) {
+ sys::swapByteOrder(s.cmd);
+ sys::swapByteOrder(s.cmdsize);
+ sys::swapByteOrder(s.client);
+}
+
+inline void swapStruct(routines_command &r) {
+ sys::swapByteOrder(r.cmd);
+ sys::swapByteOrder(r.cmdsize);
+ sys::swapByteOrder(r.init_address);
+ sys::swapByteOrder(r.init_module);
+ sys::swapByteOrder(r.reserved1);
+ sys::swapByteOrder(r.reserved2);
+ sys::swapByteOrder(r.reserved3);
+ sys::swapByteOrder(r.reserved4);
+ sys::swapByteOrder(r.reserved5);
+ sys::swapByteOrder(r.reserved6);
+}
+
+inline void swapStruct(routines_command_64 &r) {
+ sys::swapByteOrder(r.cmd);
+ sys::swapByteOrder(r.cmdsize);
+ sys::swapByteOrder(r.init_address);
+ sys::swapByteOrder(r.init_module);
+ sys::swapByteOrder(r.reserved1);
+ sys::swapByteOrder(r.reserved2);
+ sys::swapByteOrder(r.reserved3);
+ sys::swapByteOrder(r.reserved4);
+ sys::swapByteOrder(r.reserved5);
+ sys::swapByteOrder(r.reserved6);
+}
+
+inline void swapStruct(thread_command &t) {
+ sys::swapByteOrder(t.cmd);
+ sys::swapByteOrder(t.cmdsize);
+}
+
+inline void swapStruct(dylinker_command &d) {
+ sys::swapByteOrder(d.cmd);
+ sys::swapByteOrder(d.cmdsize);
+ sys::swapByteOrder(d.name);
+}
+
+inline void swapStruct(uuid_command &u) {
+ sys::swapByteOrder(u.cmd);
+ sys::swapByteOrder(u.cmdsize);
+}
+
+inline void swapStruct(rpath_command &r) {
+ sys::swapByteOrder(r.cmd);
+ sys::swapByteOrder(r.cmdsize);
+ sys::swapByteOrder(r.path);
+}
+
+inline void swapStruct(source_version_command &s) {
+ sys::swapByteOrder(s.cmd);
+ sys::swapByteOrder(s.cmdsize);
+ sys::swapByteOrder(s.version);
+}
+
+inline void swapStruct(entry_point_command &e) {
+ sys::swapByteOrder(e.cmd);
+ sys::swapByteOrder(e.cmdsize);
+ sys::swapByteOrder(e.entryoff);
+ sys::swapByteOrder(e.stacksize);
+}
+
+inline void swapStruct(encryption_info_command &e) {
+ sys::swapByteOrder(e.cmd);
+ sys::swapByteOrder(e.cmdsize);
+ sys::swapByteOrder(e.cryptoff);
+ sys::swapByteOrder(e.cryptsize);
+ sys::swapByteOrder(e.cryptid);
+}
+
+inline void swapStruct(encryption_info_command_64 &e) {
+ sys::swapByteOrder(e.cmd);
+ sys::swapByteOrder(e.cmdsize);
+ sys::swapByteOrder(e.cryptoff);
+ sys::swapByteOrder(e.cryptsize);
+ sys::swapByteOrder(e.cryptid);
+ sys::swapByteOrder(e.pad);
+}
+
+inline void swapStruct(dysymtab_command &dst) {
+ sys::swapByteOrder(dst.cmd);
+ sys::swapByteOrder(dst.cmdsize);
+ sys::swapByteOrder(dst.ilocalsym);
+ sys::swapByteOrder(dst.nlocalsym);
+ sys::swapByteOrder(dst.iextdefsym);
+ sys::swapByteOrder(dst.nextdefsym);
+ sys::swapByteOrder(dst.iundefsym);
+ sys::swapByteOrder(dst.nundefsym);
+ sys::swapByteOrder(dst.tocoff);
+ sys::swapByteOrder(dst.ntoc);
+ sys::swapByteOrder(dst.modtaboff);
+ sys::swapByteOrder(dst.nmodtab);
+ sys::swapByteOrder(dst.extrefsymoff);
+ sys::swapByteOrder(dst.nextrefsyms);
+ sys::swapByteOrder(dst.indirectsymoff);
+ sys::swapByteOrder(dst.nindirectsyms);
+ sys::swapByteOrder(dst.extreloff);
+ sys::swapByteOrder(dst.nextrel);
+ sys::swapByteOrder(dst.locreloff);
+ sys::swapByteOrder(dst.nlocrel);
+}
+
+inline void swapStruct(any_relocation_info &reloc) {
+ sys::swapByteOrder(reloc.r_word0);
+ sys::swapByteOrder(reloc.r_word1);
+}
+
+inline void swapStruct(nlist_base &S) {
+ sys::swapByteOrder(S.n_strx);
+ sys::swapByteOrder(S.n_desc);
+}
+
+inline void swapStruct(nlist &sym) {
+ sys::swapByteOrder(sym.n_strx);
+ sys::swapByteOrder(sym.n_desc);
+ sys::swapByteOrder(sym.n_value);
+}
+
+inline void swapStruct(nlist_64 &sym) {
+ sys::swapByteOrder(sym.n_strx);
+ sys::swapByteOrder(sym.n_desc);
+ sys::swapByteOrder(sym.n_value);
+}
+
+inline void swapStruct(linkedit_data_command &C) {
+ sys::swapByteOrder(C.cmd);
+ sys::swapByteOrder(C.cmdsize);
+ sys::swapByteOrder(C.dataoff);
+ sys::swapByteOrder(C.datasize);
+}
+
+inline void swapStruct(linker_option_command &C) {
+ sys::swapByteOrder(C.cmd);
+ sys::swapByteOrder(C.cmdsize);
+ sys::swapByteOrder(C.count);
+}
+
+inline void swapStruct(version_min_command &C) {
+ sys::swapByteOrder(C.cmd);
+ sys::swapByteOrder(C.cmdsize);
+ sys::swapByteOrder(C.version);
+ sys::swapByteOrder(C.sdk);
+}
+
+inline void swapStruct(note_command &C) {
+ sys::swapByteOrder(C.cmd);
+ sys::swapByteOrder(C.cmdsize);
+ sys::swapByteOrder(C.offset);
+ sys::swapByteOrder(C.size);
+}
+
+inline void swapStruct(build_version_command &C) {
+ sys::swapByteOrder(C.cmd);
+ sys::swapByteOrder(C.cmdsize);
+ sys::swapByteOrder(C.platform);
+ sys::swapByteOrder(C.minos);
+ sys::swapByteOrder(C.sdk);
+ sys::swapByteOrder(C.ntools);
+}
+
+inline void swapStruct(build_tool_version &C) {
+ sys::swapByteOrder(C.tool);
+ sys::swapByteOrder(C.version);
+}
+
+inline void swapStruct(data_in_code_entry &C) {
+ sys::swapByteOrder(C.offset);
+ sys::swapByteOrder(C.length);
+ sys::swapByteOrder(C.kind);
+}
+
+inline void swapStruct(uint32_t &C) { sys::swapByteOrder(C); }
+
+// The prebind_cksum_command is obsolete and no longer supported.
+inline void swapStruct(prebind_cksum_command &C) {
+ sys::swapByteOrder(C.cmd);
+ sys::swapByteOrder(C.cmdsize);
+ sys::swapByteOrder(C.cksum);
+}
+
+// The twolevel_hints_command is obsolete and no longer supported.
+inline void swapStruct(twolevel_hints_command &C) {
+ sys::swapByteOrder(C.cmd);
+ sys::swapByteOrder(C.cmdsize);
+ sys::swapByteOrder(C.offset);
+ sys::swapByteOrder(C.nhints);
+}
+
+// The prebound_dylib_command is obsolete and no longer supported.
+inline void swapStruct(prebound_dylib_command &C) {
+ sys::swapByteOrder(C.cmd);
+ sys::swapByteOrder(C.cmdsize);
+ sys::swapByteOrder(C.name);
+ sys::swapByteOrder(C.nmodules);
+ sys::swapByteOrder(C.linked_modules);
+}
+
+// The fvmfile_command is obsolete and no longer supported.
+inline void swapStruct(fvmfile_command &C) {
+ sys::swapByteOrder(C.cmd);
+ sys::swapByteOrder(C.cmdsize);
+ sys::swapByteOrder(C.name);
+ sys::swapByteOrder(C.header_addr);
+}
+
+// The symseg_command is obsolete and no longer supported.
+inline void swapStruct(symseg_command &C) {
+ sys::swapByteOrder(C.cmd);
+ sys::swapByteOrder(C.cmdsize);
+ sys::swapByteOrder(C.offset);
+ sys::swapByteOrder(C.size);
+}
+
+// The ident_command is obsolete and no longer supported.
+inline void swapStruct(ident_command &C) {
+ sys::swapByteOrder(C.cmd);
+ sys::swapByteOrder(C.cmdsize);
+}
+
+inline void swapStruct(fvmlib &C) {
+ sys::swapByteOrder(C.name);
+ sys::swapByteOrder(C.minor_version);
+ sys::swapByteOrder(C.header_addr);
+}
+
+// The fvmlib_command is obsolete and no longer supported.
+inline void swapStruct(fvmlib_command &C) {
+ sys::swapByteOrder(C.cmd);
+ sys::swapByteOrder(C.cmdsize);
+ swapStruct(C.fvmlib);
+}
+
+// Get/Set functions from <mach-o/nlist.h>
+
+static inline uint16_t GET_LIBRARY_ORDINAL(uint16_t n_desc) {
+ return (((n_desc) >> 8u) & 0xffu);
+}
+
+static inline void SET_LIBRARY_ORDINAL(uint16_t &n_desc, uint8_t ordinal) {
+ n_desc = (((n_desc)&0x00ff) | (((ordinal)&0xff) << 8));
+}
+
+static inline uint8_t GET_COMM_ALIGN(uint16_t n_desc) {
+ return (n_desc >> 8u) & 0x0fu;
+}
+
+static inline void SET_COMM_ALIGN(uint16_t &n_desc, uint8_t align) {
+ n_desc = ((n_desc & 0xf0ffu) | ((align & 0x0fu) << 8u));
+}
+
+// Enums from <mach/machine.h>
+enum : uint32_t {
+ // Capability bits used in the definition of cpu_type.
+ CPU_ARCH_MASK = 0xff000000, // Mask for architecture bits
+ CPU_ARCH_ABI64 = 0x01000000 // 64 bit ABI
+};
+
+// Constants for the cputype field.
+enum CPUType {
+ CPU_TYPE_ANY = -1,
+ CPU_TYPE_X86 = 7,
+ CPU_TYPE_I386 = CPU_TYPE_X86,
+ CPU_TYPE_X86_64 = CPU_TYPE_X86 | CPU_ARCH_ABI64,
+ /* CPU_TYPE_MIPS = 8, */
+ CPU_TYPE_MC98000 = 10, // Old Motorola PowerPC
+ CPU_TYPE_ARM = 12,
+ CPU_TYPE_ARM64 = CPU_TYPE_ARM | CPU_ARCH_ABI64,
+ CPU_TYPE_SPARC = 14,
+ CPU_TYPE_POWERPC = 18,
+ CPU_TYPE_POWERPC64 = CPU_TYPE_POWERPC | CPU_ARCH_ABI64
+};
+
+enum : uint32_t {
+ // Capability bits used in the definition of cpusubtype.
+ CPU_SUBTYPE_MASK = 0xff000000, // Mask for architecture bits
+ CPU_SUBTYPE_LIB64 = 0x80000000, // 64 bit libraries
+
+ // Special CPU subtype constants.
+ CPU_SUBTYPE_MULTIPLE = ~0u
+};
+
+// Constants for the cpusubtype field.
+enum CPUSubTypeX86 {
+ CPU_SUBTYPE_I386_ALL = 3,
+ CPU_SUBTYPE_386 = 3,
+ CPU_SUBTYPE_486 = 4,
+ CPU_SUBTYPE_486SX = 0x84,
+ CPU_SUBTYPE_586 = 5,
+ CPU_SUBTYPE_PENT = CPU_SUBTYPE_586,
+ CPU_SUBTYPE_PENTPRO = 0x16,
+ CPU_SUBTYPE_PENTII_M3 = 0x36,
+ CPU_SUBTYPE_PENTII_M5 = 0x56,
+ CPU_SUBTYPE_CELERON = 0x67,
+ CPU_SUBTYPE_CELERON_MOBILE = 0x77,
+ CPU_SUBTYPE_PENTIUM_3 = 0x08,
+ CPU_SUBTYPE_PENTIUM_3_M = 0x18,
+ CPU_SUBTYPE_PENTIUM_3_XEON = 0x28,
+ CPU_SUBTYPE_PENTIUM_M = 0x09,
+ CPU_SUBTYPE_PENTIUM_4 = 0x0a,
+ CPU_SUBTYPE_PENTIUM_4_M = 0x1a,
+ CPU_SUBTYPE_ITANIUM = 0x0b,
+ CPU_SUBTYPE_ITANIUM_2 = 0x1b,
+ CPU_SUBTYPE_XEON = 0x0c,
+ CPU_SUBTYPE_XEON_MP = 0x1c,
+
+ CPU_SUBTYPE_X86_ALL = 3,
+ CPU_SUBTYPE_X86_64_ALL = 3,
+ CPU_SUBTYPE_X86_ARCH1 = 4,
+ CPU_SUBTYPE_X86_64_H = 8
+};
+static inline int CPU_SUBTYPE_INTEL(int Family, int Model) {
+ return Family | (Model << 4);
+}
+static inline int CPU_SUBTYPE_INTEL_FAMILY(CPUSubTypeX86 ST) {
+ return ((int)ST) & 0x0f;
+}
+static inline int CPU_SUBTYPE_INTEL_MODEL(CPUSubTypeX86 ST) {
+ return ((int)ST) >> 4;
+}
+enum { CPU_SUBTYPE_INTEL_FAMILY_MAX = 15, CPU_SUBTYPE_INTEL_MODEL_ALL = 0 };
+
+enum CPUSubTypeARM {
+ CPU_SUBTYPE_ARM_ALL = 0,
+ CPU_SUBTYPE_ARM_V4T = 5,
+ CPU_SUBTYPE_ARM_V6 = 6,
+ CPU_SUBTYPE_ARM_V5 = 7,
+ CPU_SUBTYPE_ARM_V5TEJ = 7,
+ CPU_SUBTYPE_ARM_XSCALE = 8,
+ CPU_SUBTYPE_ARM_V7 = 9,
+ // unused ARM_V7F = 10,
+ CPU_SUBTYPE_ARM_V7S = 11,
+ CPU_SUBTYPE_ARM_V7K = 12,
+ CPU_SUBTYPE_ARM_V6M = 14,
+ CPU_SUBTYPE_ARM_V7M = 15,
+ CPU_SUBTYPE_ARM_V7EM = 16
+};
+
+enum CPUSubTypeARM64 { CPU_SUBTYPE_ARM64_ALL = 0 };
+
+enum CPUSubTypeSPARC { CPU_SUBTYPE_SPARC_ALL = 0 };
+
+enum CPUSubTypePowerPC {
+ CPU_SUBTYPE_POWERPC_ALL = 0,
+ CPU_SUBTYPE_POWERPC_601 = 1,
+ CPU_SUBTYPE_POWERPC_602 = 2,
+ CPU_SUBTYPE_POWERPC_603 = 3,
+ CPU_SUBTYPE_POWERPC_603e = 4,
+ CPU_SUBTYPE_POWERPC_603ev = 5,
+ CPU_SUBTYPE_POWERPC_604 = 6,
+ CPU_SUBTYPE_POWERPC_604e = 7,
+ CPU_SUBTYPE_POWERPC_620 = 8,
+ CPU_SUBTYPE_POWERPC_750 = 9,
+ CPU_SUBTYPE_POWERPC_7400 = 10,
+ CPU_SUBTYPE_POWERPC_7450 = 11,
+ CPU_SUBTYPE_POWERPC_970 = 100,
+
+ CPU_SUBTYPE_MC980000_ALL = CPU_SUBTYPE_POWERPC_ALL,
+ CPU_SUBTYPE_MC98601 = CPU_SUBTYPE_POWERPC_601
+};
+
+struct x86_thread_state32_t {
+ uint32_t eax;
+ uint32_t ebx;
+ uint32_t ecx;
+ uint32_t edx;
+ uint32_t edi;
+ uint32_t esi;
+ uint32_t ebp;
+ uint32_t esp;
+ uint32_t ss;
+ uint32_t eflags;
+ uint32_t eip;
+ uint32_t cs;
+ uint32_t ds;
+ uint32_t es;
+ uint32_t fs;
+ uint32_t gs;
+};
+
+struct x86_thread_state64_t {
+ uint64_t rax;
+ uint64_t rbx;
+ uint64_t rcx;
+ uint64_t rdx;
+ uint64_t rdi;
+ uint64_t rsi;
+ uint64_t rbp;
+ uint64_t rsp;
+ uint64_t r8;
+ uint64_t r9;
+ uint64_t r10;
+ uint64_t r11;
+ uint64_t r12;
+ uint64_t r13;
+ uint64_t r14;
+ uint64_t r15;
+ uint64_t rip;
+ uint64_t rflags;
+ uint64_t cs;
+ uint64_t fs;
+ uint64_t gs;
+};
+
+enum x86_fp_control_precis {
+ x86_FP_PREC_24B = 0,
+ x86_FP_PREC_53B = 2,
+ x86_FP_PREC_64B = 3
+};
+
+enum x86_fp_control_rc {
+ x86_FP_RND_NEAR = 0,
+ x86_FP_RND_DOWN = 1,
+ x86_FP_RND_UP = 2,
+ x86_FP_CHOP = 3
+};
+
+struct fp_control_t {
+ unsigned short invalid : 1, denorm : 1, zdiv : 1, ovrfl : 1, undfl : 1,
+ precis : 1, : 2, pc : 2, rc : 2, : 1, : 3;
+};
+
+struct fp_status_t {
+ unsigned short invalid : 1, denorm : 1, zdiv : 1, ovrfl : 1, undfl : 1,
+ precis : 1, stkflt : 1, errsumm : 1, c0 : 1, c1 : 1, c2 : 1, tos : 3,
+ c3 : 1, busy : 1;
+};
+
+struct mmst_reg_t {
+ char mmst_reg[10];
+ char mmst_rsrv[6];
+};
+
+struct xmm_reg_t {
+ char xmm_reg[16];
+};
+
+struct x86_float_state64_t {
+ int32_t fpu_reserved[2];
+ fp_control_t fpu_fcw;
+ fp_status_t fpu_fsw;
+ uint8_t fpu_ftw;
+ uint8_t fpu_rsrv1;
+ uint16_t fpu_fop;
+ uint32_t fpu_ip;
+ uint16_t fpu_cs;
+ uint16_t fpu_rsrv2;
+ uint32_t fpu_dp;
+ uint16_t fpu_ds;
+ uint16_t fpu_rsrv3;
+ uint32_t fpu_mxcsr;
+ uint32_t fpu_mxcsrmask;
+ mmst_reg_t fpu_stmm0;
+ mmst_reg_t fpu_stmm1;
+ mmst_reg_t fpu_stmm2;
+ mmst_reg_t fpu_stmm3;
+ mmst_reg_t fpu_stmm4;
+ mmst_reg_t fpu_stmm5;
+ mmst_reg_t fpu_stmm6;
+ mmst_reg_t fpu_stmm7;
+ xmm_reg_t fpu_xmm0;
+ xmm_reg_t fpu_xmm1;
+ xmm_reg_t fpu_xmm2;
+ xmm_reg_t fpu_xmm3;
+ xmm_reg_t fpu_xmm4;
+ xmm_reg_t fpu_xmm5;
+ xmm_reg_t fpu_xmm6;
+ xmm_reg_t fpu_xmm7;
+ xmm_reg_t fpu_xmm8;
+ xmm_reg_t fpu_xmm9;
+ xmm_reg_t fpu_xmm10;
+ xmm_reg_t fpu_xmm11;
+ xmm_reg_t fpu_xmm12;
+ xmm_reg_t fpu_xmm13;
+ xmm_reg_t fpu_xmm14;
+ xmm_reg_t fpu_xmm15;
+ char fpu_rsrv4[6 * 16];
+ uint32_t fpu_reserved1;
+};
+
+struct x86_exception_state64_t {
+ uint16_t trapno;
+ uint16_t cpu;
+ uint32_t err;
+ uint64_t faultvaddr;
+};
+
+inline void swapStruct(x86_thread_state32_t &x) {
+ sys::swapByteOrder(x.eax);
+ sys::swapByteOrder(x.ebx);
+ sys::swapByteOrder(x.ecx);
+ sys::swapByteOrder(x.edx);
+ sys::swapByteOrder(x.edi);
+ sys::swapByteOrder(x.esi);
+ sys::swapByteOrder(x.ebp);
+ sys::swapByteOrder(x.esp);
+ sys::swapByteOrder(x.ss);
+ sys::swapByteOrder(x.eflags);
+ sys::swapByteOrder(x.eip);
+ sys::swapByteOrder(x.cs);
+ sys::swapByteOrder(x.ds);
+ sys::swapByteOrder(x.es);
+ sys::swapByteOrder(x.fs);
+ sys::swapByteOrder(x.gs);
+}
+
+inline void swapStruct(x86_thread_state64_t &x) {
+ sys::swapByteOrder(x.rax);
+ sys::swapByteOrder(x.rbx);
+ sys::swapByteOrder(x.rcx);
+ sys::swapByteOrder(x.rdx);
+ sys::swapByteOrder(x.rdi);
+ sys::swapByteOrder(x.rsi);
+ sys::swapByteOrder(x.rbp);
+ sys::swapByteOrder(x.rsp);
+ sys::swapByteOrder(x.r8);
+ sys::swapByteOrder(x.r9);
+ sys::swapByteOrder(x.r10);
+ sys::swapByteOrder(x.r11);
+ sys::swapByteOrder(x.r12);
+ sys::swapByteOrder(x.r13);
+ sys::swapByteOrder(x.r14);
+ sys::swapByteOrder(x.r15);
+ sys::swapByteOrder(x.rip);
+ sys::swapByteOrder(x.rflags);
+ sys::swapByteOrder(x.cs);
+ sys::swapByteOrder(x.fs);
+ sys::swapByteOrder(x.gs);
+}
+
+inline void swapStruct(x86_float_state64_t &x) {
+ sys::swapByteOrder(x.fpu_reserved[0]);
+ sys::swapByteOrder(x.fpu_reserved[1]);
+ // TODO swap: fp_control_t fpu_fcw;
+ // TODO swap: fp_status_t fpu_fsw;
+ sys::swapByteOrder(x.fpu_fop);
+ sys::swapByteOrder(x.fpu_ip);
+ sys::swapByteOrder(x.fpu_cs);
+ sys::swapByteOrder(x.fpu_rsrv2);
+ sys::swapByteOrder(x.fpu_dp);
+ sys::swapByteOrder(x.fpu_ds);
+ sys::swapByteOrder(x.fpu_rsrv3);
+ sys::swapByteOrder(x.fpu_mxcsr);
+ sys::swapByteOrder(x.fpu_mxcsrmask);
+ sys::swapByteOrder(x.fpu_reserved1);
+}
+
+inline void swapStruct(x86_exception_state64_t &x) {
+ sys::swapByteOrder(x.trapno);
+ sys::swapByteOrder(x.cpu);
+ sys::swapByteOrder(x.err);
+ sys::swapByteOrder(x.faultvaddr);
+}
+
+struct x86_state_hdr_t {
+ uint32_t flavor;
+ uint32_t count;
+};
+
+struct x86_thread_state_t {
+ x86_state_hdr_t tsh;
+ union {
+ x86_thread_state64_t ts64;
+ x86_thread_state32_t ts32;
+ } uts;
+};
+
+struct x86_float_state_t {
+ x86_state_hdr_t fsh;
+ union {
+ x86_float_state64_t fs64;
+ } ufs;
+};
+
+struct x86_exception_state_t {
+ x86_state_hdr_t esh;
+ union {
+ x86_exception_state64_t es64;
+ } ues;
+};
+
+inline void swapStruct(x86_state_hdr_t &x) {
+ sys::swapByteOrder(x.flavor);
+ sys::swapByteOrder(x.count);
+}
+
+enum X86ThreadFlavors {
+ x86_THREAD_STATE32 = 1,
+ x86_FLOAT_STATE32 = 2,
+ x86_EXCEPTION_STATE32 = 3,
+ x86_THREAD_STATE64 = 4,
+ x86_FLOAT_STATE64 = 5,
+ x86_EXCEPTION_STATE64 = 6,
+ x86_THREAD_STATE = 7,
+ x86_FLOAT_STATE = 8,
+ x86_EXCEPTION_STATE = 9,
+ x86_DEBUG_STATE32 = 10,
+ x86_DEBUG_STATE64 = 11,
+ x86_DEBUG_STATE = 12
+};
+
+inline void swapStruct(x86_thread_state_t &x) {
+ swapStruct(x.tsh);
+ if (x.tsh.flavor == x86_THREAD_STATE64)
+ swapStruct(x.uts.ts64);
+}
+
+inline void swapStruct(x86_float_state_t &x) {
+ swapStruct(x.fsh);
+ if (x.fsh.flavor == x86_FLOAT_STATE64)
+ swapStruct(x.ufs.fs64);
+}
+
+inline void swapStruct(x86_exception_state_t &x) {
+ swapStruct(x.esh);
+ if (x.esh.flavor == x86_EXCEPTION_STATE64)
+ swapStruct(x.ues.es64);
+}
+
+const uint32_t x86_THREAD_STATE32_COUNT =
+ sizeof(x86_thread_state32_t) / sizeof(uint32_t);
+
+const uint32_t x86_THREAD_STATE64_COUNT =
+ sizeof(x86_thread_state64_t) / sizeof(uint32_t);
+const uint32_t x86_FLOAT_STATE64_COUNT =
+ sizeof(x86_float_state64_t) / sizeof(uint32_t);
+const uint32_t x86_EXCEPTION_STATE64_COUNT =
+ sizeof(x86_exception_state64_t) / sizeof(uint32_t);
+
+const uint32_t x86_THREAD_STATE_COUNT =
+ sizeof(x86_thread_state_t) / sizeof(uint32_t);
+const uint32_t x86_FLOAT_STATE_COUNT =
+ sizeof(x86_float_state_t) / sizeof(uint32_t);
+const uint32_t x86_EXCEPTION_STATE_COUNT =
+ sizeof(x86_exception_state_t) / sizeof(uint32_t);
+
+struct arm_thread_state32_t {
+ uint32_t r[13];
+ uint32_t sp;
+ uint32_t lr;
+ uint32_t pc;
+ uint32_t cpsr;
+};
+
+inline void swapStruct(arm_thread_state32_t &x) {
+ for (int i = 0; i < 13; i++)
+ sys::swapByteOrder(x.r[i]);
+ sys::swapByteOrder(x.sp);
+ sys::swapByteOrder(x.lr);
+ sys::swapByteOrder(x.pc);
+ sys::swapByteOrder(x.cpsr);
+}
+
+struct arm_thread_state64_t {
+ uint64_t x[29];
+ uint64_t fp;
+ uint64_t lr;
+ uint64_t sp;
+ uint64_t pc;
+ uint32_t cpsr;
+ uint32_t pad;
+};
+
+inline void swapStruct(arm_thread_state64_t &x) {
+ for (int i = 0; i < 29; i++)
+ sys::swapByteOrder(x.x[i]);
+ sys::swapByteOrder(x.fp);
+ sys::swapByteOrder(x.lr);
+ sys::swapByteOrder(x.sp);
+ sys::swapByteOrder(x.pc);
+ sys::swapByteOrder(x.cpsr);
+}
+
+struct arm_state_hdr_t {
+ uint32_t flavor;
+ uint32_t count;
+};
+
+struct arm_thread_state_t {
+ arm_state_hdr_t tsh;
+ union {
+ arm_thread_state32_t ts32;
+ } uts;
+};
+
+inline void swapStruct(arm_state_hdr_t &x) {
+ sys::swapByteOrder(x.flavor);
+ sys::swapByteOrder(x.count);
+}
+
+enum ARMThreadFlavors {
+ ARM_THREAD_STATE = 1,
+ ARM_VFP_STATE = 2,
+ ARM_EXCEPTION_STATE = 3,
+ ARM_DEBUG_STATE = 4,
+ ARN_THREAD_STATE_NONE = 5,
+ ARM_THREAD_STATE64 = 6,
+ ARM_EXCEPTION_STATE64 = 7
+};
+
+inline void swapStruct(arm_thread_state_t &x) {
+ swapStruct(x.tsh);
+ if (x.tsh.flavor == ARM_THREAD_STATE)
+ swapStruct(x.uts.ts32);
+}
+
+const uint32_t ARM_THREAD_STATE_COUNT =
+ sizeof(arm_thread_state32_t) / sizeof(uint32_t);
+
+const uint32_t ARM_THREAD_STATE64_COUNT =
+ sizeof(arm_thread_state64_t) / sizeof(uint32_t);
+
+struct ppc_thread_state32_t {
+ uint32_t srr0;
+ uint32_t srr1;
+ uint32_t r0;
+ uint32_t r1;
+ uint32_t r2;
+ uint32_t r3;
+ uint32_t r4;
+ uint32_t r5;
+ uint32_t r6;
+ uint32_t r7;
+ uint32_t r8;
+ uint32_t r9;
+ uint32_t r10;
+ uint32_t r11;
+ uint32_t r12;
+ uint32_t r13;
+ uint32_t r14;
+ uint32_t r15;
+ uint32_t r16;
+ uint32_t r17;
+ uint32_t r18;
+ uint32_t r19;
+ uint32_t r20;
+ uint32_t r21;
+ uint32_t r22;
+ uint32_t r23;
+ uint32_t r24;
+ uint32_t r25;
+ uint32_t r26;
+ uint32_t r27;
+ uint32_t r28;
+ uint32_t r29;
+ uint32_t r30;
+ uint32_t r31;
+ uint32_t ct;
+ uint32_t xer;
+ uint32_t lr;
+ uint32_t ctr;
+ uint32_t mq;
+ uint32_t vrsave;
+};
+
+inline void swapStruct(ppc_thread_state32_t &x) {
+ sys::swapByteOrder(x.srr0);
+ sys::swapByteOrder(x.srr1);
+ sys::swapByteOrder(x.r0);
+ sys::swapByteOrder(x.r1);
+ sys::swapByteOrder(x.r2);
+ sys::swapByteOrder(x.r3);
+ sys::swapByteOrder(x.r4);
+ sys::swapByteOrder(x.r5);
+ sys::swapByteOrder(x.r6);
+ sys::swapByteOrder(x.r7);
+ sys::swapByteOrder(x.r8);
+ sys::swapByteOrder(x.r9);
+ sys::swapByteOrder(x.r10);
+ sys::swapByteOrder(x.r11);
+ sys::swapByteOrder(x.r12);
+ sys::swapByteOrder(x.r13);
+ sys::swapByteOrder(x.r14);
+ sys::swapByteOrder(x.r15);
+ sys::swapByteOrder(x.r16);
+ sys::swapByteOrder(x.r17);
+ sys::swapByteOrder(x.r18);
+ sys::swapByteOrder(x.r19);
+ sys::swapByteOrder(x.r20);
+ sys::swapByteOrder(x.r21);
+ sys::swapByteOrder(x.r22);
+ sys::swapByteOrder(x.r23);
+ sys::swapByteOrder(x.r24);
+ sys::swapByteOrder(x.r25);
+ sys::swapByteOrder(x.r26);
+ sys::swapByteOrder(x.r27);
+ sys::swapByteOrder(x.r28);
+ sys::swapByteOrder(x.r29);
+ sys::swapByteOrder(x.r30);
+ sys::swapByteOrder(x.r31);
+ sys::swapByteOrder(x.ct);
+ sys::swapByteOrder(x.xer);
+ sys::swapByteOrder(x.lr);
+ sys::swapByteOrder(x.ctr);
+ sys::swapByteOrder(x.mq);
+ sys::swapByteOrder(x.vrsave);
+}
+
+struct ppc_state_hdr_t {
+ uint32_t flavor;
+ uint32_t count;
+};
+
+struct ppc_thread_state_t {
+ ppc_state_hdr_t tsh;
+ union {
+ ppc_thread_state32_t ts32;
+ } uts;
+};
+
+inline void swapStruct(ppc_state_hdr_t &x) {
+ sys::swapByteOrder(x.flavor);
+ sys::swapByteOrder(x.count);
+}
+
+enum PPCThreadFlavors {
+ PPC_THREAD_STATE = 1,
+ PPC_FLOAT_STATE = 2,
+ PPC_EXCEPTION_STATE = 3,
+ PPC_VECTOR_STATE = 4,
+ PPC_THREAD_STATE64 = 5,
+ PPC_EXCEPTION_STATE64 = 6,
+ PPC_THREAD_STATE_NONE = 7
+};
+
+inline void swapStruct(ppc_thread_state_t &x) {
+ swapStruct(x.tsh);
+ if (x.tsh.flavor == PPC_THREAD_STATE)
+ swapStruct(x.uts.ts32);
+}
+
+const uint32_t PPC_THREAD_STATE_COUNT =
+ sizeof(ppc_thread_state32_t) / sizeof(uint32_t);
+
+// Define a union of all load command structs
+#define LOAD_COMMAND_STRUCT(LCStruct) LCStruct LCStruct##_data;
+
+union macho_load_command {
+#include "llvm/BinaryFormat/MachO.def"
+};
+
+} // end namespace MachO
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/BinaryFormat/Magic.h b/contrib/llvm/include/llvm/BinaryFormat/Magic.h
new file mode 100644
index 0000000..c0e23db
--- /dev/null
+++ b/contrib/llvm/include/llvm/BinaryFormat/Magic.h
@@ -0,0 +1,73 @@
+//===- llvm/BinaryFormat/Magic.h - File magic identification ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#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 {
+/// file_magic - An "enum class" enumeration of file types based on magic (the
+/// first N bytes of the file).
+struct file_magic {
+ enum Impl {
+ unknown = 0, ///< Unrecognized file
+ bitcode, ///< Bitcode file
+ archive, ///< ar style archive file
+ elf, ///< ELF Unknown type
+ elf_relocatable, ///< ELF Relocatable object file
+ elf_executable, ///< ELF Executable image
+ elf_shared_object, ///< ELF dynamically linked shared lib
+ elf_core, ///< ELF core image
+ macho_object, ///< Mach-O Object file
+ macho_executable, ///< Mach-O Executable
+ macho_fixed_virtual_memory_shared_lib, ///< Mach-O Shared Lib, FVM
+ macho_core, ///< Mach-O Core File
+ macho_preload_executable, ///< Mach-O Preloaded Executable
+ macho_dynamically_linked_shared_lib, ///< Mach-O dynlinked shared lib
+ macho_dynamic_linker, ///< The Mach-O dynamic linker
+ macho_bundle, ///< Mach-O Bundle file
+ macho_dynamically_linked_shared_lib_stub, ///< Mach-O Shared lib stub
+ macho_dsym_companion, ///< Mach-O dSYM companion file
+ macho_kext_bundle, ///< Mach-O kext bundle file
+ macho_universal_binary, ///< Mach-O universal binary
+ coff_cl_gl_object, ///< Microsoft cl.exe's intermediate code file
+ coff_object, ///< COFF object file
+ coff_import_library, ///< COFF import library
+ pecoff_executable, ///< PECOFF executable file
+ windows_resource, ///< Windows compiled resource file (.res)
+ wasm_object ///< WebAssembly Object file
+ };
+
+ bool is_object() const { return V != unknown; }
+
+ file_magic() = default;
+ file_magic(Impl V) : V(V) {}
+ operator Impl() const { return V; }
+
+private:
+ Impl V = unknown;
+};
+
+/// @brief Identify the type of a binary file based on how magical it is.
+file_magic identify_magic(StringRef magic);
+
+/// @brief Get and identify \a path's type based on its content.
+///
+/// @param path Input path.
+/// @param result Set to the type of file, or file_magic::unknown.
+/// @returns errc::success if result has been successfully set, otherwise a
+/// platform-specific error_code.
+std::error_code identify_magic(const Twine &path, file_magic &result);
+} // namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/BinaryFormat/Wasm.h b/contrib/llvm/include/llvm/BinaryFormat/Wasm.h
new file mode 100644
index 0000000..23e30b7
--- /dev/null
+++ b/contrib/llvm/include/llvm/BinaryFormat/Wasm.h
@@ -0,0 +1,217 @@
+//===- Wasm.h - Wasm object file format -------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines manifest constants for the wasm object file format.
+// See: https://github.com/WebAssembly/design/blob/master/BinaryEncoding.md
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_BINARYFORMAT_WASM_H
+#define LLVM_BINARYFORMAT_WASM_H
+
+#include "llvm/ADT/ArrayRef.h"
+
+namespace llvm {
+namespace wasm {
+
+// Object file magic string.
+const char WasmMagic[] = {'\0', 'a', 's', 'm'};
+// Wasm binary format version
+const uint32_t WasmVersion = 0x1;
+// Wasm uses a 64k page size
+const uint32_t WasmPageSize = 65536;
+
+struct WasmObjectHeader {
+ StringRef Magic;
+ uint32_t Version;
+};
+
+struct WasmSignature {
+ std::vector<int32_t> ParamTypes;
+ int32_t ReturnType;
+};
+
+struct WasmExport {
+ StringRef Name;
+ uint32_t Kind;
+ uint32_t Index;
+};
+
+struct WasmLimits {
+ uint32_t Flags;
+ uint32_t Initial;
+ uint32_t Maximum;
+};
+
+struct WasmTable {
+ int32_t ElemType;
+ WasmLimits Limits;
+};
+
+struct WasmInitExpr {
+ uint8_t Opcode;
+ union {
+ int32_t Int32;
+ int64_t Int64;
+ int32_t Float32;
+ int64_t Float64;
+ uint32_t Global;
+ } Value;
+};
+
+struct WasmGlobal {
+ int32_t Type;
+ bool Mutable;
+ WasmInitExpr InitExpr;
+};
+
+struct WasmImport {
+ StringRef Module;
+ StringRef Field;
+ uint32_t Kind;
+ union {
+ uint32_t SigIndex;
+ WasmGlobal Global;
+ WasmTable Table;
+ WasmLimits Memory;
+ };
+};
+
+struct WasmLocalDecl {
+ int32_t Type;
+ uint32_t Count;
+};
+
+struct WasmFunction {
+ std::vector<WasmLocalDecl> Locals;
+ ArrayRef<uint8_t> Body;
+};
+
+struct WasmDataSegment {
+ uint32_t MemoryIndex;
+ WasmInitExpr Offset;
+ ArrayRef<uint8_t> Content;
+};
+
+struct WasmElemSegment {
+ uint32_t TableIndex;
+ WasmInitExpr Offset;
+ std::vector<uint32_t> Functions;
+};
+
+struct WasmRelocation {
+ uint32_t Type; // The type of the relocation.
+ uint32_t Index; // Index into function to global index space.
+ uint64_t Offset; // Offset from the start of the section.
+ int64_t Addend; // A value to add to the symbol.
+};
+
+struct WasmLinkingData {
+ uint32_t DataSize;
+ uint32_t DataAlignment;
+};
+
+enum : unsigned {
+ WASM_SEC_CUSTOM = 0, // Custom / User-defined section
+ WASM_SEC_TYPE = 1, // Function signature declarations
+ WASM_SEC_IMPORT = 2, // Import declarations
+ WASM_SEC_FUNCTION = 3, // Function declarations
+ WASM_SEC_TABLE = 4, // Indirect function table and other tables
+ WASM_SEC_MEMORY = 5, // Memory attributes
+ WASM_SEC_GLOBAL = 6, // Global declarations
+ WASM_SEC_EXPORT = 7, // Exports
+ WASM_SEC_START = 8, // Start function declaration
+ WASM_SEC_ELEM = 9, // Elements section
+ WASM_SEC_CODE = 10, // Function bodies (code)
+ WASM_SEC_DATA = 11 // Data segments
+};
+
+// Type immediate encodings used in various contexts.
+enum {
+ WASM_TYPE_I32 = -0x01,
+ WASM_TYPE_I64 = -0x02,
+ WASM_TYPE_F32 = -0x03,
+ WASM_TYPE_F64 = -0x04,
+ WASM_TYPE_ANYFUNC = -0x10,
+ WASM_TYPE_FUNC = -0x20,
+ WASM_TYPE_NORESULT = -0x40, // for blocks with no result values
+};
+
+// Kinds of externals (for imports and exports).
+enum : unsigned {
+ WASM_EXTERNAL_FUNCTION = 0x0,
+ WASM_EXTERNAL_TABLE = 0x1,
+ WASM_EXTERNAL_MEMORY = 0x2,
+ WASM_EXTERNAL_GLOBAL = 0x3,
+};
+
+// Opcodes used in initializer expressions.
+enum : unsigned {
+ WASM_OPCODE_END = 0x0b,
+ WASM_OPCODE_GET_GLOBAL = 0x23,
+ WASM_OPCODE_I32_CONST = 0x41,
+ WASM_OPCODE_I64_CONST = 0x42,
+ WASM_OPCODE_F32_CONST = 0x43,
+ WASM_OPCODE_F64_CONST = 0x44,
+};
+
+enum : unsigned {
+ WASM_NAMES_FUNCTION = 0x1,
+ WASM_NAMES_LOCAL = 0x2,
+};
+
+enum : unsigned {
+ WASM_LIMITS_FLAG_HAS_MAX = 0x1,
+};
+
+// Subset of types that a value can have
+enum class ValType {
+ I32 = WASM_TYPE_I32,
+ I64 = WASM_TYPE_I64,
+ F32 = WASM_TYPE_F32,
+ F64 = WASM_TYPE_F64,
+};
+
+// Linking metadata kinds.
+enum : unsigned {
+ WASM_STACK_POINTER = 0x1,
+ WASM_SYMBOL_INFO = 0x2,
+ WASM_DATA_SIZE = 0x3,
+ WASM_DATA_ALIGNMENT = 0x4,
+};
+
+enum : unsigned {
+ WASM_SYMBOL_FLAG_WEAK = 0x1,
+};
+
+#define WASM_RELOC(name, value) name = value,
+
+enum : unsigned {
+#include "WasmRelocs/WebAssembly.def"
+};
+
+#undef WASM_RELOC
+
+struct Global {
+ ValType Type;
+ bool Mutable;
+
+ // The initial value for this global is either the value of an imported
+ // global, in which case InitialModule and InitialName specify the global
+ // import, or a value, in which case InitialModule is empty and InitialValue
+ // holds the value.
+ StringRef InitialModule;
+ StringRef InitialName;
+ uint64_t InitialValue;
+};
+
+} // end namespace wasm
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/BinaryFormat/WasmRelocs/WebAssembly.def b/contrib/llvm/include/llvm/BinaryFormat/WasmRelocs/WebAssembly.def
new file mode 100644
index 0000000..da64e02
--- /dev/null
+++ b/contrib/llvm/include/llvm/BinaryFormat/WasmRelocs/WebAssembly.def
@@ -0,0 +1,13 @@
+
+#ifndef WASM_RELOC
+#error "WASM_RELOC must be defined"
+#endif
+
+WASM_RELOC(R_WEBASSEMBLY_FUNCTION_INDEX_LEB, 0)
+WASM_RELOC(R_WEBASSEMBLY_TABLE_INDEX_SLEB, 1)
+WASM_RELOC(R_WEBASSEMBLY_TABLE_INDEX_I32, 2)
+WASM_RELOC(R_WEBASSEMBLY_GLOBAL_ADDR_LEB, 3)
+WASM_RELOC(R_WEBASSEMBLY_GLOBAL_ADDR_SLEB, 4)
+WASM_RELOC(R_WEBASSEMBLY_GLOBAL_ADDR_I32, 5)
+WASM_RELOC(R_WEBASSEMBLY_TYPE_INDEX_LEB, 6)
+WASM_RELOC(R_WEBASSEMBLY_GLOBAL_INDEX_LEB, 7)
diff --git a/contrib/llvm/include/llvm/Bitcode/BitcodeReader.h b/contrib/llvm/include/llvm/Bitcode/BitcodeReader.h
index 9e042b1..160ddad 100644
--- a/contrib/llvm/include/llvm/Bitcode/BitcodeReader.h
+++ b/contrib/llvm/include/llvm/Bitcode/BitcodeReader.h
@@ -40,12 +40,23 @@ namespace llvm {
return std::move(*Val);
}
+ struct BitcodeFileContents;
+
+ /// Basic information extracted from a bitcode module to be used for LTO.
+ struct BitcodeLTOInfo {
+ bool IsThinLTO;
+ bool HasSummary;
+ };
+
/// Represents a module in a bitcode file.
class BitcodeModule {
// This covers the identification (if present) and module blocks.
ArrayRef<uint8_t> Buffer;
StringRef ModuleIdentifier;
+ // The string table used to interpret this module.
+ StringRef Strtab;
+
// The bitstream location of the IDENTIFICATION_BLOCK.
uint64_t IdentificationBit;
@@ -58,8 +69,8 @@ namespace llvm {
IdentificationBit(IdentificationBit), ModuleBit(ModuleBit) {}
// Calls the ctor.
- friend Expected<std::vector<BitcodeModule>>
- getBitcodeModuleList(MemoryBufferRef Buffer);
+ friend Expected<BitcodeFileContents>
+ getBitcodeFileContents(MemoryBufferRef Buffer);
Expected<std::unique_ptr<Module>> getModuleImpl(LLVMContext &Context,
bool MaterializeAll,
@@ -70,6 +81,7 @@ namespace llvm {
StringRef getBuffer() const {
return StringRef((const char *)Buffer.begin(), Buffer.size());
}
+ StringRef getStrtab() const { return Strtab; }
StringRef getModuleIdentifier() const { return ModuleIdentifier; }
@@ -84,13 +96,31 @@ namespace llvm {
/// Read the entire bitcode module and return it.
Expected<std::unique_ptr<Module>> parseModule(LLVMContext &Context);
- /// Check if the given bitcode buffer contains a summary block.
- Expected<bool> hasSummary();
+ /// Returns information about the module to be used for LTO: whether to
+ /// compile with ThinLTO, and whether it has a summary.
+ Expected<BitcodeLTOInfo> getLTOInfo();
/// Parse the specified bitcode buffer, returning the module summary index.
Expected<std::unique_ptr<ModuleSummaryIndex>> getSummary();
+
+ /// Parse the specified bitcode buffer and merge its module summary index
+ /// into CombinedIndex.
+ Error readSummary(ModuleSummaryIndex &CombinedIndex, StringRef ModulePath,
+ uint64_t ModuleId);
};
+ struct BitcodeFileContents {
+ std::vector<BitcodeModule> Mods;
+ StringRef Symtab, StrtabForSymtab;
+ };
+
+ /// Returns the contents of a bitcode file. This includes the raw contents of
+ /// the symbol table embedded in the bitcode file. Clients which require a
+ /// symbol table should prefer to use irsymtab::read instead of this function
+ /// because it creates a reader for the irsymtab and handles upgrading bitcode
+ /// files without a symbol table or with an old symbol table.
+ Expected<BitcodeFileContents> getBitcodeFileContents(MemoryBufferRef Buffer);
+
/// Returns a list of modules in the specified bitcode buffer.
Expected<std::vector<BitcodeModule>>
getBitcodeModuleList(MemoryBufferRef Buffer);
@@ -130,13 +160,26 @@ namespace llvm {
Expected<std::unique_ptr<Module>> parseBitcodeFile(MemoryBufferRef Buffer,
LLVMContext &Context);
- /// Check if the given bitcode buffer contains a summary block.
- Expected<bool> hasGlobalValueSummary(MemoryBufferRef Buffer);
+ /// Returns LTO information for the specified bitcode file.
+ Expected<BitcodeLTOInfo> getBitcodeLTOInfo(MemoryBufferRef Buffer);
/// Parse the specified bitcode buffer, returning the module summary index.
Expected<std::unique_ptr<ModuleSummaryIndex>>
getModuleSummaryIndex(MemoryBufferRef Buffer);
+ /// Parse the specified bitcode buffer and merge the index into CombinedIndex.
+ Error readModuleSummaryIndex(MemoryBufferRef Buffer,
+ ModuleSummaryIndex &CombinedIndex,
+ uint64_t ModuleId);
+
+ /// Parse the module summary index out of an IR file and return the module
+ /// summary index object if found, or an empty summary if not. If Path refers
+ /// to an empty file and IgnoreEmptyThinLTOIndexFile is true, then
+ /// this function will return nullptr.
+ Expected<std::unique_ptr<ModuleSummaryIndex>>
+ getModuleSummaryIndexForFile(StringRef Path,
+ bool IgnoreEmptyThinLTOIndexFile = false);
+
/// isBitcodeWrapper - Return true if the given bytes are the magic bytes
/// for an LLVM IR bitcode wrapper.
///
diff --git a/contrib/llvm/include/llvm/Bitcode/BitcodeWriter.h b/contrib/llvm/include/llvm/Bitcode/BitcodeWriter.h
index 4f72f98..f8b7fb3 100644
--- a/contrib/llvm/include/llvm/Bitcode/BitcodeWriter.h
+++ b/contrib/llvm/include/llvm/Bitcode/BitcodeWriter.h
@@ -15,6 +15,7 @@
#define LLVM_BITCODE_BITCODEWRITER_H
#include "llvm/IR/ModuleSummaryIndex.h"
+#include "llvm/MC/StringTableBuilder.h"
#include <string>
namespace llvm {
@@ -26,12 +27,41 @@ namespace llvm {
SmallVectorImpl<char> &Buffer;
std::unique_ptr<BitstreamWriter> Stream;
+ StringTableBuilder StrtabBuilder{StringTableBuilder::RAW};
+
+ // Owns any strings created by the irsymtab writer until we create the
+ // string table.
+ BumpPtrAllocator Alloc;
+
+ bool WroteStrtab = false, WroteSymtab = false;
+
+ void writeBlob(unsigned Block, unsigned Record, StringRef Blob);
+
+ std::vector<Module *> Mods;
+
public:
/// Create a BitcodeWriter that writes to Buffer.
BitcodeWriter(SmallVectorImpl<char> &Buffer);
~BitcodeWriter();
+ /// Attempt to write a symbol table to the bitcode file. This must be called
+ /// at most once after all modules have been written.
+ ///
+ /// A reader does not require a symbol table to interpret a bitcode file;
+ /// the symbol table is needed only to improve link-time performance. So
+ /// this function may decide not to write a symbol table. It may so decide
+ /// if, for example, the target is unregistered or the IR is malformed.
+ void writeSymtab();
+
+ /// Write the bitcode file's string table. This must be called exactly once
+ /// after all modules and the optional symbol table have been written.
+ void writeStrtab();
+
+ /// Copy the string table for another module into this bitcode file. This
+ /// should be called after copying the module itself into the bitcode file.
+ void copyStrtab(StringRef Strtab);
+
/// Write the specified module to the buffer specified at construction time.
///
/// If \c ShouldPreserveUseListOrder, encode the use-list order for each \a
@@ -43,9 +73,20 @@ namespace llvm {
///
/// \p GenerateHash enables hashing the Module and including the hash in the
/// bitcode (currently for use in ThinLTO incremental build).
+ ///
+ /// If \p ModHash is non-null, when GenerateHash is true, the resulting
+ /// hash is written into ModHash. When GenerateHash is false, that value
+ /// is used as the hash instead of computing from the generated bitcode.
+ /// Can be used to produce the same module hash for a minimized bitcode
+ /// used just for the thin link as in the regular full bitcode that will
+ /// be used in the backend.
void writeModule(const Module *M, bool ShouldPreserveUseListOrder = false,
const ModuleSummaryIndex *Index = nullptr,
- bool GenerateHash = false);
+ bool GenerateHash = false, ModuleHash *ModHash = nullptr);
+
+ void writeIndex(
+ const ModuleSummaryIndex *Index,
+ const std::map<std::string, GVSummaryMapTy> *ModuleToSummariesForIndex);
};
/// \brief Write the specified module to the specified raw output stream.
@@ -62,10 +103,18 @@ namespace llvm {
///
/// \p GenerateHash enables hashing the Module and including the hash in the
/// bitcode (currently for use in ThinLTO incremental build).
+ ///
+ /// If \p ModHash is non-null, when GenerateHash is true, the resulting
+ /// hash is written into ModHash. When GenerateHash is false, that value
+ /// is used as the hash instead of computing from the generated bitcode.
+ /// Can be used to produce the same module hash for a minimized bitcode
+ /// used just for the thin link as in the regular full bitcode that will
+ /// be used in the backend.
void WriteBitcodeToFile(const Module *M, raw_ostream &Out,
bool ShouldPreserveUseListOrder = false,
const ModuleSummaryIndex *Index = nullptr,
- bool GenerateHash = false);
+ bool GenerateHash = false,
+ ModuleHash *ModHash = nullptr);
/// Write the specified module summary index to the given raw output stream,
/// where it will be written in a new bitcode block. This is used when
diff --git a/contrib/llvm/include/llvm/Bitcode/LLVMBitCodes.h b/contrib/llvm/include/llvm/Bitcode/LLVMBitCodes.h
index c996c38..3777f95 100644
--- a/contrib/llvm/include/llvm/Bitcode/LLVMBitCodes.h
+++ b/contrib/llvm/include/llvm/Bitcode/LLVMBitCodes.h
@@ -22,7 +22,7 @@
namespace llvm {
namespace bitc {
-// The only top-level block type defined is for a module.
+// The only top-level block types are MODULE, IDENTIFICATION, STRTAB and SYMTAB.
enum BlockIDs {
// Blocks
MODULE_BLOCK_ID = FIRST_APPLICATION_BLOCKID,
@@ -52,7 +52,15 @@ enum BlockIDs {
OPERAND_BUNDLE_TAGS_BLOCK_ID,
- METADATA_KIND_BLOCK_ID
+ METADATA_KIND_BLOCK_ID,
+
+ STRTAB_BLOCK_ID,
+
+ FULL_LTO_GLOBALVAL_SUMMARY_BLOCK_ID,
+
+ SYMTAB_BLOCK_ID,
+
+ SYNC_SCOPE_NAMES_BLOCK_ID,
};
/// Identification block contains a string that describes the producer details,
@@ -92,9 +100,6 @@ enum ModuleCodes {
// ALIAS: [alias type, aliasee val#, linkage, visibility]
MODULE_CODE_ALIAS_OLD = 9,
- // MODULE_CODE_PURGEVALS: [numvals]
- MODULE_CODE_PURGEVALS = 10,
-
MODULE_CODE_GCNAME = 11, // GCNAME: [strchr x N]
MODULE_CODE_COMDAT = 12, // COMDAT: [selection_kind, name]
@@ -169,6 +174,10 @@ enum OperandBundleTagCode {
OPERAND_BUNDLE_TAG = 1, // TAG: [strchr x N]
};
+enum SyncScopeNameCode {
+ SYNC_SCOPE_NAME = 1,
+};
+
// Value symbol table codes.
enum ValueSymtabCodes {
VST_CODE_ENTRY = 1, // VST_ENTRY: [valueid, namechar x N]
@@ -213,8 +222,40 @@ enum GlobalValueSummarySymtabCodes {
FS_COMBINED_ORIGINAL_NAME = 9,
// VERSION of the summary, bumped when adding flags for instance.
FS_VERSION = 10,
- // The list of llvm.type.test type identifiers used by the following function.
+ // The list of llvm.type.test type identifiers used by the following function
+ // that are used other than by an llvm.assume.
+ // [n x typeid]
FS_TYPE_TESTS = 11,
+ // The list of virtual calls made by this function using
+ // llvm.assume(llvm.type.test) intrinsics that do not have all constant
+ // integer arguments.
+ // [n x (typeid, offset)]
+ FS_TYPE_TEST_ASSUME_VCALLS = 12,
+ // The list of virtual calls made by this function using
+ // llvm.type.checked.load intrinsics that do not have all constant integer
+ // arguments.
+ // [n x (typeid, offset)]
+ FS_TYPE_CHECKED_LOAD_VCALLS = 13,
+ // Identifies a virtual call made by this function using an
+ // llvm.assume(llvm.type.test) intrinsic with all constant integer arguments.
+ // [typeid, offset, n x arg]
+ FS_TYPE_TEST_ASSUME_CONST_VCALL = 14,
+ // Identifies a virtual call made by this function using an
+ // llvm.type.checked.load intrinsic with all constant integer arguments.
+ // [typeid, offset, n x arg]
+ FS_TYPE_CHECKED_LOAD_CONST_VCALL = 15,
+ // Assigns a GUID to a value ID. This normally appears only in combined
+ // summaries, but it can also appear in per-module summaries for PGO data.
+ // [valueid, guid]
+ FS_VALUE_GUID = 16,
+ // The list of local functions with CFI jump tables. Function names are
+ // strings in strtab.
+ // [n * name]
+ FS_CFI_FUNCTION_DEFS = 17,
+ // The list of external functions with CFI jump tables. Function names are
+ // strings in strtab.
+ // [n * name]
+ FS_CFI_FUNCTION_DECLS = 18,
};
enum MetadataCodes {
@@ -369,12 +410,6 @@ enum AtomicOrderingCodes {
ORDERING_SEQCST = 6
};
-/// Encoded SynchronizationScope values.
-enum AtomicSynchScopeCodes {
- SYNCHSCOPE_SINGLETHREAD = 0,
- SYNCHSCOPE_CROSSTHREAD = 1
-};
-
/// Markers and flags for call instruction.
enum CallMarkersFlags {
CALL_TAIL = 0,
@@ -522,7 +557,8 @@ enum AttributeKindCodes {
ATTR_KIND_INACCESSIBLEMEM_ONLY = 49,
ATTR_KIND_INACCESSIBLEMEM_OR_ARGMEMONLY = 50,
ATTR_KIND_ALLOC_SIZE = 51,
- ATTR_KIND_WRITEONLY = 52
+ ATTR_KIND_WRITEONLY = 52,
+ ATTR_KIND_SPECULATABLE = 53
};
enum ComdatSelectionKindCodes {
@@ -533,6 +569,14 @@ enum ComdatSelectionKindCodes {
COMDAT_SELECTION_KIND_SAME_SIZE = 5,
};
+enum StrtabCodes {
+ STRTAB_BLOB = 1,
+};
+
+enum SymtabCodes {
+ SYMTAB_BLOB = 1,
+};
+
} // End bitc namespace
} // End llvm namespace
diff --git a/contrib/llvm/include/llvm/CodeGen/Analysis.h b/contrib/llvm/include/llvm/CodeGen/Analysis.h
index f20185c..ba88f1f 100644
--- a/contrib/llvm/include/llvm/CodeGen/Analysis.h
+++ b/contrib/llvm/include/llvm/CodeGen/Analysis.h
@@ -123,13 +123,6 @@ bool returnTypeIsEligibleForTailCall(const Function *F, const Instruction *I,
const ReturnInst *Ret,
const TargetLoweringBase &TLI);
-// True if GV can be left out of the object symbol table. This is the case
-// for linkonce_odr values whose address is not significant. While legal, it is
-// not normally profitable to omit them from the .o symbol table. Using this
-// analysis makes sense when the information can be passed down to the linker
-// or we are in LTO.
-bool canBeOmittedFromSymbolTable(const GlobalValue *GV);
-
DenseMap<const MachineBasicBlock *, int>
getFuncletMembership(const MachineFunction &MF);
diff --git a/contrib/llvm/include/llvm/CodeGen/AsmPrinter.h b/contrib/llvm/include/llvm/CodeGen/AsmPrinter.h
index db3a6fc..60bbc9a 100644
--- a/contrib/llvm/include/llvm/CodeGen/AsmPrinter.h
+++ b/contrib/llvm/include/llvm/CodeGen/AsmPrinter.h
@@ -1,4 +1,4 @@
-//===-- llvm/CodeGen/AsmPrinter.h - AsmPrinter Framework --------*- C++ -*-===//
+//===- llvm/CodeGen/AsmPrinter.h - AsmPrinter Framework ---------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -17,36 +17,45 @@
#define LLVM_CODEGEN_ASMPRINTER_H
#include "llvm/ADT/MapVector.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
-#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/DwarfStringPoolEntry.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/IR/InlineAsm.h"
-#include "llvm/Support/DataTypes.h"
+#include "llvm/IR/LLVMContext.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/SourceMgr.h"
+#include <cstdint>
+#include <memory>
+#include <utility>
+#include <vector>
namespace llvm {
+
class AsmPrinterHandler;
+class BasicBlock;
class BlockAddress;
-class ByteStreamer;
-class GCStrategy;
class Constant;
class ConstantArray;
+class DataLayout;
class DIE;
class DIEAbbrev;
+class DwarfDebug;
class GCMetadataPrinter;
class GlobalIndirectSymbol;
+class GlobalObject;
class GlobalValue;
class GlobalVariable;
+class GCStrategy;
class MachineBasicBlock;
+class MachineConstantPoolValue;
class MachineFunction;
class MachineInstr;
-class MachineLocation;
-class MachineLoopInfo;
-class MachineLoop;
-class MachineConstantPoolValue;
class MachineJumpTableInfo;
+class MachineLoopInfo;
class MachineModuleInfo;
+class MachineOptimizationRemarkEmitter;
class MCAsmInfo;
class MCCFIInstruction;
class MCContext;
@@ -58,10 +67,9 @@ class MCSubtargetInfo;
class MCSymbol;
class MCTargetOptions;
class MDNode;
-class DwarfDebug;
-class Mangler;
+class Module;
+class raw_ostream;
class TargetLoweringObjectFile;
-class DataLayout;
class TargetMachine;
/// This class is intended to be used as a driving class for all asm writers.
@@ -85,33 +93,39 @@ public:
std::unique_ptr<MCStreamer> OutStreamer;
/// The current machine function.
- const MachineFunction *MF;
+ const MachineFunction *MF = nullptr;
/// This is a pointer to the current MachineModuleInfo.
- MachineModuleInfo *MMI;
+ MachineModuleInfo *MMI = nullptr;
+
+ /// Optimization remark emitter.
+ MachineOptimizationRemarkEmitter *ORE;
/// The symbol for the current function. This is recalculated at the beginning
/// of each call to runOnMachineFunction().
///
- MCSymbol *CurrentFnSym;
+ MCSymbol *CurrentFnSym = nullptr;
/// The symbol used to represent the start of the current function for the
/// purpose of calculating its size (e.g. using the .size directive). By
/// default, this is equal to CurrentFnSym.
- MCSymbol *CurrentFnSymForSize;
+ MCSymbol *CurrentFnSymForSize = nullptr;
/// Map global GOT equivalent MCSymbols to GlobalVariables and keep track of
/// its number of uses by other globals.
- typedef std::pair<const GlobalVariable *, unsigned> GOTEquivUsePair;
+ using GOTEquivUsePair = std::pair<const GlobalVariable *, unsigned>;
MapVector<const MCSymbol *, GOTEquivUsePair> GlobalGOTEquivs;
+ /// Enable print [latency:throughput] in output
+ bool EnablePrintSchedInfo = false;
+
private:
- MCSymbol *CurrentFnBegin;
- MCSymbol *CurrentFnEnd;
- MCSymbol *CurExceptionSym;
+ MCSymbol *CurrentFnBegin = nullptr;
+ MCSymbol *CurrentFnEnd = nullptr;
+ MCSymbol *CurExceptionSym = nullptr;
// The garbage collection metadata printer table.
- void *GCMetadataPrinters; // Really a DenseMap.
+ void *GCMetadataPrinters = nullptr; // Really a DenseMap.
/// Emit comments in assembly output if this is true.
///
@@ -119,7 +133,7 @@ private:
static char ID;
/// If VerboseAsm is set, a pointer to the loop info for this function.
- MachineLoopInfo *LI;
+ MachineLoopInfo *LI = nullptr;
struct HandlerInfo {
AsmPrinterHandler *Handler;
@@ -127,6 +141,7 @@ private:
const char *TimerDescription;
const char *TimerGroupName;
const char *TimerGroupDescription;
+
HandlerInfo(AsmPrinterHandler *Handler, const char *TimerName,
const char *TimerDescription, const char *TimerGroupName,
const char *TimerGroupDescription)
@@ -141,7 +156,7 @@ private:
public:
struct SrcMgrDiagInfo {
SourceMgr SrcMgr;
- const MDNode *LocInfo;
+ std::vector<const MDNode *> LocInfos;
LLVMContext::InlineAsmDiagHandlerTy DiagHandler;
void *DiagContext;
};
@@ -152,10 +167,10 @@ private:
mutable std::unique_ptr<SrcMgrDiagInfo> DiagInfo;
/// If the target supports dwarf debug info, this pointer is non-null.
- DwarfDebug *DD;
+ DwarfDebug *DD = nullptr;
/// If the current module uses dwarf CFI annotations strictly for debugging.
- bool isCFIMoveForDebugging;
+ bool isCFIMoveForDebugging = false;
protected:
explicit AsmPrinter(TargetMachine &TM, std::unique_ptr<MCStreamer> Streamer);
@@ -214,6 +229,8 @@ public:
FUNCTION_ENTER = 0,
FUNCTION_EXIT = 1,
TAIL_CALL = 2,
+ LOG_ARGS_ENTER = 3,
+ CUSTOM_EVENT = 4,
};
// The table will contain these structs that point to the sled, the function
@@ -230,7 +247,7 @@ public:
};
// All the sleds to be emitted.
- std::vector<XRayFunctionEntry> Sleds;
+ SmallVector<XRayFunctionEntry, 4> Sleds;
// Helper function to record a given XRay sled.
void recordSled(MCSymbol *Sled, const MachineInstr &MI, SledKind Kind);
@@ -395,7 +412,7 @@ public:
//===------------------------------------------------------------------===//
// Symbol Lowering Routines.
//===------------------------------------------------------------------===//
-public:
+
MCSymbol *createTempSymbol(const Twine &Name) const;
/// Return the MCSymbol for a private symbol with global value name as its
@@ -421,7 +438,7 @@ public:
//===------------------------------------------------------------------===//
// Emission Helper Routines.
//===------------------------------------------------------------------===//
-public:
+
/// This is just convenient handler for printing offsets.
void printOffset(int64_t Offset, raw_ostream &OS) const;
@@ -498,7 +515,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 EmitDebugThreadLocal(const MCExpr *Value, unsigned Size) const;
//===------------------------------------------------------------------===//
// Dwarf Lowering Routines
@@ -525,7 +542,7 @@ public:
//===------------------------------------------------------------------===//
// Inline Asm Support
//===------------------------------------------------------------------===//
-public:
+
// These are hooks that targets can override to implement inline asm
// support. These should probably be moved out of AsmPrinter someday.
@@ -569,9 +586,9 @@ public:
private:
/// Private state for PrintSpecial()
// Assign a unique ID to this machine instruction.
- mutable const MachineInstr *LastMI;
- mutable unsigned LastFn;
- mutable unsigned Counter;
+ mutable const MachineInstr *LastMI = nullptr;
+ mutable unsigned LastFn = 0;
+ mutable unsigned Counter = ~0U;
/// This method emits the header for the current function.
virtual void EmitFunctionHeader();
@@ -591,8 +608,8 @@ private:
// Internal Implementation Details
//===------------------------------------------------------------------===//
- /// This emits visibility information about symbol, if this is suported by the
- /// target.
+ /// This emits visibility information about symbol, if this is supported by
+ /// the target.
void EmitVisibility(MCSymbol *Sym, unsigned Visibility,
bool IsDefinition = true) const;
@@ -610,6 +627,7 @@ private:
void emitGlobalIndirectSymbol(Module &M,
const GlobalIndirectSymbol& GIS);
};
-}
-#endif
+} // end namespace llvm
+
+#endif // LLVM_CODEGEN_ASMPRINTER_H
diff --git a/contrib/llvm/include/llvm/CodeGen/AtomicExpandUtils.h b/contrib/llvm/include/llvm/CodeGen/AtomicExpandUtils.h
index ac18eac..1f9c96b 100644
--- a/contrib/llvm/include/llvm/CodeGen/AtomicExpandUtils.h
+++ b/contrib/llvm/include/llvm/CodeGen/AtomicExpandUtils.h
@@ -1,4 +1,4 @@
-//===-- AtomicExpandUtils.h - Utilities for expanding atomic instructions -===//
+//===- AtomicExpandUtils.h - Utilities for expanding atomic instructions --===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,19 +7,24 @@
//
//===----------------------------------------------------------------------===//
+#ifndef LLVM_CODEGEN_ATOMICEXPANDUTILS_H
+#define LLVM_CODEGEN_ATOMICEXPANDUTILS_H
+
#include "llvm/ADT/STLExtras.h"
#include "llvm/IR/IRBuilder.h"
+#include "llvm/Support/AtomicOrdering.h"
namespace llvm {
-class Value;
-class AtomicRMWInst;
+class AtomicRMWInst;
+class Value;
/// Parameters (see the expansion example below):
/// (the builder, %addr, %loaded, %new_val, ordering,
/// /* OUT */ %success, /* OUT */ %new_loaded)
-typedef function_ref<void(IRBuilder<> &, Value *, Value *, Value *,
- AtomicOrdering, Value *&, Value *&)> CreateCmpXchgInstFun;
+using CreateCmpXchgInstFun =
+ function_ref<void(IRBuilder<> &, Value *, Value *, Value *, AtomicOrdering,
+ Value *&, Value *&)>;
/// \brief Expand an atomic RMW instruction into a loop utilizing
/// cmpxchg. You'll want to make sure your target machine likes cmpxchg
@@ -42,7 +47,8 @@ typedef function_ref<void(IRBuilder<> &, Value *, Value *, Value *,
/// loop:
/// %loaded = phi iN [ %init_loaded, %entry ], [ %new_loaded, %loop ]
/// %new = some_op iN %loaded, %incr
-/// ; This is what -atomic-expand will produce using this function on i686 targets:
+/// ; This is what -atomic-expand will produce using this function on i686
+/// targets:
/// %pair = cmpxchg iN* %addr, iN %loaded, iN %new_val
/// %new_loaded = extractvalue { iN, i1 } %pair, 0
/// %success = extractvalue { iN, i1 } %pair, 1
@@ -52,6 +58,8 @@ typedef function_ref<void(IRBuilder<> &, Value *, Value *, Value *,
/// [...]
///
/// Returns true if the containing function was modified.
-bool
-expandAtomicRMWToCmpXchg(AtomicRMWInst *AI, CreateCmpXchgInstFun Factory);
-}
+bool expandAtomicRMWToCmpXchg(AtomicRMWInst *AI, CreateCmpXchgInstFun Factory);
+
+} // end namespace llvm
+
+#endif // LLVM_CODEGEN_ATOMICEXPANDUTILS_H
diff --git a/contrib/llvm/include/llvm/CodeGen/BasicTTIImpl.h b/contrib/llvm/include/llvm/CodeGen/BasicTTIImpl.h
index 7efdbcc..6331070 100644
--- a/contrib/llvm/include/llvm/CodeGen/BasicTTIImpl.h
+++ b/contrib/llvm/include/llvm/CodeGen/BasicTTIImpl.h
@@ -17,11 +17,11 @@
#define LLVM_CODEGEN_BASICTTIIMPL_H
#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/Analysis/TargetTransformInfoImpl.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Target/TargetLowering.h"
#include "llvm/Target/TargetSubtargetInfo.h"
-#include "llvm/Analysis/TargetLibraryInfo.h"
namespace llvm {
@@ -42,24 +42,6 @@ private:
typedef TargetTransformInfoImplCRTPBase<T> BaseT;
typedef TargetTransformInfo TTI;
- /// 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");
- unsigned Cost = 0;
-
- for (int i = 0, e = Ty->getVectorNumElements(); i < e; ++i) {
- if (Insert)
- Cost += static_cast<T *>(this)
- ->getVectorInstrCost(Instruction::InsertElement, Ty, i);
- if (Extract)
- Cost += static_cast<T *>(this)
- ->getVectorInstrCost(Instruction::ExtractElement, Ty, i);
- }
-
- return Cost;
- }
-
/// Estimate a cost of shuffle as a sequence of extract and insert
/// operations.
unsigned getPermuteShuffleOverhead(Type *Ty) {
@@ -111,6 +93,13 @@ public:
bool isSourceOfDivergence(const Value *V) { return false; }
+ bool isAlwaysUniform(const Value *V) { return false; }
+
+ unsigned getFlatAddressSpace() {
+ // Return an invalid address space.
+ return -1;
+ }
+
bool isLegalAddImmediate(int64_t imm) {
return getTLI()->isLegalAddImmediate(imm);
}
@@ -130,6 +119,10 @@ public:
return getTLI()->isLegalAddressingMode(DL, AM, Ty, AddrSpace);
}
+ bool isLSRCostLess(TTI::LSRCost C1, TTI::LSRCost C2) {
+ return TargetTransformInfoImplBase::isLSRCostLess(C1, C2);
+ }
+
int getScalingFactorCost(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset,
bool HasBaseReg, int64_t Scale, unsigned AddrSpace) {
TargetLoweringBase::AddrMode AM;
@@ -162,6 +155,18 @@ 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) {
return BaseT::getIntrinsicCost(IID, RetTy, Arguments);
@@ -184,6 +189,62 @@ public:
return BaseT::getIntrinsicCost(IID, RetTy, ParamTys);
}
+ unsigned getEstimatedNumberOfCaseClusters(const SwitchInst &SI,
+ unsigned &JumpTableSize) {
+ /// Try to find the estimated number of clusters. Note that the number of
+ /// clusters identified in this function could be different from the actural
+ /// numbers found in lowering. This function ignore switches that are
+ /// lowered with a mix of jump table / bit test / BTree. This function was
+ /// initially intended to be used when estimating the cost of switch in
+ /// inline cost heuristic, but it's a generic cost model to be used in other
+ /// places (e.g., in loop unrolling).
+ unsigned N = SI.getNumCases();
+ const TargetLoweringBase *TLI = getTLI();
+ const DataLayout &DL = this->getDataLayout();
+
+ JumpTableSize = 0;
+ bool IsJTAllowed = TLI->areJTsAllowed(SI.getParent()->getParent());
+
+ // Early exit if both a jump table and bit test are not allowed.
+ if (N < 1 || (!IsJTAllowed && DL.getPointerSizeInBits() < N))
+ return N;
+
+ APInt MaxCaseVal = SI.case_begin()->getCaseValue()->getValue();
+ APInt MinCaseVal = MaxCaseVal;
+ for (auto CI : SI.cases()) {
+ const APInt &CaseVal = CI.getCaseValue()->getValue();
+ if (CaseVal.sgt(MaxCaseVal))
+ MaxCaseVal = CaseVal;
+ if (CaseVal.slt(MinCaseVal))
+ MinCaseVal = CaseVal;
+ }
+
+ // Check if suitable for a bit test
+ if (N <= DL.getPointerSizeInBits()) {
+ SmallPtrSet<const BasicBlock *, 4> Dests;
+ for (auto I : SI.cases())
+ Dests.insert(I.getCaseSuccessor());
+
+ if (TLI->isSuitableForBitTests(Dests.size(), N, MinCaseVal, MaxCaseVal,
+ DL))
+ return 1;
+ }
+
+ // Check if suitable for a jump table.
+ if (IsJTAllowed) {
+ if (N < 2 || N < TLI->getMinimumJumpTableEntries())
+ return N;
+ uint64_t Range =
+ (MaxCaseVal - MinCaseVal).getLimitedValue(UINT64_MAX - 1) + 1;
+ // Check whether a range of clusters is dense enough for a jump table
+ if (TLI->isSuitableForJumpTable(&SI, N, Range)) {
+ JumpTableSize = Range;
+ return 1;
+ }
+ }
+ return N;
+ }
+
unsigned getJumpBufAlignment() { return getTLI()->getJumpBufAlignment(); }
unsigned getJumpBufSize() { return getTLI()->getJumpBufSize(); }
@@ -228,7 +289,8 @@ public:
unsigned getInliningThresholdMultiplier() { return 1; }
- void getUnrollingPreferences(Loop *L, TTI::UnrollingPreferences &UP) {
+ void getUnrollingPreferences(Loop *L, ScalarEvolution &SE,
+ TTI::UnrollingPreferences &UP) {
// This unrolling functionality is target independent, but to provide some
// motivation for its intended use, for x86:
@@ -299,7 +361,68 @@ public:
unsigned getNumberOfRegisters(bool Vector) { return Vector ? 0 : 1; }
- unsigned getRegisterBitWidth(bool Vector) { return 32; }
+ 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");
+ unsigned Cost = 0;
+
+ for (int i = 0, e = Ty->getVectorNumElements(); i < e; ++i) {
+ if (Insert)
+ Cost += static_cast<T *>(this)
+ ->getVectorInstrCost(Instruction::InsertElement, Ty, i);
+ if (Extract)
+ Cost += static_cast<T *>(this)
+ ->getVectorInstrCost(Instruction::ExtractElement, Ty, i);
+ }
+
+ return Cost;
+ }
+
+ /// 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) {
+ unsigned Cost = 0;
+ 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();
+ // If A is a vector operand, VF should be 1 or correspond to A.
+ assert ((VF == 1 || VF == VecTy->getVectorNumElements()) &&
+ "Vector argument does not match VF");
+ }
+ else
+ VecTy = VectorType::get(A->getType(), VF);
+
+ Cost += getScalarizationOverhead(VecTy, false, true);
+ }
+ }
+
+ return Cost;
+ }
+
+ unsigned getScalarizationOverhead(Type *VecTy, ArrayRef<const Value *> Args) {
+ assert (VecTy->isVectorTy());
+
+ unsigned Cost = 0;
+
+ Cost += getScalarizationOverhead(VecTy, true, false);
+ if (!Args.empty())
+ Cost += getOperandsScalarizationOverhead(Args,
+ VecTy->getVectorNumElements());
+ else
+ // When no information on arguments is provided, we add the cost
+ // associated with one argument as a heuristic.
+ Cost += getScalarizationOverhead(VecTy, false, true);
+
+ return Cost;
+ }
unsigned getMaxInterleaveFactor(unsigned VF) { return 1; }
@@ -317,7 +440,7 @@ public:
std::pair<unsigned, MVT> LT = TLI->getTypeLegalizationCost(DL, Ty);
- bool IsFloat = Ty->getScalarType()->isFloatingPointTy();
+ bool IsFloat = Ty->isFPOrFPVectorTy();
// Assume that floating point arithmetic operations cost twice as much as
// integer operations.
unsigned OpCost = (IsFloat ? 2 : 1);
@@ -341,10 +464,9 @@ public:
unsigned Num = Ty->getVectorNumElements();
unsigned Cost = static_cast<T *>(this)
->getArithmeticInstrCost(Opcode, Ty->getScalarType());
- // return the cost of multiple scalar invocation plus the cost of
- // inserting
- // and extracting the values.
- return getScalarizationOverhead(Ty, true, true) + Num * Cost;
+ // Return the cost of multiple scalar invocation plus the cost of
+ // inserting and extracting the values.
+ return getScalarizationOverhead(Ty, Args) + Num * Cost;
}
// We don't know anything about this scalar instruction.
@@ -360,7 +482,8 @@ public:
return 1;
}
- unsigned getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src) {
+ unsigned getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src,
+ const Instruction *I = nullptr) {
const TargetLoweringBase *TLI = getTLI();
int ISD = TLI->InstructionOpcodeToISD(Opcode);
assert(ISD && "Invalid opcode");
@@ -389,6 +512,18 @@ public:
Dst->getPointerAddressSpace()))
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))) {
+ 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;
+ }
+
// If the cast is marked as legal (or promote) then assume low cost.
if (SrcLT.first == DstLT.first &&
TLI->isOperationLegalOrPromote(ISD, DstLT.second))
@@ -446,14 +581,14 @@ public:
Src->getVectorNumElements() / 2);
T *TTI = static_cast<T *>(this);
return TTI->getVectorSplitCost() +
- (2 * TTI->getCastInstrCost(Opcode, SplitDst, SplitSrc));
+ (2 * TTI->getCastInstrCost(Opcode, SplitDst, SplitSrc, 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());
+ Opcode, Dst->getScalarType(), Src->getScalarType(), I);
// Return the cost of multiple scalar invocation plus the cost of
// inserting and extracting the values.
@@ -487,7 +622,8 @@ public:
return 0;
}
- unsigned getCmpSelInstrCost(unsigned Opcode, Type *ValTy, Type *CondTy) {
+ unsigned getCmpSelInstrCost(unsigned Opcode, Type *ValTy, Type *CondTy,
+ const Instruction *I) {
const TargetLoweringBase *TLI = getTLI();
int ISD = TLI->InstructionOpcodeToISD(Opcode);
assert(ISD && "Invalid opcode");
@@ -515,7 +651,7 @@ public:
if (CondTy)
CondTy = CondTy->getScalarType();
unsigned Cost = static_cast<T *>(this)->getCmpSelInstrCost(
- Opcode, ValTy->getScalarType(), CondTy);
+ Opcode, ValTy->getScalarType(), CondTy, I);
// Return the cost of multiple scalar invocation plus the cost of
// inserting and extracting the values.
@@ -534,7 +670,7 @@ public:
}
unsigned getMemoryOpCost(unsigned Opcode, Type *Src, unsigned Alignment,
- unsigned AddressSpace) {
+ unsigned AddressSpace, const Instruction *I = nullptr) {
assert(!Src->isVoidTy() && "Invalid type");
std::pair<unsigned, MVT> LT = getTLI()->getTypeLegalizationCost(DL, Src);
@@ -680,18 +816,42 @@ public:
return Cost;
}
- /// Get intrinsic cost based on arguments
+ /// Get intrinsic cost based on arguments.
unsigned getIntrinsicInstrCost(Intrinsic::ID IID, Type *RetTy,
- ArrayRef<Value *> Args, FastMathFlags FMF) {
+ ArrayRef<Value *> Args, FastMathFlags FMF,
+ unsigned VF = 1) {
+ unsigned RetVF = (RetTy->isVectorTy() ? RetTy->getVectorNumElements() : 1);
+ assert ((RetVF == 1 || VF == 1) && "VF > 1 and RetVF is a vector type");
+
switch (IID) {
default: {
+ // Assume that we need to scalarize this intrinsic.
SmallVector<Type *, 4> Types;
- for (Value *Op : Args)
- Types.push_back(Op->getType());
- return static_cast<T *>(this)->getIntrinsicInstrCost(IID, RetTy, Types,
- FMF);
+ for (Value *Op : Args) {
+ Type *OpTy = Op->getType();
+ assert (VF == 1 || !OpTy->isVectorTy());
+ Types.push_back(VF == 1 ? OpTy : VectorType::get(OpTy, VF));
+ }
+
+ if (VF > 1 && !RetTy->isVoidTy())
+ RetTy = VectorType::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
+ // CostModel will pass a vector RetTy and VF is 1.
+ unsigned ScalarizationCost = UINT_MAX;
+ if (RetVF > 1 || VF > 1) {
+ ScalarizationCost = 0;
+ if (!RetTy->isVoidTy())
+ ScalarizationCost += getScalarizationOverhead(RetTy, true, false);
+ ScalarizationCost += getOperandsScalarizationOverhead(Args, VF);
+ }
+
+ return static_cast<T *>(this)->
+ getIntrinsicInstrCost(IID, RetTy, Types, FMF, ScalarizationCost);
}
case Intrinsic::masked_scatter: {
+ assert (VF == 1 && "Can't vectorize types here.");
Value *Mask = Args[3];
bool VarMask = !isa<Constant>(Mask);
unsigned Alignment = cast<ConstantInt>(Args[2])->getZExtValue();
@@ -702,6 +862,7 @@ public:
Alignment);
}
case Intrinsic::masked_gather: {
+ assert (VF == 1 && "Can't vectorize types here.");
Value *Mask = Args[2];
bool VarMask = !isa<Constant>(Mask);
unsigned Alignment = cast<ConstantInt>(Args[1])->getZExtValue();
@@ -713,19 +874,23 @@ public:
}
}
- /// Get intrinsic cost based on argument types
+ /// Get intrinsic cost based on argument types.
+ /// If ScalarizationCostPassed is UINT_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) {
+ ArrayRef<Type *> Tys, FastMathFlags FMF,
+ unsigned ScalarizationCostPassed = UINT_MAX) {
SmallVector<unsigned, 2> ISDs;
unsigned SingleCallCost = 10; // Library call cost. Make it expensive.
switch (IID) {
default: {
// Assume that we need to scalarize this intrinsic.
- unsigned ScalarizationCost = 0;
+ unsigned ScalarizationCost = ScalarizationCostPassed;
unsigned ScalarCalls = 1;
Type *ScalarRetTy = RetTy;
if (RetTy->isVectorTy()) {
- ScalarizationCost = getScalarizationOverhead(RetTy, true, false);
+ if (ScalarizationCostPassed == UINT_MAX)
+ ScalarizationCost = getScalarizationOverhead(RetTy, true, false);
ScalarCalls = std::max(ScalarCalls, RetTy->getVectorNumElements());
ScalarRetTy = RetTy->getScalarType();
}
@@ -733,7 +898,8 @@ public:
for (unsigned i = 0, ie = Tys.size(); i != ie; ++i) {
Type *Ty = Tys[i];
if (Ty->isVectorTy()) {
- ScalarizationCost += getScalarizationOverhead(Ty, false, true);
+ if (ScalarizationCostPassed == UINT_MAX)
+ ScalarizationCost += getScalarizationOverhead(Ty, false, true);
ScalarCalls = std::max(ScalarCalls, Ty->getVectorNumElements());
Ty = Ty->getScalarType();
}
@@ -881,7 +1047,8 @@ public:
// this will emit a costly libcall, adding call overhead and spills. Make it
// very expensive.
if (RetTy->isVectorTy()) {
- unsigned ScalarizationCost = getScalarizationOverhead(RetTy, true, false);
+ unsigned ScalarizationCost = ((ScalarizationCostPassed != UINT_MAX) ?
+ ScalarizationCostPassed : getScalarizationOverhead(RetTy, true, false));
unsigned ScalarCalls = RetTy->getVectorNumElements();
SmallVector<Type *, 4> ScalarTys;
for (unsigned i = 0, ie = Tys.size(); i != ie; ++i) {
@@ -894,7 +1061,8 @@ public:
IID, RetTy->getScalarType(), ScalarTys, FMF);
for (unsigned i = 0, ie = Tys.size(); i != ie; ++i) {
if (Tys[i]->isVectorTy()) {
- ScalarizationCost += getScalarizationOverhead(Tys[i], false, true);
+ if (ScalarizationCostPassed == UINT_MAX)
+ ScalarizationCost += getScalarizationOverhead(Tys[i], false, true);
ScalarCalls = std::max(ScalarCalls, Tys[i]->getVectorNumElements());
}
}
@@ -931,46 +1099,46 @@ public:
return 0;
}
+ /// Try to calculate arithmetic and shuffle op costs for reduction operations.
+ /// We're assuming that reduction operation are performing the following way:
+ /// 1. Non-pairwise reduction
+ /// %val1 = shufflevector<n x t> %val, <n x t> %undef,
+ /// <n x i32> <i32 n/2, i32 n/2 + 1, ..., i32 n, i32 undef, ..., i32 undef>
+ /// \----------------v-------------/ \----------v------------/
+ /// n/2 elements n/2 elements
+ /// %red1 = op <n x t> %val, <n x t> val1
+ /// After this operation we have a vector %red1 where only the first n/2
+ /// elements are meaningful, the second n/2 elements are undefined and can be
+ /// dropped. All other operations are actually working with the vector of
+ /// length n/2, not n, though the real vector length is still n.
+ /// %val2 = shufflevector<n x t> %red1, <n x t> %undef,
+ /// <n x i32> <i32 n/4, i32 n/4 + 1, ..., i32 n/2, i32 undef, ..., i32 undef>
+ /// \----------------v-------------/ \----------v------------/
+ /// n/4 elements 3*n/4 elements
+ /// %red2 = op <n x t> %red1, <n x t> val2 - working with the vector of
+ /// length n/2, the resulting vector has length n/4 etc.
+ /// 2. Pairwise reduction:
+ /// Everything is the same except for an additional shuffle operation which
+ /// is used to produce operands for pairwise kind of reductions.
+ /// %val1 = shufflevector<n x t> %val, <n x t> %undef,
+ /// <n x i32> <i32 0, i32 2, ..., i32 n-2, i32 undef, ..., i32 undef>
+ /// \-------------v----------/ \----------v------------/
+ /// n/2 elements n/2 elements
+ /// %val2 = shufflevector<n x t> %val, <n x t> %undef,
+ /// <n x i32> <i32 1, i32 3, ..., i32 n-1, i32 undef, ..., i32 undef>
+ /// \-------------v----------/ \----------v------------/
+ /// n/2 elements n/2 elements
+ /// %red1 = op <n x t> %val1, <n x t> val2
+ /// Again, the operation is performed on <n x t> vector, but the resulting
+ /// vector %red1 is <n/2 x t> vector.
+ ///
+ /// The cost model should take into account that the actual length of the
+ /// vector is reduced on each iteration.
unsigned getReductionCost(unsigned Opcode, Type *Ty, bool IsPairwise) {
assert(Ty->isVectorTy() && "Expect a vector type");
Type *ScalarTy = Ty->getVectorElementType();
unsigned NumVecElts = Ty->getVectorNumElements();
unsigned NumReduxLevels = Log2_32(NumVecElts);
- // Try to calculate arithmetic and shuffle op costs for reduction operations.
- // We're assuming that reduction operation are performing the following way:
- // 1. Non-pairwise reduction
- // %val1 = shufflevector<n x t> %val, <n x t> %undef,
- // <n x i32> <i32 n/2, i32 n/2 + 1, ..., i32 n, i32 undef, ..., i32 undef>
- // \----------------v-------------/ \----------v------------/
- // n/2 elements n/2 elements
- // %red1 = op <n x t> %val, <n x t> val1
- // After this operation we have a vector %red1 with only maningfull the
- // first n/2 elements, the second n/2 elements are undefined and can be
- // dropped. All other operations are actually working with the vector of
- // length n/2, not n. though the real vector length is still n.
- // %val2 = shufflevector<n x t> %red1, <n x t> %undef,
- // <n x i32> <i32 n/4, i32 n/4 + 1, ..., i32 n/2, i32 undef, ..., i32 undef>
- // \----------------v-------------/ \----------v------------/
- // n/4 elements 3*n/4 elements
- // %red2 = op <n x t> %red1, <n x t> val2 - working with the vector of
- // length n/2, the resulting vector has length n/4 etc.
- // 2. Pairwise reduction:
- // Everything is the same except for an additional shuffle operation which
- // is used to produce operands for pairwise kind of reductions.
- // %val1 = shufflevector<n x t> %val, <n x t> %undef,
- // <n x i32> <i32 0, i32 2, ..., i32 n-2, i32 undef, ..., i32 undef>
- // \-------------v----------/ \----------v------------/
- // n/2 elements n/2 elements
- // %val2 = shufflevector<n x t> %val, <n x t> %undef,
- // <n x i32> <i32 1, i32 3, ..., i32 n-1, i32 undef, ..., i32 undef>
- // \-------------v----------/ \----------v------------/
- // n/2 elements n/2 elements
- // %red1 = op <n x t> %val1, <n x t> val2
- // Again, the operation is performed on <n x t> vector, but the resulting
- // vector %red1 is <n/2 x t> vector.
- //
- // The cost model should take into account that the actual length of the
- // vector is reduced on each iteration.
unsigned ArithCost = 0;
unsigned ShuffleCost = 0;
auto *ConcreteTTI = static_cast<T *>(this);
diff --git a/contrib/llvm/include/llvm/CodeGen/CallingConvLower.h b/contrib/llvm/include/llvm/CodeGen/CallingConvLower.h
index bfbd228..50e464e 100644
--- a/contrib/llvm/include/llvm/CodeGen/CallingConvLower.h
+++ b/contrib/llvm/include/llvm/CodeGen/CallingConvLower.h
@@ -183,11 +183,6 @@ typedef bool CCCustomFn(unsigned &ValNo, MVT &ValVT,
MVT &LocVT, CCValAssign::LocInfo &LocInfo,
ISD::ArgFlagsTy &ArgFlags, CCState &State);
-/// ParmContext - This enum tracks whether calling convention lowering is in
-/// the context of prologue or call generation. Not all backends make use of
-/// this information.
-typedef enum { Unknown, Prologue, Call } ParmContext;
-
/// CCState - This class holds information needed while lowering arguments and
/// return values. It captures which registers are already assigned and which
/// stack slots are used. It provides accessors to allocate these values.
@@ -256,9 +251,6 @@ private:
// during argument analysis.
unsigned InRegsParamsProcessed;
-protected:
- ParmContext CallOrPrologue;
-
public:
CCState(CallingConv::ID CC, bool isVarArg, MachineFunction &MF,
SmallVectorImpl<CCValAssign> &locs, LLVMContext &C);
@@ -510,8 +502,6 @@ public:
InRegsParamsProcessed = 0;
}
- ParmContext getCallOrPrologue() const { return CallOrPrologue; }
-
// Get list of pending assignments
SmallVectorImpl<llvm::CCValAssign> &getPendingLocs() {
return PendingLocs;
diff --git a/contrib/llvm/include/llvm/CodeGen/CommandFlags.h b/contrib/llvm/include/llvm/CodeGen/CommandFlags.h
index aab522d..0d89882 100644
--- a/contrib/llvm/include/llvm/CodeGen/CommandFlags.h
+++ b/contrib/llvm/include/llvm/CodeGen/CommandFlags.h
@@ -119,11 +119,6 @@ FileType("filetype", cl::init(TargetMachine::CGFT_AssemblyFile),
"Emit nothing, for performance testing")));
cl::opt<bool>
-EnableFPMAD("enable-fp-mad",
- cl::desc("Enable less precise MAD instructions to be generated"),
- cl::init(false));
-
-cl::opt<bool>
DisableFPElim("disable-fp-elim",
cl::desc("Disable frame pointer elimination optimization"),
cl::init(false));
@@ -144,6 +139,12 @@ EnableNoNaNsFPMath("enable-no-nans-fp-math",
cl::init(false));
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));
+
+cl::opt<bool>
EnableNoTrappingFPMath("enable-no-trapping-fp-math",
cl::desc("Enable setting the FP exceptions build "
"attribute not to use exceptions"),
@@ -277,11 +278,11 @@ DebuggerTuningOpt("debugger-tune",
// a TargetOptions object with CodeGen flags and returns it.
static inline TargetOptions InitTargetOptionsFromCodeGenFlags() {
TargetOptions Options;
- Options.LessPreciseFPMADOption = EnableFPMAD;
Options.AllowFPOpFusion = FuseFPOps;
Options.UnsafeFPMath = EnableUnsafeFPMath;
Options.NoInfsFPMath = EnableNoInfsFPMath;
Options.NoNaNsFPMath = EnableNoNaNsFPMath;
+ Options.NoSignedZerosFPMath = EnableNoSignedZerosFPMath;
Options.NoTrappingFPMath = EnableNoTrappingFPMath;
Options.FPDenormalMode = DenormalMode;
Options.HonorSignDependentRoundingFPMathOption =
@@ -345,29 +346,21 @@ static inline void setFunctionAttributes(StringRef CPU, StringRef Features,
Module &M) {
for (auto &F : M) {
auto &Ctx = F.getContext();
- AttributeSet Attrs = F.getAttributes(), NewAttrs;
+ AttributeList Attrs = F.getAttributes();
+ AttrBuilder NewAttrs;
if (!CPU.empty())
- NewAttrs = NewAttrs.addAttribute(Ctx, AttributeSet::FunctionIndex,
- "target-cpu", CPU);
-
+ NewAttrs.addAttribute("target-cpu", CPU);
if (!Features.empty())
- NewAttrs = NewAttrs.addAttribute(Ctx, AttributeSet::FunctionIndex,
- "target-features", Features);
-
+ NewAttrs.addAttribute("target-features", Features);
if (DisableFPElim.getNumOccurrences() > 0)
- NewAttrs = NewAttrs.addAttribute(Ctx, AttributeSet::FunctionIndex,
- "no-frame-pointer-elim",
- DisableFPElim ? "true" : "false");
-
+ NewAttrs.addAttribute("no-frame-pointer-elim",
+ DisableFPElim ? "true" : "false");
if (DisableTailCalls.getNumOccurrences() > 0)
- NewAttrs = NewAttrs.addAttribute(Ctx, AttributeSet::FunctionIndex,
- "disable-tail-calls",
- toStringRef(DisableTailCalls));
-
+ NewAttrs.addAttribute("disable-tail-calls",
+ toStringRef(DisableTailCalls));
if (StackRealign)
- NewAttrs = NewAttrs.addAttribute(Ctx, AttributeSet::FunctionIndex,
- "stackrealign");
+ NewAttrs.addAttribute("stackrealign");
if (TrapFuncName.getNumOccurrences() > 0)
for (auto &B : F)
@@ -376,13 +369,13 @@ static inline void setFunctionAttributes(StringRef CPU, StringRef Features,
if (const auto *F = Call->getCalledFunction())
if (F->getIntrinsicID() == Intrinsic::debugtrap ||
F->getIntrinsicID() == Intrinsic::trap)
- Call->addAttribute(llvm::AttributeSet::FunctionIndex,
- Attribute::get(Ctx, "trap-func-name",
- TrapFuncName));
+ Call->addAttribute(
+ llvm::AttributeList::FunctionIndex,
+ Attribute::get(Ctx, "trap-func-name", TrapFuncName));
// Let NewAttrs override Attrs.
- NewAttrs = Attrs.addAttributes(Ctx, AttributeSet::FunctionIndex, NewAttrs);
- F.setAttributes(NewAttrs);
+ F.setAttributes(
+ Attrs.addAttributes(Ctx, AttributeList::FunctionIndex, NewAttrs));
}
}
diff --git a/contrib/llvm/include/llvm/CodeGen/DFAPacketizer.h b/contrib/llvm/include/llvm/CodeGen/DFAPacketizer.h
index 8de140e..77c37ac 100644
--- a/contrib/llvm/include/llvm/CodeGen/DFAPacketizer.h
+++ b/contrib/llvm/include/llvm/CodeGen/DFAPacketizer.h
@@ -1,4 +1,4 @@
-//=- llvm/CodeGen/DFAPacketizer.h - DFA Packetizer for VLIW ---*- C++ -*-=====//
+//===- llvm/CodeGen/DFAPacketizer.h - DFA Packetizer for VLIW ---*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -29,17 +29,22 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/ScheduleDAGMutation.h"
+#include <cstdint>
#include <map>
+#include <memory>
+#include <utility>
+#include <vector>
namespace llvm {
-class MCInstrDesc;
+class DefaultVLIWScheduler;
+class InstrItineraryData;
+class MachineFunction;
class MachineInstr;
class MachineLoopInfo;
-class MachineDominatorTree;
-class InstrItineraryData;
-class DefaultVLIWScheduler;
+class MCInstrDesc;
class SUnit;
+class TargetInstrInfo;
// --------------------------------------------------------------------
// Definitions shared between DFAPacketizer.cpp and DFAPacketizerEmitter.cpp
@@ -64,17 +69,18 @@ class SUnit;
#define DFA_MAX_RESTERMS 4 // The max # of AND'ed resource terms.
#define DFA_MAX_RESOURCES 16 // The max # of resource bits in one term.
-typedef uint64_t DFAInput;
-typedef int64_t DFAStateInput;
+using DFAInput = uint64_t;
+using DFAStateInput = int64_t;
+
#define DFA_TBLTYPE "int64_t" // For generating DFAStateInputTable.
// --------------------------------------------------------------------
class DFAPacketizer {
private:
- typedef std::pair<unsigned, DFAInput> UnsignPair;
+ using UnsignPair = std::pair<unsigned, DFAInput>;
const InstrItineraryData *InstrItins;
- int CurrentState;
+ int CurrentState = 0;
const DFAStateInput (*DFAStateInputTable)[2];
const unsigned *DFAStateEntryTable;
@@ -101,24 +107,23 @@ public:
// Check if the resources occupied by a MCInstrDesc are available in
// the current state.
- bool canReserveResources(const llvm::MCInstrDesc *MID);
+ bool canReserveResources(const MCInstrDesc *MID);
// Reserve the resources occupied by a MCInstrDesc and change the current
// state to reflect that change.
- void reserveResources(const llvm::MCInstrDesc *MID);
+ void reserveResources(const MCInstrDesc *MID);
// Check if the resources occupied by a machine instruction are available
// in the current state.
- bool canReserveResources(llvm::MachineInstr &MI);
+ bool canReserveResources(MachineInstr &MI);
// Reserve the resources occupied by a machine instruction and change the
// current state to reflect that change.
- void reserveResources(llvm::MachineInstr &MI);
+ void reserveResources(MachineInstr &MI);
const InstrItineraryData *getInstrItins() const { return InstrItins; }
};
-
// VLIWPacketizerList implements a simple VLIW packetizer using DFA. The
// packetizer works on machine basic blocks. For each instruction I in BB,
// the packetizer consults the DFA to see if machine resources are available
@@ -205,6 +210,6 @@ public:
void addMutation(std::unique_ptr<ScheduleDAGMutation> Mutation);
};
-} // namespace llvm
+} // end namespace llvm
-#endif
+#endif // LLVM_CODEGEN_DFAPACKETIZER_H
diff --git a/contrib/llvm/include/llvm/CodeGen/DIE.h b/contrib/llvm/include/llvm/CodeGen/DIE.h
index 95c4b42..f809fc9 100644
--- a/contrib/llvm/include/llvm/CodeGen/DIE.h
+++ b/contrib/llvm/include/llvm/CodeGen/DIE.h
@@ -1,4 +1,4 @@
-//===--- lib/CodeGen/DIE.h - DWARF Info Entries -----------------*- C++ -*-===//
+//===- lib/CodeGen/DIE.h - DWARF Info Entries -------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -21,16 +21,17 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/iterator.h"
#include "llvm/ADT/iterator_range.h"
+#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/CodeGen/DwarfStringPoolEntry.h"
#include "llvm/Support/AlignOf.h"
#include "llvm/Support/Allocator.h"
-#include "llvm/Support/Dwarf.h"
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <iterator>
#include <new>
#include <type_traits>
+#include <utility>
#include <vector>
namespace llvm {
@@ -53,11 +54,11 @@ class DIEAbbrevData {
dwarf::Form Form;
/// Dwarf attribute value for DW_FORM_implicit_const
- int64_t Value;
+ int64_t Value = 0;
public:
DIEAbbrevData(dwarf::Attribute A, dwarf::Form F)
- : Attribute(A), Form(F), Value(0) {}
+ : Attribute(A), Form(F) {}
DIEAbbrevData(dwarf::Attribute A, int64_t V)
: Attribute(A), Form(dwarf::DW_FORM_implicit_const), Value(V) {}
@@ -120,8 +121,8 @@ public:
/// Print the abbreviation using the specified asm printer.
void Emit(const AsmPrinter *AP) const;
- void print(raw_ostream &O);
- void dump();
+ void print(raw_ostream &O) const;
+ void dump() const;
};
//===--------------------------------------------------------------------===//
@@ -136,13 +137,14 @@ class DIEAbbrevSet {
/// storage container.
BumpPtrAllocator &Alloc;
/// \brief FoldingSet that uniques the abbreviations.
- llvm::FoldingSet<DIEAbbrev> AbbreviationsSet;
+ FoldingSet<DIEAbbrev> AbbreviationsSet;
/// A list of all the unique abbreviations in use.
std::vector<DIEAbbrev *> Abbreviations;
public:
DIEAbbrevSet(BumpPtrAllocator &A) : Alloc(A) {}
~DIEAbbrevSet();
+
/// Generate the abbreviation declaration for a DIE and return a pointer to
/// the generated abbreviation.
///
@@ -289,13 +291,11 @@ public:
/// A pointer to another debug information entry. An instance of this class can
/// also be used as a proxy for a debug information entry not yet defined
/// (ie. types.)
-class DIE;
class DIEEntry {
DIE *Entry;
- DIEEntry() = delete;
-
public:
+ DIEEntry() = delete;
explicit DIEEntry(DIE &E) : Entry(&E) {}
DIE &getEntry() const { return *Entry; }
@@ -348,10 +348,10 @@ private:
///
/// All values that aren't standard layout (or are larger than 8 bytes)
/// should be stored by reference instead of by value.
- typedef AlignedCharArrayUnion<DIEInteger, DIEString, DIEExpr, DIELabel,
- DIEDelta *, DIEEntry, DIEBlock *, DIELoc *,
- DIELocList>
- ValTy;
+ using ValTy = AlignedCharArrayUnion<DIEInteger, DIEString, DIEExpr, DIELabel,
+ DIEDelta *, DIEEntry, DIEBlock *,
+ DIELoc *, DIELocList>;
+
static_assert(sizeof(ValTy) <= sizeof(uint64_t) ||
sizeof(ValTy) <= sizeof(void *),
"Expected all large types to be stored via pointer");
@@ -383,11 +383,11 @@ private:
return;
#define HANDLE_DIEVALUE_SMALL(T) \
case is##T: \
- destruct<DIE##T>();
+ destruct<DIE##T>(); \
return;
#define HANDLE_DIEVALUE_LARGE(T) \
case is##T: \
- destruct<const DIE##T *>();
+ destruct<const DIE##T *>(); \
return;
#include "llvm/CodeGen/DIEValue.def"
}
@@ -486,10 +486,12 @@ struct IntrusiveBackListNode {
};
struct IntrusiveBackListBase {
- typedef IntrusiveBackListNode Node;
+ using Node = IntrusiveBackListNode;
+
Node *Last = nullptr;
bool empty() const { return !Last; }
+
void push_back(Node &N) {
assert(N.Next.getPointer() == &N && "Expected unlinked node");
assert(N.Next.getInt() == true && "Expected unlinked node");
@@ -505,6 +507,7 @@ struct IntrusiveBackListBase {
template <class T> class IntrusiveBackList : IntrusiveBackListBase {
public:
using IntrusiveBackListBase::empty;
+
void push_back(T &N) { IntrusiveBackListBase::push_back(N); }
T &back() { return *static_cast<T *>(Last); }
const T &back() const { return *static_cast<T *>(Last); }
@@ -513,6 +516,7 @@ public:
class iterator
: public iterator_facade_base<iterator, std::forward_iterator_tag, T> {
friend class const_iterator;
+
Node *N = nullptr;
public:
@@ -585,10 +589,12 @@ public:
class DIEValueList {
struct Node : IntrusiveBackListNode {
DIEValue V;
+
explicit Node(DIEValue V) : V(V) {}
};
- typedef IntrusiveBackList<Node> ListTy;
+ using ListTy = IntrusiveBackList<Node>;
+
ListTy List;
public:
@@ -597,9 +603,10 @@ public:
: public iterator_adaptor_base<value_iterator, ListTy::iterator,
std::forward_iterator_tag, DIEValue> {
friend class const_value_iterator;
- typedef iterator_adaptor_base<value_iterator, ListTy::iterator,
- std::forward_iterator_tag,
- DIEValue> iterator_adaptor;
+
+ using iterator_adaptor =
+ iterator_adaptor_base<value_iterator, ListTy::iterator,
+ std::forward_iterator_tag, DIEValue>;
public:
value_iterator() = default;
@@ -612,9 +619,9 @@ public:
class const_value_iterator : public iterator_adaptor_base<
const_value_iterator, ListTy::const_iterator,
std::forward_iterator_tag, const DIEValue> {
- typedef iterator_adaptor_base<const_value_iterator, ListTy::const_iterator,
- std::forward_iterator_tag,
- const DIEValue> iterator_adaptor;
+ using iterator_adaptor =
+ iterator_adaptor_base<const_value_iterator, ListTy::const_iterator,
+ std::forward_iterator_tag, const DIEValue>;
public:
const_value_iterator() = default;
@@ -627,8 +634,8 @@ public:
const DIEValue &operator*() const { return wrapped()->V; }
};
- typedef iterator_range<value_iterator> value_range;
- typedef iterator_range<const_value_iterator> const_value_range;
+ using value_range = iterator_range<value_iterator>;
+ using const_value_range = iterator_range<const_value_iterator>;
value_iterator addValue(BumpPtrAllocator &Alloc, const DIEValue &V) {
List.push_back(*new (Alloc) Node(V));
@@ -657,15 +664,15 @@ class DIE : IntrusiveBackListNode, public DIEValueList {
friend class DIEUnit;
/// Dwarf unit relative offset.
- unsigned Offset;
+ unsigned Offset = 0;
/// Size of instance + children.
- unsigned Size;
+ unsigned Size = 0;
unsigned AbbrevNumber = ~0u;
/// Dwarf tag code.
dwarf::Tag Tag = (dwarf::Tag)0;
/// Set to true to force a DIE to emit an abbreviation that says it has
/// children even when it doesn't. This is used for unit testing purposes.
- bool ForceChildren;
+ bool ForceChildren = false;
/// Children DIEs.
IntrusiveBackList<DIE> Children;
@@ -673,20 +680,19 @@ class DIE : IntrusiveBackListNode, public DIEValueList {
/// DIEUnit which contains this DIE as its unit DIE.
PointerUnion<DIE *, DIEUnit *> Owner;
- DIE() = delete;
- explicit DIE(dwarf::Tag Tag) : Offset(0), Size(0), Tag(Tag),
- ForceChildren(false) {}
+ explicit DIE(dwarf::Tag Tag) : Tag(Tag) {}
public:
+ DIE() = delete;
+ DIE(const DIE &RHS) = delete;
+ DIE(DIE &&RHS) = delete;
+ DIE &operator=(const DIE &RHS) = delete;
+ DIE &operator=(const DIE &&RHS) = delete;
+
static DIE *get(BumpPtrAllocator &Alloc, dwarf::Tag Tag) {
return new (Alloc) DIE(Tag);
}
- DIE(const DIE &RHS) = delete;
- DIE(DIE &&RHS) = delete;
- void operator=(const DIE &RHS) = delete;
- void operator=(const DIE &&RHS) = delete;
-
// Accessors.
unsigned getAbbrevNumber() const { return AbbrevNumber; }
dwarf::Tag getTag() const { return Tag; }
@@ -696,10 +702,10 @@ public:
bool hasChildren() const { return ForceChildren || !Children.empty(); }
void setForceChildren(bool B) { ForceChildren = B; }
- typedef IntrusiveBackList<DIE>::iterator child_iterator;
- typedef IntrusiveBackList<DIE>::const_iterator const_child_iterator;
- typedef iterator_range<child_iterator> child_range;
- typedef iterator_range<const_child_iterator> const_child_range;
+ using child_iterator = IntrusiveBackList<DIE>::iterator;
+ using const_child_iterator = IntrusiveBackList<DIE>::const_iterator;
+ using child_range = iterator_range<child_iterator>;
+ using const_child_range = iterator_range<const_child_iterator>;
child_range children() {
return make_range(Children.begin(), Children.end());
@@ -774,7 +780,7 @@ public:
DIEValue findAttribute(dwarf::Attribute Attribute) const;
void print(raw_ostream &O, unsigned IndentCount = 0) const;
- void dump();
+ void dump() const;
};
//===--------------------------------------------------------------------===//
@@ -793,6 +799,9 @@ class DIEUnit {
uint32_t Length; /// The length in bytes of all of the DIEs in this unit.
const uint16_t Version; /// The Dwarf version number for this unit.
const uint8_t AddrSize; /// The size in bytes of an address for this unit.
+protected:
+ ~DIEUnit() = default;
+
public:
DIEUnit(uint16_t Version, uint8_t AddrSize, dwarf::Tag UnitTag);
DIEUnit(const DIEUnit &RHS) = delete;
@@ -808,6 +817,10 @@ public:
this->Section = Section;
}
+ virtual const MCSymbol *getCrossSectionRelativeBaseAddress() const {
+ return nullptr;
+ }
+
/// Return the section that this DIEUnit will be emitted into.
///
/// \returns Section pointer which can be NULL.
@@ -822,15 +835,19 @@ public:
const DIE &getUnitDie() const { return Die; }
};
-
+struct BasicDIEUnit final : DIEUnit {
+ BasicDIEUnit(uint16_t Version, uint8_t AddrSize, dwarf::Tag UnitTag)
+ : DIEUnit(Version, AddrSize, UnitTag) {}
+};
+
//===--------------------------------------------------------------------===//
/// DIELoc - Represents an expression location.
//
class DIELoc : public DIEValueList {
- mutable unsigned Size; // Size in bytes excluding size header.
+ mutable unsigned Size = 0; // Size in bytes excluding size header.
public:
- DIELoc() : Size(0) {}
+ DIELoc() = default;
/// ComputeSize - Calculate the size of the location expression.
///
@@ -861,10 +878,10 @@ public:
/// DIEBlock - Represents a block of values.
//
class DIEBlock : public DIEValueList {
- mutable unsigned Size; // Size in bytes excluding size header.
+ mutable unsigned Size = 0; // Size in bytes excluding size header.
public:
- DIEBlock() : Size(0) {}
+ DIEBlock() = default;
/// ComputeSize - Calculate the size of the location expression.
///
diff --git a/contrib/llvm/include/llvm/CodeGen/ExecutionDepsFix.h b/contrib/llvm/include/llvm/CodeGen/ExecutionDepsFix.h
new file mode 100644
index 0000000..f4db8b7
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/ExecutionDepsFix.h
@@ -0,0 +1,230 @@
+//==- llvm/CodeGen/ExecutionDepsFix.h - Execution Dependency Fix -*- C++ -*-==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+/// \file Execution Dependency Fix pass.
+///
+/// Some X86 SSE instructions like mov, and, or, xor are available in different
+/// variants for different operand types. These variant instructions are
+/// equivalent, but on Nehalem and newer cpus there is extra latency
+/// transferring data between integer and floating point domains. ARM cores
+/// have similar issues when they are configured with both VFP and NEON
+/// pipelines.
+///
+/// This pass changes the variant instructions to minimize domain crossings.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_EXECUTIONDEPSFIX_H
+#define LLVM_CODEGEN_EXECUTIONDEPSFIX_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/CodeGen/LivePhysRegs.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/RegisterClassInfo.h"
+#include "llvm/Pass.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/MathExtras.h"
+#include <cassert>
+#include <limits>
+#include <utility>
+#include <vector>
+
+namespace llvm {
+
+class MachineBasicBlock;
+class MachineInstr;
+class TargetInstrInfo;
+
+/// A DomainValue is a bit like LiveIntervals' ValNo, but it also keeps track
+/// of execution domains.
+///
+/// An open DomainValue represents a set of instructions that can still switch
+/// execution domain. Multiple registers may refer to the same open
+/// DomainValue - they will eventually be collapsed to the same execution
+/// domain.
+///
+/// A collapsed DomainValue represents a single register that has been forced
+/// into one of more execution domains. There is a separate collapsed
+/// DomainValue for each register, but it may contain multiple execution
+/// domains. A register value is initially created in a single execution
+/// domain, but if we were forced to pay the penalty of a domain crossing, we
+/// keep track of the fact that the register is now available in multiple
+/// domains.
+struct DomainValue {
+ // Basic reference counting.
+ unsigned Refs = 0;
+
+ // Bitmask of available domains. For an open DomainValue, it is the still
+ // possible domains for collapsing. For a collapsed DomainValue it is the
+ // domains where the register is available for free.
+ unsigned AvailableDomains;
+
+ // Pointer to the next DomainValue in a chain. When two DomainValues are
+ // merged, Victim.Next is set to point to Victor, so old DomainValue
+ // references can be updated by following the chain.
+ DomainValue *Next;
+
+ // Twiddleable instructions using or defining these registers.
+ SmallVector<MachineInstr*, 8> Instrs;
+
+ DomainValue() { clear(); }
+
+ // A collapsed DomainValue has no instructions to twiddle - it simply keeps
+ // track of the domains where the registers are already available.
+ bool isCollapsed() const { return Instrs.empty(); }
+
+ // Is domain available?
+ bool hasDomain(unsigned domain) const {
+ assert(domain <
+ static_cast<unsigned>(std::numeric_limits<unsigned>::digits) &&
+ "undefined behavior");
+ return AvailableDomains & (1u << domain);
+ }
+
+ // Mark domain as available.
+ void addDomain(unsigned domain) {
+ AvailableDomains |= 1u << domain;
+ }
+
+ // Restrict to a single domain available.
+ void setSingleDomain(unsigned domain) {
+ AvailableDomains = 1u << domain;
+ }
+
+ // Return bitmask of domains that are available and in mask.
+ unsigned getCommonDomains(unsigned mask) const {
+ return AvailableDomains & mask;
+ }
+
+ // First domain available.
+ unsigned getFirstDomain() const {
+ return countTrailingZeros(AvailableDomains);
+ }
+
+ // Clear this DomainValue and point to next which has all its data.
+ void clear() {
+ AvailableDomains = 0;
+ Next = nullptr;
+ Instrs.clear();
+ }
+};
+
+/// Information about a live register.
+struct LiveReg {
+ /// Value currently in this register, or NULL when no value is being tracked.
+ /// This counts as a DomainValue reference.
+ DomainValue *Value;
+
+ /// Instruction that defined this register, relative to the beginning of the
+ /// current basic block. When a LiveReg is used to represent a live-out
+ /// register, this value is relative to the end of the basic block, so it
+ /// will be a negative number.
+ int Def;
+};
+
+class ExecutionDepsFix : public MachineFunctionPass {
+ SpecificBumpPtrAllocator<DomainValue> Allocator;
+ SmallVector<DomainValue*,16> Avail;
+
+ const TargetRegisterClass *const RC;
+ MachineFunction *MF;
+ const TargetInstrInfo *TII;
+ const TargetRegisterInfo *TRI;
+ RegisterClassInfo RegClassInfo;
+ std::vector<SmallVector<int, 1>> AliasMap;
+ const unsigned NumRegs;
+ LiveReg *LiveRegs;
+ struct MBBInfo {
+ // Keeps clearance and domain information for all registers. Note that this
+ // is different from the usual definition notion of liveness. The CPU
+ // doesn't care whether or not we consider a register killed.
+ LiveReg *OutRegs = nullptr;
+
+ // Whether we have gotten to this block in primary processing yet.
+ bool PrimaryCompleted = false;
+
+ // The number of predecessors for which primary processing has completed
+ unsigned IncomingProcessed = 0;
+
+ // The value of `IncomingProcessed` at the start of primary processing
+ unsigned PrimaryIncoming = 0;
+
+ // The number of predecessors for which all processing steps are done.
+ unsigned IncomingCompleted = 0;
+
+ MBBInfo() = default;
+ };
+ using MBBInfoMap = DenseMap<MachineBasicBlock *, MBBInfo>;
+ MBBInfoMap MBBInfos;
+
+ /// List of undefined register reads in this block in forward order.
+ std::vector<std::pair<MachineInstr *, unsigned>> UndefReads;
+
+ /// Storage for register unit liveness.
+ LivePhysRegs LiveRegSet;
+
+ /// Current instruction number.
+ /// The first instruction in each basic block is 0.
+ int CurInstr;
+
+public:
+ ExecutionDepsFix(char &PassID, const TargetRegisterClass &RC)
+ : MachineFunctionPass(PassID), RC(&RC), NumRegs(RC.getNumRegs()) {}
+
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
+ AU.setPreservesAll();
+ MachineFunctionPass::getAnalysisUsage(AU);
+ }
+
+ bool runOnMachineFunction(MachineFunction &MF) override;
+
+ MachineFunctionProperties getRequiredProperties() const override {
+ return MachineFunctionProperties().set(
+ MachineFunctionProperties::Property::NoVRegs);
+ }
+
+private:
+ iterator_range<SmallVectorImpl<int>::const_iterator>
+ regIndices(unsigned Reg) const;
+ // DomainValue allocation.
+ DomainValue *alloc(int domain = -1);
+ DomainValue *retain(DomainValue *DV) {
+ if (DV) ++DV->Refs;
+ return DV;
+ }
+ void release(DomainValue*);
+ DomainValue *resolve(DomainValue*&);
+
+ // LiveRegs manipulations.
+ void setLiveReg(int rx, DomainValue *DV);
+ void kill(int rx);
+ void force(int rx, unsigned domain);
+ void collapse(DomainValue *dv, unsigned domain);
+ bool merge(DomainValue *A, DomainValue *B);
+
+ void enterBasicBlock(MachineBasicBlock*);
+ void leaveBasicBlock(MachineBasicBlock*);
+ bool isBlockDone(MachineBasicBlock *);
+ void processBasicBlock(MachineBasicBlock *MBB, bool PrimaryPass);
+ bool visitInstr(MachineInstr *);
+ void processDefs(MachineInstr *, bool breakDependency, bool Kill);
+ void visitSoftInstr(MachineInstr*, unsigned mask);
+ void visitHardInstr(MachineInstr*, unsigned domain);
+ bool pickBestRegisterForUndef(MachineInstr *MI, unsigned OpIdx,
+ unsigned Pref);
+ bool shouldBreakDependence(MachineInstr*, unsigned OpIdx, unsigned Pref);
+ void processUndefReads(MachineBasicBlock*);
+};
+
+} // end namepsace llvm
+
+#endif // LLVM_CODEGEN_EXECUTIONDEPSFIX_H
diff --git a/contrib/llvm/include/llvm/CodeGen/ExpandReductions.h b/contrib/llvm/include/llvm/CodeGen/ExpandReductions.h
new file mode 100644
index 0000000..c6aaaad
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/ExpandReductions.h
@@ -0,0 +1,24 @@
+//===----- ExpandReductions.h - Expand experimental reduction intrinsics --===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_EXPANDREDUCTIONS_H
+#define LLVM_CODEGEN_EXPANDREDUCTIONS_H
+
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+
+class ExpandReductionsPass
+ : public PassInfoMixin<ExpandReductionsPass> {
+public:
+ PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
+};
+} // end namespace llvm
+
+#endif // LLVM_CODEGEN_EXPANDREDUCTIONS_H
diff --git a/contrib/llvm/include/llvm/CodeGen/FastISel.h b/contrib/llvm/include/llvm/CodeGen/FastISel.h
index cdaea25..74e4179 100644
--- a/contrib/llvm/include/llvm/CodeGen/FastISel.h
+++ b/contrib/llvm/include/llvm/CodeGen/FastISel.h
@@ -1,4 +1,4 @@
-//===-- FastISel.h - Definition of the FastISel class ---*- C++ -*---------===//
+//===- FastISel.h - Definition of the FastISel class ------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -16,71 +16,81 @@
#define LLVM_CODEGEN_FASTISEL_H
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/CodeGen/MachineValueType.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"
+#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/Target/TargetLowering.h"
+#include <algorithm>
+#include <cstdint>
+#include <utility>
namespace llvm {
+class AllocaInst;
+class BasicBlock;
+class CallInst;
+class Constant;
+class ConstantFP;
+class DataLayout;
+class FunctionLoweringInfo;
+class LoadInst;
class MachineConstantPool;
+class MachineFrameInfo;
+class MachineFunction;
+class MachineInstr;
+class MachineMemOperand;
+class MachineOperand;
+class MachineRegisterInfo;
+class MCContext;
+class MCInstrDesc;
+class MCSymbol;
+class TargetInstrInfo;
+class TargetLibraryInfo;
+class TargetMachine;
+class TargetRegisterClass;
+class TargetRegisterInfo;
+class Type;
+class User;
+class Value;
/// \brief This is a fast-path instruction selection class that generates poor
/// code and doesn't support illegal types or non-trivial lowering, but runs
/// quickly.
class FastISel {
public:
- struct ArgListEntry {
- Value *Val;
- Type *Ty;
- bool IsSExt : 1;
- bool IsZExt : 1;
- bool IsInReg : 1;
- bool IsSRet : 1;
- bool IsNest : 1;
- bool IsByVal : 1;
- bool IsInAlloca : 1;
- bool IsReturned : 1;
- bool IsSwiftSelf : 1;
- bool IsSwiftError : 1;
- uint16_t Alignment;
-
- ArgListEntry()
- : Val(nullptr), Ty(nullptr), IsSExt(false), IsZExt(false),
- IsInReg(false), IsSRet(false), IsNest(false), IsByVal(false),
- IsInAlloca(false), IsReturned(false), IsSwiftSelf(false),
- IsSwiftError(false), Alignment(0) {}
-
- /// \brief Set CallLoweringInfo attribute flags based on a call instruction
- /// and called function attributes.
- void setAttributes(ImmutableCallSite *CS, unsigned AttrIdx);
- };
- typedef std::vector<ArgListEntry> ArgListTy;
-
+ using ArgListEntry = TargetLoweringBase::ArgListEntry;
+ using ArgListTy = TargetLoweringBase::ArgListTy;
struct CallLoweringInfo {
- Type *RetTy;
+ Type *RetTy = nullptr;
bool RetSExt : 1;
bool RetZExt : 1;
bool IsVarArg : 1;
bool IsInReg : 1;
bool DoesNotReturn : 1;
bool IsReturnValueUsed : 1;
+ bool IsPatchPoint : 1;
// \brief IsTailCall Should be modified by implementations of FastLowerCall
// that perform tail call conversions.
- bool IsTailCall;
+ bool IsTailCall = false;
- unsigned NumFixedArgs;
- CallingConv::ID CallConv;
- const Value *Callee;
- MCSymbol *Symbol;
+ unsigned NumFixedArgs = -1;
+ CallingConv::ID CallConv = CallingConv::C;
+ const Value *Callee = nullptr;
+ MCSymbol *Symbol = nullptr;
ArgListTy Args;
- ImmutableCallSite *CS;
- MachineInstr *Call;
- unsigned ResultReg;
- unsigned NumResultRegs;
-
- bool IsPatchPoint;
+ ImmutableCallSite *CS = nullptr;
+ MachineInstr *Call = nullptr;
+ unsigned ResultReg = 0;
+ unsigned NumResultRegs = 0;
SmallVector<Value *, 16> OutVals;
SmallVector<ISD::ArgFlagsTy, 16> OutFlags;
@@ -89,11 +99,8 @@ public:
SmallVector<unsigned, 4> InRegs;
CallLoweringInfo()
- : RetTy(nullptr), RetSExt(false), RetZExt(false), IsVarArg(false),
- IsInReg(false), DoesNotReturn(false), IsReturnValueUsed(true),
- IsTailCall(false), NumFixedArgs(-1), CallConv(CallingConv::C),
- Callee(nullptr), Symbol(nullptr), CS(nullptr), Call(nullptr),
- ResultReg(0), NumResultRegs(0), IsPatchPoint(false) {}
+ : RetSExt(false), RetZExt(false), IsVarArg(false), IsInReg(false),
+ DoesNotReturn(false), IsReturnValueUsed(true), IsPatchPoint(false) {}
CallLoweringInfo &setCallee(Type *ResultTy, FunctionType *FuncTy,
const Value *Target, ArgListTy &&ArgsList,
@@ -101,12 +108,12 @@ public:
RetTy = ResultTy;
Callee = Target;
- IsInReg = Call.paramHasAttr(0, Attribute::InReg);
+ IsInReg = Call.hasRetAttr(Attribute::InReg);
DoesNotReturn = Call.doesNotReturn();
IsVarArg = FuncTy->isVarArg();
IsReturnValueUsed = !Call.getInstruction()->use_empty();
- RetSExt = Call.paramHasAttr(0, Attribute::SExt);
- RetZExt = Call.paramHasAttr(0, Attribute::ZExt);
+ RetSExt = Call.hasRetAttr(Attribute::SExt);
+ RetZExt = Call.hasRetAttr(Attribute::ZExt);
CallConv = Call.getCallingConv();
Args = std::move(ArgsList);
@@ -125,12 +132,12 @@ public:
Callee = Call.getCalledValue();
Symbol = Target;
- IsInReg = Call.paramHasAttr(0, Attribute::InReg);
+ IsInReg = Call.hasRetAttr(Attribute::InReg);
DoesNotReturn = Call.doesNotReturn();
IsVarArg = FuncTy->isVarArg();
IsReturnValueUsed = !Call.getInstruction()->use_empty();
- RetSExt = Call.paramHasAttr(0, Attribute::SExt);
- RetZExt = Call.paramHasAttr(0, Attribute::ZExt);
+ RetSExt = Call.hasRetAttr(Attribute::SExt);
+ RetZExt = Call.hasRetAttr(Attribute::ZExt);
CallConv = Call.getCallingConv();
Args = std::move(ArgsList);
@@ -220,6 +227,8 @@ protected:
MachineInstr *EmitStartPt;
public:
+ virtual ~FastISel();
+
/// \brief Return the position of the last instruction emitted for
/// materializing constants for use in the current block.
MachineInstr *getLastLocalValue() { return LastLocalValue; }
@@ -311,8 +320,6 @@ public:
/// \brief Reset InsertPt to the given old insert position.
void leaveLocalValueArea(SavePoint Old);
- virtual ~FastISel();
-
protected:
explicit FastISel(FunctionLoweringInfo &FuncInfo,
const TargetLibraryInfo *LibInfo,
@@ -352,7 +359,7 @@ protected:
/// \brief This method is called by target-independent code to request that an
/// instruction with the given type, opcode, and register and immediate
- // operands be emitted.
+ /// operands be emitted.
virtual unsigned fastEmit_ri(MVT VT, MVT RetVT, unsigned Opcode, unsigned Op0,
bool Op0IsKill, uint64_t Imm);
@@ -510,7 +517,6 @@ protected:
}
}
-
bool lowerCall(const CallInst *I);
/// \brief Select and emit code for a binary operator instruction, which has
/// an opcode which directly corresponds to the given ISD opcode.
@@ -525,6 +531,7 @@ protected:
bool selectCast(const User *I, unsigned Opcode);
bool selectExtractValue(const User *I);
bool selectInsertValue(const User *I);
+ bool selectXRayCustomEvent(const CallInst *II);
private:
/// \brief Handle PHI nodes in successor blocks.
@@ -567,4 +574,4 @@ private:
} // end namespace llvm
-#endif
+#endif // LLVM_CODEGEN_FASTISEL_H
diff --git a/contrib/llvm/include/llvm/CodeGen/FaultMaps.h b/contrib/llvm/include/llvm/CodeGen/FaultMaps.h
index 9b5a3e1..98ff526 100644
--- a/contrib/llvm/include/llvm/CodeGen/FaultMaps.h
+++ b/contrib/llvm/include/llvm/CodeGen/FaultMaps.h
@@ -1,4 +1,4 @@
-//===------------------- FaultMaps.h - The "FaultMaps" section --*- C++ -*-===//
+//===- FaultMaps.h - The "FaultMaps" section --------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -12,26 +12,31 @@
#include "llvm/MC/MCSymbol.h"
#include "llvm/Support/Endian.h"
-#include "llvm/Support/Format.h"
-
-#include <vector>
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
#include <map>
+#include <vector>
namespace llvm {
class AsmPrinter;
class MCExpr;
-class MCSymbol;
-class MCStreamer;
+class raw_ostream;
class FaultMaps {
public:
- enum FaultKind { FaultingLoad = 1, FaultKindMax };
-
- static const char *faultTypeToString(FaultKind);
+ enum FaultKind {
+ FaultingLoad = 1,
+ FaultingLoadStore,
+ FaultingStore,
+ FaultKindMax
+ };
explicit FaultMaps(AsmPrinter &AP);
+ static const char *faultTypeToString(FaultKind);
+
void recordFaultingOp(FaultKind FaultTy, const MCSymbol *HandlerLabel);
void serializeToFaultMapSection();
@@ -39,13 +44,11 @@ private:
static const char *WFMP;
struct FaultInfo {
- FaultKind Kind;
- const MCExpr *FaultingOffsetExpr;
- const MCExpr *HandlerOffsetExpr;
+ FaultKind Kind = FaultKindMax;
+ const MCExpr *FaultingOffsetExpr = nullptr;
+ const MCExpr *HandlerOffsetExpr = nullptr;
- FaultInfo()
- : Kind(FaultKindMax), FaultingOffsetExpr(nullptr),
- HandlerOffsetExpr(nullptr) {}
+ FaultInfo() = default;
explicit FaultInfo(FaultMaps::FaultKind Kind, const MCExpr *FaultingOffset,
const MCExpr *HandlerOffset)
@@ -53,7 +56,7 @@ private:
HandlerOffsetExpr(HandlerOffset) {}
};
- typedef std::vector<FaultInfo> FunctionFaultInfos;
+ using FunctionFaultInfos = std::vector<FaultInfo>;
// We'd like to keep a stable iteration order for FunctionInfos to help
// FileCheck based testing.
@@ -75,20 +78,17 @@ private:
/// generated by the version of LLVM that includes it. No guarantees are made
/// with respect to forward or backward compatibility.
class FaultMapParser {
- typedef uint8_t FaultMapVersionType;
- static const size_t FaultMapVersionOffset = 0;
+ using FaultMapVersionType = uint8_t;
+ using Reserved0Type = uint8_t;
+ using Reserved1Type = uint16_t;
+ using NumFunctionsType = uint32_t;
- typedef uint8_t Reserved0Type;
+ static const size_t FaultMapVersionOffset = 0;
static const size_t Reserved0Offset =
FaultMapVersionOffset + sizeof(FaultMapVersionType);
-
- typedef uint16_t Reserved1Type;
static const size_t Reserved1Offset = Reserved0Offset + sizeof(Reserved0Type);
-
- typedef uint32_t NumFunctionsType;
static const size_t NumFunctionsOffset =
Reserved1Offset + sizeof(Reserved1Type);
-
static const size_t FunctionInfosOffset =
NumFunctionsOffset + sizeof(NumFunctionsType);
@@ -102,14 +102,13 @@ class FaultMapParser {
public:
class FunctionFaultInfoAccessor {
- typedef uint32_t FaultKindType;
- static const size_t FaultKindOffset = 0;
+ using FaultKindType = uint32_t;
+ using FaultingPCOffsetType = uint32_t;
+ using HandlerPCOffsetType = uint32_t;
- typedef uint32_t FaultingPCOffsetType;
+ static const size_t FaultKindOffset = 0;
static const size_t FaultingPCOffsetOffset =
FaultKindOffset + sizeof(FaultKindType);
-
- typedef uint32_t HandlerPCOffsetType;
static const size_t HandlerPCOffsetOffset =
FaultingPCOffsetOffset + sizeof(FaultingPCOffsetType);
@@ -137,27 +136,24 @@ public:
};
class FunctionInfoAccessor {
- typedef uint64_t FunctionAddrType;
- static const size_t FunctionAddrOffset = 0;
+ using FunctionAddrType = uint64_t;
+ using NumFaultingPCsType = uint32_t;
+ using ReservedType = uint32_t;
- typedef uint32_t NumFaultingPCsType;
+ static const size_t FunctionAddrOffset = 0;
static const size_t NumFaultingPCsOffset =
FunctionAddrOffset + sizeof(FunctionAddrType);
-
- typedef uint32_t ReservedType;
static const size_t ReservedOffset =
NumFaultingPCsOffset + sizeof(NumFaultingPCsType);
-
static const size_t FunctionFaultInfosOffset =
ReservedOffset + sizeof(ReservedType);
-
static const size_t FunctionInfoHeaderSize = FunctionFaultInfosOffset;
- const uint8_t *P;
- const uint8_t *E;
+ const uint8_t *P = nullptr;
+ const uint8_t *E = nullptr;
public:
- FunctionInfoAccessor() : P(nullptr), E(nullptr) {}
+ FunctionInfoAccessor() = default;
explicit FunctionInfoAccessor(const uint8_t *P, const uint8_t *E)
: P(P), E(E) {}
@@ -214,6 +210,6 @@ raw_ostream &operator<<(raw_ostream &OS,
raw_ostream &operator<<(raw_ostream &OS, const FaultMapParser &);
-} // namespace llvm
+} // end namespace llvm
-#endif
+#endif // LLVM_CODEGEN_FAULTMAPS_H
diff --git a/contrib/llvm/include/llvm/CodeGen/FunctionLoweringInfo.h b/contrib/llvm/include/llvm/CodeGen/FunctionLoweringInfo.h
index 75cd7da..f32a589 100644
--- a/contrib/llvm/include/llvm/CodeGen/FunctionLoweringInfo.h
+++ b/contrib/llvm/include/llvm/CodeGen/FunctionLoweringInfo.h
@@ -1,4 +1,4 @@
-//===-- FunctionLoweringInfo.h - Lower functions from LLVM IR to CodeGen --===//
+//===- FunctionLoweringInfo.h - Lower functions from LLVM IR to CodeGen ---===//
//
// The LLVM Compiler Infrastructure
//
@@ -23,28 +23,28 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/CodeGen/ISDOpcodes.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
-#include "llvm/IR/InlineAsm.h"
#include "llvm/IR/Instructions.h"
+#include "llvm/IR/Type.h"
+#include "llvm/IR/Value.h"
+#include "llvm/Support/KnownBits.h"
#include "llvm/Target/TargetRegisterInfo.h"
+#include <cassert>
+#include <utility>
#include <vector>
namespace llvm {
-class AllocaInst;
+class Argument;
class BasicBlock;
class BranchProbabilityInfo;
class Function;
-class GlobalVariable;
class Instruction;
-class MachineInstr;
-class MachineBasicBlock;
class MachineFunction;
-class MachineModuleInfo;
+class MachineInstr;
class MachineRegisterInfo;
-class SelectionDAG;
class MVT;
+class SelectionDAG;
class TargetLowering;
-class Value;
//===--------------------------------------------------------------------===//
/// FunctionLoweringInfo - This contains information that is global to a
@@ -73,25 +73,29 @@ public:
/// A map from swifterror value in a basic block to the virtual register it is
/// currently represented by.
- llvm::DenseMap<std::pair<const MachineBasicBlock *, const Value *>, unsigned>
+ DenseMap<std::pair<const MachineBasicBlock *, const Value *>, unsigned>
SwiftErrorVRegDefMap;
/// A list of upward exposed vreg uses that need to be satisfied by either a
/// copy def or a phi node at the beginning of the basic block representing
/// the predecessor(s) swifterror value.
- llvm::DenseMap<std::pair<const MachineBasicBlock *, const Value *>, unsigned>
+ DenseMap<std::pair<const MachineBasicBlock *, const Value *>, unsigned>
SwiftErrorVRegUpwardsUse;
+ /// A map from instructions that define/use a swifterror value to the virtual
+ /// register that represents that def/use.
+ llvm::DenseMap<PointerIntPair<const Instruction *, 1, bool>, unsigned>
+ SwiftErrorVRegDefUses;
+
/// The swifterror argument of the current function.
const Value *SwiftErrorArg;
- typedef SmallVector<const Value*, 1> SwiftErrorValues;
+ using SwiftErrorValues = SmallVector<const Value*, 1>;
/// A function can only have a single swifterror argument. And if it does
/// have a swifterror argument, it must be the first entry in
/// SwiftErrorVals.
SwiftErrorValues SwiftErrorVals;
-
/// Get or create the swifterror value virtual register in
/// SwiftErrorVRegDefMap for this basic block.
unsigned getOrCreateSwiftErrorVReg(const MachineBasicBlock *,
@@ -102,6 +106,13 @@ public:
void setCurrentSwiftErrorVReg(const MachineBasicBlock *MBB, const Value *,
unsigned);
+ /// Get or create the swifterror value virtual register for a def of a
+ /// swifterror by an instruction.
+ std::pair<unsigned, bool> getOrCreateSwiftErrorVRegDefAt(const Instruction *);
+ std::pair<unsigned, bool>
+ getOrCreateSwiftErrorVRegUseAt(const Instruction *, const MachineBasicBlock *,
+ const Value *);
+
/// 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.
@@ -117,7 +128,7 @@ public:
/// slot), and we track that here.
struct StatepointSpillMap {
- typedef DenseMap<const Value *, Optional<int>> SlotMapTy;
+ 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
@@ -171,9 +182,9 @@ public:
struct LiveOutInfo {
unsigned NumSignBits : 31;
unsigned IsValid : 1;
- APInt KnownOne, KnownZero;
- LiveOutInfo() : NumSignBits(0), IsValid(true), KnownOne(1, 0),
- KnownZero(1, 0) {}
+ KnownBits Known = 1;
+
+ LiveOutInfo() : NumSignBits(0), IsValid(true) {}
};
/// Record the preferred extend type (ISD::SIGN_EXTEND or ISD::ZERO_EXTEND)
@@ -247,16 +258,16 @@ public:
/// AddLiveOutRegInfo - Adds LiveOutInfo for a register.
void AddLiveOutRegInfo(unsigned Reg, unsigned NumSignBits,
- const APInt &KnownZero, const APInt &KnownOne) {
+ const KnownBits &Known) {
// Only install this information if it tells us something.
- if (NumSignBits == 1 && KnownZero == 0 && KnownOne == 0)
+ if (NumSignBits == 1 && Known.isUnknown())
return;
LiveOutRegInfo.grow(Reg);
LiveOutInfo &LOI = LiveOutRegInfo[Reg];
LOI.NumSignBits = NumSignBits;
- LOI.KnownOne = KnownOne;
- LOI.KnownZero = KnownZero;
+ LOI.Known.One = Known.One;
+ LOI.Known.Zero = Known.Zero;
}
/// ComputePHILiveOutRegInfo - Compute LiveOutInfo for a PHI's destination
@@ -298,4 +309,4 @@ private:
} // end namespace llvm
-#endif
+#endif // LLVM_CODEGEN_FUNCTIONLOWERINGINFO_H
diff --git a/contrib/llvm/include/llvm/CodeGen/GCMetadata.h b/contrib/llvm/include/llvm/CodeGen/GCMetadata.h
index e6afcbc..ad2599f 100644
--- a/contrib/llvm/include/llvm/CodeGen/GCMetadata.h
+++ b/contrib/llvm/include/llvm/CodeGen/GCMetadata.h
@@ -1,4 +1,4 @@
-//===-- GCMetadata.h - Garbage collector metadata ---------------*- C++ -*-===//
+//===- GCMetadata.h - Garbage collector metadata ----------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -36,15 +36,20 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/CodeGen/GCStrategy.h"
#include "llvm/IR/DebugLoc.h"
#include "llvm/Pass.h"
+#include <algorithm>
+#include <cstddef>
+#include <cstdint>
#include <memory>
-#include <utility>
+#include <vector>
namespace llvm {
-class AsmPrinter;
+
class Constant;
+class Function;
class MCSymbol;
/// GCPoint - Metadata for a collector-safe point in machine code.
@@ -62,20 +67,20 @@ struct GCPoint {
/// collector.
struct GCRoot {
int Num; ///< Usually a frame index.
- int StackOffset; ///< Offset from the stack pointer.
+ int StackOffset = -1; ///< Offset from the stack pointer.
const Constant *Metadata; ///< Metadata straight from the call
///< to llvm.gcroot.
- GCRoot(int N, const Constant *MD) : Num(N), StackOffset(-1), Metadata(MD) {}
+ GCRoot(int N, const Constant *MD) : Num(N), Metadata(MD) {}
};
/// Garbage collection metadata for a single function. Currently, this
/// information only applies to GCStrategies which use GCRoot.
class GCFunctionInfo {
public:
- typedef std::vector<GCPoint>::iterator iterator;
- typedef std::vector<GCRoot>::iterator roots_iterator;
- typedef std::vector<GCRoot>::const_iterator live_iterator;
+ using iterator = std::vector<GCPoint>::iterator;
+ using roots_iterator = std::vector<GCRoot>::iterator;
+ using live_iterator = std::vector<GCRoot>::const_iterator;
private:
const Function &F;
@@ -99,11 +104,9 @@ public:
~GCFunctionInfo();
/// getFunction - Return the function to which this metadata applies.
- ///
const Function &getFunction() const { return F; }
/// getStrategy - Return the GC strategy for the function.
- ///
GCStrategy &getStrategy() { return S; }
/// addStackRoot - Registers a root that lives on the stack. Num is the
@@ -126,24 +129,20 @@ public:
}
/// getFrameSize/setFrameSize - Records the function's frame size.
- ///
uint64_t getFrameSize() const { return FrameSize; }
void setFrameSize(uint64_t S) { FrameSize = S; }
/// begin/end - Iterators for safe points.
- ///
iterator begin() { return SafePoints.begin(); }
iterator end() { return SafePoints.end(); }
size_t size() const { return SafePoints.size(); }
/// roots_begin/roots_end - Iterators for all roots in the function.
- ///
roots_iterator roots_begin() { return Roots.begin(); }
roots_iterator roots_end() { return Roots.end(); }
size_t roots_size() const { return Roots.size(); }
/// live_begin/live_end - Iterators for live roots at a given safe point.
- ///
live_iterator live_begin(const iterator &p) { return roots_begin(); }
live_iterator live_end(const iterator &p) { return roots_end(); }
size_t live_size(const iterator &p) const { return roots_size(); }
@@ -166,7 +165,7 @@ public:
/// List of per function info objects. In theory, Each of these
/// may be associated with a different GC.
- typedef std::vector<std::unique_ptr<GCFunctionInfo>> FuncInfoVec;
+ using FuncInfoVec = std::vector<std::unique_ptr<GCFunctionInfo>>;
FuncInfoVec::iterator funcinfo_begin() { return Functions.begin(); }
FuncInfoVec::iterator funcinfo_end() { return Functions.end(); }
@@ -177,11 +176,11 @@ private:
/// Non-owning map to bypass linear search when finding the GCFunctionInfo
/// associated with a particular Function.
- typedef DenseMap<const Function *, GCFunctionInfo *> finfo_map_type;
+ using finfo_map_type = DenseMap<const Function *, GCFunctionInfo *>;
finfo_map_type FInfoMap;
public:
- typedef SmallVector<std::unique_ptr<GCStrategy>,1>::const_iterator iterator;
+ using iterator = SmallVector<std::unique_ptr<GCStrategy>, 1>::const_iterator;
static char ID;
@@ -202,6 +201,7 @@ public:
/// will soon change.
GCFunctionInfo &getFunctionInfo(const Function &F);
};
-}
-#endif
+} // end namespace llvm
+
+#endif // LLVM_CODEGEN_GCMETADATA_H
diff --git a/contrib/llvm/include/llvm/CodeGen/GCMetadataPrinter.h b/contrib/llvm/include/llvm/CodeGen/GCMetadataPrinter.h
index 2208470..1cc69a7 100644
--- a/contrib/llvm/include/llvm/CodeGen/GCMetadataPrinter.h
+++ b/contrib/llvm/include/llvm/CodeGen/GCMetadataPrinter.h
@@ -1,4 +1,4 @@
-//===-- llvm/CodeGen/GCMetadataPrinter.h - Prints asm GC tables -*- C++ -*-===//
+//===- llvm/CodeGen/GCMetadataPrinter.h - Prints asm GC tables --*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -20,45 +20,48 @@
#ifndef LLVM_CODEGEN_GCMETADATAPRINTER_H
#define LLVM_CODEGEN_GCMETADATAPRINTER_H
-#include "llvm/CodeGen/GCMetadata.h"
-#include "llvm/CodeGen/GCStrategy.h"
#include "llvm/Support/Registry.h"
namespace llvm {
+class AsmPrinter;
class GCMetadataPrinter;
+class GCModuleInfo;
+class GCStrategy;
+class Module;
/// GCMetadataPrinterRegistry - The GC assembly printer registry uses all the
/// defaults from Registry.
-typedef Registry<GCMetadataPrinter> GCMetadataPrinterRegistry;
+using GCMetadataPrinterRegistry = Registry<GCMetadataPrinter>;
/// GCMetadataPrinter - Emits GC metadata as assembly code. Instances are
/// created, managed, and owned by the AsmPrinter.
class GCMetadataPrinter {
private:
- GCStrategy *S;
friend class AsmPrinter;
+ GCStrategy *S;
+
protected:
// May only be subclassed.
GCMetadataPrinter();
-private:
+public:
GCMetadataPrinter(const GCMetadataPrinter &) = delete;
GCMetadataPrinter &operator=(const GCMetadataPrinter &) = delete;
+ virtual ~GCMetadataPrinter();
-public:
GCStrategy &getStrategy() { return *S; }
/// Called before the assembly for the module is generated by
/// the AsmPrinter (but after target specific hooks.)
virtual void beginAssembly(Module &M, GCModuleInfo &Info, AsmPrinter &AP) {}
+
/// Called after the assembly for the module is generated by
/// the AsmPrinter (but before target specific hooks)
virtual void finishAssembly(Module &M, GCModuleInfo &Info, AsmPrinter &AP) {}
-
- virtual ~GCMetadataPrinter();
};
-}
-#endif
+} // end namespace llvm
+
+#endif // LLVM_CODEGEN_GCMETADATAPRINTER_H
diff --git a/contrib/llvm/include/llvm/CodeGen/GCStrategy.h b/contrib/llvm/include/llvm/CodeGen/GCStrategy.h
index 3088a86..16168e7 100644
--- a/contrib/llvm/include/llvm/CodeGen/GCStrategy.h
+++ b/contrib/llvm/include/llvm/CodeGen/GCStrategy.h
@@ -1,4 +1,4 @@
-//===-- llvm/CodeGen/GCStrategy.h - Garbage collection ----------*- C++ -*-===//
+//===- llvm/CodeGen/GCStrategy.h - Garbage collection -----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -47,19 +47,20 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_IR_GCSTRATEGY_H
-#define LLVM_IR_GCSTRATEGY_H
+#ifndef LLVM_CODEGEN_GCSTRATEGY_H
+#define LLVM_CODEGEN_GCSTRATEGY_H
+#include "llvm/ADT/None.h"
#include "llvm/ADT/Optional.h"
-#include "llvm/IR/Function.h"
-#include "llvm/IR/Module.h"
-#include "llvm/IR/Value.h"
-#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Registry.h"
#include <string>
namespace llvm {
+
+class Type;
+
namespace GC {
+
/// PointKind - Used to indicate whether the address of the call instruction
/// or the address after the call instruction is listed in the stackmap. For
/// most runtimes, PostCall safepoints are appropriate.
@@ -68,7 +69,8 @@ enum PointKind {
PreCall, ///< Instr is a call instruction.
PostCall ///< Instr is the return address of a call.
};
-}
+
+} // end namespace GC
/// GCStrategy describes a garbage collector algorithm's code generation
/// requirements, and provides overridable hooks for those needs which cannot
@@ -77,24 +79,25 @@ enum PointKind {
/// be immutable.
class GCStrategy {
private:
- std::string Name;
friend class GCModuleInfo;
+ std::string Name;
+
protected:
- bool UseStatepoints; /// Uses gc.statepoints as opposed to gc.roots,
- /// if set, none of the other options can be
- /// anything but their default values.
+ bool UseStatepoints = false; /// Uses gc.statepoints as opposed to gc.roots,
+ /// if set, none of the other options can be
+ /// anything but their default values.
- unsigned NeededSafePoints; ///< Bitmask of required safe points.
- bool CustomReadBarriers; ///< Default is to insert loads.
- bool CustomWriteBarriers; ///< Default is to insert stores.
- bool CustomRoots; ///< Default is to pass through to backend.
- bool InitRoots; ///< If set, roots are nulled during lowering.
- bool UsesMetadata; ///< If set, backend must emit metadata tables.
+ unsigned NeededSafePoints = 0; ///< Bitmask of required safe points.
+ bool CustomReadBarriers = false; ///< Default is to insert loads.
+ bool CustomWriteBarriers = false; ///< Default is to insert stores.
+ bool CustomRoots = false; ///< Default is to pass through to backend.
+ bool InitRoots= true; ///< If set, roots are nulled during lowering.
+ bool UsesMetadata = false; ///< If set, backend must emit metadata tables.
public:
GCStrategy();
- virtual ~GCStrategy() {}
+ virtual ~GCStrategy() = default;
/// Return the name of the GC strategy. This is the value of the collector
/// name string specified on functions which use this strategy.
@@ -171,7 +174,8 @@ public:
/// Note that to use a custom GCMetadataPrinter w/gc.roots, you must also
/// register your GCMetadataPrinter subclass with the
/// GCMetadataPrinterRegistery as well.
-typedef Registry<GCStrategy> GCRegistry;
-}
+using GCRegistry = Registry<GCStrategy>;
+
+} // end namespace llvm
-#endif
+#endif // LLVM_CODEGEN_GCSTRATEGY_H
diff --git a/contrib/llvm/include/llvm/CodeGen/GlobalISel/CallLowering.h b/contrib/llvm/include/llvm/CodeGen/GlobalISel/CallLowering.h
index 0b157bf..e7ce194 100644
--- a/contrib/llvm/include/llvm/CodeGen/GlobalISel/CallLowering.h
+++ b/contrib/llvm/include/llvm/CodeGen/GlobalISel/CallLowering.h
@@ -1,4 +1,4 @@
-//===-- llvm/CodeGen/GlobalISel/CallLowering.h - Call lowering --*- C++ -*-===//
+//===- llvm/CodeGen/GlobalISel/CallLowering.h - Call lowering ---*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -15,29 +15,41 @@
#ifndef LLVM_CODEGEN_GLOBALISEL_CALLLOWERING_H
#define LLVM_CODEGEN_GLOBALISEL_CALLLOWERING_H
-#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/CodeGen/CallingConvLower.h"
-#include "llvm/CodeGen/ValueTypes.h"
-#include "llvm/IR/Function.h"
+#include "llvm/CodeGen/MachineValueType.h"
+#include "llvm/IR/CallSite.h"
+#include "llvm/IR/CallingConv.h"
+#include "llvm/Support/ErrorHandling.h"
#include "llvm/Target/TargetCallingConv.h"
+#include <cstdint>
+#include <functional>
namespace llvm {
-// Forward declarations.
+
+class DataLayout;
+class Function;
class MachineIRBuilder;
class MachineOperand;
+struct MachinePointerInfo;
+class MachineRegisterInfo;
class TargetLowering;
+class Type;
class Value;
class CallLowering {
const TargetLowering *TLI;
+
public:
struct ArgInfo {
unsigned Reg;
Type *Ty;
ISD::ArgFlagsTy Flags;
+ bool IsFixed;
- ArgInfo(unsigned Reg, Type *Ty, ISD::ArgFlagsTy Flags = ISD::ArgFlagsTy{})
- : Reg(Reg), Ty(Ty), Flags(Flags) {}
+ ArgInfo(unsigned Reg, Type *Ty, ISD::ArgFlagsTy Flags = ISD::ArgFlagsTy{},
+ bool IsFixed = true)
+ : Reg(Reg), Ty(Ty), Flags(Flags), IsFixed(IsFixed) {}
};
/// Argument handling is mostly uniform between the four places that
@@ -47,6 +59,12 @@ public:
/// arugment should go, exactly what happens can vary slightly. This
/// class abstracts the differences.
struct ValueHandler {
+ ValueHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
+ CCAssignFn *AssignFn)
+ : MIRBuilder(MIRBuilder), MRI(MRI), AssignFn(AssignFn) {}
+
+ virtual ~ValueHandler() = default;
+
/// Materialize a VReg containing the address of the specified
/// stack-based object. This is either based on a FrameIndex or
/// direct SP manipulation, depending on the context. \p MPO
@@ -68,15 +86,28 @@ public:
uint64_t Size, MachinePointerInfo &MPO,
CCValAssign &VA) = 0;
- unsigned extendRegister(unsigned ValReg, CCValAssign &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
+ /// processing.
+ virtual unsigned assignCustomValue(const ArgInfo &Arg,
+ ArrayRef<CCValAssign> VAs) {
+ // This is not a pure virtual method because not all targets need to worry
+ // about custom values.
+ llvm_unreachable("Custom values not supported");
+ }
- ValueHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI)
- : MIRBuilder(MIRBuilder), MRI(MRI) {}
+ unsigned extendRegister(unsigned ValReg, CCValAssign &VA);
- virtual ~ValueHandler() {}
+ virtual bool assignArg(unsigned ValNo, MVT ValVT, MVT LocVT,
+ CCValAssign::LocInfo LocInfo, const ArgInfo &Info,
+ CCState &State) {
+ return AssignFn(ValNo, ValVT, LocVT, LocInfo, Info.Flags, State);
+ }
MachineIRBuilder &MIRBuilder;
MachineRegisterInfo &MRI;
+ CCAssignFn *AssignFn;
};
protected:
@@ -91,21 +122,20 @@ protected:
return static_cast<const XXXTargetLowering *>(TLI);
}
-
template <typename FuncInfoTy>
void setArgFlags(ArgInfo &Arg, unsigned OpNum, const DataLayout &DL,
const FuncInfoTy &FuncInfo) const;
- /// Invoke the \p AssignFn on each of the given \p Args and then use
+ /// Invoke Handler::assignArg on each of the given \p Args and then use
/// \p Callback to move them to the assigned locations.
///
/// \return True if everything has succeeded, false otherwise.
- bool handleAssignments(MachineIRBuilder &MIRBuilder, CCAssignFn *AssignFn,
- ArrayRef<ArgInfo> Args, ValueHandler &Callback) const;
+ bool handleAssignments(MachineIRBuilder &MIRBuilder, ArrayRef<ArgInfo> Args,
+ ValueHandler &Callback) const;
public:
CallLowering(const TargetLowering *TLI) : TLI(TLI) {}
- virtual ~CallLowering() {}
+ virtual ~CallLowering() = default;
/// This hook must be implemented to lower outgoing return values, described
/// by \p Val, into the specified virtual register \p VReg.
@@ -135,6 +165,8 @@ public:
/// This hook must be implemented to lower the given call instruction,
/// including argument and return value marshalling.
///
+ /// \p CallConv is the calling convention to be used for the call.
+ ///
/// \p Callee is the destination of the call. It should be either a register,
/// globaladdress, or externalsymbol.
///
@@ -150,14 +182,16 @@ public:
/// needs to be passed.
///
/// \return true if the lowering succeeded, false otherwise.
- virtual bool lowerCall(MachineIRBuilder &MIRBuilder,
+ virtual bool lowerCall(MachineIRBuilder &MIRBuilder, CallingConv::ID CallConv,
const MachineOperand &Callee, const ArgInfo &OrigRet,
ArrayRef<ArgInfo> OrigArgs) const {
return false;
}
- /// This hook must be implemented to lower the given call instruction,
- /// including argument and return value marshalling.
+ /// Lower the given call instruction, including argument and return value
+ /// marshalling.
+ ///
+ /// \p CI is the call/invoke instruction.
///
/// \p ResReg is a register where the call's return value should be stored (or
/// 0 if there is no return value).
@@ -171,10 +205,11 @@ public:
/// range of an immediate jump.
///
/// \return true if the lowering succeeded, false otherwise.
- virtual bool lowerCall(MachineIRBuilder &MIRBuilder, const CallInst &CI,
- unsigned ResReg, ArrayRef<unsigned> ArgRegs,
- std::function<unsigned()> GetCalleeReg) const;
+ bool lowerCall(MachineIRBuilder &MIRBuilder, ImmutableCallSite CS,
+ unsigned ResReg, ArrayRef<unsigned> ArgRegs,
+ std::function<unsigned()> GetCalleeReg) const;
};
-} // End namespace llvm.
-#endif
+} // end namespace llvm
+
+#endif // LLVM_CODEGEN_GLOBALISEL_CALLLOWERING_H
diff --git a/contrib/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h b/contrib/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h
index 26ba5c6..7061c01 100644
--- a/contrib/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h
+++ b/contrib/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h
@@ -1,4 +1,4 @@
-//===-- llvm/CodeGen/GlobalISel/IRTranslator.h - IRTranslator ---*- C++ -*-===//
+//===- llvm/CodeGen/GlobalISel/IRTranslator.h - IRTranslator ----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -19,23 +19,33 @@
#ifndef LLVM_CODEGEN_GLOBALISEL_IRTRANSLATOR_H
#define LLVM_CODEGEN_GLOBALISEL_IRTRANSLATOR_H
-#include "Types.h"
#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
+#include "llvm/CodeGen/GlobalISel/Types.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/IR/Intrinsics.h"
+#include <memory>
+#include <utility>
namespace llvm {
-// Forward declarations.
+
+class AllocaInst;
class BasicBlock;
+class CallInst;
class CallLowering;
class Constant;
+class DataLayout;
class Instruction;
class MachineBasicBlock;
class MachineFunction;
class MachineInstr;
class MachineRegisterInfo;
+class OptimizationRemarkEmitter;
+class PHINode;
class TargetPassConfig;
+class User;
+class Value;
// Technically the pass should run on an hypothetical MachineModule,
// since it should translate Global into some sort of MachineGlobal.
@@ -52,24 +62,24 @@ public:
private:
/// Interface used to lower the everything related to calls.
const CallLowering *CLI;
+
/// Mapping of the values of the current LLVM IR function
/// to the related virtual registers.
ValueToVReg ValToVReg;
- // Constants are special because when we encounter one,
- // we do not know at first where to insert the definition since
- // this depends on all its uses.
- // Thus, we will insert the sequences to materialize them when
- // we know all their users.
- // In the meantime, just keep it in a set.
- // Note: Constants that end up as immediate in the related instructions,
- // do not appear in that map.
- SmallSetVector<const Constant *, 8> Constants;
// N.b. it's not completely obvious that this will be sufficient for every
// LLVM IR construct (with "invoke" being the obvious candidate to mess up our
// lives.
DenseMap<const BasicBlock *, MachineBasicBlock *> BBToMBB;
+ // One BasicBlock can be translated to multiple MachineBasicBlocks. For such
+ // BasicBlocks translated to multiple MachineBasicBlocks, MachinePreds retains
+ // a mapping between the edges arriving at the BasicBlock to the corresponding
+ // created MachineBasicBlocks. Some BasicBlocks that get translated to a
+ // single MachineBasicBlock may also end up in this Map.
+ using CFGEdge = std::pair<const BasicBlock *, const BasicBlock *>;
+ DenseMap<CFGEdge, SmallVector<MachineBasicBlock *, 1>> MachinePreds;
+
// List of stubbed PHI instructions, for values and basic blocks to be filled
// in once all MachineBasicBlocks have been created.
SmallVector<std::pair<const PHINode *, MachineInstr *>, 4> PendingPHIs;
@@ -78,7 +88,7 @@ private:
/// this function.
DenseMap<const AllocaInst *, int> FrameIndices;
- /// Methods for translating form LLVM IR to MachineInstr.
+ /// \name Methods for translating form LLVM IR to MachineInstr.
/// \see ::translate for general information on the translate methods.
/// @{
@@ -122,7 +132,9 @@ private:
/// Translate an LLVM store instruction into generic IR.
bool translateStore(const User &U, MachineIRBuilder &MIRBuilder);
- bool translateMemcpy(const CallInst &CI, MachineIRBuilder &MIRBuilder);
+ /// Translate an LLVM string intrinsic (memcpy, memset, ...).
+ bool translateMemfunc(const CallInst &CI, MachineIRBuilder &MIRBuilder,
+ unsigned Intrinsic);
void getStackGuard(unsigned DstReg, MachineIRBuilder &MIRBuilder);
@@ -132,6 +144,8 @@ private:
bool translateKnownIntrinsic(const CallInst &CI, Intrinsic::ID ID,
MachineIRBuilder &MIRBuilder);
+ bool translateInlineAsm(const CallInst &CI, MachineIRBuilder &MIRBuilder);
+
/// Translate call instruction.
/// \pre \p U is a call instruction.
bool translateCall(const User &U, MachineIRBuilder &MIRBuilder);
@@ -145,11 +159,6 @@ private:
bool translateCast(unsigned Opcode, const User &U,
MachineIRBuilder &MIRBuilder);
- /// Translate static alloca instruction (i.e. one of constant size and in the
- /// first basic block).
- bool translateStaticAlloca(const AllocaInst &Inst,
- MachineIRBuilder &MIRBuilder);
-
/// Translate a phi instruction.
bool translatePHI(const User &U, MachineIRBuilder &MIRBuilder);
@@ -166,7 +175,6 @@ private:
return translateCompare(U, MIRBuilder);
}
-
/// Add remaining operands onto phis we've translated. Executed after all
/// MachineBasicBlocks for the function have been created.
void finishPendingPhis();
@@ -182,6 +190,8 @@ private:
bool translateSwitch(const User &U, MachineIRBuilder &MIRBuilder);
+ bool translateIndirectBr(const User &U, MachineIRBuilder &MIRBuilder);
+
bool translateExtractValue(const User &U, MachineIRBuilder &MIRBuilder);
bool translateInsertValue(const User &U, MachineIRBuilder &MIRBuilder);
@@ -190,12 +200,16 @@ private:
bool translateGetElementPtr(const User &U, MachineIRBuilder &MIRBuilder);
+ bool translateAlloca(const User &U, MachineIRBuilder &MIRBuilder);
+
/// Translate return (ret) instruction.
/// The target needs to implement CallLowering::lowerReturn for
/// this to succeed.
/// \pre \p U is a return instruction.
bool translateRet(const User &U, MachineIRBuilder &MIRBuilder);
+ bool translateFSub(const User &U, MachineIRBuilder &MIRBuilder);
+
bool translateAdd(const User &U, MachineIRBuilder &MIRBuilder) {
return translateBinaryOp(TargetOpcode::G_ADD, U, MIRBuilder);
}
@@ -227,9 +241,6 @@ private:
bool translateSRem(const User &U, MachineIRBuilder &MIRBuilder) {
return translateBinaryOp(TargetOpcode::G_SREM, U, MIRBuilder);
}
- bool translateAlloca(const User &U, MachineIRBuilder &MIRBuilder) {
- return translateStaticAlloca(cast<AllocaInst>(U), MIRBuilder);
- }
bool translateIntToPtr(const User &U, MachineIRBuilder &MIRBuilder) {
return translateCast(TargetOpcode::G_INTTOPTR, U, MIRBuilder);
}
@@ -281,9 +292,6 @@ private:
bool translateFAdd(const User &U, MachineIRBuilder &MIRBuilder) {
return translateBinaryOp(TargetOpcode::G_FADD, U, MIRBuilder);
}
- bool translateFSub(const User &U, MachineIRBuilder &MIRBuilder) {
- return translateBinaryOp(TargetOpcode::G_FSUB, U, MIRBuilder);
- }
bool translateFMul(const User &U, MachineIRBuilder &MIRBuilder) {
return translateBinaryOp(TargetOpcode::G_FMUL, U, MIRBuilder);
}
@@ -294,11 +302,16 @@ private:
return translateBinaryOp(TargetOpcode::G_FREM, U, MIRBuilder);
}
+ bool translateVAArg(const User &U, MachineIRBuilder &MIRBuilder);
+
+ bool translateInsertElement(const User &U, MachineIRBuilder &MIRBuilder);
+
+ bool translateExtractElement(const User &U, MachineIRBuilder &MIRBuilder);
+
+ bool translateShuffleVector(const User &U, MachineIRBuilder &MIRBuilder);
+
// Stubs to keep the compiler happy while we implement the rest of the
// translation.
- bool translateIndirectBr(const User &U, MachineIRBuilder &MIRBuilder) {
- return false;
- }
bool translateResume(const User &U, MachineIRBuilder &MIRBuilder) {
return false;
}
@@ -335,18 +348,6 @@ private:
bool translateUserOp2(const User &U, MachineIRBuilder &MIRBuilder) {
return false;
}
- bool translateVAArg(const User &U, MachineIRBuilder &MIRBuilder) {
- return false;
- }
- bool translateExtractElement(const User &U, MachineIRBuilder &MIRBuilder) {
- return false;
- }
- bool translateInsertElement(const User &U, MachineIRBuilder &MIRBuilder) {
- return false;
- }
- bool translateShuffleVector(const User &U, MachineIRBuilder &MIRBuilder) {
- return false;
- }
/// @}
@@ -364,13 +365,16 @@ private:
MachineFunction *MF;
/// MachineRegisterInfo used to create virtual registers.
- MachineRegisterInfo *MRI;
+ MachineRegisterInfo *MRI = nullptr;
const DataLayout *DL;
/// Current target configuration. Controls how the pass handles errors.
const TargetPassConfig *TPC;
+ /// Current optimization remark emitter. Used to report failures.
+ std::unique_ptr<OptimizationRemarkEmitter> ORE;
+
// * Insert all the code needed to materialize the constants
// at the proper place. E.g., Entry block or dominator block
// of each constant depending on how fancy we want to be.
@@ -390,10 +394,27 @@ private:
/// the type being accessed (according to the Module's DataLayout).
unsigned getMemOpAlignment(const Instruction &I);
- /// Get the MachineBasicBlock that represents \p BB.
- /// If such basic block does not exist, it is created.
- MachineBasicBlock &getOrCreateBB(const BasicBlock &BB);
+ /// Get the MachineBasicBlock that represents \p BB. Specifically, the block
+ /// returned will be the head of the translated block (suitable for branch
+ /// destinations).
+ MachineBasicBlock &getMBB(const BasicBlock &BB);
+ /// Record \p NewPred as a Machine predecessor to `Edge.second`, corresponding
+ /// to `Edge.first` at the IR level. This is used when IRTranslation creates
+ /// multiple MachineBasicBlocks for a given IR block and the CFG is no longer
+ /// represented simply by the IR-level CFG.
+ void addMachineCFGPred(CFGEdge Edge, MachineBasicBlock *NewPred);
+
+ /// Returns the Machine IR predecessors for the given IR CFG edge. Usually
+ /// this is just the single MachineBasicBlock corresponding to the predecessor
+ /// in the IR. More complex lowering can result in multiple MachineBasicBlocks
+ /// preceding the original though (e.g. switch instructions).
+ SmallVector<MachineBasicBlock *, 1> getMachinePredBBs(CFGEdge Edge) {
+ auto RemappedEdge = MachinePreds.find(Edge);
+ if (RemappedEdge != MachinePreds.end())
+ return RemappedEdge->second;
+ return SmallVector<MachineBasicBlock *, 4>(1, &getMBB(*Edge.first));
+ }
public:
// Ctor, nothing fancy.
@@ -407,16 +428,17 @@ public:
// CallLowering = MF.subtarget.getCallLowering()
// F = MF.getParent()
// MIRBuilder.reset(MF)
- // MIRBuilder.getOrCreateBB(F.getEntryBB())
+ // getMBB(F.getEntryBB())
// CallLowering->translateArguments(MIRBuilder, F, ValToVReg)
// for each bb in F
- // MIRBuilder.getOrCreateBB(bb)
+ // getMBB(bb)
// for each inst in bb
// if (!translate(MIRBuilder, inst, ValToVReg, ConstantToSequence))
- // report_fatal_error(“Don’t know how to translate input");
+ // report_fatal_error("Don't know how to translate input");
// finalize()
bool runOnMachineFunction(MachineFunction &MF) override;
};
-} // End namespace llvm.
-#endif
+} // end namespace llvm
+
+#endif // LLVM_CODEGEN_GLOBALISEL_IRTRANSLATOR_H
diff --git a/contrib/llvm/include/llvm/CodeGen/GlobalISel/InstructionSelector.h b/contrib/llvm/include/llvm/CodeGen/GlobalISel/InstructionSelector.h
index 63b4f7b..1060d8f 100644
--- a/contrib/llvm/include/llvm/CodeGen/GlobalISel/InstructionSelector.h
+++ b/contrib/llvm/include/llvm/CodeGen/GlobalISel/InstructionSelector.h
@@ -1,4 +1,4 @@
-//==-- llvm/CodeGen/GlobalISel/InstructionSelector.h -------------*- C++ -*-==//
+//===- llvm/CodeGen/GlobalISel/InstructionSelector.h ------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -16,16 +16,182 @@
#ifndef LLVM_CODEGEN_GLOBALISEL_INSTRUCTIONSELECTOR_H
#define LLVM_CODEGEN_GLOBALISEL_INSTRUCTIONSELECTOR_H
+#include "llvm/ADT/SmallVector.h"
+#include <bitset>
+#include <cstddef>
+#include <cstdint>
+#include <functional>
+#include <initializer_list>
+#include <vector>
+
namespace llvm {
+
+class LLT;
class MachineInstr;
+class MachineInstrBuilder;
+class MachineOperand;
+class MachineRegisterInfo;
class RegisterBankInfo;
class TargetInstrInfo;
+class TargetRegisterClass;
class TargetRegisterInfo;
+/// Container class for CodeGen predicate results.
+/// This is convenient because std::bitset does not have a constructor
+/// with an initializer list of set bits.
+///
+/// Each InstructionSelector subclass should define a PredicateBitset class
+/// with:
+/// const unsigned MAX_SUBTARGET_PREDICATES = 192;
+/// using PredicateBitset = PredicateBitsetImpl<MAX_SUBTARGET_PREDICATES>;
+/// and updating the constant to suit the target. Tablegen provides a suitable
+/// definition for the predicates in use in <Target>GenGlobalISel.inc when
+/// GET_GLOBALISEL_PREDICATE_BITSET is defined.
+template <std::size_t MaxPredicates>
+class PredicateBitsetImpl : public std::bitset<MaxPredicates> {
+public:
+ // Cannot inherit constructors because it's not supported by VC++..
+ PredicateBitsetImpl() = default;
+
+ PredicateBitsetImpl(const std::bitset<MaxPredicates> &B)
+ : std::bitset<MaxPredicates>(B) {}
+
+ PredicateBitsetImpl(std::initializer_list<unsigned> Init) {
+ for (auto I : Init)
+ std::bitset<MaxPredicates>::set(I);
+ }
+};
+
+enum {
+ /// Record the specified instruction
+ /// - NewInsnID - Instruction ID to define
+ /// - InsnID - Instruction ID
+ /// - OpIdx - Operand index
+ GIM_RecordInsn,
+
+ /// Check the feature bits
+ /// - Expected features
+ GIM_CheckFeatures,
+
+ /// Check the opcode on the specified instruction
+ /// - InsnID - Instruction ID
+ /// - Expected opcode
+ GIM_CheckOpcode,
+ /// Check the instruction has the right number of operands
+ /// - InsnID - Instruction ID
+ /// - Expected number of operands
+ GIM_CheckNumOperands,
+
+ /// Check the type for the specified operand
+ /// - InsnID - Instruction ID
+ /// - OpIdx - Operand index
+ /// - Expected type
+ GIM_CheckType,
+ /// Check the register bank for the specified operand
+ /// - InsnID - Instruction ID
+ /// - OpIdx - Operand index
+ /// - Expected register bank (specified as a register class)
+ GIM_CheckRegBankForClass,
+ /// Check the operand matches a complex predicate
+ /// - InsnID - Instruction ID
+ /// - OpIdx - Operand index
+ /// - RendererID - The renderer to hold the result
+ /// - Complex predicate ID
+ GIM_CheckComplexPattern,
+ /// Check the operand is a specific integer
+ /// - InsnID - Instruction ID
+ /// - OpIdx - Operand index
+ /// - Expected integer
+ GIM_CheckConstantInt,
+ /// Check the operand is a specific literal integer (i.e. MO.isImm() or
+ /// MO.isCImm() is true).
+ /// - InsnID - Instruction ID
+ /// - OpIdx - Operand index
+ /// - Expected integer
+ GIM_CheckLiteralInt,
+ /// Check the operand is a specific intrinsic ID
+ /// - InsnID - Instruction ID
+ /// - OpIdx - Operand index
+ /// - Expected Intrinsic ID
+ GIM_CheckIntrinsicID,
+ /// Check the specified operand is an MBB
+ /// - InsnID - Instruction ID
+ /// - OpIdx - Operand index
+ GIM_CheckIsMBB,
+
+ /// Check if the specified operand is safe to fold into the current
+ /// instruction.
+ /// - InsnID - Instruction ID
+ GIM_CheckIsSafeToFold,
+
+ //=== Renderers ===
+
+ /// Mutate an instruction
+ /// - NewInsnID - Instruction ID to define
+ /// - OldInsnID - Instruction ID to mutate
+ /// - NewOpcode - The new opcode to use
+ GIR_MutateOpcode,
+ /// Build a new instruction
+ /// - InsnID - Instruction ID to define
+ /// - Opcode - The new opcode to use
+ GIR_BuildMI,
+
+ /// Copy an operand to the specified instruction
+ /// - NewInsnID - Instruction ID to modify
+ /// - OldInsnID - Instruction ID to copy from
+ /// - OpIdx - The operand to copy
+ GIR_Copy,
+ /// Copy an operand to the specified instruction
+ /// - NewInsnID - Instruction ID to modify
+ /// - OldInsnID - Instruction ID to copy from
+ /// - OpIdx - The operand to copy
+ /// - SubRegIdx - The subregister to copy
+ GIR_CopySubReg,
+ /// Add an implicit register def to the specified instruction
+ /// - InsnID - Instruction ID to modify
+ /// - RegNum - The register to add
+ GIR_AddImplicitDef,
+ /// Add an implicit register use to the specified instruction
+ /// - InsnID - Instruction ID to modify
+ /// - RegNum - The register to add
+ GIR_AddImplicitUse,
+ /// Add an register to the specified instruction
+ /// - InsnID - Instruction ID to modify
+ /// - RegNum - The register to add
+ GIR_AddRegister,
+ /// Add an immediate to the specified instruction
+ /// - InsnID - Instruction ID to modify
+ /// - Imm - The immediate to add
+ GIR_AddImm,
+ /// Render complex operands to the specified instruction
+ /// - InsnID - Instruction ID to modify
+ /// - RendererID - The renderer to call
+ GIR_ComplexRenderer,
+
+ /// Constrain an instruction operand to a register class.
+ /// - InsnID - Instruction ID to modify
+ /// - OpIdx - Operand index
+ /// - RCEnum - Register class enumeration value
+ GIR_ConstrainOperandRC,
+ /// Constrain an instructions operands according to the instruction
+ /// description.
+ /// - InsnID - Instruction ID to modify
+ GIR_ConstrainSelectedInstOperands,
+ /// Merge all memory operands into instruction.
+ /// - InsnID - Instruction ID to modify
+ GIR_MergeMemOperands,
+ /// Erase from parent.
+ /// - InsnID - Instruction ID to erase
+ GIR_EraseFromParent,
+
+ /// A successful emission
+ GIR_Done,
+};
+
/// Provides the logic to select generic machine instructions.
class InstructionSelector {
public:
- virtual ~InstructionSelector() {}
+ virtual ~InstructionSelector() = default;
/// Select the (possibly generic) instruction \p I to only use target-specific
/// opcodes. It is OK to insert multiple instructions, but they cannot be
@@ -41,8 +207,50 @@ public:
virtual bool select(MachineInstr &I) const = 0;
protected:
+ using ComplexRendererFn = std::function<void(MachineInstrBuilder &)>;
+ using RecordedMIVector = SmallVector<MachineInstr *, 4>;
+ using NewMIVector = SmallVector<MachineInstrBuilder, 4>;
+
+ struct MatcherState {
+ std::vector<ComplexRendererFn> Renderers;
+ RecordedMIVector MIs;
+
+ MatcherState(unsigned MaxRenderers);
+ };
+
+public:
+ template <class PredicateBitset, class ComplexMatcherMemFn>
+ struct MatcherInfoTy {
+ const LLT *TypeObjects;
+ const PredicateBitset *FeatureBitsets;
+ const std::vector<ComplexMatcherMemFn> ComplexPredicates;
+ };
+
+protected:
InstructionSelector();
+ /// Execute a given matcher table and return true if the match was successful
+ /// and false otherwise.
+ template <class TgtInstructionSelector, class PredicateBitset,
+ class ComplexMatcherMemFn>
+ bool executeMatchTable(
+ TgtInstructionSelector &ISel, NewMIVector &OutMIs, MatcherState &State,
+ const MatcherInfoTy<PredicateBitset, ComplexMatcherMemFn> &MatcherInfo,
+ const int64_t *MatchTable, const TargetInstrInfo &TII,
+ MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI,
+ const RegisterBankInfo &RBI,
+ const PredicateBitset &AvailableFeatures) const;
+
+ /// Constrain a register operand of an instruction \p I to a specified
+ /// register class. This could involve inserting COPYs before (for uses) or
+ /// after (for defs) and may replace the operand of \p I.
+ /// \returns whether operand regclass constraining succeeded.
+ bool constrainOperandRegToRegClass(MachineInstr &I, unsigned OpIdx,
+ const TargetRegisterClass &RC,
+ const TargetInstrInfo &TII,
+ const TargetRegisterInfo &TRI,
+ const RegisterBankInfo &RBI) const;
+
/// Mutate the newly-selected instruction \p I to constrain its (possibly
/// generic) virtual register operands to the instruction's register class.
/// This could involve inserting COPYs before (for uses) or after (for defs).
@@ -56,8 +264,13 @@ protected:
const TargetInstrInfo &TII,
const TargetRegisterInfo &TRI,
const RegisterBankInfo &RBI) const;
+
+ bool isOperandImmEqual(const MachineOperand &MO, int64_t Value,
+ const MachineRegisterInfo &MRI) const;
+
+ bool isObviouslySafeToFold(MachineInstr &MI) const;
};
-} // End namespace llvm.
+} // end namespace llvm
-#endif
+#endif // LLVM_CODEGEN_GLOBALISEL_INSTRUCTIONSELECTOR_H
diff --git a/contrib/llvm/include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h b/contrib/llvm/include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h
new file mode 100644
index 0000000..98b6b85
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h
@@ -0,0 +1,337 @@
+//==-- llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h ---------*- C++ -*-==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+/// \file This file declares the API for the instruction selector.
+/// This class is responsible for selecting machine instructions.
+/// It's implemented by the target. It's used by the InstructionSelect pass.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_GLOBALISEL_INSTRUCTIONSELECTORIMPL_H
+#define LLVM_CODEGEN_GLOBALISEL_INSTRUCTIONSELECTORIMPL_H
+
+namespace llvm {
+template <class TgtInstructionSelector, class PredicateBitset,
+ class ComplexMatcherMemFn>
+bool InstructionSelector::executeMatchTable(
+ TgtInstructionSelector &ISel, NewMIVector &OutMIs, MatcherState &State,
+ const MatcherInfoTy<PredicateBitset, ComplexMatcherMemFn> &MatcherInfo,
+ const int64_t *MatchTable, const TargetInstrInfo &TII,
+ MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI,
+ const RegisterBankInfo &RBI,
+ const PredicateBitset &AvailableFeatures) const {
+ const int64_t *Command = MatchTable;
+ while (true) {
+ switch (*Command++) {
+ case GIM_RecordInsn: {
+ int64_t NewInsnID = *Command++;
+ int64_t InsnID = *Command++;
+ int64_t OpIdx = *Command++;
+
+ // As an optimisation we require that MIs[0] is always the root. Refuse
+ // any attempt to modify it.
+ assert(NewInsnID != 0 && "Refusing to modify MIs[0]");
+ (void)NewInsnID;
+
+ MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
+ if (!MO.isReg()) {
+ DEBUG(dbgs() << "Rejected (not a register)\n");
+ return false;
+ }
+ if (TRI.isPhysicalRegister(MO.getReg())) {
+ DEBUG(dbgs() << "Rejected (is a physical register)\n");
+ return false;
+ }
+
+ assert((size_t)NewInsnID == State.MIs.size() &&
+ "Expected to store MIs in order");
+ State.MIs.push_back(MRI.getVRegDef(MO.getReg()));
+ DEBUG(dbgs() << "MIs[" << NewInsnID << "] = GIM_RecordInsn(" << InsnID
+ << ", " << OpIdx << ")\n");
+ break;
+ }
+
+ case GIM_CheckFeatures: {
+ int64_t ExpectedBitsetID = *Command++;
+ DEBUG(dbgs() << "GIM_CheckFeatures(ExpectedBitsetID=" << ExpectedBitsetID
+ << ")\n");
+ if ((AvailableFeatures & MatcherInfo.FeatureBitsets[ExpectedBitsetID]) !=
+ MatcherInfo.FeatureBitsets[ExpectedBitsetID]) {
+ DEBUG(dbgs() << "Rejected\n");
+ return false;
+ }
+ break;
+ }
+
+ case GIM_CheckOpcode: {
+ int64_t InsnID = *Command++;
+ int64_t Expected = *Command++;
+
+ unsigned Opcode = State.MIs[InsnID]->getOpcode();
+ DEBUG(dbgs() << "GIM_CheckOpcode(MIs[" << InsnID << "], ExpectedOpcode="
+ << Expected << ") // Got=" << Opcode << "\n");
+ assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
+ if (Opcode != Expected)
+ return false;
+ break;
+ }
+ case GIM_CheckNumOperands: {
+ int64_t InsnID = *Command++;
+ int64_t Expected = *Command++;
+ DEBUG(dbgs() << "GIM_CheckNumOperands(MIs[" << InsnID
+ << "], Expected=" << Expected << ")\n");
+ assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
+ if (State.MIs[InsnID]->getNumOperands() != Expected)
+ return false;
+ break;
+ }
+
+ case GIM_CheckType: {
+ int64_t InsnID = *Command++;
+ int64_t OpIdx = *Command++;
+ int64_t TypeID = *Command++;
+ DEBUG(dbgs() << "GIM_CheckType(MIs[" << InsnID << "]->getOperand("
+ << OpIdx << "), TypeID=" << TypeID << ")\n");
+ assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
+ if (MRI.getType(State.MIs[InsnID]->getOperand(OpIdx).getReg()) !=
+ MatcherInfo.TypeObjects[TypeID])
+ return false;
+ break;
+ }
+ case GIM_CheckRegBankForClass: {
+ int64_t InsnID = *Command++;
+ int64_t OpIdx = *Command++;
+ int64_t RCEnum = *Command++;
+ DEBUG(dbgs() << "GIM_CheckRegBankForClass(MIs[" << InsnID
+ << "]->getOperand(" << OpIdx << "), RCEnum=" << RCEnum
+ << ")\n");
+ assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
+ if (&RBI.getRegBankFromRegClass(*TRI.getRegClass(RCEnum)) !=
+ RBI.getRegBank(State.MIs[InsnID]->getOperand(OpIdx).getReg(), MRI, TRI))
+ return false;
+ break;
+ }
+ case GIM_CheckComplexPattern: {
+ int64_t InsnID = *Command++;
+ int64_t OpIdx = *Command++;
+ int64_t RendererID = *Command++;
+ int64_t ComplexPredicateID = *Command++;
+ DEBUG(dbgs() << "State.Renderers[" << RendererID
+ << "] = GIM_CheckComplexPattern(MIs[" << InsnID
+ << "]->getOperand(" << OpIdx
+ << "), ComplexPredicateID=" << ComplexPredicateID << ")\n");
+ assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
+ // FIXME: Use std::invoke() when it's available.
+ if (!(State.Renderers[RendererID] =
+ (ISel.*MatcherInfo.ComplexPredicates[ComplexPredicateID])(
+ State.MIs[InsnID]->getOperand(OpIdx))))
+ return false;
+ break;
+ }
+ case GIM_CheckConstantInt: {
+ int64_t InsnID = *Command++;
+ int64_t OpIdx = *Command++;
+ int64_t Value = *Command++;
+ DEBUG(dbgs() << "GIM_CheckConstantInt(MIs[" << InsnID << "]->getOperand("
+ << OpIdx << "), Value=" << Value << ")\n");
+ assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
+ if (!isOperandImmEqual(State.MIs[InsnID]->getOperand(OpIdx), Value, MRI))
+ return false;
+ break;
+ }
+ case GIM_CheckLiteralInt: {
+ int64_t InsnID = *Command++;
+ int64_t OpIdx = *Command++;
+ int64_t Value = *Command++;
+ DEBUG(dbgs() << "GIM_CheckLiteralInt(MIs[" << InsnID << "]->getOperand(" << OpIdx
+ << "), Value=" << Value << ")\n");
+ assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
+ MachineOperand &OM = State.MIs[InsnID]->getOperand(OpIdx);
+ if (!OM.isCImm() || !OM.getCImm()->equalsInt(Value))
+ return false;
+ break;
+ }
+ case GIM_CheckIntrinsicID: {
+ int64_t InsnID = *Command++;
+ int64_t OpIdx = *Command++;
+ int64_t Value = *Command++;
+ DEBUG(dbgs() << "GIM_CheckIntrinsicID(MIs[" << InsnID << "]->getOperand(" << OpIdx
+ << "), Value=" << Value << ")\n");
+ assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
+ MachineOperand &OM = State.MIs[InsnID]->getOperand(OpIdx);
+ if (!OM.isIntrinsicID() || OM.getIntrinsicID() != Value)
+ return false;
+ break;
+ }
+ case GIM_CheckIsMBB: {
+ int64_t InsnID = *Command++;
+ int64_t OpIdx = *Command++;
+ DEBUG(dbgs() << "GIM_CheckIsMBB(MIs[" << InsnID << "]->getOperand("
+ << OpIdx << "))\n");
+ assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
+ if (!State.MIs[InsnID]->getOperand(OpIdx).isMBB())
+ return false;
+ break;
+ }
+
+ case GIM_CheckIsSafeToFold: {
+ int64_t InsnID = *Command++;
+ DEBUG(dbgs() << "GIM_CheckIsSafeToFold(MIs[" << InsnID << "])\n");
+ assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
+ if (!isObviouslySafeToFold(*State.MIs[InsnID]))
+ return false;
+ break;
+ }
+
+ case GIR_MutateOpcode: {
+ int64_t OldInsnID = *Command++;
+ int64_t NewInsnID = *Command++;
+ int64_t NewOpcode = *Command++;
+ assert((size_t)NewInsnID == OutMIs.size() &&
+ "Expected to store MIs in order");
+ OutMIs.push_back(
+ MachineInstrBuilder(*State.MIs[OldInsnID]->getParent()->getParent(),
+ State.MIs[OldInsnID]));
+ OutMIs[NewInsnID]->setDesc(TII.get(NewOpcode));
+ DEBUG(dbgs() << "GIR_MutateOpcode(OutMIs[" << NewInsnID << "], MIs["
+ << OldInsnID << "], " << NewOpcode << ")\n");
+ break;
+ }
+ case GIR_BuildMI: {
+ int64_t InsnID = *Command++;
+ int64_t Opcode = *Command++;
+ assert((size_t)InsnID == OutMIs.size() &&
+ "Expected to store MIs in order");
+ (void)InsnID;
+ OutMIs.push_back(BuildMI(*State.MIs[0]->getParent(), State.MIs[0],
+ State.MIs[0]->getDebugLoc(), TII.get(Opcode)));
+ DEBUG(dbgs() << "GIR_BuildMI(OutMIs[" << InsnID << "], " << Opcode
+ << ")\n");
+ break;
+ }
+
+ case GIR_Copy: {
+ int64_t NewInsnID = *Command++;
+ int64_t OldInsnID = *Command++;
+ int64_t OpIdx = *Command++;
+ assert(OutMIs[NewInsnID] && "Attempted to add to undefined instruction");
+ OutMIs[NewInsnID].add(State.MIs[OldInsnID]->getOperand(OpIdx));
+ DEBUG(dbgs() << "GIR_Copy(OutMIs[" << NewInsnID << "], MIs[" << OldInsnID
+ << "], " << OpIdx << ")\n");
+ break;
+ }
+ case GIR_CopySubReg: {
+ int64_t NewInsnID = *Command++;
+ int64_t OldInsnID = *Command++;
+ int64_t OpIdx = *Command++;
+ int64_t SubRegIdx = *Command++;
+ assert(OutMIs[NewInsnID] && "Attempted to add to undefined instruction");
+ OutMIs[NewInsnID].addReg(State.MIs[OldInsnID]->getOperand(OpIdx).getReg(),
+ 0, SubRegIdx);
+ DEBUG(dbgs() << "GIR_CopySubReg(OutMIs[" << NewInsnID << "], MIs["
+ << OldInsnID << "], " << OpIdx << ", " << SubRegIdx
+ << ")\n");
+ break;
+ }
+ case GIR_AddImplicitDef: {
+ int64_t InsnID = *Command++;
+ int64_t RegNum = *Command++;
+ assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
+ OutMIs[InsnID].addDef(RegNum, RegState::Implicit);
+ DEBUG(dbgs() << "GIR_AddImplicitDef(OutMIs[" << InsnID << "], " << RegNum
+ << ")\n");
+ break;
+ }
+ case GIR_AddImplicitUse: {
+ int64_t InsnID = *Command++;
+ int64_t RegNum = *Command++;
+ assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
+ OutMIs[InsnID].addUse(RegNum, RegState::Implicit);
+ DEBUG(dbgs() << "GIR_AddImplicitUse(OutMIs[" << InsnID << "], " << RegNum
+ << ")\n");
+ break;
+ }
+ case GIR_AddRegister: {
+ int64_t InsnID = *Command++;
+ int64_t RegNum = *Command++;
+ assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
+ OutMIs[InsnID].addReg(RegNum);
+ DEBUG(dbgs() << "GIR_AddRegister(OutMIs[" << InsnID << "], " << RegNum
+ << ")\n");
+ break;
+ }
+ case GIR_AddImm: {
+ int64_t InsnID = *Command++;
+ int64_t Imm = *Command++;
+ assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
+ OutMIs[InsnID].addImm(Imm);
+ DEBUG(dbgs() << "GIR_AddImm(OutMIs[" << InsnID << "], " << Imm << ")\n");
+ break;
+ }
+ case GIR_ComplexRenderer: {
+ int64_t InsnID = *Command++;
+ int64_t RendererID = *Command++;
+ assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
+ State.Renderers[RendererID](OutMIs[InsnID]);
+ DEBUG(dbgs() << "GIR_ComplexRenderer(OutMIs[" << InsnID << "], "
+ << RendererID << ")\n");
+ break;
+ }
+
+ case GIR_ConstrainOperandRC: {
+ int64_t InsnID = *Command++;
+ int64_t OpIdx = *Command++;
+ int64_t RCEnum = *Command++;
+ assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
+ constrainOperandRegToRegClass(*OutMIs[InsnID].getInstr(), OpIdx,
+ *TRI.getRegClass(RCEnum), TII, TRI, RBI);
+ DEBUG(dbgs() << "GIR_ConstrainOperandRC(OutMIs[" << InsnID << "], "
+ << OpIdx << ", " << RCEnum << ")\n");
+ break;
+ }
+ case GIR_ConstrainSelectedInstOperands: {
+ int64_t InsnID = *Command++;
+ assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
+ constrainSelectedInstRegOperands(*OutMIs[InsnID].getInstr(), TII, TRI,
+ RBI);
+ DEBUG(dbgs() << "GIR_ConstrainSelectedInstOperands(OutMIs[" << InsnID
+ << "])\n");
+ break;
+ }
+ case GIR_MergeMemOperands: {
+ int64_t InsnID = *Command++;
+ assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
+ for (const auto *FromMI : State.MIs)
+ for (const auto &MMO : FromMI->memoperands())
+ OutMIs[InsnID].addMemOperand(MMO);
+ DEBUG(dbgs() << "GIR_MergeMemOperands(OutMIs[" << InsnID << "])\n");
+ break;
+ }
+ case GIR_EraseFromParent: {
+ int64_t InsnID = *Command++;
+ assert(State.MIs[InsnID] &&
+ "Attempted to erase an undefined instruction");
+ State.MIs[InsnID]->eraseFromParent();
+ DEBUG(dbgs() << "GIR_EraseFromParent(MIs[" << InsnID << "])\n");
+ break;
+ }
+
+ case GIR_Done:
+ DEBUG(dbgs() << "GIR_Done");
+ return true;
+
+ default:
+ llvm_unreachable("Unexpected command");
+ }
+ }
+}
+
+} // end namespace llvm
+
+#endif // LLVM_CODEGEN_GLOBALISEL_INSTRUCTIONSELECTORIMPL_H
diff --git a/contrib/llvm/include/llvm/CodeGen/GlobalISel/Legalizer.h b/contrib/llvm/include/llvm/CodeGen/GlobalISel/Legalizer.h
index 8284ab6..9b9b8b5 100644
--- a/contrib/llvm/include/llvm/CodeGen/GlobalISel/Legalizer.h
+++ b/contrib/llvm/include/llvm/CodeGen/GlobalISel/Legalizer.h
@@ -58,6 +58,9 @@ public:
bool combineExtracts(MachineInstr &MI, MachineRegisterInfo &MRI,
const TargetInstrInfo &TII);
+ bool combineMerges(MachineInstr &MI, MachineRegisterInfo &MRI,
+ const TargetInstrInfo &TII, MachineIRBuilder &MIRBuilder);
+
bool runOnMachineFunction(MachineFunction &MF) override;
};
} // End namespace llvm.
diff --git a/contrib/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h b/contrib/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
index 56c444c..1fd45b5 100644
--- a/contrib/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
+++ b/contrib/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
@@ -21,9 +21,11 @@
#ifndef LLVM_CODEGEN_GLOBALISEL_MACHINELEGALIZEHELPER_H
#define LLVM_CODEGEN_GLOBALISEL_MACHINELEGALIZEHELPER_H
+#include "llvm/CodeGen/GlobalISel/CallLowering.h"
#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
-#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/LowLevelType.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/RuntimeLibcalls.h"
namespace llvm {
// Forward declarations.
@@ -55,11 +57,7 @@ public:
///
/// Considered as an opaque blob, the legal code will use and define the same
/// registers as \p MI.
- LegalizeResult legalizeInstrStep(MachineInstr &MI,
- const LegalizerInfo &LegalizerInfo);
-
- LegalizeResult legalizeInstr(MachineInstr &MI,
- const LegalizerInfo &LegalizerInfo);
+ LegalizeResult legalizeInstrStep(MachineInstr &MI);
/// Legalize an instruction by emiting a runtime library call instead.
LegalizeResult libcall(MachineInstr &MI);
@@ -87,6 +85,10 @@ public:
LegalizeResult moreElementsVector(MachineInstr &MI, unsigned TypeIdx,
LLT WideTy);
+ /// Expose MIRBuilder so clients can set their own RecordInsertInstruction
+ /// functions
+ MachineIRBuilder MIRBuilder;
+
private:
/// Helper function to split a wide generic register into bitwise blocks with
@@ -95,10 +97,16 @@ private:
void extractParts(unsigned Reg, LLT Ty, int NumParts,
SmallVectorImpl<unsigned> &Ops);
- MachineIRBuilder MIRBuilder;
MachineRegisterInfo &MRI;
+ const LegalizerInfo &LI;
};
+/// Helper function that creates the given libcall.
+LegalizerHelper::LegalizeResult
+createLibcall(MachineIRBuilder &MIRBuilder, RTLIB::Libcall Libcall,
+ const CallLowering::ArgInfo &Result,
+ ArrayRef<CallLowering::ArgInfo> Args);
+
} // End namespace llvm.
#endif
diff --git a/contrib/llvm/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h b/contrib/llvm/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h
index edf52da..c259e93 100644
--- a/contrib/llvm/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h
+++ b/contrib/llvm/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h
@@ -1,4 +1,4 @@
-//==-- llvm/CodeGen/GlobalISel/LegalizerInfo.h -------------------*- C++ -*-==//
+//===- llvm/CodeGen/GlobalISel/LegalizerInfo.h ------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -12,32 +12,36 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CODEGEN_GLOBALISEL_MACHINELEGALIZER_H
-#define LLVM_CODEGEN_GLOBALISEL_MACHINELEGALIZER_H
+#ifndef LLVM_CODEGEN_GLOBALISEL_LEGALIZERINFO_H
+#define LLVM_CODEGEN_GLOBALISEL_LEGALIZERINFO_H
#include "llvm/ADT/DenseMap.h"
-#include "llvm/CodeGen/LowLevelType.h"
+#include "llvm/ADT/None.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/LowLevelTypeImpl.h"
#include "llvm/Target/TargetOpcodes.h"
-
#include <cstdint>
-#include <functional>
+#include <cassert>
+#include <tuple>
+#include <utility>
namespace llvm {
-class LLVMContext;
+
class MachineInstr;
+class MachineIRBuilder;
class MachineRegisterInfo;
-class Type;
-class VectorType;
/// Legalization is decided based on an instruction's opcode, which type slot
/// we're considering, and what the existing type is. These aspects are gathered
/// together for convenience in the InstrAspect class.
struct InstrAspect {
unsigned Opcode;
- unsigned Idx;
+ unsigned Idx = 0;
LLT Type;
- InstrAspect(unsigned Opcode, LLT Type) : Opcode(Opcode), Idx(0), Type(Type) {}
+ InstrAspect(unsigned Opcode, LLT Type) : Opcode(Opcode), Type(Type) {}
InstrAspect(unsigned Opcode, unsigned Idx, LLT Type)
: Opcode(Opcode), Idx(Idx), Type(Type) {}
@@ -96,12 +100,26 @@ public:
};
LegalizerInfo();
+ virtual ~LegalizerInfo() = default;
/// Compute any ancillary tables needed to quickly decide how an operation
/// should be handled. This must be called after all "set*Action"methods but
/// before any query is made or incorrect results may be returned.
void computeTables();
+ static bool needsLegalizingToDifferentSize(const LegalizeAction Action) {
+ switch (Action) {
+ case NarrowScalar:
+ case WidenScalar:
+ case FewerElements:
+ case MoreElements:
+ case Unsupported:
+ return true;
+ default:
+ return false;
+ }
+ }
+
/// More friendly way to set an action for common types that have an LLT
/// representation.
void setAction(const InstrAspect &Aspect, LegalizeAction Action) {
@@ -123,7 +141,6 @@ public:
ScalarInVectorActions[std::make_pair(Opcode, ScalarTy)] = Action;
}
-
/// Determine what action should be taken to legalize the given generic
/// instruction opcode, type-index and type. Requires computeTables to have
/// been called.
@@ -143,29 +160,35 @@ public:
/// Iterate the given function (typically something like doubling the width)
/// on Ty until we find a legal type for this operation.
- LLT findLegalType(const InstrAspect &Aspect,
- std::function<LLT(LLT)> NextType) const {
+ Optional<LLT> findLegalizableSize(const InstrAspect &Aspect,
+ function_ref<LLT(LLT)> NextType) const {
LegalizeAction Action;
const TypeMap &Map = Actions[Aspect.Opcode - FirstOp][Aspect.Idx];
LLT Ty = Aspect.Type;
do {
Ty = NextType(Ty);
auto ActionIt = Map.find(Ty);
- if (ActionIt == Map.end())
- Action = DefaultActions.find(Aspect.Opcode)->second;
- else
+ if (ActionIt == Map.end()) {
+ auto DefaultIt = DefaultActions.find(Aspect.Opcode);
+ if (DefaultIt == DefaultActions.end())
+ return None;
+ Action = DefaultIt->second;
+ } else
Action = ActionIt->second;
- } while(Action != Legal);
+ } while (needsLegalizingToDifferentSize(Action));
return Ty;
}
/// Find what type it's actually OK to perform the given operation on, given
/// the general approach we've decided to take.
- LLT findLegalType(const InstrAspect &Aspect, LegalizeAction Action) const;
+ Optional<LLT> findLegalType(const InstrAspect &Aspect, LegalizeAction Action) const;
std::pair<LegalizeAction, LLT> findLegalAction(const InstrAspect &Aspect,
LegalizeAction Action) const {
- return std::make_pair(Action, findLegalType(Aspect, Action));
+ auto LegalType = findLegalType(Aspect, Action);
+ if (!LegalType)
+ return std::make_pair(LegalizeAction::Unsupported, LLT());
+ return std::make_pair(Action, *LegalType);
}
/// Find the specified \p Aspect in the primary (explicitly set) Actions
@@ -186,22 +209,25 @@ public:
bool isLegal(const MachineInstr &MI, const MachineRegisterInfo &MRI) const;
+ virtual bool legalizeCustom(MachineInstr &MI,
+ MachineRegisterInfo &MRI,
+ MachineIRBuilder &MIRBuilder) const;
+
private:
static const int FirstOp = TargetOpcode::PRE_ISEL_GENERIC_OPCODE_START;
static const int LastOp = TargetOpcode::PRE_ISEL_GENERIC_OPCODE_END;
- typedef DenseMap<LLT, LegalizeAction> TypeMap;
- typedef DenseMap<std::pair<unsigned, LLT>, LegalizeAction> SIVActionMap;
+ using TypeMap = DenseMap<LLT, LegalizeAction>;
+ using SIVActionMap = DenseMap<std::pair<unsigned, LLT>, LegalizeAction>;
SmallVector<TypeMap, 1> Actions[LastOp - FirstOp + 1];
SIVActionMap ScalarInVectorActions;
DenseMap<std::pair<unsigned, LLT>, uint16_t> MaxLegalVectorElts;
DenseMap<unsigned, LegalizeAction> DefaultActions;
- bool TablesInitialized;
+ bool TablesInitialized = false;
};
+} // end namespace llvm
-} // End namespace llvm.
-
-#endif
+#endif // LLVM_CODEGEN_GLOBALISEL_LEGALIZERINFO_H
diff --git a/contrib/llvm/include/llvm/CodeGen/GlobalISel/Localizer.h b/contrib/llvm/include/llvm/CodeGen/GlobalISel/Localizer.h
new file mode 100644
index 0000000..0a46eb9
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/GlobalISel/Localizer.h
@@ -0,0 +1,78 @@
+//== llvm/CodeGen/GlobalISel/Localizer.h - Localizer -------------*- C++ -*-==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+/// \file This file describes the interface of the Localizer pass.
+/// This pass moves/duplicates constant-like instructions close to their uses.
+/// Its primarily goal is to workaround the deficiencies of the fast register
+/// allocator.
+/// With GlobalISel constants are all materialized in the entry block of
+/// a function. However, the fast allocator cannot rematerialize constants and
+/// has a lot more live-ranges to deal with and will most likely end up
+/// spilling a lot.
+/// By pushing the constants close to their use, we only create small
+/// live-ranges.
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_GLOBALISEL_LOCALIZER_H
+#define LLVM_CODEGEN_GLOBALISEL_LOCALIZER_H
+
+#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+
+namespace llvm {
+// Forward declarations.
+class MachineRegisterInfo;
+
+/// This pass implements the localization mechanism described at the
+/// top of this file. One specificity of the implementation is that
+/// it will materialize one and only one instance of a constant per
+/// basic block, thus enabling reuse of that constant within that block.
+/// Moreover, it only materializes constants in blocks where they
+/// are used. PHI uses are considered happening at the end of the
+/// related predecessor.
+class Localizer : public MachineFunctionPass {
+public:
+ static char ID;
+
+private:
+ /// MRI contains all the register class/bank information that this
+ /// pass uses and updates.
+ MachineRegisterInfo *MRI;
+
+ /// Check whether or not \p MI needs to be moved close to its uses.
+ static bool shouldLocalize(const MachineInstr &MI);
+
+ /// Check if \p MOUse is used in the same basic block as \p Def.
+ /// If the use is in the same block, we say it is local.
+ /// When the use is not local, \p InsertMBB will contain the basic
+ /// block when to insert \p Def to have a local use.
+ static bool isLocalUse(MachineOperand &MOUse, const MachineInstr &Def,
+ MachineBasicBlock *&InsertMBB);
+
+ /// Initialize the field members using \p MF.
+ void init(MachineFunction &MF);
+
+public:
+ Localizer();
+
+ StringRef getPassName() const override { return "Localizer"; }
+
+ MachineFunctionProperties getRequiredProperties() const override {
+ return MachineFunctionProperties()
+ .set(MachineFunctionProperties::Property::IsSSA)
+ .set(MachineFunctionProperties::Property::Legalized)
+ .set(MachineFunctionProperties::Property::RegBankSelected);
+ }
+
+ bool runOnMachineFunction(MachineFunction &MF) override;
+};
+
+} // End namespace llvm.
+
+#endif
diff --git a/contrib/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h b/contrib/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
index ecd3e5e..85e6fef 100644
--- a/contrib/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
+++ b/contrib/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
@@ -16,9 +16,10 @@
#include "llvm/CodeGen/GlobalISel/Types.h"
+#include "llvm/CodeGen/LowLevelType.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
-#include "llvm/CodeGen/LowLevelType.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DebugLoc.h"
@@ -40,12 +41,12 @@ class MachineIRBuilder {
MachineFunction *MF;
/// Information used to access the description of the opcodes.
const TargetInstrInfo *TII;
- /// Information used to verify types are consistent.
- const MachineRegisterInfo *MRI;
+ /// Information used to verify types are consistent and to create virtual registers.
+ MachineRegisterInfo *MRI;
/// Debug location to be set to any instruction we create.
DebugLoc DL;
- /// Fields describing the insertion point.
+ /// \name Fields describing the insertion point.
/// @{
MachineBasicBlock *MBB;
MachineBasicBlock::iterator II;
@@ -59,6 +60,21 @@ class MachineIRBuilder {
}
void validateTruncExt(unsigned Dst, unsigned Src, bool IsExtend);
+ MachineInstrBuilder buildBinaryOp(unsigned Opcode, unsigned Res, unsigned Op0, unsigned Op1);
+
+ unsigned getDestFromArg(unsigned Reg) { return Reg; }
+ unsigned getDestFromArg(LLT Ty) {
+ return getMF().getRegInfo().createGenericVirtualRegister(Ty);
+ }
+ unsigned getDestFromArg(const TargetRegisterClass *RC) {
+ return getMF().getRegInfo().createVirtualRegister(RC);
+ }
+
+ unsigned getRegFromArg(unsigned Reg) { return Reg; }
+
+ unsigned getRegFromArg(const MachineInstrBuilder &MIB) {
+ return MIB->getOperand(0).getReg();
+ }
public:
/// Getter for the function we currently build.
@@ -84,7 +100,7 @@ public:
void setInsertPt(MachineBasicBlock &MBB, MachineBasicBlock::iterator II);
/// @}
- /// Setters for the insertion point.
+ /// \name Setters for the insertion point.
/// @{
/// Set the MachineFunction where to build instructions.
void setMF(MachineFunction &);
@@ -98,7 +114,7 @@ public:
void setInstr(MachineInstr &MI);
/// @}
- /// Control where instructions we create are recorded (typically for
+ /// \name Control where instructions we create are recorded (typically for
/// visiting again later during legalization).
/// @{
void recordInsertions(std::function<void(MachineInstr *)> InsertedInstr);
@@ -108,6 +124,9 @@ public:
/// Set the debug location to \p DL for all the next build instructions.
void setDebugLoc(const DebugLoc &DL) { this->DL = DL; }
+ /// Get the current instruction's debug location.
+ DebugLoc getDebugLoc() { return DL; }
+
/// Build and insert <empty> = \p Opcode <empty>.
/// The insertion point is the one set by the last call of either
/// setBasicBlock or setMI.
@@ -117,6 +136,22 @@ public:
/// \return a MachineInstrBuilder for the newly created instruction.
MachineInstrBuilder buildInstr(unsigned Opcode);
+ /// DAG like Generic method for building arbitrary instructions as above.
+ /// \Opc opcode for the instruction.
+ /// \Ty Either LLT/TargetRegisterClass/unsigned types for Dst
+ /// \Args Variadic list of uses of types(unsigned/MachineInstrBuilder)
+ /// Uses of type MachineInstrBuilder will perform
+ /// getOperand(0).getReg() to convert to register.
+ template <typename DstTy, typename... UseArgsTy>
+ MachineInstrBuilder buildInstr(unsigned Opc, DstTy &&Ty,
+ UseArgsTy &&... Args) {
+ auto MIB = buildInstr(Opc).addDef(getDestFromArg(Ty));
+ unsigned It[] = {(getRegFromArg(Args))...};
+ for (const auto &i : It)
+ MIB.addUse(i);
+ return MIB;
+ }
+
/// Build but don't insert <empty> = \p Opcode <empty>.
///
/// \pre setMF, setBasicBlock or setMI must have been called.
@@ -127,6 +162,29 @@ public:
/// Insert an existing instruction at the insertion point.
MachineInstrBuilder insertInstr(MachineInstrBuilder MIB);
+ /// Build and insert a DBG_VALUE instruction expressing the fact that the
+ /// associated \p Variable lives in \p Reg (suitably modified by \p Expr).
+ MachineInstrBuilder buildDirectDbgValue(unsigned Reg, const MDNode *Variable,
+ const MDNode *Expr);
+
+ /// Build and insert a DBG_VALUE instruction expressing the fact that the
+ /// associated \p Variable lives in memory at \p Reg + \p Offset (suitably
+ /// modified by \p Expr).
+ MachineInstrBuilder buildIndirectDbgValue(unsigned Reg, unsigned Offset,
+ const MDNode *Variable,
+ const MDNode *Expr);
+ /// Build and insert a DBG_VALUE instruction expressing the fact that the
+ /// associated \p Variable lives in the stack slot specified by \p FI
+ /// (suitably modified by \p Expr).
+ MachineInstrBuilder buildFIDbgValue(int FI, const MDNode *Variable,
+ const MDNode *Expr);
+
+ /// Build and insert a DBG_VALUE instructions specifying that \p Variable is
+ /// given by \p C (suitably modified by \p Expr).
+ MachineInstrBuilder buildConstDbgValue(const Constant &C, unsigned Offset,
+ const MDNode *Variable,
+ const MDNode *Expr);
+
/// Build and insert \p Res<def> = G_FRAME_INDEX \p Idx
///
/// G_FRAME_INDEX materializes the address of an alloca value or other
@@ -162,6 +220,11 @@ public:
/// \return a MachineInstrBuilder for the newly created instruction.
MachineInstrBuilder buildAdd(unsigned Res, unsigned Op0,
unsigned Op1);
+ template <typename DstTy, typename... UseArgsTy>
+ MachineInstrBuilder buildAdd(DstTy &&Ty, UseArgsTy &&... UseArgs) {
+ unsigned Res = getDestFromArg(Ty);
+ return buildAdd(Res, (getRegFromArg(UseArgs))...);
+ }
/// Build and insert \p Res<def> = G_SUB \p Op0, \p Op1
///
@@ -203,6 +266,42 @@ public:
MachineInstrBuilder buildGEP(unsigned Res, unsigned Op0,
unsigned Op1);
+ /// Materialize and insert \p Res<def> = G_GEP \p Op0, (G_CONSTANT \p Value)
+ ///
+ /// G_GEP adds \p Value bytes to the pointer specified by \p Op0,
+ /// storing the resulting pointer in \p Res. If \p Value is zero then no
+ /// G_GEP or G_CONSTANT will be created and \pre Op0 will be assigned to
+ /// \p Res.
+ ///
+ /// \pre setBasicBlock or setMI must have been called.
+ /// \pre \p Op0 must be a generic virtual register with pointer type.
+ /// \pre \p ValueTy must be a scalar type.
+ /// \pre \p Res must be 0. This is to detect confusion between
+ /// materializeGEP() and buildGEP().
+ /// \post \p Res will either be a new generic virtual register of the same
+ /// type as \p Op0 or \p Op0 itself.
+ ///
+ /// \return a MachineInstrBuilder for the newly created instruction.
+ Optional<MachineInstrBuilder> materializeGEP(unsigned &Res, unsigned Op0,
+ const LLT &ValueTy,
+ uint64_t Value);
+
+ /// Build and insert \p Res<def> = G_PTR_MASK \p Op0, \p NumBits
+ ///
+ /// G_PTR_MASK 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.
+ ///
+ /// \pre setBasicBlock or setMI must have been called.
+ /// \pre \p Res and \p Op0 must be generic virtual registers with pointer
+ /// type.
+ /// \pre \p NumBits must be an integer representing the number of low bits to
+ /// be cleared in \p Op0.
+ ///
+ /// \return a MachineInstrBuilder for the newly created instruction.
+ MachineInstrBuilder buildPtrMask(unsigned Res, unsigned Op0,
+ uint32_t NumBits);
+
/// Build and insert \p Res<def>, \p CarryOut<def> = G_UADDE \p Op0,
/// \p Op1, \p CarryIn
///
@@ -220,6 +319,31 @@ public:
MachineInstrBuilder buildUAdde(unsigned Res, unsigned CarryOut, unsigned Op0,
unsigned Op1, unsigned CarryIn);
+ /// Build and insert \p Res<def> = G_AND \p Op0, \p Op1
+ ///
+ /// G_AND sets \p Res to the bitwise and of integer parameters \p Op0 and \p
+ /// Op1.
+ ///
+ /// \pre setBasicBlock or setMI must have been called.
+ /// \pre \p Res, \p Op0 and \p Op1 must be generic virtual registers
+ /// with the same (scalar or vector) type).
+ ///
+ /// \return a MachineInstrBuilder for the newly created instruction.
+ MachineInstrBuilder buildAnd(unsigned Res, unsigned Op0,
+ unsigned Op1);
+
+ /// Build and insert \p Res<def> = G_OR \p Op0, \p Op1
+ ///
+ /// G_OR sets \p Res to the bitwise or of integer parameters \p Op0 and \p
+ /// Op1.
+ ///
+ /// \pre setBasicBlock or setMI must have been called.
+ /// \pre \p Res, \p Op0 and \p Op1 must be generic virtual registers
+ /// with the same (scalar or vector) type).
+ ///
+ /// \return a MachineInstrBuilder for the newly created instruction.
+ MachineInstrBuilder buildOr(unsigned Res, unsigned Op0, unsigned Op1);
+
/// Build and insert \p Res<def> = G_ANYEXT \p Op0
///
/// G_ANYEXT produces a register of the specified width, with bits 0 to
@@ -273,6 +397,19 @@ public:
/// \return The newly created instruction.
MachineInstrBuilder buildSExtOrTrunc(unsigned Res, unsigned Op);
+ /// Build and insert \p Res<def> = G_ZEXT \p Op, \p Res = G_TRUNC \p Op, or
+ /// \p Res = COPY \p Op depending on the differing sizes of \p Res and \p Op.
+ /// ///
+ /// \pre setBasicBlock or setMI must have been called.
+ /// \pre \p Res must be a generic virtual register with scalar or vector type.
+ /// \pre \p Op must be a generic virtual register with scalar or vector type.
+ ///
+ /// \return The newly created instruction.
+ MachineInstrBuilder buildZExtOrTrunc(unsigned Res, unsigned Op);
+
+ /// Build and insert an appropriate cast between two registers of equal size.
+ MachineInstrBuilder buildCast(unsigned Dst, unsigned Src);
+
/// Build and insert G_BR \p Dest
///
/// G_BR is an unconditional branch to \p Dest.
@@ -296,6 +433,16 @@ public:
/// \return The newly created instruction.
MachineInstrBuilder buildBrCond(unsigned Tst, MachineBasicBlock &BB);
+ /// Build and insert G_BRINDIRECT \p Tgt
+ ///
+ /// G_BRINDIRECT is an indirect branch to \p Tgt.
+ ///
+ /// \pre setBasicBlock or setMI must have been called.
+ /// \pre \p Tgt must be a generic virtual register with pointer type.
+ ///
+ /// \return a MachineInstrBuilder for the newly created instruction.
+ MachineInstrBuilder buildBrIndirect(unsigned Tgt);
+
/// Build and insert \p Res = G_CONSTANT \p Val
///
/// G_CONSTANT is an integer constant with the specified size and value. \p
@@ -318,6 +465,10 @@ public:
/// \return The newly created instruction.
MachineInstrBuilder buildConstant(unsigned Res, int64_t Val);
+ template <typename DstType>
+ MachineInstrBuilder buildConstant(DstType &&Res, int64_t Val) {
+ return buildConstant(getDestFromArg(Res), Val);
+ }
/// Build and insert \p Res = G_FCONSTANT \p Val
///
/// G_FCONSTANT is a floating-point constant with the specified size and
@@ -362,24 +513,23 @@ public:
MachineInstrBuilder buildStore(unsigned Val, unsigned Addr,
MachineMemOperand &MMO);
- /// Build and insert `Res0<def>, ... = G_EXTRACT Src, Idx0, ...`.
- ///
- /// If \p Res[i] has size N bits, G_EXTRACT sets \p Res[i] to bits `[Idxs[i],
- /// Idxs[i] + N)` of \p Src.
+ /// Build and insert `Res0<def>, ... = G_EXTRACT Src, Idx0`.
///
/// \pre setBasicBlock or setMI must have been called.
- /// \pre Indices must be in ascending order of bit position.
- /// \pre Each member of \p Results and \p Src must be a generic
- /// virtual register.
+ /// \pre \p Res and \p Src must be generic virtual registers.
///
/// \return a MachineInstrBuilder for the newly created instruction.
- MachineInstrBuilder buildExtract(ArrayRef<unsigned> Results,
- ArrayRef<uint64_t> Indices, unsigned Src);
+ MachineInstrBuilder buildExtract(unsigned Res, unsigned Src, uint64_t Index);
+
+ /// Build and insert \p Res = IMPLICIT_DEF.
+ MachineInstrBuilder buildUndef(unsigned Dst);
- /// Build and insert \p Res<def> = G_SEQUENCE \p Op0, \p Idx0...
+ /// Build and insert instructions to put \p Ops together at the specified p
+ /// Indices to form a larger register.
///
- /// G_SEQUENCE inserts each element of Ops into an IMPLICIT_DEF register,
- /// where each entry starts at the bit-index specified by \p Indices.
+ /// If the types of the input registers are uniform and cover the entirity of
+ /// \p Res then a G_MERGE_VALUES will be produced. Otherwise an IMPLICIT_DEF
+ /// followed by a sequence of G_INSERT instructions.
///
/// \pre setBasicBlock or setMI must have been called.
/// \pre The final element of the sequence must not extend past the end of the
@@ -387,38 +537,36 @@ public:
/// \pre The bits defined by each Op (derived from index and scalar size) must
/// not overlap.
/// \pre \p Indices must be in ascending order of bit position.
+ void buildSequence(unsigned Res, ArrayRef<unsigned> Ops,
+ ArrayRef<uint64_t> Indices);
+
+ /// Build and insert \p Res<def> = G_MERGE_VALUES \p Op0, ...
+ ///
+ /// G_MERGE_VALUES combines the input elements contiguously into a larger
+ /// register.
+ ///
+ /// \pre setBasicBlock or setMI must have been called.
+ /// \pre The entire register \p Res (and no more) must be covered by the input
+ /// registers.
+ /// \pre The type of all \p Ops registers must be identical.
///
/// \return a MachineInstrBuilder for the newly created instruction.
- MachineInstrBuilder buildSequence(unsigned Res,
- ArrayRef<unsigned> Ops,
- ArrayRef<uint64_t> Indices);
-
- void addUsesWithIndices(MachineInstrBuilder MIB) {}
+ MachineInstrBuilder buildMerge(unsigned Res, ArrayRef<unsigned> Ops);
- template <typename... ArgTys>
- void addUsesWithIndices(MachineInstrBuilder MIB, unsigned Reg,
- unsigned BitIndex, ArgTys... Args) {
- MIB.addUse(Reg).addImm(BitIndex);
- addUsesWithIndices(MIB, Args...);
- }
-
- template <typename... ArgTys>
- MachineInstrBuilder buildSequence(unsigned Res, unsigned Op,
- unsigned Index, ArgTys... Args) {
- MachineInstrBuilder MIB =
- buildInstr(TargetOpcode::G_SEQUENCE).addDef(Res);
- addUsesWithIndices(MIB, Op, Index, Args...);
- return MIB;
- }
+ /// Build and insert \p Res0<def>, ... = G_UNMERGE_VALUES \p Op
+ ///
+ /// G_UNMERGE_VALUES splits contiguous bits of the input into multiple
+ ///
+ /// \pre setBasicBlock or setMI must have been called.
+ /// \pre The entire register \p Res (and no more) must be covered by the input
+ /// registers.
+ /// \pre The type of all \p Res registers must be identical.
+ ///
+ /// \return a MachineInstrBuilder for the newly created instruction.
+ MachineInstrBuilder buildUnmerge(ArrayRef<unsigned> Res, unsigned Op);
- template <typename... ArgTys>
MachineInstrBuilder buildInsert(unsigned Res, unsigned Src,
- unsigned Op, unsigned Index, ArgTys... Args) {
- MachineInstrBuilder MIB =
- buildInstr(TargetOpcode::G_INSERT).addDef(Res).addUse(Src);
- addUsesWithIndices(MIB, Op, Index, Args...);
- return MIB;
- }
+ unsigned 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
@@ -500,6 +648,30 @@ public:
/// \return a MachineInstrBuilder for the newly created instruction.
MachineInstrBuilder buildSelect(unsigned Res, unsigned Tst,
unsigned Op0, unsigned Op1);
+
+ /// Build and insert \p Res<def> = G_INSERT_VECTOR_ELT \p Val,
+ /// \p Elt, \p Idx
+ ///
+ /// \pre setBasicBlock or setMI must have been called.
+ /// \pre \p Res and \p Val must be a generic virtual register
+ // with the same vector type.
+ /// \pre \p Elt and \p Idx must be a generic virtual register
+ /// with scalar type.
+ ///
+ /// \return The newly created instruction.
+ MachineInstrBuilder buildInsertVectorElement(unsigned Res, unsigned Val,
+ unsigned Elt, unsigned Idx);
+
+ /// Build and insert \p Res<def> = G_EXTRACT_VECTOR_ELT \p Val, \p Idx
+ ///
+ /// \pre setBasicBlock or setMI must have been called.
+ /// \pre \p Res must be a generic virtual register with scalar type.
+ /// \pre \p Val must be a generic virtual register with vector type.
+ /// \pre \p Idx must be a generic virtual register with scalar type.
+ ///
+ /// \return The newly created instruction.
+ MachineInstrBuilder buildExtractVectorElement(unsigned Res, unsigned Val,
+ unsigned Idx);
};
} // End namespace llvm.
diff --git a/contrib/llvm/include/llvm/CodeGen/GlobalISel/RegBankSelect.h b/contrib/llvm/include/llvm/CodeGen/GlobalISel/RegBankSelect.h
index b331533..676955c 100644
--- a/contrib/llvm/include/llvm/CodeGen/GlobalISel/RegBankSelect.h
+++ b/contrib/llvm/include/llvm/CodeGen/GlobalISel/RegBankSelect.h
@@ -1,4 +1,4 @@
-//== llvm/CodeGen/GlobalISel/RegBankSelect.h - Reg Bank Selector -*- C++ -*-==//
+//=- llvm/CodeGen/GlobalISel/RegBankSelect.h - Reg Bank Selector --*- C++ -*-=//
//
// The LLVM Compiler Infrastructure
//
@@ -64,19 +64,27 @@
#ifndef LLVM_CODEGEN_GLOBALISEL_REGBANKSELECT_H
#define LLVM_CODEGEN_GLOBALISEL_REGBANKSELECT_H
+#include "llvm/ADT/SmallVector.h"
#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
#include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h"
+#include <cassert>
+#include <cstdint>
+#include <memory>
namespace llvm {
-// Forward declarations.
+
class BlockFrequency;
-class MachineBranchProbabilityInfo;
class MachineBlockFrequencyInfo;
+class MachineBranchProbabilityInfo;
+class MachineOperand;
class MachineRegisterInfo;
+class Pass;
+class raw_ostream;
class TargetPassConfig;
class TargetRegisterInfo;
-class raw_ostream;
/// This pass implements the reg bank selector pass used in the GlobalISel
/// pipeline. At the end of this pass, all register operands have been assigned
@@ -104,6 +112,7 @@ public:
protected:
/// Tell if the insert point has already been materialized.
bool WasMaterialized = false;
+
/// Materialize the insertion point.
///
/// If isSplit() is true, this involves actually splitting
@@ -127,7 +136,7 @@ public:
virtual MachineBasicBlock::iterator getPointImpl() = 0;
public:
- virtual ~InsertPoint() {}
+ virtual ~InsertPoint() = default;
/// The first call to this method will cause the splitting to
/// happen if need be, then sub sequent calls just return
@@ -196,6 +205,7 @@ public:
private:
/// Insertion point.
MachineInstr &Instr;
+
/// Does the insertion point is before or after Instr.
bool Before;
@@ -215,6 +225,7 @@ public:
public:
/// Create an insertion point before (\p Before=true) or after \p Instr.
InstrInsertPoint(MachineInstr &Instr, bool Before = true);
+
bool isSplit() const override;
uint64_t frequency(const Pass &P) const override;
@@ -227,6 +238,7 @@ public:
private:
/// Insertion point.
MachineBasicBlock &MBB;
+
/// Does the insertion point is at the beginning or end of MBB.
bool Beginning;
@@ -251,6 +263,7 @@ public:
assert((Beginning || MBB.getFirstTerminator() == MBB.end()) &&
"Invalid end point");
}
+
bool isSplit() const override { return false; }
uint64_t frequency(const Pass &P) const override;
bool canMaterialize() const override { return true; };
@@ -261,10 +274,12 @@ public:
private:
/// Source of the edge.
MachineBasicBlock &Src;
+
/// Destination of the edge.
/// After the materialization is done, this hold the basic block
/// that resulted from the splitting.
MachineBasicBlock *DstOrSplit;
+
/// P is used to update the analysis passes as applicable.
Pass &P;
@@ -285,9 +300,11 @@ public:
public:
EdgeInsertPoint(MachineBasicBlock &Src, MachineBasicBlock &Dst, Pass &P)
: InsertPoint(), Src(Src), DstOrSplit(&Dst), P(P) {}
+
bool isSplit() const override {
return Src.succ_size() > 1 && DstOrSplit->pred_size() > 1;
}
+
uint64_t frequency(const Pass &P) const override;
bool canMaterialize() const override;
};
@@ -308,11 +325,11 @@ public:
Impossible
};
- /// Convenient types for a list of insertion points.
+ /// \name Convenient types for a list of insertion points.
/// @{
- typedef SmallVector<std::unique_ptr<InsertPoint>, 2> InsertionPoints;
- typedef InsertionPoints::iterator insertpt_iterator;
- typedef InsertionPoints::const_iterator const_insertpt_iterator;
+ using InsertionPoints = SmallVector<std::unique_ptr<InsertPoint>, 2>;
+ using insertpt_iterator = InsertionPoints::iterator;
+ using const_insertpt_iterator = InsertionPoints::const_iterator;
/// @}
private:
@@ -323,7 +340,7 @@ public:
/// Are all the insert points materializeable?
bool CanMaterialize;
/// Is there any of the insert points needing splitting?
- bool HasSplit;
+ bool HasSplit = false;
/// Insertion point for the repair code.
/// The repairing code needs to happen just before these points.
InsertionPoints InsertPoints;
@@ -340,7 +357,7 @@ public:
const TargetRegisterInfo &TRI, Pass &P,
RepairingKind Kind = RepairingKind::Insert);
- /// Getters.
+ /// \name Getters.
/// @{
RepairingKind getKind() const { return Kind; }
unsigned getOpIdx() const { return OpIdx; }
@@ -348,7 +365,7 @@ public:
bool hasSplit() { return HasSplit; }
/// @}
- /// Overloaded methods to add an insertion point.
+ /// \name Overloaded methods to add an insertion point.
/// @{
/// Add a MBBInsertionPoint to the list of InsertPoints.
void addInsertPoint(MachineBasicBlock &MBB, bool Beginning);
@@ -361,7 +378,7 @@ public:
void addInsertPoint(InsertPoint &Point);
/// @}
- /// Accessors related to the insertion points.
+ /// \name Accessors related to the insertion points.
/// @{
insertpt_iterator begin() { return InsertPoints.begin(); }
insertpt_iterator end() { return InsertPoints.end(); }
@@ -406,10 +423,10 @@ private:
private:
/// Cost of the local instructions.
/// This cost is free of basic block frequency.
- uint64_t LocalCost;
+ uint64_t LocalCost = 0;
/// Cost of the non-local instructions.
/// This cost should include the frequency of the related blocks.
- uint64_t NonLocalCost;
+ uint64_t NonLocalCost = 0;
/// Frequency of the block where the local instructions live.
uint64_t LocalFreq;
@@ -467,22 +484,25 @@ private:
/// Interface to the target lowering info related
/// to register banks.
- const RegisterBankInfo *RBI;
+ const RegisterBankInfo *RBI = nullptr;
/// MRI contains all the register class/bank information that this
/// pass uses and updates.
- MachineRegisterInfo *MRI;
+ MachineRegisterInfo *MRI = nullptr;
/// Information on the register classes for the current function.
- const TargetRegisterInfo *TRI;
+ const TargetRegisterInfo *TRI = nullptr;
/// Get the frequency of blocks.
/// This is required for non-fast mode.
- MachineBlockFrequencyInfo *MBFI;
+ MachineBlockFrequencyInfo *MBFI = nullptr;
/// Get the frequency of the edges.
/// This is required for non-fast mode.
- MachineBranchProbabilityInfo *MBPI;
+ MachineBranchProbabilityInfo *MBPI = nullptr;
+
+ /// Current optimization remark emitter. Used to report failures.
+ std::unique_ptr<MachineOptimizationRemarkEmitter> MORE;
/// Helper class used for every code morphing.
MachineIRBuilder MIRBuilder;
@@ -557,7 +577,7 @@ private:
/// Find the best mapping for \p MI from \p PossibleMappings.
/// \return a reference on the best mapping in \p PossibleMappings.
- RegisterBankInfo::InstructionMapping &
+ const RegisterBankInfo::InstructionMapping &
findBestMapping(MachineInstr &MI,
RegisterBankInfo::InstructionMappings &PossibleMappings,
SmallVectorImpl<RepairingPlacement> &RepairPts);
@@ -640,6 +660,6 @@ public:
bool runOnMachineFunction(MachineFunction &MF) override;
};
-} // End namespace llvm.
+} // end namespace llvm
-#endif
+#endif // LLVM_CODEGEN_GLOBALISEL_REGBANKSELECT_H
diff --git a/contrib/llvm/include/llvm/CodeGen/GlobalISel/RegisterBank.h b/contrib/llvm/include/llvm/CodeGen/GlobalISel/RegisterBank.h
index b05bf99..5d75842 100644
--- a/contrib/llvm/include/llvm/CodeGen/GlobalISel/RegisterBank.h
+++ b/contrib/llvm/include/llvm/CodeGen/GlobalISel/RegisterBank.h
@@ -42,7 +42,7 @@ private:
public:
RegisterBank(unsigned ID, const char *Name, unsigned Size,
- const uint32_t *ContainedRegClasses);
+ const uint32_t *ContainedRegClasses, unsigned NumRegClasses);
/// Get the identifier of this register bank.
unsigned getID() const { return ID; }
diff --git a/contrib/llvm/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h b/contrib/llvm/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h
index 312dc93..60905c7 100644
--- a/contrib/llvm/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h
+++ b/contrib/llvm/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h
@@ -1,4 +1,4 @@
-//==-- llvm/CodeGen/GlobalISel/RegisterBankInfo.h ----------------*- C++ -*-==//
+//===- llvm/CodeGen/GlobalISel/RegisterBankInfo.h ---------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -12,26 +12,27 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CODEGEN_GLOBALISEL_REGBANKINFO_H
-#define LLVM_CODEGEN_GLOBALISEL_REGBANKINFO_H
+#ifndef LLVM_CODEGEN_GLOBALISEL_REGISTERBANKINFO_H
+#define LLVM_CODEGEN_GLOBALISEL_REGISTERBANKINFO_H
-#include "llvm/ADT/APInt.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/Hashing.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/CodeGen/GlobalISel/RegisterBank.h"
-#include "llvm/CodeGen/MachineValueType.h" // For SimpleValueType.
+#include "llvm/ADT/iterator_range.h"
#include "llvm/Support/ErrorHandling.h"
-
#include <cassert>
-#include <memory> // For unique_ptr.
+#include <initializer_list>
+#include <memory>
namespace llvm {
+
class MachineInstr;
class MachineRegisterInfo;
+class raw_ostream;
+class RegisterBank;
class TargetInstrInfo;
+class TargetRegisterClass;
class TargetRegisterInfo;
-class raw_ostream;
/// Holds all the information related to register banks.
class RegisterBankInfo {
@@ -48,10 +49,12 @@ public:
/// original value. The bits are counted from less significant
/// bits to most significant bits.
unsigned StartIdx;
+
/// Length of this mapping in bits. This is how many bits this
/// partial mapping covers in the original value:
/// from StartIdx to StartIdx + Length -1.
unsigned Length;
+
/// Register bank where the partial value lives.
const RegisterBank *RegBank;
@@ -180,13 +183,16 @@ public:
/// Identifier of the mapping.
/// This is used to communicate between the target and the optimizers
/// which mapping should be realized.
- unsigned ID;
+ unsigned ID = InvalidMappingID;
+
/// Cost of this mapping.
- unsigned Cost;
+ unsigned Cost = 0;
+
/// Mapping of all the operands.
const ValueMapping *OperandsMapping;
+
/// Number of operands.
- unsigned NumOperands;
+ unsigned NumOperands = 0;
const ValueMapping &getOperandMapping(unsigned i) {
assert(i < getNumOperands() && "Out of bound operand");
@@ -213,7 +219,7 @@ public:
/// Default constructor.
/// Use this constructor to express that the mapping is invalid.
- InstructionMapping() : ID(InvalidMappingID), Cost(0), NumOperands(0) {}
+ InstructionMapping() = default;
/// Get the cost.
unsigned getCost() const { return Cost; }
@@ -264,7 +270,7 @@ public:
/// Convenient type to represent the alternatives for mapping an
/// instruction.
/// \todo When we move to TableGen this should be an array ref.
- typedef SmallVector<InstructionMapping, 4> InstructionMappings;
+ using InstructionMappings = SmallVector<const InstructionMapping *, 4>;
/// Helper class used to get/create the virtual registers that will be used
/// to replace the MachineOperand when applying a mapping.
@@ -273,12 +279,16 @@ public:
/// OpIdx-th operand starts. -1 means we do not have such mapping yet.
/// Note: We use a SmallVector to avoid heap allocation for most cases.
SmallVector<int, 8> OpToNewVRegIdx;
+
/// Hold the registers that will be used to map MI with InstrMapping.
SmallVector<unsigned, 8> NewVRegs;
+
/// Current MachineRegisterInfo, used to create new virtual registers.
MachineRegisterInfo &MRI;
+
/// Instruction being remapped.
MachineInstr &MI;
+
/// New mapping of the instruction.
const InstructionMapping &InstrMapping;
@@ -310,19 +320,25 @@ public:
OperandsMapper(MachineInstr &MI, const InstructionMapping &InstrMapping,
MachineRegisterInfo &MRI);
- /// Getters.
+ /// \name Getters.
/// @{
/// The MachineInstr being remapped.
MachineInstr &getMI() const { return MI; }
/// The final mapping of the instruction.
const InstructionMapping &getInstrMapping() const { return InstrMapping; }
+
+ /// The MachineRegisterInfo we used to realize the mapping.
+ MachineRegisterInfo &getMRI() const { return MRI; }
/// @}
/// Create as many new virtual registers as needed for the mapping of the \p
/// OpIdx-th operand.
/// The number of registers is determined by the number of breakdown for the
/// related operand in the instruction mapping.
+ /// The type of the new registers is a plain scalar of the right size.
+ /// The proper type is expected to be set when the mapping is applied to
+ /// the instruction(s) that realizes the mapping.
///
/// \pre getMI().getOperand(OpIdx).isReg()
///
@@ -367,22 +383,31 @@ public:
protected:
/// Hold the set of supported register banks.
RegisterBank **RegBanks;
+
/// Total number of register banks.
unsigned NumRegBanks;
/// Keep dynamically allocated PartialMapping in a separate map.
/// This shouldn't be needed when everything gets TableGen'ed.
- mutable DenseMap<unsigned, const PartialMapping *> MapOfPartialMappings;
+ mutable DenseMap<unsigned, std::unique_ptr<const PartialMapping>>
+ MapOfPartialMappings;
/// Keep dynamically allocated ValueMapping in a separate map.
/// This shouldn't be needed when everything gets TableGen'ed.
- mutable DenseMap<unsigned, const ValueMapping *> MapOfValueMappings;
+ mutable DenseMap<unsigned, std::unique_ptr<const ValueMapping>>
+ MapOfValueMappings;
/// Keep dynamically allocated array of ValueMapping in a separate map.
/// This shouldn't be needed when everything gets TableGen'ed.
- mutable DenseMap<unsigned, ValueMapping *> MapOfOperandsMappings;
+ mutable DenseMap<unsigned, std::unique_ptr<ValueMapping[]>>
+ MapOfOperandsMappings;
- /// Create a RegisterBankInfo that can accomodate up to \p NumRegBanks
+ /// Keep dynamically allocated InstructionMapping in a separate map.
+ /// This shouldn't be needed when everything gets TableGen'ed.
+ mutable DenseMap<unsigned, std::unique_ptr<const InstructionMapping>>
+ MapOfInstructionMappings;
+
+ /// Create a RegisterBankInfo that can accommodate up to \p NumRegBanks
/// RegisterBank instances.
RegisterBankInfo(RegisterBank **RegBanks, unsigned NumRegBanks);
@@ -419,14 +444,14 @@ protected:
/// register, a register class, or a register bank.
/// In other words, this method will likely fail to find a mapping for
/// any generic opcode that has not been lowered by target specific code.
- InstructionMapping getInstrMappingImpl(const MachineInstr &MI) const;
+ const InstructionMapping &getInstrMappingImpl(const MachineInstr &MI) const;
/// Get the uniquely generated PartialMapping for the
/// given arguments.
const PartialMapping &getPartialMapping(unsigned StartIdx, unsigned Length,
const RegisterBank &RegBank) const;
- /// Methods to get a uniquely generated ValueMapping.
+ /// \name Methods to get a uniquely generated ValueMapping.
/// @{
/// The most common ValueMapping consists of a single PartialMapping.
@@ -439,7 +464,7 @@ protected:
unsigned NumBreakDowns) const;
/// @}
- /// Methods to get a uniquely generated array of ValueMapping.
+ /// \name Methods to get a uniquely generated array of ValueMapping.
/// @{
/// Get the uniquely generated array of ValueMapping for the
@@ -472,6 +497,33 @@ protected:
std::initializer_list<const ValueMapping *> OpdsMapping) const;
/// @}
+ /// \name Methods to get a uniquely generated InstructionMapping.
+ /// @{
+
+private:
+ /// Method to get a uniquely generated InstructionMapping.
+ const InstructionMapping &
+ getInstructionMappingImpl(bool IsInvalid, unsigned ID = InvalidMappingID,
+ unsigned Cost = 0,
+ const ValueMapping *OperandsMapping = nullptr,
+ unsigned NumOperands = 0) const;
+
+public:
+ /// Method to get a uniquely generated InstructionMapping.
+ const InstructionMapping &
+ getInstructionMapping(unsigned ID, unsigned Cost,
+ const ValueMapping *OperandsMapping,
+ unsigned NumOperands) const {
+ return getInstructionMappingImpl(/*IsInvalid*/ false, ID, Cost,
+ OperandsMapping, NumOperands);
+ }
+
+ /// Method to get a uniquely generated invalid InstructionMapping.
+ const InstructionMapping &getInvalidInstructionMapping() const {
+ return getInstructionMappingImpl(/*IsInvalid*/ true);
+ }
+ /// @}
+
/// Get the register bank for the \p OpIdx-th operand of \p MI form
/// the encoding constraints, if any.
///
@@ -487,6 +539,12 @@ protected:
/// Basically, that means that \p OpdMapper.getMI() is left untouched
/// aside from the reassignment of the register operand that have been
/// remapped.
+ ///
+ /// The type of all the new registers that have been created by the
+ /// mapper are properly remapped to the type of the original registers
+ /// they replace. In other words, the semantic of the instruction does
+ /// not change, only the register banks.
+ ///
/// If the mapping of one of the operand spans several registers, this
/// method will abort as this is not like a default mapping anymore.
///
@@ -500,7 +558,7 @@ protected:
}
public:
- virtual ~RegisterBankInfo();
+ virtual ~RegisterBankInfo() = default;
/// Get the register bank identified by \p ID.
const RegisterBank &getRegBank(unsigned ID) const {
@@ -591,7 +649,8 @@ public:
///
/// \note If returnedVal does not verify MI, this would probably mean
/// that the target does not support that instruction.
- virtual InstructionMapping getInstrMapping(const MachineInstr &MI) const;
+ virtual const InstructionMapping &
+ getInstrMapping(const MachineInstr &MI) const;
/// Get the alternative mappings for \p MI.
/// Alternative in the sense different from getInstrMapping.
@@ -681,6 +740,7 @@ operator<<(raw_ostream &OS, const RegisterBankInfo::OperandsMapper &OpdMapper) {
/// Hashing function for PartialMapping.
/// It is required for the hashing of ValueMapping.
hash_code hash_value(const RegisterBankInfo::PartialMapping &PartMapping);
-} // End namespace llvm.
-#endif
+} // end namespace llvm
+
+#endif // LLVM_CODEGEN_GLOBALISEL_REGISTERBANKINFO_H
diff --git a/contrib/llvm/include/llvm/CodeGen/GlobalISel/Types.h b/contrib/llvm/include/llvm/CodeGen/GlobalISel/Types.h
index 7d97487..7b22e34 100644
--- a/contrib/llvm/include/llvm/CodeGen/GlobalISel/Types.h
+++ b/contrib/llvm/include/llvm/CodeGen/GlobalISel/Types.h
@@ -1,4 +1,4 @@
-//===-- llvm/CodeGen/GlobalISel/Types.h - Types used by GISel ----*- C++ -*-===//
+//===- llvm/CodeGen/GlobalISel/Types.h - Types used by GISel ----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -16,17 +16,19 @@
#define LLVM_CODEGEN_GLOBALISEL_TYPES_H
#include "llvm/ADT/DenseMap.h"
-#include "llvm/IR/Value.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.
-typedef DenseMap<const Value *, unsigned> ValueToVReg;
+using ValueToVReg = DenseMap<const Value *, unsigned>;
+
+} // end namespace llvm
-} // End namespace llvm.
-#endif
+#endif // LLVM_CODEGEN_GLOBALISEL_TYPES_H
diff --git a/contrib/llvm/include/llvm/CodeGen/GlobalISel/Utils.h b/contrib/llvm/include/llvm/CodeGen/GlobalISel/Utils.h
index f5d5f5c..50ddbeb 100644
--- a/contrib/llvm/include/llvm/CodeGen/GlobalISel/Utils.h
+++ b/contrib/llvm/include/llvm/CodeGen/GlobalISel/Utils.h
@@ -15,20 +15,40 @@
#ifndef LLVM_CODEGEN_GLOBALISEL_UTILS_H
#define LLVM_CODEGEN_GLOBALISEL_UTILS_H
+#include "llvm/ADT/StringRef.h"
+
namespace llvm {
class MachineFunction;
class MachineInstr;
+class MachineOptimizationRemarkEmitter;
+class MachineOptimizationRemarkMissed;
class MachineRegisterInfo;
class MCInstrDesc;
class RegisterBankInfo;
class TargetInstrInfo;
+class TargetPassConfig;
class TargetRegisterInfo;
+class TargetRegisterClass;
+class Twine;
+class ConstantFP;
+
+/// Try to constrain Reg to the specified register class. If this fails,
+/// create a new virtual register in the correct class and insert a COPY before
+/// \p InsertPt. The debug location of \p InsertPt is used for the new copy.
+///
+/// \return The virtual register constrained to the right register class.
+unsigned constrainRegToClass(MachineRegisterInfo &MRI,
+ const TargetInstrInfo &TII,
+ const RegisterBankInfo &RBI,
+ MachineInstr &InsertPt, unsigned Reg,
+ const TargetRegisterClass &RegClass);
/// 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
/// register in the correct class and insert a COPY before \p InsertPt.
-/// The debug location of \p InsertPt is used for the new copy.
+/// This is equivalent to constrainRegToClass() with RegClass obtained from the
+/// MCInstrDesc. 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,
@@ -39,5 +59,25 @@ unsigned constrainOperandRegClass(const MachineFunction &MF,
MachineInstr &InsertPt, const MCInstrDesc &II,
unsigned Reg, unsigned OpIdx);
+/// 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);
+
+/// Report an ISel error as a missed optimization remark to the LLVMContext's
+/// diagnostic stream. Set the FailedISel MachineFunction property.
+void reportGISelFailure(MachineFunction &MF, const TargetPassConfig &TPC,
+ MachineOptimizationRemarkEmitter &MORE,
+ MachineOptimizationRemarkMissed &R);
+
+void reportGISelFailure(MachineFunction &MF, const TargetPassConfig &TPC,
+ MachineOptimizationRemarkEmitter &MORE,
+ const char *PassName, StringRef Msg,
+ const MachineInstr &MI);
+
+Optional<int64_t> getConstantVRegVal(unsigned VReg,
+ const MachineRegisterInfo &MRI);
+const ConstantFP* getConstantFPVRegVal(unsigned VReg,
+ const MachineRegisterInfo &MRI);
+
} // End namespace llvm.
#endif
diff --git a/contrib/llvm/include/llvm/CodeGen/ISDOpcodes.h b/contrib/llvm/include/llvm/CodeGen/ISDOpcodes.h
index df700bf..bc5d235 100644
--- a/contrib/llvm/include/llvm/CodeGen/ISDOpcodes.h
+++ b/contrib/llvm/include/llvm/CodeGen/ISDOpcodes.h
@@ -216,6 +216,9 @@ namespace ISD {
/// 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
@@ -227,6 +230,16 @@ namespace ISD {
/// 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
@@ -245,6 +258,20 @@ namespace ISD {
/// 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,
+
+ /// 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,
+
/// FMA - Perform a * b + c with no intermediate rounding step.
FMA,
@@ -281,7 +308,8 @@ namespace ISD {
/// 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.
+ /// 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
@@ -332,6 +360,12 @@ namespace ISD {
/// 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
@@ -376,12 +410,22 @@ namespace ISD {
/// 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
+ /// Like SetCC, ops #0 and #1 are the LHS and RHS operands to compare, and
/// op #2 is a *carry value*. This operator checks the result of
/// "LHS - RHS - Carry", and can be used to compare two wide integers:
/// (setcce lhshi rhshi (subc lhslo rhslo) cc). Only valid for integers.
+ /// FIXME: This node is deprecated in favor of SETCCCARRY.
+ /// It is kept around for now to provide a smooth transition path
+ /// toward the use of SETCCCARRY and will eventually be removed.
SETCCE,
+ /// 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: (setcce lhshi rhshi (subc 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
@@ -618,6 +662,13 @@ namespace ISD {
/// 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
@@ -757,6 +808,20 @@ namespace ISD {
/// 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,
+ VECREDUCE_ADD, VECREDUCE_MUL,
+ VECREDUCE_AND, VECREDUCE_OR, VECREDUCE_XOR,
+ VECREDUCE_SMAX, VECREDUCE_SMIN, VECREDUCE_UMAX, VECREDUCE_UMIN,
+ /// FMIN/FMAX nodes can have flags, for NaN/NoNaN variants.
+ VECREDUCE_FMAX, VECREDUCE_FMIN,
+
/// 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
@@ -801,10 +866,11 @@ namespace ISD {
PRE_INC,
PRE_DEC,
POST_INC,
- POST_DEC,
- LAST_INDEXED_MODE
+ POST_DEC
};
+ static const int LAST_INDEXED_MODE = POST_DEC + 1;
+
//===--------------------------------------------------------------------===//
/// LoadExtType enum - This enum defines the three variants of LOADEXT
/// (load with extension).
@@ -819,10 +885,11 @@ namespace ISD {
NON_EXTLOAD = 0,
EXTLOAD,
SEXTLOAD,
- ZEXTLOAD,
- LAST_LOADEXT_TYPE
+ ZEXTLOAD
};
+ static const int LAST_LOADEXT_TYPE = ZEXTLOAD + 1;
+
NodeType getExtForLoadExtType(bool IsFP, LoadExtType);
//===--------------------------------------------------------------------===//
diff --git a/contrib/llvm/include/llvm/CodeGen/LazyMachineBlockFrequencyInfo.h b/contrib/llvm/include/llvm/CodeGen/LazyMachineBlockFrequencyInfo.h
new file mode 100644
index 0000000..848ee1d
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/LazyMachineBlockFrequencyInfo.h
@@ -0,0 +1,76 @@
+///===- LazyMachineBlockFrequencyInfo.h - Lazy Block Frequency -*- C++ -*--===//
+///
+/// The LLVM Compiler Infrastructure
+///
+/// This file is distributed under the University of Illinois Open Source
+/// License. See LICENSE.TXT for details.
+///
+///===---------------------------------------------------------------------===//
+/// \file
+/// This is an alternative analysis pass to MachineBlockFrequencyInfo. The
+/// difference is that with this pass the block frequencies are not computed
+/// when the analysis pass is executed but rather when the BFI result is
+/// explicitly requested by the analysis client.
+///
+///===---------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_LAZYMACHINEBLOCKFREQUENCYINFO_H
+#define LLVM_ANALYSIS_LAZYMACHINEBLOCKFREQUENCYINFO_H
+
+#include "llvm/CodeGen/MachineBlockFrequencyInfo.h"
+#include "llvm/CodeGen/MachineBranchProbabilityInfo.h"
+#include "llvm/CodeGen/MachineDominators.h"
+#include "llvm/CodeGen/MachineLoopInfo.h"
+
+namespace llvm {
+/// \brief This is an alternative analysis pass to MachineBlockFrequencyInfo.
+/// The difference is that with this pass, the block frequencies are not
+/// computed when the analysis pass is executed but rather when the BFI result
+/// is explicitly requested by the analysis client.
+///
+/// This works by checking querying if MBFI is available and otherwise
+/// generating MBFI on the fly. In this case the passes required for (LI, DT)
+/// are also queried before being computed on the fly.
+///
+/// Note that it is expected that we wouldn't need this functionality for the
+/// new PM since with the new PM, analyses are executed on demand.
+
+class LazyMachineBlockFrequencyInfoPass : public MachineFunctionPass {
+private:
+ /// If generated on the fly this own the instance.
+ mutable std::unique_ptr<MachineBlockFrequencyInfo> OwnedMBFI;
+
+ /// If generated on the fly this own the instance.
+ mutable std::unique_ptr<MachineLoopInfo> OwnedMLI;
+
+ /// If generated on the fly this own the instance.
+ mutable std::unique_ptr<MachineDominatorTree> OwnedMDT;
+
+ /// The function.
+ MachineFunction *MF = nullptr;
+
+ /// \brief Calculate MBFI and all other analyses that's not available and
+ /// required by BFI.
+ MachineBlockFrequencyInfo &calculateIfNotAvailable() const;
+
+public:
+ static char ID;
+
+ LazyMachineBlockFrequencyInfoPass();
+
+ /// \brief Compute and return the block frequencies.
+ MachineBlockFrequencyInfo &getBFI() { return calculateIfNotAvailable(); }
+
+ /// \brief Compute and return the block frequencies.
+ const MachineBlockFrequencyInfo &getBFI() const {
+ return calculateIfNotAvailable();
+ }
+
+ void getAnalysisUsage(AnalysisUsage &AU) const override;
+
+ bool runOnMachineFunction(MachineFunction &F) override;
+ void releaseMemory() override;
+ void print(raw_ostream &OS, const Module *M) const override;
+};
+}
+#endif
diff --git a/contrib/llvm/include/llvm/CodeGen/LexicalScopes.h b/contrib/llvm/include/llvm/CodeGen/LexicalScopes.h
index 7d7e48a..3ba5034 100644
--- a/contrib/llvm/include/llvm/CodeGen/LexicalScopes.h
+++ b/contrib/llvm/include/llvm/CodeGen/LexicalScopes.h
@@ -1,4 +1,4 @@
-//===- LexicalScopes.cpp - Collecting lexical scope info -*- C++ -*--------===//
+//===- LexicalScopes.cpp - Collecting lexical scope info --------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -19,37 +19,39 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/IR/DebugLoc.h"
#include "llvm/IR/DebugInfoMetadata.h"
-#include "llvm/IR/ValueHandle.h"
+#include <cassert>
#include <unordered_map>
#include <utility>
+
namespace llvm {
-class MachineInstr;
class MachineBasicBlock;
class MachineFunction;
+class MachineInstr;
+class MDNode;
//===----------------------------------------------------------------------===//
/// InsnRange - This is used to track range of instructions with identical
/// lexical scope.
///
-typedef std::pair<const MachineInstr *, const MachineInstr *> InsnRange;
+using InsnRange = std::pair<const MachineInstr *, const MachineInstr *>;
//===----------------------------------------------------------------------===//
/// LexicalScope - This class is used to track scope information.
///
class LexicalScope {
-
public:
LexicalScope(LexicalScope *P, const DILocalScope *D, const DILocation *I,
bool A)
- : Parent(P), Desc(D), InlinedAtLocation(I), AbstractScope(A),
- LastInsn(nullptr), FirstInsn(nullptr), DFSIn(0), DFSOut(0) {
- assert((!D || D->isResolved()) && "Expected resolved node");
+ : Parent(P), Desc(D), InlinedAtLocation(I), AbstractScope(A) {
+ assert(D);
+ assert(D->getSubprogram()->getUnit()->getEmissionKind() !=
+ DICompileUnit::NoDebug &&
+ "Don't build lexical scopes for non-debug locations");
+ assert(D->isResolved() && "Expected resolved node");
assert((!I || I->isResolved()) && "Expected resolved node");
if (Parent)
Parent->addChild(this);
@@ -127,10 +129,10 @@ private:
// Contents not owned.
SmallVector<InsnRange, 4> Ranges;
- const MachineInstr *LastInsn; // Last instruction of this scope.
- const MachineInstr *FirstInsn; // First instruction of this scope.
- unsigned DFSIn, DFSOut; // In & Out Depth use to determine
- // scope nesting.
+ const MachineInstr *LastInsn = nullptr; // Last instruction of this scope.
+ const MachineInstr *FirstInsn = nullptr; // First instruction of this scope.
+ unsigned DFSIn = 0; // In & Out Depth use to determine scope nesting.
+ unsigned DFSOut = 0;
};
//===----------------------------------------------------------------------===//
@@ -139,7 +141,7 @@ private:
///
class LexicalScopes {
public:
- LexicalScopes() : MF(nullptr), CurrentFnLexicalScope(nullptr) {}
+ LexicalScopes() = default;
/// initialize - Scan machine function and constuct lexical scope nest, resets
/// the instance if necessary.
@@ -194,7 +196,7 @@ public:
}
/// dump - Print data structures to dbgs().
- void dump();
+ void dump() const;
/// getOrCreateAbstractScope - Find or create an abstract lexical scope.
LexicalScope *getOrCreateAbstractScope(const DILocalScope *Scope);
@@ -225,8 +227,7 @@ private:
assignInstructionRanges(SmallVectorImpl<InsnRange> &MIRanges,
DenseMap<const MachineInstr *, LexicalScope *> &M);
-private:
- const MachineFunction *MF;
+ const MachineFunction *MF = nullptr;
/// LexicalScopeMap - Tracks the scopes in the current function.
// Use an unordered_map to ensure value pointer validity over insertion.
@@ -249,9 +250,9 @@ private:
/// CurrentFnLexicalScope - Top level scope for the current function.
///
- LexicalScope *CurrentFnLexicalScope;
+ LexicalScope *CurrentFnLexicalScope = nullptr;
};
-} // end llvm namespace
+} // end namespace llvm
-#endif
+#endif // LLVM_CODEGEN_LEXICALSCOPES_H
diff --git a/contrib/llvm/include/llvm/CodeGen/LiveInterval.h b/contrib/llvm/include/llvm/CodeGen/LiveInterval.h
index a867062..f4fa872 100644
--- a/contrib/llvm/include/llvm/CodeGen/LiveInterval.h
+++ b/contrib/llvm/include/llvm/CodeGen/LiveInterval.h
@@ -1,4 +1,4 @@
-//===-- llvm/CodeGen/LiveInterval.h - Interval representation ---*- C++ -*-===//
+//===- llvm/CodeGen/LiveInterval.h - Interval representation ----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -21,22 +21,30 @@
#ifndef LLVM_CODEGEN_LIVEINTERVAL_H
#define LLVM_CODEGEN_LIVEINTERVAL_H
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/IntEqClasses.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/iterator_range.h"
#include "llvm/CodeGen/SlotIndexes.h"
+#include "llvm/MC/LaneBitmask.h"
#include "llvm/Support/Allocator.h"
-#include "llvm/Target/TargetRegisterInfo.h"
+#include "llvm/Support/MathExtras.h"
+#include <algorithm>
#include <cassert>
-#include <climits>
+#include <cstddef>
+#include <functional>
+#include <memory>
#include <set>
+#include <tuple>
+#include <utility>
namespace llvm {
+
class CoalescerPair;
class LiveIntervals;
- class MachineInstr;
class MachineRegisterInfo;
- class TargetRegisterInfo;
class raw_ostream;
- template <typename T, unsigned Small> class SmallPtrSet;
/// VNInfo - Value Number Information.
/// This class holds information about a machine level values, including
@@ -44,7 +52,7 @@ namespace llvm {
///
class VNInfo {
public:
- typedef BumpPtrAllocator Allocator;
+ using Allocator = BumpPtrAllocator;
/// The ID number of this value.
unsigned id;
@@ -53,14 +61,10 @@ namespace llvm {
SlotIndex def;
/// VNInfo constructor.
- VNInfo(unsigned i, SlotIndex d)
- : id(i), def(d)
- { }
+ VNInfo(unsigned i, SlotIndex d) : id(i), def(d) {}
/// VNInfo constructor, copies values from orig, except for the value number.
- VNInfo(unsigned i, const VNInfo &orig)
- : id(i), def(orig.def)
- { }
+ VNInfo(unsigned i, const VNInfo &orig) : id(i), def(orig.def) {}
/// Copy from the parameter into this VNInfo.
void copyFrom(VNInfo &src) {
@@ -152,16 +156,16 @@ namespace llvm {
/// segment with a new value number is used.
class LiveRange {
public:
-
/// This represents a simple continuous liveness interval for a value.
/// The start point is inclusive, the end point exclusive. These intervals
/// are rendered as [start,end).
struct Segment {
SlotIndex start; // Start point of the interval (inclusive)
SlotIndex end; // End point of the interval (exclusive)
- VNInfo *valno; // identifier for the value contained in this segment.
+ VNInfo *valno = nullptr; // identifier for the value contained in this
+ // segment.
- Segment() : valno(nullptr) {}
+ Segment() = default;
Segment(SlotIndex S, SlotIndex E, VNInfo *V)
: start(S), end(E), valno(V) {
@@ -189,8 +193,8 @@ namespace llvm {
void dump() const;
};
- typedef SmallVector<Segment, 2> Segments;
- typedef SmallVector<VNInfo *, 2> VNInfoList;
+ using Segments = SmallVector<Segment, 2>;
+ using VNInfoList = SmallVector<VNInfo *, 2>;
Segments segments; // the liveness segments
VNInfoList valnos; // value#'s
@@ -198,22 +202,24 @@ namespace llvm {
// The segment set is used temporarily to accelerate initial computation
// of live ranges of physical registers in computeRegUnitRange.
// After that the set is flushed to the segment vector and deleted.
- typedef std::set<Segment> SegmentSet;
+ using SegmentSet = std::set<Segment>;
std::unique_ptr<SegmentSet> segmentSet;
- typedef Segments::iterator iterator;
+ using iterator = Segments::iterator;
+ using const_iterator = Segments::const_iterator;
+
iterator begin() { return segments.begin(); }
iterator end() { return segments.end(); }
- typedef Segments::const_iterator const_iterator;
const_iterator begin() const { return segments.begin(); }
const_iterator end() const { return segments.end(); }
- typedef VNInfoList::iterator vni_iterator;
+ using vni_iterator = VNInfoList::iterator;
+ using const_vni_iterator = VNInfoList::const_iterator;
+
vni_iterator vni_begin() { return valnos.begin(); }
vni_iterator vni_end() { return valnos.end(); }
- typedef VNInfoList::const_iterator const_vni_iterator;
const_vni_iterator vni_begin() const { return valnos.begin(); }
const_vni_iterator vni_end() const { return valnos.end(); }
@@ -227,15 +233,22 @@ namespace llvm {
LiveRange(const LiveRange &Other, BumpPtrAllocator &Allocator) {
assert(Other.segmentSet == nullptr &&
"Copying of LiveRanges with active SegmentSets is not supported");
+ assign(Other, Allocator);
+ }
+ /// Copies values numbers and live segments from \p Other into this range.
+ void assign(const LiveRange &Other, BumpPtrAllocator &Allocator) {
+ if (this == &Other)
+ return;
+
+ assert(Other.segmentSet == nullptr &&
+ "Copying of LiveRanges with active SegmentSets is not supported");
// Duplicate valnos.
- for (const VNInfo *VNI : Other.valnos) {
+ for (const VNInfo *VNI : Other.valnos)
createValueCopy(VNI, Allocator);
- }
// Now we can copy segments and remap their valnos.
- for (const Segment &S : Other.segments) {
+ for (const Segment &S : Other.segments)
segments.push_back(Segment(S.start, S.end, valnos[S.valno->id]));
- }
}
/// advanceTo - Advance the specified iterator to point to the Segment
@@ -624,40 +637,37 @@ namespace llvm {
/// or stack slot.
class LiveInterval : public LiveRange {
public:
- typedef LiveRange super;
+ using super = LiveRange;
/// A live range for subregisters. The LaneMask specifies which parts of the
/// super register are covered by the interval.
/// (@sa TargetRegisterInfo::getSubRegIndexLaneMask()).
class SubRange : public LiveRange {
public:
- SubRange *Next;
+ SubRange *Next = nullptr;
LaneBitmask LaneMask;
/// Constructs a new SubRange object.
- SubRange(LaneBitmask LaneMask)
- : Next(nullptr), LaneMask(LaneMask) {
- }
+ SubRange(LaneBitmask LaneMask) : LaneMask(LaneMask) {}
/// Constructs a new SubRange object by copying liveness from @p Other.
SubRange(LaneBitmask LaneMask, const LiveRange &Other,
BumpPtrAllocator &Allocator)
- : LiveRange(Other, Allocator), Next(nullptr), LaneMask(LaneMask) {
- }
+ : LiveRange(Other, Allocator), LaneMask(LaneMask) {}
void print(raw_ostream &OS) const;
void dump() const;
};
private:
- SubRange *SubRanges; ///< Single linked list of subregister live ranges.
+ SubRange *SubRanges = nullptr; ///< Single linked list of subregister live
+ /// ranges.
public:
const unsigned reg; // the register or stack slot of this interval.
float weight; // weight of this interval
- LiveInterval(unsigned Reg, float Weight)
- : SubRanges(nullptr), reg(Reg), weight(Weight) {}
+ LiveInterval(unsigned Reg, float Weight) : reg(Reg), weight(Weight) {}
~LiveInterval() {
clearSubRanges();
@@ -666,8 +676,10 @@ namespace llvm {
template<typename T>
class SingleLinkedListIterator {
T *P;
+
public:
SingleLinkedListIterator<T>(T *P) : P(P) {}
+
SingleLinkedListIterator<T> &operator++() {
P = P->Next;
return *this;
@@ -691,7 +703,9 @@ namespace llvm {
}
};
- typedef SingleLinkedListIterator<SubRange> subrange_iterator;
+ using subrange_iterator = SingleLinkedListIterator<SubRange>;
+ using const_subrange_iterator = SingleLinkedListIterator<const SubRange>;
+
subrange_iterator subrange_begin() {
return subrange_iterator(SubRanges);
}
@@ -699,7 +713,6 @@ namespace llvm {
return subrange_iterator(nullptr);
}
- typedef SingleLinkedListIterator<const SubRange> const_subrange_iterator;
const_subrange_iterator subrange_begin() const {
return const_subrange_iterator(SubRanges);
}
@@ -752,12 +765,12 @@ namespace llvm {
/// isSpillable - Can this interval be spilled?
bool isSpillable() const {
- return weight != llvm::huge_valf;
+ return weight != huge_valf;
}
/// markNotSpillable - Mark interval as not spillable
void markNotSpillable() {
- weight = llvm::huge_valf;
+ weight = huge_valf;
}
/// For a given lane mask @p LaneMask, compute indexes at which the
@@ -767,6 +780,19 @@ namespace llvm {
const MachineRegisterInfo &MRI,
const SlotIndexes &Indexes) const;
+ /// Refines the subranges to support \p LaneMask. This may only be called
+ /// for LI.hasSubrange()==true. Subregister ranges are split or created
+ /// until \p LaneMask can be matched exactly. \p Mod is executed on the
+ /// matching subranges.
+ ///
+ /// Example:
+ /// Given an interval with subranges with lanemasks L0F00, L00F0 and
+ /// L000F, refining for mask L0018. Will split the L00F0 lane into
+ /// L00E0 and L0010 and the L000F lane into L0007 and L0008. The Mod
+ /// function will be applied to the L0010 and L0008 subranges.
+ void refineSubRanges(BumpPtrAllocator &Allocator, LaneBitmask LaneMask,
+ std::function<void(LiveInterval::SubRange&)> Mod);
+
bool operator<(const LiveInterval& other) const {
const SlotIndex &thisIndex = beginIndex();
const SlotIndex &otherIndex = other.beginIndex();
@@ -911,5 +937,7 @@ namespace llvm {
void Distribute(LiveInterval &LI, LiveInterval *LIV[],
MachineRegisterInfo &MRI);
};
-}
-#endif
+
+} // end namespace llvm
+
+#endif // LLVM_CODEGEN_LIVEINTERVAL_H
diff --git a/contrib/llvm/include/llvm/CodeGen/LiveIntervalAnalysis.h b/contrib/llvm/include/llvm/CodeGen/LiveIntervalAnalysis.h
index f8dc525..820e883 100644
--- a/contrib/llvm/include/llvm/CodeGen/LiveIntervalAnalysis.h
+++ b/contrib/llvm/include/llvm/CodeGen/LiveIntervalAnalysis.h
@@ -1,4 +1,4 @@
-//===-- LiveIntervalAnalysis.h - Live Interval Analysis ---------*- C++ -*-===//
+//===- LiveIntervalAnalysis.h - Live Interval Analysis ----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,19 +7,20 @@
//
//===----------------------------------------------------------------------===//
//
-// This file implements the LiveInterval analysis pass. Given some numbering of
-// each the machine instructions (in this implemention depth-first order) an
-// interval [i, j) is said to be a live interval for register v if there is no
-// instruction with number j' > j such that v is live at j' and there is no
-// instruction with number i' < i such that v is live at i'. In this
-// implementation intervals can have holes, i.e. an interval might look like
-// [1,20), [50,65), [1000,1001).
+/// \file This file implements the LiveInterval analysis pass. Given some
+/// numbering of each the machine instructions (in this implemention depth-first
+/// order) an interval [i, j) is said to be a live interval for register v if
+/// there is no instruction with number j' > j such that v is live at j' and
+/// there is no instruction with number i' < i such that v is live at i'. In
+/// this implementation intervals can have holes, i.e. an interval might look
+/// like [1,20), [50,65), [1000,1001).
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CODEGEN_LIVEINTERVALANALYSIS_H
#define LLVM_CODEGEN_LIVEINTERVALANALYSIS_H
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/IndexedMap.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Analysis/AliasAnalysis.h"
@@ -27,27 +28,29 @@
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/SlotIndexes.h"
-#include "llvm/Support/Allocator.h"
+#include "llvm/MC/LaneBitmask.h"
#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/ErrorHandling.h"
#include "llvm/Target/TargetRegisterInfo.h"
-#include <cmath>
+#include <cassert>
+#include <cstdint>
+#include <utility>
namespace llvm {
extern cl::opt<bool> UseSegmentSetForPhysRegs;
- class BitVector;
- class BlockFrequency;
- class LiveRangeCalc;
- class LiveVariables;
- class MachineDominatorTree;
- class MachineLoopInfo;
- class TargetRegisterInfo;
- class MachineRegisterInfo;
- class TargetInstrInfo;
- class TargetRegisterClass;
- class VirtRegMap;
- class MachineBlockFrequencyInfo;
+class BitVector;
+class LiveRangeCalc;
+class MachineBlockFrequencyInfo;
+class MachineDominatorTree;
+class MachineFunction;
+class MachineInstr;
+class MachineRegisterInfo;
+class raw_ostream;
+class TargetInstrInfo;
+class VirtRegMap;
class LiveIntervals : public MachineFunctionPass {
MachineFunction* MF;
@@ -56,24 +59,21 @@ extern cl::opt<bool> UseSegmentSetForPhysRegs;
const TargetInstrInfo* TII;
AliasAnalysis *AA;
SlotIndexes* Indexes;
- MachineDominatorTree *DomTree;
- LiveRangeCalc *LRCalc;
+ MachineDominatorTree *DomTree = nullptr;
+ LiveRangeCalc *LRCalc = nullptr;
/// Special pool allocator for VNInfo's (LiveInterval val#).
- ///
VNInfo::Allocator VNInfoAllocator;
/// Live interval pointers for all the virtual registers.
IndexedMap<LiveInterval*, VirtReg2IndexFunctor> VirtRegIntervals;
- /// RegMaskSlots - Sorted list of instructions with register mask operands.
- /// Always use the 'r' slot, RegMasks are normal clobbers, not early
- /// clobbers.
+ /// Sorted list of instructions with register mask operands. Always use the
+ /// 'r' slot, RegMasks are normal clobbers, not early clobbers.
SmallVector<SlotIndex, 8> RegMaskSlots;
- /// RegMaskBits - This vector is parallel to RegMaskSlots, it holds a
- /// pointer to the corresponding register mask. This pointer can be
- /// recomputed as:
+ /// This vector is parallel to RegMaskSlots, it holds a pointer to the
+ /// corresponding register mask. This pointer can be recomputed as:
///
/// MI = Indexes->getInstructionFromIndex(RegMaskSlot[N]);
/// unsigned OpNum = findRegMaskOperand(MI);
@@ -97,11 +97,12 @@ extern cl::opt<bool> UseSegmentSetForPhysRegs;
SmallVector<LiveRange*, 0> RegUnitRanges;
public:
- static char ID; // Pass identification, replacement for typeid
+ static char ID;
+
LiveIntervals();
~LiveIntervals() override;
- // Calculate the spill weight to assign to a single instruction.
+ /// Calculate the spill weight to assign to a single instruction.
static float getSpillWeight(bool isDef, bool isUse,
const MachineBlockFrequencyInfo *MBFI,
const MachineInstr &Instr);
@@ -121,7 +122,7 @@ extern cl::opt<bool> UseSegmentSetForPhysRegs;
return VirtRegIntervals.inBounds(Reg) && VirtRegIntervals[Reg];
}
- // Interval creation.
+ /// Interval creation.
LiveInterval &createEmptyInterval(unsigned Reg) {
assert(!hasInterval(Reg) && "Interval already exists!");
VirtRegIntervals.grow(Reg);
@@ -135,7 +136,7 @@ extern cl::opt<bool> UseSegmentSetForPhysRegs;
return LI;
}
- // Interval removal.
+ /// Interval removal.
void removeInterval(unsigned Reg) {
delete VirtRegIntervals[Reg];
VirtRegIntervals[Reg] = nullptr;
@@ -163,16 +164,16 @@ extern cl::opt<bool> UseSegmentSetForPhysRegs;
/// LiveInterval::removeEmptySubranges() afterwards.
void shrinkToUses(LiveInterval::SubRange &SR, unsigned Reg);
- /// Extend the live range @p LR to reach all points in @p Indices. The
- /// points in the @p Indices array must be jointly dominated by the union
- /// of the existing defs in @p LR and points in @p Undefs.
+ /// Extend the live range \p LR to reach all points in \p Indices. The
+ /// points in the \p Indices array must be jointly dominated by the union
+ /// of the existing defs in \p LR and points in \p Undefs.
///
/// PHI-defs are added as needed to maintain SSA form.
///
- /// If a SlotIndex in @p Indices is the end index of a basic block, @p LR
+ /// If a SlotIndex in \p Indices is the end index of a basic block, \p LR
/// will be extended to be live out of the basic block.
- /// If a SlotIndex in @p Indices is jointy dominated only by points in
- /// @p Undefs, the live range will not be extended to that point.
+ /// If a SlotIndex in \p Indices is jointy dominated only by points in
+ /// \p Undefs, the live range will not be extended to that point.
///
/// See also LiveRangeCalc::extend().
void extendToIndices(LiveRange &LR, ArrayRef<SlotIndex> Indices,
@@ -182,7 +183,7 @@ extern cl::opt<bool> UseSegmentSetForPhysRegs;
extendToIndices(LR, Indices, /*Undefs=*/{});
}
- /// If @p LR has a live value at @p Kill, prune its live range by removing
+ /// If \p LR has a live value at \p Kill, prune its live range by removing
/// any liveness reachable from Kill. Add live range end points to
/// EndPoints such that extendToIndices(LI, EndPoints) will reconstruct the
/// value's live range.
@@ -192,6 +193,16 @@ extern cl::opt<bool> UseSegmentSetForPhysRegs;
void pruneValue(LiveRange &LR, SlotIndex Kill,
SmallVectorImpl<SlotIndex> *EndPoints);
+ /// This function should not be used. Its intend is to tell you that
+ /// you are doing something wrong if you call pruveValue directly on a
+ /// LiveInterval. Indeed, you are supposed to call pruneValue on the main
+ /// LiveRange and all the LiveRange of the subranges if any.
+ LLVM_ATTRIBUTE_UNUSED void pruneValue(LiveInterval &, SlotIndex,
+ SmallVectorImpl<SlotIndex> *) {
+ llvm_unreachable(
+ "Use pruneValue on the main LiveRange and on each subrange");
+ }
+
SlotIndexes *getSlotIndexes() const {
return Indexes;
}
@@ -200,8 +211,8 @@ extern cl::opt<bool> UseSegmentSetForPhysRegs;
return AA;
}
- /// isNotInMIMap - returns true if the specified machine instr has been
- /// removed or was never entered in the map.
+ /// Returns true if the specified machine instr has been removed or was
+ /// never entered in the map.
bool isNotInMIMap(const MachineInstr &Instr) const {
return !Indexes->hasIndex(Instr);
}
@@ -270,35 +281,32 @@ extern cl::opt<bool> UseSegmentSetForPhysRegs;
void getAnalysisUsage(AnalysisUsage &AU) const override;
void releaseMemory() override;
- /// runOnMachineFunction - pass entry point
+ /// Pass entry point; Calculates LiveIntervals.
bool runOnMachineFunction(MachineFunction&) override;
- /// print - Implement the dump method.
+ /// Implement the dump method.
void print(raw_ostream &O, const Module* = nullptr) const override;
- /// intervalIsInOneMBB - If LI is confined to a single basic block, return
- /// a pointer to that block. If LI is live in to or out of any block,
- /// return NULL.
+ /// If LI is confined to a single basic block, return a pointer to that
+ /// block. If LI is live in to or out of any block, return NULL.
MachineBasicBlock *intervalIsInOneMBB(const LiveInterval &LI) const;
/// Returns true if VNI is killed by any PHI-def values in LI.
/// This may conservatively return true to avoid expensive computations.
bool hasPHIKill(const LiveInterval &LI, const VNInfo *VNI) const;
- /// addKillFlags - Add kill flags to any instruction that kills a virtual
- /// register.
+ /// Add kill flags to any instruction that kills a virtual register.
void addKillFlags(const VirtRegMap*);
- /// handleMove - call this method to notify LiveIntervals that
- /// instruction 'mi' has been moved within a basic block. This will update
- /// the live intervals for all operands of mi. Moves between basic blocks
- /// are not supported.
+ /// Call this method to notify LiveIntervals that instruction \p MI has been
+ /// moved within a basic block. This will update the live intervals for all
+ /// operands of \p MI. Moves between basic blocks are not supported.
///
/// \param UpdateFlags Update live intervals for nonallocatable physregs.
void handleMove(MachineInstr &MI, bool UpdateFlags = false);
- /// moveIntoBundle - Update intervals for operands of MI so that they
- /// begin/end on the SlotIndex for BundleStart.
+ /// Update intervals for operands of \p MI so that they begin/end on the
+ /// SlotIndex for \p BundleStart.
///
/// \param UpdateFlags Update live intervals for nonallocatable physregs.
///
@@ -308,10 +316,9 @@ extern cl::opt<bool> UseSegmentSetForPhysRegs;
void handleMoveIntoBundle(MachineInstr &MI, MachineInstr &BundleStart,
bool UpdateFlags = false);
- /// repairIntervalsInRange - Update live intervals for instructions in a
- /// range of iterators. It is intended for use after target hooks that may
- /// insert or remove instructions, and is only efficient for a small number
- /// of instructions.
+ /// Update live intervals for instructions in a range of iterators. It is
+ /// intended for use after target hooks that may insert or remove
+ /// instructions, and is only efficient for a small number of instructions.
///
/// OrigRegs is a vector of registers that were originally used by the
/// instructions in the range between the two iterators.
@@ -334,34 +341,33 @@ extern cl::opt<bool> UseSegmentSetForPhysRegs;
// LiveIntervalAnalysis maintains a sorted list of instructions with
// register mask operands.
- /// getRegMaskSlots - Returns a sorted array of slot indices of all
- /// instructions with register mask operands.
+ /// Returns a sorted array of slot indices of all instructions with
+ /// register mask operands.
ArrayRef<SlotIndex> getRegMaskSlots() const { return RegMaskSlots; }
- /// getRegMaskSlotsInBlock - Returns a sorted array of slot indices of all
- /// instructions with register mask operands in the basic block numbered
- /// MBBNum.
+ /// Returns a sorted array of slot indices of all instructions with register
+ /// mask operands in the basic block numbered \p MBBNum.
ArrayRef<SlotIndex> getRegMaskSlotsInBlock(unsigned MBBNum) const {
std::pair<unsigned, unsigned> P = RegMaskBlocks[MBBNum];
return getRegMaskSlots().slice(P.first, P.second);
}
- /// getRegMaskBits() - Returns an array of register mask pointers
- /// corresponding to getRegMaskSlots().
+ /// Returns an array of register mask pointers corresponding to
+ /// getRegMaskSlots().
ArrayRef<const uint32_t*> getRegMaskBits() const { return RegMaskBits; }
- /// getRegMaskBitsInBlock - Returns an array of mask pointers corresponding
- /// to getRegMaskSlotsInBlock(MBBNum).
+ /// Returns an array of mask pointers corresponding to
+ /// getRegMaskSlotsInBlock(MBBNum).
ArrayRef<const uint32_t*> getRegMaskBitsInBlock(unsigned MBBNum) const {
std::pair<unsigned, unsigned> P = RegMaskBlocks[MBBNum];
return getRegMaskBits().slice(P.first, P.second);
}
- /// checkRegMaskInterference - Test if LI is live across any register mask
- /// instructions, and compute a bit mask of physical registers that are not
- /// clobbered by any of them.
+ /// Test if \p LI is live across any register mask instructions, and
+ /// compute a bit mask of physical registers that are not clobbered by any
+ /// of them.
///
- /// Returns false if LI doesn't cross any register mask instructions. In
+ /// Returns false if \p LI doesn't cross any register mask instructions. In
/// that case, the bit vector is not filled in.
bool checkRegMaskInterference(LiveInterval &LI,
BitVector &UsableRegs);
@@ -377,8 +383,8 @@ extern cl::opt<bool> UseSegmentSetForPhysRegs;
// track liveness per register unit to handle aliasing registers more
// efficiently.
- /// getRegUnit - Return the live range for Unit.
- /// It will be computed if it doesn't exist.
+ /// Return the live range for register unit \p Unit. It will be computed if
+ /// it doesn't exist.
LiveRange &getRegUnit(unsigned Unit) {
LiveRange *LR = RegUnitRanges[Unit];
if (!LR) {
@@ -390,8 +396,8 @@ extern cl::opt<bool> UseSegmentSetForPhysRegs;
return *LR;
}
- /// getCachedRegUnit - Return the live range for Unit if it has already
- /// been computed, or NULL if it hasn't been computed yet.
+ /// Return the live range for register unit \p Unit if it has already been
+ /// computed, or nullptr if it hasn't been computed yet.
LiveRange *getCachedRegUnit(unsigned Unit) {
return RegUnitRanges[Unit];
}
@@ -400,7 +406,7 @@ extern cl::opt<bool> UseSegmentSetForPhysRegs;
return RegUnitRanges[Unit];
}
- /// removeRegUnit - Remove computed live range for Unit. Subsequent uses
+ /// Remove computed live range for register unit \p Unit. Subsequent uses
/// should rely on on-demand recomputation.
void removeRegUnit(unsigned Unit) {
delete RegUnitRanges[Unit];
@@ -408,12 +414,12 @@ extern cl::opt<bool> UseSegmentSetForPhysRegs;
}
/// Remove value numbers and related live segments starting at position
- /// @p Pos that are part of any liverange of physical register @p Reg or one
+ /// \p Pos that are part of any liverange of physical register \p Reg or one
/// of its subregisters.
void removePhysRegDefAt(unsigned Reg, SlotIndex Pos);
- /// Remove value number and related live segments of @p LI and its subranges
- /// that start at position @p Pos.
+ /// Remove value number and related live segments of \p LI and its subranges
+ /// that start at position \p Pos.
void removeVRegDefAt(LiveInterval &LI, SlotIndex Pos);
/// Split separate components in LiveInterval \p LI into separate intervals.
@@ -432,10 +438,10 @@ extern cl::opt<bool> UseSegmentSetForPhysRegs;
/// Compute RegMaskSlots and RegMaskBits.
void computeRegMasks();
- /// Walk the values in @p LI and check for dead values:
+ /// Walk the values in \p LI and check for dead values:
/// - Dead PHIDef values are marked as unused.
/// - Dead operands are marked as such.
- /// - Completely dead machine instructions are added to the @p dead vector
+ /// - Completely dead machine instructions are added to the \p dead vector
/// if it is not nullptr.
/// Returns true if any PHI value numbers have been removed which may
/// have separated the interval into multiple connected components.
@@ -453,8 +459,8 @@ extern cl::opt<bool> UseSegmentSetForPhysRegs;
/// Helper function for repairIntervalsInRange(), walks backwards and
- /// creates/modifies live segments in @p LR to match the operands found.
- /// Only full operands or operands with subregisters matching @p LaneMask
+ /// creates/modifies live segments in \p LR to match the operands found.
+ /// Only full operands or operands with subregisters matching \p LaneMask
/// are considered.
void repairOldRegInRange(MachineBasicBlock::iterator Begin,
MachineBasicBlock::iterator End,
@@ -464,6 +470,7 @@ extern cl::opt<bool> UseSegmentSetForPhysRegs;
class HMEditor;
};
-} // End llvm namespace
-#endif
+} // end namespace llvm
+
+#endif // LLVM_CODEGEN_LIVEINTERVALANALYSIS_H
diff --git a/contrib/llvm/include/llvm/CodeGen/LiveIntervalUnion.h b/contrib/llvm/include/llvm/CodeGen/LiveIntervalUnion.h
index f0f1637..b922e54 100644
--- a/contrib/llvm/include/llvm/CodeGen/LiveIntervalUnion.h
+++ b/contrib/llvm/include/llvm/CodeGen/LiveIntervalUnion.h
@@ -1,4 +1,4 @@
-//===-- LiveIntervalUnion.h - Live interval union data struct --*- C++ -*--===//
+//===- LiveIntervalUnion.h - Live interval union data struct ---*- C++ -*--===//
//
// The LLVM Compiler Infrastructure
//
@@ -18,24 +18,23 @@
#define LLVM_CODEGEN_LIVEINTERVALUNION_H
#include "llvm/ADT/IntervalMap.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/CodeGen/LiveInterval.h"
+#include "llvm/CodeGen/SlotIndexes.h"
+#include <cassert>
+#include <limits>
namespace llvm {
+class raw_ostream;
class TargetRegisterInfo;
#ifndef NDEBUG
// forward declaration
template <unsigned Element> class SparseBitVector;
-typedef SparseBitVector<128> LiveVirtRegBitSet;
-#endif
-/// Compare a live virtual register segment to a LiveIntervalUnion segment.
-inline bool
-overlap(const LiveInterval::Segment &VRSeg,
- const IntervalMap<SlotIndex, LiveInterval*>::const_iterator &LUSeg) {
- return VRSeg.start < LUSeg.stop() && LUSeg.start() < VRSeg.end;
-}
+using LiveVirtRegBitSet = SparseBitVector<128>;
+#endif
/// Union of live intervals that are strong candidates for coalescing into a
/// single register (either physical or virtual depending on the context). We
@@ -45,37 +44,42 @@ class LiveIntervalUnion {
// A set of live virtual register segments that supports fast insertion,
// intersection, and removal.
// Mapping SlotIndex intervals to virtual register numbers.
- typedef IntervalMap<SlotIndex, LiveInterval*> LiveSegments;
+ using LiveSegments = IntervalMap<SlotIndex, LiveInterval*>;
public:
// SegmentIter can advance to the next segment ordered by starting position
// which may belong to a different live virtual register. We also must be able
// to reach the current segment's containing virtual register.
- typedef LiveSegments::iterator SegmentIter;
+ using SegmentIter = LiveSegments::iterator;
- // LiveIntervalUnions share an external allocator.
- typedef LiveSegments::Allocator Allocator;
+ /// Const version of SegmentIter.
+ using ConstSegmentIter = LiveSegments::const_iterator;
- class Query;
+ // LiveIntervalUnions share an external allocator.
+ using Allocator = LiveSegments::Allocator;
private:
- unsigned Tag; // unique tag for current contents.
+ unsigned Tag = 0; // unique tag for current contents.
LiveSegments Segments; // union of virtual reg segments
public:
- explicit LiveIntervalUnion(Allocator &a) : Tag(0), Segments(a) {}
+ explicit LiveIntervalUnion(Allocator &a) : Segments(a) {}
// Iterate over all segments in the union of live virtual registers ordered
// by their starting position.
SegmentIter begin() { return Segments.begin(); }
SegmentIter end() { return Segments.end(); }
SegmentIter find(SlotIndex x) { return Segments.find(x); }
+ ConstSegmentIter begin() const { return Segments.begin(); }
+ ConstSegmentIter end() const { return Segments.end(); }
+ ConstSegmentIter find(SlotIndex x) const { return Segments.find(x); }
+
bool empty() const { return Segments.empty(); }
SlotIndex startIndex() const { return Segments.start(); }
// Provide public access to the underlying map to allow overlap iteration.
- typedef LiveSegments Map;
- const Map &getMap() { return Segments; }
+ using Map = LiveSegments;
+ const Map &getMap() const { return Segments; }
/// getTag - Return an opaque tag representing the current state of the union.
unsigned getTag() const { return Tag; }
@@ -85,15 +89,9 @@ public:
// Add a live virtual register to this union and merge its segments.
void unify(LiveInterval &VirtReg, const LiveRange &Range);
- void unify(LiveInterval &VirtReg) {
- unify(VirtReg, VirtReg);
- }
// Remove a live virtual register's segments from this union.
void extract(LiveInterval &VirtReg, const LiveRange &Range);
- void extract(LiveInterval &VirtReg) {
- extract(VirtReg, VirtReg);
- }
// Remove all inserted virtual registers.
void clear() { Segments.clear(); ++Tag; }
@@ -109,52 +107,42 @@ public:
/// Query interferences between a single live virtual register and a live
/// interval union.
class Query {
- LiveIntervalUnion *LiveUnion;
- LiveInterval *VirtReg;
- LiveInterval::iterator VirtRegI; // current position in VirtReg
- SegmentIter LiveUnionI; // current position in LiveUnion
+ const LiveIntervalUnion *LiveUnion = nullptr;
+ const LiveRange *LR = nullptr;
+ LiveRange::const_iterator LRI; ///< current position in LR
+ ConstSegmentIter LiveUnionI; ///< current position in LiveUnion
SmallVector<LiveInterval*,4> InterferingVRegs;
- bool CheckedFirstInterference;
- bool SeenAllInterferences;
- bool SeenUnspillableVReg;
- unsigned Tag, UserTag;
-
- public:
- Query(): LiveUnion(), VirtReg(), Tag(0), UserTag(0) {}
-
- Query(LiveInterval *VReg, LiveIntervalUnion *LIU):
- LiveUnion(LIU), VirtReg(VReg), CheckedFirstInterference(false),
- SeenAllInterferences(false), SeenUnspillableVReg(false)
- {}
-
- void clear() {
- LiveUnion = nullptr;
- VirtReg = nullptr;
+ bool CheckedFirstInterference = false;
+ bool SeenAllInterferences = false;
+ unsigned Tag = 0;
+ unsigned UserTag = 0;
+
+ void reset(unsigned NewUserTag, const LiveRange &NewLR,
+ const LiveIntervalUnion &NewLiveUnion) {
+ LiveUnion = &NewLiveUnion;
+ LR = &NewLR;
InterferingVRegs.clear();
CheckedFirstInterference = false;
SeenAllInterferences = false;
- SeenUnspillableVReg = false;
- Tag = 0;
- UserTag = 0;
+ Tag = NewLiveUnion.getTag();
+ UserTag = NewUserTag;
}
- void init(unsigned UTag, LiveInterval *VReg, LiveIntervalUnion *LIU) {
- assert(VReg && LIU && "Invalid arguments");
- if (UserTag == UTag && VirtReg == VReg &&
- LiveUnion == LIU && !LIU->changedSince(Tag)) {
+ public:
+ Query() = default;
+ Query(const LiveRange &LR, const LiveIntervalUnion &LIU):
+ LiveUnion(&LIU), LR(&LR) {}
+ Query(const Query &) = delete;
+ Query &operator=(const Query &) = delete;
+
+ void init(unsigned NewUserTag, const LiveRange &NewLR,
+ const LiveIntervalUnion &NewLiveUnion) {
+ if (UserTag == NewUserTag && LR == &NewLR && LiveUnion == &NewLiveUnion &&
+ !NewLiveUnion.changedSince(Tag)) {
// Retain cached results, e.g. firstInterference.
return;
}
- clear();
- LiveUnion = LIU;
- VirtReg = VReg;
- Tag = LIU->getTag();
- UserTag = UTag;
- }
-
- LiveInterval &virtReg() const {
- assert(VirtReg && "uninitialized");
- return *VirtReg;
+ reset(NewUserTag, NewLR, NewLiveUnion);
}
// Does this live virtual register interfere with the union?
@@ -162,7 +150,8 @@ public:
// Count the virtual registers in this union that interfere with this
// query's live virtual register, up to maxInterferingRegs.
- unsigned collectInterferingVRegs(unsigned MaxInterferingRegs = UINT_MAX);
+ unsigned collectInterferingVRegs(
+ unsigned MaxInterferingRegs = std::numeric_limits<unsigned>::max());
// Was this virtual register visited during collectInterferingVRegs?
bool isSeenInterference(LiveInterval *VReg) const;
@@ -170,25 +159,19 @@ public:
// Did collectInterferingVRegs collect all interferences?
bool seenAllInterferences() const { return SeenAllInterferences; }
- // Did collectInterferingVRegs encounter an unspillable vreg?
- bool seenUnspillableVReg() const { return SeenUnspillableVReg; }
-
// Vector generated by collectInterferingVRegs.
const SmallVectorImpl<LiveInterval*> &interferingVRegs() const {
return InterferingVRegs;
}
-
- private:
- Query(const Query&) = delete;
- void operator=(const Query&) = delete;
};
// Array of LiveIntervalUnions.
class Array {
- unsigned Size;
- LiveIntervalUnion *LIUs;
+ unsigned Size = 0;
+ LiveIntervalUnion *LIUs = nullptr;
+
public:
- Array() : Size(0), LIUs(nullptr) {}
+ Array() = default;
~Array() { clear(); }
// Initialize the array to have Size entries.
@@ -213,4 +196,4 @@ public:
} // end namespace llvm
-#endif // !defined(LLVM_CODEGEN_LIVEINTERVALUNION_H)
+#endif // LLVM_CODEGEN_LIVEINTERVALUNION_H
diff --git a/contrib/llvm/include/llvm/CodeGen/LivePhysRegs.h b/contrib/llvm/include/llvm/CodeGen/LivePhysRegs.h
index 9e04c46..f9c741d 100644
--- a/contrib/llvm/include/llvm/CodeGen/LivePhysRegs.h
+++ b/contrib/llvm/include/llvm/CodeGen/LivePhysRegs.h
@@ -7,23 +7,24 @@
//
//===----------------------------------------------------------------------===//
//
-// This file implements the LivePhysRegs utility for tracking liveness of
-// physical registers. This can be used for ad-hoc liveness tracking after
-// register allocation. You can start with the live-ins/live-outs at the
-// beginning/end of a block and update the information while walking the
-// instructions inside the block. This implementation tracks the liveness on a
-// sub-register granularity.
-//
-// We assume that the high bits of a physical super-register are not preserved
-// unless the instruction has an implicit-use operand reading the super-
-// register.
-//
-// X86 Example:
-// %YMM0<def> = ...
-// %XMM0<def> = ... (Kills %XMM0, all %XMM0s sub-registers, and %YMM0)
-//
-// %YMM0<def> = ...
-// %XMM0<def> = ..., %YMM0<imp-use> (%YMM0 and all its sub-registers are alive)
+/// \file
+/// This file implements the LivePhysRegs utility for tracking liveness of
+/// physical registers. This can be used for ad-hoc liveness tracking after
+/// register allocation. You can start with the live-ins/live-outs at the
+/// beginning/end of a block and update the information while walking the
+/// instructions inside the block. This implementation tracks the liveness on a
+/// sub-register granularity.
+///
+/// We assume that the high bits of a physical super-register are not preserved
+/// unless the instruction has an implicit-use operand reading the super-
+/// register.
+///
+/// X86 Example:
+/// %YMM0<def> = ...
+/// %XMM0<def> = ... (Kills %XMM0, all %XMM0s sub-registers, and %YMM0)
+///
+/// %YMM0<def> = ...
+/// %XMM0<def> = ..., %YMM0<imp-use> (%YMM0 and all its sub-registers are alive)
//===----------------------------------------------------------------------===//
#ifndef LLVM_CODEGEN_LIVEPHYSREGS_H
@@ -39,40 +40,42 @@
namespace llvm {
class MachineInstr;
+class MachineOperand;
+class MachineRegisterInfo;
+class raw_ostream;
-/// \brief A set of live physical registers with functions to track liveness
+/// \brief A set of physical registers with utility functions to track liveness
/// when walking backward/forward through a basic block.
class LivePhysRegs {
const TargetRegisterInfo *TRI = nullptr;
SparseSet<unsigned> LiveRegs;
- LivePhysRegs(const LivePhysRegs&) = delete;
- LivePhysRegs &operator=(const LivePhysRegs&) = delete;
-
public:
- /// \brief Constructs a new empty LivePhysRegs set.
+ /// Constructs an unitialized set. init() needs to be called to initialize it.
LivePhysRegs() = default;
- /// \brief Constructs and initialize an empty LivePhysRegs set.
- LivePhysRegs(const TargetRegisterInfo *TRI) : TRI(TRI) {
- assert(TRI && "Invalid TargetRegisterInfo pointer.");
- LiveRegs.setUniverse(TRI->getNumRegs());
+ /// Constructs and initializes an empty set.
+ LivePhysRegs(const TargetRegisterInfo &TRI) : TRI(&TRI) {
+ LiveRegs.setUniverse(TRI.getNumRegs());
}
- /// \brief Clear and initialize the LivePhysRegs set.
+ LivePhysRegs(const LivePhysRegs&) = delete;
+ LivePhysRegs &operator=(const LivePhysRegs&) = delete;
+
+ /// (re-)initializes and clears the set.
void init(const TargetRegisterInfo &TRI) {
this->TRI = &TRI;
LiveRegs.clear();
LiveRegs.setUniverse(TRI.getNumRegs());
}
- /// \brief Clears the LivePhysRegs set.
+ /// Clears the set.
void clear() { LiveRegs.clear(); }
- /// \brief Returns true if the set is empty.
+ /// Returns true if the set is empty.
bool empty() const { return LiveRegs.empty(); }
- /// \brief Adds a physical register and all its sub-registers to the set.
+ /// Adds a physical register and all its sub-registers to the set.
void addReg(unsigned Reg) {
assert(TRI && "LivePhysRegs is not initialized.");
assert(Reg <= TRI->getNumRegs() && "Expected a physical register.");
@@ -90,12 +93,13 @@ public:
LiveRegs.erase(*R);
}
- /// \brief Removes physical registers clobbered by the regmask operand @p MO.
+ /// Removes physical registers clobbered by the regmask operand \p MO.
void removeRegsInMask(const MachineOperand &MO,
- SmallVectorImpl<std::pair<unsigned, const MachineOperand*>> *Clobbers);
+ SmallVectorImpl<std::pair<unsigned, const MachineOperand*>> *Clobbers =
+ nullptr);
- /// \brief Returns true if register @p Reg is contained in the set. This also
- /// works if only the super register of @p Reg has been defined, because
+ /// \brief Returns true if register \p Reg is contained in the set. This also
+ /// works if only the super register of \p Reg has been defined, because
/// addReg() always adds all sub-registers to the set as well.
/// Note: Returns false if just some sub registers are live, use available()
/// when searching a free register.
@@ -104,48 +108,48 @@ public:
/// Returns true if register \p Reg and no aliasing register is in the set.
bool available(const MachineRegisterInfo &MRI, unsigned Reg) const;
- /// \brief Simulates liveness when stepping backwards over an
- /// instruction(bundle): Remove Defs, add uses. This is the recommended way of
- /// calculating liveness.
+ /// Simulates liveness when stepping backwards over an instruction(bundle).
+ /// Remove Defs, add uses. This is the recommended way of calculating
+ /// liveness.
void stepBackward(const MachineInstr &MI);
- /// \brief Simulates liveness when stepping forward over an
- /// instruction(bundle): Remove killed-uses, add defs. This is the not
- /// recommended way, because it depends on accurate kill flags. If possible
- /// use stepBackward() instead of this function.
- /// The clobbers set will be the list of registers either defined or clobbered
- /// by a regmask. The operand will identify whether this is a regmask or
- /// register operand.
+ /// Simulates liveness when stepping forward over an instruction(bundle).
+ /// Remove killed-uses, add defs. This is the not recommended way, because it
+ /// depends on accurate kill flags. If possible use stepBackward() instead of
+ /// this function. The clobbers set will be the list of registers either
+ /// defined or clobbered by a regmask. The operand will identify whether this
+ /// is a regmask or register operand.
void stepForward(const MachineInstr &MI,
SmallVectorImpl<std::pair<unsigned, const MachineOperand*>> &Clobbers);
- /// Adds all live-in registers of basic block @p MBB.
+ /// Adds all live-in registers of basic block \p MBB.
/// Live in registers are the registers in the blocks live-in list and the
/// pristine registers.
void addLiveIns(const MachineBasicBlock &MBB);
- /// Adds all live-out registers of basic block @p MBB.
+ /// Adds all live-out registers of basic block \p MBB.
/// Live out registers are the union of the live-in registers of the successor
/// blocks and pristine registers. Live out registers of the end block are the
/// callee saved registers.
void addLiveOuts(const MachineBasicBlock &MBB);
- /// Like addLiveOuts() but does not add pristine registers/callee saved
+ /// Adds all live-out registers of basic block \p MBB but skips pristine
/// registers.
void addLiveOutsNoPristines(const MachineBasicBlock &MBB);
- typedef SparseSet<unsigned>::const_iterator const_iterator;
+ using const_iterator = SparseSet<unsigned>::const_iterator;
+
const_iterator begin() const { return LiveRegs.begin(); }
const_iterator end() const { return LiveRegs.end(); }
- /// \brief Prints the currently live registers to @p OS.
+ /// Prints the currently live registers to \p OS.
void print(raw_ostream &OS) const;
- /// \brief Dumps the currently live registers to the debug output.
+ /// Dumps the currently live registers to the debug output.
void dump() const;
private:
- /// Adds live-in registers from basic block @p MBB, taking associated
+ /// \brief Adds live-in registers from basic block \p MBB, taking associated
/// lane masks into consideration.
void addBlockLiveIns(const MachineBasicBlock &MBB);
};
@@ -155,11 +159,11 @@ inline raw_ostream &operator<<(raw_ostream &OS, const LivePhysRegs& LR) {
return OS;
}
-/// Compute the live-in list for \p MBB assuming all of its successors live-in
-/// lists are up-to-date. Uses the given LivePhysReg instance \p LiveRegs; This
-/// is just here to avoid repeated heap allocations when calling this multiple
-/// times in a pass.
-void computeLiveIns(LivePhysRegs &LiveRegs, const TargetRegisterInfo &TRI,
+/// \brief Computes the live-in list for \p MBB assuming all of its successors
+/// live-in lists are up-to-date. Uses the given LivePhysReg instance \p
+/// LiveRegs; This is just here to avoid repeated heap allocations when calling
+/// this multiple times in a pass.
+void computeLiveIns(LivePhysRegs &LiveRegs, const MachineRegisterInfo &MRI,
MachineBasicBlock &MBB);
} // end namespace llvm
diff --git a/contrib/llvm/include/llvm/CodeGen/LiveRangeEdit.h b/contrib/llvm/include/llvm/CodeGen/LiveRangeEdit.h
index 4250777..362d985 100644
--- a/contrib/llvm/include/llvm/CodeGen/LiveRangeEdit.h
+++ b/contrib/llvm/include/llvm/CodeGen/LiveRangeEdit.h
@@ -1,4 +1,4 @@
-//===---- LiveRangeEdit.h - Basic tools for split and spill -----*- C++ -*-===//
+//===- LiveRangeEdit.h - Basic tools for split and spill --------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -19,19 +19,28 @@
#define LLVM_CODEGEN_LIVERANGEEDIT_H
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/None.h"
#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"
#include "llvm/CodeGen/MachineRegisterInfo.h"
-#include "llvm/Target/TargetMachine.h"
+#include "llvm/CodeGen/SlotIndexes.h"
#include "llvm/Target/TargetSubtargetInfo.h"
+#include <cassert>
namespace llvm {
class LiveIntervals;
class MachineBlockFrequencyInfo;
+class MachineInstr;
class MachineLoopInfo;
+class MachineOperand;
+class TargetInstrInfo;
+class TargetRegisterInfo;
class VirtRegMap;
class LiveRangeEdit : private MachineRegisterInfo::Delegate {
@@ -39,7 +48,10 @@ public:
/// Callback methods for LiveRangeEdit owners.
class Delegate {
virtual void anchor();
+
public:
+ virtual ~Delegate() = default;
+
/// Called immediately before erasing a dead machine instruction.
virtual void LRE_WillEraseInstruction(MachineInstr *MI) {}
@@ -53,8 +65,6 @@ public:
/// Called after cloning a virtual register.
/// This is used for new registers representing connected components of Old.
virtual void LRE_DidCloneVirtReg(unsigned New, unsigned Old) {}
-
- virtual ~Delegate() {}
};
private:
@@ -70,7 +80,7 @@ private:
const unsigned FirstNew;
/// ScannedRemattable - true when remattable values have been identified.
- bool ScannedRemattable;
+ bool ScannedRemattable = false;
/// DeadRemats - The saved instructions which have already been dead after
/// rematerialization but not deleted yet -- to be done in postOptimization.
@@ -78,11 +88,11 @@ private:
/// Remattable - Values defined by remattable instructions as identified by
/// tii.isTriviallyReMaterializable().
- SmallPtrSet<const VNInfo*,4> Remattable;
+ SmallPtrSet<const VNInfo *, 4> Remattable;
/// Rematted - Values that were actually rematted, and so need to have their
/// live range trimmed or entirely removed.
- SmallPtrSet<const VNInfo*,4> Rematted;
+ SmallPtrSet<const VNInfo *, 4> Rematted;
/// scanRemattable - Identify the Parent values that may rematerialize.
void scanRemattable(AliasAnalysis *aa);
@@ -94,11 +104,11 @@ private:
/// foldAsLoad - If LI has a single use and a single def that can be folded as
/// a load, eliminate the register by folding the def into the use.
- bool foldAsLoad(LiveInterval *LI, SmallVectorImpl<MachineInstr*> &Dead);
+ bool foldAsLoad(LiveInterval *LI, SmallVectorImpl<MachineInstr *> &Dead);
+
+ using ToShrinkSet = SetVector<LiveInterval *, SmallVector<LiveInterval *, 8>,
+ SmallPtrSet<LiveInterval *, 8>>;
- typedef SetVector<LiveInterval*,
- SmallVector<LiveInterval*, 8>,
- SmallPtrSet<LiveInterval*, 8> > ToShrinkSet;
/// Helper for eliminateDeadDefs.
void eliminateDeadDef(MachineInstr *MI, ToShrinkSet &ToShrink,
AliasAnalysis *AA);
@@ -129,26 +139,26 @@ public:
SmallPtrSet<MachineInstr *, 32> *deadRemats = nullptr)
: Parent(parent), NewRegs(newRegs), MRI(MF.getRegInfo()), LIS(lis),
VRM(vrm), TII(*MF.getSubtarget().getInstrInfo()), TheDelegate(delegate),
- FirstNew(newRegs.size()), ScannedRemattable(false),
- DeadRemats(deadRemats) {
+ FirstNew(newRegs.size()), DeadRemats(deadRemats) {
MRI.setDelegate(this);
}
~LiveRangeEdit() override { MRI.resetDelegate(this); }
LiveInterval &getParent() const {
- assert(Parent && "No parent LiveInterval");
- return *Parent;
+ assert(Parent && "No parent LiveInterval");
+ return *Parent;
}
+
unsigned getReg() const { return getParent().reg; }
/// Iterator for accessing the new registers added by this edit.
- typedef SmallVectorImpl<unsigned>::const_iterator iterator;
- iterator begin() const { return NewRegs.begin()+FirstNew; }
+ using iterator = SmallVectorImpl<unsigned>::const_iterator;
+ iterator begin() const { return NewRegs.begin() + FirstNew; }
iterator end() const { return NewRegs.end(); }
- unsigned size() const { return NewRegs.size()-FirstNew; }
+ unsigned size() const { return NewRegs.size() - FirstNew; }
bool empty() const { return size() == 0; }
- unsigned get(unsigned idx) const { return NewRegs[idx+FirstNew]; }
+ unsigned 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
@@ -176,26 +186,25 @@ public:
return createEmptyIntervalFrom(getReg());
}
- unsigned create() {
- return createFrom(getReg());
- }
+ unsigned 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(AliasAnalysis *);
/// checkRematerializable - Manually add VNI to the list of rematerializable
/// values if DefMI may be rematerializable.
bool checkRematerializable(VNInfo *VNI, const MachineInstr *DefMI,
- AliasAnalysis*);
+ AliasAnalysis *);
/// Remat - Information needed to rematerialize at a specific location.
struct Remat {
- VNInfo *ParentVNI; // parent_'s value at the remat location.
- MachineInstr *OrigMI; // Instruction defining OrigVNI. It contains the
- // real expr for remat.
- explicit Remat(VNInfo *ParentVNI) : ParentVNI(ParentVNI), OrigMI(nullptr) {}
+ VNInfo *ParentVNI; // parent_'s value at the remat location.
+ MachineInstr *OrigMI = nullptr; // Instruction defining OrigVNI. It contains
+ // the real expr for remat.
+
+ explicit Remat(VNInfo *ParentVNI) : ParentVNI(ParentVNI) {}
};
/// canRematerializeAt - Determine if ParentVNI can be rematerialized at
@@ -209,10 +218,8 @@ public:
/// liveness is not updated.
/// Return the SlotIndex of the new instruction.
SlotIndex rematerializeAt(MachineBasicBlock &MBB,
- MachineBasicBlock::iterator MI,
- unsigned DestReg,
- const Remat &RM,
- const TargetRegisterInfo&,
+ MachineBasicBlock::iterator MI, unsigned DestReg,
+ const Remat &RM, const TargetRegisterInfo &,
bool Late = false);
/// markRematerialized - explicitly mark a value as rematerialized after doing
@@ -248,11 +255,10 @@ public:
/// calculateRegClassAndHint - Recompute register class and hint for each new
/// register.
- void calculateRegClassAndHint(MachineFunction&,
- const MachineLoopInfo&,
- const MachineBlockFrequencyInfo&);
+ void calculateRegClassAndHint(MachineFunction &, const MachineLoopInfo &,
+ const MachineBlockFrequencyInfo &);
};
-}
+} // end namespace llvm
-#endif
+#endif // LLVM_CODEGEN_LIVERANGEEDIT_H
diff --git a/contrib/llvm/include/llvm/CodeGen/LiveRegMatrix.h b/contrib/llvm/include/llvm/CodeGen/LiveRegMatrix.h
index e169058..fa6827f 100644
--- a/contrib/llvm/include/llvm/CodeGen/LiveRegMatrix.h
+++ b/contrib/llvm/include/llvm/CodeGen/LiveRegMatrix.h
@@ -1,4 +1,4 @@
-//===-- LiveRegMatrix.h - Track register interference ---------*- C++ -*---===//
+//===- LiveRegMatrix.h - Track register interference ----------*- C++ -*---===//
//
// The LLVM Compiler Infrastructure
//
@@ -27,11 +27,14 @@
#include "llvm/ADT/BitVector.h"
#include "llvm/CodeGen/LiveIntervalUnion.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
+#include <memory>
namespace llvm {
+class AnalysisUsage;
class LiveInterval;
-class LiveIntervalAnalysis;
+class LiveIntervals;
+class MachineFunction;
class TargetRegisterInfo;
class VirtRegMap;
@@ -41,7 +44,7 @@ class LiveRegMatrix : public MachineFunctionPass {
VirtRegMap *VRM;
// UserTag changes whenever virtual registers have been modified.
- unsigned UserTag;
+ unsigned UserTag = 0;
// The matrix is represented as a LiveIntervalUnion per register unit.
LiveIntervalUnion::Allocator LIUAlloc;
@@ -51,16 +54,18 @@ class LiveRegMatrix : public MachineFunctionPass {
std::unique_ptr<LiveIntervalUnion::Query[]> Queries;
// Cached register mask interference info.
- unsigned RegMaskTag;
- unsigned RegMaskVirtReg;
+ unsigned RegMaskTag = 0;
+ unsigned RegMaskVirtReg = 0;
BitVector RegMaskUsable;
// MachineFunctionPass boilerplate.
- void getAnalysisUsage(AnalysisUsage&) const override;
- bool runOnMachineFunction(MachineFunction&) override;
+ void getAnalysisUsage(AnalysisUsage &) const override;
+ bool runOnMachineFunction(MachineFunction &) override;
void releaseMemory() override;
+
public:
static char ID;
+
LiveRegMatrix();
//===--------------------------------------------------------------------===//
@@ -136,7 +141,7 @@ public:
/// Use MCRegUnitIterator to enumerate all regunits in the desired PhysReg.
/// This returns a reference to an internal Query data structure that is only
/// valid until the next query() call.
- LiveIntervalUnion::Query &query(LiveInterval &VirtReg, unsigned RegUnit);
+ LiveIntervalUnion::Query &query(const LiveRange &LR, unsigned RegUnit);
/// Directly access the live interval unions per regunit.
/// This returns an array indexed by the regunit number.
diff --git a/contrib/llvm/include/llvm/CodeGen/LiveRegUnits.h b/contrib/llvm/include/llvm/CodeGen/LiveRegUnits.h
new file mode 100644
index 0000000..c28b1a0
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/LiveRegUnits.h
@@ -0,0 +1,130 @@
+//===- llvm/CodeGen/LiveRegUnits.h - Register Unit Set ----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+/// \file
+/// A set of register units. It is intended for register liveness tracking.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_LIVEREGUNITS_H
+#define LLVM_CODEGEN_LIVEREGUNITS_H
+
+#include "llvm/ADT/BitVector.h"
+#include "llvm/MC/LaneBitmask.h"
+#include "llvm/MC/MCRegisterInfo.h"
+#include "llvm/Target/TargetRegisterInfo.h"
+#include <cstdint>
+
+namespace llvm {
+
+class MachineInstr;
+class MachineBasicBlock;
+
+/// A set of register units used to track register liveness.
+class LiveRegUnits {
+ const TargetRegisterInfo *TRI = nullptr;
+ BitVector Units;
+
+public:
+ /// Constructs a new empty LiveRegUnits set.
+ LiveRegUnits() = default;
+
+ /// Constructs and initialize an empty LiveRegUnits set.
+ LiveRegUnits(const TargetRegisterInfo &TRI) {
+ init(TRI);
+ }
+
+ /// Initialize and clear the set.
+ void init(const TargetRegisterInfo &TRI) {
+ this->TRI = &TRI;
+ Units.reset();
+ Units.resize(TRI.getNumRegUnits());
+ }
+
+ /// Clears the set.
+ void clear() { Units.reset(); }
+
+ /// Returns true if the set is empty.
+ bool empty() const { return Units.empty(); }
+
+ /// Adds register units covered by physical register \p Reg.
+ void addReg(unsigned Reg) {
+ for (MCRegUnitIterator Unit(Reg, TRI); Unit.isValid(); ++Unit)
+ Units.set(*Unit);
+ }
+
+ /// \brief Adds register units covered by physical register \p Reg that are
+ /// part of the lanemask \p Mask.
+ void addRegMasked(unsigned Reg, LaneBitmask Mask) {
+ for (MCRegUnitMaskIterator Unit(Reg, TRI); Unit.isValid(); ++Unit) {
+ LaneBitmask UnitMask = (*Unit).second;
+ if (UnitMask.none() || (UnitMask & Mask).any())
+ Units.set((*Unit).first);
+ }
+ }
+
+ /// Removes all register units covered by physical register \p Reg.
+ void removeReg(unsigned Reg) {
+ for (MCRegUnitIterator Unit(Reg, TRI); Unit.isValid(); ++Unit)
+ Units.reset(*Unit);
+ }
+
+ /// Removes register units not preserved by the regmask \p RegMask.
+ /// The regmask has the same format as the one in the RegMask machine operand.
+ void removeRegsNotPreserved(const uint32_t *RegMask);
+
+ /// Adds register units not preserved by the regmask \p RegMask.
+ /// The regmask has the same format as the one in the RegMask machine operand.
+ void addRegsInMask(const uint32_t *RegMask);
+
+ /// Returns true if no part of physical register \p Reg is live.
+ bool available(unsigned Reg) const {
+ for (MCRegUnitIterator Unit(Reg, TRI); Unit.isValid(); ++Unit) {
+ if (Units.test(*Unit))
+ return false;
+ }
+ return true;
+ }
+
+ /// Updates liveness when stepping backwards over the instruction \p MI.
+ /// This removes all register units defined or clobbered in \p MI and then
+ /// adds the units used (as in use operands) in \p MI.
+ void stepBackward(const MachineInstr &MI);
+
+ /// Adds all register units used, defined or clobbered in \p MI.
+ /// This is useful when walking over a range of instruction to find registers
+ /// unused over the whole range.
+ void accumulate(const MachineInstr &MI);
+
+ /// Adds registers living out of block \p MBB.
+ /// Live out registers are the union of the live-in registers of the successor
+ /// blocks and pristine registers. Live out registers of the end block are the
+ /// callee saved registers.
+ void addLiveOuts(const MachineBasicBlock &MBB);
+
+ /// Adds registers living into block \p MBB.
+ void addLiveIns(const MachineBasicBlock &MBB);
+
+ /// Adds all register units marked in the bitvector \p RegUnits.
+ void addUnits(const BitVector &RegUnits) {
+ Units |= RegUnits;
+ }
+ /// Removes all register units marked in the bitvector \p RegUnits.
+ void removeUnits(const BitVector &RegUnits) {
+ Units.reset(RegUnits);
+ }
+ /// Return the internal bitvector representation of the set.
+ const BitVector &getBitVector() const {
+ return Units;
+ }
+};
+
+} // end namespace llvm
+
+#endif // LLVM_CODEGEN_LIVEREGUNITS_H
diff --git a/contrib/llvm/include/llvm/CodeGen/LiveStackAnalysis.h b/contrib/llvm/include/llvm/CodeGen/LiveStackAnalysis.h
index 3ffbe3d..c90ae7b 100644
--- a/contrib/llvm/include/llvm/CodeGen/LiveStackAnalysis.h
+++ b/contrib/llvm/include/llvm/CodeGen/LiveStackAnalysis.h
@@ -1,4 +1,4 @@
-//===-- LiveStackAnalysis.h - Live Stack Slot Analysis ----------*- C++ -*-===//
+//===- LiveStackAnalysis.h - Live Stack Slot Analysis -----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -18,13 +18,16 @@
#include "llvm/CodeGen/LiveInterval.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
-#include "llvm/Support/Allocator.h"
-#include "llvm/Target/TargetRegisterInfo.h"
+#include "llvm/Pass.h"
+#include <cassert>
#include <map>
#include <unordered_map>
namespace llvm {
+class TargetRegisterClass;
+class TargetRegisterInfo;
+
class LiveStacks : public MachineFunctionPass {
const TargetRegisterInfo *TRI;
@@ -33,8 +36,7 @@ class LiveStacks : public MachineFunctionPass {
VNInfo::Allocator VNInfoAllocator;
/// S2IMap - Stack slot indices to live interval mapping.
- ///
- typedef std::unordered_map<int, LiveInterval> SS2IntervalMap;
+ using SS2IntervalMap = std::unordered_map<int, LiveInterval>;
SS2IntervalMap S2IMap;
/// S2RCMap - Stack slot indices to register class mapping.
@@ -42,12 +44,14 @@ class LiveStacks : public MachineFunctionPass {
public:
static char ID; // Pass identification, replacement for typeid
+
LiveStacks() : MachineFunctionPass(ID) {
initializeLiveStacksPass(*PassRegistry::getPassRegistry());
}
- typedef SS2IntervalMap::iterator iterator;
- typedef SS2IntervalMap::const_iterator const_iterator;
+ using iterator = SS2IntervalMap::iterator;
+ using const_iterator = SS2IntervalMap::const_iterator;
+
const_iterator begin() const { return S2IMap.begin(); }
const_iterator end() const { return S2IMap.end(); }
iterator begin() { return S2IMap.begin(); }
@@ -93,6 +97,7 @@ public:
/// print - Implement the dump method.
void print(raw_ostream &O, const Module * = nullptr) const override;
};
-}
-#endif /* LLVM_CODEGEN_LIVESTACK_ANALYSIS_H */
+} // end namespace llvm
+
+#endif // LLVM_CODEGEN_LIVESTACK_ANALYSIS_H
diff --git a/contrib/llvm/include/llvm/CodeGen/LowLevelType.h b/contrib/llvm/include/llvm/CodeGen/LowLevelType.h
index b8885c3..a3c5c93 100644
--- a/contrib/llvm/include/llvm/CodeGen/LowLevelType.h
+++ b/contrib/llvm/include/llvm/CodeGen/LowLevelType.h
@@ -1,4 +1,4 @@
-//== llvm/CodeGen/GlobalISel/LowLevelType.h -------------------- -*- C++ -*-==//
+//== llvm/CodeGen/LowLevelType.h ------------------------------- -*- C++ -*-==//
//
// The LLVM Compiler Infrastructure
//
@@ -10,197 +10,23 @@
/// Implement a low-level type suitable for MachineInstr level instruction
/// selection.
///
-/// For a type attached to a MachineInstr, we only care about 2 details: total
-/// size and the number of vector lanes (if any). Accordingly, there are 4
-/// possible valid type-kinds:
-///
-/// * `sN` for scalars and aggregates
-/// * `<N x sM>` for vectors, which must have at least 2 elements.
-/// * `pN` for pointers
-///
-/// Other information required for correct selection is expected to be carried
-/// by the opcode, or non-type flags. For example the distinction between G_ADD
-/// and G_FADD for int/float or fast-math flags.
+/// This provides the CodeGen aspects of LowLevelType, such as Type conversion.
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CODEGEN_GLOBALISEL_LOWLEVELTYPE_H
-#define LLVM_CODEGEN_GLOBALISEL_LOWLEVELTYPE_H
+#ifndef LLVM_CODEGEN_LOWLEVELTYPE_H
+#define LLVM_CODEGEN_LOWLEVELTYPE_H
-#include <cassert>
-#include "llvm/ADT/DenseMapInfo.h"
-#include "llvm/CodeGen/ValueTypes.h"
+#include "llvm/Support/LowLevelTypeImpl.h"
namespace llvm {
class DataLayout;
-class LLVMContext;
class Type;
-class raw_ostream;
-
-class LLT {
-public:
- enum TypeKind : uint16_t {
- Invalid,
- Scalar,
- Pointer,
- Vector,
- };
-
- /// Get a low-level scalar or aggregate "bag of bits".
- static LLT scalar(unsigned SizeInBits) {
- assert(SizeInBits > 0 && "invalid scalar size");
- return LLT{Scalar, 1, SizeInBits};
- }
-
- /// Get a low-level pointer in the given address space (defaulting to 0).
- static LLT pointer(uint16_t AddressSpace, unsigned SizeInBits) {
- return LLT{Pointer, AddressSpace, SizeInBits};
- }
-
- /// Get a low-level vector of some number of elements and element width.
- /// \p NumElements must be at least 2.
- static LLT vector(uint16_t NumElements, unsigned ScalarSizeInBits) {
- assert(NumElements > 1 && "invalid number of vector elements");
- return LLT{Vector, NumElements, ScalarSizeInBits};
- }
-
- /// Get a low-level vector of some number of elements and element type.
- static LLT vector(uint16_t NumElements, LLT ScalarTy) {
- assert(NumElements > 1 && "invalid number of vector elements");
- assert(ScalarTy.isScalar() && "invalid vector element type");
- return LLT{Vector, NumElements, ScalarTy.getSizeInBits()};
- }
-
- explicit LLT(TypeKind Kind, uint16_t NumElements, unsigned SizeInBits)
- : SizeInBits(SizeInBits), ElementsOrAddrSpace(NumElements), Kind(Kind) {
- assert((Kind != Vector || ElementsOrAddrSpace > 1) &&
- "invalid number of vector elements");
- }
-
- explicit LLT() : SizeInBits(0), ElementsOrAddrSpace(0), Kind(Invalid) {}
-
- /// Construct a low-level type based on an LLVM type.
- explicit LLT(Type &Ty, const DataLayout &DL);
-
- explicit LLT(MVT VT);
-
- bool isValid() const { return Kind != Invalid; }
-
- bool isScalar() const { return Kind == Scalar; }
-
- bool isPointer() const { return Kind == Pointer; }
-
- bool isVector() const { return Kind == Vector; }
-
- /// Returns the number of elements in a vector LLT. Must only be called on
- /// vector types.
- uint16_t getNumElements() const {
- assert(isVector() && "cannot get number of elements on scalar/aggregate");
- return ElementsOrAddrSpace;
- }
-
- /// Returns the total size of the type. Must only be called on sized types.
- unsigned getSizeInBits() const {
- if (isPointer() || isScalar())
- return SizeInBits;
- return SizeInBits * ElementsOrAddrSpace;
- }
-
- unsigned getScalarSizeInBits() const {
- return SizeInBits;
- }
-
- unsigned getAddressSpace() const {
- assert(isPointer() && "cannot get address space of non-pointer type");
- return ElementsOrAddrSpace;
- }
-
- /// Returns the vector's element type. Only valid for vector types.
- LLT getElementType() const {
- assert(isVector() && "cannot get element type of scalar/aggregate");
- return scalar(SizeInBits);
- }
-
- /// Get a low-level type with half the size of the original, by halving the
- /// size of the scalar type involved. For example `s32` will become `s16`,
- /// `<2 x s32>` will become `<2 x s16>`.
- LLT halfScalarSize() const {
- assert(!isPointer() && getScalarSizeInBits() > 1 &&
- getScalarSizeInBits() % 2 == 0 && "cannot half size of this type");
- return LLT{Kind, ElementsOrAddrSpace, SizeInBits / 2};
- }
-
- /// Get a low-level type with twice the size of the original, by doubling the
- /// size of the scalar type involved. For example `s32` will become `s64`,
- /// `<2 x s32>` will become `<2 x s64>`.
- LLT doubleScalarSize() const {
- assert(!isPointer() && "cannot change size of this type");
- return LLT{Kind, ElementsOrAddrSpace, SizeInBits * 2};
- }
-
- /// Get a low-level type with half the size of the original, by halving the
- /// number of vector elements of the scalar type involved. The source must be
- /// a vector type with an even number of elements. For example `<4 x s32>`
- /// will become `<2 x s32>`, `<2 x s32>` will become `s32`.
- LLT halfElements() const {
- assert(isVector() && ElementsOrAddrSpace % 2 == 0 &&
- "cannot half odd vector");
- if (ElementsOrAddrSpace == 2)
- return scalar(SizeInBits);
-
- return LLT{Vector, static_cast<uint16_t>(ElementsOrAddrSpace / 2),
- SizeInBits};
- }
-
- /// Get a low-level type with twice the size of the original, by doubling the
- /// number of vector elements of the scalar type involved. The source must be
- /// a vector type. For example `<2 x s32>` will become `<4 x s32>`. Doubling
- /// the number of elements in sN produces <2 x sN>.
- LLT doubleElements() const {
- assert(!isPointer() && "cannot double elements in pointer");
- return LLT{Vector, static_cast<uint16_t>(ElementsOrAddrSpace * 2),
- SizeInBits};
- }
-
- void print(raw_ostream &OS) const;
-
- bool operator==(const LLT &RHS) const {
- return Kind == RHS.Kind && SizeInBits == RHS.SizeInBits &&
- ElementsOrAddrSpace == RHS.ElementsOrAddrSpace;
- }
-
- bool operator!=(const LLT &RHS) const { return !(*this == RHS); }
-
- friend struct DenseMapInfo<LLT>;
-private:
- unsigned SizeInBits;
- uint16_t ElementsOrAddrSpace;
- TypeKind Kind;
-};
-
-inline raw_ostream& operator<<(raw_ostream &OS, const LLT &Ty) {
- Ty.print(OS);
- return OS;
-}
-template<> struct DenseMapInfo<LLT> {
- static inline LLT getEmptyKey() {
- return LLT{LLT::Invalid, 0, -1u};
- }
- static inline LLT getTombstoneKey() {
- return LLT{LLT::Invalid, 0, -2u};
- }
- static inline unsigned getHashValue(const LLT &Ty) {
- uint64_t Val = ((uint64_t)Ty.SizeInBits << 32) |
- ((uint64_t)Ty.ElementsOrAddrSpace << 16) | (uint64_t)Ty.Kind;
- return DenseMapInfo<uint64_t>::getHashValue(Val);
- }
- static bool isEqual(const LLT &LHS, const LLT &RHS) {
- return LHS == RHS;
- }
-};
+/// Construct a low-level type based on an LLVM type.
+LLT getLLTForType(Type &Ty, const DataLayout &DL);
}
-#endif
+#endif // LLVM_CODEGEN_LOWLEVELTYPE_H
diff --git a/contrib/llvm/include/llvm/CodeGen/MIRParser/MIRParser.h b/contrib/llvm/include/llvm/CodeGen/MIRParser/MIRParser.h
index dd07803..b631a8c 100644
--- a/contrib/llvm/include/llvm/CodeGen/MIRParser/MIRParser.h
+++ b/contrib/llvm/include/llvm/CodeGen/MIRParser/MIRParser.h
@@ -18,7 +18,6 @@
#ifndef LLVM_CODEGEN_MIRPARSER_MIRPARSER_H
#define LLVM_CODEGEN_MIRPARSER_MIRPARSER_H
-#include "llvm/CodeGen/MachineFunctionInitializer.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/MemoryBuffer.h"
#include <memory>
@@ -27,29 +26,30 @@ namespace llvm {
class StringRef;
class MIRParserImpl;
+class MachineModuleInfo;
class SMDiagnostic;
/// This class initializes machine functions by applying the state loaded from
/// a MIR file.
-class MIRParser : public MachineFunctionInitializer {
+class MIRParser {
std::unique_ptr<MIRParserImpl> Impl;
public:
MIRParser(std::unique_ptr<MIRParserImpl> Impl);
MIRParser(const MIRParser &) = delete;
- ~MIRParser() override;
+ ~MIRParser();
- /// Parse the optional LLVM IR module that's embedded in the MIR file.
+ /// Parses the optional LLVM IR module in the MIR file.
///
/// A new, empty module is created if the LLVM IR isn't present.
- /// Returns null if a parsing error occurred.
- std::unique_ptr<Module> parseLLVMModule();
+ /// \returns nullptr if a parsing error occurred.
+ std::unique_ptr<Module> parseIRModule();
- /// Initialize the machine function to the state that's described in the MIR
- /// file.
+ /// \brief Parses MachineFunctions in the MIR file and add them to the given
+ /// MachineModuleInfo \p MMI.
///
- /// Return true if error occurred.
- bool initializeMachineFunction(MachineFunction &MF) override;
+ /// \returns true if an error occurred.
+ bool parseMachineFunctions(Module &M, MachineModuleInfo &MMI);
};
/// This function is the main interface to the MIR serialization format parser.
diff --git a/contrib/llvm/include/llvm/CodeGen/MIRPrinter.h b/contrib/llvm/include/llvm/CodeGen/MIRPrinter.h
new file mode 100644
index 0000000..c73adc3
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/MIRPrinter.h
@@ -0,0 +1,46 @@
+//===- MIRPrinter.h - MIR serialization format printer --------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the functions that print out the LLVM IR and the machine
+// functions using the MIR serialization format.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_CODEGEN_MIRPRINTER_H
+#define LLVM_LIB_CODEGEN_MIRPRINTER_H
+
+namespace llvm {
+
+class MachineBasicBlock;
+class MachineFunction;
+class Module;
+class raw_ostream;
+template <typename T> class SmallVectorImpl;
+
+/// Print LLVM IR using the MIR serialization format to the given output stream.
+void printMIR(raw_ostream &OS, const Module &M);
+
+/// Print a machine function using the MIR serialization format to the given
+/// output stream.
+void printMIR(raw_ostream &OS, const MachineFunction &MF);
+
+/// Determine a possible list of successors of a basic block based on the
+/// basic block machine operand being used inside the block. This should give
+/// you the correct list of successor blocks in most cases except for things
+/// like jump tables where the basic block references can't easily be found.
+/// The MIRPRinter will skip printing successors if they match the result of
+/// this funciton and the parser will use this function to construct a list if
+/// it is missing.
+void guessSuccessors(const MachineBasicBlock &MBB,
+ SmallVectorImpl<MachineBasicBlock*> &Successors,
+ bool &IsFallthrough);
+
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/CodeGen/MIRYamlMapping.h b/contrib/llvm/include/llvm/CodeGen/MIRYamlMapping.h
index 778f72c..1b1ba6a 100644
--- a/contrib/llvm/include/llvm/CodeGen/MIRYamlMapping.h
+++ b/contrib/llvm/include/llvm/CodeGen/MIRYamlMapping.h
@@ -55,7 +55,7 @@ template <> struct ScalarTraits<StringValue> {
struct FlowStringValue : StringValue {
FlowStringValue() {}
- FlowStringValue(std::string Value) : StringValue(Value) {}
+ FlowStringValue(std::string Value) : StringValue(std::move(Value)) {}
};
template <> struct ScalarTraits<FlowStringValue> {
@@ -72,6 +72,9 @@ template <> struct ScalarTraits<FlowStringValue> {
struct BlockStringValue {
StringValue Value;
+ bool operator==(const BlockStringValue &Other) const {
+ return Value == Other.Value;
+ }
};
template <> struct BlockScalarTraits<BlockStringValue> {
@@ -146,6 +149,10 @@ struct VirtualRegisterDefinition {
StringValue Class;
StringValue PreferredRegister;
// TODO: Serialize the target specific register hints.
+ bool operator==(const VirtualRegisterDefinition &Other) const {
+ return ID == Other.ID && Class == Other.Class &&
+ PreferredRegister == Other.PreferredRegister;
+ }
};
template <> struct MappingTraits<VirtualRegisterDefinition> {
@@ -162,6 +169,10 @@ template <> struct MappingTraits<VirtualRegisterDefinition> {
struct MachineFunctionLiveIn {
StringValue Register;
StringValue VirtualRegister;
+ bool operator==(const MachineFunctionLiveIn &Other) const {
+ return Register == Other.Register &&
+ VirtualRegister == Other.VirtualRegister;
+ }
};
template <> struct MappingTraits<MachineFunctionLiveIn> {
@@ -196,6 +207,14 @@ struct MachineStackObject {
StringValue DebugVar;
StringValue DebugExpr;
StringValue DebugLoc;
+ bool operator==(const MachineStackObject &Other) const {
+ return ID == Other.ID && Name == Other.Name && Type == Other.Type &&
+ Offset == Other.Offset && Size == Other.Size &&
+ Alignment == Other.Alignment &&
+ CalleeSavedRegister == Other.CalleeSavedRegister &&
+ LocalOffset == Other.LocalOffset && DebugVar == Other.DebugVar &&
+ DebugExpr == Other.DebugExpr && DebugLoc == Other.DebugLoc;
+ }
};
template <> struct ScalarEnumerationTraits<MachineStackObject::ObjectType> {
@@ -214,13 +233,13 @@ template <> struct MappingTraits<MachineStackObject> {
YamlIO.mapOptional(
"type", Object.Type,
MachineStackObject::DefaultType); // Don't print the default type.
- YamlIO.mapOptional("offset", Object.Offset);
+ YamlIO.mapOptional("offset", Object.Offset, (int64_t)0);
if (Object.Type != MachineStackObject::VariableSized)
YamlIO.mapRequired("size", Object.Size);
- YamlIO.mapOptional("alignment", Object.Alignment);
+ YamlIO.mapOptional("alignment", Object.Alignment, (unsigned)0);
YamlIO.mapOptional("callee-saved-register", Object.CalleeSavedRegister,
StringValue()); // Don't print it out when it's empty.
- YamlIO.mapOptional("local-offset", Object.LocalOffset);
+ YamlIO.mapOptional("local-offset", Object.LocalOffset, Optional<int64_t>());
YamlIO.mapOptional("di-variable", Object.DebugVar,
StringValue()); // Don't print it out when it's empty.
YamlIO.mapOptional("di-expression", Object.DebugExpr,
@@ -244,6 +263,12 @@ struct FixedMachineStackObject {
bool IsImmutable = false;
bool IsAliased = false;
StringValue CalleeSavedRegister;
+ bool operator==(const FixedMachineStackObject &Other) const {
+ return ID == Other.ID && Type == Other.Type && Offset == Other.Offset &&
+ Size == Other.Size && Alignment == Other.Alignment &&
+ IsImmutable == Other.IsImmutable && IsAliased == Other.IsAliased &&
+ CalleeSavedRegister == Other.CalleeSavedRegister;
+ }
};
template <>
@@ -261,12 +286,12 @@ template <> struct MappingTraits<FixedMachineStackObject> {
YamlIO.mapOptional(
"type", Object.Type,
FixedMachineStackObject::DefaultType); // Don't print the default type.
- YamlIO.mapOptional("offset", Object.Offset);
- YamlIO.mapOptional("size", Object.Size);
- YamlIO.mapOptional("alignment", Object.Alignment);
+ YamlIO.mapOptional("offset", Object.Offset, (int64_t)0);
+ YamlIO.mapOptional("size", Object.Size, (uint64_t)0);
+ YamlIO.mapOptional("alignment", Object.Alignment, (unsigned)0);
if (Object.Type != FixedMachineStackObject::SpillSlot) {
- YamlIO.mapOptional("isImmutable", Object.IsImmutable);
- YamlIO.mapOptional("isAliased", Object.IsAliased);
+ YamlIO.mapOptional("isImmutable", Object.IsImmutable, false);
+ YamlIO.mapOptional("isAliased", Object.IsAliased, false);
}
YamlIO.mapOptional("callee-saved-register", Object.CalleeSavedRegister,
StringValue()); // Don't print it out when it's empty.
@@ -279,13 +304,17 @@ struct MachineConstantPoolValue {
UnsignedValue ID;
StringValue Value;
unsigned Alignment = 0;
+ bool operator==(const MachineConstantPoolValue &Other) const {
+ return ID == Other.ID && Value == Other.Value &&
+ Alignment == Other.Alignment;
+ }
};
template <> struct MappingTraits<MachineConstantPoolValue> {
static void mapping(IO &YamlIO, MachineConstantPoolValue &Constant) {
YamlIO.mapRequired("id", Constant.ID);
- YamlIO.mapOptional("value", Constant.Value);
- YamlIO.mapOptional("alignment", Constant.Alignment);
+ YamlIO.mapOptional("value", Constant.Value, StringValue());
+ YamlIO.mapOptional("alignment", Constant.Alignment, (unsigned)0);
}
};
@@ -293,16 +322,22 @@ struct MachineJumpTable {
struct Entry {
UnsignedValue ID;
std::vector<FlowStringValue> Blocks;
+ bool operator==(const Entry &Other) const {
+ return ID == Other.ID && Blocks == Other.Blocks;
+ }
};
MachineJumpTableInfo::JTEntryKind Kind = MachineJumpTableInfo::EK_Custom32;
std::vector<Entry> Entries;
+ bool operator==(const MachineJumpTable &Other) const {
+ return Kind == Other.Kind && Entries == Other.Entries;
+ }
};
template <> struct MappingTraits<MachineJumpTable::Entry> {
static void mapping(IO &YamlIO, MachineJumpTable::Entry &Entry) {
YamlIO.mapRequired("id", Entry.ID);
- YamlIO.mapOptional("blocks", Entry.Blocks);
+ YamlIO.mapOptional("blocks", Entry.Blocks, std::vector<FlowStringValue>());
}
};
@@ -322,7 +357,8 @@ namespace yaml {
template <> struct MappingTraits<MachineJumpTable> {
static void mapping(IO &YamlIO, MachineJumpTable &JT) {
YamlIO.mapRequired("kind", JT.Kind);
- YamlIO.mapOptional("entries", JT.Entries);
+ YamlIO.mapOptional("entries", JT.Entries,
+ std::vector<MachineJumpTable::Entry>());
}
};
@@ -345,31 +381,49 @@ struct MachineFrameInfo {
bool HasCalls = false;
StringValue StackProtector;
// TODO: Serialize FunctionContextIdx
- unsigned MaxCallFrameSize = 0;
+ unsigned MaxCallFrameSize = ~0u; ///< ~0u means: not computed yet.
bool HasOpaqueSPAdjustment = false;
bool HasVAStart = false;
bool HasMustTailInVarArgFunc = false;
StringValue SavePoint;
StringValue RestorePoint;
+ bool operator==(const MachineFrameInfo &Other) const {
+ return IsFrameAddressTaken == Other.IsFrameAddressTaken &&
+ IsReturnAddressTaken == Other.IsReturnAddressTaken &&
+ HasStackMap == Other.HasStackMap &&
+ HasPatchPoint == Other.HasPatchPoint &&
+ StackSize == Other.StackSize &&
+ OffsetAdjustment == Other.OffsetAdjustment &&
+ MaxAlignment == Other.MaxAlignment &&
+ AdjustsStack == Other.AdjustsStack && HasCalls == Other.HasCalls &&
+ StackProtector == Other.StackProtector &&
+ MaxCallFrameSize == Other.MaxCallFrameSize &&
+ HasOpaqueSPAdjustment == Other.HasOpaqueSPAdjustment &&
+ HasVAStart == Other.HasVAStart &&
+ HasMustTailInVarArgFunc == Other.HasMustTailInVarArgFunc &&
+ SavePoint == Other.SavePoint && RestorePoint == Other.RestorePoint;
+ }
};
template <> struct MappingTraits<MachineFrameInfo> {
static void mapping(IO &YamlIO, MachineFrameInfo &MFI) {
- YamlIO.mapOptional("isFrameAddressTaken", MFI.IsFrameAddressTaken);
- YamlIO.mapOptional("isReturnAddressTaken", MFI.IsReturnAddressTaken);
- YamlIO.mapOptional("hasStackMap", MFI.HasStackMap);
- YamlIO.mapOptional("hasPatchPoint", MFI.HasPatchPoint);
- YamlIO.mapOptional("stackSize", MFI.StackSize);
- YamlIO.mapOptional("offsetAdjustment", MFI.OffsetAdjustment);
- YamlIO.mapOptional("maxAlignment", MFI.MaxAlignment);
- YamlIO.mapOptional("adjustsStack", MFI.AdjustsStack);
- YamlIO.mapOptional("hasCalls", MFI.HasCalls);
+ YamlIO.mapOptional("isFrameAddressTaken", MFI.IsFrameAddressTaken, false);
+ YamlIO.mapOptional("isReturnAddressTaken", MFI.IsReturnAddressTaken, false);
+ YamlIO.mapOptional("hasStackMap", MFI.HasStackMap, false);
+ YamlIO.mapOptional("hasPatchPoint", MFI.HasPatchPoint, false);
+ YamlIO.mapOptional("stackSize", MFI.StackSize, (uint64_t)0);
+ YamlIO.mapOptional("offsetAdjustment", MFI.OffsetAdjustment, (int)0);
+ YamlIO.mapOptional("maxAlignment", MFI.MaxAlignment, (unsigned)0);
+ YamlIO.mapOptional("adjustsStack", MFI.AdjustsStack, false);
+ YamlIO.mapOptional("hasCalls", MFI.HasCalls, false);
YamlIO.mapOptional("stackProtector", MFI.StackProtector,
StringValue()); // Don't print it out when it's empty.
- YamlIO.mapOptional("maxCallFrameSize", MFI.MaxCallFrameSize);
- YamlIO.mapOptional("hasOpaqueSPAdjustment", MFI.HasOpaqueSPAdjustment);
- YamlIO.mapOptional("hasVAStart", MFI.HasVAStart);
- YamlIO.mapOptional("hasMustTailInVarArgFunc", MFI.HasMustTailInVarArgFunc);
+ YamlIO.mapOptional("maxCallFrameSize", MFI.MaxCallFrameSize, (unsigned)~0);
+ YamlIO.mapOptional("hasOpaqueSPAdjustment", MFI.HasOpaqueSPAdjustment,
+ false);
+ YamlIO.mapOptional("hasVAStart", MFI.HasVAStart, false);
+ YamlIO.mapOptional("hasMustTailInVarArgFunc", MFI.HasMustTailInVarArgFunc,
+ false);
YamlIO.mapOptional("savePoint", MFI.SavePoint,
StringValue()); // Don't print it out when it's empty.
YamlIO.mapOptional("restorePoint", MFI.RestorePoint,
@@ -403,22 +457,28 @@ struct MachineFunction {
template <> struct MappingTraits<MachineFunction> {
static void mapping(IO &YamlIO, MachineFunction &MF) {
YamlIO.mapRequired("name", MF.Name);
- YamlIO.mapOptional("alignment", MF.Alignment);
- YamlIO.mapOptional("exposesReturnsTwice", MF.ExposesReturnsTwice);
- YamlIO.mapOptional("legalized", MF.Legalized);
- YamlIO.mapOptional("regBankSelected", MF.RegBankSelected);
- YamlIO.mapOptional("selected", MF.Selected);
- YamlIO.mapOptional("tracksRegLiveness", MF.TracksRegLiveness);
- YamlIO.mapOptional("registers", MF.VirtualRegisters);
- YamlIO.mapOptional("liveins", MF.LiveIns);
- YamlIO.mapOptional("calleeSavedRegisters", MF.CalleeSavedRegisters);
- YamlIO.mapOptional("frameInfo", MF.FrameInfo);
- YamlIO.mapOptional("fixedStack", MF.FixedStackObjects);
- YamlIO.mapOptional("stack", MF.StackObjects);
- YamlIO.mapOptional("constants", MF.Constants);
+ YamlIO.mapOptional("alignment", MF.Alignment, (unsigned)0);
+ YamlIO.mapOptional("exposesReturnsTwice", MF.ExposesReturnsTwice, false);
+ YamlIO.mapOptional("legalized", MF.Legalized, false);
+ YamlIO.mapOptional("regBankSelected", MF.RegBankSelected, false);
+ YamlIO.mapOptional("selected", MF.Selected, false);
+ YamlIO.mapOptional("tracksRegLiveness", MF.TracksRegLiveness, false);
+ YamlIO.mapOptional("registers", MF.VirtualRegisters,
+ std::vector<VirtualRegisterDefinition>());
+ YamlIO.mapOptional("liveins", MF.LiveIns,
+ std::vector<MachineFunctionLiveIn>());
+ YamlIO.mapOptional("calleeSavedRegisters", MF.CalleeSavedRegisters,
+ Optional<std::vector<FlowStringValue>>());
+ YamlIO.mapOptional("frameInfo", MF.FrameInfo, MachineFrameInfo());
+ YamlIO.mapOptional("fixedStack", MF.FixedStackObjects,
+ std::vector<FixedMachineStackObject>());
+ YamlIO.mapOptional("stack", MF.StackObjects,
+ std::vector<MachineStackObject>());
+ YamlIO.mapOptional("constants", MF.Constants,
+ std::vector<MachineConstantPoolValue>());
if (!YamlIO.outputting() || !MF.JumpTableInfo.Entries.empty())
- YamlIO.mapOptional("jumpTable", MF.JumpTableInfo);
- YamlIO.mapOptional("body", MF.Body);
+ YamlIO.mapOptional("jumpTable", MF.JumpTableInfo, MachineJumpTable());
+ YamlIO.mapOptional("body", MF.Body, BlockStringValue());
}
};
diff --git a/contrib/llvm/include/llvm/CodeGen/MachineBasicBlock.h b/contrib/llvm/include/llvm/CodeGen/MachineBasicBlock.h
index f3f5e32..97a49ce 100644
--- a/contrib/llvm/include/llvm/CodeGen/MachineBasicBlock.h
+++ b/contrib/llvm/include/llvm/CodeGen/MachineBasicBlock.h
@@ -1,4 +1,4 @@
-//===-- llvm/CodeGen/MachineBasicBlock.h ------------------------*- C++ -*-===//
+//===- llvm/CodeGen/MachineBasicBlock.h -------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -15,41 +15,50 @@
#define LLVM_CODEGEN_MACHINEBASICBLOCK_H
#include "llvm/ADT/GraphTraits.h"
+#include "llvm/ADT/ilist.h"
+#include "llvm/ADT/ilist_node.h"
#include "llvm/ADT/iterator_range.h"
-#include "llvm/CodeGen/MachineInstrBundleIterator.h"
+#include "llvm/ADT/simple_ilist.h"
#include "llvm/CodeGen/MachineInstr.h"
-#include "llvm/Support/BranchProbability.h"
+#include "llvm/CodeGen/MachineInstrBundleIterator.h"
+#include "llvm/IR/DebugLoc.h"
#include "llvm/MC/LaneBitmask.h"
#include "llvm/MC/MCRegisterInfo.h"
-#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/BranchProbability.h"
+#include <cassert>
+#include <cstdint>
#include <functional>
+#include <iterator>
+#include <string>
+#include <vector>
namespace llvm {
-class Pass;
class BasicBlock;
class MachineFunction;
class MCSymbol;
-class MIPrinter;
+class ModuleSlotTracker;
+class Pass;
class SlotIndexes;
class StringRef;
class raw_ostream;
-class MachineBranchProbabilityInfo;
+class TargetRegisterClass;
+class TargetRegisterInfo;
template <> struct ilist_traits<MachineInstr> {
private:
friend class MachineBasicBlock; // Set by the owning MachineBasicBlock.
+
MachineBasicBlock *Parent;
- typedef simple_ilist<MachineInstr, ilist_sentinel_tracking<true>>::iterator
- instr_iterator;
+ using instr_iterator =
+ simple_ilist<MachineInstr, ilist_sentinel_tracking<true>>::iterator;
public:
void addNodeToList(MachineInstr *N);
void removeNodeFromList(MachineInstr *N);
void transferNodesFromList(ilist_traits &OldList, instr_iterator First,
instr_iterator Last);
-
void deleteNode(MachineInstr *MI);
};
@@ -69,7 +78,8 @@ public:
};
private:
- typedef ilist<MachineInstr, ilist_sentinel_tracking<true>> Instructions;
+ using Instructions = ilist<MachineInstr, ilist_sentinel_tracking<true>>;
+
Instructions Insts;
const BasicBlock *BB;
int Number;
@@ -83,12 +93,12 @@ private:
/// same order as Successors, or it is empty if we don't use it (disable
/// optimization).
std::vector<BranchProbability> Probs;
- typedef std::vector<BranchProbability>::iterator probability_iterator;
- typedef std::vector<BranchProbability>::const_iterator
- const_probability_iterator;
+ using probability_iterator = std::vector<BranchProbability>::iterator;
+ using const_probability_iterator =
+ std::vector<BranchProbability>::const_iterator;
/// Keep track of the physical registers that are livein of the basicblock.
- typedef std::vector<RegisterMaskPair> LiveInVector;
+ using LiveInVector = std::vector<RegisterMaskPair>;
LiveInVector LiveIns;
/// Alignment of the basic block. Zero if the basic block does not need to be
@@ -113,7 +123,7 @@ private:
mutable MCSymbol *CachedMCSymbol = nullptr;
// Intrusive list support
- MachineBasicBlock() {}
+ MachineBasicBlock() = default;
explicit MachineBasicBlock(MachineFunction &MF, const BasicBlock *BB);
@@ -128,7 +138,7 @@ public:
/// to an LLVM basic block.
const BasicBlock *getBasicBlock() const { return BB; }
- /// Return the name of the corresponding LLVM basic block, or "(null)".
+ /// Return the name of the corresponding LLVM basic block, or an empty string.
StringRef getName() const;
/// Return a formatted string to identify this block and its parent function.
@@ -145,16 +155,16 @@ public:
const MachineFunction *getParent() const { return xParent; }
MachineFunction *getParent() { return xParent; }
- typedef Instructions::iterator instr_iterator;
- typedef Instructions::const_iterator const_instr_iterator;
- typedef Instructions::reverse_iterator reverse_instr_iterator;
- typedef Instructions::const_reverse_iterator const_reverse_instr_iterator;
+ using instr_iterator = Instructions::iterator;
+ using const_instr_iterator = Instructions::const_iterator;
+ using reverse_instr_iterator = Instructions::reverse_iterator;
+ using const_reverse_instr_iterator = Instructions::const_reverse_iterator;
- typedef MachineInstrBundleIterator<MachineInstr> iterator;
- typedef MachineInstrBundleIterator<const MachineInstr> const_iterator;
- typedef MachineInstrBundleIterator<MachineInstr, true> reverse_iterator;
- typedef MachineInstrBundleIterator<const MachineInstr, true>
- const_reverse_iterator;
+ using iterator = MachineInstrBundleIterator<MachineInstr>;
+ using const_iterator = MachineInstrBundleIterator<const MachineInstr>;
+ using reverse_iterator = MachineInstrBundleIterator<MachineInstr, true>;
+ using const_reverse_iterator =
+ MachineInstrBundleIterator<const MachineInstr, true>;
unsigned size() const { return (unsigned)Insts.size(); }
bool empty() const { return Insts.empty(); }
@@ -178,8 +188,8 @@ public:
reverse_instr_iterator instr_rend () { return Insts.rend(); }
const_reverse_instr_iterator instr_rend () const { return Insts.rend(); }
- typedef iterator_range<instr_iterator> instr_range;
- typedef iterator_range<const_instr_iterator> const_instr_range;
+ using instr_range = iterator_range<instr_iterator>;
+ using const_instr_range = iterator_range<const_instr_iterator>;
instr_range instrs() { return instr_range(instr_begin(), instr_end()); }
const_instr_range instrs() const {
return const_instr_range(instr_begin(), instr_end());
@@ -213,18 +223,18 @@ public:
}
// Machine-CFG iterators
- typedef std::vector<MachineBasicBlock *>::iterator pred_iterator;
- typedef std::vector<MachineBasicBlock *>::const_iterator const_pred_iterator;
- typedef std::vector<MachineBasicBlock *>::iterator succ_iterator;
- typedef std::vector<MachineBasicBlock *>::const_iterator const_succ_iterator;
- typedef std::vector<MachineBasicBlock *>::reverse_iterator
- pred_reverse_iterator;
- typedef std::vector<MachineBasicBlock *>::const_reverse_iterator
- const_pred_reverse_iterator;
- typedef std::vector<MachineBasicBlock *>::reverse_iterator
- succ_reverse_iterator;
- typedef std::vector<MachineBasicBlock *>::const_reverse_iterator
- const_succ_reverse_iterator;
+ using pred_iterator = std::vector<MachineBasicBlock *>::iterator;
+ using const_pred_iterator = std::vector<MachineBasicBlock *>::const_iterator;
+ using succ_iterator = std::vector<MachineBasicBlock *>::iterator;
+ using const_succ_iterator = std::vector<MachineBasicBlock *>::const_iterator;
+ using pred_reverse_iterator =
+ std::vector<MachineBasicBlock *>::reverse_iterator;
+ using const_pred_reverse_iterator =
+ std::vector<MachineBasicBlock *>::const_reverse_iterator;
+ using succ_reverse_iterator =
+ std::vector<MachineBasicBlock *>::reverse_iterator;
+ using const_succ_reverse_iterator =
+ std::vector<MachineBasicBlock *>::const_reverse_iterator;
pred_iterator pred_begin() { return Predecessors.begin(); }
const_pred_iterator pred_begin() const { return Predecessors.begin(); }
pred_iterator pred_end() { return Predecessors.end(); }
@@ -307,7 +317,7 @@ public:
// Iteration support for live in sets. These sets are kept in sorted
// order by their register number.
- typedef LiveInVector::const_iterator livein_iterator;
+ using livein_iterator = LiveInVector::const_iterator;
#ifndef NDEBUG
/// Unlike livein_begin, this method does not check that the liveness
/// information is accurate. Still for debug purposes it may be useful
@@ -325,6 +335,9 @@ public:
return make_range(livein_begin(), livein_end());
}
+ /// Remove entry from the livein set and return iterator to the next.
+ livein_iterator removeLiveIn(livein_iterator I);
+
/// Get the clobber mask for the start of this basic block. Funclets use this
/// to prevent register allocation across funclet transitions.
const uint32_t *getBeginClobberMask(const TargetRegisterInfo *TRI) const;
@@ -363,6 +376,9 @@ public:
/// Indicates if this is the entry block of a cleanup funclet.
void setIsCleanupFuncletEntry(bool V = true) { IsCleanupFuncletEntry = V; }
+ /// Returns true if it is legal to hoist instructions into this block.
+ bool isLegalToHoistInto() const;
+
// Code Layout methods.
/// Move 'this' block before or after the specified block. This only moves
@@ -455,10 +471,18 @@ public:
/// other block.
bool isLayoutSuccessor(const MachineBasicBlock *MBB) const;
- /// Return true if the block can implicitly transfer control to the block
- /// after it by falling off the end of it. This should return false if it can
- /// reach the block after it, but it uses an explicit branch to do so (e.g., a
- /// table jump). True is a conservative answer.
+ /// Return the fallthrough block if the block can implicitly
+ /// transfer control to the block after it by falling off the end of
+ /// it. This should return null if it can reach the block after
+ /// it, but it uses an explicit branch to do so (e.g., a table
+ /// jump). Non-null return is a conservative answer.
+ MachineBasicBlock *getFallThrough();
+
+ /// Return true if the block can implicitly transfer control to the
+ /// block after it by falling off the end of it. This should return
+ /// false if it can reach the block after it, but it uses an
+ /// explicit branch to do so (e.g., a table jump). True is a
+ /// conservative answer.
bool canFallThrough();
/// Returns a pointer to the first instruction in this block that is not a
@@ -664,6 +688,10 @@ public:
return findDebugLoc(MBBI.getInstrIterator());
}
+ /// Find and return the merged DebugLoc of the branch instructions of the
+ /// block. Return UnknownLoc if there is none.
+ DebugLoc findBranchDebugLoc();
+
/// Possible outcome of a register liveness query to computeRegisterLiveness()
enum LivenessQueryResult {
LQR_Live, ///< Register is known to be (at least partially) live.
@@ -682,7 +710,7 @@ public:
LivenessQueryResult computeRegisterLiveness(const TargetRegisterInfo *TRI,
unsigned Reg,
const_iterator Before,
- unsigned Neighborhood=10) const;
+ unsigned Neighborhood = 10) const;
// Debugging methods.
void dump() const;
@@ -701,7 +729,6 @@ public:
/// Return the MCSymbol for this basic block.
MCSymbol *getSymbol() const;
-
private:
/// Return probability iterator corresponding to the I successor iterator.
probability_iterator getProbabilityIterator(succ_iterator I);
@@ -751,8 +778,8 @@ struct MBB2NumberFunctor :
//
template <> struct GraphTraits<MachineBasicBlock *> {
- typedef MachineBasicBlock *NodeRef;
- typedef MachineBasicBlock::succ_iterator ChildIteratorType;
+ using NodeRef = MachineBasicBlock *;
+ using ChildIteratorType = MachineBasicBlock::succ_iterator;
static NodeRef getEntryNode(MachineBasicBlock *BB) { return BB; }
static ChildIteratorType child_begin(NodeRef N) { return N->succ_begin(); }
@@ -760,8 +787,8 @@ template <> struct GraphTraits<MachineBasicBlock *> {
};
template <> struct GraphTraits<const MachineBasicBlock *> {
- typedef const MachineBasicBlock *NodeRef;
- typedef MachineBasicBlock::const_succ_iterator ChildIteratorType;
+ using NodeRef = const MachineBasicBlock *;
+ using ChildIteratorType = MachineBasicBlock::const_succ_iterator;
static NodeRef getEntryNode(const MachineBasicBlock *BB) { return BB; }
static ChildIteratorType child_begin(NodeRef N) { return N->succ_begin(); }
@@ -774,28 +801,30 @@ template <> struct GraphTraits<const MachineBasicBlock *> {
// to be when traversing the predecessor edges of a MBB
// instead of the successor edges.
//
-template <> struct GraphTraits<Inverse<MachineBasicBlock*> > {
- typedef MachineBasicBlock *NodeRef;
- typedef MachineBasicBlock::pred_iterator ChildIteratorType;
+template <> struct GraphTraits<Inverse<MachineBasicBlock*>> {
+ using NodeRef = MachineBasicBlock *;
+ using ChildIteratorType = MachineBasicBlock::pred_iterator;
+
static NodeRef getEntryNode(Inverse<MachineBasicBlock *> G) {
return G.Graph;
}
+
static ChildIteratorType child_begin(NodeRef N) { return N->pred_begin(); }
static ChildIteratorType child_end(NodeRef N) { return N->pred_end(); }
};
-template <> struct GraphTraits<Inverse<const MachineBasicBlock*> > {
- typedef const MachineBasicBlock *NodeRef;
- typedef MachineBasicBlock::const_pred_iterator ChildIteratorType;
+template <> struct GraphTraits<Inverse<const MachineBasicBlock*>> {
+ using NodeRef = const MachineBasicBlock *;
+ using ChildIteratorType = MachineBasicBlock::const_pred_iterator;
+
static NodeRef getEntryNode(Inverse<const MachineBasicBlock *> G) {
return G.Graph;
}
+
static ChildIteratorType child_begin(NodeRef N) { return N->pred_begin(); }
static ChildIteratorType child_end(NodeRef N) { return N->pred_end(); }
};
-
-
/// MachineInstrSpan provides an interface to get an iteration range
/// containing the instruction it was initialized with, along with all
/// those instructions inserted prior to or following that instruction
@@ -803,6 +832,7 @@ template <> struct GraphTraits<Inverse<const MachineBasicBlock*> > {
class MachineInstrSpan {
MachineBasicBlock &MBB;
MachineBasicBlock::iterator I, B, E;
+
public:
MachineInstrSpan(MachineBasicBlock::iterator I)
: MBB(*I->getParent()),
@@ -841,6 +871,6 @@ inline IterT skipDebugInstructionsBackward(IterT It, IterT Begin) {
return It;
}
-} // End llvm namespace
+} // end namespace llvm
-#endif
+#endif // LLVM_CODEGEN_MACHINEBASICBLOCK_H
diff --git a/contrib/llvm/include/llvm/CodeGen/MachineBlockFrequencyInfo.h b/contrib/llvm/include/llvm/CodeGen/MachineBlockFrequencyInfo.h
index bfa5bf6..cba79c8 100644
--- a/contrib/llvm/include/llvm/CodeGen/MachineBlockFrequencyInfo.h
+++ b/contrib/llvm/include/llvm/CodeGen/MachineBlockFrequencyInfo.h
@@ -1,4 +1,4 @@
-//===- MachineBlockFrequencyInfo.h - MBB Frequency Analysis -*- C++ -*-----===//
+//===- MachineBlockFrequencyInfo.h - MBB Frequency Analysis -----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -17,31 +17,39 @@
#include "llvm/ADT/Optional.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/Support/BlockFrequency.h"
-#include <climits>
+#include <cstdint>
+#include <memory>
namespace llvm {
+template <class BlockT> class BlockFrequencyInfoImpl;
class MachineBasicBlock;
class MachineBranchProbabilityInfo;
-template <class BlockT> class BlockFrequencyInfoImpl;
+class MachineFunction;
+class MachineLoopInfo;
+class raw_ostream;
/// MachineBlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation
/// to estimate machine basic block frequencies.
class MachineBlockFrequencyInfo : public MachineFunctionPass {
- typedef BlockFrequencyInfoImpl<MachineBasicBlock> ImplType;
+ using ImplType = BlockFrequencyInfoImpl<MachineBasicBlock>;
std::unique_ptr<ImplType> MBFI;
public:
static char ID;
MachineBlockFrequencyInfo();
-
~MachineBlockFrequencyInfo() override;
void getAnalysisUsage(AnalysisUsage &AU) const override;
bool runOnMachineFunction(MachineFunction &F) override;
+ /// calculate - compute block frequency info for the given function.
+ void calculate(const MachineFunction &F,
+ const MachineBranchProbabilityInfo &MBPI,
+ const MachineLoopInfo &MLI);
+
void releaseMemory() override;
/// getblockFreq - Return block frequency. Return 0 if we don't have the
@@ -56,7 +64,7 @@ public:
const MachineFunction *getFunction() const;
const MachineBranchProbabilityInfo *getMBPI() const;
- void view() const;
+ void view(const Twine &Name, bool isSimple = true) const;
// Print the block frequency Freq to OS using the current functions entry
// frequency to convert freq into a relative decimal form.
@@ -68,9 +76,8 @@ public:
const MachineBasicBlock *MBB) const;
uint64_t getEntryFreq() const;
-
};
-}
+} // end namespace llvm
-#endif
+#endif // LLVM_CODEGEN_MACHINEBLOCKFREQUENCYINFO_H
diff --git a/contrib/llvm/include/llvm/CodeGen/MachineCombinerPattern.h b/contrib/llvm/include/llvm/CodeGen/MachineCombinerPattern.h
index 1123801..8c54ae9 100644
--- a/contrib/llvm/include/llvm/CodeGen/MachineCombinerPattern.h
+++ b/contrib/llvm/include/llvm/CodeGen/MachineCombinerPattern.h
@@ -48,6 +48,8 @@ enum class MachineCombinerPattern {
FMULADDD_OP2,
FMULSUBD_OP1,
FMULSUBD_OP2,
+ FNMULSUBS_OP1,
+ FNMULSUBD_OP1,
FMLAv1i32_indexed_OP1,
FMLAv1i32_indexed_OP2,
FMLAv1i64_indexed_OP1,
diff --git a/contrib/llvm/include/llvm/CodeGen/MachineConstantPool.h b/contrib/llvm/include/llvm/CodeGen/MachineConstantPool.h
index d2036c4..1705a0f 100644
--- a/contrib/llvm/include/llvm/CodeGen/MachineConstantPool.h
+++ b/contrib/llvm/include/llvm/CodeGen/MachineConstantPool.h
@@ -1,4 +1,4 @@
-//===-- CodeGen/MachineConstantPool.h - Abstract Constant Pool --*- C++ -*-===//
+//===- CodeGen/MachineConstantPool.h - Abstract Constant Pool ---*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -18,29 +18,28 @@
#include "llvm/ADT/DenseSet.h"
#include "llvm/MC/SectionKind.h"
-#include <cassert>
#include <climits>
#include <vector>
namespace llvm {
class Constant;
-class FoldingSetNodeID;
class DataLayout;
-class TargetMachine;
-class Type;
+class FoldingSetNodeID;
class MachineConstantPool;
class raw_ostream;
+class Type;
/// Abstract base class for all machine specific constantpool value subclasses.
///
class MachineConstantPoolValue {
virtual void anchor();
+
Type *Ty;
public:
explicit MachineConstantPoolValue(Type *ty) : Ty(ty) {}
- virtual ~MachineConstantPoolValue() {}
+ virtual ~MachineConstantPoolValue() = default;
/// getType - get type of this MachineConstantPoolValue.
///
@@ -81,6 +80,7 @@ public:
: Alignment(A) {
Val.ConstVal = V;
}
+
MachineConstantPoolEntry(MachineConstantPoolValue *V, unsigned A)
: Alignment(A) {
Val.MachineCPVal = V;
@@ -153,13 +153,12 @@ public:
/// print - Used by the MachineFunction printer to print information about
/// constant pool objects. Implemented in MachineFunction.cpp
- ///
void print(raw_ostream &OS) const;
/// dump - Call print(cerr) to be called from the debugger.
void dump() const;
};
-} // End llvm namespace
+} // end namespace llvm
-#endif
+#endif // LLVM_CODEGEN_MACHINECONSTANTPOOL_H
diff --git a/contrib/llvm/include/llvm/CodeGen/MachineDominanceFrontier.h b/contrib/llvm/include/llvm/CodeGen/MachineDominanceFrontier.h
index 4131194..6efeefd 100644
--- a/contrib/llvm/include/llvm/CodeGen/MachineDominanceFrontier.h
+++ b/contrib/llvm/include/llvm/CodeGen/MachineDominanceFrontier.h
@@ -11,34 +11,36 @@
#define LLVM_CODEGEN_MACHINEDOMINANCEFRONTIER_H
#include "llvm/Analysis/DominanceFrontier.h"
+#include "llvm/Analysis/DominanceFrontierImpl.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
-
+#include "llvm/Support/GenericDomTree.h"
+#include <vector>
namespace llvm {
class MachineDominanceFrontier : public MachineFunctionPass {
ForwardDominanceFrontierBase<MachineBasicBlock> Base;
+
public:
- typedef DominatorTreeBase<MachineBasicBlock> DomTreeT;
- typedef DomTreeNodeBase<MachineBasicBlock> DomTreeNodeT;
- typedef DominanceFrontierBase<MachineBasicBlock>::DomSetType DomSetType;
- typedef DominanceFrontierBase<MachineBasicBlock>::iterator iterator;
- typedef DominanceFrontierBase<MachineBasicBlock>::const_iterator const_iterator;
+ using DomTreeT = DomTreeBase<MachineBasicBlock>;
+ using DomTreeNodeT = DomTreeNodeBase<MachineBasicBlock>;
+ using DomSetType = DominanceFrontierBase<MachineBasicBlock, false>::DomSetType;
+ using iterator = DominanceFrontierBase<MachineBasicBlock, false>::iterator;
+ using const_iterator =
+ DominanceFrontierBase<MachineBasicBlock, false>::const_iterator;
- void operator=(const MachineDominanceFrontier &) = delete;
- MachineDominanceFrontier(const MachineDominanceFrontier &) = delete;
+ MachineDominanceFrontier(const MachineDominanceFrontier &) = delete;
+ MachineDominanceFrontier &operator=(const MachineDominanceFrontier &) = delete;
- static char ID;
+ static char ID;
- MachineDominanceFrontier();
+ MachineDominanceFrontier();
- DominanceFrontierBase<MachineBasicBlock> &getBase() {
- return Base;
- }
+ DominanceFrontierBase<MachineBasicBlock, false> &getBase() { return Base; }
- inline const std::vector<MachineBasicBlock*> &getRoots() const {
- return Base.getRoots();
+ inline const std::vector<MachineBasicBlock *> &getRoots() const {
+ return Base.getRoots();
}
MachineBasicBlock *getRoot() const {
@@ -93,7 +95,7 @@ public:
return Base.compareDomSet(DS1, DS2);
}
- bool compare(DominanceFrontierBase<MachineBasicBlock> &Other) const {
+ bool compare(DominanceFrontierBase<MachineBasicBlock, false> &Other) const {
return Base.compare(Other);
}
@@ -104,6 +106,6 @@ public:
void getAnalysisUsage(AnalysisUsage &AU) const override;
};
-}
+} // end namespace llvm
-#endif
+#endif // LLVM_CODEGEN_MACHINEDOMINANCEFRONTIER_H
diff --git a/contrib/llvm/include/llvm/CodeGen/MachineDominators.h b/contrib/llvm/include/llvm/CodeGen/MachineDominators.h
index 21ecef5..8bf98f6 100644
--- a/contrib/llvm/include/llvm/CodeGen/MachineDominators.h
+++ b/contrib/llvm/include/llvm/CodeGen/MachineDominators.h
@@ -1,4 +1,4 @@
-//=- llvm/CodeGen/MachineDominators.h - Machine Dom Calculation --*- C++ -*-==//
+//==- llvm/CodeGen/MachineDominators.h - Machine Dom Calculation -*- C++ -*-==//
//
// The LLVM Compiler Infrastructure
//
@@ -16,23 +16,29 @@
#define LLVM_CODEGEN_MACHINEDOMINATORS_H
#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
-#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/Support/GenericDomTree.h"
#include "llvm/Support/GenericDomTreeConstruction.h"
+#include <cassert>
+#include <memory>
+#include <vector>
namespace llvm {
-template<>
-inline void DominatorTreeBase<MachineBasicBlock>::addRoot(MachineBasicBlock* MBB) {
+template <>
+inline void DominatorTreeBase<MachineBasicBlock, false>::addRoot(
+ MachineBasicBlock *MBB) {
this->Roots.push_back(MBB);
}
extern template class DomTreeNodeBase<MachineBasicBlock>;
-extern template class DominatorTreeBase<MachineBasicBlock>;
+extern template class DominatorTreeBase<MachineBasicBlock, false>; // DomTree
+extern template class DominatorTreeBase<MachineBasicBlock, true>; // PostDomTree
-typedef DomTreeNodeBase<MachineBasicBlock> MachineDomTreeNode;
+using MachineDomTreeNode = DomTreeNodeBase<MachineBasicBlock>;
//===-------------------------------------
/// DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to
@@ -51,6 +57,7 @@ class MachineDominatorTree : public MachineFunctionPass {
/// The splitting of a critical edge is local and thus, it is possible
/// to apply several of those changes at the same time.
mutable SmallVector<CriticalEdge, 32> CriticalEdgesToSplit;
+
/// \brief Remember all the basic blocks that are inserted during
/// edge splitting.
/// Invariant: NewBBs == all the basic blocks contained in the NewBB
@@ -60,7 +67,7 @@ class MachineDominatorTree : public MachineFunctionPass {
mutable SmallSet<MachineBasicBlock *, 32> NewBBs;
/// The DominatorTreeBase that is used to compute a normal dominator tree
- DominatorTreeBase<MachineBasicBlock>* DT;
+ std::unique_ptr<DomTreeBase<MachineBasicBlock>> DT;
/// \brief Apply all the recorded critical edges to the DT.
/// This updates the underlying DT information in a way that uses
@@ -74,9 +81,8 @@ public:
MachineDominatorTree();
- ~MachineDominatorTree() override;
-
- DominatorTreeBase<MachineBasicBlock> &getBase() {
+ DomTreeBase<MachineBasicBlock> &getBase() {
+ if (!DT) DT.reset(new DomTreeBase<MachineBasicBlock>());
applySplitCriticalEdges();
return *DT;
}
@@ -244,21 +250,6 @@ public:
CriticalEdgesToSplit.push_back({FromBB, ToBB, NewBB});
}
- /// \brief Returns *false* if the other dominator tree matches this dominator
- /// tree.
- inline bool compare(const MachineDominatorTree &Other) const {
- const MachineDomTreeNode *R = getRootNode();
- const MachineDomTreeNode *OtherR = Other.getRootNode();
-
- if (!R || !OtherR || R->getBlock() != OtherR->getBlock())
- return true;
-
- if (DT->compare(*Other.DT))
- return true;
-
- return false;
- }
-
/// \brief Verify the correctness of the domtree by re-computing it.
///
/// This should only be used for debugging as it aborts the program if the
@@ -273,8 +264,8 @@ public:
template <class Node, class ChildIterator>
struct MachineDomTreeGraphTraitsBase {
- typedef Node *NodeRef;
- typedef ChildIterator ChildIteratorType;
+ using NodeRef = Node *;
+ using ChildIteratorType = ChildIterator;
static NodeRef getEntryNode(NodeRef N) { return N; }
static ChildIteratorType child_begin(NodeRef N) { return N->begin(); }
@@ -301,6 +292,6 @@ template <> struct GraphTraits<MachineDominatorTree*>
}
};
-}
+} // end namespace llvm
-#endif
+#endif // LLVM_CODEGEN_MACHINEDOMINATORS_H
diff --git a/contrib/llvm/include/llvm/CodeGen/MachineFrameInfo.h b/contrib/llvm/include/llvm/CodeGen/MachineFrameInfo.h
index 4600c2c..689f3cd 100644
--- a/contrib/llvm/include/llvm/CodeGen/MachineFrameInfo.h
+++ b/contrib/llvm/include/llvm/CodeGen/MachineFrameInfo.h
@@ -21,15 +21,9 @@
namespace llvm {
class raw_ostream;
-class DataLayout;
-class TargetRegisterClass;
-class Type;
class MachineFunction;
class MachineBasicBlock;
-class TargetFrameLowering;
-class TargetMachine;
class BitVector;
-class Value;
class AllocaInst;
/// The CalleeSavedInfo class tracks the information need to locate where a
@@ -226,7 +220,7 @@ class MachineFrameInfo {
/// setup/destroy pseudo instructions (as defined in the TargetFrameInfo
/// class). This information is important for frame pointer elimination.
/// It is only valid during and after prolog/epilog code insertion.
- unsigned MaxCallFrameSize = 0;
+ unsigned MaxCallFrameSize = ~0u;
/// The prolog/epilog code inserter fills in this vector with each
/// callee saved register saved in the frame. Beyond its use by the prolog/
@@ -526,12 +520,29 @@ public:
bool hasTailCall() const { return HasTailCall; }
void setHasTailCall() { HasTailCall = true; }
+ /// Computes the maximum size of a callframe and the AdjustsStack property.
+ /// This only works for targets defining
+ /// TargetInstrInfo::getCallFrameSetupOpcode(), getCallFrameDestroyOpcode(),
+ /// and getFrameSize().
+ /// This is usually computed by the prologue epilogue inserter but some
+ /// targets may call this to compute it earlier.
+ void computeMaxCallFrameSize(const MachineFunction &MF);
+
/// Return the maximum size of a call frame that must be
/// allocated for an outgoing function call. This is only available if
/// CallFrameSetup/Destroy pseudo instructions are used by the target, and
/// then only during or after prolog/epilog code insertion.
///
- unsigned getMaxCallFrameSize() const { return MaxCallFrameSize; }
+ unsigned getMaxCallFrameSize() const {
+ // TODO: Enable this assert when targets are fixed.
+ //assert(isMaxCallFrameSizeComputed() && "MaxCallFrameSize not computed yet");
+ if (!isMaxCallFrameSizeComputed())
+ return 0;
+ return MaxCallFrameSize;
+ }
+ bool isMaxCallFrameSizeComputed() const {
+ return MaxCallFrameSize != ~0u;
+ }
void setMaxCallFrameSize(unsigned S) { MaxCallFrameSize = S; }
/// Create a new object at a fixed location on the stack.
@@ -559,8 +570,7 @@ public:
return Objects[ObjectIdx+NumFixedObjects].isAliased;
}
- /// isImmutableObjectIndex - Returns true if the specified index corresponds
- /// to an immutable object.
+ /// Returns true if the specified index corresponds to an immutable object.
bool isImmutableObjectIndex(int ObjectIdx) const {
// Tail calling functions can clobber their function arguments.
if (HasTailCall)
@@ -570,6 +580,13 @@ public:
return Objects[ObjectIdx+NumFixedObjects].isImmutable;
}
+ /// Marks the immutability of an object.
+ void setIsImmutableObjectIndex(int ObjectIdx, bool Immutable) {
+ assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
+ "Invalid Object Idx!");
+ Objects[ObjectIdx+NumFixedObjects].isImmutable = Immutable;
+ }
+
/// Returns true if the specified index corresponds to a spill slot.
bool isSpillSlotObjectIndex(int ObjectIdx) const {
assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
diff --git a/contrib/llvm/include/llvm/CodeGen/MachineFunction.h b/contrib/llvm/include/llvm/CodeGen/MachineFunction.h
index 0c21b32..010d703 100644
--- a/contrib/llvm/include/llvm/CodeGen/MachineFunction.h
+++ b/contrib/llvm/include/llvm/CodeGen/MachineFunction.h
@@ -1,4 +1,4 @@
-//===-- llvm/CodeGen/MachineFunction.h --------------------------*- C++ -*-===//
+//===- llvm/CodeGen/MachineFunction.h ---------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -18,38 +18,61 @@
#ifndef LLVM_CODEGEN_MACHINEFUNCTION_H
#define LLVM_CODEGEN_MACHINEFUNCTION_H
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/BitVector.h"
-#include "llvm/ADT/ilist.h"
+#include "llvm/ADT/DenseMap.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"
#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineMemOperand.h"
#include "llvm/IR/DebugLoc.h"
+#include "llvm/IR/Instructions.h"
#include "llvm/IR/Metadata.h"
#include "llvm/MC/MCDwarf.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Support/Allocator.h"
#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 <cassert>
+#include <cstdint>
+#include <memory>
+#include <utility>
+#include <vector>
namespace llvm {
-class Value;
+class BasicBlock;
+class BlockAddress;
+class DataLayout;
+class DIExpression;
+class DILocalVariable;
+class DILocation;
class Function;
-class GCModuleInfo;
-class MachineRegisterInfo;
-class MachineFrameInfo;
+class GlobalValue;
class MachineConstantPool;
+class MachineFrameInfo;
+class MachineFunction;
class MachineJumpTableInfo;
class MachineModuleInfo;
+class MachineRegisterInfo;
class MCContext;
+class MCInstrDesc;
class Pass;
class PseudoSourceValueManager;
+class raw_ostream;
+class SlotIndexes;
class TargetMachine;
-class TargetSubtargetInfo;
class TargetRegisterClass;
-struct MachinePointerInfo;
+class TargetSubtargetInfo;
struct WinEHFuncInfo;
template <> struct ilist_alloc_traits<MachineBasicBlock> {
@@ -137,27 +160,33 @@ public:
bool hasProperty(Property P) const {
return Properties[static_cast<unsigned>(P)];
}
+
MachineFunctionProperties &set(Property P) {
Properties.set(static_cast<unsigned>(P));
return *this;
}
+
MachineFunctionProperties &reset(Property P) {
Properties.reset(static_cast<unsigned>(P));
return *this;
}
+
/// Reset all the properties.
MachineFunctionProperties &reset() {
Properties.reset();
return *this;
}
+
MachineFunctionProperties &set(const MachineFunctionProperties &MFP) {
Properties |= MFP.Properties;
return *this;
}
+
MachineFunctionProperties &reset(const MachineFunctionProperties &MFP) {
Properties.reset(MFP.Properties);
return *this;
}
+
// Returns true if all properties set in V (i.e. required by a pass) are set
// in this.
bool verifyRequiredProperties(const MachineFunctionProperties &V) const {
@@ -180,18 +209,17 @@ struct SEHHandler {
const BlockAddress *RecoverBA;
};
-
/// This structure is used to retain landing pad info for the current function.
struct LandingPadInfo {
MachineBasicBlock *LandingPadBlock; // Landing pad block.
SmallVector<MCSymbol *, 1> BeginLabels; // Labels prior to invoke.
SmallVector<MCSymbol *, 1> EndLabels; // Labels after invoke.
SmallVector<SEHHandler, 1> SEHHandlers; // SEH handlers active at this lpad.
- MCSymbol *LandingPadLabel; // Label at beginning of landing pad.
- std::vector<int> TypeIds; // List of type ids (filters negative).
+ MCSymbol *LandingPadLabel = nullptr; // Label at beginning of landing pad.
+ std::vector<int> TypeIds; // List of type ids (filters negative).
explicit LandingPadInfo(MachineBasicBlock *MBB)
- : LandingPadBlock(MBB), LandingPadLabel(nullptr) {}
+ : LandingPadBlock(MBB) {}
};
class MachineFunction {
@@ -239,7 +267,7 @@ class MachineFunction {
Recycler<MachineBasicBlock> BasicBlockRecycler;
// List of machine basic blocks in function
- typedef ilist<MachineBasicBlock> BasicBlockListType;
+ using BasicBlockListType = ilist<MachineBasicBlock>;
BasicBlockListType BasicBlocks;
/// FunctionNumber - This provides a unique ID for each function emitted in
@@ -281,7 +309,7 @@ class MachineFunction {
std::vector<LandingPadInfo> LandingPads;
/// Map a landing pad's EH symbol to the call site indexes.
- DenseMap<MCSymbol*, SmallVector<unsigned, 4> > LPadToCallSiteMap;
+ DenseMap<MCSymbol*, SmallVector<unsigned, 4>> LPadToCallSiteMap;
/// Map of invoke call site index values to associated begin EH_LABEL.
DenseMap<MCSymbol*, unsigned> CallSiteMap;
@@ -303,9 +331,6 @@ class MachineFunction {
/// \}
- MachineFunction(const MachineFunction &) = delete;
- void operator=(const MachineFunction&) = delete;
-
/// Clear all the members of this MachineFunction, but the ones used
/// to initialize again the MachineFunction.
/// More specifically, this deallocates all the dynamically allocated
@@ -316,8 +341,8 @@ class MachineFunction {
/// In particular, the XXXInfo data structure.
/// \pre Fn, Target, MMI, and FunctionNumber are properly set.
void init();
-public:
+public:
struct VariableDbgInfo {
const DILocalVariable *Var;
const DIExpression *Expr;
@@ -328,11 +353,13 @@ public:
unsigned Slot, const DILocation *Loc)
: Var(Var), Expr(Expr), Slot(Slot), Loc(Loc) {}
};
- typedef SmallVector<VariableDbgInfo, 4> VariableDbgInfoMapTy;
+ using VariableDbgInfoMapTy = SmallVector<VariableDbgInfo, 4>;
VariableDbgInfoMapTy VariableDbgInfos;
MachineFunction(const Function *Fn, const TargetMachine &TM,
unsigned FunctionNum, MachineModuleInfo &MMI);
+ MachineFunction(const MachineFunction &) = delete;
+ MachineFunction &operator=(const MachineFunction &) = delete;
~MachineFunction();
/// Reset the instance as if it was just created.
@@ -350,19 +377,15 @@ public:
const DataLayout &getDataLayout() const;
/// getFunction - Return the LLVM function that this machine code represents
- ///
const Function *getFunction() const { return Fn; }
/// getName - Return the name of the corresponding LLVM function.
- ///
StringRef getName() const;
/// getFunctionNumber - Return a unique ID for the current function.
- ///
unsigned getFunctionNumber() const { return FunctionNumber; }
/// getTarget - Return the target machine this machine code is compiled with
- ///
const TargetMachine &getTarget() const { return Target; }
/// getSubtarget - Return the subtarget for which this machine code is being
@@ -378,14 +401,12 @@ public:
}
/// getRegInfo - Return information about the registers currently in use.
- ///
MachineRegisterInfo &getRegInfo() { return *RegInfo; }
const MachineRegisterInfo &getRegInfo() const { return *RegInfo; }
/// getFrameInfo - Return the frame info object for the current function.
/// This object contains information about objects allocated on the stack
/// frame of the current function in an abstract way.
- ///
MachineFrameInfo &getFrameInfo() { return *FrameInfo; }
const MachineFrameInfo &getFrameInfo() const { return *FrameInfo; }
@@ -402,7 +423,6 @@ public:
/// getConstantPool - Return the constant pool object for the current
/// function.
- ///
MachineConstantPool *getConstantPool() { return ConstantPool; }
const MachineConstantPool *getConstantPool() const { return ConstantPool; }
@@ -413,11 +433,9 @@ public:
WinEHFuncInfo *getWinEHFuncInfo() { return WinEHInfo; }
/// getAlignment - Return the alignment (log2, not bytes) of the function.
- ///
unsigned getAlignment() const { return Alignment; }
/// setAlignment - Set the alignment (log2, not bytes) of the function.
- ///
void setAlignment(unsigned A) { Alignment = A; }
/// ensureAlignment - Make sure the function is at least 1 << A bytes aligned.
@@ -475,9 +493,8 @@ public:
/// getBlockNumbered - MachineBasicBlocks are automatically numbered when they
/// are inserted into the machine function. The block number for a machine
- /// basic block can be found by using the MBB::getBlockNumber method, this
- /// method provides the inverse mapping.
- ///
+ /// basic block can be found by using the MBB::getNumber method, this method
+ /// provides the inverse mapping.
MachineBasicBlock *getBlockNumbered(unsigned N) const {
assert(N < MBBNumbering.size() && "Illegal block number");
assert(MBBNumbering[N] && "Block was removed from the machine function!");
@@ -488,7 +505,6 @@ public:
bool shouldSplitStack() const;
/// getNumBlockIDs - Return the number of MBB ID's allocated.
- ///
unsigned getNumBlockIDs() const { return (unsigned)MBBNumbering.size(); }
/// RenumberBlocks - This discards all of the MachineBasicBlock numbers and
@@ -500,7 +516,6 @@ public:
/// print - Print out the MachineFunction in a format suitable for debugging
/// to the specified stream.
- ///
void print(raw_ostream &OS, const SlotIndexes* = nullptr) const;
/// viewCFG - This function is meant for use from the debugger. You can just
@@ -508,7 +523,6 @@ public:
/// program, displaying the CFG of the current function with the code for each
/// basic block inside. This depends on there being a 'dot' and 'gv' program
/// in your path.
- ///
void viewCFG() const;
/// viewCFGOnly - This function is meant for use from the debugger. It works
@@ -519,7 +533,6 @@ public:
void viewCFGOnly() const;
/// dump - Print the current MachineFunction to cerr, useful for debugger use.
- ///
void dump() const;
/// Run the current MachineFunction through the machine code verifier, useful
@@ -529,10 +542,10 @@ public:
bool AbortOnError = true) const;
// Provide accessors for the MachineBasicBlock list...
- typedef BasicBlockListType::iterator iterator;
- typedef BasicBlockListType::const_iterator const_iterator;
- typedef BasicBlockListType::const_reverse_iterator const_reverse_iterator;
- typedef BasicBlockListType::reverse_iterator reverse_iterator;
+ using iterator = BasicBlockListType::iterator;
+ using const_iterator = BasicBlockListType::const_iterator;
+ using const_reverse_iterator = BasicBlockListType::const_reverse_iterator;
+ using reverse_iterator = BasicBlockListType::reverse_iterator;
/// Support for MachineBasicBlock::getNextNode().
static BasicBlockListType MachineFunction::*
@@ -591,11 +604,9 @@ public:
//===--------------------------------------------------------------------===//
// Internal functions used to automatically number MachineBasicBlocks
- //
/// \brief Adds the MBB to the internal numbering. Returns the unique number
/// assigned to the MBB.
- ///
unsigned addToMBBNumbering(MachineBasicBlock *MBB) {
MBBNumbering.push_back(MBB);
return (unsigned)MBBNumbering.size()-1;
@@ -611,7 +622,6 @@ public:
/// CreateMachineInstr - Allocate a new MachineInstr. Use this instead
/// of `new MachineInstr'.
- ///
MachineInstr *CreateMachineInstr(const MCInstrDesc &MCID, const DebugLoc &DL,
bool NoImp = false);
@@ -624,16 +634,13 @@ public:
MachineInstr *CloneMachineInstr(const MachineInstr *Orig);
/// DeleteMachineInstr - Delete the given MachineInstr.
- ///
void DeleteMachineInstr(MachineInstr *MI);
/// CreateMachineBasicBlock - Allocate a new MachineBasicBlock. Use this
/// instead of `new MachineBasicBlock'.
- ///
MachineBasicBlock *CreateMachineBasicBlock(const BasicBlock *bb = nullptr);
/// DeleteMachineBasicBlock - Delete the given MachineBasicBlock.
- ///
void DeleteMachineBasicBlock(MachineBasicBlock *MBB);
/// getMachineMemOperand - Allocate a new MachineMemOperand.
@@ -643,7 +650,7 @@ public:
MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, uint64_t s,
unsigned base_alignment, const AAMDNodes &AAInfo = AAMDNodes(),
const MDNode *Ranges = nullptr,
- SynchronizationScope SynchScope = CrossThread,
+ SyncScope::ID SSID = SyncScope::System,
AtomicOrdering Ordering = AtomicOrdering::NotAtomic,
AtomicOrdering FailureOrdering = AtomicOrdering::NotAtomic);
@@ -654,7 +661,13 @@ public:
MachineMemOperand *getMachineMemOperand(const MachineMemOperand *MMO,
int64_t Offset, uint64_t Size);
- typedef ArrayRecycler<MachineOperand>::Capacity OperandCapacity;
+ /// Allocate a new MachineMemOperand by copying an existing one,
+ /// replacing only AliasAnalysis information. MachineMemOperands are owned
+ /// by the MachineFunction and need not be explicitly deallocated.
+ MachineMemOperand *getMachineMemOperand(const MachineMemOperand *MMO,
+ const AAMDNodes &AAInfo);
+
+ using OperandCapacity = ArrayRecycler<MachineOperand>::Capacity;
/// Allocate an array of MachineOperands. This is only intended for use by
/// internal MachineInstr functions.
@@ -701,7 +714,6 @@ public:
//===--------------------------------------------------------------------===//
// Label Manipulation.
- //
/// getJTISymbol - Return the MCSymbol for the specified non-empty jump table.
/// If isLinkerPrivate is specified, an 'l' label is returned, otherwise a
@@ -859,13 +871,16 @@ template <> struct GraphTraits<MachineFunction*> :
static NodeRef getEntryNode(MachineFunction *F) { return &F->front(); }
// nodes_iterator/begin/end - Allow iteration over all nodes in the graph
- typedef pointer_iterator<MachineFunction::iterator> nodes_iterator;
+ using nodes_iterator = pointer_iterator<MachineFunction::iterator>;
+
static nodes_iterator nodes_begin(MachineFunction *F) {
return nodes_iterator(F->begin());
}
+
static nodes_iterator nodes_end(MachineFunction *F) {
return nodes_iterator(F->end());
}
+
static unsigned size (MachineFunction *F) { return F->size(); }
};
template <> struct GraphTraits<const MachineFunction*> :
@@ -873,37 +888,39 @@ template <> struct GraphTraits<const MachineFunction*> :
static NodeRef getEntryNode(const MachineFunction *F) { return &F->front(); }
// nodes_iterator/begin/end - Allow iteration over all nodes in the graph
- typedef pointer_iterator<MachineFunction::const_iterator> nodes_iterator;
+ using nodes_iterator = pointer_iterator<MachineFunction::const_iterator>;
+
static nodes_iterator nodes_begin(const MachineFunction *F) {
return nodes_iterator(F->begin());
}
+
static nodes_iterator nodes_end (const MachineFunction *F) {
return nodes_iterator(F->end());
}
+
static unsigned size (const MachineFunction *F) {
return F->size();
}
};
-
// Provide specializations of GraphTraits to be able to treat a function as a
// graph of basic blocks... and to walk it in inverse order. Inverse order for
// a function is considered to be when traversing the predecessor edges of a BB
// instead of the successor edges.
//
-template <> struct GraphTraits<Inverse<MachineFunction*> > :
- public GraphTraits<Inverse<MachineBasicBlock*> > {
+template <> struct GraphTraits<Inverse<MachineFunction*>> :
+ public GraphTraits<Inverse<MachineBasicBlock*>> {
static NodeRef getEntryNode(Inverse<MachineFunction *> G) {
return &G.Graph->front();
}
};
-template <> struct GraphTraits<Inverse<const MachineFunction*> > :
- public GraphTraits<Inverse<const MachineBasicBlock*> > {
+template <> struct GraphTraits<Inverse<const MachineFunction*>> :
+ public GraphTraits<Inverse<const MachineBasicBlock*>> {
static NodeRef getEntryNode(Inverse<const MachineFunction *> G) {
return &G.Graph->front();
}
};
-} // End llvm namespace
+} // end namespace llvm
-#endif
+#endif // LLVM_CODEGEN_MACHINEFUNCTION_H
diff --git a/contrib/llvm/include/llvm/CodeGen/MachineFunctionInitializer.h b/contrib/llvm/include/llvm/CodeGen/MachineFunctionInitializer.h
deleted file mode 100644
index ff4c29c..0000000
--- a/contrib/llvm/include/llvm/CodeGen/MachineFunctionInitializer.h
+++ /dev/null
@@ -1,38 +0,0 @@
-//===- MachineFunctionInitalizer.h - machine function initializer ---------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file declares an interface that allows custom machine function
-// initialization.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CODEGEN_MACHINEFUNCTIONINITIALIZER_H
-#define LLVM_CODEGEN_MACHINEFUNCTIONINITIALIZER_H
-
-namespace llvm {
-
-class MachineFunction;
-
-/// This interface provides a way to initialize machine functions after they are
-/// created by the machine function analysis pass.
-class MachineFunctionInitializer {
- virtual void anchor();
-
-public:
- virtual ~MachineFunctionInitializer() {}
-
- /// Initialize the machine function.
- ///
- /// Return true if error occurred.
- virtual bool initializeMachineFunction(MachineFunction &MF) = 0;
-};
-
-} // end namespace llvm
-
-#endif
diff --git a/contrib/llvm/include/llvm/CodeGen/MachineFunctionPass.h b/contrib/llvm/include/llvm/CodeGen/MachineFunctionPass.h
index 653d117..6d978da 100644
--- a/contrib/llvm/include/llvm/CodeGen/MachineFunctionPass.h
+++ b/contrib/llvm/include/llvm/CodeGen/MachineFunctionPass.h
@@ -19,8 +19,8 @@
#ifndef LLVM_CODEGEN_MACHINEFUNCTIONPASS_H
#define LLVM_CODEGEN_MACHINEFUNCTIONPASS_H
-#include "llvm/Pass.h"
#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/Pass.h"
namespace llvm {
diff --git a/contrib/llvm/include/llvm/CodeGen/MachineInstr.h b/contrib/llvm/include/llvm/CodeGen/MachineInstr.h
index bac93e5..b87aff1 100644
--- a/contrib/llvm/include/llvm/CodeGen/MachineInstr.h
+++ b/contrib/llvm/include/llvm/CodeGen/MachineInstr.h
@@ -1,4 +1,4 @@
-//===-- llvm/CodeGen/MachineInstr.h - MachineInstr class --------*- C++ -*-===//
+//===- llvm/CodeGen/MachineInstr.h - MachineInstr class ---------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -17,7 +17,6 @@
#define LLVM_CODEGEN_MACHINEINSTR_H
#include "llvm/ADT/DenseMapInfo.h"
-#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/ilist.h"
#include "llvm/ADT/ilist_node.h"
#include "llvm/ADT/iterator_range.h"
@@ -28,19 +27,27 @@
#include "llvm/MC/MCInstrDesc.h"
#include "llvm/Support/ArrayRecycler.h"
#include "llvm/Target/TargetOpcodes.h"
+#include <algorithm>
+#include <cassert>
+#include <cstdint>
+#include <utility>
namespace llvm {
-class StringRef;
template <typename T> class ArrayRef;
-template <typename T> class SmallVectorImpl;
-class DILocalVariable;
class DIExpression;
+class DILocalVariable;
+class MachineBasicBlock;
+class MachineFunction;
+class MachineMemOperand;
+class MachineRegisterInfo;
+class ModuleSlotTracker;
+class raw_ostream;
+template <typename T> class SmallVectorImpl;
+class StringRef;
class TargetInstrInfo;
class TargetRegisterClass;
class TargetRegisterInfo;
-class MachineFunction;
-class MachineMemOperand;
//===----------------------------------------------------------------------===//
/// Representation of each machine instruction.
@@ -53,7 +60,7 @@ class MachineInstr
: public ilist_node_with_parent<MachineInstr, MachineBasicBlock,
ilist_sentinel_tracking<true>> {
public:
- typedef MachineMemOperand **mmo_iterator;
+ using mmo_iterator = MachineMemOperand **;
/// Flags to specify different kinds of comments to output in
/// assembly code. These flags carry semantic information not
@@ -72,43 +79,39 @@ public:
BundledPred = 1 << 2, // Instruction has bundled predecessors.
BundledSucc = 1 << 3 // Instruction has bundled successors.
};
+
private:
const MCInstrDesc *MCID; // Instruction descriptor.
- MachineBasicBlock *Parent; // Pointer to the owning basic block.
+ MachineBasicBlock *Parent = nullptr; // Pointer to the owning basic block.
// Operands are allocated by an ArrayRecycler.
- MachineOperand *Operands; // Pointer to the first operand.
- unsigned NumOperands; // Number of operands on instruction.
- typedef ArrayRecycler<MachineOperand>::Capacity OperandCapacity;
+ 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.
- uint8_t Flags; // Various bits of additional
+ uint8_t Flags = 0; // Various bits of additional
// information about machine
// instruction.
- uint8_t AsmPrinterFlags; // Various bits of information used by
+ uint8_t AsmPrinterFlags = 0; // Various bits of information used by
// the AsmPrinter to emit helpful
// comments. This is *not* semantic
// information. Do not use this for
// anything other than to convey comment
// information to AsmPrinter.
- uint8_t NumMemRefs; // Information on memory references.
+ uint8_t NumMemRefs = 0; // Information on memory references.
// Note that MemRefs == nullptr, means 'don't know', not 'no memory access'.
// Calling code must treat missing information conservatively. If the number
// of memory operands required to be precise exceeds the maximum value of
// NumMemRefs - currently 256 - we remove the operands entirely. Note also
// that this is a non-owning reference to a shared copy on write buffer owned
// by the MachineFunction and created via MF.allocateMemRefsArray.
- mmo_iterator MemRefs;
+ mmo_iterator MemRefs = nullptr;
DebugLoc debugLoc; // Source line information.
- MachineInstr(const MachineInstr&) = delete;
- void operator=(const MachineInstr&) = delete;
- // Use MachineFunction::DeleteMachineInstr() instead.
- ~MachineInstr() = delete;
-
// Intrusive list support
friend struct ilist_traits<MachineInstr>;
friend struct ilist_callback_traits<MachineBasicBlock>;
@@ -128,6 +131,11 @@ private:
friend class MachineFunction;
public:
+ MachineInstr(const MachineInstr &) = delete;
+ MachineInstr &operator=(const MachineInstr &) = delete;
+ // Use MachineFunction::DeleteMachineInstr() instead.
+ ~MachineInstr() = delete;
+
const MachineBasicBlock* getParent() const { return Parent; }
MachineBasicBlock* getParent() { return Parent; }
@@ -178,7 +186,6 @@ public:
Flags &= ~((uint8_t)Flag);
}
-
/// Return true if MI is in a bundle (but not the first MI in a bundle).
///
/// A bundle looks like this before it's finalized:
@@ -263,7 +270,6 @@ public:
/// earlier.
///
/// If this method returns, the caller should try to recover from the error.
- ///
void emitError(StringRef Msg) const;
/// Returns the target instruction descriptor of this MachineInstr.
@@ -273,7 +279,6 @@ public:
unsigned getOpcode() const { return MCID->Opcode; }
/// Access to explicit operands of the instruction.
- ///
unsigned getNumOperands() const { return NumOperands; }
const MachineOperand& getOperand(unsigned i) const {
@@ -289,8 +294,8 @@ public:
unsigned getNumExplicitOperands() const;
/// iterator/begin/end - Iterate over all operands of a machine instruction.
- typedef MachineOperand *mop_iterator;
- typedef const MachineOperand *const_mop_iterator;
+ using mop_iterator = MachineOperand *;
+ using const_mop_iterator = const MachineOperand *;
mop_iterator operands_begin() { return Operands; }
mop_iterator operands_end() { return Operands + NumOperands; }
@@ -374,6 +379,9 @@ public:
return NumMemRefs == 1;
}
+ /// Return the number of memory operands.
+ unsigned getNumMemOperands() const { return NumMemRefs; }
+
/// API for querying MachineInstr properties. They are the same as MCInstrDesc
/// queries but they are bundle aware.
@@ -713,7 +721,6 @@ public:
return hasProperty(MCID::ExtraDefRegAllocReq, Type);
}
-
enum MICheckType {
CheckDefs, // Check all operands for equality
CheckKillDead, // Check all operands including kill / dead markers
@@ -767,6 +774,7 @@ public:
/// Returns true if the MachineInstr represents a label.
bool isLabel() const { return isEHLabel() || isGCLabel(); }
+
bool isCFIInstruction() const {
return getOpcode() == TargetOpcode::CFI_INSTRUCTION;
}
@@ -775,6 +783,7 @@ public:
bool isPosition() const { return isLabel() || isCFIInstruction(); }
bool isDebugValue() const { return getOpcode() == TargetOpcode::DBG_VALUE; }
+
/// A DBG_VALUE is indirect iff the first operand is a register and
/// the second operand is an immediate.
bool isIndirectDebugValue() const {
@@ -787,29 +796,38 @@ public:
bool isKill() const { return getOpcode() == TargetOpcode::KILL; }
bool isImplicitDef() const { return getOpcode()==TargetOpcode::IMPLICIT_DEF; }
bool isInlineAsm() const { return getOpcode() == TargetOpcode::INLINEASM; }
+
bool isMSInlineAsm() const {
return getOpcode() == TargetOpcode::INLINEASM && getInlineAsmDialect();
}
+
bool isStackAligningInlineAsm() const;
InlineAsm::AsmDialect getInlineAsmDialect() const;
+
bool isInsertSubreg() const {
return getOpcode() == TargetOpcode::INSERT_SUBREG;
}
+
bool isSubregToReg() const {
return getOpcode() == TargetOpcode::SUBREG_TO_REG;
}
+
bool isRegSequence() const {
return getOpcode() == TargetOpcode::REG_SEQUENCE;
}
+
bool isBundle() const {
return getOpcode() == TargetOpcode::BUNDLE;
}
+
bool isCopy() const {
return getOpcode() == TargetOpcode::COPY;
}
+
bool isFullCopy() const {
return isCopy() && !getOperand(0).getSubReg() && !getOperand(1).getSubReg();
}
+
bool isExtractSubreg() const {
return getOpcode() == TargetOpcode::EXTRACT_SUBREG;
}
@@ -826,26 +844,35 @@ public:
getOperand(0).getSubReg() == getOperand(1).getSubReg();
}
- /// Return true if this is a transient instruction that is
- /// either very likely to be eliminated during register allocation (such as
- /// copy-like instructions), or if this instruction doesn't have an
- /// execution-time cost.
+ /// Return true if this instruction doesn't produce any output in the form of
+ /// executable instructions.
+ bool isMetaInstruction() const {
+ switch (getOpcode()) {
+ default:
+ return false;
+ case TargetOpcode::IMPLICIT_DEF:
+ case TargetOpcode::KILL:
+ case TargetOpcode::CFI_INSTRUCTION:
+ case TargetOpcode::EH_LABEL:
+ case TargetOpcode::GC_LABEL:
+ case TargetOpcode::DBG_VALUE:
+ return true;
+ }
+ }
+
+ /// Return true if this is a transient instruction that is either very likely
+ /// to be eliminated during register allocation (such as copy-like
+ /// instructions), or if this instruction doesn't have an execution-time cost.
bool isTransient() const {
- switch(getOpcode()) {
- default: return false;
+ switch (getOpcode()) {
+ default:
+ return isMetaInstruction();
// Copy-like instructions are usually eliminated during register allocation.
case TargetOpcode::PHI:
case TargetOpcode::COPY:
case TargetOpcode::INSERT_SUBREG:
case TargetOpcode::SUBREG_TO_REG:
case TargetOpcode::REG_SEQUENCE:
- // Pseudo-instructions that don't produce any real output.
- case TargetOpcode::IMPLICIT_DEF:
- case TargetOpcode::KILL:
- case TargetOpcode::CFI_INSTRUCTION:
- case TargetOpcode::EH_LABEL:
- case TargetOpcode::GC_LABEL:
- case TargetOpcode::DBG_VALUE:
return true;
}
}
@@ -969,7 +996,6 @@ public:
///
/// The flag operand is an immediate that can be decoded with methods like
/// InlineAsm::hasRegClassConstraint().
- ///
int findInlineAsmFlagIdx(unsigned OpIdx, unsigned *GroupNo = nullptr) const;
/// Compute the static register class constraint for operand OpIdx.
@@ -978,7 +1004,6 @@ public:
///
/// Returns NULL if the static register class constraint cannot be
/// determined.
- ///
const TargetRegisterClass*
getRegClassConstraint(unsigned OpIdx,
const TargetInstrInfo *TII,
@@ -1108,6 +1133,18 @@ public:
/// the instruction's location and its intended destination.
bool isSafeToMove(AliasAnalysis *AA, bool &SawStore) const;
+ /// Returns true if this instruction's memory access aliases the memory
+ /// access of Other.
+ //
+ /// Assumes any physical registers used to compute addresses
+ /// have the same value for both instructions. Returns false if neither
+ /// instruction writes to memory.
+ ///
+ /// @param AA Optional alias analysis, used to compare memory operands.
+ /// @param Other MachineInstr to check aliasing against.
+ /// @param UseTBAA Whether to pass TBAA information to alias analysis.
+ bool mayAlias(AliasAnalysis *AA, MachineInstr &Other, bool UseTBAA);
+
/// Return true if this instruction may have an ordered
/// or volatile memory reference, or if the information describing the memory
/// reference is not available. Return false if it is known to have no
@@ -1146,14 +1183,21 @@ public:
/// instruction to this instruction.
void copyImplicitOps(MachineFunction &MF, const MachineInstr &MI);
- //
- // Debugging support
- //
- void print(raw_ostream &OS, bool SkipOpers = false,
+ /// Debugging support
+ /// @{
+ /// Print this MI to \p OS.
+ /// Only print the defs and the opcode if \p SkipOpers is true.
+ /// Otherwise, also print operands if \p SkipDebugLoc is true.
+ /// Otherwise, also print the debug loc, with a terminating newline.
+ /// \p TII is used to print the opcode name. If it's not present, but the
+ /// MI is in a function, the opcode will be printed using the function's TII.
+ void print(raw_ostream &OS, bool SkipOpers = false, bool SkipDebugLoc = false,
const TargetInstrInfo *TII = nullptr) const;
void print(raw_ostream &OS, ModuleSlotTracker &MST, bool SkipOpers = false,
+ bool SkipDebugLoc = false,
const TargetInstrInfo *TII = nullptr) const;
- void dump(const TargetInstrInfo *TII = nullptr) const;
+ void dump() const;
+ /// @}
//===--------------------------------------------------------------------===//
// Accessors used to build up machine instructions.
@@ -1300,6 +1344,6 @@ inline raw_ostream& operator<<(raw_ostream &OS, const MachineInstr &MI) {
return OS;
}
-} // End llvm namespace
+} // end namespace llvm
-#endif
+#endif // LLVM_CODEGEN_MACHINEINSTR_H
diff --git a/contrib/llvm/include/llvm/CodeGen/MachineInstrBuilder.h b/contrib/llvm/include/llvm/CodeGen/MachineInstrBuilder.h
index 3c8a362..412c55d 100644
--- a/contrib/llvm/include/llvm/CodeGen/MachineInstrBuilder.h
+++ b/contrib/llvm/include/llvm/CodeGen/MachineInstrBuilder.h
@@ -1,4 +1,4 @@
-//===-- CodeGen/MachineInstBuilder.h - Simplify creation of MIs -*- C++ -*-===//
+//===- CodeGen/MachineInstrBuilder.h - Simplify creation of MIs --*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -19,9 +19,18 @@
#ifndef LLVM_CODEGEN_MACHINEINSTRBUILDER_H
#define LLVM_CODEGEN_MACHINEINSTRBUILDER_H
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrBundle.h"
+#include "llvm/CodeGen/MachineOperand.h"
+#include "llvm/IR/InstrTypes.h"
+#include "llvm/IR/Intrinsics.h"
#include "llvm/Support/ErrorHandling.h"
+#include <cassert>
+#include <cstdint>
+#include <utility>
namespace llvm {
@@ -29,6 +38,7 @@ class MCInstrDesc;
class MDNode;
namespace RegState {
+
enum {
Define = 0x2,
Implicit = 0x4,
@@ -42,13 +52,15 @@ namespace RegState {
ImplicitDefine = Implicit | Define,
ImplicitKill = Implicit | Kill
};
-}
+
+} // end namespace RegState
class MachineInstrBuilder {
- MachineFunction *MF;
- MachineInstr *MI;
+ MachineFunction *MF = nullptr;
+ MachineInstr *MI = nullptr;
+
public:
- MachineInstrBuilder() : MF(nullptr), MI(nullptr) {}
+ MachineInstrBuilder() = default;
/// Create a MachineInstrBuilder for manipulating an existing instruction.
/// F must be the machine function that was used to allocate I.
@@ -187,11 +199,18 @@ public:
return *this;
}
- const MachineInstrBuilder &addOperand(const MachineOperand &MO) const {
+ const MachineInstrBuilder &add(const MachineOperand &MO) const {
MI->addOperand(*MF, MO);
return *this;
}
+ const MachineInstrBuilder &add(ArrayRef<MachineOperand> MOs) const {
+ for (const MachineOperand &MO : MOs) {
+ MI->addOperand(*MF, MO);
+ }
+ return *this;
+ }
+
const MachineInstrBuilder &addMetadata(const MDNode *MD) const {
MI->addOperand(*MF, MachineOperand::CreateMetadata(MD));
assert((MI->isDebugValue() ? static_cast<bool>(MI->getDebugVariable())
@@ -394,6 +413,11 @@ MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
unsigned Reg, unsigned Offset,
const MDNode *Variable, const MDNode *Expr);
+/// Clone a DBG_VALUE whose value has been spilled to FrameIndex.
+MachineInstr *buildDbgValueForSpill(MachineBasicBlock &BB,
+ MachineBasicBlock::iterator I,
+ const MachineInstr &Orig, int FrameIndex);
+
inline unsigned getDefRegState(bool B) {
return B ? RegState::Define : 0;
}
@@ -511,6 +535,6 @@ public:
}
};
-} // End llvm namespace
+} // end namespace llvm
-#endif
+#endif // LLVM_CODEGEN_MACHINEINSTRBUILDER_H
diff --git a/contrib/llvm/include/llvm/CodeGen/MachineInstrBundleIterator.h b/contrib/llvm/include/llvm/CodeGen/MachineInstrBundleIterator.h
index 3104185..5fe4964 100644
--- a/contrib/llvm/include/llvm/CodeGen/MachineInstrBundleIterator.h
+++ b/contrib/llvm/include/llvm/CodeGen/MachineInstrBundleIterator.h
@@ -15,34 +15,37 @@
#define LLVM_CODEGEN_MACHINEINSTRBUNDLEITERATOR_H
#include "llvm/ADT/ilist.h"
+#include "llvm/ADT/simple_ilist.h"
+#include <cassert>
#include <iterator>
+#include <type_traits>
namespace llvm {
template <class T, bool IsReverse> struct MachineInstrBundleIteratorTraits;
template <class T> struct MachineInstrBundleIteratorTraits<T, false> {
- typedef simple_ilist<T, ilist_sentinel_tracking<true>> list_type;
- typedef typename list_type::iterator instr_iterator;
- typedef typename list_type::iterator nonconst_instr_iterator;
- typedef typename list_type::const_iterator const_instr_iterator;
+ using list_type = simple_ilist<T, ilist_sentinel_tracking<true>>;
+ using instr_iterator = typename list_type::iterator;
+ using nonconst_instr_iterator = typename list_type::iterator;
+ using const_instr_iterator = typename list_type::const_iterator;
};
template <class T> struct MachineInstrBundleIteratorTraits<T, true> {
- typedef simple_ilist<T, ilist_sentinel_tracking<true>> list_type;
- typedef typename list_type::reverse_iterator instr_iterator;
- typedef typename list_type::reverse_iterator nonconst_instr_iterator;
- typedef typename list_type::const_reverse_iterator const_instr_iterator;
+ using list_type = simple_ilist<T, ilist_sentinel_tracking<true>>;
+ using instr_iterator = typename list_type::reverse_iterator;
+ using nonconst_instr_iterator = typename list_type::reverse_iterator;
+ using const_instr_iterator = typename list_type::const_reverse_iterator;
};
template <class T> struct MachineInstrBundleIteratorTraits<const T, false> {
- typedef simple_ilist<T, ilist_sentinel_tracking<true>> list_type;
- typedef typename list_type::const_iterator instr_iterator;
- typedef typename list_type::iterator nonconst_instr_iterator;
- typedef typename list_type::const_iterator const_instr_iterator;
+ using list_type = simple_ilist<T, ilist_sentinel_tracking<true>>;
+ using instr_iterator = typename list_type::const_iterator;
+ using nonconst_instr_iterator = typename list_type::iterator;
+ using const_instr_iterator = typename list_type::const_iterator;
};
template <class T> struct MachineInstrBundleIteratorTraits<const T, true> {
- typedef simple_ilist<T, ilist_sentinel_tracking<true>> list_type;
- typedef typename list_type::const_reverse_iterator instr_iterator;
- typedef typename list_type::reverse_iterator nonconst_instr_iterator;
- typedef typename list_type::const_reverse_iterator const_instr_iterator;
+ using list_type = simple_ilist<T, ilist_sentinel_tracking<true>>;
+ using instr_iterator = typename list_type::const_reverse_iterator;
+ using nonconst_instr_iterator = typename list_type::reverse_iterator;
+ using const_instr_iterator = typename list_type::const_reverse_iterator;
};
template <bool IsReverse> struct MachineInstrBundleIteratorHelper;
@@ -104,27 +107,27 @@ template <> struct MachineInstrBundleIteratorHelper<true> {
/// inside bundles (i.e. walk top level MIs only).
template <typename Ty, bool IsReverse = false>
class MachineInstrBundleIterator : MachineInstrBundleIteratorHelper<IsReverse> {
- typedef MachineInstrBundleIteratorTraits<Ty, IsReverse> Traits;
- typedef typename Traits::instr_iterator instr_iterator;
+ using Traits = MachineInstrBundleIteratorTraits<Ty, IsReverse>;
+ using instr_iterator = typename Traits::instr_iterator;
+
instr_iterator MII;
public:
- typedef typename instr_iterator::value_type value_type;
- typedef typename instr_iterator::difference_type difference_type;
- typedef typename instr_iterator::pointer pointer;
- typedef typename instr_iterator::reference reference;
- typedef std::bidirectional_iterator_tag iterator_category;
-
- typedef typename instr_iterator::const_pointer const_pointer;
- typedef typename instr_iterator::const_reference const_reference;
+ using value_type = typename instr_iterator::value_type;
+ using difference_type = typename instr_iterator::difference_type;
+ using pointer = typename instr_iterator::pointer;
+ using reference = typename instr_iterator::reference;
+ using const_pointer = typename instr_iterator::const_pointer;
+ using const_reference = typename instr_iterator::const_reference;
+ using iterator_category = std::bidirectional_iterator_tag;
private:
- typedef typename Traits::nonconst_instr_iterator nonconst_instr_iterator;
- typedef typename Traits::const_instr_iterator const_instr_iterator;
- typedef MachineInstrBundleIterator<
- typename nonconst_instr_iterator::value_type, IsReverse>
- nonconst_iterator;
- typedef MachineInstrBundleIterator<Ty, !IsReverse> reverse_iterator;
+ using nonconst_instr_iterator = typename Traits::nonconst_instr_iterator;
+ using const_instr_iterator = typename Traits::const_instr_iterator;
+ using nonconst_iterator =
+ MachineInstrBundleIterator<typename nonconst_instr_iterator::value_type,
+ IsReverse>;
+ using reverse_iterator = MachineInstrBundleIterator<Ty, !IsReverse>;
public:
MachineInstrBundleIterator(instr_iterator MI) : MII(MI) {
@@ -138,12 +141,14 @@ public:
"MachineInstrBundleIterator with a "
"bundled MI");
}
+
MachineInstrBundleIterator(pointer MI) : MII(MI) {
// FIXME: This conversion should be explicit.
assert((!MI || !MI->isBundledWithPred()) && "It's not legal to initialize "
"MachineInstrBundleIterator "
"with a bundled MI");
}
+
// Template allows conversion from const to nonconst.
template <class OtherTy>
MachineInstrBundleIterator(
@@ -151,6 +156,7 @@ public:
typename std::enable_if<std::is_convertible<OtherTy *, Ty *>::value,
void *>::type = nullptr)
: MII(I.getInstrIterator()) {}
+
MachineInstrBundleIterator() : MII(nullptr) {}
/// Explicit conversion between forward/reverse iterators.
@@ -280,4 +286,4 @@ public:
} // end namespace llvm
-#endif
+#endif // LLVM_CODEGEN_MACHINEINSTRBUNDLEITERATOR_H
diff --git a/contrib/llvm/include/llvm/CodeGen/MachineLoopInfo.h b/contrib/llvm/include/llvm/CodeGen/MachineLoopInfo.h
index dc72ae1..58cffaa 100644
--- a/contrib/llvm/include/llvm/CodeGen/MachineLoopInfo.h
+++ b/contrib/llvm/include/llvm/CodeGen/MachineLoopInfo.h
@@ -33,6 +33,8 @@
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/IR/DebugLoc.h"
+#include "llvm/Pass.h"
namespace llvm {
@@ -60,10 +62,18 @@ public:
/// multiple exiting blocks are present.
MachineBasicBlock *findLoopControlBlock();
+ /// Return the debug location of the start of this loop.
+ /// This looks for a BB terminating instruction with a known debug
+ /// location by looking at the preheader and header blocks. If it
+ /// cannot find a terminating instruction with location information,
+ /// it returns an unknown location.
+ DebugLoc getStartLoc() const;
+
void dump() const;
private:
friend class LoopInfoBase<MachineBasicBlock, MachineLoop>;
+
explicit MachineLoop(MachineBasicBlock *MBB)
: LoopBase<MachineBasicBlock, MachineLoop>(MBB) {}
};
@@ -72,11 +82,9 @@ private:
extern template class LoopInfoBase<MachineBasicBlock, MachineLoop>;
class MachineLoopInfo : public MachineFunctionPass {
- LoopInfoBase<MachineBasicBlock, MachineLoop> LI;
friend class LoopBase<MachineBasicBlock, MachineLoop>;
- void operator=(const MachineLoopInfo &) = delete;
- MachineLoopInfo(const MachineLoopInfo &) = delete;
+ LoopInfoBase<MachineBasicBlock, MachineLoop> LI;
public:
static char ID; // Pass identification, replacement for typeid
@@ -84,6 +92,8 @@ public:
MachineLoopInfo() : MachineFunctionPass(ID) {
initializeMachineLoopInfoPass(*PassRegistry::getPassRegistry());
}
+ MachineLoopInfo(const MachineLoopInfo &) = delete;
+ MachineLoopInfo &operator=(const MachineLoopInfo &) = delete;
LoopInfoBase<MachineBasicBlock, MachineLoop>& getBase() { return LI; }
@@ -96,7 +106,7 @@ public:
bool SpeculativePreheader = false) const;
/// The iterator interface to the top-level loops in the current function.
- typedef LoopInfoBase<MachineBasicBlock, MachineLoop>::iterator iterator;
+ using iterator = LoopInfoBase<MachineBasicBlock, MachineLoop>::iterator;
inline iterator begin() const { return LI.begin(); }
inline iterator end() const { return LI.end(); }
bool empty() const { return LI.empty(); }
@@ -159,11 +169,10 @@ public:
}
};
-
// Allow clients to walk the list of nested loops...
template <> struct GraphTraits<const MachineLoop*> {
- typedef const MachineLoop *NodeRef;
- typedef MachineLoopInfo::iterator ChildIteratorType;
+ using NodeRef = const MachineLoop *;
+ using ChildIteratorType = MachineLoopInfo::iterator;
static NodeRef getEntryNode(const MachineLoop *L) { return L; }
static ChildIteratorType child_begin(NodeRef N) { return N->begin(); }
@@ -171,14 +180,14 @@ template <> struct GraphTraits<const MachineLoop*> {
};
template <> struct GraphTraits<MachineLoop*> {
- typedef MachineLoop *NodeRef;
- typedef MachineLoopInfo::iterator ChildIteratorType;
+ using NodeRef = MachineLoop *;
+ using ChildIteratorType = MachineLoopInfo::iterator;
static NodeRef getEntryNode(MachineLoop *L) { return L; }
static ChildIteratorType child_begin(NodeRef N) { return N->begin(); }
static ChildIteratorType child_end(NodeRef N) { return N->end(); }
};
-} // End llvm namespace
+} // end namespace llvm
-#endif
+#endif // LLVM_CODEGEN_MACHINELOOPINFO_H
diff --git a/contrib/llvm/include/llvm/CodeGen/MachineMemOperand.h b/contrib/llvm/include/llvm/CodeGen/MachineMemOperand.h
index a311124..a9de0db 100644
--- a/contrib/llvm/include/llvm/CodeGen/MachineMemOperand.h
+++ b/contrib/llvm/include/llvm/CodeGen/MachineMemOperand.h
@@ -21,7 +21,7 @@
#include "llvm/CodeGen/PseudoSourceValue.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Metadata.h"
-#include "llvm/IR/Value.h" // PointerLikeTypeTraits<Value*>
+#include "llvm/IR/Value.h" // PointerLikeTypeTraits<Value*>
#include "llvm/Support/AtomicOrdering.h"
#include "llvm/Support/DataTypes.h"
@@ -59,6 +59,11 @@ struct MachinePointerInfo {
return MachinePointerInfo(V.get<const PseudoSourceValue*>(), Offset+O);
}
+ /// Return true if memory region [V, V+Offset+Size) is known to be
+ /// dereferenceable.
+ bool isDereferenceable(unsigned Size, LLVMContext &C,
+ const DataLayout &DL) const;
+
/// Return the LLVM IR address space number that this pointer points into.
unsigned getAddrSpace() const;
@@ -109,6 +114,9 @@ public:
MOInvariant = 1u << 5,
// Reserved for use by target-specific passes.
+ // Targets may override getSerializableMachineMemOperandTargetFlags() to
+ // enable MIR serialization/parsing of these flags. If more of these flags
+ // are added, the MIR printing/parsing code will need to be updated as well.
MOTargetFlag1 = 1u << 6,
MOTargetFlag2 = 1u << 7,
MOTargetFlag3 = 1u << 8,
@@ -119,8 +127,8 @@ public:
private:
/// Atomic information for this memory operation.
struct MachineAtomicInfo {
- /// Synchronization scope for this memory operation.
- unsigned SynchScope : 1; // enum SynchronizationScope
+ /// Synchronization scope ID for this memory operation.
+ unsigned SSID : 8; // SyncScope::ID
/// Atomic ordering requirements for this memory operation. For cmpxchg
/// atomic operations, atomic ordering requirements when store occurs.
unsigned Ordering : 4; // enum AtomicOrdering
@@ -147,7 +155,7 @@ public:
unsigned base_alignment,
const AAMDNodes &AAInfo = AAMDNodes(),
const MDNode *Ranges = nullptr,
- SynchronizationScope SynchScope = CrossThread,
+ SyncScope::ID SSID = SyncScope::System,
AtomicOrdering Ordering = AtomicOrdering::NotAtomic,
AtomicOrdering FailureOrdering = AtomicOrdering::NotAtomic);
@@ -197,9 +205,9 @@ public:
/// Return the range tag for the memory reference.
const MDNode *getRanges() const { return Ranges; }
- /// Return the synchronization scope for this memory operation.
- SynchronizationScope getSynchScope() const {
- return static_cast<SynchronizationScope>(AtomicInfo.SynchScope);
+ /// Returns the synchronization scope ID for this memory operation.
+ SyncScope::ID getSyncScopeID() const {
+ return static_cast<SyncScope::ID>(AtomicInfo.SSID);
}
/// Return the atomic ordering requirements for this memory operation. For
diff --git a/contrib/llvm/include/llvm/CodeGen/MachineModuleInfo.h b/contrib/llvm/include/llvm/CodeGen/MachineModuleInfo.h
index 182d23e..d64941a 100644
--- a/contrib/llvm/include/llvm/CodeGen/MachineModuleInfo.h
+++ b/contrib/llvm/include/llvm/CodeGen/MachineModuleInfo.h
@@ -31,35 +31,25 @@
#ifndef LLVM_CODEGEN_MACHINEMODULEINFO_H
#define LLVM_CODEGEN_MACHINEMODULEINFO_H
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/PointerIntPair.h"
-#include "llvm/ADT/SmallPtrSet.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/IR/DebugLoc.h"
-#include "llvm/IR/ValueHandle.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCSymbol.h"
-#include "llvm/MC/MachineLocation.h"
#include "llvm/Pass.h"
-#include "llvm/Support/DataTypes.h"
+#include <memory>
+#include <utility>
+#include <vector>
namespace llvm {
-//===----------------------------------------------------------------------===//
-// Forward declarations.
-class BlockAddress;
+class BasicBlock;
class CallInst;
-class Constant;
-class GlobalVariable;
-class LandingPadInst;
-class MDNode;
-class MMIAddrLabelMap;
-class MachineBasicBlock;
+class Function;
class MachineFunction;
-class MachineFunctionInitializer;
+class MMIAddrLabelMap;
class Module;
-class PointerType;
-class StructType;
+class TargetMachine;
//===----------------------------------------------------------------------===//
/// This class can be derived from and used by targets to hold private
@@ -69,11 +59,12 @@ class StructType;
///
class MachineModuleInfoImpl {
public:
- typedef PointerIntPair<MCSymbol*, 1, bool> StubValueTy;
+ using StubValueTy = PointerIntPair<MCSymbol *, 1, bool>;
+ using SymbolListTy = std::vector<std::pair<MCSymbol *, StubValueTy>>;
+
virtual ~MachineModuleInfoImpl();
- typedef std::vector<std::pair<MCSymbol*, StubValueTy> > SymbolListTy;
-protected:
+protected:
/// Return the entries from a DenseMap in a deterministic sorted orer.
/// Clears the map.
static SymbolListTy getSortedStubs(DenseMap<MCSymbol*, StubValueTy>&);
@@ -116,7 +107,7 @@ class MachineModuleInfo : public ImmutablePass {
// TODO: Ideally, what we'd like is to have a switch that allows emitting
// synchronous (precise at call-sites only) CFA into .eh_frame. However,
- // even under this switch, we'd like .debug_frame to be precise when using.
+ // even under this switch, we'd like .debug_frame to be precise when using
// -g. At this moment, there's no way to specify that some CFI directives
// go into .eh_frame only, while others go into .debug_frame only.
@@ -134,7 +125,6 @@ class MachineModuleInfo : public ImmutablePass {
/// comments in lib/Target/X86/X86FrameLowering.cpp for more details.
bool UsesMorestackAddr;
- MachineFunctionInitializer *MFInitializer;
/// Maps IR Functions to their corresponding MachineFunctions.
DenseMap<const Function*, std::unique_ptr<MachineFunction>> MachineFunctions;
/// Next unique number available for a MachineFunction.
@@ -158,14 +148,13 @@ public:
void setModule(const Module *M) { TheModule = M; }
const Module *getModule() const { return TheModule; }
- void setMachineFunctionInitializer(MachineFunctionInitializer *MFInit) {
- MFInitializer = MFInit;
- }
-
/// Returns the MachineFunction constructed for the IR function \p F.
- /// Creates a new MachineFunction and runs the MachineFunctionInitializer
- /// if none exists yet.
- MachineFunction &getMachineFunction(const Function &F);
+ /// Creates a new MachineFunction if none exists yet.
+ MachineFunction &getOrCreateMachineFunction(const Function &F);
+
+ /// \bried Returns the MachineFunction associated to IR function \p F if there
+ /// is one, otherwise nullptr.
+ MachineFunction *getMachineFunction(const Function &F) const;
/// Delete the MachineFunction \p MF and reset the link in the IR Function to
/// Machine Function map.
@@ -252,6 +241,6 @@ public:
/// which will link in MSVCRT's floating-point support.
void computeUsesVAFloatArgument(const CallInst &I, MachineModuleInfo &MMI);
-} // End llvm namespace
+} // end namespace llvm
-#endif
+#endif // LLVM_CODEGEN_MACHINEMODULEINFO_H
diff --git a/contrib/llvm/include/llvm/CodeGen/MachineModuleInfoImpls.h b/contrib/llvm/include/llvm/CodeGen/MachineModuleInfoImpls.h
index f9fa699..34b21ce 100644
--- a/contrib/llvm/include/llvm/CodeGen/MachineModuleInfoImpls.h
+++ b/contrib/llvm/include/llvm/CodeGen/MachineModuleInfoImpls.h
@@ -15,7 +15,9 @@
#ifndef LLVM_CODEGEN_MACHINEMODULEINFOIMPLS_H
#define LLVM_CODEGEN_MACHINEMODULEINFOIMPLS_H
+#include "llvm/BinaryFormat/Wasm.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
+#include "llvm/CodeGen/ValueTypes.h"
namespace llvm {
class MCSymbol;
diff --git a/contrib/llvm/include/llvm/CodeGen/MachineOperand.h b/contrib/llvm/include/llvm/CodeGen/MachineOperand.h
index 5df99a6..2560399 100644
--- a/contrib/llvm/include/llvm/CodeGen/MachineOperand.h
+++ b/contrib/llvm/include/llvm/CodeGen/MachineOperand.h
@@ -14,8 +14,8 @@
#ifndef LLVM_CODEGEN_MACHINEOPERAND_H
#define LLVM_CODEGEN_MACHINEOPERAND_H
-#include "llvm/Support/DataTypes.h"
#include "llvm/IR/Intrinsics.h"
+#include "llvm/Support/DataTypes.h"
#include <cassert>
namespace llvm {
@@ -229,7 +229,7 @@ public:
void print(raw_ostream &os, ModuleSlotTracker &MST,
const TargetRegisterInfo *TRI = nullptr,
const TargetIntrinsicInfo *IntrinsicInfo = nullptr) const;
- LLVM_DUMP_METHOD void dump() const;
+ void dump() const;
//===--------------------------------------------------------------------===//
// Accessors that tell you what kind of MachineOperand you're looking at.
@@ -355,7 +355,7 @@ public:
void setReg(unsigned Reg);
void setSubReg(unsigned subReg) {
- assert(isReg() && "Wrong MachineOperand accessor");
+ assert(isReg() && "Wrong MachineOperand mutator");
SubReg_TargetFlags = subReg;
assert(SubReg_TargetFlags == subReg && "SubReg out of range");
}
@@ -378,38 +378,38 @@ public:
void setIsDef(bool Val = true);
void setImplicit(bool Val = true) {
- assert(isReg() && "Wrong MachineOperand accessor");
+ assert(isReg() && "Wrong MachineOperand mutator");
IsImp = Val;
}
void setIsKill(bool Val = true) {
- assert(isReg() && !IsDef && "Wrong MachineOperand accessor");
+ assert(isReg() && !IsDef && "Wrong MachineOperand mutator");
assert((!Val || !isDebug()) && "Marking a debug operation as kill");
IsKill = Val;
}
void setIsDead(bool Val = true) {
- assert(isReg() && IsDef && "Wrong MachineOperand accessor");
+ assert(isReg() && IsDef && "Wrong MachineOperand mutator");
IsDead = Val;
}
void setIsUndef(bool Val = true) {
- assert(isReg() && "Wrong MachineOperand accessor");
+ assert(isReg() && "Wrong MachineOperand mutator");
IsUndef = Val;
}
void setIsInternalRead(bool Val = true) {
- assert(isReg() && "Wrong MachineOperand accessor");
+ assert(isReg() && "Wrong MachineOperand mutator");
IsInternalRead = Val;
}
void setIsEarlyClobber(bool Val = true) {
- assert(isReg() && IsDef && "Wrong MachineOperand accessor");
+ assert(isReg() && IsDef && "Wrong MachineOperand mutator");
IsEarlyClobber = Val;
}
void setIsDebug(bool Val = true) {
- assert(isReg() && !IsDef && "Wrong MachineOperand accessor");
+ assert(isReg() && !IsDef && "Wrong MachineOperand mutator");
IsDebug = Val;
}
@@ -538,19 +538,19 @@ public:
void setOffset(int64_t Offset) {
assert((isGlobal() || isSymbol() || isMCSymbol() || isCPI() ||
isTargetIndex() || isBlockAddress()) &&
- "Wrong MachineOperand accessor");
+ "Wrong MachineOperand mutator");
SmallContents.OffsetLo = unsigned(Offset);
Contents.OffsetedInfo.OffsetHi = int(Offset >> 32);
}
void setIndex(int Idx) {
assert((isFI() || isCPI() || isTargetIndex() || isJTI()) &&
- "Wrong MachineOperand accessor");
+ "Wrong MachineOperand mutator");
Contents.OffsetedInfo.Val.Index = Idx;
}
void setMBB(MachineBasicBlock *MBB) {
- assert(isMBB() && "Wrong MachineOperand accessor");
+ assert(isMBB() && "Wrong MachineOperand mutator");
Contents.MBB = MBB;
}
diff --git a/contrib/llvm/include/llvm/CodeGen/MachineOptimizationRemarkEmitter.h b/contrib/llvm/include/llvm/CodeGen/MachineOptimizationRemarkEmitter.h
new file mode 100644
index 0000000..6ad5de5
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/MachineOptimizationRemarkEmitter.h
@@ -0,0 +1,203 @@
+///===- MachineOptimizationRemarkEmitter.h - Opt Diagnostics -*- C++ -*----===//
+///
+/// The LLVM Compiler Infrastructure
+///
+/// This file is distributed under the University of Illinois Open Source
+/// License. See LICENSE.TXT for details.
+///
+///===---------------------------------------------------------------------===//
+/// \file
+/// Optimization diagnostic interfaces for machine passes. It's packaged as an
+/// analysis pass so that by using this service passes become dependent on MBFI
+/// as well. MBFI is used to compute the "hotness" of the diagnostic message.
+///
+///===---------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINEOPTIMIZATIONREMARKEMITTER_H
+#define LLVM_CODEGEN_MACHINEOPTIMIZATIONREMARKEMITTER_H
+
+#include "llvm/Analysis/OptimizationDiagnosticInfo.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+
+namespace llvm {
+class MachineBasicBlock;
+class MachineBlockFrequencyInfo;
+class MachineInstr;
+
+/// \brief Common features for diagnostics dealing with optimization remarks
+/// that are used by machine passes.
+class DiagnosticInfoMIROptimization : public DiagnosticInfoOptimizationBase {
+public:
+ DiagnosticInfoMIROptimization(enum DiagnosticKind Kind, const char *PassName,
+ StringRef RemarkName,
+ const DiagnosticLocation &Loc,
+ const MachineBasicBlock *MBB)
+ : DiagnosticInfoOptimizationBase(Kind, DS_Remark, PassName, RemarkName,
+ *MBB->getParent()->getFunction(), Loc),
+ MBB(MBB) {}
+
+ /// MI-specific kinds of diagnostic Arguments.
+ struct MachineArgument : public DiagnosticInfoOptimizationBase::Argument {
+ /// Print an entire MachineInstr.
+ MachineArgument(StringRef Key, const MachineInstr &MI);
+ };
+
+ static bool classof(const DiagnosticInfo *DI) {
+ return DI->getKind() >= DK_FirstMachineRemark &&
+ DI->getKind() <= DK_LastMachineRemark;
+ }
+
+ const MachineBasicBlock *getBlock() const { return MBB; }
+
+private:
+ const MachineBasicBlock *MBB;
+};
+
+/// Diagnostic information for applied optimization remarks.
+class MachineOptimizationRemark : public DiagnosticInfoMIROptimization {
+public:
+ /// \p PassName is the name of the pass emitting this diagnostic. If this name
+ /// matches the regular expression given in -Rpass=, then the diagnostic will
+ /// be emitted. \p RemarkName is a textual identifier for the remark. \p
+ /// Loc is the debug location and \p MBB is the block that the optimization
+ /// operates in.
+ MachineOptimizationRemark(const char *PassName, StringRef RemarkName,
+ const DiagnosticLocation &Loc,
+ const MachineBasicBlock *MBB)
+ : DiagnosticInfoMIROptimization(DK_MachineOptimizationRemark, PassName,
+ RemarkName, Loc, MBB) {}
+
+ static bool classof(const DiagnosticInfo *DI) {
+ return DI->getKind() == DK_MachineOptimizationRemark;
+ }
+
+ /// \see DiagnosticInfoOptimizationBase::isEnabled.
+ bool isEnabled() const override {
+ return OptimizationRemark::isEnabled(getPassName());
+ }
+};
+
+/// Diagnostic information for missed-optimization remarks.
+class MachineOptimizationRemarkMissed : public DiagnosticInfoMIROptimization {
+public:
+ /// \p PassName is the name of the pass emitting this diagnostic. If this name
+ /// matches the regular expression given in -Rpass-missed=, then the
+ /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
+ /// remark. \p Loc is the debug location and \p MBB is the block that the
+ /// optimization operates in.
+ MachineOptimizationRemarkMissed(const char *PassName, StringRef RemarkName,
+ const DiagnosticLocation &Loc,
+ const MachineBasicBlock *MBB)
+ : DiagnosticInfoMIROptimization(DK_MachineOptimizationRemarkMissed,
+ PassName, RemarkName, Loc, MBB) {}
+
+ static bool classof(const DiagnosticInfo *DI) {
+ return DI->getKind() == DK_MachineOptimizationRemarkMissed;
+ }
+
+ /// \see DiagnosticInfoOptimizationBase::isEnabled.
+ bool isEnabled() const override {
+ return OptimizationRemarkMissed::isEnabled(getPassName());
+ }
+};
+
+/// Diagnostic information for optimization analysis remarks.
+class MachineOptimizationRemarkAnalysis : public DiagnosticInfoMIROptimization {
+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
+ /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
+ /// remark. \p Loc is the debug location and \p MBB is the block that the
+ /// optimization operates in.
+ MachineOptimizationRemarkAnalysis(const char *PassName, StringRef RemarkName,
+ const DiagnosticLocation &Loc,
+ const MachineBasicBlock *MBB)
+ : DiagnosticInfoMIROptimization(DK_MachineOptimizationRemarkAnalysis,
+ PassName, RemarkName, Loc, MBB) {}
+
+ static bool classof(const DiagnosticInfo *DI) {
+ return DI->getKind() == DK_MachineOptimizationRemarkAnalysis;
+ }
+
+ /// \see DiagnosticInfoOptimizationBase::isEnabled.
+ bool isEnabled() const override {
+ return OptimizationRemarkAnalysis::isEnabled(getPassName());
+ }
+};
+
+/// Extend llvm::ore:: with MI-specific helper names.
+namespace ore {
+using MNV = DiagnosticInfoMIROptimization::MachineArgument;
+}
+
+/// The optimization diagnostic interface.
+///
+/// It allows reporting when optimizations are performed and when they are not
+/// along with the reasons for it. Hotness information of the corresponding
+/// code region can be included in the remark if DiagnosticsHotnessRequested is
+/// enabled in the LLVM context.
+class MachineOptimizationRemarkEmitter {
+public:
+ MachineOptimizationRemarkEmitter(MachineFunction &MF,
+ MachineBlockFrequencyInfo *MBFI)
+ : MF(MF), MBFI(MBFI) {}
+
+ /// Emit an optimization remark.
+ void emit(DiagnosticInfoOptimizationBase &OptDiag);
+
+ /// \brief Whether we allow for extra compile-time budget to perform more
+ /// analysis to be more informative.
+ ///
+ /// This is useful to enable additional missed optimizations to be reported
+ /// that are normally too noisy. In this mode, we can use the extra analysis
+ /// (1) to filter trivial false positives or (2) to provide more context so
+ /// that non-trivial false positives can be quickly detected by the user.
+ bool allowExtraAnalysis() const {
+ // For now, only allow this with -fsave-optimization-record since the -Rpass
+ // options are handled in the front-end.
+ return MF.getFunction()->getContext().getDiagnosticsOutputFile();
+ }
+
+private:
+ MachineFunction &MF;
+
+ /// MBFI is only set if hotness is requested.
+ MachineBlockFrequencyInfo *MBFI;
+
+ /// Compute hotness from IR value (currently assumed to be a block) if PGO is
+ /// available.
+ Optional<uint64_t> computeHotness(const MachineBasicBlock &MBB);
+
+ /// Similar but use value from \p OptDiag and update hotness there.
+ void computeHotness(DiagnosticInfoMIROptimization &Remark);
+
+ /// \brief Only allow verbose messages if we know we're filtering by hotness
+ /// (BFI is only set in this case).
+ bool shouldEmitVerbose() { return MBFI != nullptr; }
+};
+
+/// The analysis pass
+///
+/// Note that this pass shouldn't generally be marked as preserved by other
+/// passes. It's holding onto BFI, so if the pass does not preserve BFI, BFI
+/// could be freed.
+class MachineOptimizationRemarkEmitterPass : public MachineFunctionPass {
+ std::unique_ptr<MachineOptimizationRemarkEmitter> ORE;
+
+public:
+ MachineOptimizationRemarkEmitterPass();
+
+ bool runOnMachineFunction(MachineFunction &MF) override;
+
+ void getAnalysisUsage(AnalysisUsage &AU) const override;
+
+ MachineOptimizationRemarkEmitter &getORE() {
+ assert(ORE && "pass not run yet");
+ return *ORE;
+ }
+
+ static char ID;
+};
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/CodeGen/MachinePassRegistry.h b/contrib/llvm/include/llvm/CodeGen/MachinePassRegistry.h
index db914b1..3aba0bb 100644
--- a/contrib/llvm/include/llvm/CodeGen/MachinePassRegistry.h
+++ b/contrib/llvm/include/llvm/CodeGen/MachinePassRegistry.h
@@ -1,4 +1,4 @@
-//===-- llvm/CodeGen/MachinePassRegistry.h ----------------------*- C++ -*-===//
+//===- llvm/CodeGen/MachinePassRegistry.h -----------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -18,13 +18,13 @@
#ifndef LLVM_CODEGEN_MACHINEPASSREGISTRY_H
#define LLVM_CODEGEN_MACHINEPASSREGISTRY_H
+#include "llvm/ADT/StringRef.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/Support/CommandLine.h"
namespace llvm {
-typedef void *(*MachinePassCtor)();
-
+using MachinePassCtor = void *(*)();
//===----------------------------------------------------------------------===//
///
@@ -34,36 +34,30 @@ typedef void *(*MachinePassCtor)();
//===----------------------------------------------------------------------===//
class MachinePassRegistryListener {
virtual void anchor();
+
public:
- MachinePassRegistryListener() {}
- virtual ~MachinePassRegistryListener() {}
+ MachinePassRegistryListener() = default;
+ virtual ~MachinePassRegistryListener() = default;
+
virtual void NotifyAdd(StringRef N, MachinePassCtor C, StringRef D) = 0;
virtual void NotifyRemove(StringRef N) = 0;
};
-
//===----------------------------------------------------------------------===//
///
/// MachinePassRegistryNode - Machine pass node stored in registration list.
///
//===----------------------------------------------------------------------===//
class MachinePassRegistryNode {
-
private:
-
- MachinePassRegistryNode *Next; // Next function pass in list.
+ MachinePassRegistryNode *Next = nullptr; // Next function pass in list.
StringRef Name; // Name of function pass.
StringRef Description; // Description string.
MachinePassCtor Ctor; // Function pass creator.
public:
-
MachinePassRegistryNode(const char *N, const char *D, MachinePassCtor C)
- : Next(nullptr)
- , Name(N)
- , Description(D)
- , Ctor(C)
- {}
+ : Name(N), Description(D), Ctor(C) {}
// Accessors
MachinePassRegistryNode *getNext() const { return Next; }
@@ -72,25 +66,20 @@ public:
StringRef getDescription() const { return Description; }
MachinePassCtor getCtor() const { return Ctor; }
void setNext(MachinePassRegistryNode *N) { Next = N; }
-
};
-
//===----------------------------------------------------------------------===//
///
/// MachinePassRegistry - Track the registration of machine passes.
///
//===----------------------------------------------------------------------===//
class MachinePassRegistry {
-
private:
-
MachinePassRegistryNode *List; // List of registry nodes.
MachinePassCtor Default; // Default function pass creator.
- MachinePassRegistryListener* Listener;// Listener for list adds are removes.
+ MachinePassRegistryListener *Listener; // Listener for list adds are removes.
public:
-
// NO CONSTRUCTOR - we don't want static constructor ordering to mess
// with the registry.
@@ -109,10 +98,8 @@ public:
/// Remove - Removes a function pass from the registration list.
///
void Remove(MachinePassRegistryNode *Node);
-
};
-
//===----------------------------------------------------------------------===//
///
/// RegisterPassParser class - Handle the addition of new machine passes.
@@ -142,7 +129,6 @@ public:
}
// Implement the MachinePassRegistryListener callbacks.
- //
void NotifyAdd(StringRef N, MachinePassCtor C, StringRef D) override {
this->addLiteralOption(N, (typename RegistryClass::FunctionPassCtor)C, D);
}
@@ -151,7 +137,6 @@ public:
}
};
-
} // end namespace llvm
-#endif
+#endif // LLVM_CODEGEN_MACHINEPASSREGISTRY_H
diff --git a/contrib/llvm/include/llvm/CodeGen/MachinePostDominators.h b/contrib/llvm/include/llvm/CodeGen/MachinePostDominators.h
index 70bdb19..d29d2d8 100644
--- a/contrib/llvm/include/llvm/CodeGen/MachinePostDominators.h
+++ b/contrib/llvm/include/llvm/CodeGen/MachinePostDominators.h
@@ -26,7 +26,7 @@ namespace llvm {
///
struct MachinePostDominatorTree : public MachineFunctionPass {
private:
- DominatorTreeBase<MachineBasicBlock> *DT;
+ PostDomTreeBase<MachineBasicBlock> *DT;
public:
static char ID;
diff --git a/contrib/llvm/include/llvm/CodeGen/MachineRegionInfo.h b/contrib/llvm/include/llvm/CodeGen/MachineRegionInfo.h
index 21f847c..8394b58 100644
--- a/contrib/llvm/include/llvm/CodeGen/MachineRegionInfo.h
+++ b/contrib/llvm/include/llvm/CodeGen/MachineRegionInfo.h
@@ -10,83 +10,77 @@
#ifndef LLVM_CODEGEN_MACHINEREGIONINFO_H
#define LLVM_CODEGEN_MACHINEREGIONINFO_H
+#include "llvm/ADT/DepthFirstIterator.h"
#include "llvm/Analysis/RegionInfo.h"
#include "llvm/Analysis/RegionIterator.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineDominanceFrontier.h"
#include "llvm/CodeGen/MachineDominators.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineLoopInfo.h"
-
+#include <cassert>
namespace llvm {
-class MachineDominatorTree;
struct MachinePostDominatorTree;
class MachineRegion;
class MachineRegionNode;
class MachineRegionInfo;
-template<>
-struct RegionTraits<MachineFunction> {
- typedef MachineFunction FuncT;
- typedef MachineBasicBlock BlockT;
- typedef MachineRegion RegionT;
- typedef MachineRegionNode RegionNodeT;
- typedef MachineRegionInfo RegionInfoT;
- typedef MachineDominatorTree DomTreeT;
- typedef MachineDomTreeNode DomTreeNodeT;
- typedef MachinePostDominatorTree PostDomTreeT;
- typedef MachineDominanceFrontier DomFrontierT;
- typedef MachineInstr InstT;
- typedef MachineLoop LoopT;
- typedef MachineLoopInfo LoopInfoT;
+template <> struct RegionTraits<MachineFunction> {
+ using FuncT = MachineFunction;
+ using BlockT = MachineBasicBlock;
+ using RegionT = MachineRegion;
+ using RegionNodeT = MachineRegionNode;
+ using RegionInfoT = MachineRegionInfo;
+ using DomTreeT = MachineDominatorTree;
+ using DomTreeNodeT = MachineDomTreeNode;
+ using PostDomTreeT = MachinePostDominatorTree;
+ using DomFrontierT = MachineDominanceFrontier;
+ using InstT = MachineInstr;
+ using LoopT = MachineLoop;
+ using LoopInfoT = MachineLoopInfo;
static unsigned getNumSuccessors(MachineBasicBlock *BB) {
return BB->succ_size();
}
};
-
class MachineRegionNode : public RegionNodeBase<RegionTraits<MachineFunction>> {
public:
- inline MachineRegionNode(MachineRegion *Parent,
- MachineBasicBlock *Entry,
+ inline MachineRegionNode(MachineRegion *Parent, MachineBasicBlock *Entry,
bool isSubRegion = false)
- : RegionNodeBase<RegionTraits<MachineFunction>>(Parent, Entry, isSubRegion) {
-
- }
+ : RegionNodeBase<RegionTraits<MachineFunction>>(Parent, Entry,
+ isSubRegion) {}
bool operator==(const MachineRegion &RN) const {
- return this == reinterpret_cast<const MachineRegionNode*>(&RN);
+ return this == reinterpret_cast<const MachineRegionNode *>(&RN);
}
};
class MachineRegion : public RegionBase<RegionTraits<MachineFunction>> {
public:
MachineRegion(MachineBasicBlock *Entry, MachineBasicBlock *Exit,
- MachineRegionInfo* RI,
- MachineDominatorTree *DT, MachineRegion *Parent = nullptr);
+ MachineRegionInfo *RI, MachineDominatorTree *DT,
+ MachineRegion *Parent = nullptr);
~MachineRegion();
bool operator==(const MachineRegionNode &RN) const {
- return &RN == reinterpret_cast<const MachineRegionNode*>(this);
+ return &RN == reinterpret_cast<const MachineRegionNode *>(this);
}
};
class MachineRegionInfo : public RegionInfoBase<RegionTraits<MachineFunction>> {
public:
explicit MachineRegionInfo();
-
~MachineRegionInfo() override;
// updateStatistics - Update statistic about created regions.
void updateStatistics(MachineRegion *R) final;
- void recalculate(MachineFunction &F,
- MachineDominatorTree *DT,
- MachinePostDominatorTree *PDT,
- MachineDominanceFrontier *DF);
+ void recalculate(MachineFunction &F, MachineDominatorTree *DT,
+ MachinePostDominatorTree *PDT, MachineDominanceFrontier *DF);
};
class MachineRegionInfoPass : public MachineFunctionPass {
@@ -94,17 +88,13 @@ class MachineRegionInfoPass : public MachineFunctionPass {
public:
static char ID;
- explicit MachineRegionInfoPass();
+ explicit MachineRegionInfoPass();
~MachineRegionInfoPass() override;
- MachineRegionInfo &getRegionInfo() {
- return RI;
- }
+ MachineRegionInfo &getRegionInfo() { return RI; }
- const MachineRegionInfo &getRegionInfo() const {
- return RI;
- }
+ const MachineRegionInfo &getRegionInfo() const { return RI; }
/// @name MachineFunctionPass interface
//@{
@@ -117,66 +107,76 @@ public:
//@}
};
-
template <>
template <>
-inline MachineBasicBlock* RegionNodeBase<RegionTraits<MachineFunction>>::getNodeAs<MachineBasicBlock>() const {
+inline MachineBasicBlock *
+RegionNodeBase<RegionTraits<MachineFunction>>::getNodeAs<MachineBasicBlock>()
+ const {
assert(!isSubRegion() && "This is not a MachineBasicBlock RegionNode!");
return getEntry();
}
-template<>
-template<>
-inline MachineRegion* RegionNodeBase<RegionTraits<MachineFunction>>::getNodeAs<MachineRegion>() const {
+template <>
+template <>
+inline MachineRegion *
+RegionNodeBase<RegionTraits<MachineFunction>>::getNodeAs<MachineRegion>()
+ const {
assert(isSubRegion() && "This is not a subregion RegionNode!");
- auto Unconst = const_cast<RegionNodeBase<RegionTraits<MachineFunction>>*>(this);
- return reinterpret_cast<MachineRegion*>(Unconst);
+ auto Unconst =
+ const_cast<RegionNodeBase<RegionTraits<MachineFunction>> *>(this);
+ return reinterpret_cast<MachineRegion *>(Unconst);
}
-
RegionNodeGraphTraits(MachineRegionNode, MachineBasicBlock, MachineRegion);
-RegionNodeGraphTraits(const MachineRegionNode, MachineBasicBlock, MachineRegion);
+RegionNodeGraphTraits(const MachineRegionNode, MachineBasicBlock,
+ MachineRegion);
RegionGraphTraits(MachineRegion, MachineRegionNode);
RegionGraphTraits(const MachineRegion, const MachineRegionNode);
-template <> struct GraphTraits<MachineRegionInfo*>
- : public GraphTraits<FlatIt<MachineRegionNode*> > {
- typedef df_iterator<NodeRef, df_iterator_default_set<NodeRef>, false,
- GraphTraits<FlatIt<NodeRef>>>
- nodes_iterator;
+template <>
+struct GraphTraits<MachineRegionInfo *>
+ : public GraphTraits<FlatIt<MachineRegionNode *>> {
+ using nodes_iterator = df_iterator<NodeRef, df_iterator_default_set<NodeRef>,
+ false, GraphTraits<FlatIt<NodeRef>>>;
static NodeRef getEntryNode(MachineRegionInfo *RI) {
- return GraphTraits<FlatIt<MachineRegion*> >::getEntryNode(RI->getTopLevelRegion());
+ return GraphTraits<FlatIt<MachineRegion *>>::getEntryNode(
+ RI->getTopLevelRegion());
}
- static nodes_iterator nodes_begin(MachineRegionInfo* RI) {
+
+ static nodes_iterator nodes_begin(MachineRegionInfo *RI) {
return nodes_iterator::begin(getEntryNode(RI));
}
+
static nodes_iterator nodes_end(MachineRegionInfo *RI) {
return nodes_iterator::end(getEntryNode(RI));
}
};
-template <> struct GraphTraits<MachineRegionInfoPass*>
- : public GraphTraits<MachineRegionInfo *> {
- typedef df_iterator<NodeRef, df_iterator_default_set<NodeRef>, false,
- GraphTraits<FlatIt<NodeRef>>>
- nodes_iterator;
+template <>
+struct GraphTraits<MachineRegionInfoPass *>
+ : public GraphTraits<MachineRegionInfo *> {
+ using nodes_iterator = df_iterator<NodeRef, df_iterator_default_set<NodeRef>,
+ false, GraphTraits<FlatIt<NodeRef>>>;
static NodeRef getEntryNode(MachineRegionInfoPass *RI) {
- return GraphTraits<MachineRegionInfo*>::getEntryNode(&RI->getRegionInfo());
+ return GraphTraits<MachineRegionInfo *>::getEntryNode(&RI->getRegionInfo());
}
- static nodes_iterator nodes_begin(MachineRegionInfoPass* RI) {
- return GraphTraits<MachineRegionInfo*>::nodes_begin(&RI->getRegionInfo());
+
+ static nodes_iterator nodes_begin(MachineRegionInfoPass *RI) {
+ return GraphTraits<MachineRegionInfo *>::nodes_begin(&RI->getRegionInfo());
}
+
static nodes_iterator nodes_end(MachineRegionInfoPass *RI) {
- return GraphTraits<MachineRegionInfo*>::nodes_end(&RI->getRegionInfo());
+ return GraphTraits<MachineRegionInfo *>::nodes_end(&RI->getRegionInfo());
}
};
extern template class RegionBase<RegionTraits<MachineFunction>>;
extern template class RegionNodeBase<RegionTraits<MachineFunction>>;
extern template class RegionInfoBase<RegionTraits<MachineFunction>>;
-}
-#endif
+} // end namespace llvm
+
+#endif // LLVM_CODEGEN_MACHINEREGIONINFO_H
diff --git a/contrib/llvm/include/llvm/CodeGen/MachineRegisterInfo.h b/contrib/llvm/include/llvm/CodeGen/MachineRegisterInfo.h
index c599caf..8347f00 100644
--- a/contrib/llvm/include/llvm/CodeGen/MachineRegisterInfo.h
+++ b/contrib/llvm/include/llvm/CodeGen/MachineRegisterInfo.h
@@ -1,4 +1,4 @@
-//===-- llvm/CodeGen/MachineRegisterInfo.h ----------------------*- C++ -*-===//
+//===- llvm/CodeGen/MachineRegisterInfo.h -----------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,25 +14,37 @@
#ifndef LLVM_CODEGEN_MACHINEREGISTERINFO_H
#define LLVM_CODEGEN_MACHINEREGISTERINFO_H
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/BitVector.h"
+#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/IndexedMap.h"
#include "llvm/ADT/PointerUnion.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/iterator_range.h"
-// PointerUnion needs to have access to the full RegisterBank type.
#include "llvm/CodeGen/GlobalISel/RegisterBank.h"
#include "llvm/CodeGen/LowLevelType.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstrBundle.h"
+#include "llvm/CodeGen/MachineOperand.h"
+#include "llvm/MC/LaneBitmask.h"
#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/Target/TargetSubtargetInfo.h"
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
+#include <iterator>
+#include <memory>
+#include <utility>
#include <vector>
namespace llvm {
+
class PSetIterator;
/// Convenient type to represent either a register class or a register bank.
-typedef PointerUnion<const TargetRegisterClass *, const RegisterBank *>
- RegClassOrRegBank;
+using RegClassOrRegBank =
+ PointerUnion<const TargetRegisterClass *, const RegisterBank *>;
/// MachineRegisterInfo - Keep track of information for virtual and physical
/// registers, including vreg register classes, use/def chains for registers,
@@ -41,15 +53,16 @@ class MachineRegisterInfo {
public:
class Delegate {
virtual void anchor();
+
public:
- virtual void MRI_NoteNewVirtualRegister(unsigned Reg) = 0;
+ virtual ~Delegate() = default;
- virtual ~Delegate() {}
+ virtual void MRI_NoteNewVirtualRegister(unsigned Reg) = 0;
};
private:
MachineFunction *MF;
- Delegate *TheDelegate;
+ Delegate *TheDelegate = nullptr;
/// True if subregister liveness is tracked.
const bool TracksSubRegLiveness;
@@ -62,6 +75,15 @@ private:
VirtReg2IndexFunctor>
VRegInfo;
+ /// The flag is true upon \p UpdatedCSRs initialization
+ /// and false otherwise.
+ bool IsUpdatedCSRsInitialized;
+
+ /// Contains the updated callee saved register list.
+ /// As opposed to the static list defined in register info,
+ /// all registers that were disabled are removed from the list.
+ SmallVector<MCPhysReg, 16> UpdatedCSRs;
+
/// RegAllocHints - This vector records register allocation hints for virtual
/// registers. For each virtual register, it keeps a register and hint type
/// pair making up the allocation hint. Hint type is target specific except
@@ -105,7 +127,7 @@ private:
/// started.
BitVector ReservedRegs;
- typedef DenseMap<unsigned, LLT> VRegToTypeMap;
+ using VRegToTypeMap = DenseMap<unsigned, LLT>;
/// Map generic virtual registers to their actual size.
mutable std::unique_ptr<VRegToTypeMap> VRegToType;
@@ -113,12 +135,12 @@ 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<unsigned, unsigned>> LiveIns;
- MachineRegisterInfo(const MachineRegisterInfo&) = delete;
- void operator=(const MachineRegisterInfo&) = delete;
public:
explicit MachineRegisterInfo(MachineFunction *MF);
+ MachineRegisterInfo(const MachineRegisterInfo &) = delete;
+ MachineRegisterInfo &operator=(const MachineRegisterInfo &) = delete;
const TargetRegisterInfo *getTargetRegisterInfo() const {
return MF->getSubtarget().getRegisterInfo();
@@ -196,6 +218,23 @@ public:
// Register Info
//===--------------------------------------------------------------------===//
+ /// Returns true if the updated CSR list was initialized and false otherwise.
+ bool isUpdatedCSRsInitialized() const { return IsUpdatedCSRsInitialized; }
+
+ /// 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);
+
+ /// Returns list of callee saved registers.
+ /// The function returns the updated CSR list (after taking into account
+ /// registers that are disabled from the CSR list).
+ const MCPhysReg *getCalleeSavedRegs() const;
+
+ /// Sets the updated Callee Saved Registers list.
+ /// Notice that it will override ant previously disabled/saved CSRs.
+ void setCalleeSavedRegs(ArrayRef<MCPhysReg> CSRs);
+
// Strictly for use by MachineInstr.cpp.
void addRegOperandToUseList(MachineOperand *MO);
@@ -227,12 +266,10 @@ public:
template<bool, bool, bool, bool, bool, bool>
friend class defusechain_instr_iterator;
-
-
/// reg_iterator/reg_begin/reg_end - Walk all defs and uses of the specified
/// register.
- typedef defusechain_iterator<true,true,false,true,false,false>
- reg_iterator;
+ using reg_iterator =
+ defusechain_iterator<true, true, false, true, false, false>;
reg_iterator reg_begin(unsigned RegNo) const {
return reg_iterator(getRegUseDefListHead(RegNo));
}
@@ -244,8 +281,8 @@ public:
/// reg_instr_iterator/reg_instr_begin/reg_instr_end - Walk all defs and uses
/// of the specified register, stepping by MachineInstr.
- typedef defusechain_instr_iterator<true,true,false,false,true,false>
- reg_instr_iterator;
+ using reg_instr_iterator =
+ defusechain_instr_iterator<true, true, false, false, true, false>;
reg_instr_iterator reg_instr_begin(unsigned RegNo) const {
return reg_instr_iterator(getRegUseDefListHead(RegNo));
}
@@ -260,8 +297,8 @@ public:
/// reg_bundle_iterator/reg_bundle_begin/reg_bundle_end - Walk all defs and uses
/// of the specified register, stepping by bundle.
- typedef defusechain_instr_iterator<true,true,false,false,false,true>
- reg_bundle_iterator;
+ using reg_bundle_iterator =
+ defusechain_instr_iterator<true, true, false, false, false, true>;
reg_bundle_iterator reg_bundle_begin(unsigned RegNo) const {
return reg_bundle_iterator(getRegUseDefListHead(RegNo));
}
@@ -279,8 +316,8 @@ public:
/// reg_nodbg_iterator/reg_nodbg_begin/reg_nodbg_end - Walk all defs and uses
/// of the specified register, skipping those marked as Debug.
- typedef defusechain_iterator<true,true,true,true,false,false>
- reg_nodbg_iterator;
+ using reg_nodbg_iterator =
+ defusechain_iterator<true, true, true, true, false, false>;
reg_nodbg_iterator reg_nodbg_begin(unsigned RegNo) const {
return reg_nodbg_iterator(getRegUseDefListHead(RegNo));
}
@@ -296,8 +333,8 @@ public:
/// reg_instr_nodbg_iterator/reg_instr_nodbg_begin/reg_instr_nodbg_end - Walk
/// all defs and uses of the specified register, stepping by MachineInstr,
/// skipping those marked as Debug.
- typedef defusechain_instr_iterator<true,true,true,false,true,false>
- reg_instr_nodbg_iterator;
+ 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 {
return reg_instr_nodbg_iterator(getRegUseDefListHead(RegNo));
}
@@ -313,8 +350,8 @@ public:
/// reg_bundle_nodbg_iterator/reg_bundle_nodbg_begin/reg_bundle_nodbg_end - Walk
/// all defs and uses of the specified register, stepping by bundle,
/// skipping those marked as Debug.
- typedef defusechain_instr_iterator<true,true,true,false,false,true>
- reg_bundle_nodbg_iterator;
+ 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 {
return reg_bundle_nodbg_iterator(getRegUseDefListHead(RegNo));
}
@@ -334,8 +371,8 @@ public:
}
/// def_iterator/def_begin/def_end - Walk all defs of the specified register.
- typedef defusechain_iterator<false,true,false,true,false,false>
- def_iterator;
+ using def_iterator =
+ defusechain_iterator<false, true, false, true, false, false>;
def_iterator def_begin(unsigned RegNo) const {
return def_iterator(getRegUseDefListHead(RegNo));
}
@@ -347,8 +384,8 @@ public:
/// def_instr_iterator/def_instr_begin/def_instr_end - Walk all defs of the
/// specified register, stepping by MachineInst.
- typedef defusechain_instr_iterator<false,true,false,false,true,false>
- def_instr_iterator;
+ using def_instr_iterator =
+ defusechain_instr_iterator<false, true, false, false, true, false>;
def_instr_iterator def_instr_begin(unsigned RegNo) const {
return def_instr_iterator(getRegUseDefListHead(RegNo));
}
@@ -363,8 +400,8 @@ public:
/// def_bundle_iterator/def_bundle_begin/def_bundle_end - Walk all defs of the
/// specified register, stepping by bundle.
- typedef defusechain_instr_iterator<false,true,false,false,false,true>
- def_bundle_iterator;
+ using def_bundle_iterator =
+ defusechain_instr_iterator<false, true, false, false, false, true>;
def_bundle_iterator def_bundle_begin(unsigned RegNo) const {
return def_bundle_iterator(getRegUseDefListHead(RegNo));
}
@@ -390,8 +427,8 @@ public:
}
/// use_iterator/use_begin/use_end - Walk all uses of the specified register.
- typedef defusechain_iterator<true,false,false,true,false,false>
- use_iterator;
+ using use_iterator =
+ defusechain_iterator<true, false, false, true, false, false>;
use_iterator use_begin(unsigned RegNo) const {
return use_iterator(getRegUseDefListHead(RegNo));
}
@@ -403,8 +440,8 @@ public:
/// use_instr_iterator/use_instr_begin/use_instr_end - Walk all uses of the
/// specified register, stepping by MachineInstr.
- typedef defusechain_instr_iterator<true,false,false,false,true,false>
- use_instr_iterator;
+ using use_instr_iterator =
+ defusechain_instr_iterator<true, false, false, false, true, false>;
use_instr_iterator use_instr_begin(unsigned RegNo) const {
return use_instr_iterator(getRegUseDefListHead(RegNo));
}
@@ -419,8 +456,8 @@ public:
/// use_bundle_iterator/use_bundle_begin/use_bundle_end - Walk all uses of the
/// specified register, stepping by bundle.
- typedef defusechain_instr_iterator<true,false,false,false,false,true>
- use_bundle_iterator;
+ using use_bundle_iterator =
+ defusechain_instr_iterator<true, false, false, false, false, true>;
use_bundle_iterator use_bundle_begin(unsigned RegNo) const {
return use_bundle_iterator(getRegUseDefListHead(RegNo));
}
@@ -447,8 +484,8 @@ public:
/// use_nodbg_iterator/use_nodbg_begin/use_nodbg_end - Walk all uses of the
/// specified register, skipping those marked as Debug.
- typedef defusechain_iterator<true,false,true,true,false,false>
- use_nodbg_iterator;
+ using use_nodbg_iterator =
+ defusechain_iterator<true, false, true, true, false, false>;
use_nodbg_iterator use_nodbg_begin(unsigned RegNo) const {
return use_nodbg_iterator(getRegUseDefListHead(RegNo));
}
@@ -464,8 +501,8 @@ public:
/// use_instr_nodbg_iterator/use_instr_nodbg_begin/use_instr_nodbg_end - Walk
/// all uses of the specified register, stepping by MachineInstr, skipping
/// those marked as Debug.
- typedef defusechain_instr_iterator<true,false,true,false,true,false>
- use_instr_nodbg_iterator;
+ 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 {
return use_instr_nodbg_iterator(getRegUseDefListHead(RegNo));
}
@@ -481,8 +518,8 @@ public:
/// use_bundle_nodbg_iterator/use_bundle_nodbg_begin/use_bundle_nodbg_end - Walk
/// all uses of the specified register, stepping by bundle, skipping
/// those marked as Debug.
- typedef defusechain_instr_iterator<true,false,true,false,false,true>
- use_bundle_nodbg_iterator;
+ 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 {
return use_bundle_nodbg_iterator(getRegUseDefListHead(RegNo));
}
@@ -558,7 +595,6 @@ public:
/// Return the register class of the specified virtual register.
/// This shouldn't be used directly unless \p Reg has a register class.
/// \see getRegClassOrNull when this might happen.
- ///
const TargetRegisterClass *getRegClass(unsigned Reg) const {
assert(VRegInfo[Reg].first.is<const TargetRegisterClass *>() &&
"Register class not set, wrong accessor");
@@ -585,7 +621,6 @@ 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 RegClassOrRegBank &Val = VRegInfo[Reg].first;
return Val.dyn_cast<const RegisterBank *>();
@@ -594,26 +629,27 @@ 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 {
return VRegInfo[Reg].first;
}
/// setRegClass - Set the register class of the specified virtual register.
- ///
void setRegClass(unsigned Reg, const TargetRegisterClass *RC);
/// Set the register bank to \p RegBank for \p Reg.
- ///
void setRegBank(unsigned Reg, const RegisterBank &RegBank);
+ void setRegClassOrRegBank(unsigned Reg,
+ const RegClassOrRegBank &RCOrRB){
+ VRegInfo[Reg].first = RCOrRB;
+ }
+
/// constrainRegClass - Constrain the register class of the specified virtual
/// register to be a common subclass of RC and the current register class,
/// but only if the new class has at least MinNumRegs registers. Return the
/// new register class, or NULL if no such class exists.
/// This should only be used when the constraint is known to be trivial, like
/// GR32 -> GR32_NOSP. Beware of increasing register pressure.
- ///
const TargetRegisterClass *constrainRegClass(unsigned Reg,
const TargetRegisterClass *RC,
unsigned MinNumRegs = 0);
@@ -625,12 +661,10 @@ 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);
/// createVirtualRegister - Create and return a new virtual register in the
/// function with the specified register class.
- ///
unsigned createVirtualRegister(const TargetRegisterClass *RegClass);
/// Accessor for VRegToType. This accessor should only be used
@@ -664,7 +698,6 @@ public:
unsigned createIncompleteVirtualRegister();
/// getNumVirtRegs - Return the number of virtual registers created.
- ///
unsigned getNumVirtRegs() const { return VRegInfo.size(); }
/// clearVirtRegs - Remove all virtual registers (after physreg assignment).
@@ -727,8 +760,6 @@ public:
const BitVector &getUsedPhysRegsMask() const { return UsedPhysRegMask; }
- void setUsedPhysRegMask(BitVector &Mask) { UsedPhysRegMask = Mask; }
-
//===--------------------------------------------------------------------===//
// Reserved Register Info
//===--------------------------------------------------------------------===//
@@ -772,7 +803,6 @@ public:
///
/// Reserved registers may belong to an allocatable register class, but the
/// target has explicitly requested that they are not used.
- ///
bool isReserved(unsigned PhysReg) const {
return getReservedRegs().test(PhysReg);
}
@@ -800,8 +830,8 @@ public:
// Iteration support for the live-ins set. It's kept in sorted order
// by register number.
- typedef std::vector<std::pair<unsigned,unsigned> >::const_iterator
- livein_iterator;
+ using livein_iterator =
+ std::vector<std::pair<unsigned,unsigned>>::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(); }
@@ -836,7 +866,10 @@ public:
bool ByOperand, bool ByInstr, bool ByBundle>
class defusechain_iterator
: public std::iterator<std::forward_iterator_tag, MachineInstr, ptrdiff_t> {
- MachineOperand *Op;
+ friend class MachineRegisterInfo;
+
+ MachineOperand *Op = nullptr;
+
explicit defusechain_iterator(MachineOperand *op) : Op(op) {
// If the first node isn't one we're interested in, advance to one that
// we are interested in.
@@ -847,7 +880,6 @@ public:
advance();
}
}
- friend class MachineRegisterInfo;
void advance() {
assert(Op && "Cannot increment end iterator!");
@@ -868,13 +900,14 @@ public:
Op = getNextOperandForReg(Op);
}
}
+
public:
- typedef std::iterator<std::forward_iterator_tag,
- MachineInstr, ptrdiff_t>::reference reference;
- typedef std::iterator<std::forward_iterator_tag,
- MachineInstr, ptrdiff_t>::pointer pointer;
+ using reference = std::iterator<std::forward_iterator_tag,
+ MachineInstr, ptrdiff_t>::reference;
+ using pointer = std::iterator<std::forward_iterator_tag,
+ MachineInstr, ptrdiff_t>::pointer;
- defusechain_iterator() : Op(nullptr) {}
+ defusechain_iterator() = default;
bool operator==(const defusechain_iterator &x) const {
return Op == x.Op;
@@ -939,7 +972,10 @@ public:
bool ByOperand, bool ByInstr, bool ByBundle>
class defusechain_instr_iterator
: public std::iterator<std::forward_iterator_tag, MachineInstr, ptrdiff_t> {
- MachineOperand *Op;
+ friend class MachineRegisterInfo;
+
+ MachineOperand *Op = nullptr;
+
explicit defusechain_instr_iterator(MachineOperand *op) : Op(op) {
// If the first node isn't one we're interested in, advance to one that
// we are interested in.
@@ -950,7 +986,6 @@ public:
advance();
}
}
- friend class MachineRegisterInfo;
void advance() {
assert(Op && "Cannot increment end iterator!");
@@ -971,13 +1006,14 @@ public:
Op = getNextOperandForReg(Op);
}
}
+
public:
- typedef std::iterator<std::forward_iterator_tag,
- MachineInstr, ptrdiff_t>::reference reference;
- typedef std::iterator<std::forward_iterator_tag,
- MachineInstr, ptrdiff_t>::pointer pointer;
+ using reference = std::iterator<std::forward_iterator_tag,
+ MachineInstr, ptrdiff_t>::reference;
+ using pointer = std::iterator<std::forward_iterator_tag,
+ MachineInstr, ptrdiff_t>::pointer;
- defusechain_instr_iterator() : Op(nullptr) {}
+ defusechain_instr_iterator() = default;
bool operator==(const defusechain_instr_iterator &x) const {
return Op == x.Op;
@@ -1029,10 +1065,12 @@ public:
/// register. If Reg is physical, it must be a register unit (from
/// MCRegUnitIterator).
class PSetIterator {
- const int *PSet;
- unsigned Weight;
+ const int *PSet = nullptr;
+ unsigned Weight = 0;
+
public:
- PSetIterator(): PSet(nullptr), Weight(0) {}
+ PSetIterator() = default;
+
PSetIterator(unsigned RegUnit, const MachineRegisterInfo *MRI) {
const TargetRegisterInfo *TRI = MRI->getTargetRegisterInfo();
if (TargetRegisterInfo::isVirtualRegister(RegUnit)) {
@@ -1047,6 +1085,7 @@ public:
if (*PSet == -1)
PSet = nullptr;
}
+
bool isValid() const { return PSet; }
unsigned getWeight() const { return Weight; }
@@ -1066,6 +1105,6 @@ getPressureSets(unsigned RegUnit) const {
return PSetIterator(RegUnit, this);
}
-} // End llvm namespace
+} // end namespace llvm
-#endif
+#endif // LLVM_CODEGEN_MACHINEREGISTERINFO_H
diff --git a/contrib/llvm/include/llvm/CodeGen/MachineScheduler.h b/contrib/llvm/include/llvm/CodeGen/MachineScheduler.h
index 81b8741..8590b7a 100644
--- a/contrib/llvm/include/llvm/CodeGen/MachineScheduler.h
+++ b/contrib/llvm/include/llvm/CodeGen/MachineScheduler.h
@@ -1,4 +1,4 @@
-//==- MachineScheduler.h - MachineInstr Scheduling Pass ----------*- C++ -*-==//
+//===- MachineScheduler.h - MachineInstr Scheduling Pass --------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -32,7 +32,7 @@
//
// ScheduleDAGInstrs *<Target>PassConfig::
// createMachineScheduler(MachineSchedContext *C) {
-// return new ScheduleDAGMI(C, CustomStrategy(C));
+// return new ScheduleDAGMILive(C, CustomStrategy(C));
// }
//
// The DAG builder can also be customized in a sense by adding DAG mutations
@@ -104,20 +104,25 @@ extern cl::opt<bool> ForceBottomUp;
class LiveIntervals;
class MachineDominatorTree;
+class MachineFunction;
+class MachineInstr;
class MachineLoopInfo;
class RegisterClassInfo;
class SchedDFSResult;
class ScheduleHazardRecognizer;
+class TargetInstrInfo;
+class TargetPassConfig;
+class TargetRegisterInfo;
/// MachineSchedContext provides enough context from the MachineScheduler pass
/// for the target to instantiate a scheduler.
struct MachineSchedContext {
- MachineFunction *MF;
- const MachineLoopInfo *MLI;
- const MachineDominatorTree *MDT;
- const TargetPassConfig *PassConfig;
- AliasAnalysis *AA;
- LiveIntervals *LIS;
+ MachineFunction *MF = nullptr;
+ const MachineLoopInfo *MLI = nullptr;
+ const MachineDominatorTree *MDT = nullptr;
+ const TargetPassConfig *PassConfig = nullptr;
+ AliasAnalysis *AA = nullptr;
+ LiveIntervals *LIS = nullptr;
RegisterClassInfo *RegClassInfo;
@@ -129,10 +134,10 @@ struct MachineSchedContext {
/// schedulers.
class MachineSchedRegistry : public MachinePassRegistryNode {
public:
- typedef ScheduleDAGInstrs *(*ScheduleDAGCtor)(MachineSchedContext *);
+ using ScheduleDAGCtor = ScheduleDAGInstrs *(*)(MachineSchedContext *);
// RegisterPassParser requires a (misnamed) FunctionPassCtor type.
- typedef ScheduleDAGCtor FunctionPassCtor;
+ using FunctionPassCtor = ScheduleDAGCtor;
static MachinePassRegistry Registry;
@@ -165,22 +170,21 @@ class ScheduleDAGMI;
/// before building the DAG.
struct MachineSchedPolicy {
// Allow the scheduler to disable register pressure tracking.
- bool ShouldTrackPressure;
+ bool ShouldTrackPressure = false;
/// Track LaneMasks to allow reordering of independent subregister writes
/// of the same vreg. \sa MachineSchedStrategy::shouldTrackLaneMasks()
- bool ShouldTrackLaneMasks;
+ bool ShouldTrackLaneMasks = false;
// Allow the scheduler to force top-down or bottom-up scheduling. If neither
// is true, the scheduler runs in both directions and converges.
- bool OnlyTopDown;
- bool OnlyBottomUp;
+ bool OnlyTopDown = false;
+ bool OnlyBottomUp = false;
// Disable heuristic that tries to fetch nodes from long dependency chains
// first.
- bool DisableLatencyHeuristic;
+ bool DisableLatencyHeuristic = false;
- MachineSchedPolicy(): ShouldTrackPressure(false), ShouldTrackLaneMasks(false),
- OnlyTopDown(false), OnlyBottomUp(false), DisableLatencyHeuristic(false) {}
+ MachineSchedPolicy() = default;
};
/// MachineSchedStrategy - Interface to the scheduling algorithm used by
@@ -199,7 +203,7 @@ public:
MachineBasicBlock::iterator End,
unsigned NumRegionInstrs) {}
- virtual void dumpPolicy() {}
+ virtual void dumpPolicy() const {}
/// Check if pressure tracking is needed before building the DAG and
/// initializing this strategy. Called after initPolicy.
@@ -232,6 +236,7 @@ public:
/// When all predecessor dependencies have been resolved, free this node for
/// top-down scheduling.
virtual void releaseTopNode(SUnit *SU) = 0;
+
/// When all successor dependencies have been resolved, free this node for
/// bottom-up scheduling.
virtual void releaseBottomNode(SUnit *SU) = 0;
@@ -261,24 +266,20 @@ protected:
MachineBasicBlock::iterator CurrentBottom;
/// Record the next node in a scheduled cluster.
- const SUnit *NextClusterPred;
- const SUnit *NextClusterSucc;
+ const SUnit *NextClusterPred = nullptr;
+ const SUnit *NextClusterSucc = nullptr;
#ifndef NDEBUG
/// The number of instructions scheduled so far. Used to cut off the
/// scheduler at the point determined by misched-cutoff.
- unsigned NumInstrsScheduled;
+ unsigned NumInstrsScheduled = 0;
#endif
+
public:
ScheduleDAGMI(MachineSchedContext *C, std::unique_ptr<MachineSchedStrategy> S,
bool RemoveKillFlags)
: ScheduleDAGInstrs(*C->MF, C->MLI, RemoveKillFlags), AA(C->AA),
- LIS(C->LIS), SchedImpl(std::move(S)), Topo(SUnits, &ExitSU),
- NextClusterPred(nullptr), NextClusterSucc(nullptr) {
-#ifndef NDEBUG
- NumInstrsScheduled = 0;
-#endif
- }
+ LIS(C->LIS), SchedImpl(std::move(S)), Topo(SUnits, &ExitSU) {}
// Provide a vtable anchor
~ScheduleDAGMI() override;
@@ -375,7 +376,7 @@ protected:
/// Information about DAG subtrees. If DFSResult is NULL, then SchedulerTrees
/// will be empty.
- SchedDFSResult *DFSResult;
+ SchedDFSResult *DFSResult = nullptr;
BitVector ScheduledTrees;
MachineBasicBlock::iterator LiveRegionEnd;
@@ -389,8 +390,8 @@ protected:
PressureDiffs SUPressureDiffs;
/// Register pressure in this region computed by initRegPressure.
- bool ShouldTrackPressure;
- bool ShouldTrackLaneMasks;
+ bool ShouldTrackPressure = false;
+ bool ShouldTrackLaneMasks = false;
IntervalPressure RegPressure;
RegPressureTracker RPTracker;
@@ -409,16 +410,14 @@ protected:
/// True if disconnected subregister components are already renamed.
/// The renaming is only done on demand if lane masks are tracked.
- bool DisconnectedComponentsRenamed;
+ bool DisconnectedComponentsRenamed = false;
public:
ScheduleDAGMILive(MachineSchedContext *C,
std::unique_ptr<MachineSchedStrategy> S)
: ScheduleDAGMI(C, std::move(S), /*RemoveKillFlags=*/false),
- RegClassInfo(C->RegClassInfo), DFSResult(nullptr),
- ShouldTrackPressure(false), ShouldTrackLaneMasks(false),
- RPTracker(RegPressure), TopRPTracker(TopPressure),
- BotRPTracker(BotPressure), DisconnectedComponentsRenamed(false) {}
+ RegClassInfo(C->RegClassInfo), RPTracker(RegPressure),
+ TopRPTracker(TopPressure), BotRPTracker(BotPressure) {}
~ScheduleDAGMILive() override;
@@ -533,7 +532,7 @@ public:
unsigned size() const { return Queue.size(); }
- typedef std::vector<SUnit*>::iterator iterator;
+ using iterator = std::vector<SUnit*>::iterator;
iterator begin() { return Queue.begin(); }
@@ -556,7 +555,7 @@ public:
return Queue.begin() + idx;
}
- void dump();
+ void dump() const;
};
/// Summarize the unscheduled region.
@@ -573,6 +572,8 @@ struct SchedRemainder {
// Unscheduled resources
SmallVector<unsigned, 16> RemainingCounts;
+ SchedRemainder() { reset(); }
+
void reset() {
CriticalPath = 0;
CyclicCritPath = 0;
@@ -581,8 +582,6 @@ struct SchedRemainder {
RemainingCounts.clear();
}
- SchedRemainder() { reset(); }
-
void init(ScheduleDAGMI *DAG, const TargetSchedModel *SchedModel);
};
@@ -598,14 +597,14 @@ public:
LogMaxQID = 2
};
- ScheduleDAGMI *DAG;
- const TargetSchedModel *SchedModel;
- SchedRemainder *Rem;
+ ScheduleDAGMI *DAG = nullptr;
+ const TargetSchedModel *SchedModel = nullptr;
+ SchedRemainder *Rem = nullptr;
ReadyQueue Available;
ReadyQueue Pending;
- ScheduleHazardRecognizer *HazardRec;
+ ScheduleHazardRecognizer *HazardRec = nullptr;
private:
/// True if the pending Q should be checked/updated before scheduling another
@@ -665,9 +664,7 @@ public:
/// Pending queues extend the ready queues with the same ID and the
/// PendingFlag set.
SchedBoundary(unsigned ID, const Twine &Name):
- DAG(nullptr), SchedModel(nullptr), Rem(nullptr), Available(ID, Name+".A"),
- Pending(ID << LogMaxQID, Name+".P"),
- HazardRec(nullptr) {
+ Available(ID, Name+".A"), Pending(ID << LogMaxQID, Name+".P") {
reset();
}
@@ -759,7 +756,7 @@ public:
SUnit *pickOnlyChoice();
#ifndef NDEBUG
- void dumpScheduledState();
+ void dumpScheduledState() const;
#endif
};
@@ -781,11 +778,11 @@ public:
/// Policy for scheduling the next instruction in the candidate's zone.
struct CandPolicy {
- bool ReduceLatency;
- unsigned ReduceResIdx;
- unsigned DemandResIdx;
+ bool ReduceLatency = false;
+ unsigned ReduceResIdx = 0;
+ unsigned DemandResIdx = 0;
- CandPolicy(): ReduceLatency(false), ReduceResIdx(0), DemandResIdx(0) {}
+ CandPolicy() = default;
bool operator==(const CandPolicy &RHS) const {
return ReduceLatency == RHS.ReduceLatency &&
@@ -800,12 +797,12 @@ public:
/// Status of an instruction's critical resource consumption.
struct SchedResourceDelta {
// Count critical resources in the scheduled region required by SU.
- unsigned CritResources;
+ unsigned CritResources = 0;
// Count critical resources from another region consumed by SU.
- unsigned DemandedResources;
+ unsigned DemandedResources = 0;
- SchedResourceDelta(): CritResources(0), DemandedResources(0) {}
+ SchedResourceDelta() = default;
bool operator==(const SchedResourceDelta &RHS) const {
return CritResources == RHS.CritResources
@@ -866,13 +863,12 @@ public:
protected:
const MachineSchedContext *Context;
- const TargetSchedModel *SchedModel;
- const TargetRegisterInfo *TRI;
+ const TargetSchedModel *SchedModel = nullptr;
+ const TargetRegisterInfo *TRI = nullptr;
SchedRemainder Rem;
- GenericSchedulerBase(const MachineSchedContext *C):
- Context(C), SchedModel(nullptr), TRI(nullptr) {}
+ GenericSchedulerBase(const MachineSchedContext *C) : Context(C) {}
void setPolicy(CandPolicy &Policy, bool IsPostRA, SchedBoundary &CurrZone,
SchedBoundary *OtherZone);
@@ -887,14 +883,14 @@ protected:
class GenericScheduler : public GenericSchedulerBase {
public:
GenericScheduler(const MachineSchedContext *C):
- GenericSchedulerBase(C), DAG(nullptr), Top(SchedBoundary::TopQID, "TopQ"),
+ GenericSchedulerBase(C), Top(SchedBoundary::TopQID, "TopQ"),
Bot(SchedBoundary::BotQID, "BotQ") {}
void initPolicy(MachineBasicBlock::iterator Begin,
MachineBasicBlock::iterator End,
unsigned NumRegionInstrs) override;
- void dumpPolicy() override;
+ void dumpPolicy() const override;
bool shouldTrackPressure() const override {
return RegionPolicy.ShouldTrackPressure;
@@ -929,7 +925,7 @@ public:
void registerRoots() override;
protected:
- ScheduleDAGMILive *DAG;
+ ScheduleDAGMILive *DAG = nullptr;
MachineSchedPolicy RegionPolicy;
@@ -1033,9 +1029,6 @@ createStoreClusterDAGMutation(const TargetInstrInfo *TII,
const TargetRegisterInfo *TRI);
std::unique_ptr<ScheduleDAGMutation>
-createMacroFusionDAGMutation(const TargetInstrInfo *TII);
-
-std::unique_ptr<ScheduleDAGMutation>
createCopyConstrainDAGMutation(const TargetInstrInfo *TII,
const TargetRegisterInfo *TRI);
diff --git a/contrib/llvm/include/llvm/CodeGen/MachineTraceMetrics.h b/contrib/llvm/include/llvm/CodeGen/MachineTraceMetrics.h
index 06db17a..284f8c1 100644
--- a/contrib/llvm/include/llvm/CodeGen/MachineTraceMetrics.h
+++ b/contrib/llvm/include/llvm/CodeGen/MachineTraceMetrics.h
@@ -49,54 +49,59 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/None.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
-#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/TargetSchedule.h"
namespace llvm {
-class InstrItineraryData;
+class AnalysisUsage;
class MachineBasicBlock;
+class MachineFunction;
class MachineInstr;
class MachineLoop;
class MachineLoopInfo;
class MachineRegisterInfo;
+struct MCSchedClassDesc;
+class raw_ostream;
class TargetInstrInfo;
class TargetRegisterInfo;
-class raw_ostream;
class MachineTraceMetrics : public MachineFunctionPass {
- const MachineFunction *MF;
- const TargetInstrInfo *TII;
- const TargetRegisterInfo *TRI;
- const MachineRegisterInfo *MRI;
- const MachineLoopInfo *Loops;
+ const MachineFunction *MF = nullptr;
+ const TargetInstrInfo *TII = nullptr;
+ const TargetRegisterInfo *TRI = nullptr;
+ const MachineRegisterInfo *MRI = nullptr;
+ const MachineLoopInfo *Loops = nullptr;
TargetSchedModel SchedModel;
public:
+ friend class Ensemble;
+ friend class Trace;
+
class Ensemble;
- class Trace;
+
static char ID;
+
MachineTraceMetrics();
+
void getAnalysisUsage(AnalysisUsage&) const override;
bool runOnMachineFunction(MachineFunction&) override;
void releaseMemory() override;
void verifyAnalysis() const override;
- friend class Ensemble;
- friend class Trace;
-
/// Per-basic block information that doesn't depend on the trace through the
/// block.
struct FixedBlockInfo {
/// The number of non-trivial instructions in the block.
/// Doesn't count PHI and COPY instructions that are likely to be removed.
- unsigned InstrCount;
+ unsigned InstrCount = ~0u;
/// True when the block contains calls.
- bool HasCalls;
+ bool HasCalls = false;
- FixedBlockInfo() : InstrCount(~0u), HasCalls(false) {}
+ FixedBlockInfo() = default;
/// Returns true when resource information for this block has been computed.
bool hasResources() const { return InstrCount != ~0u; }
@@ -134,11 +139,11 @@ public:
struct TraceBlockInfo {
/// Trace predecessor, or NULL for the first block in the trace.
/// Valid when hasValidDepth().
- const MachineBasicBlock *Pred;
+ const MachineBasicBlock *Pred = nullptr;
/// Trace successor, or NULL for the last block in the trace.
/// Valid when hasValidHeight().
- const MachineBasicBlock *Succ;
+ const MachineBasicBlock *Succ = nullptr;
/// The block number of the head of the trace. (When hasValidDepth()).
unsigned Head;
@@ -148,16 +153,13 @@ public:
/// Accumulated number of instructions in the trace above this block.
/// Does not include instructions in this block.
- unsigned InstrDepth;
+ unsigned InstrDepth = ~0u;
/// Accumulated number of instructions in the trace below this block.
/// Includes instructions in this block.
- unsigned InstrHeight;
+ unsigned InstrHeight = ~0u;
- TraceBlockInfo() :
- Pred(nullptr), Succ(nullptr),
- InstrDepth(~0u), InstrHeight(~0u),
- HasValidInstrDepths(false), HasValidInstrHeights(false) {}
+ TraceBlockInfo() = default;
/// Returns true if the depth resources have been computed from the trace
/// above this block.
@@ -199,10 +201,10 @@ public:
// itinerary data.
/// Instruction depths have been computed. This implies hasValidDepth().
- bool HasValidInstrDepths;
+ bool HasValidInstrDepths = false;
/// Instruction heights have been computed. This implies hasValidHeight().
- bool HasValidInstrHeights;
+ bool HasValidInstrHeights = false;
/// Critical path length. This is the number of cycles in the longest data
/// dependency chain through the trace. This is only valid when both
@@ -242,6 +244,7 @@ public:
public:
explicit Trace(Ensemble &te, TraceBlockInfo &tbi) : TE(te), TBI(tbi) {}
+
void print(raw_ostream&) const;
/// Compute the total number of instructions in the trace.
@@ -300,11 +303,12 @@ public:
/// strategy, for example 'minimum resource height'. There is one trace for
/// every block in the function.
class Ensemble {
+ friend class Trace;
+
SmallVector<TraceBlockInfo, 4> BlockInfo;
DenseMap<const MachineInstr*, InstrCycles> Cycles;
SmallVector<unsigned, 0> ProcResourceDepths;
SmallVector<unsigned, 0> ProcResourceHeights;
- friend class Trace;
void computeTrace(const MachineBasicBlock*);
void computeDepthResources(const MachineBasicBlock*);
@@ -317,9 +321,11 @@ public:
protected:
MachineTraceMetrics &MTM;
+
+ explicit Ensemble(MachineTraceMetrics*);
+
virtual const MachineBasicBlock *pickTracePred(const MachineBasicBlock*) =0;
virtual const MachineBasicBlock *pickTraceSucc(const MachineBasicBlock*) =0;
- explicit Ensemble(MachineTraceMetrics*);
const MachineLoop *getLoopFor(const MachineBasicBlock*) const;
const TraceBlockInfo *getDepthResources(const MachineBasicBlock*) const;
const TraceBlockInfo *getHeightResources(const MachineBasicBlock*) const;
@@ -328,7 +334,8 @@ public:
public:
virtual ~Ensemble();
- virtual const char *getName() const =0;
+
+ virtual const char *getName() const = 0;
void print(raw_ostream&) const;
void invalidate(const MachineBasicBlock *MBB);
void verify() const;
@@ -394,6 +401,7 @@ inline raw_ostream &operator<<(raw_ostream &OS,
En.print(OS);
return OS;
}
+
} // end namespace llvm
-#endif
+#endif // LLVM_CODEGEN_MACHINETRACEMETRICS_H
diff --git a/contrib/llvm/include/llvm/CodeGen/MachineValueType.h b/contrib/llvm/include/llvm/CodeGen/MachineValueType.h
index de7064f..0bdb38b 100644
--- a/contrib/llvm/include/llvm/CodeGen/MachineValueType.h
+++ b/contrib/llvm/include/llvm/CodeGen/MachineValueType.h
@@ -18,167 +18,259 @@
#include "llvm/ADT/iterator_range.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
+#include <cassert>
namespace llvm {
class Type;
- /// MVT - Machine Value Type. Every type that is supported natively by some
+ /// Machine Value Type. Every type that is supported natively by some
/// processor targeted by LLVM occurs here. This means that any legal value
/// type can be represented by an MVT.
-class MVT {
+ class MVT {
public:
- enum SimpleValueType : int8_t {
- // INVALID_SIMPLE_VALUE_TYPE - Simple value types less than zero are
- // considered extended value types.
- INVALID_SIMPLE_VALUE_TYPE = -1,
+ enum SimpleValueType : uint8_t {
+ // Simple value types that aren't explicitly part of this enumeration
+ // are considered extended value types.
+ INVALID_SIMPLE_VALUE_TYPE = 0,
// If you change this numbering, you must change the values in
// ValueTypes.td as well!
- Other = 0, // This is a non-standard value
- i1 = 1, // This is a 1 bit integer value
- i8 = 2, // This is an 8 bit integer value
- i16 = 3, // This is a 16 bit integer value
- i32 = 4, // This is a 32 bit integer value
- i64 = 5, // This is a 64 bit integer value
- i128 = 6, // This is a 128 bit integer value
+ Other = 1, // This is a non-standard value
+ i1 = 2, // This is a 1 bit integer value
+ i8 = 3, // This is an 8 bit integer value
+ i16 = 4, // This is a 16 bit integer value
+ i32 = 5, // This is a 32 bit integer value
+ i64 = 6, // This is a 64 bit integer value
+ i128 = 7, // This is a 128 bit integer value
FIRST_INTEGER_VALUETYPE = i1,
LAST_INTEGER_VALUETYPE = i128,
- f16 = 7, // This is a 16 bit floating point value
- f32 = 8, // This is a 32 bit floating point value
- f64 = 9, // This is a 64 bit floating point value
- f80 = 10, // This is a 80 bit floating point value
- f128 = 11, // This is a 128 bit floating point value
- ppcf128 = 12, // This is a PPC 128-bit floating point value
+ 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,
LAST_FP_VALUETYPE = ppcf128,
- v2i1 = 13, // 2 x i1
- v4i1 = 14, // 4 x i1
- v8i1 = 15, // 8 x i1
- v16i1 = 16, // 16 x i1
- v32i1 = 17, // 32 x i1
- v64i1 = 18, // 64 x i1
- v512i1 = 19, // 512 x i1
- v1024i1 = 20, // 1024 x i1
-
- v1i8 = 21, // 1 x i8
- v2i8 = 22, // 2 x i8
- v4i8 = 23, // 4 x i8
- v8i8 = 24, // 8 x i8
- v16i8 = 25, // 16 x i8
- v32i8 = 26, // 32 x i8
- v64i8 = 27, // 64 x i8
- v128i8 = 28, //128 x i8
- v256i8 = 29, //256 x i8
-
- v1i16 = 30, // 1 x i16
- v2i16 = 31, // 2 x i16
- v4i16 = 32, // 4 x i16
- v8i16 = 33, // 8 x i16
- v16i16 = 34, // 16 x i16
- v32i16 = 35, // 32 x i16
- v64i16 = 36, // 64 x i16
- v128i16 = 37, //128 x i16
-
- v1i32 = 38, // 1 x i32
- v2i32 = 39, // 2 x i32
- v4i32 = 40, // 4 x i32
- v8i32 = 41, // 8 x i32
- v16i32 = 42, // 16 x i32
- v32i32 = 43, // 32 x i32
- v64i32 = 44, // 64 x i32
-
- v1i64 = 45, // 1 x i64
- v2i64 = 46, // 2 x i64
- v4i64 = 47, // 4 x i64
- v8i64 = 48, // 8 x i64
- v16i64 = 49, // 16 x i64
- v32i64 = 50, // 32 x i64
-
- v1i128 = 51, // 1 x i128
-
- FIRST_INTEGER_VECTOR_VALUETYPE = v2i1,
- LAST_INTEGER_VECTOR_VALUETYPE = v1i128,
-
- v2f16 = 52, // 2 x f16
- v4f16 = 53, // 4 x f16
- v8f16 = 54, // 8 x f16
- v1f32 = 55, // 1 x f32
- v2f32 = 56, // 2 x f32
- v4f32 = 57, // 4 x f32
- v8f32 = 58, // 8 x f32
- v16f32 = 59, // 16 x f32
- v1f64 = 60, // 1 x f64
- v2f64 = 61, // 2 x f64
- v4f64 = 62, // 4 x f64
- v8f64 = 63, // 8 x f64
+ 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
+ v512i1 = 21, // 512 x i1
+ v1024i1 = 22, // 1024 x i1
+
+ v1i8 = 23, // 1 x i8
+ v2i8 = 24, // 2 x i8
+ v4i8 = 25, // 4 x i8
+ v8i8 = 26, // 8 x i8
+ v16i8 = 27, // 16 x i8
+ v32i8 = 28, // 32 x i8
+ v64i8 = 29, // 64 x i8
+ v128i8 = 30, //128 x i8
+ v256i8 = 31, //256 x i8
+
+ v1i16 = 32, // 1 x i16
+ v2i16 = 33, // 2 x i16
+ v4i16 = 34, // 4 x i16
+ v8i16 = 35, // 8 x i16
+ v16i16 = 36, // 16 x i16
+ v32i16 = 37, // 32 x i16
+ v64i16 = 38, // 64 x i16
+ v128i16 = 39, //128 x i16
+
+ v1i32 = 40, // 1 x i32
+ v2i32 = 41, // 2 x i32
+ v4i32 = 42, // 4 x i32
+ v8i32 = 43, // 8 x i32
+ v16i32 = 44, // 16 x i32
+ v32i32 = 45, // 32 x i32
+ v64i32 = 46, // 64 x i32
+
+ v1i64 = 47, // 1 x i64
+ v2i64 = 48, // 2 x i64
+ v4i64 = 49, // 4 x i64
+ v8i64 = 50, // 8 x i64
+ v16i64 = 51, // 16 x i64
+ v32i64 = 52, // 32 x i64
+
+ v1i128 = 53, // 1 x i128
+
+ // Scalable integer types
+ nxv1i1 = 54, // n x 1 x i1
+ nxv2i1 = 55, // n x 2 x i1
+ nxv4i1 = 56, // n x 4 x i1
+ nxv8i1 = 57, // n x 8 x i1
+ nxv16i1 = 58, // n x 16 x i1
+ nxv32i1 = 59, // n x 32 x i1
+
+ nxv1i8 = 60, // n x 1 x i8
+ nxv2i8 = 61, // n x 2 x i8
+ nxv4i8 = 62, // n x 4 x i8
+ nxv8i8 = 63, // n x 8 x i8
+ nxv16i8 = 64, // n x 16 x i8
+ nxv32i8 = 65, // n x 32 x i8
+
+ nxv1i16 = 66, // n x 1 x i16
+ nxv2i16 = 67, // n x 2 x i16
+ nxv4i16 = 68, // n x 4 x i16
+ nxv8i16 = 69, // n x 8 x i16
+ nxv16i16 = 70, // n x 16 x i16
+ nxv32i16 = 71, // n x 32 x i16
+
+ nxv1i32 = 72, // n x 1 x i32
+ nxv2i32 = 73, // n x 2 x i32
+ nxv4i32 = 74, // n x 4 x i32
+ nxv8i32 = 75, // n x 8 x i32
+ nxv16i32 = 76, // n x 16 x i32
+ nxv32i32 = 77, // n x 32 x i32
+
+ nxv1i64 = 78, // n x 1 x i64
+ nxv2i64 = 79, // n x 2 x i64
+ nxv4i64 = 80, // n x 4 x i64
+ nxv8i64 = 81, // n x 8 x i64
+ nxv16i64 = 82, // n x 16 x i64
+ nxv32i64 = 83, // n x 32 x i64
+
+ FIRST_INTEGER_VECTOR_VALUETYPE = v1i1,
+ LAST_INTEGER_VECTOR_VALUETYPE = nxv32i64,
+
+ FIRST_INTEGER_SCALABLE_VALUETYPE = nxv1i1,
+ LAST_INTEGER_SCALABLE_VALUETYPE = nxv32i64,
+
+ v2f16 = 84, // 2 x f16
+ v4f16 = 85, // 4 x f16
+ v8f16 = 86, // 8 x f16
+ v1f32 = 87, // 1 x f32
+ v2f32 = 88, // 2 x f32
+ v4f32 = 89, // 4 x f32
+ v8f32 = 90, // 8 x f32
+ v16f32 = 91, // 16 x f32
+ v1f64 = 92, // 1 x f64
+ v2f64 = 93, // 2 x f64
+ v4f64 = 94, // 4 x f64
+ v8f64 = 95, // 8 x f64
+
+ nxv2f16 = 96, // n x 2 x f16
+ nxv4f16 = 97, // n x 4 x f16
+ nxv8f16 = 98, // n x 8 x f16
+ nxv1f32 = 99, // n x 1 x f32
+ nxv2f32 = 100, // n x 2 x f32
+ nxv4f32 = 101, // n x 4 x f32
+ nxv8f32 = 102, // n x 8 x f32
+ nxv16f32 = 103, // n x 16 x f32
+ nxv1f64 = 104, // n x 1 x f64
+ nxv2f64 = 105, // n x 2 x f64
+ nxv4f64 = 106, // n x 4 x f64
+ nxv8f64 = 107, // n x 8 x f64
FIRST_FP_VECTOR_VALUETYPE = v2f16,
- LAST_FP_VECTOR_VALUETYPE = v8f64,
+ LAST_FP_VECTOR_VALUETYPE = nxv8f64,
- FIRST_VECTOR_VALUETYPE = v2i1,
- LAST_VECTOR_VALUETYPE = v8f64,
+ FIRST_FP_SCALABLE_VALUETYPE = nxv2f16,
+ LAST_FP_SCALABLE_VALUETYPE = nxv8f64,
- x86mmx = 64, // This is an X86 MMX value
+ FIRST_VECTOR_VALUETYPE = v1i1,
+ LAST_VECTOR_VALUETYPE = nxv8f64,
- Glue = 65, // This glues nodes together during pre-RA sched
+ x86mmx = 108, // This is an X86 MMX value
- isVoid = 66, // This has no value
+ Glue = 109, // This glues nodes together during pre-RA sched
- Untyped = 67, // This value takes a register, but has
- // unspecified type. The register class
- // will be determined by the opcode.
+ isVoid = 110, // This has no value
- FIRST_VALUETYPE = 0, // This is always the beginning of the list.
- LAST_VALUETYPE = 68, // This always remains at the end of the list.
+ Untyped = 111, // This value takes a register, but has
+ // unspecified type. The register class
+ // will be determined by the opcode.
+
+ FIRST_VALUETYPE = 1, // This is always the beginning of the list.
+ LAST_VALUETYPE = 112, // 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
// This value must be a multiple of 32.
- MAX_ALLOWED_VALUETYPE = 96,
+ MAX_ALLOWED_VALUETYPE = 128,
- // Token - A value of type llvm::TokenTy
- token = 120,
+ // A value of type llvm::TokenTy
+ token = 248,
- // Metadata - This is MDNode or MDString.
- Metadata = 121,
+ // This is MDNode or MDString.
+ Metadata = 249,
- // iPTRAny - An int value the size of the pointer of the current
+ // An int value the size of the pointer of the current
// target to any address space. This must only be used internal to
// tblgen. Other than for overloading, we treat iPTRAny the same as iPTR.
- iPTRAny = 122,
+ iPTRAny = 250,
- // vAny - A vector with any length and element size. This is used
+ // A vector with any length and element size. This is used
// for intrinsics that have overloadings based on vector types.
// This is only for tblgen's consumption!
- vAny = 123,
+ vAny = 251,
- // fAny - Any floating-point or vector floating-point value. This is used
+ // Any floating-point or vector floating-point value. This is used
// for intrinsics that have overloadings based on floating-point types.
// This is only for tblgen's consumption!
- fAny = 124,
+ fAny = 252,
- // iAny - An integer or vector integer value of any bit width. This is
+ // An integer or vector integer value of any bit width. This is
// used for intrinsics that have overloadings based on integer bit widths.
// This is only for tblgen's consumption!
- iAny = 125,
+ iAny = 253,
- // iPTR - An int value the size of the pointer of the current
+ // An int value the size of the pointer of the current
// target. This should only be used internal to tblgen!
- iPTR = 126,
+ iPTR = 254,
- // Any - Any type. This is used for intrinsics that have overloadings.
+ // Any type. This is used for intrinsics that have overloadings.
// This is only for tblgen's consumption!
- Any = 127
+ Any = 255
};
- SimpleValueType SimpleTy;
+ SimpleValueType SimpleTy = INVALID_SIMPLE_VALUE_TYPE;
+
+ // A class to represent the number of elements in a vector
+ //
+ // For fixed-length vectors, the total number of elements is equal to 'Min'
+ // For scalable vectors, the total number of elements is a multiple of 'Min'
+ class ElementCount {
+ public:
+ unsigned Min;
+ bool Scalable;
+
+ ElementCount(unsigned Min, bool Scalable)
+ : Min(Min), Scalable(Scalable) {}
+
+ ElementCount operator*(unsigned RHS) {
+ return { Min * RHS, Scalable };
+ }
+
+ ElementCount& operator*=(unsigned RHS) {
+ Min *= RHS;
+ return *this;
+ }
+
+ ElementCount operator/(unsigned RHS) {
+ return { Min / RHS, Scalable };
+ }
+
+ ElementCount& operator/=(unsigned RHS) {
+ Min /= RHS;
+ return *this;
+ }
+
+ bool operator==(const ElementCount& RHS) {
+ return Min == RHS.Min && Scalable == RHS.Scalable;
+ }
+ };
- constexpr MVT() : SimpleTy(INVALID_SIMPLE_VALUE_TYPE) {}
+ constexpr MVT() = default;
constexpr MVT(SimpleValueType SVT) : SimpleTy(SVT) {}
bool operator>(const MVT& S) const { return SimpleTy > S.SimpleTy; }
@@ -188,13 +280,13 @@ class MVT {
bool operator>=(const MVT& S) const { return SimpleTy >= S.SimpleTy; }
bool operator<=(const MVT& S) const { return SimpleTy <= S.SimpleTy; }
- /// isValid - Return true if this is a valid simple valuetype.
+ /// Return true if this is a valid simple valuetype.
bool isValid() const {
return (SimpleTy >= MVT::FIRST_VALUETYPE &&
SimpleTy < MVT::LAST_VALUETYPE);
}
- /// isFloatingPoint - Return true if this is a FP, or a vector FP type.
+ /// Return true if this is a FP or a vector FP type.
bool isFloatingPoint() const {
return ((SimpleTy >= MVT::FIRST_FP_VALUETYPE &&
SimpleTy <= MVT::LAST_FP_VALUETYPE) ||
@@ -202,7 +294,7 @@ class MVT {
SimpleTy <= MVT::LAST_FP_VECTOR_VALUETYPE));
}
- /// isInteger - Return true if this is an integer, or a vector integer type.
+ /// Return true if this is an integer or a vector integer type.
bool isInteger() const {
return ((SimpleTy >= MVT::FIRST_INTEGER_VALUETYPE &&
SimpleTy <= MVT::LAST_INTEGER_VALUETYPE) ||
@@ -210,41 +302,49 @@ class MVT {
SimpleTy <= MVT::LAST_INTEGER_VECTOR_VALUETYPE));
}
- /// isScalarInteger - Return true if this is an integer, not including
- /// vectors.
+ /// Return true if this is an integer, not including vectors.
bool isScalarInteger() const {
return (SimpleTy >= MVT::FIRST_INTEGER_VALUETYPE &&
SimpleTy <= MVT::LAST_INTEGER_VALUETYPE);
}
- /// isVector - Return true if this is a vector value type.
+ /// Return true if this is a vector value type.
bool isVector() const {
return (SimpleTy >= MVT::FIRST_VECTOR_VALUETYPE &&
SimpleTy <= MVT::LAST_VECTOR_VALUETYPE);
}
- /// is16BitVector - Return true if this is a 16-bit vector type.
+ /// Return true if this is a vector value type where the
+ /// runtime length is machine dependent
+ bool isScalableVector() const {
+ return ((SimpleTy >= MVT::FIRST_INTEGER_SCALABLE_VALUETYPE &&
+ SimpleTy <= MVT::LAST_INTEGER_SCALABLE_VALUETYPE) ||
+ (SimpleTy >= MVT::FIRST_FP_SCALABLE_VALUETYPE &&
+ SimpleTy <= MVT::LAST_FP_SCALABLE_VALUETYPE));
+ }
+
+ /// Return true if this is a 16-bit vector type.
bool is16BitVector() const {
return (SimpleTy == MVT::v2i8 || SimpleTy == MVT::v1i16 ||
SimpleTy == MVT::v16i1);
}
- /// is32BitVector - Return true if this is a 32-bit vector type.
+ /// Return true if this is a 32-bit vector type.
bool is32BitVector() const {
- return (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::v1f32);
}
- /// is64BitVector - Return true if this is a 64-bit vector type.
+ /// Return true if this is a 64-bit vector type.
bool is64BitVector() const {
- return (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::v2f32 || SimpleTy == MVT::v1f64);
}
- /// is128BitVector - Return true if this is a 128-bit vector type.
+ /// Return true if this is a 128-bit vector type.
bool is128BitVector() const {
return (SimpleTy == MVT::v16i8 || SimpleTy == MVT::v8i16 ||
SimpleTy == MVT::v4i32 || SimpleTy == MVT::v2i64 ||
@@ -252,14 +352,14 @@ class MVT {
SimpleTy == MVT::v4f32 || SimpleTy == MVT::v2f64);
}
- /// is256BitVector - Return true if this is a 256-bit vector type.
+ /// Return true if this is a 256-bit vector type.
bool is256BitVector() const {
return (SimpleTy == MVT::v8f32 || SimpleTy == MVT::v4f64 ||
SimpleTy == MVT::v32i8 || SimpleTy == MVT::v16i16 ||
SimpleTy == MVT::v8i32 || SimpleTy == MVT::v4i64);
}
- /// is512BitVector - Return true if this is a 512-bit vector type.
+ /// Return true if this is a 512-bit vector type.
bool is512BitVector() const {
return (SimpleTy == MVT::v16f32 || SimpleTy == MVT::v8f64 ||
SimpleTy == MVT::v512i1 || SimpleTy == MVT::v64i8 ||
@@ -267,34 +367,34 @@ class MVT {
SimpleTy == MVT::v8i64);
}
- /// is1024BitVector - Return true if this is a 1024-bit vector type.
+ /// 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);
}
- /// is2048BitVector - Return true if this is a 1024-bit vector type.
+ /// Return true if this is a 1024-bit vector type.
bool is2048BitVector() const {
return (SimpleTy == MVT::v256i8 || SimpleTy == MVT::v128i16 ||
SimpleTy == MVT::v64i32 || SimpleTy == MVT::v32i64);
}
- /// isOverloaded - Return true if this is an overloaded type for TableGen.
+ /// 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);
}
- /// isPow2VectorType - Returns true if the given vector is a power of 2.
+ /// Returns true if the given vector is a power of 2.
bool isPow2VectorType() const {
unsigned NElts = getVectorNumElements();
return !(NElts & (NElts - 1));
}
- /// getPow2VectorType - Widens the length of the given vector MVT up to
- /// the nearest power of 2 and returns that type.
+ /// Widens the length of the given vector MVT up to the nearest power of 2
+ /// and returns that type.
MVT getPow2VectorType() const {
if (isPow2VectorType())
return *this;
@@ -304,8 +404,7 @@ class MVT {
return MVT::getVectorVT(getVectorElementType(), Pow2NElts);
}
- /// getScalarType - If this is a vector type, return the element type,
- /// otherwise return this.
+ /// If this is a vector, return the element type, otherwise return this.
MVT getScalarType() const {
return isVector() ? getVectorElementType() : *this;
}
@@ -314,6 +413,7 @@ class MVT {
switch (SimpleTy) {
default:
llvm_unreachable("Not a vector MVT!");
+ case v1i1:
case v2i1:
case v4i1:
case v8i1:
@@ -321,7 +421,13 @@ class MVT {
case v32i1:
case v64i1:
case v512i1:
- case v1024i1: return i1;
+ case v1024i1:
+ case nxv1i1:
+ case nxv2i1:
+ case nxv4i1:
+ case nxv8i1:
+ case nxv16i1:
+ case nxv32i1: return i1;
case v1i8:
case v2i8:
case v4i8:
@@ -330,7 +436,13 @@ class MVT {
case v32i8:
case v64i8:
case v128i8:
- case v256i8: return i8;
+ case v256i8:
+ case nxv1i8:
+ case nxv2i8:
+ case nxv4i8:
+ case nxv8i8:
+ case nxv16i8:
+ case nxv32i8: return i8;
case v1i16:
case v2i16:
case v4i16:
@@ -338,33 +450,63 @@ class MVT {
case v16i16:
case v32i16:
case v64i16:
- case v128i16: return i16;
+ case v128i16:
+ case nxv1i16:
+ case nxv2i16:
+ case nxv4i16:
+ case nxv8i16:
+ case nxv16i16:
+ case nxv32i16: return i16;
case v1i32:
case v2i32:
case v4i32:
case v8i32:
case v16i32:
case v32i32:
- case v64i32: return i32;
+ case v64i32:
+ case nxv1i32:
+ case nxv2i32:
+ case nxv4i32:
+ case nxv8i32:
+ case nxv16i32:
+ case nxv32i32: return i32;
case v1i64:
case v2i64:
case v4i64:
case v8i64:
case v16i64:
- case v32i64: return i64;
+ case v32i64:
+ case nxv1i64:
+ case nxv2i64:
+ case nxv4i64:
+ case nxv8i64:
+ case nxv16i64:
+ case nxv32i64: return i64;
case v1i128: return i128;
case v2f16:
case v4f16:
- case v8f16: return f16;
+ case v8f16:
+ case nxv2f16:
+ case nxv4f16:
+ case nxv8f16: return f16;
case v1f32:
case v2f32:
case v4f32:
case v8f32:
- case v16f32: return f32;
+ case v16f32:
+ case nxv1f32:
+ case nxv2f32:
+ case nxv4f32:
+ case nxv8f32:
+ case nxv16f32: return f32;
case v1f64:
case v2f64:
case v4f64:
- case v8f64: return f64;
+ case v8f64:
+ case nxv1f64:
+ case nxv2f64:
+ case nxv4f64:
+ case nxv8f64: return f64;
}
}
@@ -385,13 +527,24 @@ class MVT {
case v32i8:
case v32i16:
case v32i32:
- case v32i64: return 32;
+ case v32i64:
+ case nxv32i1:
+ case nxv32i8:
+ case nxv32i16:
+ case nxv32i32:
+ case nxv32i64: return 32;
case v16i1:
case v16i8:
case v16i16:
case v16i32:
case v16i64:
- case v16f32: return 16;
+ case v16f32:
+ case nxv16i1:
+ case nxv16i8:
+ case nxv16i16:
+ case nxv16i32:
+ case nxv16i64:
+ case nxv16f32: return 16;
case v8i1:
case v8i8:
case v8i16:
@@ -399,7 +552,15 @@ class MVT {
case v8i64:
case v8f16:
case v8f32:
- case v8f64: return 8;
+ case v8f64:
+ case nxv8i1:
+ case nxv8i8:
+ case nxv8i16:
+ case nxv8i32:
+ case nxv8i64:
+ case nxv8f16:
+ case nxv8f32:
+ case nxv8f64: return 8;
case v4i1:
case v4i8:
case v4i16:
@@ -407,7 +568,15 @@ class MVT {
case v4i64:
case v4f16:
case v4f32:
- case v4f64: return 4;
+ case v4f64:
+ case nxv4i1:
+ case nxv4i8:
+ case nxv4i16:
+ case nxv4i32:
+ case nxv4i64:
+ case nxv4f16:
+ case nxv4f32:
+ case nxv4f64: return 4;
case v2i1:
case v2i8:
case v2i16:
@@ -415,17 +584,37 @@ class MVT {
case v2i64:
case v2f16:
case v2f32:
- case v2f64: return 2;
+ case v2f64:
+ case nxv2i1:
+ case nxv2i8:
+ case nxv2i16:
+ case nxv2i32:
+ case nxv2i64:
+ case nxv2f16:
+ case nxv2f32:
+ case nxv2f64: return 2;
+ case v1i1:
case v1i8:
case v1i16:
case v1i32:
case v1i64:
case v1i128:
case v1f32:
- case v1f64: return 1;
+ case v1f64:
+ case nxv1i1:
+ case nxv1i8:
+ case nxv1i16:
+ case nxv1i32:
+ case nxv1i64:
+ case nxv1f32:
+ case nxv1f64: return 1;
}
}
+ MVT::ElementCount getVectorElementCount() const {
+ return { getVectorNumElements(), isScalableVector() };
+ }
+
unsigned getSizeInBits() const {
switch (SimpleTy) {
default:
@@ -445,17 +634,26 @@ class MVT {
"in codegen and has no size");
case Metadata:
llvm_unreachable("Value type is metadata.");
- case i1 : return 1;
- case v2i1: return 2;
- case v4i1: return 4;
+ case i1:
+ case v1i1:
+ case nxv1i1: return 1;
+ case v2i1:
+ case nxv2i1: return 2;
+ case v4i1:
+ case nxv4i1: return 4;
case i8 :
case v1i8:
- case v8i1: return 8;
+ case v8i1:
+ case nxv1i8:
+ case nxv8i1: return 8;
case i16 :
case f16:
case v16i1:
case v2i8:
- case v1i16: return 16;
+ case v1i16:
+ case nxv16i1:
+ case nxv2i8:
+ case nxv1i16: return 16;
case f32 :
case i32 :
case v32i1:
@@ -463,7 +661,13 @@ class MVT {
case v2i16:
case v2f16:
case v1f32:
- case v1i32: return 32;
+ case v1i32:
+ case nxv32i1:
+ case nxv4i8:
+ case nxv2i16:
+ case nxv1i32:
+ case nxv2f16:
+ case nxv1f32: return 32;
case x86mmx:
case f64 :
case i64 :
@@ -474,7 +678,14 @@ class MVT {
case v1i64:
case v4f16:
case v2f32:
- case v1f64: return 64;
+ case v1f64:
+ case nxv8i8:
+ case nxv4i16:
+ case nxv2i32:
+ case nxv1i64:
+ case nxv4f16:
+ case nxv2f32:
+ case nxv1f64: return 64;
case f80 : return 80;
case f128:
case ppcf128:
@@ -486,29 +697,50 @@ class MVT {
case v1i128:
case v8f16:
case v4f32:
- case v2f64: return 128;
+ case v2f64:
+ case nxv16i8:
+ case nxv8i16:
+ case nxv4i32:
+ case nxv2i64:
+ case nxv8f16:
+ case nxv4f32:
+ case nxv2f64: return 128;
case v32i8:
case v16i16:
case v8i32:
case v4i64:
case v8f32:
- case v4f64: return 256;
+ case v4f64:
+ case nxv32i8:
+ case nxv16i16:
+ case nxv8i32:
+ case nxv4i64:
+ case nxv8f32:
+ case nxv4f64: return 256;
case v512i1:
case v64i8:
case v32i16:
case v16i32:
case v8i64:
case v16f32:
- case v8f64: return 512;
+ case v8f64:
+ case nxv32i16:
+ case nxv16i32:
+ case nxv8i64:
+ case nxv16f32:
+ case nxv8f64: return 512;
case v1024i1:
case v128i8:
case v64i16:
case v32i32:
- case v16i64: return 1024;
+ case v16i64:
+ case nxv32i32:
+ case nxv16i64: return 1024;
case v256i8:
case v128i16:
case v64i32:
- case v32i64: return 2048;
+ case v32i64:
+ case nxv32i64: return 2048;
}
}
@@ -516,14 +748,14 @@ class MVT {
return getScalarType().getSizeInBits();
}
- /// getStoreSize - Return the number of bytes overwritten by a store
- /// of the specified value type.
+ /// Return the number of bytes overwritten by a store of the specified value
+ /// type.
unsigned getStoreSize() const {
return (getSizeInBits() + 7) / 8;
}
- /// getStoreSizeInBits - Return the number of bits overwritten by a store
- /// of the specified value type.
+ /// Return the number of bits overwritten by a store of the specified value
+ /// type.
unsigned getStoreSizeInBits() const {
return getStoreSize() * 8;
}
@@ -548,7 +780,6 @@ class MVT {
return getSizeInBits() <= VT.getSizeInBits();
}
-
static MVT getFloatingPointVT(unsigned BitWidth) {
switch (BitWidth) {
default:
@@ -590,6 +821,7 @@ class MVT {
default:
break;
case MVT::i1:
+ if (NumElements == 1) return MVT::v1i1;
if (NumElements == 2) return MVT::v2i1;
if (NumElements == 4) return MVT::v4i1;
if (NumElements == 8) return MVT::v8i1;
@@ -662,6 +894,84 @@ class MVT {
return (MVT::SimpleValueType)(MVT::INVALID_SIMPLE_VALUE_TYPE);
}
+ static MVT getScalableVectorVT(MVT VT, unsigned NumElements) {
+ switch(VT.SimpleTy) {
+ default:
+ break;
+ case MVT::i1:
+ if (NumElements == 1) return MVT::nxv1i1;
+ if (NumElements == 2) return MVT::nxv2i1;
+ if (NumElements == 4) return MVT::nxv4i1;
+ if (NumElements == 8) return MVT::nxv8i1;
+ if (NumElements == 16) return MVT::nxv16i1;
+ if (NumElements == 32) return MVT::nxv32i1;
+ break;
+ case MVT::i8:
+ if (NumElements == 1) return MVT::nxv1i8;
+ if (NumElements == 2) return MVT::nxv2i8;
+ if (NumElements == 4) return MVT::nxv4i8;
+ if (NumElements == 8) return MVT::nxv8i8;
+ if (NumElements == 16) return MVT::nxv16i8;
+ if (NumElements == 32) return MVT::nxv32i8;
+ break;
+ case MVT::i16:
+ if (NumElements == 1) return MVT::nxv1i16;
+ if (NumElements == 2) return MVT::nxv2i16;
+ if (NumElements == 4) return MVT::nxv4i16;
+ if (NumElements == 8) return MVT::nxv8i16;
+ if (NumElements == 16) return MVT::nxv16i16;
+ if (NumElements == 32) return MVT::nxv32i16;
+ break;
+ case MVT::i32:
+ if (NumElements == 1) return MVT::nxv1i32;
+ if (NumElements == 2) return MVT::nxv2i32;
+ if (NumElements == 4) return MVT::nxv4i32;
+ if (NumElements == 8) return MVT::nxv8i32;
+ if (NumElements == 16) return MVT::nxv16i32;
+ if (NumElements == 32) return MVT::nxv32i32;
+ break;
+ case MVT::i64:
+ if (NumElements == 1) return MVT::nxv1i64;
+ if (NumElements == 2) return MVT::nxv2i64;
+ if (NumElements == 4) return MVT::nxv4i64;
+ if (NumElements == 8) return MVT::nxv8i64;
+ if (NumElements == 16) return MVT::nxv16i64;
+ if (NumElements == 32) return MVT::nxv32i64;
+ break;
+ case MVT::f16:
+ if (NumElements == 2) return MVT::nxv2f16;
+ if (NumElements == 4) return MVT::nxv4f16;
+ if (NumElements == 8) return MVT::nxv8f16;
+ break;
+ case MVT::f32:
+ if (NumElements == 1) return MVT::nxv1f32;
+ if (NumElements == 2) return MVT::nxv2f32;
+ if (NumElements == 4) return MVT::nxv4f32;
+ if (NumElements == 8) return MVT::nxv8f32;
+ if (NumElements == 16) return MVT::nxv16f32;
+ break;
+ case MVT::f64:
+ if (NumElements == 1) return MVT::nxv1f64;
+ if (NumElements == 2) return MVT::nxv2f64;
+ if (NumElements == 4) return MVT::nxv4f64;
+ if (NumElements == 8) return MVT::nxv8f64;
+ break;
+ }
+ return (MVT::SimpleValueType)(MVT::INVALID_SIMPLE_VALUE_TYPE);
+ }
+
+ static MVT getVectorVT(MVT VT, unsigned NumElements, bool IsScalable) {
+ if (IsScalable)
+ return getScalableVectorVT(VT, NumElements);
+ return getVectorVT(VT, NumElements);
+ }
+
+ static MVT getVectorVT(MVT VT, MVT::ElementCount EC) {
+ if (EC.Scalable)
+ return getScalableVectorVT(VT, EC.Min);
+ return getVectorVT(VT, EC.Min);
+ }
+
/// Return the value type corresponding to the specified type. This returns
/// all pointers as iPTR. If HandleUnknown is true, unknown types are
/// returned as Other, otherwise they are invalid.
@@ -671,9 +981,12 @@ class MVT {
/// A simple iterator over the MVT::SimpleValueType enum.
struct mvt_iterator {
SimpleValueType VT;
+
mvt_iterator(SimpleValueType VT) : VT(VT) {}
+
MVT operator*() const { return VT; }
bool operator!=(const mvt_iterator &LHS) const { return VT != LHS.VT; }
+
mvt_iterator& operator++() {
VT = (MVT::SimpleValueType)((int)VT + 1);
assert((int)VT <= MVT::MAX_ALLOWED_VALUETYPE &&
@@ -681,8 +994,9 @@ class MVT {
return *this;
}
};
+
/// A range of the MVT::SimpleValueType enum.
- typedef iterator_range<mvt_iterator> mvt_range;
+ using mvt_range = iterator_range<mvt_iterator>;
public:
/// SimpleValueType Iteration
@@ -690,31 +1004,46 @@ class MVT {
static mvt_range all_valuetypes() {
return mvt_range(MVT::FIRST_VALUETYPE, MVT::LAST_VALUETYPE);
}
+
static mvt_range integer_valuetypes() {
return mvt_range(MVT::FIRST_INTEGER_VALUETYPE,
(MVT::SimpleValueType)(MVT::LAST_INTEGER_VALUETYPE + 1));
}
+
static mvt_range fp_valuetypes() {
return mvt_range(MVT::FIRST_FP_VALUETYPE,
(MVT::SimpleValueType)(MVT::LAST_FP_VALUETYPE + 1));
}
+
static mvt_range vector_valuetypes() {
return mvt_range(MVT::FIRST_VECTOR_VALUETYPE,
(MVT::SimpleValueType)(MVT::LAST_VECTOR_VALUETYPE + 1));
}
+
static mvt_range integer_vector_valuetypes() {
return mvt_range(
MVT::FIRST_INTEGER_VECTOR_VALUETYPE,
(MVT::SimpleValueType)(MVT::LAST_INTEGER_VECTOR_VALUETYPE + 1));
}
+
static mvt_range fp_vector_valuetypes() {
return mvt_range(
MVT::FIRST_FP_VECTOR_VALUETYPE,
(MVT::SimpleValueType)(MVT::LAST_FP_VECTOR_VALUETYPE + 1));
}
+
+ static mvt_range integer_scalable_vector_valuetypes() {
+ return mvt_range(MVT::FIRST_INTEGER_SCALABLE_VALUETYPE,
+ (MVT::SimpleValueType)(MVT::LAST_INTEGER_SCALABLE_VALUETYPE + 1));
+ }
+
+ static mvt_range fp_scalable_vector_valuetypes() {
+ return mvt_range(MVT::FIRST_FP_SCALABLE_VALUETYPE,
+ (MVT::SimpleValueType)(MVT::LAST_FP_SCALABLE_VALUETYPE + 1));
+ }
/// @}
};
-} // End llvm namespace
+} // end namespace llvm
-#endif
+#endif // LLVM_CODEGEN_MACHINEVALUETYPE_H
diff --git a/contrib/llvm/include/llvm/CodeGen/MacroFusion.h b/contrib/llvm/include/llvm/CodeGen/MacroFusion.h
new file mode 100644
index 0000000..dc105fd
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/MacroFusion.h
@@ -0,0 +1,50 @@
+//===- MacroFusion.h - Macro Fusion -----------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+/// \file This file contains the definition of the DAG scheduling mutation to
+/// pair instructions back to back.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACROFUSION_H
+#define LLVM_CODEGEN_MACROFUSION_H
+
+#include <functional>
+#include <memory>
+
+namespace llvm {
+
+class MachineInstr;
+class ScheduleDAGMutation;
+class TargetInstrInfo;
+class TargetSubtargetInfo;
+
+/// \brief Check if the instr pair, FirstMI and SecondMI, should be fused
+/// together. Given SecondMI, when FirstMI is unspecified, then check if
+/// SecondMI may be part of a fused pair at all.
+using ShouldSchedulePredTy = std::function<bool(const TargetInstrInfo &TII,
+ const TargetSubtargetInfo &TSI,
+ const MachineInstr *FirstMI,
+ const MachineInstr &SecondMI)>;
+
+/// \brief Create a DAG scheduling mutation to pair instructions back to back
+/// for instructions that benefit according to the target-specific
+/// shouldScheduleAdjacent predicate function.
+std::unique_ptr<ScheduleDAGMutation>
+createMacroFusionDAGMutation(ShouldSchedulePredTy shouldScheduleAdjacent);
+
+/// \brief Create a DAG scheduling mutation to pair branch instructions with one
+/// of their predecessors back to back for instructions that benefit according
+/// to the target-specific shouldScheduleAdjacent predicate function.
+std::unique_ptr<ScheduleDAGMutation>
+createBranchMacroFusionDAGMutation(ShouldSchedulePredTy shouldScheduleAdjacent);
+
+} // end namespace llvm
+
+#endif // LLVM_CODEGEN_MACROFUSION_H
diff --git a/contrib/llvm/include/llvm/CodeGen/PBQP/CostAllocator.h b/contrib/llvm/include/llvm/CodeGen/PBQP/CostAllocator.h
index 02d39fe..bde451a 100644
--- a/contrib/llvm/include/llvm/CodeGen/PBQP/CostAllocator.h
+++ b/contrib/llvm/include/llvm/CodeGen/PBQP/CostAllocator.h
@@ -1,4 +1,4 @@
-//===---------- CostAllocator.h - PBQP Cost Allocator -----------*- C++ -*-===//
+//===- CostAllocator.h - PBQP Cost Allocator --------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -19,26 +19,28 @@
#define LLVM_CODEGEN_PBQP_COSTALLOCATOR_H
#include "llvm/ADT/DenseSet.h"
+#include <algorithm>
+#include <cstdint>
#include <memory>
-#include <type_traits>
namespace llvm {
namespace PBQP {
-template <typename ValueT>
-class ValuePool {
+template <typename ValueT> class ValuePool {
public:
- typedef std::shared_ptr<const ValueT> PoolRef;
+ using PoolRef = std::shared_ptr<const ValueT>;
private:
-
class PoolEntry : public std::enable_shared_from_this<PoolEntry> {
public:
template <typename ValueKeyT>
PoolEntry(ValuePool &Pool, ValueKeyT Value)
: Pool(Pool), Value(std::move(Value)) {}
+
~PoolEntry() { Pool.removeEntry(this); }
- const ValueT& getValue() const { return Value; }
+
+ const ValueT &getValue() const { return Value; }
+
private:
ValuePool &Pool;
ValueT Value;
@@ -46,10 +48,10 @@ private:
class PoolEntryDSInfo {
public:
- static inline PoolEntry* getEmptyKey() { return nullptr; }
+ static inline PoolEntry *getEmptyKey() { return nullptr; }
- static inline PoolEntry* getTombstoneKey() {
- return reinterpret_cast<PoolEntry*>(static_cast<uintptr_t>(1));
+ static inline PoolEntry *getTombstoneKey() {
+ return reinterpret_cast<PoolEntry *>(static_cast<uintptr_t>(1));
}
template <typename ValueKeyT>
@@ -66,8 +68,7 @@ private:
}
template <typename ValueKeyT1, typename ValueKeyT2>
- static
- bool isEqual(const ValueKeyT1 &C1, const ValueKeyT2 &C2) {
+ static bool isEqual(const ValueKeyT1 &C1, const ValueKeyT2 &C2) {
return C1 == C2;
}
@@ -83,10 +84,9 @@ private:
return P1 == P2;
return isEqual(P1->getValue(), P2);
}
-
};
- typedef DenseSet<PoolEntry*, PoolEntryDSInfo> EntrySetT;
+ using EntrySetT = DenseSet<PoolEntry *, PoolEntryDSInfo>;
EntrySetT EntrySet;
@@ -105,28 +105,31 @@ public:
}
};
-template <typename VectorT, typename MatrixT>
-class PoolCostAllocator {
+template <typename VectorT, typename MatrixT> class PoolCostAllocator {
private:
- typedef ValuePool<VectorT> VectorCostPool;
- typedef ValuePool<MatrixT> MatrixCostPool;
+ using VectorCostPool = ValuePool<VectorT>;
+ using MatrixCostPool = ValuePool<MatrixT>;
+
public:
- typedef VectorT Vector;
- typedef MatrixT Matrix;
- typedef typename VectorCostPool::PoolRef VectorPtr;
- typedef typename MatrixCostPool::PoolRef MatrixPtr;
+ using Vector = VectorT;
+ using Matrix = MatrixT;
+ using VectorPtr = typename VectorCostPool::PoolRef;
+ using MatrixPtr = typename MatrixCostPool::PoolRef;
+
+ template <typename VectorKeyT> VectorPtr getVector(VectorKeyT v) {
+ return VectorPool.getValue(std::move(v));
+ }
- template <typename VectorKeyT>
- VectorPtr getVector(VectorKeyT v) { return VectorPool.getValue(std::move(v)); }
+ template <typename MatrixKeyT> MatrixPtr getMatrix(MatrixKeyT m) {
+ return MatrixPool.getValue(std::move(m));
+ }
- template <typename MatrixKeyT>
- MatrixPtr getMatrix(MatrixKeyT m) { return MatrixPool.getValue(std::move(m)); }
private:
VectorCostPool VectorPool;
MatrixCostPool MatrixPool;
};
-} // namespace PBQP
-} // namespace llvm
+} // end namespace PBQP
+} // end namespace llvm
-#endif
+#endif // LLVM_CODEGEN_PBQP_COSTALLOCATOR_H
diff --git a/contrib/llvm/include/llvm/CodeGen/PBQP/Graph.h b/contrib/llvm/include/llvm/CodeGen/PBQP/Graph.h
index 83487e6..e94878c 100644
--- a/contrib/llvm/include/llvm/CodeGen/PBQP/Graph.h
+++ b/contrib/llvm/include/llvm/CodeGen/PBQP/Graph.h
@@ -1,4 +1,4 @@
-//===-------------------- Graph.h - PBQP Graph ------------------*- C++ -*-===//
+//===- Graph.h - PBQP Graph -------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -11,16 +11,14 @@
//
//===----------------------------------------------------------------------===//
-
#ifndef LLVM_CODEGEN_PBQP_GRAPH_H
#define LLVM_CODEGEN_PBQP_GRAPH_H
#include "llvm/ADT/STLExtras.h"
-#include "llvm/Support/Debug.h"
#include <algorithm>
#include <cassert>
+#include <iterator>
#include <limits>
-#include <utility>
#include <vector>
namespace llvm {
@@ -28,8 +26,8 @@ namespace PBQP {
class GraphBase {
public:
- typedef unsigned NodeId;
- typedef unsigned EdgeId;
+ using NodeId = unsigned;
+ using EdgeId = unsigned;
/// @brief Returns a value representing an invalid (non-existent) node.
static NodeId invalidNodeId() {
@@ -48,32 +46,32 @@ namespace PBQP {
template <typename SolverT>
class Graph : public GraphBase {
private:
- typedef typename SolverT::CostAllocator CostAllocator;
+ using CostAllocator = typename SolverT::CostAllocator;
+
public:
- typedef typename SolverT::RawVector RawVector;
- typedef typename SolverT::RawMatrix RawMatrix;
- typedef typename SolverT::Vector Vector;
- typedef typename SolverT::Matrix Matrix;
- typedef typename CostAllocator::VectorPtr VectorPtr;
- typedef typename CostAllocator::MatrixPtr MatrixPtr;
- typedef typename SolverT::NodeMetadata NodeMetadata;
- typedef typename SolverT::EdgeMetadata EdgeMetadata;
- typedef typename SolverT::GraphMetadata GraphMetadata;
+ using RawVector = typename SolverT::RawVector;
+ using RawMatrix = typename SolverT::RawMatrix;
+ using Vector = typename SolverT::Vector;
+ using Matrix = typename SolverT::Matrix;
+ using VectorPtr = typename CostAllocator::VectorPtr;
+ using MatrixPtr = typename CostAllocator::MatrixPtr;
+ using NodeMetadata = typename SolverT::NodeMetadata;
+ using EdgeMetadata = typename SolverT::EdgeMetadata;
+ using GraphMetadata = typename SolverT::GraphMetadata;
private:
-
class NodeEntry {
public:
- typedef std::vector<EdgeId> AdjEdgeList;
- typedef AdjEdgeList::size_type AdjEdgeIdx;
- typedef AdjEdgeList::const_iterator AdjEdgeItr;
+ using AdjEdgeList = std::vector<EdgeId>;
+ using AdjEdgeIdx = AdjEdgeList::size_type;
+ using AdjEdgeItr = AdjEdgeList::const_iterator;
+
+ NodeEntry(VectorPtr Costs) : Costs(std::move(Costs)) {}
static AdjEdgeIdx getInvalidAdjEdgeIdx() {
return std::numeric_limits<AdjEdgeIdx>::max();
}
- NodeEntry(VectorPtr Costs) : Costs(std::move(Costs)) {}
-
AdjEdgeIdx addAdjEdgeId(EdgeId EId) {
AdjEdgeIdx Idx = AdjEdgeIds.size();
AdjEdgeIds.push_back(EId);
@@ -96,6 +94,7 @@ namespace PBQP {
VectorPtr Costs;
NodeMetadata Metadata;
+
private:
AdjEdgeList AdjEdgeIds;
};
@@ -150,8 +149,10 @@ namespace PBQP {
NodeId getN1Id() const { return NIds[0]; }
NodeId getN2Id() const { return NIds[1]; }
+
MatrixPtr Costs;
EdgeMetadata Metadata;
+
private:
NodeId NIds[2];
typename NodeEntry::AdjEdgeIdx ThisEdgeAdjIdxs[2];
@@ -161,18 +162,20 @@ namespace PBQP {
GraphMetadata Metadata;
CostAllocator CostAlloc;
- SolverT *Solver;
+ SolverT *Solver = nullptr;
- typedef std::vector<NodeEntry> NodeVector;
- typedef std::vector<NodeId> FreeNodeVector;
+ using NodeVector = std::vector<NodeEntry>;
+ using FreeNodeVector = std::vector<NodeId>;
NodeVector Nodes;
FreeNodeVector FreeNodeIds;
- typedef std::vector<EdgeEntry> EdgeVector;
- typedef std::vector<EdgeId> FreeEdgeVector;
+ using EdgeVector = std::vector<EdgeEntry>;
+ using FreeEdgeVector = std::vector<EdgeId>;
EdgeVector Edges;
FreeEdgeVector FreeEdgeIds;
+ Graph(const Graph &Other) {}
+
// ----- INTERNAL METHODS -----
NodeEntry &getNode(NodeId NId) {
@@ -220,20 +223,18 @@ namespace PBQP {
return EId;
}
- Graph(const Graph &Other) {}
void operator=(const Graph &Other) {}
public:
-
- typedef typename NodeEntry::AdjEdgeItr AdjEdgeItr;
+ using AdjEdgeItr = typename NodeEntry::AdjEdgeItr;
class NodeItr {
public:
- typedef std::forward_iterator_tag iterator_category;
- typedef NodeId value_type;
- typedef int difference_type;
- typedef NodeId* pointer;
- typedef NodeId& reference;
+ using iterator_category = std::forward_iterator_tag;
+ using value_type = NodeId;
+ using difference_type = int;
+ using pointer = NodeId *;
+ using reference = NodeId &;
NodeItr(NodeId CurNId, const Graph &G)
: CurNId(CurNId), EndNId(G.Nodes.size()), FreeNodeIds(G.FreeNodeIds) {
@@ -283,53 +284,65 @@ namespace PBQP {
class NodeIdSet {
public:
- NodeIdSet(const Graph &G) : G(G) { }
+ NodeIdSet(const Graph &G) : G(G) {}
+
NodeItr begin() const { return NodeItr(0, G); }
NodeItr end() const { return NodeItr(G.Nodes.size(), G); }
+
bool empty() const { return G.Nodes.empty(); }
+
typename NodeVector::size_type size() const {
return G.Nodes.size() - G.FreeNodeIds.size();
}
+
private:
const Graph& G;
};
class EdgeIdSet {
public:
- EdgeIdSet(const Graph &G) : G(G) { }
+ EdgeIdSet(const Graph &G) : G(G) {}
+
EdgeItr begin() const { return EdgeItr(0, G); }
EdgeItr end() const { return EdgeItr(G.Edges.size(), G); }
+
bool empty() const { return G.Edges.empty(); }
+
typename NodeVector::size_type size() const {
return G.Edges.size() - G.FreeEdgeIds.size();
}
+
private:
const Graph& G;
};
class AdjEdgeIdSet {
public:
- AdjEdgeIdSet(const NodeEntry &NE) : NE(NE) { }
+ AdjEdgeIdSet(const NodeEntry &NE) : NE(NE) {}
+
typename NodeEntry::AdjEdgeItr begin() const {
return NE.getAdjEdgeIds().begin();
}
+
typename NodeEntry::AdjEdgeItr end() const {
return NE.getAdjEdgeIds().end();
}
+
bool empty() const { return NE.getAdjEdgeIds().empty(); }
+
typename NodeEntry::AdjEdgeList::size_type size() const {
return NE.getAdjEdgeIds().size();
}
+
private:
const NodeEntry &NE;
};
/// @brief Construct an empty PBQP graph.
- Graph() : Solver(nullptr) {}
+ Graph() = default;
/// @brief Construct an empty PBQP graph with the given graph metadata.
- Graph(GraphMetadata Metadata)
- : Metadata(std::move(Metadata)), Solver(nullptr) {}
+ Graph(GraphMetadata Metadata) : Metadata(std::move(Metadata)) {}
/// @brief Get a reference to the graph metadata.
GraphMetadata& getMetadata() { return Metadata; }
@@ -656,7 +669,7 @@ namespace PBQP {
}
};
-} // namespace PBQP
-} // namespace llvm
+} // end namespace PBQP
+} // end namespace llvm
#endif // LLVM_CODEGEN_PBQP_GRAPH_HPP
diff --git a/contrib/llvm/include/llvm/CodeGen/PBQP/Math.h b/contrib/llvm/include/llvm/CodeGen/PBQP/Math.h
index 2787875..ba405e8 100644
--- a/contrib/llvm/include/llvm/CodeGen/PBQP/Math.h
+++ b/contrib/llvm/include/llvm/CodeGen/PBQP/Math.h
@@ -1,4 +1,4 @@
-//===------ Math.h - PBQP Vector and Matrix classes -------------*- C++ -*-===//
+//===- Math.h - PBQP Vector and Matrix classes ------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -11,20 +11,22 @@
#define LLVM_CODEGEN_PBQP_MATH_H
#include "llvm/ADT/Hashing.h"
+#include "llvm/ADT/STLExtras.h"
#include <algorithm>
#include <cassert>
#include <functional>
+#include <memory>
namespace llvm {
namespace PBQP {
-typedef float PBQPNum;
+using PBQPNum = float;
/// \brief PBQP Vector class.
class Vector {
friend hash_code hash_value(const Vector &);
-public:
+public:
/// \brief Construct a PBQP vector of the given size.
explicit Vector(unsigned Length)
: Length(Length), Data(llvm::make_unique<PBQPNum []>(Length)) {}
@@ -120,8 +122,8 @@ OStream& operator<<(OStream &OS, const Vector &V) {
class Matrix {
private:
friend hash_code hash_value(const Matrix &);
-public:
+public:
/// \brief Construct a PBQP Matrix with the given dimensions.
Matrix(unsigned Rows, unsigned Cols) :
Rows(Rows), Cols(Cols), Data(llvm::make_unique<PBQPNum []>(Rows * Cols)) {
@@ -253,9 +255,11 @@ OStream& operator<<(OStream &OS, const Matrix &M) {
template <typename Metadata>
class MDVector : public Vector {
public:
- MDVector(const Vector &v) : Vector(v), md(*this) { }
+ MDVector(const Vector &v) : Vector(v), md(*this) {}
MDVector(Vector &&v) : Vector(std::move(v)), md(*this) { }
+
const Metadata& getMetadata() const { return md; }
+
private:
Metadata md;
};
@@ -268,9 +272,11 @@ inline hash_code hash_value(const MDVector<Metadata> &V) {
template <typename Metadata>
class MDMatrix : public Matrix {
public:
- MDMatrix(const Matrix &m) : Matrix(m), md(*this) { }
+ MDMatrix(const Matrix &m) : Matrix(m), md(*this) {}
MDMatrix(Matrix &&m) : Matrix(std::move(m)), md(*this) { }
+
const Metadata& getMetadata() const { return md; }
+
private:
Metadata md;
};
@@ -280,7 +286,7 @@ inline hash_code hash_value(const MDMatrix<Metadata> &M) {
return hash_value(static_cast<const Matrix&>(M));
}
-} // namespace PBQP
-} // namespace llvm
+} // end namespace PBQP
+} // end namespace llvm
#endif // LLVM_CODEGEN_PBQP_MATH_H
diff --git a/contrib/llvm/include/llvm/CodeGen/PBQP/ReductionRules.h b/contrib/llvm/include/llvm/CodeGen/PBQP/ReductionRules.h
index d4a544b..8aeb519 100644
--- a/contrib/llvm/include/llvm/CodeGen/PBQP/ReductionRules.h
+++ b/contrib/llvm/include/llvm/CodeGen/PBQP/ReductionRules.h
@@ -1,4 +1,4 @@
-//===----------- ReductionRules.h - Reduction Rules -------------*- C++ -*-===//
+//===- ReductionRules.h - Reduction Rules -----------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -17,6 +17,8 @@
#include "Graph.h"
#include "Math.h"
#include "Solution.h"
+#include <cassert>
+#include <limits>
namespace llvm {
namespace PBQP {
@@ -27,11 +29,11 @@ namespace PBQP {
/// neighbor. Notify the problem domain.
template <typename GraphT>
void applyR1(GraphT &G, typename GraphT::NodeId NId) {
- typedef typename GraphT::NodeId NodeId;
- typedef typename GraphT::EdgeId EdgeId;
- typedef typename GraphT::Vector Vector;
- typedef typename GraphT::Matrix Matrix;
- typedef typename GraphT::RawVector RawVector;
+ using NodeId = typename GraphT::NodeId;
+ using EdgeId = typename GraphT::EdgeId;
+ using Vector = typename GraphT::Vector;
+ using Matrix = typename GraphT::Matrix;
+ using RawVector = typename GraphT::RawVector;
assert(G.getNodeDegree(NId) == 1 &&
"R1 applied to node with degree != 1.");
@@ -71,11 +73,11 @@ namespace PBQP {
template <typename GraphT>
void applyR2(GraphT &G, typename GraphT::NodeId NId) {
- typedef typename GraphT::NodeId NodeId;
- typedef typename GraphT::EdgeId EdgeId;
- typedef typename GraphT::Vector Vector;
- typedef typename GraphT::Matrix Matrix;
- typedef typename GraphT::RawMatrix RawMatrix;
+ using NodeId = typename GraphT::NodeId;
+ using EdgeId = typename GraphT::EdgeId;
+ using Vector = typename GraphT::Vector;
+ using Matrix = typename GraphT::Matrix;
+ using RawMatrix = typename GraphT::RawMatrix;
assert(G.getNodeDegree(NId) == 2 &&
"R2 applied to node with degree != 2.");
@@ -177,9 +179,9 @@ namespace PBQP {
// state.
template <typename GraphT, typename StackT>
Solution backpropagate(GraphT& G, StackT stack) {
- typedef GraphBase::NodeId NodeId;
- typedef typename GraphT::Matrix Matrix;
- typedef typename GraphT::RawVector RawVector;
+ using NodeId = GraphBase::NodeId;
+ using Matrix = typename GraphT::Matrix;
+ using RawVector = typename GraphT::RawVector;
Solution s;
@@ -215,7 +217,7 @@ namespace PBQP {
return s;
}
-} // namespace PBQP
-} // namespace llvm
+} // end namespace PBQP
+} // end namespace llvm
-#endif
+#endif // LLVM_CODEGEN_PBQP_REDUCTIONRULES_H
diff --git a/contrib/llvm/include/llvm/CodeGen/PBQP/Solution.h b/contrib/llvm/include/llvm/CodeGen/PBQP/Solution.h
index bd74805..8d5d237 100644
--- a/contrib/llvm/include/llvm/CodeGen/PBQP/Solution.h
+++ b/contrib/llvm/include/llvm/CodeGen/PBQP/Solution.h
@@ -1,4 +1,4 @@
-//===-- Solution.h ------- PBQP Solution ------------------------*- C++ -*-===//
+//===- Solution.h - PBQP Solution -------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,8 +14,8 @@
#ifndef LLVM_CODEGEN_PBQP_SOLUTION_H
#define LLVM_CODEGEN_PBQP_SOLUTION_H
-#include "Graph.h"
-#include "Math.h"
+#include "llvm/CodeGen/PBQP/Graph.h"
+#include <cassert>
#include <map>
namespace llvm {
@@ -26,17 +26,17 @@ namespace PBQP {
/// To get the selection for each node in the problem use the getSelection method.
class Solution {
private:
-
- typedef std::map<GraphBase::NodeId, unsigned> SelectionsMap;
+ using SelectionsMap = std::map<GraphBase::NodeId, unsigned>;
SelectionsMap selections;
- unsigned r0Reductions, r1Reductions, r2Reductions, rNReductions;
+ unsigned r0Reductions = 0;
+ unsigned r1Reductions = 0;
+ unsigned r2Reductions = 0;
+ unsigned rNReductions = 0;
public:
-
/// \brief Initialise an empty solution.
- Solution()
- : r0Reductions(0), r1Reductions(0), r2Reductions(0), rNReductions(0) {}
+ Solution() = default;
/// \brief Set the selection for a given node.
/// @param nodeId Node id.
@@ -53,10 +53,9 @@ namespace PBQP {
assert(sItr != selections.end() && "No selection for node.");
return sItr->second;
}
-
};
-} // namespace PBQP
-} // namespace llvm
+} // end namespace PBQP
+} // end namespace llvm
#endif // LLVM_CODEGEN_PBQP_SOLUTION_H
diff --git a/contrib/llvm/include/llvm/CodeGen/PBQPRAConstraint.h b/contrib/llvm/include/llvm/CodeGen/PBQPRAConstraint.h
index 833b9ba..269b7a7 100644
--- a/contrib/llvm/include/llvm/CodeGen/PBQPRAConstraint.h
+++ b/contrib/llvm/include/llvm/CodeGen/PBQPRAConstraint.h
@@ -1,4 +1,4 @@
-//===-- RegAllocPBQP.h ------------------------------------------*- C++ -*-===//
+//===- RegAllocPBQP.h -------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -16,23 +16,22 @@
#ifndef LLVM_CODEGEN_PBQPRACONSTRAINT_H
#define LLVM_CODEGEN_PBQPRACONSTRAINT_H
+#include <algorithm>
#include <memory>
#include <vector>
namespace llvm {
+
namespace PBQP {
namespace RegAlloc {
+
// Forward declare PBQP graph class.
class PBQPRAGraph;
-}
-}
-class LiveIntervals;
-class MachineBlockFrequencyInfo;
-class MachineFunction;
-class TargetRegisterInfo;
+} // end namespace RegAlloc
+} // end namespace PBQP
-typedef PBQP::RegAlloc::PBQPRAGraph PBQPRAGraph;
+using PBQPRAGraph = PBQP::RegAlloc::PBQPRAGraph;
/// @brief Abstract base for classes implementing PBQP register allocation
/// constraints (e.g. Spill-costs, interference, coalescing).
@@ -40,6 +39,7 @@ class PBQPRAConstraint {
public:
virtual ~PBQPRAConstraint() = 0;
virtual void apply(PBQPRAGraph &G) = 0;
+
private:
virtual void anchor();
};
@@ -59,11 +59,13 @@ public:
if (C)
Constraints.push_back(std::move(C));
}
+
private:
std::vector<std::unique_ptr<PBQPRAConstraint>> Constraints;
+
void anchor() override;
};
-}
+} // end namespace llvm
-#endif /* LLVM_CODEGEN_PBQPRACONSTRAINT_H */
+#endif // LLVM_CODEGEN_PBQPRACONSTRAINT_H
diff --git a/contrib/llvm/include/llvm/CodeGen/Passes.h b/contrib/llvm/include/llvm/CodeGen/Passes.h
index a9fd301..96cfce5 100644
--- a/contrib/llvm/include/llvm/CodeGen/Passes.h
+++ b/contrib/llvm/include/llvm/CodeGen/Passes.h
@@ -33,7 +33,7 @@ class raw_ostream;
/// List of target independent CodeGen pass IDs.
namespace llvm {
- FunctionPass *createAtomicExpandPass(const TargetMachine *TM);
+ FunctionPass *createAtomicExpandPass();
/// createUnreachableBlockEliminationPass - The LLVM code generator does not
/// work well with unreachable basic blocks (what live ranges make sense for a
@@ -60,11 +60,17 @@ namespace llvm {
/// as if it was just created.
/// If EmitFallbackDiag is true, the pass will emit a
/// DiagnosticInfoISelFallback for every MachineFunction it resets.
- MachineFunctionPass *createResetMachineFunctionPass(bool EmitFallbackDiag);
+ /// If AbortOnFailedISel is true, abort compilation instead of resetting.
+ MachineFunctionPass *createResetMachineFunctionPass(bool EmitFallbackDiag,
+ bool AbortOnFailedISel);
/// createCodeGenPreparePass - Transform the code to expose more pattern
/// matching during instruction selection.
- FunctionPass *createCodeGenPreparePass(const TargetMachine *TM = nullptr);
+ FunctionPass *createCodeGenPreparePass();
+
+ /// createScalarizeMaskedMemIntrinPass - Replace masked load, store, gather
+ /// and scatter intrinsics with scalar code when target doesn't support them.
+ FunctionPass *createScalarizeMaskedMemIntrinPass();
/// AtomicExpandID -- Lowers atomic operations in terms of either cmpxchg
/// load-linked/store-conditional loops.
@@ -79,6 +85,9 @@ namespace llvm {
/// MachineDominanaceFrontier - This pass is a machine dominators analysis pass.
extern char &MachineDominanceFrontierID;
+ /// MachineRegionInfo - This pass computes SESE regions for machine functions.
+ extern char &MachineRegionInfoPassID;
+
/// EdgeBundles analysis - Bundle machine CFG edges.
extern char &EdgeBundlesID;
@@ -124,9 +133,16 @@ namespace llvm {
// instruction and update the MachineFunctionInfo with that information.
extern char &ShrinkWrapID;
+ /// LiveRangeShrink pass. Move instruction close to its definition to shrink
+ /// the definition's live range.
+ extern char &LiveRangeShrinkID;
+
/// Greedy register allocator.
extern char &RAGreedyID;
+ /// Basic register allocator.
+ extern char &RABasicID;
+
/// VirtRegRewriter pass. Rewrite virtual registers to physical registers as
/// assigned in VirtRegMap.
extern char &VirtRegRewriterID;
@@ -164,7 +180,7 @@ namespace llvm {
/// PrologEpilogCodeInserter - This pass inserts prolog and epilog code,
/// and eliminates abstract frame references.
extern char &PrologEpilogCodeInserterID;
- MachineFunctionPass *createPrologEpilogInserterPass(const TargetMachine *TM);
+ MachineFunctionPass *createPrologEpilogInserterPass();
/// ExpandPostRAPseudos - This pass expands pseudo instructions after
/// register allocation.
@@ -284,12 +300,15 @@ namespace llvm {
/// the target platform.
extern char &XRayInstrumentationID;
+ /// This pass inserts FEntry calls
+ extern char &FEntryInserterID;
+
/// \brief This pass implements the "patchable-function" attribute.
extern char &PatchableFunctionID;
/// createStackProtectorPass - This pass adds stack protectors to functions.
///
- FunctionPass *createStackProtectorPass(const TargetMachine *TM);
+ FunctionPass *createStackProtectorPass();
/// createMachineVerifierPass - This pass verifies cenerated machine code
/// instructions for correctness.
@@ -298,11 +317,11 @@ namespace llvm {
/// createDwarfEHPass - This pass mulches exception handling code into a form
/// adapted to code generation. Required if using dwarf exception handling.
- FunctionPass *createDwarfEHPass(const TargetMachine *TM);
+ FunctionPass *createDwarfEHPass();
/// createWinEHPass - Prepares personality functions used by MSVC on Windows,
/// in addition to the Itanium LSDA based personalities.
- FunctionPass *createWinEHPass(const TargetMachine *TM);
+ FunctionPass *createWinEHPass();
/// createSjLjEHPreparePass - This pass adapts exception handling code to use
/// the GCC-style builtin setjmp/longjmp (sjlj) to handling EH control flow.
@@ -318,14 +337,6 @@ namespace llvm {
/// ExpandISelPseudos - This pass expands pseudo-instructions.
extern char &ExpandISelPseudosID;
- /// createExecutionDependencyFixPass - This pass fixes execution time
- /// problems with dependent instructions, such as switching execution
- /// domains to match.
- ///
- /// The pass will examine instructions using and defining registers in RC.
- ///
- FunctionPass *createExecutionDependencyFixPass(const TargetRegisterClass *RC);
-
/// UnpackMachineBundles - This pass unpack machine instruction bundles.
extern char &UnpackMachineBundlesID;
@@ -354,12 +365,12 @@ namespace llvm {
/// InterleavedAccess Pass - This pass identifies and matches interleaved
/// memory accesses to target specific intrinsics.
///
- FunctionPass *createInterleavedAccessPass(const TargetMachine *TM);
+ FunctionPass *createInterleavedAccessPass();
/// LowerEmuTLS - This pass generates __emutls_[vt].xyz variables for all
/// TLS variables for the emulated TLS model.
///
- ModulePass *createLowerEmuTLSPass(const TargetMachine *TM);
+ ModulePass *createLowerEmuTLSPass();
/// This pass lowers the @llvm.load.relative intrinsic to instructions.
/// This is unsafe to do earlier because a pass may combine the constant
@@ -376,7 +387,7 @@ namespace llvm {
/// This pass splits the stack into a safe stack and an unsafe stack to
/// protect against stack-based overflow vulnerabilities.
- FunctionPass *createSafeStackPass(const TargetMachine *TM = nullptr);
+ FunctionPass *createSafeStackPass();
/// This pass detects subregister lanes in a virtual register that are used
/// independently of other lanes and splits them into separate virtual
@@ -397,35 +408,18 @@ namespace llvm {
/// This pass frees the memory occupied by the MachineFunction.
FunctionPass *createFreeMachineFunctionPass();
-} // End llvm namespace
-/// Target machine pass initializer for passes with dependencies. Use with
-/// INITIALIZE_TM_PASS_END.
-#define INITIALIZE_TM_PASS_BEGIN INITIALIZE_PASS_BEGIN
-
-/// Target machine pass initializer for passes with dependencies. Use with
-/// INITIALIZE_TM_PASS_BEGIN.
-#define INITIALIZE_TM_PASS_END(passName, arg, name, cfg, analysis) \
- PassInfo *PI = new PassInfo( \
- name, arg, &passName::ID, \
- PassInfo::NormalCtor_t(callDefaultCtor<passName>), cfg, analysis, \
- PassInfo::TargetMachineCtor_t(callTargetMachineCtor<passName>)); \
- Registry.registerPass(*PI, true); \
- return PI; \
- } \
- LLVM_DEFINE_ONCE_FLAG(Initialize##passName##PassFlag); \
- void llvm::initialize##passName##Pass(PassRegistry &Registry) { \
- llvm::call_once(Initialize##passName##PassFlag, \
- initialize##passName##PassOnce, std::ref(Registry)); \
- }
-
-/// This initializer registers TargetMachine constructor, so the pass being
-/// initialized can use target dependent interfaces. Please do not move this
-/// macro to be together with INITIALIZE_PASS, which is a complete target
-/// independent initializer, and we don't want to make libScalarOpts depend
-/// on libCodeGen.
-#define INITIALIZE_TM_PASS(passName, arg, name, cfg, analysis) \
- INITIALIZE_TM_PASS_BEGIN(passName, arg, name, cfg, analysis) \
- INITIALIZE_TM_PASS_END(passName, arg, name, cfg, analysis)
+ /// This pass combine basic blocks guarded by the same branch.
+ extern char &BranchCoalescingID;
+
+ /// This pass performs outlining on machine instructions directly before
+ /// printing assembly.
+ ModulePass *createMachineOutlinerPass();
+
+ /// This pass expands the experimental reduction intrinsics into sequences of
+ /// shuffles.
+ FunctionPass *createExpandReductionsPass();
+
+} // End llvm namespace
#endif
diff --git a/contrib/llvm/include/llvm/CodeGen/PseudoSourceValue.h b/contrib/llvm/include/llvm/CodeGen/PseudoSourceValue.h
index 681ccb4..f5aedb0 100644
--- a/contrib/llvm/include/llvm/CodeGen/PseudoSourceValue.h
+++ b/contrib/llvm/include/llvm/CodeGen/PseudoSourceValue.h
@@ -94,7 +94,7 @@ public:
explicit FixedStackPseudoSourceValue(int FI)
: PseudoSourceValue(FixedStack), FI(FI) {}
- static inline bool classof(const PseudoSourceValue *V) {
+ static bool classof(const PseudoSourceValue *V) {
return V->kind() == FixedStack;
}
@@ -126,7 +126,7 @@ class GlobalValuePseudoSourceValue : public CallEntryPseudoSourceValue {
public:
GlobalValuePseudoSourceValue(const GlobalValue *GV);
- static inline bool classof(const PseudoSourceValue *V) {
+ static bool classof(const PseudoSourceValue *V) {
return V->kind() == GlobalValueCallEntry;
}
@@ -140,7 +140,7 @@ class ExternalSymbolPseudoSourceValue : public CallEntryPseudoSourceValue {
public:
ExternalSymbolPseudoSourceValue(const char *ES);
- static inline bool classof(const PseudoSourceValue *V) {
+ static bool classof(const PseudoSourceValue *V) {
return V->kind() == ExternalSymbolCallEntry;
}
diff --git a/contrib/llvm/include/llvm/CodeGen/RegAllocPBQP.h b/contrib/llvm/include/llvm/CodeGen/RegAllocPBQP.h
index 2cad90b..5b34286 100644
--- a/contrib/llvm/include/llvm/CodeGen/RegAllocPBQP.h
+++ b/contrib/llvm/include/llvm/CodeGen/RegAllocPBQP.h
@@ -1,4 +1,4 @@
-//===-- RegAllocPBQP.h ------------------------------------------*- C++ -*-===//
+//===- RegAllocPBQP.h -------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -16,15 +16,28 @@
#ifndef LLVM_CODEGEN_REGALLOCPBQP_H
#define LLVM_CODEGEN_REGALLOCPBQP_H
-#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/Hashing.h"
#include "llvm/CodeGen/PBQP/CostAllocator.h"
+#include "llvm/CodeGen/PBQP/Graph.h"
+#include "llvm/CodeGen/PBQP/Math.h"
#include "llvm/CodeGen/PBQP/ReductionRules.h"
-#include "llvm/CodeGen/PBQPRAConstraint.h"
+#include "llvm/CodeGen/PBQP/Solution.h"
#include "llvm/Support/ErrorHandling.h"
+#include <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <limits>
+#include <memory>
#include <set>
+#include <vector>
namespace llvm {
+class FunctionPass;
+class LiveIntervals;
+class MachineBlockFrequencyInfo;
+class MachineFunction;
class raw_ostream;
namespace PBQP {
@@ -37,15 +50,10 @@ inline unsigned getSpillOptionIdx() { return 0; }
///
/// Keeps track of the number of infinities in each row and column.
class MatrixMetadata {
-private:
- MatrixMetadata(const MatrixMetadata&);
- void operator=(const MatrixMetadata&);
public:
MatrixMetadata(const Matrix& M)
- : WorstRow(0), WorstCol(0),
- UnsafeRows(new bool[M.getRows() - 1]()),
+ : UnsafeRows(new bool[M.getRows() - 1]()),
UnsafeCols(new bool[M.getCols() - 1]()) {
-
unsigned* ColCounts = new unsigned[M.getCols() - 1]();
for (unsigned i = 1; i < M.getRows(); ++i) {
@@ -66,13 +74,17 @@ public:
delete[] ColCounts;
}
+ MatrixMetadata(const MatrixMetadata &) = delete;
+ MatrixMetadata &operator=(const MatrixMetadata &) = delete;
+
unsigned getWorstRow() const { return WorstRow; }
unsigned getWorstCol() const { return WorstCol; }
const bool* getUnsafeRows() const { return UnsafeRows.get(); }
const bool* getUnsafeCols() const { return UnsafeCols.get(); }
private:
- unsigned WorstRow, WorstCol;
+ unsigned WorstRow = 0;
+ unsigned WorstCol = 0;
std::unique_ptr<bool[]> UnsafeRows;
std::unique_ptr<bool[]> UnsafeCols;
};
@@ -80,17 +92,16 @@ private:
/// \brief Holds a vector of the allowed physical regs for a vreg.
class AllowedRegVector {
friend hash_code hash_value(const AllowedRegVector &);
-public:
- AllowedRegVector() : NumOpts(0), Opts(nullptr) {}
+public:
+ AllowedRegVector() = default;
+ AllowedRegVector(AllowedRegVector &&) = default;
AllowedRegVector(const std::vector<unsigned> &OptVec)
: NumOpts(OptVec.size()), Opts(new unsigned[NumOpts]) {
std::copy(OptVec.begin(), OptVec.end(), Opts.get());
}
- AllowedRegVector(AllowedRegVector &&) = default;
-
unsigned size() const { return NumOpts; }
unsigned operator[](size_t I) const { return Opts[I]; }
@@ -105,7 +116,7 @@ public:
}
private:
- unsigned NumOpts;
+ unsigned NumOpts = 0;
std::unique_ptr<unsigned[]> Opts;
};
@@ -119,10 +130,10 @@ inline hash_code hash_value(const AllowedRegVector &OptRegs) {
/// \brief Holds graph-level metadata relevant to PBQP RA problems.
class GraphMetadata {
private:
- typedef ValuePool<AllowedRegVector> AllowedRegVecPool;
-public:
+ using AllowedRegVecPool = ValuePool<AllowedRegVector>;
- typedef AllowedRegVecPool::PoolRef AllowedRegVecRef;
+public:
+ using AllowedRegVecRef = AllowedRegVecPool::PoolRef;
GraphMetadata(MachineFunction &MF,
LiveIntervals &LIS,
@@ -156,25 +167,19 @@ private:
/// \brief Holds solver state and other metadata relevant to each PBQP RA node.
class NodeMetadata {
public:
- typedef RegAlloc::AllowedRegVector AllowedRegVector;
+ using AllowedRegVector = RegAlloc::AllowedRegVector;
// The node's reduction state. The order in this enum is important,
// as it is assumed nodes can only progress up (i.e. towards being
// optimally reducible) when reducing the graph.
- typedef enum {
+ using ReductionState = enum {
Unprocessed,
NotProvablyAllocatable,
ConservativelyAllocatable,
OptimallyReducible
- } ReductionState;
+ };
- NodeMetadata()
- : RS(Unprocessed), NumOpts(0), DeniedOpts(0), OptUnsafeEdges(nullptr),
- VReg(0)
-#ifndef NDEBUG
- , everConservativelyAllocatable(false)
-#endif
- {}
+ NodeMetadata() = default;
NodeMetadata(const NodeMetadata &Other)
: RS(Other.RS), NumOpts(Other.NumOpts), DeniedOpts(Other.DeniedOpts),
@@ -190,9 +195,8 @@ public:
}
}
- NodeMetadata(NodeMetadata &&Other) = default;
-
- NodeMetadata& operator=(NodeMetadata &&Other) = default;
+ NodeMetadata(NodeMetadata &&) = default;
+ NodeMetadata& operator=(NodeMetadata &&) = default;
void setVReg(unsigned VReg) { this->VReg = VReg; }
unsigned getVReg() const { return VReg; }
@@ -249,36 +253,37 @@ public:
#endif
private:
- ReductionState RS;
- unsigned NumOpts;
- unsigned DeniedOpts;
+ ReductionState RS = Unprocessed;
+ unsigned NumOpts = 0;
+ unsigned DeniedOpts = 0;
std::unique_ptr<unsigned[]> OptUnsafeEdges;
- unsigned VReg;
+ unsigned VReg = 0;
GraphMetadata::AllowedRegVecRef AllowedRegs;
#ifndef NDEBUG
- bool everConservativelyAllocatable;
+ bool everConservativelyAllocatable = false;
#endif
};
class RegAllocSolverImpl {
private:
- typedef MDMatrix<MatrixMetadata> RAMatrix;
+ using RAMatrix = MDMatrix<MatrixMetadata>;
+
public:
- typedef PBQP::Vector RawVector;
- typedef PBQP::Matrix RawMatrix;
- typedef PBQP::Vector Vector;
- typedef RAMatrix Matrix;
- typedef PBQP::PoolCostAllocator<Vector, Matrix> CostAllocator;
+ using RawVector = PBQP::Vector;
+ using RawMatrix = PBQP::Matrix;
+ using Vector = PBQP::Vector;
+ using Matrix = RAMatrix;
+ using CostAllocator = PBQP::PoolCostAllocator<Vector, Matrix>;
- typedef GraphBase::NodeId NodeId;
- typedef GraphBase::EdgeId EdgeId;
+ using NodeId = GraphBase::NodeId;
+ using EdgeId = GraphBase::EdgeId;
- typedef RegAlloc::NodeMetadata NodeMetadata;
- struct EdgeMetadata { };
- typedef RegAlloc::GraphMetadata GraphMetadata;
+ using NodeMetadata = RegAlloc::NodeMetadata;
+ struct EdgeMetadata {};
+ using GraphMetadata = RegAlloc::GraphMetadata;
- typedef PBQP::Graph<RegAllocSolverImpl> Graph;
+ using Graph = PBQP::Graph<RegAllocSolverImpl>;
RegAllocSolverImpl(Graph &G) : G(G) {}
@@ -296,6 +301,7 @@ public:
"PBQP Graph should not contain single or zero-option nodes");
G.getNodeMetadata(NId).setup(G.getNodeCosts(NId));
}
+
void handleRemoveNode(NodeId NId) {}
void handleSetNodeCosts(NodeId NId, const Vector& newCosts) {}
@@ -342,7 +348,6 @@ public:
}
private:
-
void promote(NodeId NId, NodeMetadata& NMd) {
if (G.getNodeDegree(NId) == 3) {
// This node is becoming optimally reducible.
@@ -421,7 +426,7 @@ private:
std::vector<GraphBase::NodeId> reduce() {
assert(!G.empty() && "Cannot reduce empty graph.");
- typedef GraphBase::NodeId NodeId;
+ using NodeId = GraphBase::NodeId;
std::vector<NodeId> NodeStack;
// Consume worklists.
@@ -454,7 +459,6 @@ private:
ConservativelyAllocatableNodes.erase(NItr);
NodeStack.push_back(NId);
G.disconnectAllNeighborsFromNode(NId);
-
} else if (!NotProvablyAllocatableNodes.empty()) {
NodeSet::iterator NItr =
std::min_element(NotProvablyAllocatableNodes.begin(),
@@ -474,6 +478,7 @@ private:
class SpillCostComparator {
public:
SpillCostComparator(const Graph& G) : G(G) {}
+
bool operator()(NodeId N1Id, NodeId N2Id) {
PBQPNum N1SC = G.getNodeCosts(N1Id)[0];
PBQPNum N2SC = G.getNodeCosts(N2Id)[0];
@@ -481,12 +486,13 @@ private:
return G.getNodeDegree(N1Id) < G.getNodeDegree(N2Id);
return N1SC < N2SC;
}
+
private:
const Graph& G;
};
Graph& G;
- typedef std::set<NodeId> NodeSet;
+ using NodeSet = std::set<NodeId>;
NodeSet OptimallyReducibleNodes;
NodeSet ConservativelyAllocatableNodes;
NodeSet NotProvablyAllocatableNodes;
@@ -494,9 +500,10 @@ private:
class PBQPRAGraph : public PBQP::Graph<RegAllocSolverImpl> {
private:
- typedef PBQP::Graph<RegAllocSolverImpl> BaseT;
+ using BaseT = PBQP::Graph<RegAllocSolverImpl>;
+
public:
- PBQPRAGraph(GraphMetadata Metadata) : BaseT(Metadata) {}
+ PBQPRAGraph(GraphMetadata Metadata) : BaseT(std::move(Metadata)) {}
/// @brief Dump this graph to dbgs().
void dump() const;
@@ -517,13 +524,13 @@ inline Solution solve(PBQPRAGraph& G) {
return RegAllocSolver.solve();
}
-} // namespace RegAlloc
-} // namespace PBQP
+} // end namespace RegAlloc
+} // end namespace PBQP
/// @brief Create a PBQP register allocator instance.
FunctionPass *
createPBQPRegisterAllocator(char *customPassID = nullptr);
-} // namespace llvm
+} // end namespace llvm
-#endif /* LLVM_CODEGEN_REGALLOCPBQP_H */
+#endif // LLVM_CODEGEN_REGALLOCPBQP_H
diff --git a/contrib/llvm/include/llvm/CodeGen/RegAllocRegistry.h b/contrib/llvm/include/llvm/CodeGen/RegAllocRegistry.h
index 5c7e999..481747d 100644
--- a/contrib/llvm/include/llvm/CodeGen/RegAllocRegistry.h
+++ b/contrib/llvm/include/llvm/CodeGen/RegAllocRegistry.h
@@ -1,4 +1,4 @@
-//===-- llvm/CodeGen/RegAllocRegistry.h -------------------------*- C++ -*-===//
+//===- llvm/CodeGen/RegAllocRegistry.h --------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -19,16 +19,16 @@
namespace llvm {
+class FunctionPass;
+
//===----------------------------------------------------------------------===//
///
/// RegisterRegAlloc class - Track the registration of register allocators.
///
//===----------------------------------------------------------------------===//
class RegisterRegAlloc : public MachinePassRegistryNode {
-
public:
-
- typedef FunctionPass *(*FunctionPassCtor)();
+ using FunctionPassCtor = FunctionPass *(*)();
static MachinePassRegistry Registry;
@@ -36,22 +36,26 @@ public:
: MachinePassRegistryNode(N, D, (MachinePassCtor)C) {
Registry.Add(this);
}
+
~RegisterRegAlloc() { Registry.Remove(this); }
// Accessors.
- //
RegisterRegAlloc *getNext() const {
return (RegisterRegAlloc *)MachinePassRegistryNode::getNext();
}
+
static RegisterRegAlloc *getList() {
return (RegisterRegAlloc *)Registry.getList();
}
+
static FunctionPassCtor getDefault() {
return (FunctionPassCtor)Registry.getDefault();
}
+
static void setDefault(FunctionPassCtor C) {
Registry.setDefault((MachinePassCtor)C);
}
+
static void setListener(MachinePassRegistryListener *L) {
Registry.setListener(L);
}
@@ -59,5 +63,4 @@ public:
} // end namespace llvm
-
-#endif
+#endif // LLVM_CODEGEN_REGALLOCREGISTRY_H
diff --git a/contrib/llvm/include/llvm/CodeGen/RegisterClassInfo.h b/contrib/llvm/include/llvm/CodeGen/RegisterClassInfo.h
index d784dfb..355c9f9 100644
--- a/contrib/llvm/include/llvm/CodeGen/RegisterClassInfo.h
+++ b/contrib/llvm/include/llvm/CodeGen/RegisterClassInfo.h
@@ -1,4 +1,4 @@
-//===-- RegisterClassInfo.h - Dynamic Register Class Info -*- C++ -*-------===//
+//===- RegisterClassInfo.h - Dynamic Register Class Info --------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -19,22 +19,25 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/BitVector.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/Target/TargetRegisterInfo.h"
+#include <cassert>
+#include <cstdint>
+#include <memory>
namespace llvm {
class RegisterClassInfo {
struct RCInfo {
- unsigned Tag;
- unsigned NumRegs;
- bool ProperSubClass;
- uint8_t MinCost;
- uint16_t LastCostChange;
+ unsigned Tag = 0;
+ unsigned NumRegs = 0;
+ bool ProperSubClass = false;
+ uint8_t MinCost = 0;
+ uint16_t LastCostChange = 0;
std::unique_ptr<MCPhysReg[]> Order;
- RCInfo()
- : Tag(0), NumRegs(0), ProperSubClass(false), MinCost(0),
- LastCostChange(0) {}
+ RCInfo() = default;
operator ArrayRef<MCPhysReg>() const {
return makeArrayRef(Order.get(), NumRegs);
@@ -46,17 +49,18 @@ class RegisterClassInfo {
// Tag changes whenever cached information needs to be recomputed. An RCInfo
// entry is valid when its tag matches.
- unsigned Tag;
+ unsigned Tag = 0;
- const MachineFunction *MF;
- const TargetRegisterInfo *TRI;
+ const MachineFunction *MF = nullptr;
+ const TargetRegisterInfo *TRI = nullptr;
// Callee saved registers of last MF. Assumed to be valid until the next
// runOnFunction() call.
- const MCPhysReg *CalleeSaved;
+ // Used only to determine if an update was made to CalleeSavedAliases.
+ const MCPhysReg *CalleeSavedRegs = nullptr;
- // Map register number to CalleeSaved index + 1;
- SmallVector<uint8_t, 4> CSRNum;
+ // Map register alias to the callee saved Register.
+ SmallVector<MCPhysReg, 4> CalleeSavedAliases;
// Reserved registers in the current MF.
BitVector Reserved;
@@ -105,11 +109,11 @@ public:
}
/// getLastCalleeSavedAlias - Returns the last callee saved register that
- /// overlaps PhysReg, or 0 if Reg doesn't overlap a CSR.
+ /// overlaps PhysReg, or 0 if Reg doesn't overlap a CalleeSavedAliases.
unsigned getLastCalleeSavedAlias(unsigned PhysReg) const {
assert(TargetRegisterInfo::isPhysicalRegister(PhysReg));
- if (unsigned N = CSRNum[PhysReg])
- return CalleeSaved[N-1];
+ if (PhysReg < CalleeSavedAliases.size())
+ return CalleeSavedAliases[PhysReg];
return 0;
}
@@ -140,6 +144,7 @@ public:
protected:
unsigned computePSetLimit(unsigned Idx) const;
};
+
} // end namespace llvm
-#endif
+#endif // LLVM_CODEGEN_REGISTERCLASSINFO_H
diff --git a/contrib/llvm/include/llvm/CodeGen/RegisterPressure.h b/contrib/llvm/include/llvm/CodeGen/RegisterPressure.h
index 313be35..e997aaf 100644
--- a/contrib/llvm/include/llvm/CodeGen/RegisterPressure.h
+++ b/contrib/llvm/include/llvm/CodeGen/RegisterPressure.h
@@ -1,4 +1,4 @@
-//===-- RegisterPressure.h - Dynamic Register Pressure -*- C++ -*-------===//
+//===- RegisterPressure.h - Dynamic Register Pressure -----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -15,16 +15,27 @@
#ifndef LLVM_CODEGEN_REGISTERPRESSURE_H
#define LLVM_CODEGEN_REGISTERPRESSURE_H
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/SparseSet.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/SlotIndexes.h"
+#include "llvm/MC/LaneBitmask.h"
#include "llvm/Target/TargetRegisterInfo.h"
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
+#include <cstdlib>
+#include <limits>
+#include <vector>
namespace llvm {
class LiveIntervals;
-class LiveRange;
-class RegisterClassInfo;
+class MachineFunction;
class MachineInstr;
+class MachineRegisterInfo;
+class RegisterClassInfo;
struct RegisterMaskPair {
unsigned RegUnit; ///< Virtual register or register unit.
@@ -91,12 +102,13 @@ struct RegionPressure : RegisterPressure {
/// higher level assert that pressure is consistent within a region. We also
/// effectively ignore dead defs which don't affect heuristics much.
class PressureChange {
- uint16_t PSetID; // ID+1. 0=Invalid.
- int16_t UnitInc;
+ uint16_t PSetID = 0; // ID+1. 0=Invalid.
+ int16_t UnitInc = 0;
+
public:
- PressureChange(): PSetID(0), UnitInc(0) {}
- PressureChange(unsigned id): PSetID(id+1), UnitInc(0) {
- assert(id < UINT16_MAX && "PSetID overflow.");
+ PressureChange() = default;
+ PressureChange(unsigned id): PSetID(id + 1) {
+ assert(id < std::numeric_limits<uint16_t>::max() && "PSetID overflow.");
}
bool isValid() const { return PSetID > 0; }
@@ -105,8 +117,11 @@ public:
assert(isValid() && "invalid PressureChange");
return PSetID - 1;
}
+
// If PSetID is invalid, return UINT16_MAX to give it lowest priority.
- unsigned getPSetOrMax() const { return (PSetID - 1) & UINT16_MAX; }
+ unsigned getPSetOrMax() const {
+ return (PSetID - 1) & std::numeric_limits<uint16_t>::max();
+ }
int getUnitInc() const { return UnitInc; }
@@ -134,19 +149,21 @@ class PressureDiff {
PressureChange PressureChanges[MaxPSets];
- typedef PressureChange* iterator;
+ using iterator = PressureChange *;
+
iterator nonconst_begin() { return &PressureChanges[0]; }
iterator nonconst_end() { return &PressureChanges[MaxPSets]; }
public:
- typedef const PressureChange* const_iterator;
+ using const_iterator = const PressureChange *;
+
const_iterator begin() const { return &PressureChanges[0]; }
const_iterator end() const { return &PressureChanges[MaxPSets]; }
void addPressureChange(unsigned RegUnit, bool IsDec,
const MachineRegisterInfo *MRI);
- LLVM_DUMP_METHOD void dump(const TargetRegisterInfo &TRI) const;
+ void dump(const TargetRegisterInfo &TRI) const;
};
/// List of registers defined and used by a machine instruction.
@@ -182,11 +199,12 @@ public:
/// Array of PressureDiffs.
class PressureDiffs {
- PressureDiff *PDiffArray;
- unsigned Size;
- unsigned Max;
+ PressureDiff *PDiffArray = nullptr;
+ unsigned Size = 0;
+ unsigned Max = 0;
+
public:
- PressureDiffs(): PDiffArray(nullptr), Size(0), Max(0) {}
+ PressureDiffs() = default;
~PressureDiffs() { free(PDiffArray); }
void clear() { Size = 0; }
@@ -200,6 +218,7 @@ public:
const PressureDiff &operator[](unsigned Idx) const {
return const_cast<PressureDiffs*>(this)->operator[](Idx);
}
+
/// \brief Record pressure difference induced by the given operand list to
/// node with index \p Idx.
void addInstruction(unsigned Idx, const RegisterOperands &RegOpers,
@@ -225,7 +244,7 @@ struct RegPressureDelta {
PressureChange CriticalMax;
PressureChange CurrentMax;
- RegPressureDelta() {}
+ RegPressureDelta() = default;
bool operator==(const RegPressureDelta &RHS) const {
return Excess == RHS.Excess && CriticalMax == RHS.CriticalMax
@@ -254,7 +273,7 @@ private:
}
};
- typedef SparseSet<IndexMaskPair> RegSet;
+ using RegSet = SparseSet<IndexMaskPair>;
RegSet Regs;
unsigned NumRegUnits;
@@ -264,6 +283,7 @@ private:
assert(Reg < NumRegUnits);
return Reg;
}
+
unsigned getRegFromSparseIndex(unsigned SparseIndex) const {
if (SparseIndex >= NumRegUnits)
return TargetRegisterInfo::index2VirtReg(SparseIndex-NumRegUnits);
@@ -338,14 +358,14 @@ public:
/// tracking. Changing direction has the side effect of closing region, and
/// traversing past TopIdx or BottomIdx reopens it.
class RegPressureTracker {
- const MachineFunction *MF;
- const TargetRegisterInfo *TRI;
- const RegisterClassInfo *RCI;
+ const MachineFunction *MF = nullptr;
+ const TargetRegisterInfo *TRI = nullptr;
+ const RegisterClassInfo *RCI = nullptr;
const MachineRegisterInfo *MRI;
- const LiveIntervals *LIS;
+ const LiveIntervals *LIS = nullptr;
/// We currently only allow pressure tracking within a block.
- const MachineBasicBlock *MBB;
+ const MachineBasicBlock *MBB = nullptr;
/// Track the max pressure within the region traversed so far.
RegisterPressure &P;
@@ -355,10 +375,10 @@ class RegPressureTracker {
bool RequireIntervals;
/// True if UntiedDefs will be populated.
- bool TrackUntiedDefs;
+ bool TrackUntiedDefs = false;
/// True if lanemasks should be tracked.
- bool TrackLaneMasks;
+ bool TrackLaneMasks = false;
/// Register pressure corresponds to liveness before this instruction
/// iterator. It may point to the end of the block or a DebugValue rather than
@@ -377,13 +397,8 @@ class RegPressureTracker {
std::vector<unsigned> LiveThruPressure;
public:
- RegPressureTracker(IntervalPressure &rp) :
- MF(nullptr), TRI(nullptr), RCI(nullptr), LIS(nullptr), MBB(nullptr), P(rp),
- RequireIntervals(true), TrackUntiedDefs(false), TrackLaneMasks(false) {}
-
- RegPressureTracker(RegionPressure &rp) :
- MF(nullptr), TRI(nullptr), RCI(nullptr), LIS(nullptr), MBB(nullptr), P(rp),
- RequireIntervals(false), TrackUntiedDefs(false), TrackLaneMasks(false) {}
+ RegPressureTracker(IntervalPressure &rp) : P(rp), RequireIntervals(true) {}
+ RegPressureTracker(RegionPressure &rp) : P(rp), RequireIntervals(false) {}
void reset();
@@ -555,6 +570,7 @@ protected:
void dumpRegSetPressure(ArrayRef<unsigned> SetPressure,
const TargetRegisterInfo *TRI);
+
} // end namespace llvm
-#endif
+#endif // LLVM_CODEGEN_REGISTERPRESSURE_H
diff --git a/contrib/llvm/include/llvm/CodeGen/RegisterScavenging.h b/contrib/llvm/include/llvm/CodeGen/RegisterScavenging.h
index 1b9232b..489c72b 100644
--- a/contrib/llvm/include/llvm/CodeGen/RegisterScavenging.h
+++ b/contrib/llvm/include/llvm/CodeGen/RegisterScavenging.h
@@ -1,4 +1,4 @@
-//===-- RegisterScavenging.h - Machine register scavenging ------*- C++ -*-===//
+//===- RegisterScavenging.h - Machine register scavenging -------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -19,49 +19,49 @@
#define LLVM_CODEGEN_REGISTERSCAVENGING_H
#include "llvm/ADT/BitVector.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/CodeGen/LiveRegUnits.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/MC/LaneBitmask.h"
namespace llvm {
-class MachineRegisterInfo;
-class TargetRegisterInfo;
+class MachineInstr;
class TargetInstrInfo;
class TargetRegisterClass;
+class TargetRegisterInfo;
class RegScavenger {
const TargetRegisterInfo *TRI;
const TargetInstrInfo *TII;
MachineRegisterInfo* MRI;
- MachineBasicBlock *MBB;
+ MachineBasicBlock *MBB = nullptr;
MachineBasicBlock::iterator MBBI;
- unsigned NumRegUnits;
+ unsigned NumRegUnits = 0;
/// True if RegScavenger is currently tracking the liveness of registers.
- bool Tracking;
+ bool Tracking = false;
/// Information on scavenged registers (held in a spill slot).
struct ScavengedInfo {
- ScavengedInfo(int FI = -1) : FrameIndex(FI), Reg(0), Restore(nullptr) {}
+ ScavengedInfo(int FI = -1) : FrameIndex(FI) {}
/// A spill slot used for scavenging a register post register allocation.
int FrameIndex;
/// If non-zero, the specific register is currently being
/// scavenged. That is, it is spilled to this scavenging stack slot.
- unsigned Reg;
+ unsigned Reg = 0;
/// The instruction that restores the scavenged register from stack.
- const MachineInstr *Restore;
+ const MachineInstr *Restore = nullptr;
};
/// A vector of information on scavenged registers.
SmallVector<ScavengedInfo, 2> Scavenged;
- /// The current state of each reg unit immediately before MBBI.
- /// One bit per register unit. If bit is not set it means any
- /// register containing that register unit is currently being used.
- BitVector RegUnitsAvailable;
+ LiveRegUnits LiveUnits;
// These BitVectors are only used internally to forward(). They are members
// to avoid frequent reallocations.
@@ -69,8 +69,7 @@ class RegScavenger {
BitVector TmpRegUnits;
public:
- RegScavenger()
- : MBB(nullptr), NumRegUnits(0), Tracking(false) {}
+ RegScavenger() = default;
/// Start tracking liveness from the begin of basic block \p MBB.
void enterBasicBlock(MachineBasicBlock &MBB);
@@ -157,25 +156,38 @@ public:
/// available and do the appropriate bookkeeping. SPAdj is the stack
/// adjustment due to call frame, it's passed along to eliminateFrameIndex().
/// Returns the scavenged register.
+ /// This is deprecated as it depends on the quality of the kill flags being
+ /// present; Use scavengeRegisterBackwards() instead!
unsigned scavengeRegister(const TargetRegisterClass *RegClass,
MachineBasicBlock::iterator I, int SPAdj);
unsigned scavengeRegister(const TargetRegisterClass *RegClass, int SPAdj) {
return scavengeRegister(RegClass, MBBI, SPAdj);
}
+ /// Make a register of the specific register class available from the current
+ /// position backwards to the place before \p To. If \p RestoreAfter is true
+ /// this includes the instruction following the current position.
+ /// SPAdj is the stack adjustment due to call frame, it's passed along to
+ /// eliminateFrameIndex().
+ /// Returns the scavenged register.
+ unsigned scavengeRegisterBackwards(const TargetRegisterClass &RC,
+ MachineBasicBlock::iterator To,
+ bool RestoreAfter, int SPAdj);
+
/// Tell the scavenger a register is used.
void setRegUsed(unsigned Reg, LaneBitmask LaneMask = LaneBitmask::getAll());
+
private:
/// Returns true if a register is reserved. It is never "unused".
bool isReserved(unsigned Reg) const { return MRI->isReserved(Reg); }
/// setUsed / setUnused - Mark the state of one or a number of register units.
///
- void setUsed(BitVector &RegUnits) {
- RegUnitsAvailable.reset(RegUnits);
+ void setUsed(const BitVector &RegUnits) {
+ LiveUnits.addUnits(RegUnits);
}
- void setUnused(BitVector &RegUnits) {
- RegUnitsAvailable |= RegUnits;
+ void setUnused(const BitVector &RegUnits) {
+ LiveUnits.removeUnits(RegUnits);
}
/// Processes the current instruction and fill the KillRegUnits and
@@ -202,8 +214,18 @@ private:
/// Mark live-in registers of basic block as used.
void setLiveInsUsed(const MachineBasicBlock &MBB);
+
+ /// Spill a register after position \p After and reload it before position
+ /// \p UseMI.
+ ScavengedInfo &spill(unsigned Reg, const TargetRegisterClass &RC, int SPAdj,
+ MachineBasicBlock::iterator After,
+ MachineBasicBlock::iterator &UseMI);
};
-} // End llvm namespace
+/// Replaces all frame index virtual registers with physical registers. Uses the
+/// register scavenger to find an appropriate register to use.
+void scavengeFrameVirtualRegs(MachineFunction &MF, RegScavenger &RS);
+
+} // end namespace llvm
-#endif
+#endif // LLVM_CODEGEN_REGISTERSCAVENGING_H
diff --git a/contrib/llvm/include/llvm/CodeGen/RegisterUsageInfo.h b/contrib/llvm/include/llvm/CodeGen/RegisterUsageInfo.h
index 3f88032..0a04bc6 100644
--- a/contrib/llvm/include/llvm/CodeGen/RegisterUsageInfo.h
+++ b/contrib/llvm/include/llvm/CodeGen/RegisterUsageInfo.h
@@ -1,4 +1,4 @@
-//==- RegisterUsageInfo.h - Register Usage Informartion Storage -*- C++ -*-===//
+//==- RegisterUsageInfo.h - Register Usage Informartion Storage --*- C++ -*-==//
//
// The LLVM Compiler Infrastructure
//
@@ -20,15 +20,15 @@
#define LLVM_CODEGEN_PHYSICALREGISTERUSAGEINFO_H
#include "llvm/ADT/DenseMap.h"
-#include "llvm/CodeGen/MachineRegisterInfo.h"
-#include "llvm/IR/Function.h"
-#include "llvm/IR/Module.h"
#include "llvm/Pass.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/raw_ostream.h"
+#include <cstdint>
+#include <vector>
namespace llvm {
+class Function;
+class TargetMachine;
+
class PhysicalRegisterUsageInfo : public ImmutablePass {
virtual void anchor();
@@ -70,6 +70,7 @@ private:
const TargetMachine *TM;
};
-}
-#endif
+} // end namespace llvm
+
+#endif // LLVM_CODEGEN_PHYSICALREGISTERUSAGEINFO_H
diff --git a/contrib/llvm/include/llvm/CodeGen/RuntimeLibcalls.h b/contrib/llvm/include/llvm/CodeGen/RuntimeLibcalls.h
index ddfabb0..08151be 100644
--- a/contrib/llvm/include/llvm/CodeGen/RuntimeLibcalls.h
+++ b/contrib/llvm/include/llvm/CodeGen/RuntimeLibcalls.h
@@ -333,12 +333,24 @@ namespace RTLIB {
MEMSET,
MEMMOVE,
- // ELEMENT-WISE ATOMIC MEMORY
- MEMCPY_ELEMENT_ATOMIC_1,
- MEMCPY_ELEMENT_ATOMIC_2,
- MEMCPY_ELEMENT_ATOMIC_4,
- MEMCPY_ELEMENT_ATOMIC_8,
- MEMCPY_ELEMENT_ATOMIC_16,
+ // ELEMENT-WISE UNORDERED-ATOMIC MEMORY of different element sizes
+ MEMCPY_ELEMENT_UNORDERED_ATOMIC_1,
+ MEMCPY_ELEMENT_UNORDERED_ATOMIC_2,
+ MEMCPY_ELEMENT_UNORDERED_ATOMIC_4,
+ MEMCPY_ELEMENT_UNORDERED_ATOMIC_8,
+ MEMCPY_ELEMENT_UNORDERED_ATOMIC_16,
+
+ MEMMOVE_ELEMENT_UNORDERED_ATOMIC_1,
+ MEMMOVE_ELEMENT_UNORDERED_ATOMIC_2,
+ MEMMOVE_ELEMENT_UNORDERED_ATOMIC_4,
+ MEMMOVE_ELEMENT_UNORDERED_ATOMIC_8,
+ MEMMOVE_ELEMENT_UNORDERED_ATOMIC_16,
+
+ MEMSET_ELEMENT_UNORDERED_ATOMIC_1,
+ MEMSET_ELEMENT_UNORDERED_ATOMIC_2,
+ MEMSET_ELEMENT_UNORDERED_ATOMIC_4,
+ MEMSET_ELEMENT_UNORDERED_ATOMIC_8,
+ MEMSET_ELEMENT_UNORDERED_ATOMIC_16,
// EXCEPTION HANDLING
UNWIND_RESUME,
@@ -511,9 +523,21 @@ namespace RTLIB {
/// UNKNOWN_LIBCALL if there is none.
Libcall getSYNC(unsigned Opc, MVT VT);
- /// getMEMCPY_ELEMENT_ATOMIC - Return MEMCPY_ELEMENT_ATOMIC_* value for the
- /// given element size or UNKNOW_LIBCALL if there is none.
- Libcall getMEMCPY_ELEMENT_ATOMIC(uint64_t ElementSize);
+ /// getMEMCPY_ELEMENT_UNORDERED_ATOMIC - Return
+ /// MEMCPY_ELEMENT_UNORDERED_ATOMIC_* value for the given element size or
+ /// UNKNOW_LIBCALL if there is none.
+ Libcall getMEMCPY_ELEMENT_UNORDERED_ATOMIC(uint64_t ElementSize);
+
+ /// getMEMMOVE_ELEMENT_UNORDERED_ATOMIC - Return
+ /// MEMMOVE_ELEMENT_UNORDERED_ATOMIC_* value for the given element size or
+ /// UNKNOW_LIBCALL if there is none.
+ Libcall getMEMMOVE_ELEMENT_UNORDERED_ATOMIC(uint64_t ElementSize);
+
+ /// getMEMSET_ELEMENT_UNORDERED_ATOMIC - Return
+ /// MEMSET_ELEMENT_UNORDERED_ATOMIC_* value for the given element size or
+ /// UNKNOW_LIBCALL if there is none.
+ Libcall getMEMSET_ELEMENT_UNORDERED_ATOMIC(uint64_t ElementSize);
+
}
}
diff --git a/contrib/llvm/include/llvm/CodeGen/ScheduleDAG.h b/contrib/llvm/include/llvm/CodeGen/ScheduleDAG.h
index ed4e0bc8..25afc5b 100644
--- a/contrib/llvm/include/llvm/CodeGen/ScheduleDAG.h
+++ b/contrib/llvm/include/llvm/CodeGen/ScheduleDAG.h
@@ -1,4 +1,4 @@
-//===------- llvm/CodeGen/ScheduleDAG.h - Common Base Class------*- C++ -*-===//
+//===- llvm/CodeGen/ScheduleDAG.h - Common Base Class -----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,9 +7,9 @@
//
//===----------------------------------------------------------------------===//
//
-// This file implements the ScheduleDAG class, which is used as the common
-// base class for instruction schedulers. This encapsulates the scheduling DAG,
-// which is shared between SelectionDAG and MachineInstr scheduling.
+/// \file Implements the ScheduleDAG class, which is used as the common base
+/// class for instruction schedulers. This encapsulates the scheduling DAG,
+/// which is shared between SelectionDAG and MachineInstr scheduling.
//
//===----------------------------------------------------------------------===//
@@ -20,41 +20,46 @@
#include "llvm/ADT/GraphTraits.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/Analysis/AliasAnalysis.h"
+#include "llvm/ADT/iterator.h"
#include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/Support/ErrorHandling.h"
#include "llvm/Target/TargetLowering.h"
+#include <cassert>
+#include <cstddef>
+#include <iterator>
+#include <string>
+#include <vector>
namespace llvm {
- class SUnit;
- class MachineConstantPool;
- class MachineFunction;
- class MachineRegisterInfo;
- class MachineInstr;
- struct MCSchedClassDesc;
- class TargetRegisterInfo;
- class ScheduleDAG;
- class SDNode;
- class TargetInstrInfo;
- class MCInstrDesc;
- class TargetMachine;
- class TargetRegisterClass;
- template<class Graph> class GraphWriter;
-
- /// SDep - Scheduling dependency. This represents one direction of an
- /// edge in the scheduling DAG.
+
+template<class Graph> class GraphWriter;
+class MachineFunction;
+class MachineRegisterInfo;
+class MCInstrDesc;
+struct MCSchedClassDesc;
+class ScheduleDAG;
+class SDNode;
+class SUnit;
+class TargetInstrInfo;
+class TargetMachine;
+class TargetRegisterClass;
+class TargetRegisterInfo;
+
+ /// Scheduling dependency. This represents one direction of an edge in the
+ /// scheduling DAG.
class SDep {
public:
- /// Kind - These are the different kinds of scheduling dependencies.
+ /// These are the different kinds of scheduling dependencies.
enum Kind {
Data, ///< Regular data dependence (aka true-dependence).
- Anti, ///< A register anti-dependedence (aka WAR).
+ Anti, ///< A register anti-dependence (aka WAR).
Output, ///< A register output-dependence (aka WAW).
Order ///< Any other ordering dependency.
};
// Strong dependencies must be respected by the scheduler. Artificial
// dependencies may be removed only if they are redundant with another
- // strong depedence.
+ // strong dependence.
//
// Weak dependencies may be violated by the scheduling strategy, but only if
// the strategy can prove it is correct to do so.
@@ -71,33 +76,32 @@ namespace llvm {
};
private:
- /// Dep - A pointer to the depending/depended-on SUnit, and an enum
+ /// \brief A pointer to the depending/depended-on SUnit, and an enum
/// indicating the kind of the dependency.
PointerIntPair<SUnit *, 2, Kind> Dep;
- /// Contents - A union discriminated by the dependence kind.
+ /// A union discriminated by the dependence kind.
union {
- /// Reg - For Data, Anti, and Output dependencies, the associated
- /// register. For Data dependencies that don't currently have a register
- /// assigned, this is set to zero.
+ /// For Data, Anti, and Output dependencies, the associated register. For
+ /// Data dependencies that don't currently have a register/ assigned, this
+ /// is set to zero.
unsigned Reg;
- /// Order - Additional information about Order dependencies.
+ /// Additional information about Order dependencies.
unsigned OrdKind; // enum OrderKind
} Contents;
- /// Latency - The time associated with this edge. Often this is just
- /// the value of the Latency field of the predecessor, however advanced
- /// models may provide additional information about specific edges.
+ /// The time associated with this edge. Often this is just the value of the
+ /// Latency field of the predecessor, however advanced models may provide
+ /// additional information about specific edges.
unsigned Latency;
public:
- /// SDep - Construct a null SDep. This is only for use by container
- /// classes which require default constructors. SUnits may not
- /// have null SDep edges.
+ /// Constructs a null SDep. This is only for use by container classes which
+ /// require default constructors. SUnits may not/ have null SDep edges.
SDep() : Dep(nullptr, Data) {}
- /// SDep - Construct an SDep with the specified values.
+ /// Constructs an SDep with the specified values.
SDep(SUnit *S, Kind kind, unsigned Reg)
: Dep(S, kind), Contents() {
switch (kind) {
@@ -116,12 +120,13 @@ namespace llvm {
break;
}
}
+
SDep(SUnit *S, OrderKind kind)
: Dep(S, Order), Contents(), Latency(0) {
Contents.OrdKind = kind;
}
- /// Return true if the specified SDep is equivalent except for latency.
+ /// Returns true if the specified SDep is equivalent except for latency.
bool overlaps(const SDep &Other) const;
bool operator==(const SDep &Other) const {
@@ -132,100 +137,95 @@ namespace llvm {
return !operator==(Other);
}
- /// getLatency - Return the latency value for this edge, which roughly
- /// means the minimum number of cycles that must elapse between the
- /// predecessor and the successor, given that they have this edge
- /// between them.
+ /// \brief Returns the latency value for this edge, which roughly means the
+ /// minimum number of cycles that must elapse between the predecessor and
+ /// the successor, given that they have this edge between them.
unsigned getLatency() const {
return Latency;
}
- /// setLatency - Set the latency for this edge.
+ /// Sets the latency for this edge.
void setLatency(unsigned Lat) {
Latency = Lat;
}
- //// getSUnit - Return the SUnit to which this edge points.
+ //// Returns the SUnit to which this edge points.
SUnit *getSUnit() const;
- //// setSUnit - Assign the SUnit to which this edge points.
+ //// Assigns the SUnit to which this edge points.
void setSUnit(SUnit *SU);
- /// getKind - Return an enum value representing the kind of the dependence.
+ /// Returns an enum value representing the kind of the dependence.
Kind getKind() const;
- /// isCtrl - Shorthand for getKind() != SDep::Data.
+ /// Shorthand for getKind() != SDep::Data.
bool isCtrl() const {
return getKind() != Data;
}
- /// isNormalMemory - Test if this is an Order dependence between two
- /// memory accesses where both sides of the dependence access memory
- /// in non-volatile and fully modeled ways.
+ /// \brief Tests if this is an Order dependence between two memory accesses
+ /// where both sides of the dependence access memory in non-volatile and
+ /// fully modeled ways.
bool isNormalMemory() const {
return getKind() == Order && (Contents.OrdKind == MayAliasMem
|| Contents.OrdKind == MustAliasMem);
}
- /// isBarrier - Test if this is an Order dependence that is marked
- /// as a barrier.
+ /// Tests if this is an Order dependence that is marked as a barrier.
bool isBarrier() const {
return getKind() == Order && Contents.OrdKind == Barrier;
}
- /// isNormalMemoryOrBarrier - Test if this is could be any kind of memory
- /// dependence.
+ /// Tests if this is could be any kind of memory dependence.
bool isNormalMemoryOrBarrier() const {
return (isNormalMemory() || isBarrier());
}
- /// isMustAlias - Test if this is an Order dependence that is marked
- /// as "must alias", meaning that the SUnits at either end of the edge
- /// have a memory dependence on a known memory location.
+ /// \brief Tests if this is an Order dependence that is marked as
+ /// "must alias", meaning that the SUnits at either end of the edge have a
+ /// memory dependence on a known memory location.
bool isMustAlias() const {
return getKind() == Order && Contents.OrdKind == MustAliasMem;
}
- /// isWeak - Test if this a weak dependence. Weak dependencies are
- /// considered DAG edges for height computation and other heuristics, but do
- /// not force ordering. Breaking a weak edge may require the scheduler to
- /// compensate, for example by inserting a copy.
+ /// Tests if this a weak dependence. Weak dependencies are considered DAG
+ /// edges for height computation and other heuristics, but do not force
+ /// ordering. Breaking a weak edge may require the scheduler to compensate,
+ /// for example by inserting a copy.
bool isWeak() const {
return getKind() == Order && Contents.OrdKind >= Weak;
}
- /// isArtificial - Test if this is an Order dependence that is marked
- /// as "artificial", meaning it isn't necessary for correctness.
+ /// \brief Tests if this is an Order dependence that is marked as
+ /// "artificial", meaning it isn't necessary for correctness.
bool isArtificial() const {
return getKind() == Order && Contents.OrdKind == Artificial;
}
- /// isCluster - Test if this is an Order dependence that is marked
- /// as "cluster", meaning it is artificial and wants to be adjacent.
+ /// \brief Tests if this is an Order dependence that is marked as "cluster",
+ /// meaning it is artificial and wants to be adjacent.
bool isCluster() const {
return getKind() == Order && Contents.OrdKind == Cluster;
}
- /// isAssignedRegDep - Test if this is a Data dependence that is
- /// associated with a register.
+ /// Tests if this is a Data dependence that is associated with a register.
bool isAssignedRegDep() const {
return getKind() == Data && Contents.Reg != 0;
}
- /// getReg - Return the register associated with this edge. This is
- /// only valid on Data, Anti, and Output edges. On Data edges, this
- /// value may be zero, meaning there is no associated register.
+ /// Returns the register associated with this edge. This is only valid on
+ /// Data, Anti, and Output edges. On Data edges, this value may be zero,
+ /// meaning there is no associated register.
unsigned getReg() const {
assert((getKind() == Data || getKind() == Anti || getKind() == Output) &&
"getReg called on non-register dependence edge!");
return Contents.Reg;
}
- /// setReg - Assign the associated register for this edge. This is
- /// only valid on Data, Anti, and Output edges. On Anti and Output
- /// edges, this value must not be zero. On Data edges, the value may
- /// be zero, which would mean that no specific register is associated
- /// with this edge.
+ /// Assigns the associated register for this edge. This is only valid on
+ /// Data, Anti, and Output edges. On Anti and Output edges, this value must
+ /// not be zero. On Data edges, the value may be zero, which would mean that
+ /// no specific register is associated with this edge.
void setReg(unsigned Reg) {
assert((getKind() == Data || getKind() == Anti || getKind() == Output) &&
"setReg called on non-register dependence edge!");
@@ -235,120 +235,109 @@ namespace llvm {
"SDep::Output edge cannot use the zero register!");
Contents.Reg = Reg;
}
+
+ raw_ostream &print(raw_ostream &O,
+ const TargetRegisterInfo *TRI = nullptr) const;
};
template <>
struct isPodLike<SDep> { static const bool value = true; };
- /// SUnit - Scheduling unit. This is a node in the scheduling DAG.
+ /// Scheduling unit. This is a node in the scheduling DAG.
class SUnit {
private:
enum : unsigned { BoundaryID = ~0u };
- SDNode *Node; // Representative node.
- MachineInstr *Instr; // Alternatively, a MachineInstr.
+ SDNode *Node = nullptr; ///< Representative node.
+ MachineInstr *Instr = nullptr; ///< Alternatively, a MachineInstr.
+
public:
- SUnit *OrigNode; // If not this, the node from which
- // this node was cloned.
- // (SD scheduling only)
+ SUnit *OrigNode = nullptr; ///< If not this, the node from which this node
+ /// was cloned. (SD scheduling only)
- const MCSchedClassDesc *SchedClass; // NULL or resolved SchedClass.
+ const MCSchedClassDesc *SchedClass =
+ nullptr; ///< nullptr or resolved SchedClass.
- // Preds/Succs - The SUnits before/after us in the graph.
- SmallVector<SDep, 4> Preds; // All sunit predecessors.
- SmallVector<SDep, 4> Succs; // All sunit successors.
+ SmallVector<SDep, 4> Preds; ///< All sunit predecessors.
+ SmallVector<SDep, 4> Succs; ///< All sunit successors.
typedef SmallVectorImpl<SDep>::iterator pred_iterator;
typedef SmallVectorImpl<SDep>::iterator succ_iterator;
typedef SmallVectorImpl<SDep>::const_iterator const_pred_iterator;
typedef SmallVectorImpl<SDep>::const_iterator const_succ_iterator;
- unsigned NodeNum; // Entry # of node in the node vector.
- unsigned NodeQueueId; // Queue id of node.
- unsigned NumPreds; // # of SDep::Data preds.
- unsigned NumSuccs; // # of SDep::Data sucss.
- unsigned NumPredsLeft; // # of preds not scheduled.
- unsigned NumSuccsLeft; // # of succs not scheduled.
- unsigned WeakPredsLeft; // # of weak preds not scheduled.
- unsigned WeakSuccsLeft; // # of weak succs not scheduled.
- unsigned short NumRegDefsLeft; // # of reg defs with no scheduled use.
- unsigned short Latency; // Node latency.
- bool isVRegCycle : 1; // May use and def the same vreg.
- bool isCall : 1; // Is a function call.
- bool isCallOp : 1; // Is a function call operand.
- bool isTwoAddress : 1; // Is a two-address instruction.
- bool isCommutable : 1; // Is a commutable instruction.
- bool hasPhysRegUses : 1; // Has physreg uses.
- bool hasPhysRegDefs : 1; // Has physreg defs that are being used.
- bool hasPhysRegClobbers : 1; // Has any physreg defs, used or not.
- bool isPending : 1; // True once pending.
- bool isAvailable : 1; // True once available.
- bool isScheduled : 1; // True once scheduled.
- bool isScheduleHigh : 1; // True if preferable to schedule high.
- bool isScheduleLow : 1; // True if preferable to schedule low.
- bool isCloned : 1; // True if this node has been cloned.
- bool isUnbuffered : 1; // Uses an unbuffered resource.
- bool hasReservedResource : 1; // Uses a reserved resource.
- Sched::Preference SchedulingPref; // Scheduling preference.
+ unsigned NodeNum = BoundaryID; ///< Entry # of node in the node vector.
+ unsigned NodeQueueId = 0; ///< Queue id of node.
+ unsigned NumPreds = 0; ///< # of SDep::Data preds.
+ unsigned NumSuccs = 0; ///< # of SDep::Data sucss.
+ unsigned NumPredsLeft = 0; ///< # of preds not scheduled.
+ unsigned NumSuccsLeft = 0; ///< # of succs not scheduled.
+ unsigned WeakPredsLeft = 0; ///< # of weak preds not scheduled.
+ unsigned WeakSuccsLeft = 0; ///< # of weak succs not scheduled.
+ unsigned short NumRegDefsLeft = 0; ///< # of reg defs with no scheduled use.
+ unsigned short Latency = 0; ///< Node latency.
+ bool isVRegCycle : 1; ///< May use and def the same vreg.
+ bool isCall : 1; ///< Is a function call.
+ bool isCallOp : 1; ///< Is a function call operand.
+ bool isTwoAddress : 1; ///< Is a two-address instruction.
+ bool isCommutable : 1; ///< Is a commutable instruction.
+ bool hasPhysRegUses : 1; ///< Has physreg uses.
+ bool hasPhysRegDefs : 1; ///< Has physreg defs that are being used.
+ bool hasPhysRegClobbers : 1; ///< Has any physreg defs, used or not.
+ bool isPending : 1; ///< True once pending.
+ bool isAvailable : 1; ///< True once available.
+ bool isScheduled : 1; ///< True once scheduled.
+ bool isScheduleHigh : 1; ///< True if preferable to schedule high.
+ bool isScheduleLow : 1; ///< True if preferable to schedule low.
+ bool isCloned : 1; ///< True if this node has been cloned.
+ bool isUnbuffered : 1; ///< Uses an unbuffered resource.
+ bool hasReservedResource : 1; ///< Uses a reserved resource.
+ Sched::Preference SchedulingPref = Sched::None; ///< Scheduling preference.
private:
- bool isDepthCurrent : 1; // True if Depth is current.
- bool isHeightCurrent : 1; // True if Height is current.
- unsigned Depth; // Node depth.
- unsigned Height; // Node height.
+ bool isDepthCurrent : 1; ///< True if Depth is current.
+ bool isHeightCurrent : 1; ///< True if Height is current.
+ unsigned Depth = 0; ///< Node depth.
+ unsigned Height = 0; ///< Node height.
+
public:
- unsigned TopReadyCycle; // Cycle relative to start when node is ready.
- unsigned BotReadyCycle; // Cycle relative to end when node is ready.
+ unsigned TopReadyCycle = 0; ///< Cycle relative to start when node is ready.
+ unsigned BotReadyCycle = 0; ///< Cycle relative to end when node is ready.
- const TargetRegisterClass *CopyDstRC; // Is a special copy node if not null.
- const TargetRegisterClass *CopySrcRC;
+ const TargetRegisterClass *CopyDstRC =
+ nullptr; ///< Is a special copy node if != nullptr.
+ const TargetRegisterClass *CopySrcRC = nullptr;
- /// SUnit - Construct an SUnit for pre-regalloc scheduling to represent
- /// an SDNode and any nodes flagged to it.
+ /// \brief Constructs an SUnit for pre-regalloc scheduling to represent an
+ /// SDNode and any nodes flagged to it.
SUnit(SDNode *node, unsigned nodenum)
- : Node(node), Instr(nullptr), OrigNode(nullptr), SchedClass(nullptr),
- NodeNum(nodenum), NodeQueueId(0), NumPreds(0), NumSuccs(0),
- NumPredsLeft(0), NumSuccsLeft(0), WeakPredsLeft(0), WeakSuccsLeft(0),
- NumRegDefsLeft(0), Latency(0), isVRegCycle(false), isCall(false),
+ : Node(node), NodeNum(nodenum), isVRegCycle(false), isCall(false),
isCallOp(false), isTwoAddress(false), isCommutable(false),
hasPhysRegUses(false), hasPhysRegDefs(false), hasPhysRegClobbers(false),
isPending(false), isAvailable(false), isScheduled(false),
isScheduleHigh(false), isScheduleLow(false), isCloned(false),
- isUnbuffered(false), hasReservedResource(false),
- SchedulingPref(Sched::None), isDepthCurrent(false),
- isHeightCurrent(false), Depth(0), Height(0), TopReadyCycle(0),
- BotReadyCycle(0), CopyDstRC(nullptr), CopySrcRC(nullptr) {}
+ isUnbuffered(false), hasReservedResource(false), isDepthCurrent(false),
+ isHeightCurrent(false) {}
- /// SUnit - Construct an SUnit for post-regalloc scheduling to represent
- /// a MachineInstr.
+ /// \brief Constructs an SUnit for post-regalloc scheduling to represent a
+ /// MachineInstr.
SUnit(MachineInstr *instr, unsigned nodenum)
- : Node(nullptr), Instr(instr), OrigNode(nullptr), SchedClass(nullptr),
- NodeNum(nodenum), NodeQueueId(0), NumPreds(0), NumSuccs(0),
- NumPredsLeft(0), NumSuccsLeft(0), WeakPredsLeft(0), WeakSuccsLeft(0),
- NumRegDefsLeft(0), Latency(0), isVRegCycle(false), isCall(false),
+ : Instr(instr), NodeNum(nodenum), isVRegCycle(false), isCall(false),
isCallOp(false), isTwoAddress(false), isCommutable(false),
hasPhysRegUses(false), hasPhysRegDefs(false), hasPhysRegClobbers(false),
isPending(false), isAvailable(false), isScheduled(false),
isScheduleHigh(false), isScheduleLow(false), isCloned(false),
- isUnbuffered(false), hasReservedResource(false),
- SchedulingPref(Sched::None), isDepthCurrent(false),
- isHeightCurrent(false), Depth(0), Height(0), TopReadyCycle(0),
- BotReadyCycle(0), CopyDstRC(nullptr), CopySrcRC(nullptr) {}
+ isUnbuffered(false), hasReservedResource(false), isDepthCurrent(false),
+ isHeightCurrent(false) {}
- /// SUnit - Construct a placeholder SUnit.
+ /// \brief Constructs a placeholder SUnit.
SUnit()
- : Node(nullptr), Instr(nullptr), OrigNode(nullptr), SchedClass(nullptr),
- NodeNum(BoundaryID), NodeQueueId(0), NumPreds(0), NumSuccs(0),
- NumPredsLeft(0), NumSuccsLeft(0), WeakPredsLeft(0), WeakSuccsLeft(0),
- NumRegDefsLeft(0), Latency(0), isVRegCycle(false), isCall(false),
- isCallOp(false), isTwoAddress(false), isCommutable(false),
- hasPhysRegUses(false), hasPhysRegDefs(false), hasPhysRegClobbers(false),
- isPending(false), isAvailable(false), isScheduled(false),
- isScheduleHigh(false), isScheduleLow(false), isCloned(false),
- isUnbuffered(false), hasReservedResource(false),
- SchedulingPref(Sched::None), isDepthCurrent(false),
- isHeightCurrent(false), Depth(0), Height(0), TopReadyCycle(0),
- BotReadyCycle(0), CopyDstRC(nullptr), CopySrcRC(nullptr) {}
+ : isVRegCycle(false), isCall(false), isCallOp(false), isTwoAddress(false),
+ isCommutable(false), hasPhysRegUses(false), hasPhysRegDefs(false),
+ hasPhysRegClobbers(false), isPending(false), isAvailable(false),
+ isScheduled(false), isScheduleHigh(false), isScheduleLow(false),
+ isCloned(false), isUnbuffered(false), hasReservedResource(false),
+ isDepthCurrent(false), isHeightCurrent(false) {}
/// \brief Boundary nodes are placeholders for the boundary of the
/// scheduling region.
@@ -356,49 +345,47 @@ namespace llvm {
/// BoundaryNodes can have DAG edges, including Data edges, but they do not
/// correspond to schedulable entities (e.g. instructions) and do not have a
/// valid ID. Consequently, always check for boundary nodes before accessing
- /// an assoicative data structure keyed on node ID.
+ /// an associative data structure keyed on node ID.
bool isBoundaryNode() const { return NodeNum == BoundaryID; }
- /// setNode - Assign the representative SDNode for this SUnit.
- /// This may be used during pre-regalloc scheduling.
+ /// Assigns the representative SDNode for this SUnit. This may be used
+ /// during pre-regalloc scheduling.
void setNode(SDNode *N) {
assert(!Instr && "Setting SDNode of SUnit with MachineInstr!");
Node = N;
}
- /// getNode - Return the representative SDNode for this SUnit.
- /// This may be used during pre-regalloc scheduling.
+ /// Returns the representative SDNode for this SUnit. This may be used
+ /// during pre-regalloc scheduling.
SDNode *getNode() const {
assert(!Instr && "Reading SDNode of SUnit with MachineInstr!");
return Node;
}
- /// isInstr - Return true if this SUnit refers to a machine instruction as
+ /// \brief Returns true if this SUnit refers to a machine instruction as
/// opposed to an SDNode.
bool isInstr() const { return Instr; }
- /// setInstr - Assign the instruction for the SUnit.
- /// This may be used during post-regalloc scheduling.
+ /// Assigns the instruction for the SUnit. This may be used during
+ /// post-regalloc scheduling.
void setInstr(MachineInstr *MI) {
assert(!Node && "Setting MachineInstr of SUnit with SDNode!");
Instr = MI;
}
- /// getInstr - Return the representative MachineInstr for this SUnit.
- /// This may be used during post-regalloc scheduling.
+ /// Returns the representative MachineInstr for this SUnit. This may be used
+ /// during post-regalloc scheduling.
MachineInstr *getInstr() const {
assert(!Node && "Reading MachineInstr of SUnit with SDNode!");
return Instr;
}
- /// addPred - This adds the specified edge as a pred of the current node if
- /// not already. It also adds the current node as a successor of the
- /// specified node.
+ /// Adds the specified edge as a pred of the current node if not already.
+ /// It also adds the current node as a successor of the specified node.
bool addPred(const SDep &D, bool Required = true);
- /// addPredBarrier - This adds a barrier edge to SU by calling
- /// addPred(), with latency 0 generally or latency 1 for a store
- /// followed by a load.
+ /// \brief Adds a barrier edge to SU by calling addPred(), with latency 0
+ /// generally or latency 1 for a store followed by a load.
bool addPredBarrier(SUnit *SU) {
SDep Dep(SU, SDep::Barrier);
unsigned TrueMemOrderLatency =
@@ -407,20 +394,19 @@ namespace llvm {
return addPred(Dep);
}
- /// removePred - This removes the specified edge as a pred of the current
- /// node if it exists. It also removes the current node as a successor of
- /// the specified node.
+ /// Removes the specified edge as a pred of the current node if it exists.
+ /// It also removes the current node as a successor of the specified node.
void removePred(const SDep &D);
- /// getDepth - Return the depth of this node, which is the length of the
- /// maximum path up to any node which has no predecessors.
+ /// Returns the depth of this node, which is the length of the maximum path
+ /// up to any node which has no predecessors.
unsigned getDepth() const {
if (!isDepthCurrent)
const_cast<SUnit *>(this)->ComputeDepth();
return Depth;
}
- /// getHeight - Return the height of this node, which is the length of the
+ /// \brief Returns the height of this node, which is the length of the
/// maximum path down to any node which has no successors.
unsigned getHeight() const {
if (!isHeightCurrent)
@@ -428,38 +414,36 @@ namespace llvm {
return Height;
}
- /// setDepthToAtLeast - If NewDepth is greater than this node's
- /// depth value, set it to be the new depth value. This also
- /// recursively marks successor nodes dirty.
+ /// \brief If NewDepth is greater than this node's depth value, sets it to
+ /// be the new depth value. This also recursively marks successor nodes
+ /// dirty.
void setDepthToAtLeast(unsigned NewDepth);
- /// setDepthToAtLeast - If NewDepth is greater than this node's
- /// depth value, set it to be the new height value. This also
- /// recursively marks predecessor nodes dirty.
+ /// \brief If NewDepth is greater than this node's depth value, set it to be
+ /// the new height value. This also recursively marks predecessor nodes
+ /// dirty.
void setHeightToAtLeast(unsigned NewHeight);
- /// setDepthDirty - Set a flag in this node to indicate that its
- /// stored Depth value will require recomputation the next time
- /// getDepth() is called.
+ /// \brief Sets a flag in this node to indicate that its stored Depth value
+ /// will require recomputation the next time getDepth() is called.
void setDepthDirty();
- /// setHeightDirty - Set a flag in this node to indicate that its
- /// stored Height value will require recomputation the next time
- /// getHeight() is called.
+ /// \brief Sets a flag in this node to indicate that its stored Height value
+ /// will require recomputation the next time getHeight() is called.
void setHeightDirty();
- /// isPred - Test if node N is a predecessor of this node.
- bool isPred(SUnit *N) {
- for (unsigned i = 0, e = (unsigned)Preds.size(); i != e; ++i)
- if (Preds[i].getSUnit() == N)
+ /// Tests if node N is a predecessor of this node.
+ bool isPred(const SUnit *N) const {
+ for (const SDep &Pred : Preds)
+ if (Pred.getSUnit() == N)
return true;
return false;
}
- /// isSucc - Test if node N is a successor of this node.
- bool isSucc(SUnit *N) {
- for (unsigned i = 0, e = (unsigned)Succs.size(); i != e; ++i)
- if (Succs[i].getSUnit() == N)
+ /// Tests if node N is a successor of this node.
+ bool isSucc(const SUnit *N) const {
+ for (const SDep &Succ : Succs)
+ if (Succ.getSUnit() == N)
return true;
return false;
}
@@ -471,20 +455,23 @@ namespace llvm {
return NumSuccsLeft == 0;
}
- /// \brief Order this node's predecessor edges such that the critical path
+ /// \brief Orders this node's predecessor edges such that the critical path
/// edge occurs first.
void biasCriticalPath();
void dump(const ScheduleDAG *G) const;
void dumpAll(const ScheduleDAG *G) const;
- void print(raw_ostream &O, const ScheduleDAG *G) const;
+ raw_ostream &print(raw_ostream &O,
+ const SUnit *N = nullptr,
+ const SUnit *X = nullptr) const;
+ raw_ostream &print(raw_ostream &O, const ScheduleDAG *G) const;
private:
void ComputeDepth();
void ComputeHeight();
};
- /// Return true if the specified SDep is equivalent except for latency.
+ /// Returns true if the specified SDep is equivalent except for latency.
inline bool SDep::overlaps(const SDep &Other) const {
if (Dep != Other.Dep)
return false;
@@ -499,31 +486,33 @@ namespace llvm {
llvm_unreachable("Invalid dependency kind!");
}
- //// getSUnit - Return the SUnit to which this edge points.
+ //// Returns the SUnit to which this edge points.
inline SUnit *SDep::getSUnit() const { return Dep.getPointer(); }
- //// setSUnit - Assign the SUnit to which this edge points.
+ //// Assigns the SUnit to which this edge points.
inline void SDep::setSUnit(SUnit *SU) { Dep.setPointer(SU); }
- /// getKind - Return an enum value representing the kind of the dependence.
+ /// Returns an enum value representing the kind of the dependence.
inline SDep::Kind SDep::getKind() const { return Dep.getInt(); }
//===--------------------------------------------------------------------===//
- /// SchedulingPriorityQueue - This interface is used to plug different
- /// priorities computation algorithms into the list scheduler. It implements
- /// the interface of a standard priority queue, where nodes are inserted in
- /// arbitrary order and returned in priority order. The computation of the
- /// priority and the representation of the queue are totally up to the
- /// implementation to decide.
- ///
+
+ /// \brief This interface is used to plug different priorities computation
+ /// algorithms into the list scheduler. It implements the interface of a
+ /// standard priority queue, where nodes are inserted in arbitrary order and
+ /// returned in priority order. The computation of the priority and the
+ /// representation of the queue are totally up to the implementation to
+ /// decide.
class SchedulingPriorityQueue {
virtual void anchor();
- unsigned CurCycle;
+
+ unsigned CurCycle = 0;
bool HasReadyFilter;
+
public:
- SchedulingPriorityQueue(bool rf = false):
- CurCycle(0), HasReadyFilter(rf) {}
- virtual ~SchedulingPriorityQueue() {}
+ SchedulingPriorityQueue(bool rf = false) : HasReadyFilter(rf) {}
+
+ virtual ~SchedulingPriorityQueue() = default;
virtual bool isBottomUp() const = 0;
@@ -542,6 +531,7 @@ namespace llvm {
assert(!HasReadyFilter && "The ready filter must override isReady()");
return true;
}
+
virtual void push(SUnit *U) = 0;
void push_all(const std::vector<SUnit *> &Nodes) {
@@ -556,10 +546,9 @@ namespace llvm {
virtual void dump(ScheduleDAG *) const {}
- /// scheduledNode - As each node is scheduled, this method is invoked. This
- /// allows the priority function to adjust the priority of related
- /// unscheduled nodes, for example.
- ///
+ /// As each node is scheduled, this method is invoked. This allows the
+ /// priority function to adjust the priority of related unscheduled nodes,
+ /// for example.
virtual void scheduledNode(SUnit *) {}
virtual void unscheduledNode(SUnit *) {}
@@ -575,14 +564,14 @@ namespace llvm {
class ScheduleDAG {
public:
- const TargetMachine &TM; // Target processor
- const TargetInstrInfo *TII; // Target instruction information
- const TargetRegisterInfo *TRI; // Target processor register info
- MachineFunction &MF; // Machine function
- MachineRegisterInfo &MRI; // Virtual/real register map
- std::vector<SUnit> SUnits; // The scheduling units.
- SUnit EntrySU; // Special node for the region entry.
- SUnit ExitSU; // Special node for the region exit.
+ const TargetMachine &TM; ///< Target processor
+ const TargetInstrInfo *TII; ///< Target instruction information
+ const TargetRegisterInfo *TRI; ///< Target processor register info
+ MachineFunction &MF; ///< Machine function
+ MachineRegisterInfo &MRI; ///< Virtual/real register map
+ std::vector<SUnit> SUnits; ///< The scheduling units.
+ SUnit EntrySU; ///< Special node for the region entry.
+ SUnit ExitSU; ///< Special node for the region exit.
#ifdef NDEBUG
static const bool StressSched = false;
@@ -594,43 +583,39 @@ namespace llvm {
virtual ~ScheduleDAG();
- /// clearDAG - clear the DAG state (between regions).
+ /// Clears the DAG state (between regions).
void clearDAG();
- /// getInstrDesc - Return the MCInstrDesc of this SUnit.
- /// Return NULL for SDNodes without a machine opcode.
+ /// Returns the MCInstrDesc of this SUnit.
+ /// Returns NULL for SDNodes without a machine opcode.
const MCInstrDesc *getInstrDesc(const SUnit *SU) const {
if (SU->isInstr()) return &SU->getInstr()->getDesc();
return getNodeDesc(SU->getNode());
}
- /// viewGraph - Pop up a GraphViz/gv window with the ScheduleDAG rendered
- /// using 'dot'.
- ///
+ /// Pops up a GraphViz/gv window with the ScheduleDAG rendered using 'dot'.
virtual void viewGraph(const Twine &Name, const Twine &Title);
virtual void viewGraph();
virtual void dumpNode(const SUnit *SU) const = 0;
- /// getGraphNodeLabel - Return a label for an SUnit node in a visualization
- /// of the ScheduleDAG.
+ /// Returns a label for an SUnit node in a visualization of the ScheduleDAG.
virtual std::string getGraphNodeLabel(const SUnit *SU) const = 0;
- /// getDAGLabel - Return a label for the region of code covered by the DAG.
+ /// Returns a label for the region of code covered by the DAG.
virtual std::string getDAGName() const = 0;
- /// addCustomGraphFeatures - Add custom features for a visualization of
- /// the ScheduleDAG.
+ /// Adds custom features for a visualization of the ScheduleDAG.
virtual void addCustomGraphFeatures(GraphWriter<ScheduleDAG*> &) const {}
#ifndef NDEBUG
- /// VerifyScheduledDAG - Verify that all SUnits were scheduled and that
- /// their state is consistent. Return the number of scheduled SUnits.
+ /// \brief Verifies that all SUnits were scheduled and that their state is
+ /// consistent. Returns the number of scheduled SUnits.
unsigned VerifyScheduledDAG(bool isBottomUp);
#endif
private:
- // Return the MCInstrDesc of this SDNode or NULL.
+ /// Returns the MCInstrDesc of this SDNode or NULL.
const MCInstrDesc *getNodeDesc(const SDNode *Node) const;
};
@@ -640,6 +625,7 @@ namespace llvm {
unsigned Operand;
SUnitIterator(SUnit *N, unsigned Op) : Node(N), Operand(Op) {}
+
public:
bool operator==(const SUnitIterator& x) const {
return Operand == x.Operand;
@@ -666,7 +652,8 @@ namespace llvm {
unsigned getOperand() const { return Operand; }
const SUnit *getNode() const { return Node; }
- /// isCtrlDep - Test if this is not an SDep::Data dependence.
+
+ /// Tests if this is not an SDep::Data dependence.
bool isCtrlDep() const {
return getSDep().isCtrl();
}
@@ -700,56 +687,61 @@ namespace llvm {
}
};
- /// ScheduleDAGTopologicalSort is a class that computes a topological
- /// ordering for SUnits and provides methods for dynamically updating
- /// the ordering as new edges are added.
+ /// This class can compute a topological ordering for SUnits and provides
+ /// methods for dynamically updating the ordering as new edges are added.
///
/// This allows a very fast implementation of IsReachable, for example.
- ///
class ScheduleDAGTopologicalSort {
- /// SUnits - A reference to the ScheduleDAG's SUnits.
+ /// A reference to the ScheduleDAG's SUnits.
std::vector<SUnit> &SUnits;
SUnit *ExitSU;
- /// Index2Node - Maps topological index to the node number.
+ /// Maps topological index to the node number.
std::vector<int> Index2Node;
- /// Node2Index - Maps the node number to its topological index.
+ /// Maps the node number to its topological index.
std::vector<int> Node2Index;
- /// Visited - a set of nodes visited during a DFS traversal.
+ /// a set of nodes visited during a DFS traversal.
BitVector Visited;
- /// DFS - make a DFS traversal and mark all nodes affected by the
- /// edge insertion. These nodes will later get new topological indexes
- /// by means of the Shift method.
+ /// Makes a DFS traversal and mark all nodes affected by the edge insertion.
+ /// These nodes will later get new topological indexes by means of the Shift
+ /// method.
void DFS(const SUnit *SU, int UpperBound, bool& HasLoop);
- /// Shift - reassign topological indexes for the nodes in the DAG
- /// to preserve the topological ordering.
+ /// \brief Reassigns topological indexes for the nodes in the DAG to
+ /// preserve the topological ordering.
void Shift(BitVector& Visited, int LowerBound, int UpperBound);
- /// Allocate - assign the topological index to the node n.
+ /// Assigns the topological index to the node n.
void Allocate(int n, int index);
public:
ScheduleDAGTopologicalSort(std::vector<SUnit> &SUnits, SUnit *ExitSU);
- /// InitDAGTopologicalSorting - create the initial topological
- /// ordering from the DAG to be scheduled.
+ /// Creates the initial topological ordering from the DAG to be scheduled.
void InitDAGTopologicalSorting();
- /// IsReachable - Checks if SU is reachable from TargetSU.
+ /// Returns an array of SUs that are both in the successor
+ /// subtree of StartSU and in the predecessor subtree of TargetSU.
+ /// StartSU and TargetSU are not in the array.
+ /// Success is false if TargetSU is not in the successor subtree of
+ /// StartSU, else it is true.
+ std::vector<int> GetSubGraph(const SUnit &StartSU, const SUnit &TargetSU,
+ bool &Success);
+
+ /// Checks if \p SU is reachable from \p TargetSU.
bool IsReachable(const SUnit *SU, const SUnit *TargetSU);
- /// WillCreateCycle - Return true if addPred(TargetSU, SU) creates a cycle.
+ /// Returns true if addPred(TargetSU, SU) creates a cycle.
bool WillCreateCycle(SUnit *TargetSU, SUnit *SU);
- /// AddPred - Updates the topological ordering to accommodate an edge
- /// to be added from SUnit X to SUnit Y.
+ /// \brief Updates the topological ordering to accommodate an edge to be
+ /// added from SUnit \p X to SUnit \p Y.
void AddPred(SUnit *Y, SUnit *X);
- /// RemovePred - Updates the topological ordering to accommodate an
- /// an edge to be removed from the specified node N from the predecessors
- /// of the current node M.
+ /// \brief Updates the topological ordering to accommodate an an edge to be
+ /// removed from the specified node \p N from the predecessors of the
+ /// current node \p M.
void RemovePred(SUnit *M, SUnit *N);
typedef std::vector<int>::iterator iterator;
@@ -766,6 +758,7 @@ namespace llvm {
reverse_iterator rend() { return Index2Node.rend(); }
const_reverse_iterator rend() const { return Index2Node.rend(); }
};
-}
-#endif
+} // end namespace llvm
+
+#endif // LLVM_CODEGEN_SCHEDULEDAG_H
diff --git a/contrib/llvm/include/llvm/CodeGen/ScheduleDAGInstrs.h b/contrib/llvm/include/llvm/CodeGen/ScheduleDAGInstrs.h
index 2746765..218e22e 100644
--- a/contrib/llvm/include/llvm/CodeGen/ScheduleDAGInstrs.h
+++ b/contrib/llvm/include/llvm/CodeGen/ScheduleDAGInstrs.h
@@ -1,4 +1,4 @@
-//==- ScheduleDAGInstrs.h - MachineInstr Scheduling --------------*- C++ -*-==//
+//===- ScheduleDAGInstrs.h - MachineInstr Scheduling ------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,29 +7,46 @@
//
//===----------------------------------------------------------------------===//
//
-// This file implements the ScheduleDAGInstrs class, which implements
-// scheduling for a MachineInstr-based dependency graph.
+/// \file Implements the ScheduleDAGInstrs class, which implements scheduling
+/// for a MachineInstr-based dependency graph.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CODEGEN_SCHEDULEDAGINSTRS_H
#define LLVM_CODEGEN_SCHEDULEDAGINSTRS_H
-#include "llvm/ADT/MapVector.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/SparseMultiSet.h"
#include "llvm/ADT/SparseSet.h"
+#include "llvm/CodeGen/LivePhysRegs.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/ScheduleDAG.h"
#include "llvm/CodeGen/TargetSchedule.h"
-#include "llvm/Support/Compiler.h"
+#include "llvm/MC/LaneBitmask.h"
#include "llvm/Target/TargetRegisterInfo.h"
+#include <cassert>
+#include <cstdint>
#include <list>
+#include <utility>
+#include <vector>
namespace llvm {
+
+ class LiveIntervals;
class MachineFrameInfo;
+ class MachineFunction;
+ class MachineInstr;
class MachineLoopInfo;
- class MachineDominatorTree;
- class RegPressureTracker;
+ class MachineOperand;
+ struct MCSchedClassDesc;
class PressureDiffs;
+ class PseudoSourceValue;
+ class RegPressureTracker;
+ class UndefValue;
+ class Value;
/// An individual mapping from virtual register number to SUnit.
struct VReg2SUnit {
@@ -69,34 +86,36 @@ namespace llvm {
/// Use a SparseMultiSet to track physical registers. Storage is only
/// allocated once for the pass. It can be cleared in constant time and reused
/// without any frees.
- typedef SparseMultiSet<PhysRegSUOper, llvm::identity<unsigned>, uint16_t>
- Reg2SUnitsMap;
+ using Reg2SUnitsMap =
+ SparseMultiSet<PhysRegSUOper, identity<unsigned>, uint16_t>;
/// Use SparseSet as a SparseMap by relying on the fact that it never
/// compares ValueT's, only unsigned keys. This allows the set to be cleared
/// between scheduling regions in constant time as long as ValueT does not
/// require a destructor.
- typedef SparseSet<VReg2SUnit, VirtReg2IndexFunctor> VReg2SUnitMap;
+ using VReg2SUnitMap = SparseSet<VReg2SUnit, VirtReg2IndexFunctor>;
/// Track local uses of virtual registers. These uses are gathered by the DAG
/// builder and may be consulted by the scheduler to avoid iterating an entire
/// vreg use list.
- typedef SparseMultiSet<VReg2SUnit, VirtReg2IndexFunctor> VReg2SUnitMultiMap;
+ using VReg2SUnitMultiMap = SparseMultiSet<VReg2SUnit, VirtReg2IndexFunctor>;
- typedef SparseMultiSet<VReg2SUnitOperIdx, VirtReg2IndexFunctor>
- VReg2SUnitOperIdxMultiMap;
+ using VReg2SUnitOperIdxMultiMap =
+ SparseMultiSet<VReg2SUnitOperIdx, VirtReg2IndexFunctor>;
+
+ using ValueType = PointerUnion<const Value *, const PseudoSourceValue *>;
- typedef PointerUnion<const Value *, const PseudoSourceValue *> ValueType;
struct UnderlyingObject : PointerIntPair<ValueType, 1, bool> {
UnderlyingObject(ValueType V, bool MayAlias)
: PointerIntPair<ValueType, 1, bool>(V, MayAlias) {}
+
ValueType getValue() const { return getPointer(); }
bool mayAlias() const { return getInt(); }
};
- typedef SmallVector<UnderlyingObject, 4> UnderlyingObjectsVector;
- /// ScheduleDAGInstrs - A ScheduleDAG subclass for scheduling lists of
- /// MachineInstrs.
+ using UnderlyingObjectsVector = SmallVector<UnderlyingObject, 4>;
+
+ /// A ScheduleDAG for scheduling lists of MachineInstr.
class ScheduleDAGInstrs : public ScheduleDAG {
protected:
const MachineLoopInfo *MLI;
@@ -114,13 +133,13 @@ namespace llvm {
/// reordering. A specialized scheduler can override
/// TargetInstrInfo::isSchedulingBoundary then enable this flag to indicate
/// it has taken responsibility for scheduling the terminator correctly.
- bool CanHandleTerminators;
+ bool CanHandleTerminators = false;
/// Whether lane masks should get tracked.
- bool TrackLaneMasks;
+ bool TrackLaneMasks = false;
- /// State specific to the current scheduling region.
- /// ------------------------------------------------
+ // State specific to the current scheduling region.
+ // ------------------------------------------------
/// The block in which to insert instructions
MachineBasicBlock *BB;
@@ -138,8 +157,8 @@ namespace llvm {
/// scheduling region is mapped to an SUnit.
DenseMap<MachineInstr*, SUnit*> MISUnitMap;
- /// State internal to DAG building.
- /// -------------------------------
+ // State internal to DAG building.
+ // -------------------------------
/// Defs, Uses - Remember where defs and uses of each register are as we
/// iterate upward through the instructions. This is allocated here instead
@@ -155,160 +174,165 @@ namespace llvm {
/// Tracks the last instructions in this region using each virtual register.
VReg2SUnitOperIdxMultiMap CurrentVRegUses;
- AliasAnalysis *AAForDep;
+ AliasAnalysis *AAForDep = nullptr;
/// Remember a generic side-effecting instruction as we proceed.
/// No other SU ever gets scheduled around it (except in the special
/// case of a huge region that gets reduced).
- SUnit *BarrierChain;
+ SUnit *BarrierChain = nullptr;
public:
-
/// A list of SUnits, used in Value2SUsMap, during DAG construction.
/// Note: to gain speed it might be worth investigating an optimized
/// implementation of this data structure, such as a singly linked list
/// with a memory pool (SmallVector was tried but slow and SparseSet is not
/// applicable).
- typedef std::list<SUnit *> SUList;
+ using SUList = std::list<SUnit *>;
+
protected:
- /// A map from ValueType to SUList, used during DAG construction,
- /// as a means of remembering which SUs depend on which memory
- /// locations.
+ /// \brief A map from ValueType to SUList, used during DAG construction, as
+ /// a means of remembering which SUs depend on which memory locations.
class Value2SUsMap;
- /// Remove in FIFO order some SUs from huge maps.
+ /// Reduces maps in FIFO order, by N SUs. This is better than turning
+ /// every Nth memory SU into BarrierChain in buildSchedGraph(), since
+ /// it avoids unnecessary edges between seen SUs above the new BarrierChain,
+ /// and those below it.
void reduceHugeMemNodeMaps(Value2SUsMap &stores,
Value2SUsMap &loads, unsigned N);
- /// Add a chain edge between SUa and SUb, but only if both AliasAnalysis
- /// and Target fail to deny the dependency.
+ /// \brief Adds a chain edge between SUa and SUb, but only if both
+ /// AliasAnalysis and Target fail to deny the dependency.
void addChainDependency(SUnit *SUa, SUnit *SUb,
unsigned Latency = 0);
- /// Add dependencies as needed from all SUs in list to SU.
- void addChainDependencies(SUnit *SU, SUList &sus, unsigned Latency) {
- for (auto *su : sus)
- addChainDependency(SU, su, Latency);
+ /// Adds dependencies as needed from all SUs in list to SU.
+ void addChainDependencies(SUnit *SU, SUList &SUs, unsigned Latency) {
+ for (SUnit *Entry : SUs)
+ addChainDependency(SU, Entry, Latency);
}
- /// Add dependencies as needed from all SUs in map, to SU.
+ /// Adds dependencies as needed from all SUs in map, to SU.
void addChainDependencies(SUnit *SU, Value2SUsMap &Val2SUsMap);
- /// Add dependencies as needed to SU, from all SUs mapped to V.
+ /// Adds dependencies as needed to SU, from all SUs mapped to V.
void addChainDependencies(SUnit *SU, Value2SUsMap &Val2SUsMap,
ValueType V);
- /// Add barrier chain edges from all SUs in map, and then clear
- /// the map. This is equivalent to insertBarrierChain(), but
- /// optimized for the common case where the new BarrierChain (a
- /// global memory object) has a higher NodeNum than all SUs in
- /// map. It is assumed BarrierChain has been set before calling
- /// this.
+ /// Adds barrier chain edges from all SUs in map, and then clear the map.
+ /// This is equivalent to insertBarrierChain(), but optimized for the common
+ /// case where the new BarrierChain (a global memory object) has a higher
+ /// NodeNum than all SUs in map. It is assumed BarrierChain has been set
+ /// before calling this.
void addBarrierChain(Value2SUsMap &map);
- /// Insert a barrier chain in a huge region, far below current
- /// SU. Add barrier chain edges from all SUs in map with higher
- /// NodeNums than this new BarrierChain, and remove them from
- /// map. It is assumed BarrierChain has been set before calling
- /// this.
+ /// Inserts a barrier chain in a huge region, far below current SU.
+ /// Adds barrier chain edges from all SUs in map with higher NodeNums than
+ /// this new BarrierChain, and remove them from map. It is assumed
+ /// BarrierChain has been set before calling this.
void insertBarrierChain(Value2SUsMap &map);
/// For an unanalyzable memory access, this Value is used in maps.
UndefValue *UnknownValue;
- /// DbgValues - Remember instruction that precedes DBG_VALUE.
+ using DbgValueVector =
+ std::vector<std::pair<MachineInstr *, MachineInstr *>>;
+ /// Remember instruction that precedes DBG_VALUE.
/// These are generated by buildSchedGraph but persist so they can be
/// referenced when emitting the final schedule.
- typedef std::vector<std::pair<MachineInstr *, MachineInstr *> >
- DbgValueVector;
DbgValueVector DbgValues;
- MachineInstr *FirstDbgValue;
+ MachineInstr *FirstDbgValue = nullptr;
/// Set of live physical registers for updating kill flags.
- BitVector LiveRegs;
+ LivePhysRegs LiveRegs;
public:
explicit ScheduleDAGInstrs(MachineFunction &mf,
const MachineLoopInfo *mli,
bool RemoveKillFlags = false);
- ~ScheduleDAGInstrs() override {}
+ ~ScheduleDAGInstrs() override = default;
- /// \brief Get the machine model for instruction scheduling.
+ /// Gets the machine model for instruction scheduling.
const TargetSchedModel *getSchedModel() const { return &SchedModel; }
- /// \brief Resolve and cache a resolved scheduling class for an SUnit.
+ /// Resolves and cache a resolved scheduling class for an SUnit.
const MCSchedClassDesc *getSchedClass(SUnit *SU) const {
if (!SU->SchedClass && SchedModel.hasInstrSchedModel())
SU->SchedClass = SchedModel.resolveSchedClass(SU->getInstr());
return SU->SchedClass;
}
- /// begin - Return an iterator to the top of the current scheduling region.
+ /// Returns an iterator to the top of the current scheduling region.
MachineBasicBlock::iterator begin() const { return RegionBegin; }
- /// end - Return an iterator to the bottom of the current scheduling region.
+ /// Returns an iterator to the bottom of the current scheduling region.
MachineBasicBlock::iterator end() const { return RegionEnd; }
- /// newSUnit - Creates a new SUnit and return a ptr to it.
+ /// Creates a new SUnit and return a ptr to it.
SUnit *newSUnit(MachineInstr *MI);
- /// getSUnit - Return an existing SUnit for this MI, or NULL.
+ /// Returns an existing SUnit for this MI, or nullptr.
SUnit *getSUnit(MachineInstr *MI) const;
- /// startBlock - Prepare to perform scheduling in the given block.
+ /// Prepares to perform scheduling in the given block.
virtual void startBlock(MachineBasicBlock *BB);
- /// finishBlock - Clean up after scheduling in the given block.
+ /// Cleans up after scheduling in the given block.
virtual void finishBlock();
- /// Initialize the scheduler state for the next scheduling region.
+ /// \brief Initialize the DAG and common scheduler state for a new
+ /// scheduling region. This does not actually create the DAG, only clears
+ /// it. The scheduling driver may call BuildSchedGraph multiple times per
+ /// scheduling region.
virtual void enterRegion(MachineBasicBlock *bb,
MachineBasicBlock::iterator begin,
MachineBasicBlock::iterator end,
unsigned regioninstrs);
- /// Notify that the scheduler has finished scheduling the current region.
+ /// Called when the scheduler has finished scheduling the current region.
virtual void exitRegion();
- /// buildSchedGraph - Build SUnits from the MachineBasicBlock that we are
- /// input.
+ /// Builds SUnits for the current region.
+ /// If \p RPTracker is non-null, compute register pressure as a side effect.
+ /// The DAG builder is an efficient place to do it because it already visits
+ /// operands.
void buildSchedGraph(AliasAnalysis *AA,
RegPressureTracker *RPTracker = nullptr,
PressureDiffs *PDiffs = nullptr,
LiveIntervals *LIS = nullptr,
bool TrackLaneMasks = false);
- /// addSchedBarrierDeps - Add dependencies from instructions in the current
- /// list of instructions being scheduled to scheduling barrier. We want to
- /// make sure instructions which define registers that are either used by
- /// the terminator or are live-out are properly scheduled. This is
- /// especially important when the definition latency of the return value(s)
- /// are too high to be hidden by the branch or when the liveout registers
- /// used by instructions in the fallthrough block.
+ /// \brief Adds dependencies from instructions in the current list of
+ /// instructions being scheduled to scheduling barrier. We want to make sure
+ /// instructions which define registers that are either used by the
+ /// terminator or are live-out are properly scheduled. This is especially
+ /// important when the definition latency of the return value(s) are too
+ /// high to be hidden by the branch or when the liveout registers used by
+ /// instructions in the fallthrough block.
void addSchedBarrierDeps();
- /// schedule - Order nodes according to selected style, filling
- /// in the Sequence member.
+ /// Orders nodes according to selected style.
///
/// Typically, a scheduling algorithm will implement schedule() without
/// overriding enterRegion() or exitRegion().
virtual void schedule() = 0;
- /// finalizeSchedule - Allow targets to perform final scheduling actions at
- /// the level of the whole MachineFunction. By default does nothing.
+ /// Allow targets to perform final scheduling actions at the level of the
+ /// whole MachineFunction. By default does nothing.
virtual void finalizeSchedule() {}
void dumpNode(const SUnit *SU) const override;
- /// Return a label for a DAG node that points to an instruction.
+ /// Returns a label for a DAG node that points to an instruction.
std::string getGraphNodeLabel(const SUnit *SU) const override;
- /// Return a label for the region of code covered by the DAG.
+ /// Returns a label for the region of code covered by the DAG.
std::string getDAGName() const override;
- /// \brief Fix register kill flags that scheduling has made invalid.
- void fixupKills(MachineBasicBlock *MBB);
+ /// Fixes register kill flags that scheduling has made invalid.
+ void fixupKills(MachineBasicBlock &MBB);
+
protected:
void initSUnits();
void addPhysRegDataDeps(SUnit *SU, unsigned OperIdx);
@@ -316,21 +340,22 @@ namespace llvm {
void addVRegDefDeps(SUnit *SU, unsigned OperIdx);
void addVRegUseDeps(SUnit *SU, unsigned OperIdx);
- /// \brief PostRA helper for rewriting kill flags.
+ /// Initializes register live-range state for updating kills.
+ /// PostRA helper for rewriting kill flags.
void startBlockForKills(MachineBasicBlock *BB);
- /// \brief Toggle a register operand kill flag.
+ /// Toggles a register operand kill flag.
///
/// Other adjustments may be made to the instruction if necessary. Return
/// true if the operand has been deleted, false if not.
- bool toggleKillFlag(MachineInstr *MI, MachineOperand &MO);
+ void toggleKillFlag(MachineInstr &MI, MachineOperand &MO);
/// Returns a mask for which lanes get read/written by the given (register)
/// machine operand.
LaneBitmask getLaneMaskForMO(const MachineOperand &MO) const;
};
- /// newSUnit - Creates a new SUnit and return a ptr to it.
+ /// Creates a new SUnit and return a ptr to it.
inline SUnit *ScheduleDAGInstrs::newSUnit(MachineInstr *MI) {
#ifndef NDEBUG
const SUnit *Addr = SUnits.empty() ? nullptr : &SUnits[0];
@@ -341,13 +366,14 @@ namespace llvm {
return &SUnits.back();
}
- /// getSUnit - Return an existing SUnit for this MI, or NULL.
+ /// Returns an existing SUnit for this MI, or nullptr.
inline SUnit *ScheduleDAGInstrs::getSUnit(MachineInstr *MI) const {
DenseMap<MachineInstr*, SUnit*>::const_iterator I = MISUnitMap.find(MI);
if (I == MISUnitMap.end())
return nullptr;
return I->second;
}
-} // namespace llvm
-#endif
+} // end namespace llvm
+
+#endif // LLVM_CODEGEN_SCHEDULEDAGINSTRS_H
diff --git a/contrib/llvm/include/llvm/CodeGen/ScheduleDAGMutation.h b/contrib/llvm/include/llvm/CodeGen/ScheduleDAGMutation.h
index 02fe229..5c23642 100644
--- a/contrib/llvm/include/llvm/CodeGen/ScheduleDAGMutation.h
+++ b/contrib/llvm/include/llvm/CodeGen/ScheduleDAGMutation.h
@@ -1,4 +1,4 @@
-//==- ScheduleDAGMutation.h - MachineInstr Scheduling ------------*- C++ -*-==//
+//===- ScheduleDAGMutation.h - MachineInstr Scheduling ----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -16,16 +16,19 @@
#define LLVM_CODEGEN_SCHEDULEDAGMUTATION_H
namespace llvm {
- class ScheduleDAGInstrs;
- /// Mutate the DAG as a postpass after normal DAG building.
- class ScheduleDAGMutation {
- virtual void anchor();
- public:
- virtual ~ScheduleDAGMutation() {}
+class ScheduleDAGInstrs;
- virtual void apply(ScheduleDAGInstrs *DAG) = 0;
- };
-}
+/// Mutate the DAG as a postpass after normal DAG building.
+class ScheduleDAGMutation {
+ virtual void anchor();
-#endif
+public:
+ virtual ~ScheduleDAGMutation() = default;
+
+ virtual void apply(ScheduleDAGInstrs *DAG) = 0;
+};
+
+} // end namespace llvm
+
+#endif // LLVM_CODEGEN_SCHEDULEDAGMUTATION_H
diff --git a/contrib/llvm/include/llvm/CodeGen/ScheduleDFS.h b/contrib/llvm/include/llvm/CodeGen/ScheduleDFS.h
index b2108ad..d6a8c79 100644
--- a/contrib/llvm/include/llvm/CodeGen/ScheduleDFS.h
+++ b/contrib/llvm/include/llvm/CodeGen/ScheduleDFS.h
@@ -14,16 +14,16 @@
#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 "llvm/Support/DataTypes.h"
+#include <cassert>
+#include <cstdint>
#include <vector>
namespace llvm {
class raw_ostream;
-class IntEqClasses;
-class ScheduleDAGInstrs;
-class SUnit;
/// \brief Represent the ILP of the subDAG rooted at a DAG node.
///
@@ -75,18 +75,18 @@ class SchedDFSResult {
/// interior node. Finally, it is set to a representative subtree ID during
/// finalization.
struct NodeData {
- unsigned InstrCount;
- unsigned SubtreeID;
+ unsigned InstrCount = 0;
+ unsigned SubtreeID = InvalidSubtreeID;
- NodeData(): InstrCount(0), SubtreeID(InvalidSubtreeID) {}
+ NodeData() = default;
};
/// \brief Per-Subtree data computed during DFS.
struct TreeData {
- unsigned ParentTreeID;
- unsigned SubInstrCount;
+ unsigned ParentTreeID = InvalidSubtreeID;
+ unsigned SubInstrCount = 0;
- TreeData(): ParentTreeID(InvalidSubtreeID), SubInstrCount(0) {}
+ TreeData() = default;
};
/// \brief Record a connection between subtrees and the connection level.
@@ -107,7 +107,7 @@ class SchedDFSResult {
// For each subtree discovered during DFS, record its connections to other
// subtrees.
- std::vector<SmallVector<Connection, 4> > SubtreeConnections;
+ std::vector<SmallVector<Connection, 4>> SubtreeConnections;
/// Cache the current connection level of each subtree.
/// This mutable array is updated during scheduling.
@@ -189,6 +189,6 @@ public:
raw_ostream &operator<<(raw_ostream &OS, const ILPValue &Val);
-} // namespace llvm
+} // end namespace llvm
-#endif
+#endif // LLVM_CODEGEN_SCHEDULEDFS_H
diff --git a/contrib/llvm/include/llvm/CodeGen/ScheduleHazardRecognizer.h b/contrib/llvm/include/llvm/CodeGen/ScheduleHazardRecognizer.h
index 214be27..ace4a2d 100644
--- a/contrib/llvm/include/llvm/CodeGen/ScheduleHazardRecognizer.h
+++ b/contrib/llvm/include/llvm/CodeGen/ScheduleHazardRecognizer.h
@@ -29,10 +29,10 @@ protected:
/// state. Important to restore the state after backtracking. Additionally,
/// MaxLookAhead=0 identifies a fake recognizer, allowing the client to
/// bypass virtual calls. Currently the PostRA scheduler ignores it.
- unsigned MaxLookAhead;
+ unsigned MaxLookAhead = 0;
public:
- ScheduleHazardRecognizer(): MaxLookAhead(0) {}
+ ScheduleHazardRecognizer() = default;
virtual ~ScheduleHazardRecognizer();
enum HazardType {
@@ -117,6 +117,6 @@ public:
}
};
-}
+} // end namespace llvm
-#endif
+#endif // LLVM_CODEGEN_SCHEDULEHAZARDRECOGNIZER_H
diff --git a/contrib/llvm/include/llvm/CodeGen/SchedulerRegistry.h b/contrib/llvm/include/llvm/CodeGen/SchedulerRegistry.h
index a7a6227..badf927 100644
--- a/contrib/llvm/include/llvm/CodeGen/SchedulerRegistry.h
+++ b/contrib/llvm/include/llvm/CodeGen/SchedulerRegistry.h
@@ -1,4 +1,4 @@
-//===-- llvm/CodeGen/SchedulerRegistry.h ------------------------*- C++ -*-===//
+//===- llvm/CodeGen/SchedulerRegistry.h -------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -16,7 +16,7 @@
#define LLVM_CODEGEN_SCHEDULERREGISTRY_H
#include "llvm/CodeGen/MachinePassRegistry.h"
-#include "llvm/Target/TargetMachine.h"
+#include "llvm/Support/CodeGen.h"
namespace llvm {
@@ -26,15 +26,13 @@ namespace llvm {
///
//===----------------------------------------------------------------------===//
-class SelectionDAGISel;
class ScheduleDAGSDNodes;
-class SelectionDAG;
-class MachineBasicBlock;
+class SelectionDAGISel;
class RegisterScheduler : public MachinePassRegistryNode {
public:
- typedef ScheduleDAGSDNodes *(*FunctionPassCtor)(SelectionDAGISel*,
- CodeGenOpt::Level);
+ using FunctionPassCtor = ScheduleDAGSDNodes *(*)(SelectionDAGISel*,
+ CodeGenOpt::Level);
static MachinePassRegistry Registry;
@@ -45,13 +43,14 @@ public:
// Accessors.
- //
RegisterScheduler *getNext() const {
return (RegisterScheduler *)MachinePassRegistryNode::getNext();
}
+
static RegisterScheduler *getList() {
return (RegisterScheduler *)Registry.getList();
}
+
static void setListener(MachinePassRegistryListener *L) {
Registry.setListener(L);
}
@@ -103,4 +102,4 @@ ScheduleDAGSDNodes *createDAGLinearizer(SelectionDAGISel *IS,
} // end namespace llvm
-#endif
+#endif // LLVM_CODEGEN_SCHEDULERREGISTRY_H
diff --git a/contrib/llvm/include/llvm/CodeGen/ScoreboardHazardRecognizer.h b/contrib/llvm/include/llvm/CodeGen/ScoreboardHazardRecognizer.h
index e0c30fe..466ab53 100644
--- a/contrib/llvm/include/llvm/CodeGen/ScoreboardHazardRecognizer.h
+++ b/contrib/llvm/include/llvm/CodeGen/ScoreboardHazardRecognizer.h
@@ -17,8 +17,8 @@
#define LLVM_CODEGEN_SCOREBOARDHAZARDRECOGNIZER_H
#include "llvm/CodeGen/ScheduleHazardRecognizer.h"
-#include "llvm/Support/DataTypes.h"
#include <cassert>
+#include <cstddef>
#include <cstring>
namespace llvm {
@@ -38,21 +38,25 @@ class ScoreboardHazardRecognizer : public ScheduleHazardRecognizer {
// bottom-up scheduler, then the scoreboard cycles are the inverse of the
// scheduler's cycles.
class Scoreboard {
- unsigned *Data;
+ unsigned *Data = nullptr;
// The maximum number of cycles monitored by the Scoreboard. This
// value is determined based on the target itineraries to ensure
// that all hazards can be tracked.
- size_t Depth;
+ size_t Depth = 0;
+
// Indices into the Scoreboard that represent the current cycle.
- size_t Head;
+ size_t Head = 0;
+
public:
- Scoreboard():Data(nullptr), Depth(0), Head(0) { }
+ Scoreboard() = default;
+
~Scoreboard() {
delete[] Data;
}
size_t getDepth() const { return Depth; }
+
unsigned& operator[](size_t idx) const {
// Depth is expected to be a power-of-2.
assert(Depth && !(Depth & (Depth - 1)) &&
@@ -93,10 +97,10 @@ class ScoreboardHazardRecognizer : public ScheduleHazardRecognizer {
const ScheduleDAG *DAG;
/// IssueWidth - Max issue per cycle. 0=Unknown.
- unsigned IssueWidth;
+ unsigned IssueWidth = 0;
/// IssueCount - Count instructions issued in this cycle.
- unsigned IssueCount;
+ unsigned IssueCount = 0;
Scoreboard ReservedScoreboard;
Scoreboard RequiredScoreboard;
@@ -119,6 +123,6 @@ public:
void RecedeCycle() override;
};
-}
+} // end namespace llvm
-#endif //!LLVM_CODEGEN_SCOREBOARDHAZARDRECOGNIZER_H
+#endif // LLVM_CODEGEN_SCOREBOARDHAZARDRECOGNIZER_H
diff --git a/contrib/llvm/include/llvm/CodeGen/SelectionDAG.h b/contrib/llvm/include/llvm/CodeGen/SelectionDAG.h
index 54d0436..d6851f7 100644
--- a/contrib/llvm/include/llvm/CodeGen/SelectionDAG.h
+++ b/contrib/llvm/include/llvm/CodeGen/SelectionDAG.h
@@ -1,4 +1,4 @@
-//===-- llvm/CodeGen/SelectionDAG.h - InstSelection DAG ---------*- C++ -*-===//
+//===- llvm/CodeGen/SelectionDAG.h - InstSelection DAG ----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -15,33 +15,72 @@
#ifndef LLVM_CODEGEN_SELECTIONDAG_H
#define LLVM_CODEGEN_SELECTIONDAG_H
+#include "llvm/ADT/APFloat.h"
+#include "llvm/ADT/APInt.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/ilist.h"
+#include "llvm/ADT/iterator.h"
+#include "llvm/ADT/iterator_range.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/CodeGen/DAGCombine.h"
+#include "llvm/CodeGen/ISDOpcodes.h"
#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineMemOperand.h"
+#include "llvm/CodeGen/MachineValueType.h"
#include "llvm/CodeGen/SelectionDAGNodes.h"
+#include "llvm/CodeGen/ValueTypes.h"
+#include "llvm/IR/DebugLoc.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/Metadata.h"
+#include "llvm/Support/Allocator.h"
#include "llvm/Support/ArrayRecycler.h"
+#include "llvm/Support/AtomicOrdering.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/CodeGen.h"
+#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/RecyclingAllocator.h"
-#include "llvm/Target/TargetMachine.h"
+#include <algorithm>
#include <cassert>
+#include <cstdint>
+#include <functional>
#include <map>
#include <string>
+#include <tuple>
+#include <utility>
#include <vector>
namespace llvm {
+class BlockAddress;
+class Constant;
+class ConstantFP;
+class ConstantInt;
+class DataLayout;
+struct fltSemantics;
+class GlobalValue;
+struct KnownBits;
+class LLVMContext;
+class MachineBasicBlock;
class MachineConstantPoolValue;
-class MachineFunction;
-class MDNode;
+class MCSymbol;
+class OptimizationRemarkEmitter;
class SDDbgValue;
-class TargetLowering;
+class SelectionDAG;
class SelectionDAGTargetInfo;
+class TargetLowering;
+class TargetMachine;
+class TargetSubtargetInfo;
+class Value;
class SDVTListNode : public FoldingSetNode {
friend struct FoldingSetTrait<SDVTListNode>;
+
/// A reference to an Interned FoldingSetNodeID for this node.
/// The Allocator in SelectionDAG holds the data.
/// SDVTList contains all types which are frequently accessed in SelectionDAG.
@@ -53,11 +92,13 @@ class SDVTListNode : public FoldingSetNode {
/// The hash value for SDVTList is fixed, so cache it to avoid
/// hash calculation.
unsigned HashValue;
+
public:
SDVTListNode(const FoldingSetNodeIDRef ID, const EVT *VT, unsigned int Num) :
FastID(ID), VTs(VT), NumVTs(Num) {
HashValue = ID.ComputeHash();
}
+
SDVTList getSDVTList() {
SDVTList result = {VTs, NumVTs};
return result;
@@ -70,12 +111,14 @@ template<> struct FoldingSetTrait<SDVTListNode> : DefaultFoldingSetTrait<SDVTLis
static void Profile(const SDVTListNode &X, FoldingSetNodeID& ID) {
ID = X.FastID;
}
+
static bool Equals(const SDVTListNode &X, const FoldingSetNodeID &ID,
unsigned IDHash, FoldingSetNodeID &TempID) {
if (X.HashValue != IDHash)
return false;
return ID == X.FastID;
}
+
static unsigned ComputeHash(const SDVTListNode &X, FoldingSetNodeID &TempID) {
return X.HashValue;
}
@@ -102,13 +145,13 @@ class SDDbgInfo {
BumpPtrAllocator Alloc;
SmallVector<SDDbgValue*, 32> DbgValues;
SmallVector<SDDbgValue*, 32> ByvalParmDbgValues;
- typedef DenseMap<const SDNode*, SmallVector<SDDbgValue*, 2> > DbgValMapType;
+ using DbgValMapType = DenseMap<const SDNode *, SmallVector<SDDbgValue *, 2>>;
DbgValMapType DbgValMap;
- void operator=(const SDDbgInfo&) = delete;
- SDDbgInfo(const SDDbgInfo&) = delete;
public:
- SDDbgInfo() {}
+ SDDbgInfo() = default;
+ SDDbgInfo(const SDDbgInfo &) = delete;
+ SDDbgInfo &operator=(const SDDbgInfo &) = delete;
void add(SDDbgValue *V, const SDNode *Node, bool isParameter) {
if (isParameter) {
@@ -142,14 +185,14 @@ public:
return ArrayRef<SDDbgValue*>();
}
- typedef SmallVectorImpl<SDDbgValue*>::iterator DbgIterator;
+ using DbgIterator = SmallVectorImpl<SDDbgValue*>::iterator;
+
DbgIterator DbgBegin() { return DbgValues.begin(); }
DbgIterator DbgEnd() { return DbgValues.end(); }
DbgIterator ByvalParmDbgBegin() { return ByvalParmDbgValues.begin(); }
DbgIterator ByvalParmDbgEnd() { return ByvalParmDbgValues.end(); }
};
-class SelectionDAG;
void checkForCycles(const SelectionDAG *DAG, bool force = false);
/// This is used to represent a portion of an LLVM function in a low-level
@@ -165,12 +208,16 @@ void checkForCycles(const SelectionDAG *DAG, bool force = false);
///
class SelectionDAG {
const TargetMachine &TM;
- const SelectionDAGTargetInfo *TSI;
- const TargetLowering *TLI;
+ const SelectionDAGTargetInfo *TSI = nullptr;
+ const TargetLowering *TLI = nullptr;
MachineFunction *MF;
LLVMContext *Context;
CodeGenOpt::Level OptLevel;
+ /// The function-level optimization remark emitter. Used to emit remarks
+ /// whenever manipulating the DAG.
+ OptimizationRemarkEmitter *ORE;
+
/// The starting token.
SDNode EntryNode;
@@ -182,9 +229,9 @@ class SelectionDAG {
/// The AllocatorType for allocating SDNodes. We use
/// pool allocation with recycling.
- typedef RecyclingAllocator<BumpPtrAllocator, SDNode, sizeof(LargestSDNode),
- alignof(MostAlignedSDNode)>
- NodeAllocatorType;
+ using NodeAllocatorType = RecyclingAllocator<BumpPtrAllocator, SDNode,
+ sizeof(LargestSDNode),
+ alignof(MostAlignedSDNode)>;
/// Pool allocation for nodes.
NodeAllocatorType NodeAllocator;
@@ -237,9 +284,11 @@ public:
struct DAGNodeDeletedListener : public DAGUpdateListener {
std::function<void(SDNode *, SDNode *)> Callback;
+
DAGNodeDeletedListener(SelectionDAG &DAG,
std::function<void(SDNode *, SDNode *)> Callback)
- : DAGUpdateListener(DAG), Callback(Callback) {}
+ : DAGUpdateListener(DAG), Callback(std::move(Callback)) {}
+
void NodeDeleted(SDNode *N, SDNode *E) override { Callback(N, E); }
};
@@ -248,7 +297,7 @@ public:
/// have legal types. This is important after type legalization since
/// any illegally typed nodes generated after this point will not experience
/// type legalization.
- bool NewNodesMustHaveLegalTypes;
+ bool NewNodesMustHaveLegalTypes = false;
private:
/// DAGUpdateListener is a friend so it can manipulate the listener stack.
@@ -256,7 +305,7 @@ private:
/// Linked list of registered DAGUpdateListener instances.
/// This stack is maintained by DAGUpdateListener RAII.
- DAGUpdateListener *UpdateListeners;
+ DAGUpdateListener *UpdateListeners = nullptr;
/// Implementation of setSubgraphColor.
/// Return whether we had to truncate the search.
@@ -310,15 +359,14 @@ private:
Node->OperandList = nullptr;
}
- void operator=(const SelectionDAG&) = delete;
- SelectionDAG(const SelectionDAG&) = delete;
-
public:
- explicit SelectionDAG(const TargetMachine &TM, llvm::CodeGenOpt::Level);
+ explicit SelectionDAG(const TargetMachine &TM, CodeGenOpt::Level);
+ SelectionDAG(const SelectionDAG &) = delete;
+ SelectionDAG &operator=(const SelectionDAG &) = delete;
~SelectionDAG();
/// Prepare this SelectionDAG to process code in the given MachineFunction.
- void init(MachineFunction &mf);
+ void init(MachineFunction &NewMF, OptimizationRemarkEmitter &NewORE);
/// Clear state and free memory necessary to make this
/// SelectionDAG ready to process a new block.
@@ -331,6 +379,7 @@ public:
const TargetLowering &getTargetLoweringInfo() const { return *TLI; }
const SelectionDAGTargetInfo &getSelectionDAGInfo() const { return *TSI; }
LLVMContext *getContext() const {return Context; }
+ OptimizationRemarkEmitter &getORE() const { return *ORE; }
/// Pop up a GraphViz/gv window with the DAG rendered using 'dot'.
void viewGraph(const std::string &Title);
@@ -357,12 +406,16 @@ public:
/// Convenience for setting subgraph color attribute.
void setSubgraphColor(SDNode *N, const char *Color);
- typedef ilist<SDNode>::const_iterator allnodes_const_iterator;
+ using allnodes_const_iterator = ilist<SDNode>::const_iterator;
+
allnodes_const_iterator allnodes_begin() const { return AllNodes.begin(); }
allnodes_const_iterator allnodes_end() const { return AllNodes.end(); }
- typedef ilist<SDNode>::iterator allnodes_iterator;
+
+ using allnodes_iterator = ilist<SDNode>::iterator;
+
allnodes_iterator allnodes_begin() { return AllNodes.begin(); }
allnodes_iterator allnodes_end() { return AllNodes.end(); }
+
ilist<SDNode>::size_type allnodes_size() const {
return AllNodes.size();
}
@@ -399,7 +452,7 @@ public:
/// certain types of nodes together, or eliminating superfluous nodes. The
/// Level argument controls whether Combine is allowed to produce nodes and
/// types that are illegal on the target.
- void Combine(CombineLevel Level, AliasAnalysis &AA,
+ void Combine(CombineLevel Level, AliasAnalysis *AA,
CodeGenOpt::Level OptLevel);
/// This transforms the SelectionDAG into a SelectionDAG that
@@ -468,7 +521,6 @@ public:
//===--------------------------------------------------------------------===//
// Node creation methods.
- //
/// \brief Create a ConstantSDNode wrapping a constant value.
/// If VT is a vector type, the constant is splatted into a BUILD_VECTOR.
@@ -480,6 +532,13 @@ public:
bool isTarget = false, bool isOpaque = false);
SDValue getConstant(const APInt &Val, const SDLoc &DL, EVT VT,
bool isTarget = false, bool isOpaque = false);
+
+ SDValue getAllOnesConstant(const SDLoc &DL, EVT VT, bool IsTarget = false,
+ bool IsOpaque = false) {
+ return getConstant(APInt::getAllOnesValue(VT.getScalarSizeInBits()), DL,
+ VT, IsTarget, IsOpaque);
+ }
+
SDValue getConstant(const ConstantInt &Val, const SDLoc &DL, EVT VT,
bool isTarget = false, bool isOpaque = false);
SDValue getIntPtrConstant(uint64_t Val, const SDLoc &DL,
@@ -641,6 +700,15 @@ public:
return getNode(ISD::BUILD_VECTOR, DL, VT, Ops);
}
+ /// Return an ISD::BUILD_VECTOR node. The number of elements in VT,
+ /// which must be a vector type, must match the number of operands in Ops.
+ /// The operands must have the same type as (or, for integers, a type wider
+ /// than) VT's element type.
+ SDValue getBuildVector(EVT VT, const SDLoc &DL, ArrayRef<SDUse> Ops) {
+ // VerifySDNode (via InsertNode) checks BUILD_VECTOR later.
+ return getNode(ISD::BUILD_VECTOR, DL, VT, Ops);
+ }
+
/// Return a splat ISD::BUILD_VECTOR node, consisting of Op splatted to all
/// elements. VT must be a vector type. Op's type must be the same as (or,
/// for integers, a type wider than) VT's element type.
@@ -665,6 +733,10 @@ public:
/// Example: shuffle A, B, <0,5,2,7> -> shuffle B, A, <4,1,6,3>
SDValue getCommutedVectorShuffle(const ShuffleVectorSDNode &SV);
+ /// Convert Op, which must be of float type, to the
+ /// float type VT, by either extending or rounding (by truncation).
+ SDValue getFPExtendOrRound(SDValue Op, const SDLoc &DL, EVT VT);
+
/// Convert Op, which must be of integer type, to the
/// integer type VT, by either any-extending or truncating it.
SDValue getAnyExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT);
@@ -710,11 +782,15 @@ public:
/// \brief Create a logical NOT operation as (XOR Val, BooleanOne).
SDValue getLogicalNOT(const SDLoc &DL, SDValue Val, EVT VT);
- /// Return a new CALLSEQ_START node, which always must have a glue result
- /// (to ensure it's not CSE'd). CALLSEQ_START does not have a useful SDLoc.
- SDValue getCALLSEQ_START(SDValue Chain, SDValue Op, const SDLoc &DL) {
+ /// Return a new CALLSEQ_START node, that starts new call frame, in which
+ /// InSize bytes are set up inside CALLSEQ_START..CALLSEQ_END sequence and
+ /// OutSize specifies part of the frame set up prior to the sequence.
+ SDValue getCALLSEQ_START(SDValue Chain, uint64_t InSize, uint64_t OutSize,
+ const SDLoc &DL) {
SDVTList VTs = getVTList(MVT::Other, MVT::Glue);
- SDValue Ops[] = { Chain, Op };
+ SDValue Ops[] = { Chain,
+ getIntPtrConstant(InSize, DL, true),
+ getIntPtrConstant(OutSize, DL, true) };
return getNode(ISD::CALLSEQ_START, DL, VTs, Ops);
}
@@ -733,6 +809,9 @@ public:
return getNode(ISD::CALLSEQ_END, DL, NodeTys, Ops);
}
+ /// Return true if the result of this operation is always undefined.
+ bool isUndef(unsigned Opcode, ArrayRef<SDValue> Ops);
+
/// Return an UNDEF node. UNDEF does not have a useful SDLoc.
SDValue getUNDEF(EVT VT) {
return getNode(ISD::UNDEF, SDLoc(), VT);
@@ -748,7 +827,7 @@ public:
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
ArrayRef<SDUse> Ops);
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
- ArrayRef<SDValue> Ops, const SDNodeFlags *Flags = nullptr);
+ ArrayRef<SDValue> Ops, const SDNodeFlags Flags = SDNodeFlags());
SDValue getNode(unsigned Opcode, const SDLoc &DL, ArrayRef<EVT> ResultTys,
ArrayRef<SDValue> Ops);
SDValue getNode(unsigned Opcode, const SDLoc &DL, SDVTList VTs,
@@ -756,9 +835,10 @@ public:
// Specialize based on number of operands.
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT);
- SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, SDValue N);
+ SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, SDValue N,
+ const SDNodeFlags Flags = SDNodeFlags());
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, SDValue N1,
- SDValue N2, const SDNodeFlags *Flags = nullptr);
+ SDValue N2, const SDNodeFlags Flags = SDNodeFlags());
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, SDValue N1,
SDValue N2, SDValue N3);
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, SDValue N1,
@@ -847,7 +927,7 @@ public:
SDValue Cmp, SDValue Swp, MachinePointerInfo PtrInfo,
unsigned Alignment, AtomicOrdering SuccessOrdering,
AtomicOrdering FailureOrdering,
- SynchronizationScope SynchScope);
+ SyncScope::ID SSID);
SDValue getAtomicCmpSwap(unsigned Opcode, const SDLoc &dl, EVT MemVT,
SDVTList VTs, SDValue Chain, SDValue Ptr,
SDValue Cmp, SDValue Swp, MachineMemOperand *MMO);
@@ -857,7 +937,7 @@ public:
SDValue getAtomic(unsigned Opcode, const SDLoc &dl, EVT MemVT, SDValue Chain,
SDValue Ptr, SDValue Val, const Value *PtrVal,
unsigned Alignment, AtomicOrdering Ordering,
- SynchronizationScope SynchScope);
+ SyncScope::ID SSID);
SDValue getAtomic(unsigned Opcode, const SDLoc &dl, EVT MemVT, SDValue Chain,
SDValue Ptr, SDValue Val, MachineMemOperand *MMO);
@@ -952,7 +1032,7 @@ public:
bool IsExpanding = false);
SDValue getMaskedStore(SDValue Chain, const SDLoc &dl, SDValue Val,
SDValue Ptr, SDValue Mask, EVT MemVT,
- MachineMemOperand *MMO, bool IsTruncating = false,
+ MachineMemOperand *MMO, bool IsTruncating = false,
bool IsCompressing = false);
SDValue getMaskedGather(SDVTList VTs, EVT VT, const SDLoc &dl,
ArrayRef<SDValue> Ops, MachineMemOperand *MMO);
@@ -1035,6 +1115,11 @@ public:
SDNode *MorphNodeTo(SDNode *N, unsigned Opc, SDVTList VTs,
ArrayRef<SDValue> Ops);
+ /// Mutate the specified strict FP node to its non-strict equivalent,
+ /// unlinking the node from its chain and dropping the metadata arguments.
+ /// The node must be a strict FP node.
+ SDNode *mutateStrictFPToFP(SDNode *Node);
+
/// These are used for target selectors to create a new node
/// with specified return type(s), MachineInstr opcode, and operands.
///
@@ -1078,7 +1163,7 @@ public:
/// Get the specified node if it's already available, or else return NULL.
SDNode *getNodeIfExists(unsigned Opcode, SDVTList VTs, ArrayRef<SDValue> Ops,
- const SDNodeFlags *Flags = nullptr);
+ const SDNodeFlags Flags = SDNodeFlags());
/// Creates a SDDbgValue node.
SDDbgValue *getDbgValue(MDNode *Var, MDNode *Expr, SDNode *N, unsigned R,
@@ -1132,6 +1217,13 @@ public:
void ReplaceAllUsesOfValuesWith(const SDValue *From, const SDValue *To,
unsigned Num);
+ /// If an existing load has uses of its chain, create a token factor node with
+ /// that chain and the new memory node's chain and update users of the old
+ /// chain to the token factor. This ensures that the new memory node will have
+ /// the same relative memory dependency position as the old load. Returns the
+ /// new merged load chain.
+ SDValue makeEquivalentMemoryOrdering(LoadSDNode *Old, SDValue New);
+
/// Topological-sort the AllNodes list and a
/// assign a unique node id for each node in the DAG based on their
/// topological order. Returns the number of nodes.
@@ -1144,39 +1236,6 @@ public:
AllNodes.insert(Position, AllNodes.remove(N));
}
- /// Returns true if the opcode is a commutative binary operation.
- static bool isCommutativeBinOp(unsigned Opcode) {
- // FIXME: This should get its info from the td file, so that we can include
- // target info.
- switch (Opcode) {
- case ISD::ADD:
- case ISD::SMIN:
- case ISD::SMAX:
- case ISD::UMIN:
- case ISD::UMAX:
- case ISD::MUL:
- case ISD::MULHU:
- case ISD::MULHS:
- case ISD::SMUL_LOHI:
- case ISD::UMUL_LOHI:
- case ISD::FADD:
- case ISD::FMUL:
- case ISD::AND:
- case ISD::OR:
- case ISD::XOR:
- case ISD::SADDO:
- case ISD::UADDO:
- case ISD::ADDC:
- case ISD::ADDE:
- case ISD::FMINNUM:
- case ISD::FMAXNUM:
- case ISD::FMINNAN:
- case ISD::FMAXNAN:
- return true;
- default: return false;
- }
- }
-
/// Returns an APFloat semantics tag appropriate for the given type. If VT is
/// a vector type, the element semantics are returned.
static const fltSemantics &EVTToAPFloatSemantics(EVT VT) {
@@ -1211,9 +1270,11 @@ public:
SDDbgInfo::DbgIterator DbgBegin() { return DbgInfo->DbgBegin(); }
SDDbgInfo::DbgIterator DbgEnd() { return DbgInfo->DbgEnd(); }
+
SDDbgInfo::DbgIterator ByvalParmDbgBegin() {
return DbgInfo->ByvalParmDbgBegin();
}
+
SDDbgInfo::DbgIterator ByvalParmDbgEnd() {
return DbgInfo->ByvalParmDbgEnd();
}
@@ -1241,7 +1302,7 @@ public:
SDValue FoldConstantVectorArithmetic(unsigned Opcode, const SDLoc &DL, EVT VT,
ArrayRef<SDValue> Ops,
- const SDNodeFlags *Flags = nullptr);
+ const SDNodeFlags Flags = SDNodeFlags());
/// Constant fold a setcc to true or false.
SDValue FoldSetCC(EVT VT, SDValue N1, SDValue N2, ISD::CondCode Cond,
@@ -1258,21 +1319,32 @@ public:
const;
/// Determine which bits of Op are known to be either zero or one and return
- /// them in the KnownZero/KnownOne bitsets. For vectors, the known bits are
- /// those that are shared by every vector element.
+ /// them in Known. For vectors, the known bits are those that are shared by
+ /// every vector element.
/// Targets can implement the computeKnownBitsForTargetNode method in the
/// TargetLowering class to allow target nodes to be understood.
- void computeKnownBits(SDValue Op, APInt &KnownZero, APInt &KnownOne,
- unsigned Depth = 0) const;
+ void computeKnownBits(SDValue Op, KnownBits &Known, unsigned Depth = 0) const;
/// Determine which bits of Op 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 requested vector
- /// elements.
+ /// them in Known. The DemandedElts argument allows us to only collect the
+ /// known bits that are shared by the requested vector elements.
/// Targets can implement the computeKnownBitsForTargetNode method in the
/// TargetLowering class to allow target nodes to be understood.
- void computeKnownBits(SDValue Op, APInt &KnownZero, APInt &KnownOne,
- const APInt &DemandedElts, unsigned Depth = 0) const;
+ void computeKnownBits(SDValue Op, KnownBits &Known, const APInt &DemandedElts,
+ unsigned Depth = 0) const;
+
+ /// Used to represent the possible overflow behavior of an operation.
+ /// Never: the operation cannot overflow.
+ /// Always: the operation will always overflow.
+ /// Sometime: the operation may or may not overflow.
+ enum OverflowKind {
+ OFK_Never,
+ OFK_Sometime,
+ OFK_Always,
+ };
+
+ /// Determine if the result of the addition of 2 node can overflow.
+ OverflowKind computeOverflowKind(SDValue N0, SDValue N1) const;
/// Test if the given value is known to have exactly one bit set. This differs
/// from computeKnownBits in that it doesn't necessarily determine which bit
@@ -1288,6 +1360,17 @@ public:
/// target nodes to be understood.
unsigned ComputeNumSignBits(SDValue Op, unsigned Depth = 0) const;
+ /// Return the number of times the sign bit of the register is replicated into
+ /// the other bits. We know that at least 1 bit is always equal to the sign
+ /// bit (itself), but other cases can give us information. For example,
+ /// immediately after an "SRA X, 2", we know that the top 3 bits are all equal
+ /// to each other, so we return 3. The DemandedElts argument allows
+ /// us to only collect the minimum sign bits of the requested vector elements.
+ /// Targets can implement the ComputeNumSignBitsForTarget method in the
+ /// TargetLowering class to allow target nodes to be understood.
+ unsigned ComputeNumSignBits(SDValue Op, const APInt &DemandedElts,
+ unsigned Depth = 0) const;
+
/// Return true if the specified operand is an ISD::ADD with a ConstantSDNode
/// on the right-hand side, or if it is an ISD::OR with a ConstantSDNode that
/// is guaranteed to have the same semantics as an ADD. This handles the
@@ -1390,10 +1473,6 @@ private:
void allnodes_clear();
- SDNode *GetBinarySDNode(unsigned Opcode, const SDLoc &DL, SDVTList VTs,
- SDValue N1, SDValue N2,
- const SDNodeFlags *Flags = nullptr);
-
/// Look up the node specified by ID in CSEMap. If it exists, return it. If
/// not, return the insertion token that will make insertion faster. This
/// overload is for nodes other than Constant or ConstantFP, use the other one
@@ -1421,10 +1500,12 @@ private:
};
template <> struct GraphTraits<SelectionDAG*> : public GraphTraits<SDNode*> {
- typedef pointer_iterator<SelectionDAG::allnodes_iterator> nodes_iterator;
+ using nodes_iterator = pointer_iterator<SelectionDAG::allnodes_iterator>;
+
static nodes_iterator nodes_begin(SelectionDAG *G) {
return nodes_iterator(G->allnodes_begin());
}
+
static nodes_iterator nodes_end(SelectionDAG *G) {
return nodes_iterator(G->allnodes_end());
}
@@ -1435,7 +1516,6 @@ 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 =
@@ -1466,6 +1546,6 @@ SDValue SelectionDAG::getTargetMemSDNode(SDVTList VTs,
return SDValue(N, 0);
}
-} // end namespace llvm
+} // end namespace llvm
-#endif
+#endif // LLVM_CODEGEN_SELECTIONDAG_H
diff --git a/contrib/llvm/include/llvm/CodeGen/SelectionDAGAddressAnalysis.h b/contrib/llvm/include/llvm/CodeGen/SelectionDAGAddressAnalysis.h
new file mode 100644
index 0000000..2107e5a
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/SelectionDAGAddressAnalysis.h
@@ -0,0 +1,64 @@
+//===-- llvm/CodeGen/SelectionDAGAddressAnalysis.h ------- DAG Address Analysis
+//---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+
+#ifndef LLVM_CODEGEN_SELECTIONDAGADDRESSANALYSIS_H
+#define LLVM_CODEGEN_SELECTIONDAGADDRESSANALYSIS_H
+
+#include "llvm/CodeGen/ISDOpcodes.h"
+#include "llvm/CodeGen/SelectionDAG.h"
+#include "llvm/CodeGen/SelectionDAGNodes.h"
+
+namespace llvm {
+/// Helper struct to parse and store a memory address as base + index + offset.
+/// We ignore sign extensions when it is safe to do so.
+/// The following two expressions are not equivalent. To differentiate we need
+/// to store whether there was a sign extension involved in the index
+/// computation.
+/// (load (i64 add (i64 copyfromreg %c)
+/// (i64 signextend (add (i8 load %index)
+/// (i8 1))))
+/// vs
+///
+/// (load (i64 add (i64 copyfromreg %c)
+/// (i64 signextend (i32 add (i32 signextend (i8 load %index))
+/// (i32 1)))))
+class BaseIndexOffset {
+private:
+ SDValue Base;
+ SDValue Index;
+ int64_t Offset;
+ bool IsIndexSignExt;
+
+public:
+ BaseIndexOffset() : Offset(0), IsIndexSignExt(false) {}
+
+ BaseIndexOffset(SDValue Base, SDValue Index, int64_t Offset,
+ bool IsIndexSignExt)
+ : Base(Base), Index(Index), Offset(Offset),
+ IsIndexSignExt(IsIndexSignExt) {}
+
+ SDValue getBase() { return Base; }
+ SDValue getIndex() { return Index; }
+
+ bool equalBaseIndex(BaseIndexOffset &Other, const SelectionDAG &DAG) {
+ int64_t Off;
+ return equalBaseIndex(Other, DAG, Off);
+ }
+
+ bool equalBaseIndex(BaseIndexOffset &Other, const SelectionDAG &DAG,
+ int64_t &Off);
+
+ /// Parses tree in Ptr for base, index, offset addresses.
+ static BaseIndexOffset match(SDValue Ptr, const SelectionDAG &DAG);
+};
+} // namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/CodeGen/SelectionDAGISel.h b/contrib/llvm/include/llvm/CodeGen/SelectionDAGISel.h
index 61d7ec4..591b2f7 100644
--- a/contrib/llvm/include/llvm/CodeGen/SelectionDAGISel.h
+++ b/contrib/llvm/include/llvm/CodeGen/SelectionDAGISel.h
@@ -20,6 +20,7 @@
#include "llvm/IR/BasicBlock.h"
#include "llvm/Pass.h"
#include "llvm/Target/TargetSubtargetInfo.h"
+#include <memory>
namespace llvm {
class FastISel;
@@ -29,6 +30,7 @@ namespace llvm {
class MachineBasicBlock;
class MachineFunction;
class MachineInstr;
+ class OptimizationRemarkEmitter;
class TargetLowering;
class TargetLibraryInfo;
class FunctionLoweringInfo;
@@ -53,6 +55,12 @@ public:
CodeGenOpt::Level OptLevel;
const TargetInstrInfo *TII;
const TargetLowering *TLI;
+ bool FastISelFailed;
+ SmallPtrSet<const Instruction *, 4> ElidedArgCopyInstrs;
+
+ /// Current optimization remark emitter.
+ /// Used to report things like combines and FastISel failures.
+ std::unique_ptr<OptimizationRemarkEmitter> ORE;
static char ID;
@@ -151,7 +159,9 @@ public:
OPC_MorphNodeTo,
// Space-optimized forms that implicitly encode number of result VTs.
OPC_MorphNodeTo0, OPC_MorphNodeTo1, OPC_MorphNodeTo2,
- OPC_CompleteMatch
+ OPC_CompleteMatch,
+ // Contains offset in table for pattern being selected
+ OPC_Coverage
};
enum {
@@ -213,6 +223,15 @@ protected:
void SelectInlineAsmMemoryOperands(std::vector<SDValue> &Ops,
const SDLoc &DL);
+ /// getPatternForIndex - Patterns selected by tablegen during ISEL
+ virtual StringRef getPatternForIndex(unsigned index) {
+ llvm_unreachable("Tblgen should generate the implementation of this!");
+ }
+
+ /// getIncludePathForIndex - get the td source location of pattern instantiation
+ virtual StringRef getIncludePathForIndex(unsigned index) {
+ llvm_unreachable("Tblgen should generate the implementation of this!");
+ }
public:
// Calls to these predicates are generated by tblgen.
bool CheckAndMask(SDValue LHS, ConstantSDNode *RHS,
@@ -270,6 +289,8 @@ private:
SDNode *MorphNode(SDNode *Node, unsigned TargetOpc, SDVTList VTs,
ArrayRef<SDValue> Ops, unsigned EmitNodeInfo);
+ SDNode *MutateStrictFPToFP(SDNode *Node, unsigned NewOpc);
+
/// Prepares the landing pad to take incoming values or do other EH
/// personality specific tasks. Returns true if the block should be
/// instruction selected, false if no code should be emitted for it.
diff --git a/contrib/llvm/include/llvm/CodeGen/SelectionDAGNodes.h b/contrib/llvm/include/llvm/CodeGen/SelectionDAGNodes.h
index b6f5424d..5fb69ae 100644
--- a/contrib/llvm/include/llvm/CodeGen/SelectionDAGNodes.h
+++ b/contrib/llvm/include/llvm/CodeGen/SelectionDAGNodes.h
@@ -1,4 +1,4 @@
-//===-- llvm/CodeGen/SelectionDAGNodes.h - SelectionDAG Nodes ---*- C++ -*-===//
+//===- llvm/CodeGen/SelectionDAGNodes.h - SelectionDAG Nodes ----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -24,11 +24,11 @@
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/GraphTraits.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/ilist_node.h"
#include "llvm/ADT/iterator.h"
#include "llvm/ADT/iterator_range.h"
-#include "llvm/ADT/SmallPtrSet.h"
-#include "llvm/ADT/SmallVector.h"
#include "llvm/CodeGen/ISDOpcodes.h"
#include "llvm/CodeGen/MachineMemOperand.h"
#include "llvm/CodeGen/MachineValueType.h"
@@ -37,6 +37,7 @@
#include "llvm/IR/DebugLoc.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
+#include "llvm/IR/Metadata.h"
#include "llvm/Support/AlignOf.h"
#include "llvm/Support/AtomicOrdering.h"
#include "llvm/Support/Casting.h"
@@ -53,14 +54,18 @@
namespace llvm {
-class SelectionDAG;
+class APInt;
+class Constant;
+template <typename T> struct DenseMapInfo;
class GlobalValue;
class MachineBasicBlock;
class MachineConstantPoolValue;
+class MCSymbol;
+class raw_ostream;
class SDNode;
+class SelectionDAG;
+class Type;
class Value;
-class MCSymbol;
-template <typename T> struct DenseMapInfo;
void checkForCycles(const SDNode *N, const SelectionDAG *DAG = nullptr,
bool force = false);
@@ -80,7 +85,10 @@ namespace ISD {
/// If N is a BUILD_VECTOR node whose elements are all the same constant or
/// undefined, return true and return the constant value in \p SplatValue.
- bool isConstantSplatVector(const SDNode *N, APInt &SplatValue);
+ /// This sets \p SplatValue to the smallest possible splat unless AllowShrink
+ /// is set to false.
+ bool isConstantSplatVector(const SDNode *N, APInt &SplatValue,
+ bool AllowShrink = true);
/// Return true if the specified node is a BUILD_VECTOR where all of the
/// elements are ~0 or undef.
@@ -118,11 +126,11 @@ namespace ISD {
class SDValue {
friend struct DenseMapInfo<SDValue>;
- SDNode *Node; // The node defining the value we are using.
- unsigned ResNo; // Which return value of the node we are using.
+ SDNode *Node = nullptr; // The node defining the value we are using.
+ unsigned ResNo = 0; // Which return value of the node we are using.
public:
- SDValue() : Node(nullptr), ResNo(0) {}
+ SDValue() = default;
SDValue(SDNode *node, unsigned resno);
/// get the index which selects a specific result in the SDNode
@@ -229,13 +237,15 @@ template <> struct isPodLike<SDValue> { static const bool value = true; };
/// Allow casting operators to work directly on
/// SDValues as if they were SDNode*'s.
template<> struct simplify_type<SDValue> {
- typedef SDNode* SimpleType;
+ using SimpleType = SDNode *;
+
static SimpleType getSimplifiedValue(SDValue &Val) {
return Val.getNode();
}
};
template<> struct simplify_type<const SDValue> {
- typedef /*const*/ SDNode* SimpleType;
+ using SimpleType = /*const*/ SDNode *;
+
static SimpleType getSimplifiedValue(const SDValue &Val) {
return Val.getNode();
}
@@ -250,16 +260,16 @@ class SDUse {
/// Val - The value being used.
SDValue Val;
/// User - The user of this value.
- SDNode *User;
+ SDNode *User = nullptr;
/// Prev, Next - Pointers to the uses list of the SDNode referred by
/// this operand.
- SDUse **Prev, *Next;
-
- SDUse(const SDUse &U) = delete;
- void operator=(const SDUse &U) = delete;
+ SDUse **Prev = nullptr;
+ SDUse *Next = nullptr;
public:
- SDUse() : User(nullptr), Prev(nullptr), Next(nullptr) {}
+ SDUse() = default;
+ SDUse(const SDUse &U) = delete;
+ SDUse &operator=(const SDUse &) = delete;
/// Normally SDUse will just implicitly convert to an SDValue that it holds.
operator const SDValue&() const { return Val; }
@@ -330,7 +340,8 @@ private:
/// simplify_type specializations - Allow casting operators to work directly on
/// SDValues as if they were SDNode*'s.
template<> struct simplify_type<SDUse> {
- typedef SDNode* SimpleType;
+ using SimpleType = SDNode *;
+
static SimpleType getSimplifiedValue(SDUse &Val) {
return Val.getNode();
}
@@ -341,6 +352,11 @@ template<> struct simplify_type<SDUse> {
/// the backend.
struct SDNodeFlags {
private:
+ // This bit is used to determine if the flags are in a defined state.
+ // Flag bits can only be masked out during intersection if the masking flags
+ // are defined.
+ bool AnyDefined : 1;
+
bool NoUnsignedWrap : 1;
bool NoSignedWrap : 1;
bool Exact : 1;
@@ -350,31 +366,62 @@ private:
bool NoSignedZeros : 1;
bool AllowReciprocal : 1;
bool VectorReduction : 1;
+ bool AllowContract : 1;
public:
/// Default constructor turns off all optimization flags.
- SDNodeFlags() {
- NoUnsignedWrap = false;
- NoSignedWrap = false;
- Exact = false;
- UnsafeAlgebra = false;
- NoNaNs = false;
- NoInfs = false;
- NoSignedZeros = false;
- AllowReciprocal = false;
- VectorReduction = false;
- }
+ SDNodeFlags()
+ : AnyDefined(false), NoUnsignedWrap(false), NoSignedWrap(false),
+ Exact(false), UnsafeAlgebra(false), NoNaNs(false), NoInfs(false),
+ NoSignedZeros(false), AllowReciprocal(false), VectorReduction(false),
+ AllowContract(false) {}
+
+ /// Sets the state of the flags to the defined state.
+ void setDefined() { AnyDefined = true; }
+ /// Returns true if the flags are in a defined state.
+ bool isDefined() const { return AnyDefined; }
// These are mutators for each flag.
- void setNoUnsignedWrap(bool b) { NoUnsignedWrap = b; }
- void setNoSignedWrap(bool b) { NoSignedWrap = b; }
- void setExact(bool b) { Exact = b; }
- void setUnsafeAlgebra(bool b) { UnsafeAlgebra = b; }
- void setNoNaNs(bool b) { NoNaNs = b; }
- void setNoInfs(bool b) { NoInfs = b; }
- void setNoSignedZeros(bool b) { NoSignedZeros = b; }
- void setAllowReciprocal(bool b) { AllowReciprocal = b; }
- void setVectorReduction(bool b) { VectorReduction = b; }
+ void setNoUnsignedWrap(bool b) {
+ setDefined();
+ NoUnsignedWrap = b;
+ }
+ void setNoSignedWrap(bool b) {
+ setDefined();
+ NoSignedWrap = b;
+ }
+ void setExact(bool b) {
+ setDefined();
+ Exact = b;
+ }
+ void setUnsafeAlgebra(bool b) {
+ setDefined();
+ UnsafeAlgebra = b;
+ }
+ void setNoNaNs(bool b) {
+ setDefined();
+ NoNaNs = b;
+ }
+ void setNoInfs(bool b) {
+ setDefined();
+ NoInfs = b;
+ }
+ void setNoSignedZeros(bool b) {
+ setDefined();
+ NoSignedZeros = b;
+ }
+ void setAllowReciprocal(bool b) {
+ setDefined();
+ AllowReciprocal = b;
+ }
+ void setVectorReduction(bool b) {
+ setDefined();
+ VectorReduction = b;
+ }
+ void setAllowContract(bool b) {
+ setDefined();
+ AllowContract = b;
+ }
// These are accessors for each flag.
bool hasNoUnsignedWrap() const { return NoUnsignedWrap; }
@@ -386,17 +433,23 @@ public:
bool hasNoSignedZeros() const { return NoSignedZeros; }
bool hasAllowReciprocal() const { return AllowReciprocal; }
bool hasVectorReduction() const { return VectorReduction; }
+ bool hasAllowContract() const { return AllowContract; }
/// Clear any flags in this flag set that aren't also set in Flags.
- void intersectWith(const SDNodeFlags *Flags) {
- NoUnsignedWrap &= Flags->NoUnsignedWrap;
- NoSignedWrap &= Flags->NoSignedWrap;
- Exact &= Flags->Exact;
- UnsafeAlgebra &= Flags->UnsafeAlgebra;
- NoNaNs &= Flags->NoNaNs;
- NoInfs &= Flags->NoInfs;
- NoSignedZeros &= Flags->NoSignedZeros;
- AllowReciprocal &= Flags->AllowReciprocal;
+ /// If the given Flags are undefined then don't do anything.
+ void intersectWith(const SDNodeFlags Flags) {
+ if (!Flags.isDefined())
+ return;
+ NoUnsignedWrap &= Flags.NoUnsignedWrap;
+ NoSignedWrap &= Flags.NoSignedWrap;
+ Exact &= Flags.Exact;
+ UnsafeAlgebra &= Flags.UnsafeAlgebra;
+ NoNaNs &= Flags.NoNaNs;
+ NoInfs &= Flags.NoInfs;
+ NoSignedZeros &= Flags.NoSignedZeros;
+ AllowReciprocal &= Flags.AllowReciprocal;
+ VectorReduction &= Flags.VectorReduction;
+ AllowContract &= Flags.AllowContract;
}
};
@@ -446,6 +499,7 @@ protected:
class LSBaseSDNodeBitfields {
friend class LSBaseSDNode;
+
uint16_t : NumMemSDNodeBits;
uint16_t AddressingMode : 3; // enum ISD::MemIndexedMode
@@ -493,21 +547,26 @@ protected:
static_assert(sizeof(StoreSDNodeBitfields) <= 2, "field too wide");
private:
+ friend class SelectionDAG;
+ // TODO: unfriend HandleSDNode once we fix its operand handling.
+ friend class HandleSDNode;
+
/// Unique id per SDNode in the DAG.
- int NodeId;
+ int NodeId = -1;
/// The values that are used by this operation.
- SDUse *OperandList;
+ SDUse *OperandList = nullptr;
/// The types of the values this node defines. SDNode's may
/// define multiple values simultaneously.
const EVT *ValueList;
/// List of uses for this SDNode.
- SDUse *UseList;
+ SDUse *UseList = nullptr;
/// The number of entries in the Operand/Value list.
- unsigned short NumOperands, NumValues;
+ unsigned short NumOperands = 0;
+ unsigned short NumValues;
// The ordering of the SDNodes. It roughly corresponds to the ordering of the
// original LLVM instructions.
@@ -522,9 +581,7 @@ private:
/// Return a pointer to the specified value type.
static const EVT *getValueTypeList(EVT VT);
- friend class SelectionDAG;
- // TODO: unfriend HandleSDNode once we fix its operand handling.
- friend class HandleSDNode;
+ SDNodeFlags Flags;
public:
/// Unique and persistent id per SDNode in the DAG.
@@ -566,6 +623,32 @@ public:
SDNodeBits.IsMemIntrinsic;
}
+ /// Test if this node is a strict floating point pseudo-op.
+ bool isStrictFPOpcode() {
+ switch (NodeType) {
+ default:
+ return false;
+ case ISD::STRICT_FADD:
+ case ISD::STRICT_FSUB:
+ case ISD::STRICT_FMUL:
+ case ISD::STRICT_FDIV:
+ case ISD::STRICT_FREM:
+ case ISD::STRICT_FSQRT:
+ case ISD::STRICT_FPOW:
+ case ISD::STRICT_FPOWI:
+ case ISD::STRICT_FSIN:
+ case ISD::STRICT_FCOS:
+ case ISD::STRICT_FEXP:
+ case ISD::STRICT_FEXP2:
+ case ISD::STRICT_FLOG:
+ case ISD::STRICT_FLOG10:
+ case ISD::STRICT_FLOG2:
+ case ISD::STRICT_FRINT:
+ case ISD::STRICT_FNEARBYINT:
+ return true;
+ }
+ }
+
/// Test if this node has a post-isel opcode, directly
/// corresponding to a MachineInstr opcode.
bool isMachineOpcode() const { return NodeType < 0; }
@@ -616,20 +699,20 @@ public:
/// operands that use a specific SDNode.
class use_iterator
: public std::iterator<std::forward_iterator_tag, SDUse, ptrdiff_t> {
- SDUse *Op;
-
friend class SDNode;
+ SDUse *Op = nullptr;
+
explicit use_iterator(SDUse *op) : Op(op) {}
public:
- typedef std::iterator<std::forward_iterator_tag,
- SDUse, ptrdiff_t>::reference reference;
- typedef std::iterator<std::forward_iterator_tag,
- SDUse, ptrdiff_t>::pointer pointer;
+ using reference = std::iterator<std::forward_iterator_tag,
+ SDUse, ptrdiff_t>::reference;
+ using pointer = std::iterator<std::forward_iterator_tag,
+ SDUse, ptrdiff_t>::pointer;
+ use_iterator() = default;
use_iterator(const use_iterator &I) : Op(I.Op) {}
- use_iterator() : Op(nullptr) {}
bool operator==(const use_iterator &x) const {
return Op == x.Op;
@@ -718,7 +801,8 @@ public:
/// if DAG changes.
static bool hasPredecessorHelper(const SDNode *N,
SmallPtrSetImpl<const SDNode *> &Visited,
- SmallVectorImpl<const SDNode *> &Worklist) {
+ SmallVectorImpl<const SDNode *> &Worklist,
+ unsigned int MaxSteps = 0) {
if (Visited.count(N))
return true;
while (!Worklist.empty()) {
@@ -733,22 +817,28 @@ public:
}
if (Found)
return true;
+ if (MaxSteps != 0 && Visited.size() >= MaxSteps)
+ return false;
}
return false;
}
+ /// Return true if all the users of N are contained in Nodes.
+ /// NOTE: Requires at least one match, but doesn't require them all.
+ static bool areOnlyUsersOf(ArrayRef<const SDNode *> Nodes, const SDNode *N);
+
/// Return the number of values used by this operation.
unsigned getNumOperands() const { return NumOperands; }
/// Helper method returns the integer value of a ConstantSDNode operand.
- uint64_t getConstantOperandVal(unsigned Num) const;
+ inline uint64_t getConstantOperandVal(unsigned Num) const;
const SDValue &getOperand(unsigned Num) const {
assert(Num < NumOperands && "Invalid child # of SDNode!");
return OperandList[Num];
}
- typedef SDUse* op_iterator;
+ using op_iterator = SDUse *;
op_iterator op_begin() const { return OperandList; }
op_iterator op_end() const { return OperandList+NumOperands; }
@@ -794,12 +884,12 @@ public:
return nullptr;
}
- /// This could be defined as a virtual function and implemented more simply
- /// and directly, but it is not to avoid creating a vtable for this class.
- const SDNodeFlags *getFlags() const;
+ const SDNodeFlags getFlags() const { return Flags; }
+ void setFlags(SDNodeFlags NewFlags) { Flags = NewFlags; }
/// Clear any flags in this node that aren't also set in Flags.
- void intersectFlagsWith(const SDNodeFlags *Flags);
+ /// If Flags is not in a defined state then this has no effect.
+ void intersectFlagsWith(const SDNodeFlags Flags);
/// Return the number of values defined/returned by this operator.
unsigned getNumValues() const { return NumValues; }
@@ -820,7 +910,8 @@ public:
return getValueType(ResNo).getSizeInBits();
}
- typedef const EVT* value_iterator;
+ using value_iterator = const EVT *;
+
value_iterator value_begin() const { return ValueList; }
value_iterator value_end() const { return ValueList+NumValues; }
@@ -896,9 +987,8 @@ protected:
/// SDNodes are created without any operands, and never own the operand
/// storage. To add operands, see SelectionDAG::createOperands.
SDNode(unsigned Opc, unsigned Order, DebugLoc dl, SDVTList VTs)
- : NodeType(Opc), NodeId(-1), OperandList(nullptr), ValueList(VTs.VTs),
- UseList(nullptr), NumOperands(0), NumValues(VTs.NumVTs), IROrder(Order),
- debugLoc(std::move(dl)) {
+ : NodeType(Opc), ValueList(VTs.VTs), NumValues(VTs.NumVTs),
+ IROrder(Order), debugLoc(std::move(dl)) {
memset(&RawSDNodeBits, 0, sizeof(RawSDNodeBits));
assert(debugLoc.hasTrivialDestructor() && "Expected trivial destructor");
assert(NumValues == VTs.NumVTs &&
@@ -1028,43 +1118,6 @@ inline void SDUse::setNode(SDNode *N) {
if (N) N->addUse(*this);
}
-/// Returns true if the opcode is a binary operation with flags.
-static bool isBinOpWithFlags(unsigned Opcode) {
- switch (Opcode) {
- case ISD::SDIV:
- case ISD::UDIV:
- case ISD::SRA:
- case ISD::SRL:
- case ISD::MUL:
- case ISD::ADD:
- case ISD::SUB:
- case ISD::SHL:
- case ISD::FADD:
- case ISD::FDIV:
- case ISD::FMUL:
- case ISD::FREM:
- case ISD::FSUB:
- return true;
- default:
- return false;
- }
-}
-
-/// This class is an extension of BinarySDNode
-/// used from those opcodes that have associated extra flags.
-class BinaryWithFlagsSDNode : public SDNode {
-public:
- SDNodeFlags Flags;
-
- BinaryWithFlagsSDNode(unsigned Opc, unsigned Order, const DebugLoc &dl,
- SDVTList VTs, const SDNodeFlags &NodeFlags)
- : SDNode(Opc, Order, dl, VTs), Flags(NodeFlags) {}
-
- static bool classof(const SDNode *N) {
- return isBinOpWithFlags(N->getOpcode());
- }
-};
-
/// This class is used to form a handle around another node that
/// is persistent and is updated across invocations of replaceAllUsesWith on its
/// operand. This node should be directly created by end-users and not added to
@@ -1166,8 +1219,8 @@ public:
/// Returns the Ranges that describes the dereference.
const MDNode *getRanges() const { return MMO->getRanges(); }
- /// Return the synchronization scope for this memory operation.
- SynchronizationScope getSynchScope() const { return MMO->getSynchScope(); }
+ /// Returns the synchronization scope ID for this memory operation.
+ SyncScope::ID getSyncScopeID() const { return MMO->getSyncScopeID(); }
/// Return the atomic ordering requirements for this memory operation. For
/// cmpxchg atomic operations, return the atomic ordering requirements when
@@ -1366,10 +1419,10 @@ public:
};
class ConstantSDNode : public SDNode {
- const ConstantInt *Value;
-
friend class SelectionDAG;
+ const ConstantInt *Value;
+
ConstantSDNode(bool isTarget, bool isOpaque, const ConstantInt *val,
const DebugLoc &DL, EVT VT)
: SDNode(isTarget ? ISD::TargetConstant : ISD::Constant, 0, DL,
@@ -1385,8 +1438,8 @@ public:
int64_t getSExtValue() const { return Value->getSExtValue(); }
bool isOne() const { return Value->isOne(); }
- bool isNullValue() const { return Value->isNullValue(); }
- bool isAllOnesValue() const { return Value->isAllOnesValue(); }
+ bool isNullValue() const { return Value->isZero(); }
+ bool isAllOnesValue() const { return Value->isMinusOne(); }
bool isOpaque() const { return ConstantSDNodeBits.IsOpaque; }
@@ -1396,11 +1449,15 @@ public:
}
};
-class ConstantFPSDNode : public SDNode {
- const ConstantFP *Value;
+uint64_t SDNode::getConstantOperandVal(unsigned Num) const {
+ return cast<ConstantSDNode>(getOperand(Num))->getZExtValue();
+}
+class ConstantFPSDNode : public SDNode {
friend class SelectionDAG;
+ const ConstantFP *Value;
+
ConstantFPSDNode(bool isTarget, const ConstantFP *val, const DebugLoc &DL,
EVT VT)
: SDNode(isTarget ? ISD::TargetConstantFP : ISD::ConstantFP, 0, DL,
@@ -1471,10 +1528,12 @@ ConstantSDNode *isConstOrConstSplat(SDValue V);
ConstantFPSDNode *isConstOrConstSplatFP(SDValue V);
class GlobalAddressSDNode : public SDNode {
+ friend class SelectionDAG;
+
const GlobalValue *TheGlobal;
int64_t Offset;
unsigned char TargetFlags;
- friend class SelectionDAG;
+
GlobalAddressSDNode(unsigned Opc, unsigned Order, const DebugLoc &DL,
const GlobalValue *GA, EVT VT, int64_t o,
unsigned char TargetFlags);
@@ -1495,10 +1554,10 @@ public:
};
class FrameIndexSDNode : public SDNode {
- int FI;
-
friend class SelectionDAG;
+ int FI;
+
FrameIndexSDNode(int fi, EVT VT, bool isTarg)
: SDNode(isTarg ? ISD::TargetFrameIndex : ISD::FrameIndex,
0, DebugLoc(), getSDVTList(VT)), FI(fi) {
@@ -1514,11 +1573,11 @@ public:
};
class JumpTableSDNode : public SDNode {
+ friend class SelectionDAG;
+
int JTI;
unsigned char TargetFlags;
- friend class SelectionDAG;
-
JumpTableSDNode(int jti, EVT VT, bool isTarg, unsigned char TF)
: SDNode(isTarg ? ISD::TargetJumpTable : ISD::JumpTable,
0, DebugLoc(), getSDVTList(VT)), JTI(jti), TargetFlags(TF) {
@@ -1535,6 +1594,8 @@ public:
};
class ConstantPoolSDNode : public SDNode {
+ friend class SelectionDAG;
+
union {
const Constant *ConstVal;
MachineConstantPoolValue *MachineCPVal;
@@ -1543,8 +1604,6 @@ class ConstantPoolSDNode : public SDNode {
unsigned Alignment; // Minimum alignment requirement of CP (not log2 value).
unsigned char TargetFlags;
- friend class SelectionDAG;
-
ConstantPoolSDNode(bool isTarget, const Constant *c, EVT VT, int o,
unsigned Align, unsigned char TF)
: SDNode(isTarget ? ISD::TargetConstantPool : ISD::ConstantPool, 0,
@@ -1598,12 +1657,12 @@ public:
/// Completely target-dependent object reference.
class TargetIndexSDNode : public SDNode {
+ friend class SelectionDAG;
+
unsigned char TargetFlags;
int Index;
int64_t Offset;
- friend class SelectionDAG;
-
public:
TargetIndexSDNode(int Idx, EVT VT, int64_t Ofs, unsigned char TF)
: SDNode(ISD::TargetIndex, 0, DebugLoc(), getSDVTList(VT)),
@@ -1619,10 +1678,10 @@ public:
};
class BasicBlockSDNode : public SDNode {
- MachineBasicBlock *MBB;
-
friend class SelectionDAG;
+ MachineBasicBlock *MBB;
+
/// Debug info is meaningful and potentially useful here, but we create
/// blocks out of order when they're jumped to, which makes it a bit
/// harder. Let's see if we need it first.
@@ -1640,10 +1699,10 @@ public:
/// A "pseudo-class" with methods for operating on BUILD_VECTORs.
class BuildVectorSDNode : public SDNode {
+public:
// These are constructed as SDNodes and then cast to BuildVectorSDNodes.
explicit BuildVectorSDNode() = delete;
-public:
/// Check if this is a constant splat, and if so, find the
/// smallest element size that splats the vector. If MinSplatBits is
/// nonzero, the element size must be at least that large. Note that the
@@ -1690,7 +1749,7 @@ public:
bool isConstant() const;
- static inline bool classof(const SDNode *N) {
+ static bool classof(const SDNode *N) {
return N->getOpcode() == ISD::BUILD_VECTOR;
}
};
@@ -1700,10 +1759,10 @@ public:
/// in the LLVM IR representation.
///
class SrcValueSDNode : public SDNode {
- const Value *V;
-
friend class SelectionDAG;
+ const Value *V;
+
/// Create a SrcValue for a general value.
explicit SrcValueSDNode(const Value *v)
: SDNode(ISD::SRCVALUE, 0, DebugLoc(), getSDVTList(MVT::Other)), V(v) {}
@@ -1718,10 +1777,10 @@ public:
};
class MDNodeSDNode : public SDNode {
- const MDNode *MD;
-
friend class SelectionDAG;
+ const MDNode *MD;
+
explicit MDNodeSDNode(const MDNode *md)
: SDNode(ISD::MDNODE_SDNODE, 0, DebugLoc(), getSDVTList(MVT::Other)), MD(md)
{}
@@ -1735,10 +1794,10 @@ public:
};
class RegisterSDNode : public SDNode {
- unsigned Reg;
-
friend class SelectionDAG;
+ unsigned Reg;
+
RegisterSDNode(unsigned reg, EVT VT)
: SDNode(ISD::Register, 0, DebugLoc(), getSDVTList(VT)), Reg(reg) {}
@@ -1751,11 +1810,11 @@ public:
};
class RegisterMaskSDNode : public SDNode {
+ friend class SelectionDAG;
+
// The memory for RegMask is not owned by the node.
const uint32_t *RegMask;
- friend class SelectionDAG;
-
RegisterMaskSDNode(const uint32_t *mask)
: SDNode(ISD::RegisterMask, 0, DebugLoc(), getSDVTList(MVT::Untyped)),
RegMask(mask) {}
@@ -1769,17 +1828,16 @@ public:
};
class BlockAddressSDNode : public SDNode {
+ friend class SelectionDAG;
+
const BlockAddress *BA;
int64_t Offset;
unsigned char TargetFlags;
- friend class SelectionDAG;
-
BlockAddressSDNode(unsigned NodeTy, EVT VT, const BlockAddress *ba,
int64_t o, unsigned char Flags)
: SDNode(NodeTy, 0, DebugLoc(), getSDVTList(VT)),
- BA(ba), Offset(o), TargetFlags(Flags) {
- }
+ BA(ba), Offset(o), TargetFlags(Flags) {}
public:
const BlockAddress *getBlockAddress() const { return BA; }
@@ -1793,10 +1851,10 @@ public:
};
class EHLabelSDNode : public SDNode {
- MCSymbol *Label;
-
friend class SelectionDAG;
+ MCSymbol *Label;
+
EHLabelSDNode(unsigned Order, const DebugLoc &dl, MCSymbol *L)
: SDNode(ISD::EH_LABEL, Order, dl, getSDVTList(MVT::Other)), Label(L) {}
@@ -1809,11 +1867,11 @@ public:
};
class ExternalSymbolSDNode : public SDNode {
+ friend class SelectionDAG;
+
const char *Symbol;
unsigned char TargetFlags;
- friend class SelectionDAG;
-
ExternalSymbolSDNode(bool isTarget, const char *Sym, unsigned char TF, EVT VT)
: SDNode(isTarget ? ISD::TargetExternalSymbol : ISD::ExternalSymbol,
0, DebugLoc(), getSDVTList(VT)), Symbol(Sym), TargetFlags(TF) {}
@@ -1829,9 +1887,10 @@ public:
};
class MCSymbolSDNode : public SDNode {
+ friend class SelectionDAG;
+
MCSymbol *Symbol;
- friend class SelectionDAG;
MCSymbolSDNode(MCSymbol *Symbol, EVT VT)
: SDNode(ISD::MCSymbol, 0, DebugLoc(), getSDVTList(VT)), Symbol(Symbol) {}
@@ -1844,10 +1903,10 @@ public:
};
class CondCodeSDNode : public SDNode {
- ISD::CondCode Condition;
-
friend class SelectionDAG;
+ ISD::CondCode Condition;
+
explicit CondCodeSDNode(ISD::CondCode Cond)
: SDNode(ISD::CONDCODE, 0, DebugLoc(), getSDVTList(MVT::Other)),
Condition(Cond) {}
@@ -1863,10 +1922,10 @@ public:
/// This class is used to represent EVT's, which are used
/// to parameterize some operations.
class VTSDNode : public SDNode {
- EVT ValueType;
-
friend class SelectionDAG;
+ EVT ValueType;
+
explicit VTSDNode(EVT VT)
: SDNode(ISD::VALUETYPE, 0, DebugLoc(), getSDVTList(MVT::Other)),
ValueType(VT) {}
@@ -1995,6 +2054,7 @@ public:
class MaskedLoadSDNode : public MaskedLoadStoreSDNode {
public:
friend class SelectionDAG;
+
MaskedLoadSDNode(unsigned Order, const DebugLoc &dl, SDVTList VTs,
ISD::LoadExtType ETy, bool IsExpanding, EVT MemVT,
MachineMemOperand *MMO)
@@ -2053,7 +2113,7 @@ class MaskedGatherScatterSDNode : public MemSDNode {
public:
friend class SelectionDAG;
- MaskedGatherScatterSDNode(ISD::NodeType NodeTy, unsigned Order,
+ MaskedGatherScatterSDNode(unsigned NodeTy, unsigned Order,
const DebugLoc &dl, SDVTList VTs, EVT MemVT,
MachineMemOperand *MMO)
: MemSDNode(NodeTy, Order, dl, VTs, MemVT, MMO) {}
@@ -2108,17 +2168,17 @@ public:
/// instruction selection proper phase.
class MachineSDNode : public SDNode {
public:
- typedef MachineMemOperand **mmo_iterator;
+ using mmo_iterator = MachineMemOperand **;
private:
friend class SelectionDAG;
MachineSDNode(unsigned Opc, unsigned Order, const DebugLoc &DL, SDVTList VTs)
- : SDNode(Opc, Order, DL, VTs), MemRefs(nullptr), MemRefsEnd(nullptr) {}
+ : SDNode(Opc, Order, DL, VTs) {}
/// Memory reference descriptions for this instruction.
- mmo_iterator MemRefs;
- mmo_iterator MemRefsEnd;
+ mmo_iterator MemRefs = nullptr;
+ mmo_iterator MemRefsEnd = nullptr;
public:
mmo_iterator memoperands_begin() const { return MemRefs; }
@@ -2180,13 +2240,15 @@ public:
};
template <> struct GraphTraits<SDNode*> {
- typedef SDNode *NodeRef;
- typedef SDNodeIterator ChildIteratorType;
+ using NodeRef = SDNode *;
+ using ChildIteratorType = SDNodeIterator;
static NodeRef getEntryNode(SDNode *N) { return N; }
+
static ChildIteratorType child_begin(NodeRef N) {
return SDNodeIterator::begin(N);
}
+
static ChildIteratorType child_end(NodeRef N) {
return SDNodeIterator::end(N);
}
@@ -2196,12 +2258,12 @@ template <> struct GraphTraits<SDNode*> {
///
/// This needs to be a union because the largest node differs on 32 bit systems
/// with 4 and 8 byte pointer alignment, respectively.
-typedef AlignedCharArrayUnion<AtomicSDNode, TargetIndexSDNode,
- BlockAddressSDNode, GlobalAddressSDNode>
- LargestSDNode;
+using LargestSDNode = AlignedCharArrayUnion<AtomicSDNode, TargetIndexSDNode,
+ BlockAddressSDNode,
+ GlobalAddressSDNode>;
/// The SDNode class with the greatest alignment requirement.
-typedef GlobalAddressSDNode MostAlignedSDNode;
+using MostAlignedSDNode = GlobalAddressSDNode;
namespace ISD {
diff --git a/contrib/llvm/include/llvm/CodeGen/SlotIndexes.h b/contrib/llvm/include/llvm/CodeGen/SlotIndexes.h
index 2ac3b3d..a7b16e7 100644
--- a/contrib/llvm/include/llvm/CodeGen/SlotIndexes.h
+++ b/contrib/llvm/include/llvm/CodeGen/SlotIndexes.h
@@ -24,13 +24,22 @@
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/ilist.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrBundle.h"
+#include "llvm/Pass.h"
#include "llvm/Support/Allocator.h"
+#include <algorithm>
+#include <cassert>
+#include <iterator>
+#include <utility>
namespace llvm {
+class raw_ostream;
+
/// This class represents an entry in the slot index list held in the
/// SlotIndexes pass. It should not be used directly. See the
/// SlotIndex & SlotIndexes classes for the public interface to this
@@ -40,7 +49,6 @@ namespace llvm {
unsigned index;
public:
-
IndexListEntry(MachineInstr *mi, unsigned index) : mi(mi), index(index) {}
MachineInstr* getInstr() const { return mi; }
@@ -301,7 +309,7 @@ namespace llvm {
return os;
}
- typedef std::pair<SlotIndex, MachineBasicBlock*> IdxMBBPair;
+ using IdxMBBPair = std::pair<SlotIndex, MachineBasicBlock *>;
inline bool operator<(SlotIndex V, const IdxMBBPair &IM) {
return V < IM.first;
@@ -325,7 +333,7 @@ namespace llvm {
// IndexListEntry allocator.
BumpPtrAllocator ileAllocator;
- typedef ilist<IndexListEntry> IndexList;
+ using IndexList = ilist<IndexListEntry>;
IndexList indexList;
#ifdef EXPENSIVE_CHECKS
@@ -334,7 +342,7 @@ namespace llvm {
MachineFunction *mf;
- typedef DenseMap<const MachineInstr*, SlotIndex> Mi2IndexMap;
+ using Mi2IndexMap = DenseMap<const MachineInstr *, SlotIndex>;
Mi2IndexMap mi2iMap;
/// MBBRanges - Map MBB number to (start, stop) indexes.
@@ -436,7 +444,7 @@ namespace llvm {
const MachineBasicBlock *MBB = MI.getParent();
assert(MBB && "MI must be inserted inna basic block");
MachineBasicBlock::const_iterator I = MI, B = MBB->begin();
- for (;;) {
+ while (true) {
if (I == B)
return getMBBStartIdx(MBB);
--I;
@@ -453,7 +461,7 @@ namespace llvm {
const MachineBasicBlock *MBB = MI.getParent();
assert(MBB && "MI must be inserted inna basic block");
MachineBasicBlock::const_iterator I = MI, E = MBB->end();
- for (;;) {
+ while (true) {
++I;
if (I == E)
return getMBBEndIdx(MBB);
@@ -497,21 +505,25 @@ namespace llvm {
/// Iterator over the idx2MBBMap (sorted pairs of slot index of basic block
/// begin and basic block)
- typedef SmallVectorImpl<IdxMBBPair>::const_iterator MBBIndexIterator;
+ using MBBIndexIterator = SmallVectorImpl<IdxMBBPair>::const_iterator;
+
/// Move iterator to the next IdxMBBPair where the SlotIndex is greater or
/// equal to \p To.
MBBIndexIterator advanceMBBIndex(MBBIndexIterator I, SlotIndex To) const {
return std::lower_bound(I, idx2MBBMap.end(), To);
}
+
/// Get an iterator pointing to the IdxMBBPair with the biggest SlotIndex
/// that is greater or equal to \p Idx.
MBBIndexIterator findMBBIndex(SlotIndex Idx) const {
return advanceMBBIndex(idx2MBBMap.begin(), Idx);
}
+
/// Returns an iterator for the begin of the idx2MBBMap.
MBBIndexIterator MBBIndexBegin() const {
return idx2MBBMap.begin();
}
+
/// Return an iterator for the end of the idx2MBBMap.
MBBIndexIterator MBBIndexEnd() const {
return idx2MBBMap.end();
@@ -602,19 +614,15 @@ namespace llvm {
return newIndex;
}
- /// Remove the given machine instruction from the mapping.
- void removeMachineInstrFromMaps(MachineInstr &MI) {
- // remove index -> MachineInstr and
- // MachineInstr -> index mappings
- Mi2IndexMap::iterator mi2iItr = mi2iMap.find(&MI);
- if (mi2iItr != mi2iMap.end()) {
- IndexListEntry *miEntry(mi2iItr->second.listEntry());
- assert(miEntry->getInstr() == &MI && "Instruction indexes broken.");
- // FIXME: Eventually we want to actually delete these indexes.
- miEntry->setInstr(nullptr);
- mi2iMap.erase(mi2iItr);
- }
- }
+ /// 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);
+
+ /// Removes a single machine instruction \p MI from the mapping.
+ /// This should be called before MachineInstr::eraseFromBundle() is used to
+ /// remove a single instruction (out of a bundle).
+ void removeSingleMachineInstrFromMaps(MachineInstr &MI);
/// ReplaceMachineInstrInMaps - Replacing a machine instr with a new one in
/// maps used by register allocator. \returns the index where the new
diff --git a/contrib/llvm/include/llvm/CodeGen/StackMaps.h b/contrib/llvm/include/llvm/CodeGen/StackMaps.h
index 7b55b79..8263946 100644
--- a/contrib/llvm/include/llvm/CodeGen/StackMaps.h
+++ b/contrib/llvm/include/llvm/CodeGen/StackMaps.h
@@ -1,4 +1,4 @@
-//===------------------- StackMaps.h - StackMaps ----------------*- C++ -*-===//
+//===- StackMaps.h - StackMaps ----------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -13,7 +13,11 @@
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/CodeGen/MachineInstr.h"
-#include "llvm/MC/MCSymbol.h"
+#include "llvm/IR/CallingConv.h"
+#include "llvm/Support/Debug.h"
+#include <algorithm>
+#include <cassert>
+#include <cstdint>
#include <vector>
namespace llvm {
@@ -21,6 +25,9 @@ namespace llvm {
class AsmPrinter;
class MCExpr;
class MCStreamer;
+class MCSymbol;
+class raw_ostream;
+class TargetRegisterInfo;
/// \brief MI-level stackmap operands.
///
@@ -138,21 +145,27 @@ public:
///
/// Statepoint operands take the form:
/// <id>, <num patch bytes >, <num call arguments>, <call target>,
-/// [call arguments], <StackMaps::ConstantOp>, <calling convention>,
+/// [call arguments...],
+/// <StackMaps::ConstantOp>, <calling convention>,
/// <StackMaps::ConstantOp>, <statepoint flags>,
-/// <StackMaps::ConstantOp>, <num other args>, [other args],
-/// [gc values]
+/// <StackMaps::ConstantOp>, <num deopt args>, [deopt args...],
+/// <gc base/derived pairs...> <gc allocas...>
+/// Note that the last two sets of arguments are not currently length
+/// prefixed.
class StatepointOpers {
-private:
+ // TODO:: we should change the STATEPOINT representation so that CC and
+ // 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
// instruction.
enum { IDPos, NBytesPos, NCallArgsPos, CallTargetPos, MetaEnd };
// These values are relative offests from the start of the statepoint meta
// arguments (i.e. the end of the call arguments).
- enum { CCOffset = 1, FlagsOffset = 3, NumVMSArgsOffset = 5 };
+ enum { CCOffset = 1, FlagsOffset = 3, NumDeoptOperandsOffset = 5 };
-public:
explicit StatepointOpers(const MachineInstr *MI) : MI(MI) {}
/// Get starting index of non call related arguments
@@ -189,21 +202,22 @@ public:
Constant,
ConstantIndex
};
- LocationType Type;
- unsigned Size;
- unsigned Reg;
- int64_t Offset;
- Location() : Type(Unprocessed), Size(0), Reg(0), Offset(0) {}
+ LocationType Type = Unprocessed;
+ unsigned Size = 0;
+ unsigned Reg = 0;
+ int64_t Offset = 0;
+
+ Location() = default;
Location(LocationType Type, unsigned Size, unsigned Reg, int64_t Offset)
: Type(Type), Size(Size), Reg(Reg), Offset(Offset) {}
};
struct LiveOutReg {
- unsigned short Reg;
- unsigned short DwarfRegNum;
- unsigned short Size;
+ unsigned short Reg = 0;
+ unsigned short DwarfRegNum = 0;
+ unsigned short Size = 0;
- LiveOutReg() : Reg(0), DwarfRegNum(0), Size(0) {}
+ LiveOutReg() = default;
LiveOutReg(unsigned short Reg, unsigned short DwarfRegNum,
unsigned short Size)
: Reg(Reg), DwarfRegNum(DwarfRegNum), Size(Size) {}
@@ -212,7 +226,7 @@ public:
// OpTypes are used to encode information about the following logical
// operand (which may consist of several MachineOperands) for the
// OpParser.
- typedef enum { DirectMemRefOp, IndirectMemRefOp, ConstantOp } OpType;
+ using OpType = enum { DirectMemRefOp, IndirectMemRefOp, ConstantOp };
StackMaps(AsmPrinter &AP);
@@ -240,31 +254,34 @@ public:
private:
static const char *WSMP;
- typedef SmallVector<Location, 8> LocationVec;
- typedef SmallVector<LiveOutReg, 8> LiveOutVec;
- typedef MapVector<uint64_t, uint64_t> ConstantPool;
+
+ using LocationVec = SmallVector<Location, 8>;
+ using LiveOutVec = SmallVector<LiveOutReg, 8>;
+ using ConstantPool = MapVector<uint64_t, uint64_t>;
struct FunctionInfo {
- uint64_t StackSize;
- uint64_t RecordCount;
- FunctionInfo() : StackSize(0), RecordCount(1) {}
- explicit FunctionInfo(uint64_t StackSize) : StackSize(StackSize), RecordCount(1) {}
+ uint64_t StackSize = 0;
+ uint64_t RecordCount = 1;
+
+ FunctionInfo() = default;
+ explicit FunctionInfo(uint64_t StackSize) : StackSize(StackSize) {}
};
struct CallsiteInfo {
- const MCExpr *CSOffsetExpr;
- uint64_t ID;
+ const MCExpr *CSOffsetExpr = nullptr;
+ uint64_t ID = 0;
LocationVec Locations;
LiveOutVec LiveOuts;
- CallsiteInfo() : CSOffsetExpr(nullptr), ID(0) {}
+
+ CallsiteInfo() = default;
CallsiteInfo(const MCExpr *CSOffsetExpr, uint64_t ID,
LocationVec &&Locations, LiveOutVec &&LiveOuts)
: CSOffsetExpr(CSOffsetExpr), ID(ID), Locations(std::move(Locations)),
LiveOuts(std::move(LiveOuts)) {}
};
- typedef MapVector<const MCSymbol *, FunctionInfo> FnInfoMap;
- typedef std::vector<CallsiteInfo> CallsiteInfoList;
+ using FnInfoMap = MapVector<const MCSymbol *, FunctionInfo>;
+ using CallsiteInfoList = std::vector<CallsiteInfo>;
AsmPrinter &AP;
CallsiteInfoList CSInfos;
@@ -309,6 +326,7 @@ private:
void print(raw_ostream &OS);
void debug() { print(dbgs()); }
};
-}
-#endif
+} // end namespace llvm
+
+#endif // LLVM_CODEGEN_STACKMAPS_H
diff --git a/contrib/llvm/include/llvm/CodeGen/StackProtector.h b/contrib/llvm/include/llvm/CodeGen/StackProtector.h
index 1b3c0eb..72de212 100644
--- a/contrib/llvm/include/llvm/CodeGen/StackProtector.h
+++ b/contrib/llvm/include/llvm/CodeGen/StackProtector.h
@@ -1,4 +1,4 @@
-//===-- StackProtector.h - Stack Protector Insertion ----------------------===//
+//===- StackProtector.h - Stack Protector Insertion -------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -19,15 +19,20 @@
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/Triple.h"
-#include "llvm/IR/Dominators.h"
+#include "llvm/IR/Instructions.h"
#include "llvm/IR/ValueMap.h"
#include "llvm/Pass.h"
-#include "llvm/Target/TargetLowering.h"
namespace llvm {
+
+class BasicBlock;
+class DominatorTree;
class Function;
+class Instruction;
class Module;
-class PHINode;
+class TargetLoweringBase;
+class TargetMachine;
+class Type;
class StackProtector : public FunctionPass {
public:
@@ -45,15 +50,15 @@ public:
};
/// A mapping of AllocaInsts to their required SSP layout.
- typedef ValueMap<const AllocaInst *, SSPLayoutKind> SSPLayoutMap;
+ using SSPLayoutMap = ValueMap<const AllocaInst *, SSPLayoutKind>;
private:
- const TargetMachine *TM;
+ const TargetMachine *TM = nullptr;
/// TLI - Keep a pointer of a TargetLowering to consult for determining
/// target type sizes.
- const TargetLoweringBase *TLI;
- const Triple Trip;
+ const TargetLoweringBase *TLI = nullptr;
+ Triple Trip;
Function *F;
Module *M;
@@ -67,7 +72,7 @@ private:
/// \brief The minimum size of buffers that will receive stack smashing
/// protection when -fstack-protection is used.
- unsigned SSPBufferSize;
+ unsigned SSPBufferSize = 0;
/// VisitedPHIs - The set of PHI nodes visited when determining
/// if a variable's reference has been taken. This set
@@ -111,19 +116,12 @@ private:
public:
static char ID; // Pass identification, replacement for typeid.
- StackProtector()
- : FunctionPass(ID), TM(nullptr), TLI(nullptr), SSPBufferSize(0) {
- initializeStackProtectorPass(*PassRegistry::getPassRegistry());
- }
- StackProtector(const TargetMachine *TM)
- : FunctionPass(ID), TM(TM), TLI(nullptr), Trip(TM->getTargetTriple()),
- SSPBufferSize(8) {
+
+ StackProtector() : FunctionPass(ID), SSPBufferSize(8) {
initializeStackProtectorPass(*PassRegistry::getPassRegistry());
}
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- AU.addPreserved<DominatorTreeWrapperPass>();
- }
+ void getAnalysisUsage(AnalysisUsage &AU) const override;
SSPLayoutKind getSSPLayout(const AllocaInst *AI) const;
@@ -134,6 +132,7 @@ public:
bool runOnFunction(Function &Fn) override;
};
+
} // end namespace llvm
#endif // LLVM_CODEGEN_STACKPROTECTOR_H
diff --git a/contrib/llvm/include/llvm/CodeGen/TailDuplicator.h b/contrib/llvm/include/llvm/CodeGen/TailDuplicator.h
index b667245..483c0ab 100644
--- a/contrib/llvm/include/llvm/CodeGen/TailDuplicator.h
+++ b/contrib/llvm/include/llvm/CodeGen/TailDuplicator.h
@@ -1,4 +1,4 @@
-//===-- llvm/CodeGen/TailDuplicator.h ---------------------------*- C++ -*-===//
+//===- llvm/CodeGen/TailDuplicator.h ----------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -15,19 +15,27 @@
#ifndef LLVM_CODEGEN_TAILDUPLICATOR_H
#define LLVM_CODEGEN_TAILDUPLICATOR_H
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/STLExtras.h"
-#include "llvm/CodeGen/MachineBranchProbabilityInfo.h"
-#include "llvm/CodeGen/MachineModuleInfo.h"
-#include "llvm/CodeGen/MachineRegisterInfo.h"
-#include "llvm/CodeGen/MachineSSAUpdater.h"
#include "llvm/CodeGen/RegisterScavenging.h"
+#include "llvm/Support/CommandLine.h"
#include "llvm/Target/TargetInstrInfo.h"
-#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/Target/TargetSubtargetInfo.h"
+#include <utility>
+#include <vector>
namespace llvm {
-extern cl::opt<unsigned> TailDupIndirectBranchSize;
+class MachineBasicBlock;
+class MachineBranchProbabilityInfo;
+class MachineFunction;
+class MachineInstr;
+class MachineModuleInfo;
+class MachineRegisterInfo;
+class TargetRegisterInfo;
/// Utility class to perform tail duplication.
class TailDuplicator {
@@ -46,7 +54,7 @@ class TailDuplicator {
// For each virtual register in SSAUpdateVals keep a list of source virtual
// registers.
- typedef std::vector<std::pair<MachineBasicBlock *, unsigned>> AvailableValsTy;
+ using AvailableValsTy = std::vector<std::pair<MachineBasicBlock *, unsigned>>;
DenseMap<unsigned, AvailableValsTy> SSAUpdateVals;
@@ -62,11 +70,14 @@ public:
void initMF(MachineFunction &MF,
const MachineBranchProbabilityInfo *MBPI,
bool LayoutMode, unsigned TailDupSize = 0);
+
bool tailDuplicateBlocks();
static bool isSimpleBB(MachineBasicBlock *TailBB);
bool shouldTailDuplicate(bool IsSimple, MachineBasicBlock &TailBB);
+
/// Returns true if TailBB can successfully be duplicated into PredBB
bool canTailDuplicate(MachineBasicBlock *TailBB, MachineBasicBlock *PredBB);
+
/// Tail duplicate a single basic block into its predecessors, and then clean
/// up.
/// If \p DuplicatePreds is not null, it will be updated to contain the list
@@ -77,10 +88,10 @@ public:
bool IsSimple, MachineBasicBlock *MBB,
MachineBasicBlock *ForcedLayoutPred,
SmallVectorImpl<MachineBasicBlock*> *DuplicatedPreds = nullptr,
- llvm::function_ref<void(MachineBasicBlock *)> *RemovalCallback = nullptr);
+ function_ref<void(MachineBasicBlock *)> *RemovalCallback = nullptr);
private:
- typedef TargetInstrInfo::RegSubRegPair RegSubRegPair;
+ using RegSubRegPair = TargetInstrInfo::RegSubRegPair;
void addSSAUpdateEntry(unsigned OrigReg, unsigned NewReg,
MachineBasicBlock *BB);
@@ -112,9 +123,9 @@ private:
void removeDeadBlock(
MachineBasicBlock *MBB,
- llvm::function_ref<void(MachineBasicBlock *)> *RemovalCallback = nullptr);
+ function_ref<void(MachineBasicBlock *)> *RemovalCallback = nullptr);
};
-} // End llvm namespace
+} // end namespace llvm
-#endif
+#endif // LLVM_CODEGEN_TAILDUPLICATOR_H
diff --git a/contrib/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/contrib/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
index cc71fa3..e4d3cc9 100644
--- a/contrib/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
+++ b/contrib/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
@@ -1,4 +1,4 @@
-//==-- llvm/CodeGen/TargetLoweringObjectFileImpl.h - Object Info -*- C++ -*-==//
+//==- llvm/CodeGen/TargetLoweringObjectFileImpl.h - Object Info --*- C++ -*-==//
//
// The LLVM Compiler Infrastructure
//
@@ -15,24 +15,22 @@
#ifndef LLVM_CODEGEN_TARGETLOWERINGOBJECTFILEIMPL_H
#define LLVM_CODEGEN_TARGETLOWERINGOBJECTFILEIMPL_H
+#include "llvm/IR/Module.h"
#include "llvm/MC/MCExpr.h"
-#include "llvm/MC/SectionKind.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
namespace llvm {
- class MachineModuleInfo;
- class Mangler;
- class MCAsmInfo;
- class MCSection;
- class MCSectionMachO;
- class MCSymbol;
- class MCContext;
- class GlobalValue;
- class TargetMachine;
+class GlobalValue;
+class MachineModuleInfo;
+class Mangler;
+class MCContext;
+class MCSection;
+class MCSymbol;
+class TargetMachine;
class TargetLoweringObjectFileELF : public TargetLoweringObjectFile {
- bool UseInitArray;
+ bool UseInitArray = false;
mutable unsigned NextUniqueID = 1; // ID 0 is reserved for execute-only sections
protected:
@@ -40,9 +38,12 @@ protected:
MCSymbolRefExpr::VK_None;
public:
- TargetLoweringObjectFileELF() : UseInitArray(false) {}
+ TargetLoweringObjectFileELF() = default;
+ ~TargetLoweringObjectFileELF() override = default;
- ~TargetLoweringObjectFileELF() override {}
+ /// Emit Obj-C garbage collection and linker options.
+ void emitModuleMetadata(MCStreamer &Streamer, Module &M,
+ const TargetMachine &TM) const override;
void emitPersonalityValue(MCStreamer &Streamer, const DataLayout &TM,
const MCSymbol *Sym) const override;
@@ -89,19 +90,16 @@ public:
const TargetMachine &TM) const override;
};
-
-
class TargetLoweringObjectFileMachO : public TargetLoweringObjectFile {
public:
- ~TargetLoweringObjectFileMachO() override {}
TargetLoweringObjectFileMachO();
+ ~TargetLoweringObjectFileMachO() override = default;
void Initialize(MCContext &Ctx, const TargetMachine &TM) override;
/// Emit the module flags that specify the garbage collection information.
- void emitModuleFlags(MCStreamer &Streamer,
- ArrayRef<Module::ModuleFlagEntry> ModuleFlags,
- const TargetMachine &TM) const override;
+ void emitModuleMetadata(MCStreamer &Streamer, Module &M,
+ const TargetMachine &TM) const override;
MCSection *SelectSectionForGlobal(const GlobalObject *GO, SectionKind Kind,
const TargetMachine &TM) const override;
@@ -135,13 +133,11 @@ public:
const TargetMachine &TM) const override;
};
-
-
class TargetLoweringObjectFileCOFF : public TargetLoweringObjectFile {
mutable unsigned NextUniqueID = 0;
public:
- ~TargetLoweringObjectFileCOFF() override {}
+ ~TargetLoweringObjectFileCOFF() override = default;
void Initialize(MCContext &Ctx, const TargetMachine &TM) override;
MCSection *getExplicitSectionGlobal(const GlobalObject *GO, SectionKind Kind,
@@ -156,11 +152,9 @@ public:
MCSection *getSectionForJumpTable(const Function &F,
const TargetMachine &TM) const override;
- /// Emit Obj-C garbage collection and linker options. Only linker option
- /// emission is implemented for COFF.
- void emitModuleFlags(MCStreamer &Streamer,
- ArrayRef<Module::ModuleFlagEntry> ModuleFlags,
- const TargetMachine &TM) const override;
+ /// Emit Obj-C garbage collection and linker options.
+ void emitModuleMetadata(MCStreamer &Streamer, Module &M,
+ const TargetMachine &TM) const override;
MCSection *getStaticCtorSection(unsigned Priority,
const MCSymbol *KeySym) const override;
@@ -171,6 +165,29 @@ public:
const GlobalValue *GV) const override;
};
+class TargetLoweringObjectFileWasm : public TargetLoweringObjectFile {
+ mutable unsigned NextUniqueID = 0;
+
+public:
+ TargetLoweringObjectFileWasm() = default;
+ ~TargetLoweringObjectFileWasm() override = default;
+
+ MCSection *getExplicitSectionGlobal(const GlobalObject *GO, SectionKind Kind,
+ const TargetMachine &TM) const override;
+
+ MCSection *SelectSectionForGlobal(const GlobalObject *GO, SectionKind Kind,
+ const TargetMachine &TM) const override;
+
+ bool shouldPutJumpTableInFunctionSection(bool UsesLabelDifference,
+ const Function &F) const override;
+
+ void InitializeWasm();
+
+ const MCExpr *lowerRelativeReference(const GlobalValue *LHS,
+ const GlobalValue *RHS,
+ const TargetMachine &TM) const override;
+};
+
} // end namespace llvm
-#endif
+#endif // LLVM_CODEGEN_TARGETLOWERINGOBJECTFILEIMPL_H
diff --git a/contrib/llvm/include/llvm/CodeGen/TargetPassConfig.h b/contrib/llvm/include/llvm/CodeGen/TargetPassConfig.h
index 2287f9a..aaf0ab5 100644
--- a/contrib/llvm/include/llvm/CodeGen/TargetPassConfig.h
+++ b/contrib/llvm/include/llvm/CodeGen/TargetPassConfig.h
@@ -1,4 +1,4 @@
-//===-- TargetPassConfig.h - Code Generation pass options -------*- C++ -*-===//
+//===- TargetPassConfig.h - Code Generation pass options --------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -16,19 +16,23 @@
#include "llvm/Pass.h"
#include "llvm/Support/CodeGen.h"
+#include <cassert>
#include <string>
namespace llvm {
+class LLVMTargetMachine;
+struct MachineSchedContext;
class PassConfigImpl;
class ScheduleDAGInstrs;
-class TargetMachine;
-struct MachineSchedContext;
// The old pass manager infrastructure is hidden in a legacy namespace now.
namespace legacy {
+
class PassManagerBase;
-}
+
+} // end namespace legacy
+
using legacy::PassManagerBase;
/// Discriminated union of Pass ID types.
@@ -50,10 +54,11 @@ class IdentifyingPassPtr {
AnalysisID ID;
Pass *P;
};
- bool IsInstance;
+ bool IsInstance = false;
+
public:
- IdentifyingPassPtr() : P(nullptr), IsInstance(false) {}
- IdentifyingPassPtr(AnalysisID IDPtr) : ID(IDPtr), IsInstance(false) {}
+ IdentifyingPassPtr() : P(nullptr) {}
+ IdentifyingPassPtr(AnalysisID IDPtr) : ID(IDPtr) {}
IdentifyingPassPtr(Pass *InstancePtr) : P(InstancePtr), IsInstance(true) {}
bool isValid() const { return P; }
@@ -63,6 +68,7 @@ public:
assert(!IsInstance && "Not a Pass ID");
return ID;
}
+
Pass *getInstance() const {
assert(IsInstance && "Not a Pass Instance");
return P;
@@ -93,30 +99,37 @@ public:
static char PostRAMachineLICMID;
private:
- PassManagerBase *PM;
+ PassManagerBase *PM = nullptr;
AnalysisID StartBefore = nullptr;
AnalysisID StartAfter = nullptr;
AnalysisID StopBefore = nullptr;
AnalysisID StopAfter = nullptr;
- bool Started;
- bool Stopped;
- bool AddingMachinePasses;
+ bool Started = true;
+ bool Stopped = false;
+ bool AddingMachinePasses = false;
protected:
- TargetMachine *TM;
- PassConfigImpl *Impl; // Internal data structures
- bool Initialized; // Flagged after all passes are configured.
+ LLVMTargetMachine *TM;
+ PassConfigImpl *Impl = nullptr; // Internal data structures
+ bool Initialized = false; // Flagged after all passes are configured.
// Target Pass Options
// Targets provide a default setting, user flags override.
- //
- bool DisableVerify;
+ bool DisableVerify = false;
/// Default setting for -enable-tail-merge on this target.
- bool EnableTailMerge;
+ bool EnableTailMerge = true;
+
+ /// Require processing of functions such that callees are generated before
+ /// callers.
+ bool RequireCodeGenSCCOrder = false;
+
+ /// Add the actual instruction selection passes. This does not include
+ /// preparation passes on IR.
+ bool addCoreISelPasses();
public:
- TargetPassConfig(TargetMachine *tm, PassManagerBase &pm);
+ TargetPassConfig(LLVMTargetMachine &TM, PassManagerBase &pm);
// Dummy constructor.
TargetPassConfig();
@@ -162,6 +175,11 @@ public:
bool getEnableTailMerge() const { return EnableTailMerge; }
void setEnableTailMerge(bool Enable) { setOpt(EnableTailMerge, Enable); }
+ bool requiresCodeGenSCCOrder() const { return RequireCodeGenSCCOrder; }
+ void setRequiresCodeGenSCCOrder(bool Enable = true) {
+ setOpt(RequireCodeGenSCCOrder, Enable);
+ }
+
/// Allow the target to override a specific pass without overriding the pass
/// pipeline. When passes are added to the standard pipeline at the
/// point where StandardID is expected, add TargetID in its place.
@@ -197,6 +215,13 @@ public:
/// has not be overriden on the command line with '-regalloc=...'
bool usingDefaultRegAlloc() const;
+ /// High level function that adds all passes necessary to go from llvm IR
+ /// representation to the MI representation.
+ /// Adds IR based lowering and target specific optimization passes and finally
+ /// the core instruction selection passes.
+ /// \returns true if an error occured, false otherwise.
+ bool addISelPasses();
+
/// Add common target configurable passes that perform LLVM IR to IR
/// transforms following machine independent optimization.
virtual void addIRPasses();
@@ -276,7 +301,6 @@ public:
/// printAndVerify - Add a pass to dump then verify the machine function, if
/// those steps are enabled.
- ///
void printAndVerify(const std::string &Banner);
/// Add a pass to print the machine function if printing is enabled.
@@ -286,6 +310,10 @@ public:
/// verification is enabled.
void addVerifyPass(const std::string &Banner);
+ /// Check whether or not GlobalISel should be enabled by default.
+ /// Fallback/abort behavior is controlled via other methods.
+ virtual bool isGlobalISelEnabled() const;
+
/// Check whether or not GlobalISel should abort on error.
/// When this is disable, GlobalISel will fall back on SDISel instead of
/// erroring out.
@@ -406,4 +434,4 @@ protected:
} // end namespace llvm
-#endif
+#endif // LLVM_CODEGEN_TARGETPASSCONFIG_H
diff --git a/contrib/llvm/include/llvm/CodeGen/TargetSchedule.h b/contrib/llvm/include/llvm/CodeGen/TargetSchedule.h
index 81054ab..f236679 100644
--- a/contrib/llvm/include/llvm/CodeGen/TargetSchedule.h
+++ b/contrib/llvm/include/llvm/CodeGen/TargetSchedule.h
@@ -1,4 +1,4 @@
-//===-- llvm/CodeGen/TargetSchedule.h - Sched Machine Model -----*- C++ -*-===//
+//===- llvm/CodeGen/TargetSchedule.h - Sched Machine Model ------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -16,6 +16,7 @@
#ifndef LLVM_CODEGEN_TARGETSCHEDULE_H
#define LLVM_CODEGEN_TARGETSCHEDULE_H
+#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/MC/MCInstrItineraries.h"
#include "llvm/MC/MCSchedule.h"
@@ -23,10 +24,8 @@
namespace llvm {
-class TargetRegisterInfo;
-class TargetSubtargetInfo;
-class TargetInstrInfo;
class MachineInstr;
+class TargetInstrInfo;
/// Provide an instruction scheduling machine model to CodeGen passes.
class TargetSchedModel {
@@ -34,8 +33,8 @@ class TargetSchedModel {
// processor.
MCSchedModel SchedModel;
InstrItineraryData InstrItins;
- const TargetSubtargetInfo *STI;
- const TargetInstrInfo *TII;
+ const TargetSubtargetInfo *STI = nullptr;
+ const TargetInstrInfo *TII = nullptr;
SmallVector<unsigned, 16> ResourceFactors;
unsigned MicroOpFactor; // Multiply to normalize microops to resource units.
@@ -44,7 +43,7 @@ class TargetSchedModel {
unsigned computeInstrLatency(const MCSchedClassDesc &SCDesc) const;
public:
- TargetSchedModel(): SchedModel(MCSchedModel::GetDefaultSchedModel()), STI(nullptr), TII(nullptr) {}
+ TargetSchedModel() : SchedModel(MCSchedModel::GetDefaultSchedModel()) {}
/// \brief Initialize the machine model for instruction scheduling.
///
@@ -57,6 +56,9 @@ public:
/// Return the MCSchedClassDesc for this instruction.
const MCSchedClassDesc *resolveSchedClass(const MachineInstr *MI) const;
+ /// \brief TargetSubtargetInfo getter.
+ const TargetSubtargetInfo *getSubtargetInfo() const { return STI; }
+
/// \brief TargetInstrInfo getter.
const TargetInstrInfo *getInstrInfo() const { return TII; }
@@ -93,6 +95,13 @@ public:
/// \brief Maximum number of micro-ops that may be scheduled per cycle.
unsigned getIssueWidth() const { return SchedModel.IssueWidth; }
+ /// \brief Return true if new group must begin.
+ bool mustBeginGroup(const MachineInstr *MI,
+ const MCSchedClassDesc *SC = nullptr) const;
+ /// \brief Return true if current group must end.
+ bool mustEndGroup(const MachineInstr *MI,
+ const MCSchedClassDesc *SC = nullptr) const;
+
/// \brief Return the number of issue slots required for this MI.
unsigned getNumMicroOps(const MachineInstr *MI,
const MCSchedClassDesc *SC = nullptr) const;
@@ -115,7 +124,7 @@ public:
}
#endif
- typedef const MCWriteProcResEntry *ProcResIter;
+ using ProcResIter = const MCWriteProcResEntry *;
// \brief Get an iterator into the processor resources consumed by this
// scheduling class.
@@ -178,13 +187,18 @@ public:
bool UseDefaultDefLatency = true) const;
unsigned computeInstrLatency(unsigned Opcode) const;
+
/// \brief Output dependency latency of a pair of defs of the same register.
///
/// This is typically one cycle.
unsigned computeOutputLatency(const MachineInstr *DefMI, unsigned DefIdx,
const MachineInstr *DepMI) const;
+
+ /// \brief Compute the reciprocal throughput of the given instruction.
+ Optional<double> computeInstrRThroughput(const MachineInstr *MI) const;
+ Optional<double> computeInstrRThroughput(unsigned Opcode) const;
};
-} // namespace llvm
+} // end namespace llvm
-#endif
+#endif // LLVM_CODEGEN_TARGETSCHEDULE_H
diff --git a/contrib/llvm/include/llvm/CodeGen/ValueTypes.h b/contrib/llvm/include/llvm/CodeGen/ValueTypes.h
index 2699fa2..40d501e 100644
--- a/contrib/llvm/include/llvm/CodeGen/ValueTypes.h
+++ b/contrib/llvm/include/llvm/CodeGen/ValueTypes.h
@@ -17,7 +17,10 @@
#define LLVM_CODEGEN_VALUETYPES_H
#include "llvm/CodeGen/MachineValueType.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/MathExtras.h"
#include <cassert>
+#include <cstdint>
#include <string>
namespace llvm {
@@ -25,18 +28,18 @@ namespace llvm {
class LLVMContext;
class Type;
- /// EVT - Extended Value Type. Capable of holding value types which are not
- /// native for any processor (such as the i12345 type), as well as the types
- /// a MVT can represent.
+ /// Extended Value Type. Capable of holding value types which are not native
+ /// for any processor (such as the i12345 type), as well as the types an MVT
+ /// can represent.
struct EVT {
private:
- MVT V;
- Type *LLVMTy;
+ MVT V = MVT::INVALID_SIMPLE_VALUE_TYPE;
+ Type *LLVMTy = nullptr;
public:
- constexpr EVT() : V(MVT::INVALID_SIMPLE_VALUE_TYPE), LLVMTy(nullptr) {}
- constexpr EVT(MVT::SimpleValueType SVT) : V(SVT), LLVMTy(nullptr) {}
- constexpr EVT(MVT S) : V(S), LLVMTy(nullptr) {}
+ constexpr EVT() = default;
+ constexpr EVT(MVT::SimpleValueType SVT) : V(SVT) {}
+ constexpr EVT(MVT S) : V(S) {}
bool operator==(EVT VT) const {
return !(*this != VT);
@@ -44,47 +47,64 @@ namespace llvm {
bool operator!=(EVT VT) const {
if (V.SimpleTy != VT.V.SimpleTy)
return true;
- if (V.SimpleTy < 0)
+ if (V.SimpleTy == MVT::INVALID_SIMPLE_VALUE_TYPE)
return LLVMTy != VT.LLVMTy;
return false;
}
- /// getFloatingPointVT - Returns the EVT that represents a floating point
- /// type with the given number of bits. There are two floating point types
- /// with 128 bits - this returns f128 rather than ppcf128.
+ /// Returns the EVT that represents a floating-point type with the given
+ /// number of bits. There are two floating-point types with 128 bits - this
+ /// returns f128 rather than ppcf128.
static EVT getFloatingPointVT(unsigned BitWidth) {
return MVT::getFloatingPointVT(BitWidth);
}
- /// getIntegerVT - Returns the EVT that represents an integer with the given
- /// number of bits.
+ /// Returns the EVT that represents an integer with the given number of
+ /// bits.
static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth) {
MVT M = MVT::getIntegerVT(BitWidth);
- if (M.SimpleTy >= 0)
+ if (M.SimpleTy != MVT::INVALID_SIMPLE_VALUE_TYPE)
return M;
return getExtendedIntegerVT(Context, BitWidth);
}
- /// getVectorVT - Returns the EVT that represents a vector NumElements in
- /// length, where each element is of type VT.
- static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements) {
- MVT M = MVT::getVectorVT(VT.V, NumElements);
- if (M.SimpleTy >= 0)
+ /// Returns the EVT that represents a vector NumElements in length, where
+ /// each element is of type VT.
+ static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements,
+ bool IsScalable = false) {
+ 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);
}
- /// changeVectorElementTypeToInteger - 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.
+ /// Returns the EVT that represents a vector EC.Min elements in length,
+ /// where each element is of type VT.
+ static EVT getVectorVT(LLVMContext &Context, EVT VT, MVT::ElementCount EC) {
+ 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 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())
+ if (!isSimple()) {
+ assert (!isScalableVector() &&
+ "We don't support extended scalable types yet");
return changeExtendedVectorElementTypeToInteger();
+ }
MVT EltTy = getSimpleVT().getVectorElementType();
unsigned BitWidth = EltTy.getSizeInBits();
MVT IntTy = MVT::getIntegerVT(BitWidth);
- MVT VecTy = MVT::getVectorVT(IntTy, getVectorNumElements());
- assert(VecTy.SimpleTy >= 0 &&
+ MVT VecTy = MVT::getVectorVT(IntTy, getVectorNumElements(),
+ isScalableVector());
+ assert(VecTy.SimpleTy != MVT::INVALID_SIMPLE_VALUE_TYPE &&
"Simple vector VT not representable by simple integer vector VT!");
return VecTy;
}
@@ -102,140 +122,146 @@ namespace llvm {
return changeExtendedTypeToInteger();
}
- /// isSimple - Test if the given EVT is simple (as opposed to being
- /// extended).
+ /// Test if the given EVT is simple (as opposed to being extended).
bool isSimple() const {
- return V.SimpleTy >= 0;
+ return V.SimpleTy != MVT::INVALID_SIMPLE_VALUE_TYPE;
}
- /// isExtended - Test if the given EVT is extended (as opposed to
- /// being simple).
+ /// Test if the given EVT is extended (as opposed to being simple).
bool isExtended() const {
return !isSimple();
}
- /// isFloatingPoint - Return true if this is a FP, or a vector FP type.
+ /// Return true if this is a FP or a vector FP type.
bool isFloatingPoint() const {
return isSimple() ? V.isFloatingPoint() : isExtendedFloatingPoint();
}
- /// isInteger - Return true if this is an integer, or a vector integer type.
+ /// Return true if this is an integer or a vector integer type.
bool isInteger() const {
return isSimple() ? V.isInteger() : isExtendedInteger();
}
- /// isScalarInteger - Return true if this is an integer, but not a vector.
+ /// Return true if this is an integer, but not a vector.
bool isScalarInteger() const {
return isSimple() ? V.isScalarInteger() : isExtendedScalarInteger();
}
- /// isVector - Return true if this is a vector value type.
+ /// Return true if this is a vector value type.
bool isVector() const {
return isSimple() ? V.isVector() : isExtendedVector();
}
- /// is16BitVector - Return true if this is a 16-bit vector type.
+ /// 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 true if this is a 16-bit vector type.
bool is16BitVector() const {
return isSimple() ? V.is16BitVector() : isExtended16BitVector();
}
- /// is32BitVector - Return true if this is a 32-bit vector type.
+ /// Return true if this is a 32-bit vector type.
bool is32BitVector() const {
return isSimple() ? V.is32BitVector() : isExtended32BitVector();
}
- /// is64BitVector - Return true if this is a 64-bit vector type.
+ /// Return true if this is a 64-bit vector type.
bool is64BitVector() const {
return isSimple() ? V.is64BitVector() : isExtended64BitVector();
}
- /// is128BitVector - Return true if this is a 128-bit vector type.
+ /// Return true if this is a 128-bit vector type.
bool is128BitVector() const {
return isSimple() ? V.is128BitVector() : isExtended128BitVector();
}
- /// is256BitVector - Return true if this is a 256-bit vector type.
+ /// Return true if this is a 256-bit vector type.
bool is256BitVector() const {
return isSimple() ? V.is256BitVector() : isExtended256BitVector();
}
- /// is512BitVector - Return true if this is a 512-bit vector type.
+ /// Return true if this is a 512-bit vector type.
bool is512BitVector() const {
return isSimple() ? V.is512BitVector() : isExtended512BitVector();
}
- /// is1024BitVector - Return true if this is a 1024-bit vector type.
+ /// Return true if this is a 1024-bit vector type.
bool is1024BitVector() const {
return isSimple() ? V.is1024BitVector() : isExtended1024BitVector();
}
- /// is2048BitVector - Return true if this is a 2048-bit vector type.
+ /// Return true if this is a 2048-bit vector type.
bool is2048BitVector() const {
return isSimple() ? V.is2048BitVector() : isExtended2048BitVector();
}
- /// isOverloaded - Return true if this is an overloaded type for TableGen.
+ /// Return true if this is an overloaded type for TableGen.
bool isOverloaded() const {
return (V==MVT::iAny || V==MVT::fAny || V==MVT::vAny || V==MVT::iPTRAny);
}
- /// isByteSized - Return true if the bit size is a multiple of 8.
+ /// Return true if the bit size is a multiple of 8.
bool isByteSized() const {
return (getSizeInBits() & 7) == 0;
}
- /// isRound - Return true if the size is a power-of-two number of bytes.
+ /// Return true if the size is a power-of-two number of bytes.
bool isRound() const {
unsigned BitSize = getSizeInBits();
return BitSize >= 8 && !(BitSize & (BitSize - 1));
}
- /// bitsEq - Return true if this has the same number of bits as VT.
+ /// Return true if this has the same number of bits as VT.
bool bitsEq(EVT VT) const {
if (EVT::operator==(VT)) return true;
return getSizeInBits() == VT.getSizeInBits();
}
- /// bitsGT - Return true if this has more bits than VT.
+ /// Return true if this has more bits than VT.
bool bitsGT(EVT VT) const {
if (EVT::operator==(VT)) return false;
return getSizeInBits() > VT.getSizeInBits();
}
- /// bitsGE - Return true if this has no less bits than VT.
+ /// Return true if this has no less bits than VT.
bool bitsGE(EVT VT) const {
if (EVT::operator==(VT)) return true;
return getSizeInBits() >= VT.getSizeInBits();
}
- /// bitsLT - Return true if this has less bits than VT.
+ /// Return true if this has less bits than VT.
bool bitsLT(EVT VT) const {
if (EVT::operator==(VT)) return false;
return getSizeInBits() < VT.getSizeInBits();
}
- /// bitsLE - Return true if this has no more bits than VT.
+ /// Return true if this has no more bits than VT.
bool bitsLE(EVT VT) const {
if (EVT::operator==(VT)) return true;
return getSizeInBits() <= VT.getSizeInBits();
}
-
- /// getSimpleVT - Return the SimpleValueType held in the specified
- /// simple EVT.
+ /// Return the SimpleValueType held in the specified simple EVT.
MVT getSimpleVT() const {
assert(isSimple() && "Expected a SimpleValueType!");
return V;
}
- /// getScalarType - If this is a vector type, return the element type,
- /// otherwise return this.
+ /// If this is a vector type, return the element type, otherwise return
+ /// this.
EVT getScalarType() const {
return isVector() ? getVectorElementType() : *this;
}
- /// getVectorElementType - Given a vector type, return the type of
- /// each element.
+ /// Given a vector type, return the type of each element.
EVT getVectorElementType() const {
assert(isVector() && "Invalid vector type!");
if (isSimple())
@@ -243,8 +269,7 @@ namespace llvm {
return getExtendedVectorElementType();
}
- /// getVectorNumElements - Given a vector type, return the number of
- /// elements it contains.
+ /// Given a vector type, return the number of elements it contains.
unsigned getVectorNumElements() const {
assert(isVector() && "Invalid vector type!");
if (isSimple())
@@ -252,7 +277,18 @@ namespace llvm {
return getExtendedVectorNumElements();
}
- /// getSizeInBits - Return the size of the specified value type in bits.
+ // Given a (possibly scalable) vector type, return the ElementCount
+ MVT::ElementCount getVectorElementCount() const {
+ assert((isVector()) && "Invalid vector type!");
+ if (isSimple())
+ return V.getVectorElementCount();
+
+ assert(!isScalableVector() &&
+ "We don't support extended scalable types yet");
+ return {getExtendedVectorNumElements(), false};
+ }
+
+ /// Return the size of the specified value type in bits.
unsigned getSizeInBits() const {
if (isSimple())
return V.getSizeInBits();
@@ -263,21 +299,21 @@ namespace llvm {
return getScalarType().getSizeInBits();
}
- /// getStoreSize - Return the number of bytes overwritten by a store
- /// of the specified value type.
+ /// Return the number of bytes overwritten by a store of the specified value
+ /// type.
unsigned getStoreSize() const {
return (getSizeInBits() + 7) / 8;
}
- /// getStoreSizeInBits - Return the number of bits overwritten by a store
- /// of the specified value type.
+ /// Return the number of bits overwritten by a store of the specified value
+ /// type.
unsigned getStoreSizeInBits() const {
return getStoreSize() * 8;
}
- /// getRoundIntegerType - Rounds the bit-width of the given integer EVT up
- /// to the nearest power of two (and at least to eight), and returns the
- /// integer EVT with that number of bits.
+ /// Rounds the bit-width of the given integer EVT up to the nearest power of
+ /// two (and at least to eight), and returns the integer EVT with that
+ /// number of bits.
EVT getRoundIntegerType(LLVMContext &Context) const {
assert(isInteger() && !isVector() && "Invalid integer type!");
unsigned BitWidth = getSizeInBits();
@@ -286,10 +322,9 @@ namespace llvm {
return getIntegerVT(Context, 1 << Log2_32_Ceil(BitWidth));
}
- /// getHalfSizedIntegerVT - Finds the smallest simple value type that is
- /// greater than or equal to half the width of this EVT. If no simple
- /// value type can be found, an extended integer value type of half the
- /// size (rounded up) is returned.
+ /// Finds the smallest simple value type that is greater than or equal to
+ /// half the width of this EVT. If no simple value type can be found, an
+ /// extended integer value type of half the size (rounded up) is returned.
EVT getHalfSizedIntegerVT(LLVMContext &Context) const {
assert(isInteger() && !isVector() && "Invalid integer type!");
unsigned EVTSize = getSizeInBits();
@@ -302,43 +337,53 @@ namespace llvm {
return getIntegerVT(Context, (EVTSize + 1) / 2);
}
- /// \brief Return a VT for an integer vector type with the size of the
+ /// Return a VT for an integer vector type with the size of the
/// elements doubled. The typed returned may be an extended type.
EVT widenIntegerVectorElementType(LLVMContext &Context) const {
EVT EltVT = getVectorElementType();
EltVT = EVT::getIntegerVT(Context, 2 * EltVT.getSizeInBits());
- return EVT::getVectorVT(Context, EltVT, getVectorNumElements());
+ return EVT::getVectorVT(Context, EltVT, getVectorElementCount());
+ }
+
+ // Return a VT for a vector type with the same element type but
+ // half the number of elements. The type returned may be an
+ // extended type.
+ EVT getHalfNumVectorElementsVT(LLVMContext &Context) const {
+ EVT EltVT = getVectorElementType();
+ auto EltCnt = getVectorElementCount();
+ assert(!(EltCnt.Min & 1) && "Splitting vector, but not in half!");
+ return EVT::getVectorVT(Context, EltVT, EltCnt / 2);
}
- /// isPow2VectorType - Returns true if the given vector is a power of 2.
+ /// Returns true if the given vector is a power of 2.
bool isPow2VectorType() const {
unsigned NElts = getVectorNumElements();
return !(NElts & (NElts - 1));
}
- /// getPow2VectorType - Widens the length of the given vector EVT up to
- /// the nearest power of 2 and returns that type.
+ /// Widens the length of the given vector EVT up to the nearest power of 2
+ /// 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);
+ return EVT::getVectorVT(Context, getVectorElementType(), Pow2NElts,
+ isScalableVector());
}
else {
return *this;
}
}
- /// getEVTString - This function returns value type as a string,
- /// e.g. "i32".
+ /// This function returns value type as a string, e.g. "i32".
std::string getEVTString() const;
- /// getTypeForEVT - This method returns an LLVM type corresponding to the
- /// specified EVT. For integer types, this returns an unsigned type. Note
- /// that this will abort for types that cannot be represented.
+ /// This method returns an LLVM type corresponding to the specified EVT.
+ /// For integer types, this returns an unsigned type. Note that this will
+ /// abort for types that cannot be represented.
Type *getTypeForEVT(LLVMContext &Context) const;
- /// getEVT - Return the value type corresponding to the specified type.
+ /// Return the value type corresponding to the specified type.
/// This returns all pointers as iPTR. If HandleUnknown is true, unknown
/// types are returned as Other, otherwise they are invalid.
static EVT getEVT(Type *Ty, bool HandleUnknown = false);
@@ -350,8 +395,8 @@ namespace llvm {
return (intptr_t)(LLVMTy);
}
- /// compareRawBits - A meaningless but well-behaved order, useful for
- /// constructing containers.
+ /// A meaningless but well-behaved order, useful for constructing
+ /// containers.
struct compareRawBits {
bool operator()(EVT L, EVT R) const {
if (L.V.SimpleTy == R.V.SimpleTy)
@@ -387,6 +432,6 @@ namespace llvm {
unsigned getExtendedSizeInBits() const LLVM_READONLY;
};
-} // End llvm namespace
+} // end namespace llvm
-#endif
+#endif // LLVM_CODEGEN_VALUETYPES_H
diff --git a/contrib/llvm/include/llvm/CodeGen/ValueTypes.td b/contrib/llvm/include/llvm/CodeGen/ValueTypes.td
index f7b1661..b1e62da 100644
--- a/contrib/llvm/include/llvm/CodeGen/ValueTypes.td
+++ b/contrib/llvm/include/llvm/CodeGen/ValueTypes.td
@@ -19,101 +19,149 @@ class ValueType<int size, int value> {
int Value = value;
}
-def OtherVT: ValueType<0 , 0>; // "Other" value
-def i1 : ValueType<1 , 1>; // One bit boolean value
-def i8 : ValueType<8 , 2>; // 8-bit integer value
-def i16 : ValueType<16 , 3>; // 16-bit integer value
-def i32 : ValueType<32 , 4>; // 32-bit integer value
-def i64 : ValueType<64 , 5>; // 64-bit integer value
-def i128 : ValueType<128, 6>; // 128-bit integer value
-def f16 : ValueType<16 , 7>; // 16-bit floating point value
-def f32 : ValueType<32 , 8>; // 32-bit floating point value
-def f64 : ValueType<64 , 9>; // 64-bit floating point value
-def f80 : ValueType<80 , 10>; // 80-bit floating point value
-def f128 : ValueType<128, 11>; // 128-bit floating point value
-def ppcf128: ValueType<128, 12>; // PPC 128-bit floating point value
-
-def v2i1 : ValueType<2 , 13>; // 2 x i1 vector value
-def v4i1 : ValueType<4 , 14>; // 4 x i1 vector value
-def v8i1 : ValueType<8 , 15>; // 8 x i1 vector value
-def v16i1 : ValueType<16, 16>; // 16 x i1 vector value
-def v32i1 : ValueType<32 , 17>; // 32 x i1 vector value
-def v64i1 : ValueType<64 , 18>; // 64 x i1 vector value
-def v512i1 : ValueType<512, 19>; // 512 x i1 vector value
-def v1024i1: ValueType<1024,20>; //1024 x i1 vector value
-
-def v1i8 : ValueType<16, 21>; // 1 x i8 vector value
-def v2i8 : ValueType<16 , 22>; // 2 x i8 vector value
-def v4i8 : ValueType<32 , 23>; // 4 x i8 vector value
-def v8i8 : ValueType<64 , 24>; // 8 x i8 vector value
-def v16i8 : ValueType<128, 25>; // 16 x i8 vector value
-def v32i8 : ValueType<256, 26>; // 32 x i8 vector value
-def v64i8 : ValueType<512, 27>; // 64 x i8 vector value
-def v128i8 : ValueType<1024,28>; //128 x i8 vector value
-def v256i8 : ValueType<2048,29>; //256 x i8 vector value
-
-def v1i16 : ValueType<16 , 30>; // 1 x i16 vector value
-def v2i16 : ValueType<32 , 31>; // 2 x i16 vector value
-def v4i16 : ValueType<64 , 32>; // 4 x i16 vector value
-def v8i16 : ValueType<128, 33>; // 8 x i16 vector value
-def v16i16 : ValueType<256, 34>; // 16 x i16 vector value
-def v32i16 : ValueType<512, 35>; // 32 x i16 vector value
-def v64i16 : ValueType<1024,36>; // 64 x i16 vector value
-def v128i16: ValueType<2048,37>; //128 x i16 vector value
-
-def v1i32 : ValueType<32 , 38>; // 1 x i32 vector value
-def v2i32 : ValueType<64 , 39>; // 2 x i32 vector value
-def v4i32 : ValueType<128, 40>; // 4 x i32 vector value
-def v8i32 : ValueType<256, 41>; // 8 x i32 vector value
-def v16i32 : ValueType<512, 42>; // 16 x i32 vector value
-def v32i32 : ValueType<1024,43>; // 32 x i32 vector value
-def v64i32 : ValueType<2048,44>; // 32 x i32 vector value
-
-def v1i64 : ValueType<64 , 45>; // 1 x i64 vector value
-def v2i64 : ValueType<128, 46>; // 2 x i64 vector value
-def v4i64 : ValueType<256, 47>; // 4 x i64 vector value
-def v8i64 : ValueType<512, 48>; // 8 x i64 vector value
-def v16i64 : ValueType<1024,49>; // 16 x i64 vector value
-def v32i64 : ValueType<2048,50>; // 32 x i64 vector value
-
-def v1i128 : ValueType<128, 51>; // 1 x i128 vector value
-
-def v2f16 : ValueType<32 , 52>; // 2 x f16 vector value
-def v4f16 : ValueType<64 , 53>; // 4 x f16 vector value
-def v8f16 : ValueType<128, 54>; // 8 x f16 vector value
-def v1f32 : ValueType<32 , 55>; // 1 x f32 vector value
-def v2f32 : ValueType<64 , 56>; // 2 x f32 vector value
-def v4f32 : ValueType<128, 57>; // 4 x f32 vector value
-def v8f32 : ValueType<256, 58>; // 8 x f32 vector value
-def v16f32 : ValueType<512, 59>; // 16 x f32 vector value
-def v1f64 : ValueType<64, 60>; // 1 x f64 vector value
-def v2f64 : ValueType<128, 61>; // 2 x f64 vector value
-def v4f64 : ValueType<256, 62>; // 4 x f64 vector value
-def v8f64 : ValueType<512, 63>; // 8 x f64 vector value
-
-
-def x86mmx : ValueType<64 , 64>; // X86 MMX value
-def FlagVT : ValueType<0 , 65>; // Pre-RA sched glue
-def isVoid : ValueType<0 , 66>; // Produces no value
-def untyped: ValueType<8 , 67>; // Produces an untyped value
-def token : ValueType<0 , 120>; // TokenTy
-def MetadataVT: ValueType<0, 121>; // Metadata
+def OtherVT: ValueType<0 , 1>; // "Other" value
+def i1 : ValueType<1 , 2>; // One bit boolean value
+def i8 : ValueType<8 , 3>; // 8-bit integer value
+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 v512i1 : ValueType<512, 21>; // 512 x i1 vector value
+def v1024i1: ValueType<1024,22>; //1024 x i1 vector value
+
+def v1i8 : ValueType<8, 23>; // 1 x i8 vector value
+def v2i8 : ValueType<16 , 24>; // 2 x i8 vector value
+def v4i8 : ValueType<32 , 25>; // 4 x i8 vector value
+def v8i8 : ValueType<64 , 26>; // 8 x i8 vector value
+def v16i8 : ValueType<128, 27>; // 16 x i8 vector value
+def v32i8 : ValueType<256, 28>; // 32 x i8 vector value
+def v64i8 : ValueType<512, 29>; // 64 x i8 vector value
+def v128i8 : ValueType<1024,30>; //128 x i8 vector value
+def v256i8 : ValueType<2048,31>; //256 x i8 vector value
+
+def v1i16 : ValueType<16 , 32>; // 1 x i16 vector value
+def v2i16 : ValueType<32 , 33>; // 2 x i16 vector value
+def v4i16 : ValueType<64 , 34>; // 4 x i16 vector value
+def v8i16 : ValueType<128, 35>; // 8 x i16 vector value
+def v16i16 : ValueType<256, 36>; // 16 x i16 vector value
+def v32i16 : ValueType<512, 37>; // 32 x i16 vector value
+def v64i16 : ValueType<1024,38>; // 64 x i16 vector value
+def v128i16: ValueType<2048,39>; //128 x i16 vector value
+
+def v1i32 : ValueType<32 , 40>; // 1 x i32 vector value
+def v2i32 : ValueType<64 , 41>; // 2 x i32 vector value
+def v4i32 : ValueType<128, 42>; // 4 x i32 vector value
+def v8i32 : ValueType<256, 43>; // 8 x i32 vector value
+def v16i32 : ValueType<512, 44>; // 16 x i32 vector value
+def v32i32 : ValueType<1024,45>; // 32 x i32 vector value
+def v64i32 : ValueType<2048,46>; // 32 x i32 vector value
+
+def v1i64 : ValueType<64 , 47>; // 1 x i64 vector value
+def v2i64 : ValueType<128, 48>; // 2 x i64 vector value
+def v4i64 : ValueType<256, 49>; // 4 x i64 vector value
+def v8i64 : ValueType<512, 50>; // 8 x i64 vector value
+def v16i64 : ValueType<1024,51>; // 16 x i64 vector value
+def v32i64 : ValueType<2048,52>; // 32 x i64 vector value
+
+def v1i128 : ValueType<128, 53>; // 1 x i128 vector value
+
+def nxv1i1 : ValueType<1, 54>; // n x 1 x i1 vector value
+def nxv2i1 : ValueType<2, 55>; // n x 2 x i1 vector value
+def nxv4i1 : ValueType<4, 56>; // n x 4 x i1 vector value
+def nxv8i1 : ValueType<8, 57>; // n x 8 x i1 vector value
+def nxv16i1 : ValueType<16, 58>; // n x 16 x i1 vector value
+def nxv32i1 : ValueType<32, 59>; // n x 32 x i1 vector value
+
+def nxv1i8 : ValueType<8, 60>; // n x 1 x i8 vector value
+def nxv2i8 : ValueType<16, 61>; // n x 2 x i8 vector value
+def nxv4i8 : ValueType<32, 62>; // n x 4 x i8 vector value
+def nxv8i8 : ValueType<64, 63>; // n x 8 x i8 vector value
+def nxv16i8 : ValueType<128, 64>; // n x 16 x i8 vector value
+def nxv32i8 : ValueType<256, 65>; // n x 32 x i8 vector value
+
+def nxv1i16 : ValueType<16, 66>; // n x 1 x i16 vector value
+def nxv2i16 : ValueType<32, 67>; // n x 2 x i16 vector value
+def nxv4i16 : ValueType<64, 68>; // n x 4 x i16 vector value
+def nxv8i16 : ValueType<128, 69>; // n x 8 x i16 vector value
+def nxv16i16: ValueType<256, 70>; // n x 16 x i16 vector value
+def nxv32i16: ValueType<512, 71>; // n x 32 x i16 vector value
+
+def nxv1i32 : ValueType<32, 72>; // n x 1 x i32 vector value
+def nxv2i32 : ValueType<64, 73>; // n x 2 x i32 vector value
+def nxv4i32 : ValueType<128, 74>; // n x 4 x i32 vector value
+def nxv8i32 : ValueType<256, 75>; // n x 8 x i32 vector value
+def nxv16i32: ValueType<512, 76>; // n x 16 x i32 vector value
+def nxv32i32: ValueType<1024,77>; // n x 32 x i32 vector value
+
+def nxv1i64 : ValueType<64, 78>; // n x 1 x i64 vector value
+def nxv2i64 : ValueType<128, 79>; // n x 2 x i64 vector value
+def nxv4i64 : ValueType<256, 80>; // n x 4 x i64 vector value
+def nxv8i64 : ValueType<512, 81>; // n x 8 x i64 vector value
+def nxv16i64: ValueType<1024,82>; // n x 16 x i64 vector value
+def nxv32i64: ValueType<2048,83>; // n x 32 x i64 vector value
+
+def v2f16 : ValueType<32 , 84>; // 2 x f16 vector value
+def v4f16 : ValueType<64 , 85>; // 4 x f16 vector value
+def v8f16 : ValueType<128, 86>; // 8 x f16 vector value
+def v1f32 : ValueType<32 , 87>; // 1 x f32 vector value
+def v2f32 : ValueType<64 , 88>; // 2 x f32 vector value
+def v4f32 : ValueType<128, 89>; // 4 x f32 vector value
+def v8f32 : ValueType<256, 90>; // 8 x f32 vector value
+def v16f32 : ValueType<512, 91>; // 16 x f32 vector value
+def v1f64 : ValueType<64, 92>; // 1 x f64 vector value
+def v2f64 : ValueType<128, 93>; // 2 x f64 vector value
+def v4f64 : ValueType<256, 94>; // 4 x f64 vector value
+def v8f64 : ValueType<512, 95>; // 8 x f64 vector value
+
+def nxv2f16 : ValueType<32 , 96>; // n x 2 x f16 vector value
+def nxv4f16 : ValueType<64 , 97>; // n x 4 x f16 vector value
+def nxv8f16 : ValueType<128, 98>; // n x 8 x f16 vector value
+def nxv1f32 : ValueType<32 , 99>; // n x 1 x f32 vector value
+def nxv2f32 : ValueType<64 , 100>; // n x 2 x f32 vector value
+def nxv4f32 : ValueType<128, 101>; // n x 4 x f32 vector value
+def nxv8f32 : ValueType<256, 102>; // n x 8 x f32 vector value
+def nxv16f32 : ValueType<512, 103>; // n x 16 x f32 vector value
+def nxv1f64 : ValueType<64, 104>; // n x 1 x f64 vector value
+def nxv2f64 : ValueType<128, 105>; // n x 2 x f64 vector value
+def nxv4f64 : ValueType<256, 106>; // n x 4 x f64 vector value
+def nxv8f64 : ValueType<512, 107>; // n x 8 x f64 vector value
+
+def x86mmx : ValueType<64 , 108>; // X86 MMX value
+def FlagVT : ValueType<0 , 109>; // Pre-RA sched glue
+def isVoid : ValueType<0 , 110>; // Produces no value
+def untyped: ValueType<8 , 111>; // Produces an untyped value
+def token : ValueType<0 , 248>; // TokenTy
+def MetadataVT: ValueType<0, 249>; // Metadata
// Pseudo valuetype mapped to the current pointer size to any address space.
// Should only be used in TableGen.
-def iPTRAny : ValueType<0, 122>;
+def iPTRAny : ValueType<0, 250>;
// Pseudo valuetype to represent "vector of any size"
-def vAny : ValueType<0 , 123>;
+def vAny : ValueType<0 , 251>;
// Pseudo valuetype to represent "float of any format"
-def fAny : ValueType<0 , 124>;
+def fAny : ValueType<0 , 252>;
// Pseudo valuetype to represent "integer of any bit width"
-def iAny : ValueType<0 , 125>;
+def iAny : ValueType<0 , 253>;
// Pseudo valuetype mapped to the current pointer size.
-def iPTR : ValueType<0 , 126>;
+def iPTR : ValueType<0 , 254>;
// Pseudo valuetype to represent "any type of any size".
-def Any : ValueType<0 , 127>;
+def Any : ValueType<0 , 255>;
diff --git a/contrib/llvm/include/llvm/CodeGen/VirtRegMap.h b/contrib/llvm/include/llvm/CodeGen/VirtRegMap.h
index d7e9209..b907635 100644
--- a/contrib/llvm/include/llvm/CodeGen/VirtRegMap.h
+++ b/contrib/llvm/include/llvm/CodeGen/VirtRegMap.h
@@ -102,14 +102,7 @@ namespace llvm {
/// @brief creates a mapping for the specified virtual register to
/// the specified physical register
- void assignVirt2Phys(unsigned virtReg, unsigned physReg) {
- assert(TargetRegisterInfo::isVirtualRegister(virtReg) &&
- TargetRegisterInfo::isPhysicalRegister(physReg));
- assert(Virt2PhysMap[virtReg] == NO_PHYS_REG &&
- "attempt to assign physical register to already mapped "
- "virtual register");
- Virt2PhysMap[virtReg] = physReg;
- }
+ void assignVirt2Phys(unsigned virtReg, MCPhysReg physReg);
/// @brief clears the specified virtual register's, physical
/// register mapping
diff --git a/contrib/llvm/include/llvm/CodeGen/WinEHFuncInfo.h b/contrib/llvm/include/llvm/CodeGen/WinEHFuncInfo.h
index dd73049..8043024 100644
--- a/contrib/llvm/include/llvm/CodeGen/WinEHFuncInfo.h
+++ b/contrib/llvm/include/llvm/CodeGen/WinEHFuncInfo.h
@@ -1,4 +1,4 @@
-//===-- llvm/CodeGen/WinEHFuncInfo.h ----------------------------*- C++ -*-===//
+//===- llvm/CodeGen/WinEHFuncInfo.h -----------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -17,28 +17,26 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/TinyPtrVector.h"
-#include "llvm/IR/Instructions.h"
+#include <cstdint>
+#include <limits>
+#include <utility>
namespace llvm {
+
class AllocaInst;
class BasicBlock;
-class CatchReturnInst;
-class Constant;
+class FuncletPadInst;
class Function;
class GlobalVariable;
+class Instruction;
class InvokeInst;
-class IntrinsicInst;
-class LandingPadInst;
-class MCExpr;
-class MCSymbol;
class MachineBasicBlock;
-class Value;
+class MCSymbol;
// The following structs respresent the .xdata tables for various
// Windows-related EH personalities.
-typedef PointerUnion<const BasicBlock *, MachineBasicBlock *> MBBOrBasicBlock;
+using MBBOrBasicBlock = PointerUnion<const BasicBlock *, MachineBasicBlock *>;
struct CxxUnwindMapEntry {
int ToState;
@@ -99,18 +97,18 @@ struct WinEHFuncInfo {
SmallVector<WinEHTryBlockMapEntry, 4> TryBlockMap;
SmallVector<SEHUnwindMapEntry, 4> SEHUnwindMap;
SmallVector<ClrEHUnwindMapEntry, 4> ClrEHUnwindMap;
- int UnwindHelpFrameIdx = INT_MAX;
- int PSPSymFrameIdx = INT_MAX;
+ int UnwindHelpFrameIdx = std::numeric_limits<int>::max();
+ int PSPSymFrameIdx = std::numeric_limits<int>::max();
int getLastStateNumber() const { return CxxUnwindMap.size() - 1; }
void addIPToStateRange(const InvokeInst *II, MCSymbol *InvokeBegin,
MCSymbol *InvokeEnd);
- int EHRegNodeFrameIndex = INT_MAX;
- int EHRegNodeEndOffset = INT_MAX;
- int EHGuardFrameIndex = INT_MAX;
- int SEHSetFrameOffset = INT_MAX;
+ int EHRegNodeFrameIndex = std::numeric_limits<int>::max();
+ int EHRegNodeEndOffset = std::numeric_limits<int>::max();
+ int EHGuardFrameIndex = std::numeric_limits<int>::max();
+ int SEHSetFrameOffset = std::numeric_limits<int>::max();
WinEHFuncInfo();
};
@@ -125,5 +123,7 @@ void calculateSEHStateNumbers(const Function *ParentFn,
WinEHFuncInfo &FuncInfo);
void calculateClrEHStateNumbers(const Function *Fn, WinEHFuncInfo &FuncInfo);
-}
+
+} // end namespace llvm
+
#endif // LLVM_CODEGEN_WINEHFUNCINFO_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/CVRecord.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/CVRecord.h
index a327d45..44040e0 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/CVRecord.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/CVRecord.h
@@ -14,8 +14,9 @@
#include "llvm/ADT/Optional.h"
#include "llvm/DebugInfo/CodeView/CodeViewError.h"
#include "llvm/DebugInfo/CodeView/RecordSerialization.h"
-#include "llvm/DebugInfo/MSF/StreamReader.h"
-#include "llvm/DebugInfo/MSF/StreamRef.h"
+#include "llvm/DebugInfo/CodeView/TypeIndex.h"
+#include "llvm/Support/BinaryStreamReader.h"
+#include "llvm/Support/BinaryStreamRef.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/Error.h"
#include <cstdint>
@@ -26,12 +27,19 @@ namespace codeview {
template <typename Kind> class CVRecord {
public:
- CVRecord() = default;
+ CVRecord() : Type(static_cast<Kind>(0)) {}
+
CVRecord(Kind K, ArrayRef<uint8_t> Data) : Type(K), RecordData(Data) {}
+ bool valid() const { return Type != static_cast<Kind>(0); }
+
uint32_t length() const { return RecordData.size(); }
Kind kind() const { return Type; }
ArrayRef<uint8_t> data() const { return RecordData; }
+ StringRef str_data() const {
+ return StringRef(reinterpret_cast<const char *>(RecordData.data()),
+ RecordData.size());
+ }
ArrayRef<uint8_t> content() const {
return RecordData.drop_front(sizeof(RecordPrefix));
@@ -46,17 +54,22 @@ public:
Optional<uint32_t> Hash;
};
-} // end namespace codeview
+template <typename Kind> struct RemappedRecord {
+ explicit RemappedRecord(const CVRecord<Kind> &R) : OriginalRecord(R) {}
-namespace msf {
+ CVRecord<Kind> OriginalRecord;
+ SmallVector<std::pair<uint32_t, TypeIndex>, 8> Mappings;
+};
+
+} // end namespace codeview
template <typename Kind>
struct VarStreamArrayExtractor<codeview::CVRecord<Kind>> {
- Error operator()(ReadableStreamRef Stream, uint32_t &Len,
- codeview::CVRecord<Kind> &Item) const {
+ Error operator()(BinaryStreamRef Stream, uint32_t &Len,
+ codeview::CVRecord<Kind> &Item) {
using namespace codeview;
const RecordPrefix *Prefix = nullptr;
- StreamReader Reader(Stream);
+ BinaryStreamReader Reader(Stream);
uint32_t Offset = Reader.getOffset();
if (auto EC = Reader.readObject(Prefix))
@@ -76,8 +89,6 @@ struct VarStreamArrayExtractor<codeview::CVRecord<Kind>> {
}
};
-} // end namespace msf
-
} // end namespace llvm
#endif // LLVM_DEBUGINFO_CODEVIEW_RECORDITERATOR_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/CVSymbolVisitor.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/CVSymbolVisitor.h
index b2d3f5e..7c8cd12 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/CVSymbolVisitor.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/CVSymbolVisitor.h
@@ -25,7 +25,9 @@ public:
CVSymbolVisitor(SymbolVisitorCallbacks &Callbacks);
Error visitSymbolRecord(CVSymbol &Record);
+ Error visitSymbolRecord(CVSymbol &Record, uint32_t Offset);
Error visitSymbolStream(const CVSymbolArray &Symbols);
+ Error visitSymbolStream(const CVSymbolArray &Symbols, uint32_t InitialOffset);
private:
SymbolVisitorCallbacks &Callbacks;
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/CVTypeDumper.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/CVTypeDumper.h
deleted file mode 100644
index e1dd6a1..0000000
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/CVTypeDumper.h
+++ /dev/null
@@ -1,56 +0,0 @@
-//===-- CVTypeDumper.h - CodeView type info dumper --------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_DEBUGINFO_CODEVIEW_CVTYPEDUMPER_H
-#define LLVM_DEBUGINFO_CODEVIEW_CVTYPEDUMPER_H
-
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/StringSet.h"
-#include "llvm/DebugInfo/CodeView/TypeDatabase.h"
-#include "llvm/DebugInfo/CodeView/TypeIndex.h"
-#include "llvm/DebugInfo/CodeView/TypeRecord.h"
-#include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
-#include "llvm/Support/ScopedPrinter.h"
-
-namespace llvm {
-
-namespace codeview {
-
-/// Dumper for CodeView type streams found in COFF object files and PDB files.
-class CVTypeDumper {
-public:
- explicit CVTypeDumper(TypeDatabase &TypeDB) : TypeDB(TypeDB) {}
-
- /// Dumps one type record. Returns false if there was a type parsing error,
- /// and true otherwise. This should be called in order, since the dumper
- /// maintains state about previous records which are necessary for cross
- /// type references.
- Error dump(const CVType &Record, TypeVisitorCallbacks &Dumper);
-
- /// Dumps the type records in Types. Returns false if there was a type stream
- /// parse error, and true otherwise.
- Error dump(const CVTypeArray &Types, TypeVisitorCallbacks &Dumper);
-
- /// Dumps the type records in Data. Returns false if there was a type stream
- /// parse error, and true otherwise. Use this method instead of the
- /// CVTypeArray overload when type records are laid out contiguously in
- /// memory.
- Error dump(ArrayRef<uint8_t> Data, TypeVisitorCallbacks &Dumper);
-
- static void printTypeIndex(ScopedPrinter &Printer, StringRef FieldName,
- TypeIndex TI, TypeDatabase &DB);
-
-private:
- TypeDatabase &TypeDB;
-};
-
-} // end namespace codeview
-} // end namespace llvm
-
-#endif // LLVM_DEBUGINFO_CODEVIEW_TYPEDUMPER_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h
index d1b0363..df55e18 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h
@@ -10,32 +10,42 @@
#ifndef LLVM_DEBUGINFO_CODEVIEW_CVTYPEVISITOR_H
#define LLVM_DEBUGINFO_CODEVIEW_CVTYPEVISITOR_H
-#include "llvm/ADT/SmallVector.h"
#include "llvm/DebugInfo/CodeView/CVRecord.h"
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
-#include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
#include "llvm/Support/Error.h"
namespace llvm {
namespace codeview {
+class TypeCollection;
+class TypeVisitorCallbacks;
+
+enum VisitorDataSource {
+ VDS_BytesPresent, // The record bytes are passed into the the visitation
+ // function. The algorithm should first deserialize them
+ // before passing them on through the pipeline.
+ VDS_BytesExternal // The record bytes are not present, and it is the
+ // responsibility of the visitor callback interface to
+ // supply the bytes.
+};
-class CVTypeVisitor {
-public:
- explicit CVTypeVisitor(TypeVisitorCallbacks &Callbacks);
-
- Error visitTypeRecord(CVType &Record);
- Error visitMemberRecord(CVMemberRecord &Record);
+Error visitTypeRecord(CVType &Record, TypeIndex Index,
+ TypeVisitorCallbacks &Callbacks,
+ VisitorDataSource Source = VDS_BytesPresent);
+Error visitTypeRecord(CVType &Record, TypeVisitorCallbacks &Callbacks,
+ VisitorDataSource Source = VDS_BytesPresent);
- /// Visits the type records in Data. Sets the error flag on parse failures.
- Error visitTypeStream(const CVTypeArray &Types);
+Error visitMemberRecord(CVMemberRecord Record, TypeVisitorCallbacks &Callbacks,
+ VisitorDataSource Source = VDS_BytesPresent);
+Error visitMemberRecord(TypeLeafKind Kind, ArrayRef<uint8_t> Record,
+ TypeVisitorCallbacks &Callbacks);
- Error visitFieldListMemberStream(ArrayRef<uint8_t> FieldList);
- Error visitFieldListMemberStream(msf::StreamReader Reader);
+Error visitMemberRecordStream(ArrayRef<uint8_t> FieldList,
+ TypeVisitorCallbacks &Callbacks);
-private:
- /// The interface to the class that gets notified of each visitation.
- TypeVisitorCallbacks &Callbacks;
-};
+Error visitTypeStream(const CVTypeArray &Types, TypeVisitorCallbacks &Callbacks,
+ VisitorDataSource Source = VDS_BytesPresent);
+Error visitTypeStream(CVTypeRange Types, TypeVisitorCallbacks &Callbacks);
+Error visitTypeStream(TypeCollection &Types, TypeVisitorCallbacks &Callbacks);
} // end namespace codeview
} // end namespace llvm
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/CodeView.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/CodeView.h
index e21cfa3..b7a7e33 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/CodeView.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/CodeView.h
@@ -6,6 +6,10 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+//
+// Defines constants and basic types describing CodeView debug information.
+//
+//===----------------------------------------------------------------------===//
#ifndef LLVM_DEBUGINFO_CODEVIEW_CODEVIEW_H
#define LLVM_DEBUGINFO_CODEVIEW_CODEVIEW_H
@@ -13,6 +17,8 @@
#include <cinttypes>
#include <type_traits>
+#include "llvm/Support/Endian.h"
+
namespace llvm {
namespace codeview {
@@ -20,28 +26,28 @@ namespace codeview {
/// documentation and headers talk about this as the "leaf" type.
enum class TypeRecordKind : uint16_t {
#define TYPE_RECORD(lf_ename, value, name) name = value,
-#include "TypeRecords.def"
+#include "CodeViewTypes.def"
};
/// Duplicate copy of the above enum, but using the official CV names. Useful
/// for reference purposes and when dealing with unknown record types.
enum TypeLeafKind : uint16_t {
#define CV_TYPE(name, val) name = val,
-#include "TypeRecords.def"
+#include "CodeViewTypes.def"
};
/// Distinguishes individual records in the Symbols subsection of a .debug$S
/// section. Equivalent to SYM_ENUM_e in cvinfo.h.
enum class SymbolRecordKind : uint16_t {
#define SYMBOL_RECORD(lf_ename, value, name) name = value,
-#include "CVSymbolTypes.def"
+#include "CodeViewSymbols.def"
};
/// Duplicate copy of the above enum, but using the official CV names. Useful
/// for reference purposes and when dealing with unknown record types.
enum SymbolKind : uint16_t {
#define CV_SYMBOL(name, val) name = val,
-#include "CVSymbolTypes.def"
+#include "CodeViewSymbols.def"
};
#define CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(Class) \
@@ -275,6 +281,12 @@ enum class MethodOptions : uint16_t {
};
CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(MethodOptions)
+/// Equivalent to CV_LABEL_TYPE_e.
+enum class LabelType : uint16_t {
+ Near = 0x0,
+ Far = 0x4,
+};
+
/// Equivalent to CV_modifier_t.
/// TODO: Add flag for _Atomic modifier
enum class ModifierOptions : uint16_t {
@@ -285,7 +297,7 @@ enum class ModifierOptions : uint16_t {
};
CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(ModifierOptions)
-enum class ModuleSubstreamKind : uint32_t {
+enum class DebugSubsectionKind : uint32_t {
None = 0,
Symbols = 0xf1,
Lines = 0xf2,
@@ -390,6 +402,16 @@ enum class LocalSymFlags : uint16_t {
};
CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(LocalSymFlags)
+/// Corresponds to the CV_PUBSYMFLAGS bitfield.
+enum class PublicSymFlags : uint32_t {
+ None = 0,
+ Code = 1 << 0,
+ Function = 1 << 1,
+ Managed = 1 << 2,
+ MSIL = 1 << 3,
+};
+CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(PublicSymFlags)
+
/// Corresponds to the CV_PROCFLAGS bitfield.
enum class ProcSymFlags : uint8_t {
None = 0,
@@ -406,6 +428,8 @@ CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(ProcSymFlags)
/// Corresponds to COMPILESYM2::Flags bitfield.
enum class CompileSym2Flags : uint32_t {
+ None = 0,
+ SourceLanguageMask = 0xFF,
EC = 1 << 8,
NoDbgInfo = 1 << 9,
LTCG = 1 << 10,
@@ -420,6 +444,8 @@ CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(CompileSym2Flags)
/// Corresponds to COMPILESYM3::Flags bitfield.
enum class CompileSym3Flags : uint32_t {
+ None = 0,
+ SourceLanguageMask = 0xFF,
EC = 1 << 8,
NoDbgInfo = 1 << 9,
LTCG = 1 << 10,
@@ -436,6 +462,7 @@ enum class CompileSym3Flags : uint32_t {
CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(CompileSym3Flags)
enum class ExportFlags : uint16_t {
+ None = 0,
IsConstant = 1 << 0,
IsData = 1 << 1,
IsPrivate = 1 << 2,
@@ -540,9 +567,54 @@ enum class TrampolineType : uint16_t { TrampIncremental, BranchIsland };
// These values correspond to the CV_SourceChksum_t enumeration.
enum class FileChecksumKind : uint8_t { None, MD5, SHA1, SHA256 };
-enum LineFlags : uint32_t {
- HaveColumns = 1, // CV_LINES_HAVE_COLUMNS
-};
+enum LineFlags : uint16_t {
+ LF_None = 0,
+ LF_HaveColumns = 1, // CV_LINES_HAVE_COLUMNS
+};
+
+/// Data in the the SUBSEC_FRAMEDATA subection.
+struct FrameData {
+ support::ulittle32_t RvaStart;
+ support::ulittle32_t CodeSize;
+ support::ulittle32_t LocalSize;
+ support::ulittle32_t ParamsSize;
+ support::ulittle32_t MaxStackSize;
+ support::ulittle32_t FrameFunc;
+ support::ulittle16_t PrologSize;
+ support::ulittle16_t SavedRegsSize;
+ support::ulittle32_t Flags;
+ enum : uint32_t {
+ HasSEH = 1 << 0,
+ HasEH = 1 << 1,
+ IsFunctionStart = 1 << 2,
+ };
+};
+
+// Corresponds to LocalIdAndGlobalIdPair structure.
+// This structure information allows cross-referencing between PDBs. For
+// example, when a PDB is being built during compilation it is not yet known
+// what other modules may end up in the PDB at link time. So certain types of
+// IDs may clash between the various compile time PDBs. For each affected
+// module, a subsection would be put into the PDB containing a mapping from its
+// local IDs to a single ID namespace for all items in the PDB file.
+struct CrossModuleExport {
+ support::ulittle32_t Local;
+ support::ulittle32_t Global;
+};
+
+struct CrossModuleImport {
+ support::ulittle32_t ModuleNameOffset;
+ support::ulittle32_t Count; // Number of elements
+ // support::ulittle32_t ids[Count]; // id from referenced module
+};
+
+enum class CodeViewContainer { ObjectFile, Pdb };
+
+inline uint32_t alignOf(CodeViewContainer Container) {
+ if (Container == CodeViewContainer::ObjectFile)
+ return 1;
+ return 4;
+}
}
}
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/CodeViewError.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/CodeViewError.h
index 0556fd0..586a720 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/CodeViewError.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/CodeViewError.h
@@ -21,6 +21,7 @@ enum class cv_error_code {
insufficient_buffer,
operation_unsupported,
corrupt_record,
+ no_records,
unknown_member_record,
};
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/CodeViewRecordIO.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/CodeViewRecordIO.h
index 5a036b9..94f104f 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/CodeViewRecordIO.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/CodeViewRecordIO.h
@@ -17,8 +17,8 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/DebugInfo/CodeView/CodeViewError.h"
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
-#include "llvm/DebugInfo/MSF/StreamReader.h"
-#include "llvm/DebugInfo/MSF/StreamWriter.h"
+#include "llvm/Support/BinaryStreamReader.h"
+#include "llvm/Support/BinaryStreamWriter.h"
#include "llvm/Support/Error.h"
#include <cassert>
#include <cstdint>
@@ -33,8 +33,8 @@ class CodeViewRecordIO {
}
public:
- explicit CodeViewRecordIO(msf::StreamReader &Reader) : Reader(&Reader) {}
- explicit CodeViewRecordIO(msf::StreamWriter &Writer) : Writer(&Writer) {}
+ explicit CodeViewRecordIO(BinaryStreamReader &Reader) : Reader(&Reader) {}
+ explicit CodeViewRecordIO(BinaryStreamWriter &Writer) : Writer(&Writer) {}
Error beginRecord(Optional<uint32_t> MaxLength);
Error endRecord();
@@ -84,7 +84,7 @@ public:
Error mapEncodedInteger(uint64_t &Value);
Error mapEncodedInteger(APSInt &Value);
Error mapStringZ(StringRef &Value);
- Error mapGuid(StringRef &Guid);
+ Error mapGuid(GUID &Guid);
Error mapStringZVectorZ(std::vector<StringRef> &Value);
@@ -136,6 +136,7 @@ public:
Error mapByteVectorTail(ArrayRef<uint8_t> &Bytes);
Error mapByteVectorTail(std::vector<uint8_t> &Bytes);
+ Error padToAlignment(uint32_t Align);
Error skipPadding();
private:
@@ -160,8 +161,8 @@ private:
SmallVector<RecordLimit, 2> Limits;
- msf::StreamReader *Reader = nullptr;
- msf::StreamWriter *Writer = nullptr;
+ BinaryStreamReader *Reader = nullptr;
+ BinaryStreamWriter *Writer = nullptr;
};
} // end namespace codeview
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/CVSymbolTypes.def b/contrib/llvm/include/llvm/DebugInfo/CodeView/CodeViewSymbols.def
index 32813d8..32813d8 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/CVSymbolTypes.def
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/CodeViewSymbols.def
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeRecords.def b/contrib/llvm/include/llvm/DebugInfo/CodeView/CodeViewTypes.def
index c98dbac..8c193bb 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeRecords.def
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/CodeViewTypes.def
@@ -41,6 +41,7 @@ TYPE_RECORD(LF_POINTER, 0x1002, Pointer)
TYPE_RECORD(LF_MODIFIER, 0x1001, Modifier)
TYPE_RECORD(LF_PROCEDURE, 0x1008, Procedure)
TYPE_RECORD(LF_MFUNCTION, 0x1009, MemberFunction)
+TYPE_RECORD(LF_LABEL, 0x000e, Label)
TYPE_RECORD(LF_ARGLIST, 0x1201, ArgList)
TYPE_RECORD(LF_FIELDLIST, 0x1203, FieldList)
@@ -79,9 +80,7 @@ MEMBER_RECORD(LF_INDEX, 0x1404, ListContinuation)
TYPE_RECORD(LF_FUNC_ID, 0x1601, FuncId)
TYPE_RECORD(LF_MFUNC_ID, 0x1602, MemberFuncId)
TYPE_RECORD(LF_BUILDINFO, 0x1603, BuildInfo)
-// FIXME: We reuse the structure of ArgListRecord for substring lists, but it
-// makes for confusing dumper output.
-TYPE_RECORD_ALIAS(LF_SUBSTR_LIST, 0x1604, StringList, ArgList)
+TYPE_RECORD(LF_SUBSTR_LIST, 0x1604, StringList)
TYPE_RECORD(LF_STRING_ID, 0x1605, StringId)
TYPE_RECORD(LF_UDT_SRC_LINE, 0x1606, UdtSourceLine)
TYPE_RECORD(LF_UDT_MOD_SRC_LINE, 0x1607, UdtModSourceLine)
@@ -103,7 +102,6 @@ CV_TYPE(LF_MFUNCTION_16t, 0x0009)
CV_TYPE(LF_COBOL0_16t, 0x000b)
CV_TYPE(LF_COBOL1, 0x000c)
CV_TYPE(LF_BARRAY_16t, 0x000d)
-CV_TYPE(LF_LABEL, 0x000e)
CV_TYPE(LF_NULLLEAF, 0x000f) // LF_NULL
CV_TYPE(LF_NOTTRAN, 0x0010)
CV_TYPE(LF_DIMARRAY_16t, 0x0011)
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h
new file mode 100644
index 0000000..78b2845
--- /dev/null
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h
@@ -0,0 +1,104 @@
+//===- DebugChecksumsSubsection.h -------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_CODEVIEW_DEBUGCHECKSUMSSUBSECTION_H
+#define LLVM_DEBUGINFO_CODEVIEW_DEBUGCHECKSUMSSUBSECTION_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/DebugSubsection.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/BinaryStreamArray.h"
+#include "llvm/Support/BinaryStreamReader.h"
+#include "llvm/Support/BinaryStreamRef.h"
+#include "llvm/Support/Error.h"
+#include <cstdint>
+#include <vector>
+
+namespace llvm {
+
+namespace codeview {
+
+class DebugStringTableSubsection;
+
+struct FileChecksumEntry {
+ uint32_t FileNameOffset; // Byte offset of filename in global stringtable.
+ FileChecksumKind Kind; // The type of checksum.
+ ArrayRef<uint8_t> Checksum; // The bytes of the checksum.
+};
+
+} // end namespace codeview
+
+template <> struct VarStreamArrayExtractor<codeview::FileChecksumEntry> {
+public:
+ using ContextType = void;
+
+ Error operator()(BinaryStreamRef Stream, uint32_t &Len,
+ codeview::FileChecksumEntry &Item);
+};
+
+namespace codeview {
+
+class DebugChecksumsSubsectionRef final : public DebugSubsectionRef {
+ using FileChecksumArray = VarStreamArray<codeview::FileChecksumEntry>;
+ using Iterator = FileChecksumArray::Iterator;
+
+public:
+ DebugChecksumsSubsectionRef()
+ : DebugSubsectionRef(DebugSubsectionKind::FileChecksums) {}
+
+ static bool classof(const DebugSubsectionRef *S) {
+ return S->kind() == DebugSubsectionKind::FileChecksums;
+ }
+
+ bool valid() const { return Checksums.valid(); }
+
+ Error initialize(BinaryStreamReader Reader);
+ Error initialize(BinaryStreamRef Stream);
+
+ Iterator begin() const { return Checksums.begin(); }
+ Iterator end() const { return Checksums.end(); }
+
+ const FileChecksumArray &getArray() const { return Checksums; }
+
+private:
+ FileChecksumArray Checksums;
+};
+
+class DebugChecksumsSubsection final : public DebugSubsection {
+public:
+ explicit DebugChecksumsSubsection(DebugStringTableSubsection &Strings);
+
+ static bool classof(const DebugSubsection *S) {
+ return S->kind() == DebugSubsectionKind::FileChecksums;
+ }
+
+ void addChecksum(StringRef FileName, FileChecksumKind Kind,
+ ArrayRef<uint8_t> Bytes);
+
+ uint32_t calculateSerializedSize() const override;
+ Error commit(BinaryStreamWriter &Writer) const override;
+ uint32_t mapChecksumOffset(StringRef FileName) const;
+
+private:
+ DebugStringTableSubsection &Strings;
+
+ DenseMap<uint32_t, uint32_t> OffsetMap;
+ uint32_t SerializedSize = 0;
+ BumpPtrAllocator Storage;
+ std::vector<FileChecksumEntry> Checksums;
+};
+
+} // end namespace codeview
+
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_CODEVIEW_DEBUGCHECKSUMSSUBSECTION_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/DebugCrossExSubsection.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/DebugCrossExSubsection.h
new file mode 100644
index 0000000..2f9e981
--- /dev/null
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/DebugCrossExSubsection.h
@@ -0,0 +1,68 @@
+//===- DebugCrossExSubsection.h ---------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_CODEVIEW_DEBUGCROSSEXSUBSECTION_H
+#define LLVM_DEBUGINFO_CODEVIEW_DEBUGCROSSEXSUBSECTION_H
+
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/DebugSubsection.h"
+#include "llvm/Support/BinaryStreamArray.h"
+#include "llvm/Support/BinaryStreamReader.h"
+#include "llvm/Support/BinaryStreamRef.h"
+#include "llvm/Support/Error.h"
+#include <cstdint>
+#include <map>
+
+namespace llvm {
+namespace codeview {
+
+class DebugCrossModuleExportsSubsectionRef final : public DebugSubsectionRef {
+ using ReferenceArray = FixedStreamArray<CrossModuleExport>;
+ using Iterator = ReferenceArray::Iterator;
+
+public:
+ DebugCrossModuleExportsSubsectionRef()
+ : DebugSubsectionRef(DebugSubsectionKind::CrossScopeExports) {}
+
+ static bool classof(const DebugSubsectionRef *S) {
+ return S->kind() == DebugSubsectionKind::CrossScopeExports;
+ }
+
+ Error initialize(BinaryStreamReader Reader);
+ Error initialize(BinaryStreamRef Stream);
+
+ Iterator begin() const { return References.begin(); }
+ Iterator end() const { return References.end(); }
+
+private:
+ FixedStreamArray<CrossModuleExport> References;
+};
+
+class DebugCrossModuleExportsSubsection final : public DebugSubsection {
+public:
+ DebugCrossModuleExportsSubsection()
+ : DebugSubsection(DebugSubsectionKind::CrossScopeExports) {}
+
+ static bool classof(const DebugSubsection *S) {
+ return S->kind() == DebugSubsectionKind::CrossScopeExports;
+ }
+
+ void addMapping(uint32_t Local, uint32_t Global);
+
+ uint32_t calculateSerializedSize() const override;
+ Error commit(BinaryStreamWriter &Writer) const override;
+
+private:
+ std::map<uint32_t, uint32_t> Mappings;
+};
+
+} // end namespace codeview
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_CODEVIEW_DEBUGCROSSEXSUBSECTION_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/DebugCrossImpSubsection.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/DebugCrossImpSubsection.h
new file mode 100644
index 0000000..8be7ef2
--- /dev/null
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/DebugCrossImpSubsection.h
@@ -0,0 +1,95 @@
+//===- DebugCrossExSubsection.h ---------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_CODEVIEW_DEBUGCROSSIMPSUBSECTION_H
+#define LLVM_DEBUGINFO_CODEVIEW_DEBUGCROSSIMPSUBSECTION_H
+
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/DebugSubsection.h"
+#include "llvm/Support/BinaryStreamArray.h"
+#include "llvm/Support/BinaryStreamReader.h"
+#include "llvm/Support/BinaryStreamRef.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
+#include <cstdint>
+#include <vector>
+
+namespace llvm {
+
+namespace codeview {
+
+struct CrossModuleImportItem {
+ const CrossModuleImport *Header = nullptr;
+ FixedStreamArray<support::ulittle32_t> Imports;
+};
+
+} // end namespace codeview
+
+template <> struct VarStreamArrayExtractor<codeview::CrossModuleImportItem> {
+public:
+ using ContextType = void;
+
+ Error operator()(BinaryStreamRef Stream, uint32_t &Len,
+ codeview::CrossModuleImportItem &Item);
+};
+
+namespace codeview {
+
+class DebugStringTableSubsection;
+
+class DebugCrossModuleImportsSubsectionRef final : public DebugSubsectionRef {
+ using ReferenceArray = VarStreamArray<CrossModuleImportItem>;
+ using Iterator = ReferenceArray::Iterator;
+
+public:
+ DebugCrossModuleImportsSubsectionRef()
+ : DebugSubsectionRef(DebugSubsectionKind::CrossScopeImports) {}
+
+ static bool classof(const DebugSubsectionRef *S) {
+ return S->kind() == DebugSubsectionKind::CrossScopeImports;
+ }
+
+ Error initialize(BinaryStreamReader Reader);
+ Error initialize(BinaryStreamRef Stream);
+
+ Iterator begin() const { return References.begin(); }
+ Iterator end() const { return References.end(); }
+
+private:
+ ReferenceArray References;
+};
+
+class DebugCrossModuleImportsSubsection final : public DebugSubsection {
+public:
+ explicit DebugCrossModuleImportsSubsection(
+ DebugStringTableSubsection &Strings)
+ : DebugSubsection(DebugSubsectionKind::CrossScopeImports),
+ Strings(Strings) {}
+
+ static bool classof(const DebugSubsection *S) {
+ return S->kind() == DebugSubsectionKind::CrossScopeImports;
+ }
+
+ void addImport(StringRef Module, uint32_t ImportId);
+
+ uint32_t calculateSerializedSize() const override;
+ Error commit(BinaryStreamWriter &Writer) const override;
+
+private:
+ DebugStringTableSubsection &Strings;
+ StringMap<std::vector<support::ulittle32_t>> Mappings;
+};
+
+} // end namespace codeview
+
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_CODEVIEW_DEBUGCROSSIMPSUBSECTION_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/DebugFrameDataSubsection.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/DebugFrameDataSubsection.h
new file mode 100644
index 0000000..1e329c7
--- /dev/null
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/DebugFrameDataSubsection.h
@@ -0,0 +1,60 @@
+//===- DebugFrameDataSubsection.h ------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_CODEVIEW_DEBUGFRAMEDATASUBSECTION_H
+#define LLVM_DEBUGINFO_CODEVIEW_DEBUGFRAMEDATASUBSECTION_H
+
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/DebugSubsection.h"
+#include "llvm/Support/BinaryStreamReader.h"
+#include "llvm/Support/Error.h"
+
+namespace llvm {
+namespace codeview {
+class DebugFrameDataSubsectionRef final : public DebugSubsectionRef {
+public:
+ DebugFrameDataSubsectionRef()
+ : DebugSubsectionRef(DebugSubsectionKind::FrameData) {}
+ static bool classof(const DebugSubsection *S) {
+ return S->kind() == DebugSubsectionKind::FrameData;
+ }
+
+ Error initialize(BinaryStreamReader Reader);
+
+ FixedStreamArray<FrameData>::Iterator begin() const { return Frames.begin(); }
+ FixedStreamArray<FrameData>::Iterator end() const { return Frames.end(); }
+
+ const void *getRelocPtr() const { return RelocPtr; }
+
+private:
+ const uint32_t *RelocPtr = nullptr;
+ FixedStreamArray<FrameData> Frames;
+};
+
+class DebugFrameDataSubsection final : public DebugSubsection {
+public:
+ DebugFrameDataSubsection()
+ : DebugSubsection(DebugSubsectionKind::FrameData) {}
+ static bool classof(const DebugSubsection *S) {
+ return S->kind() == DebugSubsectionKind::FrameData;
+ }
+
+ uint32_t calculateSerializedSize() const override;
+ Error commit(BinaryStreamWriter &Writer) const override;
+
+ void addFrameData(const FrameData &Frame);
+ void setFrames(ArrayRef<FrameData> Frames);
+
+private:
+ std::vector<FrameData> Frames;
+};
+}
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h
new file mode 100644
index 0000000..b88c0ea
--- /dev/null
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h
@@ -0,0 +1,121 @@
+//===- DebugInlineeLinesSubsection.h ----------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_CODEVIEW_DEBUGINLINEELINESSUBSECTION_H
+#define LLVM_DEBUGINFO_CODEVIEW_DEBUGINLINEELINESSUBSECTION_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/DebugSubsection.h"
+#include "llvm/DebugInfo/CodeView/Line.h"
+#include "llvm/DebugInfo/CodeView/TypeIndex.h"
+#include "llvm/Support/BinaryStreamArray.h"
+#include "llvm/Support/BinaryStreamReader.h"
+#include "llvm/Support/BinaryStreamRef.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
+#include <cstdint>
+#include <vector>
+
+namespace llvm {
+
+namespace codeview {
+
+class DebugChecksumsSubsection;
+
+enum class InlineeLinesSignature : uint32_t {
+ Normal, // CV_INLINEE_SOURCE_LINE_SIGNATURE
+ ExtraFiles // CV_INLINEE_SOURCE_LINE_SIGNATURE_EX
+};
+
+struct InlineeSourceLineHeader {
+ TypeIndex Inlinee; // ID of the function that was inlined.
+ support::ulittle32_t FileID; // Offset into FileChecksums subsection.
+ support::ulittle32_t SourceLineNum; // First line of inlined code.
+ // If extra files present:
+ // ulittle32_t ExtraFileCount;
+ // ulittle32_t Files[];
+};
+
+struct InlineeSourceLine {
+ const InlineeSourceLineHeader *Header;
+ FixedStreamArray<support::ulittle32_t> ExtraFiles;
+};
+
+} // end namespace codeview
+
+template <> struct VarStreamArrayExtractor<codeview::InlineeSourceLine> {
+ Error operator()(BinaryStreamRef Stream, uint32_t &Len,
+ codeview::InlineeSourceLine &Item);
+
+ bool HasExtraFiles = false;
+};
+
+namespace codeview {
+
+class DebugInlineeLinesSubsectionRef final : public DebugSubsectionRef {
+ using LinesArray = VarStreamArray<InlineeSourceLine>;
+ using Iterator = LinesArray::Iterator;
+
+public:
+ DebugInlineeLinesSubsectionRef();
+
+ static bool classof(const DebugSubsectionRef *S) {
+ return S->kind() == DebugSubsectionKind::InlineeLines;
+ }
+
+ Error initialize(BinaryStreamReader Reader);
+ bool hasExtraFiles() const;
+
+ Iterator begin() const { return Lines.begin(); }
+ Iterator end() const { return Lines.end(); }
+
+private:
+ InlineeLinesSignature Signature;
+ VarStreamArray<InlineeSourceLine> Lines;
+};
+
+class DebugInlineeLinesSubsection final : public DebugSubsection {
+public:
+ struct Entry {
+ std::vector<support::ulittle32_t> ExtraFiles;
+ InlineeSourceLineHeader Header;
+ };
+
+ DebugInlineeLinesSubsection(DebugChecksumsSubsection &Checksums,
+ bool HasExtraFiles = false);
+
+ static bool classof(const DebugSubsection *S) {
+ return S->kind() == DebugSubsectionKind::InlineeLines;
+ }
+
+ Error commit(BinaryStreamWriter &Writer) const override;
+ uint32_t calculateSerializedSize() const override;
+
+ void addInlineSite(TypeIndex FuncId, StringRef FileName, uint32_t SourceLine);
+ void addExtraFile(StringRef FileName);
+
+ bool hasExtraFiles() const { return HasExtraFiles; }
+ void setHasExtraFiles(bool Has) { HasExtraFiles = Has; }
+
+ std::vector<Entry>::const_iterator begin() const { return Entries.begin(); }
+ std::vector<Entry>::const_iterator end() const { return Entries.end(); }
+
+private:
+ DebugChecksumsSubsection &Checksums;
+ bool HasExtraFiles = false;
+ uint32_t ExtraFileCount = 0;
+ std::vector<Entry> Entries;
+};
+
+} // end namespace codeview
+
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_CODEVIEW_DEBUGINLINEELINESSUBSECTION_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/DebugLinesSubsection.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/DebugLinesSubsection.h
new file mode 100644
index 0000000..53044b6
--- /dev/null
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/DebugLinesSubsection.h
@@ -0,0 +1,150 @@
+//===- DebugLinesSubsection.h -----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_CODEVIEW_DEBUGLINESSUBSECTION_H
+#define LLVM_DEBUGINFO_CODEVIEW_DEBUGLINESSUBSECTION_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/DebugSubsection.h"
+#include "llvm/DebugInfo/CodeView/Line.h"
+#include "llvm/Support/BinaryStreamArray.h"
+#include "llvm/Support/BinaryStreamReader.h"
+#include "llvm/Support/BinaryStreamRef.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
+#include <cstdint>
+#include <vector>
+
+namespace llvm {
+namespace codeview {
+
+class DebugChecksumsSubsection;
+class DebugStringTableSubsection;
+
+// Corresponds to the `CV_DebugSLinesHeader_t` structure.
+struct LineFragmentHeader {
+ support::ulittle32_t RelocOffset; // Code offset of line contribution.
+ support::ulittle16_t RelocSegment; // Code segment of line contribution.
+ support::ulittle16_t Flags; // See LineFlags enumeration.
+ support::ulittle32_t CodeSize; // Code size of this line contribution.
+};
+
+// Corresponds to the `CV_DebugSLinesFileBlockHeader_t` structure.
+struct LineBlockFragmentHeader {
+ support::ulittle32_t NameIndex; // Offset of FileChecksum entry in File
+ // checksums buffer. The checksum entry then
+ // contains another offset into the string
+ // table of the actual name.
+ support::ulittle32_t NumLines; // Number of lines
+ support::ulittle32_t BlockSize; // Code size of block, in bytes.
+ // The following two variable length arrays appear immediately after the
+ // header. The structure definitions follow.
+ // LineNumberEntry Lines[NumLines];
+ // ColumnNumberEntry Columns[NumLines];
+};
+
+// Corresponds to `CV_Line_t` structure
+struct LineNumberEntry {
+ support::ulittle32_t Offset; // Offset to start of code bytes for line number
+ support::ulittle32_t Flags; // Start:24, End:7, IsStatement:1
+};
+
+// Corresponds to `CV_Column_t` structure
+struct ColumnNumberEntry {
+ support::ulittle16_t StartColumn;
+ support::ulittle16_t EndColumn;
+};
+
+struct LineColumnEntry {
+ support::ulittle32_t NameIndex;
+ FixedStreamArray<LineNumberEntry> LineNumbers;
+ FixedStreamArray<ColumnNumberEntry> Columns;
+};
+
+class LineColumnExtractor {
+public:
+ Error operator()(BinaryStreamRef Stream, uint32_t &Len,
+ LineColumnEntry &Item);
+
+ const LineFragmentHeader *Header = nullptr;
+};
+
+class DebugLinesSubsectionRef final : public DebugSubsectionRef {
+ friend class LineColumnExtractor;
+
+ using LineInfoArray = VarStreamArray<LineColumnEntry, LineColumnExtractor>;
+ using Iterator = LineInfoArray::Iterator;
+
+public:
+ DebugLinesSubsectionRef();
+
+ static bool classof(const DebugSubsectionRef *S) {
+ return S->kind() == DebugSubsectionKind::Lines;
+ }
+
+ Error initialize(BinaryStreamReader Reader);
+
+ Iterator begin() const { return LinesAndColumns.begin(); }
+ Iterator end() const { return LinesAndColumns.end(); }
+
+ const LineFragmentHeader *header() const { return Header; }
+
+ bool hasColumnInfo() const;
+
+private:
+ const LineFragmentHeader *Header = nullptr;
+ LineInfoArray LinesAndColumns;
+};
+
+class DebugLinesSubsection final : public DebugSubsection {
+ struct Block {
+ Block(uint32_t ChecksumBufferOffset)
+ : ChecksumBufferOffset(ChecksumBufferOffset) {}
+
+ uint32_t ChecksumBufferOffset;
+ std::vector<LineNumberEntry> Lines;
+ std::vector<ColumnNumberEntry> Columns;
+ };
+
+public:
+ DebugLinesSubsection(DebugChecksumsSubsection &Checksums,
+ DebugStringTableSubsection &Strings);
+
+ static bool classof(const DebugSubsection *S) {
+ return S->kind() == DebugSubsectionKind::Lines;
+ }
+
+ void createBlock(StringRef FileName);
+ void addLineInfo(uint32_t Offset, const LineInfo &Line);
+ void addLineAndColumnInfo(uint32_t Offset, const LineInfo &Line,
+ uint32_t ColStart, uint32_t ColEnd);
+
+ uint32_t calculateSerializedSize() const override;
+ Error commit(BinaryStreamWriter &Writer) const override;
+
+ void setRelocationAddress(uint16_t Segment, uint32_t Offset);
+ void setCodeSize(uint32_t Size);
+ void setFlags(LineFlags Flags);
+
+ bool hasColumnInfo() const;
+
+private:
+ DebugChecksumsSubsection &Checksums;
+ uint32_t RelocOffset = 0;
+ uint16_t RelocSegment = 0;
+ uint32_t CodeSize = 0;
+ LineFlags Flags = LF_None;
+ std::vector<Block> Blocks;
+};
+
+} // end namespace codeview
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_CODEVIEW_DEBUGLINESSUBSECTION_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/DebugStringTableSubsection.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/DebugStringTableSubsection.h
new file mode 100644
index 0000000..7f0f10e
--- /dev/null
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/DebugStringTableSubsection.h
@@ -0,0 +1,89 @@
+//===- DebugStringTableSubsection.h - CodeView String Table -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_CODEVIEW_DEBUGSTRINGTABLESUBSECTION_H
+#define LLVM_DEBUGINFO_CODEVIEW_DEBUGSTRINGTABLESUBSECTION_H
+
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/DebugSubsection.h"
+#include "llvm/Support/BinaryStreamRef.h"
+#include "llvm/Support/Error.h"
+#include <cstdint>
+
+namespace llvm {
+
+class BinaryStreamReader;
+
+namespace codeview {
+
+/// Represents a read-only view of a CodeView string table. This is a very
+/// simple flat buffer consisting of null-terminated strings, where strings
+/// are retrieved by their offset in the buffer. DebugStringTableSubsectionRef
+/// does not own the underlying storage for the buffer.
+class DebugStringTableSubsectionRef : public DebugSubsectionRef {
+public:
+ DebugStringTableSubsectionRef();
+
+ static bool classof(const DebugSubsectionRef *S) {
+ return S->kind() == DebugSubsectionKind::StringTable;
+ }
+
+ Error initialize(BinaryStreamRef Contents);
+ Error initialize(BinaryStreamReader &Reader);
+
+ Expected<StringRef> getString(uint32_t Offset) const;
+
+ bool valid() const { return Stream.valid(); }
+
+ BinaryStreamRef getBuffer() const { return Stream; }
+
+private:
+ BinaryStreamRef Stream;
+};
+
+/// Represents a read-write view of a CodeView string table.
+/// DebugStringTableSubsection owns the underlying storage for the table, and is
+/// capable of serializing the string table into a format understood by
+/// DebugStringTableSubsectionRef.
+class DebugStringTableSubsection : public DebugSubsection {
+public:
+ DebugStringTableSubsection();
+
+ static bool classof(const DebugSubsection *S) {
+ return S->kind() == DebugSubsectionKind::StringTable;
+ }
+
+ // If string S does not exist in the string table, insert it.
+ // Returns the ID for S.
+ uint32_t insert(StringRef S);
+
+ // Return the ID for string S. Assumes S exists in the table.
+ uint32_t getStringId(StringRef S) const;
+
+ uint32_t calculateSerializedSize() const override;
+ Error commit(BinaryStreamWriter &Writer) const override;
+
+ uint32_t size() const;
+
+ StringMap<uint32_t>::const_iterator begin() const { return Strings.begin(); }
+
+ StringMap<uint32_t>::const_iterator end() const { return Strings.end(); }
+
+private:
+ StringMap<uint32_t> Strings;
+ uint32_t StringSize = 1;
+};
+
+} // end namespace codeview
+
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_CODEVIEW_DEBUGSTRINGTABLESUBSECTION_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/DebugSubsection.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/DebugSubsection.h
new file mode 100644
index 0000000..e427e00
--- /dev/null
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/DebugSubsection.h
@@ -0,0 +1,52 @@
+//===- DebugSubsection.h ------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGFRAGMENT_H
+#define LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGFRAGMENT_H
+
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/Support/BinaryStreamWriter.h"
+#include "llvm/Support/Casting.h"
+
+namespace llvm {
+namespace codeview {
+
+class DebugSubsectionRef {
+public:
+ explicit DebugSubsectionRef(DebugSubsectionKind Kind) : Kind(Kind) {}
+ virtual ~DebugSubsectionRef();
+
+ static bool classof(const DebugSubsectionRef *S) { return true; }
+
+ DebugSubsectionKind kind() const { return Kind; }
+
+protected:
+ DebugSubsectionKind Kind;
+};
+
+class DebugSubsection {
+public:
+ explicit DebugSubsection(DebugSubsectionKind Kind) : Kind(Kind) {}
+ virtual ~DebugSubsection();
+
+ static bool classof(const DebugSubsection *S) { return true; }
+
+ DebugSubsectionKind kind() const { return Kind; }
+
+ virtual Error commit(BinaryStreamWriter &Writer) const = 0;
+ virtual uint32_t calculateSerializedSize() const = 0;
+
+protected:
+ DebugSubsectionKind Kind;
+};
+
+} // namespace codeview
+} // namespace llvm
+
+#endif // LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGFRAGMENT_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/DebugSubsectionRecord.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/DebugSubsectionRecord.h
new file mode 100644
index 0000000..fc0cf0d
--- /dev/null
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/DebugSubsectionRecord.h
@@ -0,0 +1,103 @@
+//===- DebugSubsectionRecord.h ----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_CODEVIEW_DEBUGSUBSECTIONRECORD_H
+#define LLVM_DEBUGINFO_CODEVIEW_DEBUGSUBSECTIONRECORD_H
+
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/Support/BinaryStreamArray.h"
+#include "llvm/Support/BinaryStreamRef.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/MathExtras.h"
+#include <cstdint>
+#include <memory>
+
+namespace llvm {
+
+class BinaryStreamWriter;
+
+namespace codeview {
+
+class DebugSubsection;
+
+// Corresponds to the `CV_DebugSSubsectionHeader_t` structure.
+struct DebugSubsectionHeader {
+ support::ulittle32_t Kind; // codeview::DebugSubsectionKind enum
+ support::ulittle32_t Length; // number of bytes occupied by this record.
+};
+
+class DebugSubsectionRecord {
+public:
+ DebugSubsectionRecord();
+ DebugSubsectionRecord(DebugSubsectionKind Kind, BinaryStreamRef Data,
+ CodeViewContainer Container);
+
+ static Error initialize(BinaryStreamRef Stream, DebugSubsectionRecord &Info,
+ CodeViewContainer Container);
+
+ 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);
+
+ /// 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);
+
+ uint32_t calculateSerializedLength();
+ Error commit(BinaryStreamWriter &Writer) 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.
+ DebugSubsectionRecord Contents;
+
+ CodeViewContainer Container;
+};
+
+} // end namespace codeview
+
+template <> struct VarStreamArrayExtractor<codeview::DebugSubsectionRecord> {
+ Error operator()(BinaryStreamRef Stream, uint32_t &Length,
+ codeview::DebugSubsectionRecord &Info) {
+ // 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))
+ return EC;
+ Length = alignTo(Info.getRecordLength(), 4);
+ return Error::success();
+ }
+};
+
+namespace codeview {
+
+using DebugSubsectionArray = VarStreamArray<DebugSubsectionRecord>;
+
+} // end namespace codeview
+
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_CODEVIEW_DEBUGSUBSECTIONRECORD_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/DebugSubsectionVisitor.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/DebugSubsectionVisitor.h
new file mode 100644
index 0000000..75f749d
--- /dev/null
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/DebugSubsectionVisitor.h
@@ -0,0 +1,114 @@
+//===- DebugSubsectionVisitor.h -----------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGFRAGMENTVISITOR_H
+#define LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGFRAGMENTVISITOR_H
+
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h"
+#include "llvm/DebugInfo/CodeView/StringsAndChecksums.h"
+#include "llvm/Support/Error.h"
+#include <cstdint>
+
+namespace llvm {
+
+namespace codeview {
+
+class DebugChecksumsSubsectionRef;
+class DebugSubsectionRecord;
+class DebugInlineeLinesSubsectionRef;
+class DebugCrossModuleExportsSubsectionRef;
+class DebugCrossModuleImportsSubsectionRef;
+class DebugFrameDataSubsectionRef;
+class DebugLinesSubsectionRef;
+class DebugStringTableSubsectionRef;
+class DebugSymbolRVASubsectionRef;
+class DebugSymbolsSubsectionRef;
+class DebugUnknownSubsectionRef;
+class StringsAndChecksumsRef;
+
+class DebugSubsectionVisitor {
+public:
+ virtual ~DebugSubsectionVisitor() = default;
+
+ virtual Error visitUnknown(DebugUnknownSubsectionRef &Unknown) {
+ return Error::success();
+ }
+ virtual Error visitLines(DebugLinesSubsectionRef &Lines,
+ const StringsAndChecksumsRef &State) = 0;
+ virtual Error visitFileChecksums(DebugChecksumsSubsectionRef &Checksums,
+ const StringsAndChecksumsRef &State) = 0;
+ virtual Error visitInlineeLines(DebugInlineeLinesSubsectionRef &Inlinees,
+ const StringsAndChecksumsRef &State) = 0;
+ virtual Error
+ visitCrossModuleExports(DebugCrossModuleExportsSubsectionRef &CSE,
+ const StringsAndChecksumsRef &State) = 0;
+ virtual Error
+ visitCrossModuleImports(DebugCrossModuleImportsSubsectionRef &CSE,
+ const StringsAndChecksumsRef &State) = 0;
+
+ virtual Error visitStringTable(DebugStringTableSubsectionRef &ST,
+ const StringsAndChecksumsRef &State) = 0;
+
+ virtual Error visitSymbols(DebugSymbolsSubsectionRef &CSE,
+ const StringsAndChecksumsRef &State) = 0;
+
+ virtual Error visitFrameData(DebugFrameDataSubsectionRef &FD,
+ const StringsAndChecksumsRef &State) = 0;
+ virtual Error visitCOFFSymbolRVAs(DebugSymbolRVASubsectionRef &RVAs,
+ const StringsAndChecksumsRef &State) = 0;
+};
+
+Error visitDebugSubsection(const DebugSubsectionRecord &R,
+ DebugSubsectionVisitor &V,
+ const StringsAndChecksumsRef &State);
+
+namespace detail {
+template <typename T>
+Error visitDebugSubsections(T &&FragmentRange, DebugSubsectionVisitor &V,
+ StringsAndChecksumsRef &State) {
+ State.initialize(std::forward<T>(FragmentRange));
+
+ for (const DebugSubsectionRecord &L : FragmentRange) {
+ if (auto EC = visitDebugSubsection(L, V, State))
+ return EC;
+ }
+ return Error::success();
+}
+} // namespace detail
+
+template <typename T>
+Error visitDebugSubsections(T &&FragmentRange, DebugSubsectionVisitor &V) {
+ StringsAndChecksumsRef State;
+ return detail::visitDebugSubsections(std::forward<T>(FragmentRange), V,
+ State);
+}
+
+template <typename T>
+Error visitDebugSubsections(T &&FragmentRange, DebugSubsectionVisitor &V,
+ const DebugStringTableSubsectionRef &Strings) {
+ StringsAndChecksumsRef State(Strings);
+ return detail::visitDebugSubsections(std::forward<T>(FragmentRange), V,
+ State);
+}
+
+template <typename T>
+Error visitDebugSubsections(T &&FragmentRange, DebugSubsectionVisitor &V,
+ const DebugStringTableSubsectionRef &Strings,
+ const DebugChecksumsSubsectionRef &Checksums) {
+ StringsAndChecksumsRef State(Strings, Checksums);
+ return detail::visitDebugSubsections(std::forward<T>(FragmentRange), V,
+ State);
+}
+
+} // end namespace codeview
+
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGFRAGMENTVISITOR_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/DebugSymbolRVASubsection.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/DebugSymbolRVASubsection.h
new file mode 100644
index 0000000..a4c04b5
--- /dev/null
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/DebugSymbolRVASubsection.h
@@ -0,0 +1,67 @@
+//===- DebugSymbolRVASubsection.h -------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_CODEVIEW_DEBUGSYMBOLRVASUBSECTION_H
+#define LLVM_DEBUGINFO_CODEVIEW_DEBUGSYMBOLRVASUBSECTION_H
+
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/DebugSubsection.h"
+#include "llvm/Support/BinaryStreamArray.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
+#include <cstdint>
+#include <vector>
+
+namespace llvm {
+
+class BinaryStreamReader;
+
+namespace codeview {
+
+class DebugSymbolRVASubsectionRef final : public DebugSubsectionRef {
+public:
+ using ArrayType = FixedStreamArray<support::ulittle32_t>;
+
+ DebugSymbolRVASubsectionRef();
+
+ static bool classof(const DebugSubsectionRef *S) {
+ return S->kind() == DebugSubsectionKind::CoffSymbolRVA;
+ }
+
+ ArrayType::Iterator begin() const { return RVAs.begin(); }
+ ArrayType::Iterator end() const { return RVAs.end(); }
+
+ Error initialize(BinaryStreamReader &Reader);
+
+private:
+ ArrayType RVAs;
+};
+
+class DebugSymbolRVASubsection final : public DebugSubsection {
+public:
+ DebugSymbolRVASubsection();
+
+ static bool classof(const DebugSubsection *S) {
+ return S->kind() == DebugSubsectionKind::CoffSymbolRVA;
+ }
+
+ Error commit(BinaryStreamWriter &Writer) const override;
+ uint32_t calculateSerializedSize() const override;
+
+ void addRVA(uint32_t RVA) { RVAs.push_back(support::ulittle32_t(RVA)); }
+
+private:
+ std::vector<support::ulittle32_t> RVAs;
+};
+
+} // end namespace codeview
+
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_CODEVIEW_DEBUGSYMBOLRVASUBSECTION_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/DebugSymbolsSubsection.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/DebugSymbolsSubsection.h
new file mode 100644
index 0000000..dfda7de
--- /dev/null
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/DebugSymbolsSubsection.h
@@ -0,0 +1,56 @@
+//===- DebugSymbolsSubsection.h --------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_CODEVIEW_DEBUGSYMBOLSSUBSECTION_H
+#define LLVM_DEBUGINFO_CODEVIEW_DEBUGSYMBOLSSUBSECTION_H
+
+#include "llvm/DebugInfo/CodeView/DebugSubsection.h"
+#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
+#include "llvm/Support/Error.h"
+
+namespace llvm {
+namespace codeview {
+class DebugSymbolsSubsectionRef final : public DebugSubsectionRef {
+public:
+ DebugSymbolsSubsectionRef()
+ : DebugSubsectionRef(DebugSubsectionKind::Symbols) {}
+
+ static bool classof(const DebugSubsectionRef *S) {
+ return S->kind() == DebugSubsectionKind::Symbols;
+ }
+
+ Error initialize(BinaryStreamReader Reader);
+
+ CVSymbolArray::Iterator begin() const { return Records.begin(); }
+ CVSymbolArray::Iterator end() const { return Records.end(); }
+
+private:
+ CVSymbolArray Records;
+};
+
+class DebugSymbolsSubsection final : public DebugSubsection {
+public:
+ DebugSymbolsSubsection() : DebugSubsection(DebugSubsectionKind::Symbols) {}
+ static bool classof(const DebugSubsection *S) {
+ return S->kind() == DebugSubsectionKind::Symbols;
+ }
+
+ uint32_t calculateSerializedSize() const override;
+ Error commit(BinaryStreamWriter &Writer) const override;
+
+ void addSymbol(CVSymbol Symbol);
+
+private:
+ uint32_t Length = 0;
+ std::vector<CVSymbol> Records;
+};
+}
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/DebugUnknownSubsection.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/DebugUnknownSubsection.h
new file mode 100644
index 0000000..ea9a96c
--- /dev/null
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/DebugUnknownSubsection.h
@@ -0,0 +1,32 @@
+//===- DebugUnknownSubsection.h -----------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGUNKNOWNFRAGMENT_H
+#define LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGUNKNOWNFRAGMENT_H
+
+#include "llvm/DebugInfo/CodeView/DebugSubsection.h"
+#include "llvm/Support/BinaryStreamRef.h"
+
+namespace llvm {
+namespace codeview {
+
+class DebugUnknownSubsectionRef final : public DebugSubsectionRef {
+public:
+ DebugUnknownSubsectionRef(DebugSubsectionKind Kind, BinaryStreamRef Data)
+ : DebugSubsectionRef(Kind), Data(Data) {}
+
+ BinaryStreamRef getData() const { return Data; }
+
+private:
+ BinaryStreamRef Data;
+};
+}
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/EnumTables.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/EnumTables.h
index 10d1c58..ee0f0f7 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/EnumTables.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/EnumTables.h
@@ -1,4 +1,4 @@
-//===- EnumTables.h Enum to string conversion tables ------------*- C++ -*-===//
+//===- EnumTables.h - Enum to string conversion tables ----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -11,17 +11,18 @@
#define LLVM_DEBUGINFO_CODEVIEW_ENUMTABLES_H
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/BinaryFormat/COFF.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
-#include "llvm/Support/COFF.h"
#include "llvm/Support/ScopedPrinter.h"
-
-#include <stdint.h>
+#include <cstdint>
namespace llvm {
namespace codeview {
+
ArrayRef<EnumEntry<SymbolKind>> getSymbolTypeNames();
ArrayRef<EnumEntry<TypeLeafKind>> getTypeLeafNames();
ArrayRef<EnumEntry<uint16_t>> getRegisterNames();
+ArrayRef<EnumEntry<uint32_t>> getPublicSymFlagNames();
ArrayRef<EnumEntry<uint8_t>> getProcSymFlagNames();
ArrayRef<EnumEntry<uint16_t>> getLocalFlagNames();
ArrayRef<EnumEntry<uint8_t>> getFrameCookieKindNames();
@@ -37,7 +38,8 @@ ArrayRef<EnumEntry<uint8_t>> getThunkOrdinalNames();
ArrayRef<EnumEntry<uint16_t>> getTrampolineNames();
ArrayRef<EnumEntry<COFF::SectionCharacteristics>>
getImageSectionCharacteristicNames();
-} // namespace codeview
-} // namespace llvm
+
+} // end namespace codeview
+} // end namespace llvm
#endif // LLVM_DEBUGINFO_CODEVIEW_ENUMTABLES_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/Formatters.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/Formatters.h
new file mode 100644
index 0000000..278ad02
--- /dev/null
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/Formatters.h
@@ -0,0 +1,73 @@
+//===- Formatters.h ---------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_CODEVIEW_FORMATTERS_H
+#define LLVM_DEBUGINFO_CODEVIEW_FORMATTERS_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/DebugInfo/CodeView/GUID.h"
+#include "llvm/DebugInfo/CodeView/TypeIndex.h"
+#include "llvm/Support/FormatAdapters.h"
+#include "llvm/Support/FormatVariadic.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cstdint>
+
+namespace llvm {
+
+namespace codeview {
+
+namespace detail {
+
+class GuidAdapter final : public FormatAdapter<ArrayRef<uint8_t>> {
+ ArrayRef<uint8_t> Guid;
+
+public:
+ explicit GuidAdapter(ArrayRef<uint8_t> Guid);
+ explicit GuidAdapter(StringRef Guid);
+
+ void format(raw_ostream &Stream, StringRef Style) override;
+};
+
+} // end namespace detail
+
+inline detail::GuidAdapter fmt_guid(StringRef Item) {
+ return detail::GuidAdapter(Item);
+}
+
+inline detail::GuidAdapter fmt_guid(ArrayRef<uint8_t> Item) {
+ return detail::GuidAdapter(Item);
+}
+
+} // end namespace codeview
+
+template <> struct format_provider<codeview::TypeIndex> {
+public:
+ static void format(const codeview::TypeIndex &V, raw_ostream &Stream,
+ StringRef Style) {
+ if (V.isNoneType())
+ Stream << "<no type>";
+ else {
+ Stream << formatv("{0:X+4}", V.getIndex());
+ if (V.isSimple())
+ Stream << " (" << codeview::TypeIndex::simpleTypeName(V) << ")";
+ }
+ }
+};
+
+template <> struct format_provider<codeview::GUID> {
+ static void format(const codeview::GUID &V, llvm::raw_ostream &Stream,
+ StringRef Style) {
+ Stream << V;
+ }
+};
+
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_CODEVIEW_FORMATTERS_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/GUID.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/GUID.h
new file mode 100644
index 0000000..a055ce9
--- /dev/null
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/GUID.h
@@ -0,0 +1,55 @@
+//===- GUID.h ---------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_CODEVIEW_GUID_H
+#define LLVM_DEBUGINFO_CODEVIEW_GUID_H
+
+#include <cstdint>
+#include <cstring>
+
+namespace llvm {
+class raw_ostream;
+
+namespace codeview {
+
+/// This represents the 'GUID' type from windows.h.
+struct GUID {
+ uint8_t Guid[16];
+};
+
+inline bool operator==(const GUID &LHS, const GUID &RHS) {
+ return 0 == ::memcmp(LHS.Guid, RHS.Guid, sizeof(LHS.Guid));
+}
+
+inline bool operator<(const GUID &LHS, const GUID &RHS) {
+ return ::memcmp(LHS.Guid, RHS.Guid, sizeof(LHS.Guid)) < 0;
+}
+
+inline bool operator<=(const GUID &LHS, const GUID &RHS) {
+ return ::memcmp(LHS.Guid, RHS.Guid, sizeof(LHS.Guid)) <= 0;
+}
+
+inline bool operator>(const GUID &LHS, const GUID &RHS) {
+ return !(LHS <= RHS);
+}
+
+inline bool operator>=(const GUID &LHS, const GUID &RHS) {
+ return !(LHS < RHS);
+}
+
+inline bool operator!=(const GUID &LHS, const GUID &RHS) {
+ return !(LHS == RHS);
+}
+
+raw_ostream &operator<<(raw_ostream &OS, const GUID &Guid);
+
+} // namespace codeview
+} // namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h
new file mode 100644
index 0000000..cc0c243
--- /dev/null
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h
@@ -0,0 +1,113 @@
+//===- LazyRandomTypeCollection.h -------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_CODEVIEW_LAZYRANDOMTYPECOLLECTION_H
+#define LLVM_DEBUGINFO_CODEVIEW_LAZYRANDOMTYPECOLLECTION_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/DebugInfo/CodeView/TypeCollection.h"
+#include "llvm/DebugInfo/CodeView/TypeIndex.h"
+#include "llvm/DebugInfo/CodeView/TypeRecord.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/BinaryStreamArray.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/StringSaver.h"
+#include <cstdint>
+#include <vector>
+
+namespace llvm {
+namespace codeview {
+
+/// \brief Provides amortized O(1) random access to a CodeView type stream.
+/// Normally to access a type from a type stream, you must know its byte
+/// offset into the type stream, because type records are variable-lengthed.
+/// However, this is not the way we prefer to access them. For example, given
+/// a symbol record one of the fields may be the TypeIndex of the symbol's
+/// type record. Or given a type record such as an array type, there might
+/// be a TypeIndex for the element type. Sequential access is perfect when
+/// we're just dumping every entry, but it's very poor for real world usage.
+///
+/// Type streams in PDBs contain an additional field which is a list of pairs
+/// containing indices and their corresponding offsets, roughly every ~8KB of
+/// record data. This general idea need not be confined to PDBs though. By
+/// supplying such an array, the producer of a type stream can allow the
+/// consumer much better access time, because the consumer can find the nearest
+/// index in this array, and do a linear scan forward only from there.
+///
+/// LazyRandomTypeCollection implements this algorithm, but additionally goes
+/// one step further by caching offsets of every record that has been visited at
+/// least once. This way, even repeated visits of the same record will never
+/// require more than one linear scan. For a type stream of N elements divided
+/// into M chunks of roughly equal size, this yields a worst case lookup time
+/// of O(N/M) and an amortized time of O(1).
+class LazyRandomTypeCollection : public TypeCollection {
+ using PartialOffsetArray = FixedStreamArray<TypeIndexOffset>;
+
+ struct CacheEntry {
+ CVType Type;
+ uint32_t Offset;
+ StringRef Name;
+ };
+
+public:
+ explicit LazyRandomTypeCollection(uint32_t RecordCountHint);
+ LazyRandomTypeCollection(StringRef Data, uint32_t RecordCountHint);
+ LazyRandomTypeCollection(ArrayRef<uint8_t> Data, uint32_t RecordCountHint);
+ LazyRandomTypeCollection(const CVTypeArray &Types, uint32_t RecordCountHint,
+ PartialOffsetArray PartialOffsets);
+ LazyRandomTypeCollection(const CVTypeArray &Types, uint32_t RecordCountHint);
+
+ void reset(ArrayRef<uint8_t> Data, uint32_t RecordCountHint);
+ void reset(StringRef Data, uint32_t RecordCountHint);
+
+ uint32_t getOffsetOfType(TypeIndex Index);
+
+ CVType getType(TypeIndex Index) override;
+ StringRef getTypeName(TypeIndex Index) override;
+ bool contains(TypeIndex Index) override;
+ uint32_t size() override;
+ uint32_t capacity() override;
+ Optional<TypeIndex> getFirst() override;
+ Optional<TypeIndex> getNext(TypeIndex Prev) override;
+
+private:
+ Error ensureTypeExists(TypeIndex Index);
+ void ensureCapacityFor(TypeIndex Index);
+
+ Error visitRangeForType(TypeIndex TI);
+ Error fullScanForType(TypeIndex TI);
+ void visitRange(TypeIndex Begin, uint32_t BeginOffset, TypeIndex End);
+
+ /// Number of actual records.
+ uint32_t Count = 0;
+
+ /// The largest type index which we've visited.
+ TypeIndex LargestTypeIndex = TypeIndex::None();
+
+ BumpPtrAllocator Allocator;
+ StringSaver NameStorage;
+
+ /// The type array to allow random access visitation of.
+ CVTypeArray Types;
+
+ std::vector<CacheEntry> Records;
+
+ /// An array of index offsets for the given type stream, allowing log(N)
+ /// lookups of a type record by index. Similar to KnownOffsets but only
+ /// contains offsets for some type indices, some of which may not have
+ /// ever been visited.
+ PartialOffsetArray PartialOffsets;
+};
+
+} // end namespace codeview
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_CODEVIEW_LAZYRANDOMTYPECOLLECTION_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/Line.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/Line.h
index 975b503..ac229c3 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/Line.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/Line.h
@@ -127,27 +127,6 @@ public:
bool isNeverStepInto() const { return LineInf.isNeverStepInto(); }
};
-enum class InlineeLinesSignature : uint32_t {
- Normal, // CV_INLINEE_SOURCE_LINE_SIGNATURE
- ExtraFiles // CV_INLINEE_SOURCE_LINE_SIGNATURE_EX
-};
-
-struct InlineeSourceLine {
- TypeIndex Inlinee; // ID of the function that was inlined.
- ulittle32_t FileID; // Offset into FileChecksums subsection.
- ulittle32_t SourceLineNum; // First line of inlined code.
- // If extra files present:
- // ulittle32_t ExtraFileCount;
- // ulittle32_t Files[];
-};
-
-struct FileChecksum {
- ulittle32_t FileNameOffset; // Byte offset of filename in global string table.
- uint8_t ChecksumSize; // Number of bytes of checksum.
- uint8_t ChecksumKind; // FileChecksumKind
- // Checksum bytes follow.
-};
-
} // namespace codeview
} // namespace llvm
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/ModuleSubstream.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/ModuleSubstream.h
deleted file mode 100644
index 8860ae4..0000000
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/ModuleSubstream.h
+++ /dev/null
@@ -1,89 +0,0 @@
-//===- ModuleSubstream.h ----------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_DEBUGINFO_CODEVIEW_MODULESUBSTREAM_H
-#define LLVM_DEBUGINFO_CODEVIEW_MODULESUBSTREAM_H
-
-#include "llvm/DebugInfo/CodeView/CodeView.h"
-#include "llvm/DebugInfo/MSF/StreamArray.h"
-#include "llvm/DebugInfo/MSF/StreamRef.h"
-#include "llvm/Support/Endian.h"
-#include "llvm/Support/Error.h"
-
-namespace llvm {
-namespace codeview {
-
-// Corresponds to the `CV_DebugSSubsectionHeader_t` structure.
-struct ModuleSubsectionHeader {
- support::ulittle32_t Kind; // codeview::ModuleSubstreamKind enum
- support::ulittle32_t Length; // number of bytes occupied by this record.
-};
-
-// Corresponds to the `CV_DebugSLinesHeader_t` structure.
-struct LineSubstreamHeader {
- support::ulittle32_t RelocOffset; // Code offset of line contribution.
- support::ulittle16_t RelocSegment; // Code segment of line contribution.
- support::ulittle16_t Flags; // See LineFlags enumeration.
- support::ulittle32_t CodeSize; // Code size of this line contribution.
-};
-
-// Corresponds to the `CV_DebugSLinesFileBlockHeader_t` structure.
-struct LineFileBlockHeader {
- support::ulittle32_t NameIndex; // Index in DBI name buffer of filename.
- support::ulittle32_t NumLines; // Number of lines
- support::ulittle32_t BlockSize; // Code size of block, in bytes.
- // The following two variable length arrays appear immediately after the
- // header. The structure definitions follow.
- // LineNumberEntry Lines[NumLines];
- // ColumnNumberEntry Columns[NumLines];
-};
-
-// Corresponds to `CV_Line_t` structure
-struct LineNumberEntry {
- support::ulittle32_t Offset; // Offset to start of code bytes for line number
- support::ulittle32_t Flags; // Start:24, End:7, IsStatement:1
-};
-
-// Corresponds to `CV_Column_t` structure
-struct ColumnNumberEntry {
- support::ulittle16_t StartColumn;
- support::ulittle16_t EndColumn;
-};
-
-class ModuleSubstream {
-public:
- ModuleSubstream();
- ModuleSubstream(ModuleSubstreamKind Kind, msf::ReadableStreamRef Data);
- static Error initialize(msf::ReadableStreamRef Stream, ModuleSubstream &Info);
- uint32_t getRecordLength() const;
- ModuleSubstreamKind getSubstreamKind() const;
- msf::ReadableStreamRef getRecordData() const;
-
-private:
- ModuleSubstreamKind Kind;
- msf::ReadableStreamRef Data;
-};
-
-typedef msf::VarStreamArray<ModuleSubstream> ModuleSubstreamArray;
-} // namespace codeview
-
-namespace msf {
-template <> struct VarStreamArrayExtractor<codeview::ModuleSubstream> {
- Error operator()(ReadableStreamRef Stream, uint32_t &Length,
- codeview::ModuleSubstream &Info) const {
- if (auto EC = codeview::ModuleSubstream::initialize(Stream, Info))
- return EC;
- Length = Info.getRecordLength();
- return Error::success();
- }
-};
-} // namespace msf
-} // namespace llvm
-
-#endif // LLVM_DEBUGINFO_CODEVIEW_MODULESUBSTREAM_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/ModuleSubstreamVisitor.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/ModuleSubstreamVisitor.h
deleted file mode 100644
index f9927d6..0000000
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/ModuleSubstreamVisitor.h
+++ /dev/null
@@ -1,136 +0,0 @@
-//===- ModuleSubstreamVisitor.h ---------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_DEBUGINFO_CODEVIEW_MODULESUBSTREAMVISITOR_H
-#define LLVM_DEBUGINFO_CODEVIEW_MODULESUBSTREAMVISITOR_H
-
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/DebugInfo/CodeView/CodeView.h"
-#include "llvm/DebugInfo/CodeView/CodeViewError.h"
-#include "llvm/DebugInfo/CodeView/Line.h"
-#include "llvm/DebugInfo/CodeView/ModuleSubstream.h"
-#include "llvm/DebugInfo/MSF/StreamArray.h"
-#include "llvm/DebugInfo/MSF/StreamReader.h"
-#include "llvm/DebugInfo/MSF/StreamRef.h"
-#include "llvm/Support/Endian.h"
-#include "llvm/Support/Error.h"
-#include <cstdint>
-
-namespace llvm {
-
-namespace codeview {
-
-struct LineColumnEntry {
- support::ulittle32_t NameIndex;
- msf::FixedStreamArray<LineNumberEntry> LineNumbers;
- msf::FixedStreamArray<ColumnNumberEntry> Columns;
-};
-
-struct FileChecksumEntry {
- uint32_t FileNameOffset; // Byte offset of filename in global stringtable.
- FileChecksumKind Kind; // The type of checksum.
- ArrayRef<uint8_t> Checksum; // The bytes of the checksum.
-};
-
-typedef msf::VarStreamArray<LineColumnEntry> LineInfoArray;
-typedef msf::VarStreamArray<FileChecksumEntry> FileChecksumArray;
-
-class IModuleSubstreamVisitor {
-public:
- virtual ~IModuleSubstreamVisitor() = default;
-
- virtual Error visitUnknown(ModuleSubstreamKind Kind,
- msf::ReadableStreamRef Data) = 0;
- virtual Error visitSymbols(msf::ReadableStreamRef Data);
- virtual Error visitLines(msf::ReadableStreamRef Data,
- const LineSubstreamHeader *Header,
- const LineInfoArray &Lines);
- virtual Error visitStringTable(msf::ReadableStreamRef Data);
- virtual Error visitFileChecksums(msf::ReadableStreamRef Data,
- const FileChecksumArray &Checksums);
- virtual Error visitFrameData(msf::ReadableStreamRef Data);
- virtual Error visitInlineeLines(msf::ReadableStreamRef Data);
- virtual Error visitCrossScopeImports(msf::ReadableStreamRef Data);
- virtual Error visitCrossScopeExports(msf::ReadableStreamRef Data);
- virtual Error visitILLines(msf::ReadableStreamRef Data);
- virtual Error visitFuncMDTokenMap(msf::ReadableStreamRef Data);
- virtual Error visitTypeMDTokenMap(msf::ReadableStreamRef Data);
- virtual Error visitMergedAssemblyInput(msf::ReadableStreamRef Data);
- virtual Error visitCoffSymbolRVA(msf::ReadableStreamRef Data);
-};
-
-Error visitModuleSubstream(const ModuleSubstream &R,
- IModuleSubstreamVisitor &V);
-} // end namespace codeview
-
-namespace msf {
-
-template <> class VarStreamArrayExtractor<codeview::LineColumnEntry> {
-public:
- VarStreamArrayExtractor(const codeview::LineSubstreamHeader *Header)
- : Header(Header) {}
-
- Error operator()(ReadableStreamRef Stream, uint32_t &Len,
- codeview::LineColumnEntry &Item) const {
- using namespace codeview;
- const LineFileBlockHeader *BlockHeader;
- StreamReader Reader(Stream);
- if (auto EC = Reader.readObject(BlockHeader))
- return EC;
- bool HasColumn = Header->Flags & LineFlags::HaveColumns;
- uint32_t LineInfoSize =
- BlockHeader->NumLines *
- (sizeof(LineNumberEntry) + (HasColumn ? sizeof(ColumnNumberEntry) : 0));
- if (BlockHeader->BlockSize < sizeof(LineFileBlockHeader))
- return make_error<CodeViewError>(cv_error_code::corrupt_record,
- "Invalid line block record size");
- uint32_t Size = BlockHeader->BlockSize - sizeof(LineFileBlockHeader);
- if (LineInfoSize > Size)
- return make_error<CodeViewError>(cv_error_code::corrupt_record,
- "Invalid line block record size");
- // The value recorded in BlockHeader->BlockSize includes the size of
- // LineFileBlockHeader.
- Len = BlockHeader->BlockSize;
- Item.NameIndex = BlockHeader->NameIndex;
- if (auto EC = Reader.readArray(Item.LineNumbers, BlockHeader->NumLines))
- return EC;
- if (HasColumn) {
- if (auto EC = Reader.readArray(Item.Columns, BlockHeader->NumLines))
- return EC;
- }
- return Error::success();
- }
-
-private:
- const codeview::LineSubstreamHeader *Header;
-};
-
-template <> class VarStreamArrayExtractor<codeview::FileChecksumEntry> {
-public:
- Error operator()(ReadableStreamRef Stream, uint32_t &Len,
- codeview::FileChecksumEntry &Item) const {
- using namespace codeview;
- const FileChecksum *Header;
- StreamReader Reader(Stream);
- if (auto EC = Reader.readObject(Header))
- return EC;
- Item.FileNameOffset = Header->FileNameOffset;
- Item.Kind = static_cast<FileChecksumKind>(Header->ChecksumKind);
- if (auto EC = Reader.readBytes(Item.Checksum, Header->ChecksumSize))
- return EC;
- Len = sizeof(FileChecksum) + Header->ChecksumSize;
- return Error::success();
- }
-};
-
-} // end namespace msf
-
-} // end namespace llvm
-
-#endif // LLVM_DEBUGINFO_CODEVIEW_MODULESUBSTREAMVISITOR_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/RecordSerialization.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/RecordSerialization.h
index 97b6f56..58449c2 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/RecordSerialization.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/RecordSerialization.h
@@ -15,7 +15,7 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/DebugInfo/CodeView/CodeViewError.h"
-#include "llvm/DebugInfo/MSF/StreamReader.h"
+#include "llvm/Support/BinaryStreamReader.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/Error.h"
#include <cinttypes>
@@ -41,37 +41,37 @@ struct RecordPrefix {
StringRef getBytesAsCharacters(ArrayRef<uint8_t> LeafData);
StringRef getBytesAsCString(ArrayRef<uint8_t> LeafData);
-inline Error consume(msf::StreamReader &Reader) { return Error::success(); }
+inline Error consume(BinaryStreamReader &Reader) { return Error::success(); }
/// Decodes a numeric "leaf" value. These are integer literals encountered in
/// the type stream. If the value is positive and less than LF_NUMERIC (1 <<
/// 15), it is emitted directly in Data. Otherwise, it has a tag like LF_CHAR
/// that indicates the bitwidth and sign of the numeric data.
-Error consume(msf::StreamReader &Reader, APSInt &Num);
+Error consume(BinaryStreamReader &Reader, APSInt &Num);
/// Decodes a numeric leaf value that is known to be a particular type.
-Error consume_numeric(msf::StreamReader &Reader, uint64_t &Value);
+Error consume_numeric(BinaryStreamReader &Reader, uint64_t &Value);
/// Decodes signed and unsigned fixed-length integers.
-Error consume(msf::StreamReader &Reader, uint32_t &Item);
-Error consume(msf::StreamReader &Reader, int32_t &Item);
+Error consume(BinaryStreamReader &Reader, uint32_t &Item);
+Error consume(BinaryStreamReader &Reader, int32_t &Item);
/// Decodes a null terminated string.
-Error consume(msf::StreamReader &Reader, StringRef &Item);
+Error consume(BinaryStreamReader &Reader, StringRef &Item);
Error consume(StringRef &Data, APSInt &Num);
Error consume(StringRef &Data, uint32_t &Item);
/// Decodes an arbitrary object whose layout matches that of the underlying
/// byte sequence, and returns a pointer to the object.
-template <typename T> Error consume(msf::StreamReader &Reader, T *&Item) {
+template <typename T> Error consume(BinaryStreamReader &Reader, T *&Item) {
return Reader.readObject(Item);
}
template <typename T, typename U> struct serialize_conditional_impl {
serialize_conditional_impl(T &Item, U Func) : Item(Item), Func(Func) {}
- Error deserialize(msf::StreamReader &Reader) const {
+ Error deserialize(BinaryStreamReader &Reader) const {
if (!Func())
return Error::success();
return consume(Reader, Item);
@@ -89,7 +89,7 @@ serialize_conditional_impl<T, U> serialize_conditional(T &Item, U Func) {
template <typename T, typename U> struct serialize_array_impl {
serialize_array_impl(ArrayRef<T> &Item, U Func) : Item(Item), Func(Func) {}
- Error deserialize(msf::StreamReader &Reader) const {
+ Error deserialize(BinaryStreamReader &Reader) const {
return Reader.readArray(Item, Func());
}
@@ -100,7 +100,7 @@ template <typename T, typename U> struct serialize_array_impl {
template <typename T> struct serialize_vector_tail_impl {
serialize_vector_tail_impl(std::vector<T> &Item) : Item(Item) {}
- Error deserialize(msf::StreamReader &Reader) const {
+ Error deserialize(BinaryStreamReader &Reader) const {
T Field;
// Stop when we run out of bytes or we hit record padding bytes.
while (!Reader.empty() && Reader.peek() < LF_PAD0) {
@@ -118,14 +118,14 @@ struct serialize_null_term_string_array_impl {
serialize_null_term_string_array_impl(std::vector<StringRef> &Item)
: Item(Item) {}
- Error deserialize(msf::StreamReader &Reader) const {
+ Error deserialize(BinaryStreamReader &Reader) const {
if (Reader.empty())
return make_error<CodeViewError>(cv_error_code::insufficient_buffer,
"Null terminated string is empty!");
while (Reader.peek() != 0) {
StringRef Field;
- if (auto EC = Reader.readZeroString(Field))
+ if (auto EC = Reader.readCString(Field))
return EC;
Item.push_back(Field);
}
@@ -138,7 +138,7 @@ struct serialize_null_term_string_array_impl {
template <typename T> struct serialize_arrayref_tail_impl {
serialize_arrayref_tail_impl(ArrayRef<T> &Item) : Item(Item) {}
- Error deserialize(msf::StreamReader &Reader) const {
+ Error deserialize(BinaryStreamReader &Reader) const {
uint32_t Count = Reader.bytesRemaining() / sizeof(T);
return Reader.readArray(Item, Count);
}
@@ -149,7 +149,7 @@ template <typename T> struct serialize_arrayref_tail_impl {
template <typename T> struct serialize_numeric_impl {
serialize_numeric_impl(T &Item) : Item(Item) {}
- Error deserialize(msf::StreamReader &Reader) const {
+ Error deserialize(BinaryStreamReader &Reader) const {
return consume_numeric(Reader, Item);
}
@@ -201,42 +201,42 @@ template <typename T> serialize_numeric_impl<T> serialize_numeric(T &Item) {
#define CV_NUMERIC_FIELD(I) serialize_numeric(I)
template <typename T, typename U>
-Error consume(msf::StreamReader &Reader,
+Error consume(BinaryStreamReader &Reader,
const serialize_conditional_impl<T, U> &Item) {
return Item.deserialize(Reader);
}
template <typename T, typename U>
-Error consume(msf::StreamReader &Reader,
+Error consume(BinaryStreamReader &Reader,
const serialize_array_impl<T, U> &Item) {
return Item.deserialize(Reader);
}
-inline Error consume(msf::StreamReader &Reader,
+inline Error consume(BinaryStreamReader &Reader,
const serialize_null_term_string_array_impl &Item) {
return Item.deserialize(Reader);
}
template <typename T>
-Error consume(msf::StreamReader &Reader,
+Error consume(BinaryStreamReader &Reader,
const serialize_vector_tail_impl<T> &Item) {
return Item.deserialize(Reader);
}
template <typename T>
-Error consume(msf::StreamReader &Reader,
+Error consume(BinaryStreamReader &Reader,
const serialize_arrayref_tail_impl<T> &Item) {
return Item.deserialize(Reader);
}
template <typename T>
-Error consume(msf::StreamReader &Reader,
+Error consume(BinaryStreamReader &Reader,
const serialize_numeric_impl<T> &Item) {
return Item.deserialize(Reader);
}
template <typename T, typename U, typename... Args>
-Error consume(msf::StreamReader &Reader, T &&X, U &&Y, Args &&... Rest) {
+Error consume(BinaryStreamReader &Reader, T &&X, U &&Y, Args &&... Rest) {
if (auto EC = consume(Reader, X))
return EC;
return consume(Reader, Y, std::forward<Args>(Rest)...);
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/StringsAndChecksums.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/StringsAndChecksums.h
new file mode 100644
index 0000000..1a83882
--- /dev/null
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/StringsAndChecksums.h
@@ -0,0 +1,102 @@
+//===- StringsAndChecksums.h ------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_CODEVIEW_STRINGSANDCHECKSUMS_H
+#define LLVM_DEBUGINFO_CODEVIEW_STRINGSANDCHECKSUMS_H
+
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h"
+#include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h"
+#include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h"
+#include <memory>
+
+namespace llvm {
+namespace codeview {
+
+class StringsAndChecksumsRef {
+public:
+ // If no subsections are known about initially, we find as much as we can.
+ StringsAndChecksumsRef();
+
+ // If only a string table subsection is given, we find a checksums subsection.
+ explicit StringsAndChecksumsRef(const DebugStringTableSubsectionRef &Strings);
+
+ // If both subsections are given, we don't need to find anything.
+ StringsAndChecksumsRef(const DebugStringTableSubsectionRef &Strings,
+ const DebugChecksumsSubsectionRef &Checksums);
+
+ void setChecksums(const DebugChecksumsSubsectionRef &CS);
+
+ template <typename T> void initialize(T &&FragmentRange) {
+ for (const DebugSubsectionRecord &R : FragmentRange) {
+ if (Strings && Checksums)
+ return;
+ if (R.kind() == DebugSubsectionKind::FileChecksums) {
+ initializeChecksums(R);
+ continue;
+ }
+ if (R.kind() == DebugSubsectionKind::StringTable && !Strings) {
+ // While in practice we should never encounter a string table even
+ // though the string table is already initialized, in theory it's
+ // possible. PDBs are supposed to have one global string table and
+ // then this subsection should not appear. Whereas object files are
+ // supposed to have this subsection appear exactly once. However,
+ // for testing purposes it's nice to be able to test this subsection
+ // independently of one format or the other, so for some tests we
+ // manually construct a PDB that contains this subsection in addition
+ // to a global string table.
+ initializeStrings(R);
+ continue;
+ }
+ }
+ }
+
+ const DebugStringTableSubsectionRef &strings() const { return *Strings; }
+ const DebugChecksumsSubsectionRef &checksums() const { return *Checksums; }
+
+ bool hasStrings() const { return Strings != nullptr; }
+ bool hasChecksums() const { return Checksums != nullptr; }
+
+private:
+ void initializeStrings(const DebugSubsectionRecord &SR);
+ void initializeChecksums(const DebugSubsectionRecord &FCR);
+
+ std::unique_ptr<DebugStringTableSubsectionRef> OwnedStrings;
+ std::unique_ptr<DebugChecksumsSubsectionRef> OwnedChecksums;
+
+ const DebugStringTableSubsectionRef *Strings = nullptr;
+ const DebugChecksumsSubsectionRef *Checksums = nullptr;
+};
+
+class StringsAndChecksums {
+public:
+ using StringsPtr = std::shared_ptr<DebugStringTableSubsection>;
+ using ChecksumsPtr = std::shared_ptr<DebugChecksumsSubsection>;
+
+ // If no subsections are known about initially, we find as much as we can.
+ StringsAndChecksums() = default;
+
+ void setStrings(const StringsPtr &SP) { Strings = SP; }
+ void setChecksums(const ChecksumsPtr &CP) { Checksums = CP; }
+
+ const StringsPtr &strings() const { return Strings; }
+ const ChecksumsPtr &checksums() const { return Checksums; }
+
+ bool hasStrings() const { return Strings != nullptr; }
+ bool hasChecksums() const { return Checksums != nullptr; }
+
+private:
+ StringsPtr Strings;
+ ChecksumsPtr Checksums;
+};
+
+} // end namespace codeview
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_CODEVIEW_STRINGSANDCHECKSUMS_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolDeserializer.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolDeserializer.h
index 13c2bb1..5b6599d 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolDeserializer.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolDeserializer.h
@@ -15,8 +15,8 @@
#include "llvm/DebugInfo/CodeView/SymbolRecordMapping.h"
#include "llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h"
#include "llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h"
-#include "llvm/DebugInfo/MSF/ByteStream.h"
-#include "llvm/DebugInfo/MSF/StreamReader.h"
+#include "llvm/Support/BinaryByteStream.h"
+#include "llvm/Support/BinaryStreamReader.h"
#include "llvm/Support/Error.h"
namespace llvm {
@@ -24,21 +24,40 @@ namespace codeview {
class SymbolVisitorDelegate;
class SymbolDeserializer : public SymbolVisitorCallbacks {
struct MappingInfo {
- explicit MappingInfo(ArrayRef<uint8_t> RecordData)
- : Stream(RecordData), Reader(Stream), Mapping(Reader) {}
+ MappingInfo(ArrayRef<uint8_t> RecordData, CodeViewContainer Container)
+ : Stream(RecordData, llvm::support::little), Reader(Stream),
+ Mapping(Reader, Container) {}
- msf::ByteStream Stream;
- msf::StreamReader Reader;
+ BinaryByteStream Stream;
+ BinaryStreamReader Reader;
SymbolRecordMapping Mapping;
};
public:
- explicit SymbolDeserializer(SymbolVisitorDelegate *Delegate)
- : Delegate(Delegate) {}
+ template <typename T> static Error deserializeAs(CVSymbol Symbol, T &Record) {
+ // If we're just deserializing one record, then don't worry about alignment
+ // as there's nothing that comes after.
+ SymbolDeserializer S(nullptr, CodeViewContainer::ObjectFile);
+ if (auto EC = S.visitSymbolBegin(Symbol))
+ return EC;
+ if (auto EC = S.visitKnownRecord(Symbol, Record))
+ return EC;
+ if (auto EC = S.visitSymbolEnd(Symbol))
+ return EC;
+ return Error::success();
+ }
+
+ explicit SymbolDeserializer(SymbolVisitorDelegate *Delegate,
+ CodeViewContainer Container)
+ : Delegate(Delegate), Container(Container) {}
+
+ Error visitSymbolBegin(CVSymbol &Record, uint32_t Offset) override {
+ return visitSymbolBegin(Record);
+ }
Error visitSymbolBegin(CVSymbol &Record) override {
assert(!Mapping && "Already in a symbol mapping!");
- Mapping = llvm::make_unique<MappingInfo>(Record.content());
+ Mapping = llvm::make_unique<MappingInfo>(Record.content(), Container);
return Mapping->Mapping.visitSymbolBegin(Record);
}
Error visitSymbolEnd(CVSymbol &Record) override {
@@ -53,7 +72,7 @@ public:
return visitKnownRecordImpl(CVR, Record); \
}
#define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
-#include "CVSymbolTypes.def"
+#include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
private:
template <typename T> Error visitKnownRecordImpl(CVSymbol &CVR, T &Record) {
@@ -66,6 +85,7 @@ private:
}
SymbolVisitorDelegate *Delegate;
+ CodeViewContainer Container;
std::unique_ptr<MappingInfo> Mapping;
};
}
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolDumper.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolDumper.h
index a5419b3..293daa8 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolDumper.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolDumper.h
@@ -20,15 +20,17 @@ namespace llvm {
class ScopedPrinter;
namespace codeview {
-class TypeDatabase;
+class TypeCollection;
/// Dumper for CodeView symbol streams found in COFF object files and PDB files.
class CVSymbolDumper {
public:
- CVSymbolDumper(ScopedPrinter &W, TypeDatabase &TypeDB,
+ CVSymbolDumper(ScopedPrinter &W, TypeCollection &Types,
+ CodeViewContainer Container,
std::unique_ptr<SymbolDumpDelegate> ObjDelegate,
bool PrintRecordBytes)
- : W(W), TypeDB(TypeDB), ObjDelegate(std::move(ObjDelegate)),
+ : W(W), Types(Types), Container(Container),
+ ObjDelegate(std::move(ObjDelegate)),
PrintRecordBytes(PrintRecordBytes) {}
/// Dumps one type record. Returns false if there was a type parsing error,
@@ -43,7 +45,8 @@ public:
private:
ScopedPrinter &W;
- TypeDatabase &TypeDB;
+ TypeCollection &Types;
+ CodeViewContainer Container;
std::unique_ptr<SymbolDumpDelegate> ObjDelegate;
bool PrintRecordBytes;
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolRecord.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolRecord.h
index 57772d3..f3086cf 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolRecord.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolRecord.h
@@ -13,16 +13,14 @@
#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/Optional.h"
-#include "llvm/ADT/iterator_range.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/iterator_range.h"
#include "llvm/DebugInfo/CodeView/CVRecord.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/DebugInfo/CodeView/RecordSerialization.h"
#include "llvm/DebugInfo/CodeView/TypeIndex.h"
-#include "llvm/DebugInfo/MSF/StreamArray.h"
+#include "llvm/Support/BinaryStreamArray.h"
#include "llvm/Support/Endian.h"
-#include "llvm/Support/Error.h"
-#include <cstddef>
#include <cstdint>
#include <vector>
@@ -36,7 +34,6 @@ protected:
public:
SymbolRecordKind getKind() const { return Kind; }
-private:
SymbolRecordKind Kind;
};
@@ -155,6 +152,7 @@ public:
: SymbolRecord(Kind), RecordOffset(RecordOffset) {}
std::vector<TypeIndex> Indices;
+
uint32_t RecordOffset;
};
@@ -167,8 +165,8 @@ struct BinaryAnnotationIterator {
int32_t S1;
};
- BinaryAnnotationIterator(ArrayRef<uint8_t> Annotations) : Data(Annotations) {}
BinaryAnnotationIterator() = default;
+ BinaryAnnotationIterator(ArrayRef<uint8_t> Annotations) : Data(Annotations) {}
BinaryAnnotationIterator(const BinaryAnnotationIterator &Other)
: Data(Other.Data) {}
@@ -176,7 +174,7 @@ struct BinaryAnnotationIterator {
return Data == Other.Data;
}
- bool operator!=(BinaryAnnotationIterator Other) const {
+ bool operator!=(const BinaryAnnotationIterator &Other) const {
return !(*this == Other);
}
@@ -344,9 +342,9 @@ public:
: SymbolRecord(SymbolRecordKind::InlineSiteSym),
RecordOffset(RecordOffset) {}
- llvm::iterator_range<BinaryAnnotationIterator> annotations() const {
- return llvm::make_range(BinaryAnnotationIterator(AnnotationData),
- BinaryAnnotationIterator());
+ iterator_range<BinaryAnnotationIterator> annotations() const {
+ return make_range(BinaryAnnotationIterator(AnnotationData),
+ BinaryAnnotationIterator());
}
uint32_t Parent;
@@ -365,7 +363,7 @@ public:
: SymbolRecord(SymbolRecordKind::PublicSym32),
RecordOffset(RecordOffset) {}
- uint32_t Index;
+ PublicSymFlags Flags;
uint32_t Offset;
uint16_t Segment;
StringRef Name;
@@ -381,7 +379,7 @@ public:
: SymbolRecord(SymbolRecordKind::RegisterSym),
RecordOffset(RecordOffset) {}
- uint32_t Index;
+ TypeIndex Index;
RegisterId Register;
StringRef Name;
@@ -481,6 +479,7 @@ public:
ulittle16_t Register;
ulittle16_t MayHaveNoName;
};
+
explicit DefRangeRegisterSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
DefRangeRegisterSym(uint32_t RecordOffset)
: SymbolRecord(SymbolRecordKind::DefRangeRegisterSym),
@@ -503,6 +502,7 @@ public:
ulittle16_t MayHaveNoName;
ulittle32_t OffsetInParent;
};
+
explicit DefRangeSubfieldRegisterSym(SymbolRecordKind Kind)
: SymbolRecord(Kind) {}
DefRangeSubfieldRegisterSym(uint32_t RecordOffset)
@@ -548,6 +548,7 @@ public:
ulittle16_t Flags;
little32_t BasePointerOffset;
};
+
explicit DefRangeRegisterRelSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
explicit DefRangeRegisterRelSym(uint32_t RecordOffset)
: SymbolRecord(SymbolRecordKind::DefRangeRegisterRelSym),
@@ -681,7 +682,7 @@ public:
: SymbolRecord(SymbolRecordKind::FileStaticSym),
RecordOffset(RecordOffset) {}
- uint32_t Index;
+ TypeIndex Index;
uint32_t ModFilenameOffset;
LocalSymFlags Flags;
StringRef Name;
@@ -734,6 +735,10 @@ public:
uint16_t VersionBackendQFE;
StringRef Version;
+ void setLanguage(SourceLanguage Lang) {
+ Flags = CompileSym3Flags((uint32_t(Flags) & 0xFFFFFF00) | uint32_t(Lang));
+ }
+
uint8_t getLanguage() const { return static_cast<uint32_t>(Flags) & 0xFF; }
uint32_t getFlags() const { return static_cast<uint32_t>(Flags) & ~0xFF; }
@@ -816,7 +821,7 @@ public:
uint32_t CodeOffset;
uint16_t Register;
- uint8_t CookieKind;
+ FrameCookieKind CookieKind;
uint8_t Flags;
uint32_t RecordOffset;
@@ -843,7 +848,7 @@ public:
: SymbolRecord(SymbolRecordKind::BuildInfoSym),
RecordOffset(RecordOffset) {}
- uint32_t BuildId;
+ TypeIndex BuildId;
uint32_t RecordOffset;
};
@@ -873,7 +878,7 @@ public:
uint32_t Offset;
TypeIndex Type;
- uint16_t Register;
+ RegisterId Register;
StringRef Name;
uint32_t RecordOffset;
@@ -937,8 +942,8 @@ public:
uint32_t RecordOffset;
};
-typedef CVRecord<SymbolKind> CVSymbol;
-typedef msf::VarStreamArray<CVSymbol> CVSymbolArray;
+using CVSymbol = CVRecord<SymbolKind>;
+using CVSymbolArray = VarStreamArray<CVSymbol>;
} // end namespace codeview
} // end namespace llvm
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolRecordMapping.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolRecordMapping.h
index 1bd14ed..391e8f1 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolRecordMapping.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolRecordMapping.h
@@ -14,16 +14,18 @@
#include "llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h"
namespace llvm {
-namespace msf {
-class StreamReader;
-class StreamWriter;
-}
+class BinaryStreamReader;
+class BinaryStreamWriter;
namespace codeview {
class SymbolRecordMapping : public SymbolVisitorCallbacks {
public:
- explicit SymbolRecordMapping(msf::StreamReader &Reader) : IO(Reader) {}
- explicit SymbolRecordMapping(msf::StreamWriter &Writer) : IO(Writer) {}
+ explicit SymbolRecordMapping(BinaryStreamReader &Reader,
+ CodeViewContainer Container)
+ : IO(Reader), Container(Container) {}
+ explicit SymbolRecordMapping(BinaryStreamWriter &Writer,
+ CodeViewContainer Container)
+ : IO(Writer), Container(Container) {}
Error visitSymbolBegin(CVSymbol &Record) override;
Error visitSymbolEnd(CVSymbol &Record) override;
@@ -31,12 +33,13 @@ public:
#define SYMBOL_RECORD(EnumName, EnumVal, Name) \
Error visitKnownRecord(CVSymbol &CVR, Name &Record) override;
#define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
-#include "CVSymbolTypes.def"
+#include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
private:
Optional<SymbolKind> Kind;
CodeViewRecordIO IO;
+ CodeViewContainer Container;
};
}
}
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolSerializer.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolSerializer.h
index 4eb914e..b63ced5 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolSerializer.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolSerializer.h
@@ -1,4 +1,4 @@
-//===- symbolSerializer.h ---------------------------------------*- C++ -*-===//
+//===- SymbolSerializer.h ---------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -10,25 +10,27 @@
#ifndef LLVM_DEBUGINFO_CODEVIEW_SYMBOLSERIALIZER_H
#define LLVM_DEBUGINFO_CODEVIEW_SYMBOLSERIALIZER_H
+#include "llvm/ADT/Optional.h"
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/RecordSerialization.h"
+#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
#include "llvm/DebugInfo/CodeView/SymbolRecordMapping.h"
#include "llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h"
-#include "llvm/DebugInfo/MSF/ByteStream.h"
-#include "llvm/DebugInfo/MSF/StreamWriter.h"
-
-#include "llvm/ADT/Optional.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringMap.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/iterator_range.h"
#include "llvm/Support/Allocator.h"
+#include "llvm/Support/BinaryByteStream.h"
+#include "llvm/Support/BinaryStreamWriter.h"
#include "llvm/Support/Error.h"
+#include <cstdint>
+#include <vector>
namespace llvm {
namespace codeview {
class SymbolSerializer : public SymbolVisitorCallbacks {
- uint32_t RecordStart = 0;
- msf::StreamWriter &Writer;
+ BumpPtrAllocator &Storage;
+ std::vector<uint8_t> RecordBuffer;
+ MutableBinaryByteStream Stream;
+ BinaryStreamWriter Writer;
SymbolRecordMapping Mapping;
Optional<SymbolKind> CurrentSymbol;
@@ -42,47 +44,29 @@ class SymbolSerializer : public SymbolVisitorCallbacks {
}
public:
- explicit SymbolSerializer(msf::StreamWriter &Writer)
- : Writer(Writer), Mapping(Writer) {}
-
- virtual Error visitSymbolBegin(CVSymbol &Record) override {
- assert(!CurrentSymbol.hasValue() && "Already in a symbol mapping!");
-
- RecordStart = Writer.getOffset();
- if (auto EC = writeRecordPrefix(Record.kind()))
- return EC;
-
- CurrentSymbol = Record.kind();
- if (auto EC = Mapping.visitSymbolBegin(Record))
- return EC;
-
- return Error::success();
+ SymbolSerializer(BumpPtrAllocator &Storage, CodeViewContainer Container);
+
+ template <typename SymType>
+ static CVSymbol writeOneSymbol(SymType &Sym, BumpPtrAllocator &Storage,
+ CodeViewContainer Container) {
+ CVSymbol Result;
+ Result.Type = static_cast<SymbolKind>(Sym.Kind);
+ SymbolSerializer Serializer(Storage, Container);
+ consumeError(Serializer.visitSymbolBegin(Result));
+ consumeError(Serializer.visitKnownRecord(Result, Sym));
+ consumeError(Serializer.visitSymbolEnd(Result));
+ return Result;
}
- virtual Error visitSymbolEnd(CVSymbol &Record) override {
- assert(CurrentSymbol.hasValue() && "Not in a symbol mapping!");
-
- if (auto EC = Mapping.visitSymbolEnd(Record))
- return EC;
-
- uint32_t RecordEnd = Writer.getOffset();
- Writer.setOffset(RecordStart);
- uint16_t Length = RecordEnd - Writer.getOffset() - 2;
- if (auto EC = Writer.writeInteger(Length))
- return EC;
-
- Writer.setOffset(RecordEnd);
- CurrentSymbol.reset();
-
- return Error::success();
- }
+ Error visitSymbolBegin(CVSymbol &Record) override;
+ Error visitSymbolEnd(CVSymbol &Record) override;
#define SYMBOL_RECORD(EnumName, EnumVal, Name) \
- virtual Error visitKnownRecord(CVSymbol &CVR, Name &Record) override { \
+ Error visitKnownRecord(CVSymbol &CVR, Name &Record) override { \
return visitKnownRecordImpl(CVR, Record); \
}
#define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
-#include "CVSymbolTypes.def"
+#include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
private:
template <typename RecordKind>
@@ -90,7 +74,8 @@ private:
return Mapping.visitKnownRecord(CVR, Record);
}
};
-}
-}
-#endif
+} // end namespace codeview
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_CODEVIEW_SYMBOLSERIALIZER_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolVisitorCallbackPipeline.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolVisitorCallbackPipeline.h
index 96a93bf..e29511a 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolVisitorCallbackPipeline.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolVisitorCallbackPipeline.h
@@ -30,6 +30,14 @@ public:
return Error::success();
}
+ Error visitSymbolBegin(CVSymbol &Record, uint32_t Offset) override {
+ for (auto Visitor : Pipeline) {
+ if (auto EC = Visitor->visitSymbolBegin(Record, Offset))
+ return EC;
+ }
+ return Error::success();
+ }
+
Error visitSymbolBegin(CVSymbol &Record) override {
for (auto Visitor : Pipeline) {
if (auto EC = Visitor->visitSymbolBegin(Record))
@@ -59,7 +67,7 @@ public:
return Error::success(); \
}
#define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
-#include "llvm/DebugInfo/CodeView/CVSymbolTypes.def"
+#include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
private:
std::vector<SymbolVisitorCallbacks *> Pipeline;
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h
index aaa9d2e..0816f7c 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h
@@ -29,8 +29,10 @@ public:
/// Paired begin/end actions for all symbols. Receives all record data,
/// including the fixed-length record prefix. visitSymbolBegin() should
- /// return
- /// the type of the Symbol, or an error if it cannot be determined.
+ /// return the type of the Symbol, or an error if it cannot be determined.
+ virtual Error visitSymbolBegin(CVSymbol &Record, uint32_t Offset) {
+ return Error::success();
+ }
virtual Error visitSymbolBegin(CVSymbol &Record) { return Error::success(); }
virtual Error visitSymbolEnd(CVSymbol &Record) { return Error::success(); }
@@ -39,7 +41,7 @@ public:
return Error::success(); \
}
#define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
-#include "CVSymbolTypes.def"
+#include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
};
} // end namespace codeview
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h
index 2b468a2..a2a3c6f 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h
@@ -15,19 +15,19 @@
namespace llvm {
-namespace msf {
-class StreamReader;
-} // end namespace msf
+class BinaryStreamReader;
namespace codeview {
+class DebugStringTableSubsectionRef;
+
class SymbolVisitorDelegate {
public:
virtual ~SymbolVisitorDelegate() = default;
- virtual uint32_t getRecordOffset(msf::StreamReader Reader) = 0;
+ virtual uint32_t getRecordOffset(BinaryStreamReader Reader) = 0;
virtual StringRef getFileNameForFileOffset(uint32_t FileOffset) = 0;
- virtual StringRef getStringTable() = 0;
+ virtual DebugStringTableSubsectionRef getStringTable() = 0;
};
} // end namespace codeview
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeCollection.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeCollection.h
new file mode 100644
index 0000000..0f856f5
--- /dev/null
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeCollection.h
@@ -0,0 +1,38 @@
+//===- TypeCollection.h - A collection of CodeView type records -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_CODEVIEW_TYPECOLLECTION_H
+#define LLVM_DEBUGINFO_CODEVIEW_TYPECOLLECTION_H
+
+#include "llvm/ADT/StringRef.h"
+
+#include "llvm/DebugInfo/CodeView/TypeIndex.h"
+#include "llvm/DebugInfo/CodeView/TypeRecord.h"
+
+namespace llvm {
+namespace codeview {
+class TypeCollection {
+public:
+ virtual ~TypeCollection() = default;
+
+ bool empty() { return size() == 0; }
+
+ virtual Optional<TypeIndex> getFirst() = 0;
+ virtual Optional<TypeIndex> getNext(TypeIndex Prev) = 0;
+
+ virtual CVType getType(TypeIndex Index) = 0;
+ virtual StringRef getTypeName(TypeIndex Index) = 0;
+ virtual bool contains(TypeIndex Index) = 0;
+ virtual uint32_t size() = 0;
+ virtual uint32_t capacity() = 0;
+};
+}
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeDatabase.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeDatabase.h
deleted file mode 100644
index cccc286..0000000
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeDatabase.h
+++ /dev/null
@@ -1,55 +0,0 @@
-//===- TypeDatabase.h - A collection of CodeView type records ---*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_DEBUGINFO_CODEVIEW_TYPEDATABASE_H
-#define LLVM_DEBUGINFO_CODEVIEW_TYPEDATABASE_H
-
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/DebugInfo/CodeView/TypeIndex.h"
-#include "llvm/DebugInfo/CodeView/TypeRecord.h"
-#include "llvm/Support/Allocator.h"
-#include "llvm/Support/StringSaver.h"
-
-namespace llvm {
-namespace codeview {
-class TypeDatabase {
-public:
- TypeDatabase() : TypeNameStorage(Allocator) {}
-
- /// Gets the type index for the next type record.
- TypeIndex getNextTypeIndex() const;
-
- /// Records the name of a type, and reserves its type index.
- void recordType(StringRef Name, CVType Data);
-
- /// Saves the name in a StringSet and creates a stable StringRef.
- StringRef saveTypeName(StringRef TypeName);
-
- StringRef getTypeName(TypeIndex Index) const;
-
- bool containsTypeIndex(TypeIndex Index) const;
-
- uint32_t size() const;
-
-private:
- BumpPtrAllocator Allocator;
-
- /// All user defined type records in .debug$T live in here. Type indices
- /// greater than 0x1000 are user defined. Subtract 0x1000 from the index to
- /// index into this vector.
- SmallVector<StringRef, 10> CVUDTNames;
- SmallVector<CVType, 10> TypeRecords;
-
- StringSaver TypeNameStorage;
-};
-}
-}
-
-#endif \ No newline at end of file
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeDatabaseVisitor.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeDatabaseVisitor.h
deleted file mode 100644
index 39d234c..0000000
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeDatabaseVisitor.h
+++ /dev/null
@@ -1,53 +0,0 @@
-//===-- TypeDatabaseVisitor.h -----------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_DEBUGINFO_CODEVIEW_TYPEDATABASEVISITOR_H
-#define LLVM_DEBUGINFO_CODEVIEW_TYPEDATABASEVISITOR_H
-
-#include "llvm/DebugInfo/CodeView/TypeDatabase.h"
-#include "llvm/DebugInfo/CodeView/TypeIndex.h"
-#include "llvm/DebugInfo/CodeView/TypeRecord.h"
-#include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
-
-namespace llvm {
-namespace codeview {
-
-/// Dumper for CodeView type streams found in COFF object files and PDB files.
-class TypeDatabaseVisitor : public TypeVisitorCallbacks {
-public:
- explicit TypeDatabaseVisitor(TypeDatabase &TypeDB) : TypeDB(TypeDB) {}
-
- /// Paired begin/end actions for all types. Receives all record data,
- /// including the fixed-length record prefix.
- Error visitTypeBegin(CVType &Record) override;
- Error visitTypeEnd(CVType &Record) override;
- Error visitMemberBegin(CVMemberRecord &Record) override;
- Error visitMemberEnd(CVMemberRecord &Record) override;
-
-#define TYPE_RECORD(EnumName, EnumVal, Name) \
- Error visitKnownRecord(CVType &CVR, Name##Record &Record) override;
-#define MEMBER_RECORD(EnumName, EnumVal, Name) \
- Error visitKnownMember(CVMemberRecord &CVR, Name##Record &Record) override;
-#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
-#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
-#include "TypeRecords.def"
-
-private:
- bool IsInFieldList = false;
-
- /// Name of the current type. Only valid before visitTypeEnd.
- StringRef Name;
-
- TypeDatabase &TypeDB;
-};
-
-} // end namespace codeview
-} // end namespace llvm
-
-#endif // LLVM_DEBUGINFO_CODEVIEW_TYPEDUMPER_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeDeserializer.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeDeserializer.h
index dc5eaf8..965cdfd 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeDeserializer.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeDeserializer.h
@@ -16,8 +16,8 @@
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
#include "llvm/DebugInfo/CodeView/TypeRecordMapping.h"
#include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
-#include "llvm/DebugInfo/MSF/ByteStream.h"
-#include "llvm/DebugInfo/MSF/StreamReader.h"
+#include "llvm/Support/BinaryByteStream.h"
+#include "llvm/Support/BinaryStreamReader.h"
#include "llvm/Support/Error.h"
#include <cassert>
#include <cstdint>
@@ -29,22 +29,39 @@ namespace codeview {
class TypeDeserializer : public TypeVisitorCallbacks {
struct MappingInfo {
explicit MappingInfo(ArrayRef<uint8_t> RecordData)
- : Stream(RecordData), Reader(Stream), Mapping(Reader) {}
+ : Stream(RecordData, llvm::support::little), Reader(Stream),
+ Mapping(Reader) {}
- msf::ByteStream Stream;
- msf::StreamReader Reader;
+ BinaryByteStream Stream;
+ BinaryStreamReader Reader;
TypeRecordMapping Mapping;
};
public:
TypeDeserializer() = default;
+ template <typename T> static Error deserializeAs(CVType &CVT, T &Record) {
+ Record.Kind = static_cast<TypeRecordKind>(CVT.kind());
+ MappingInfo I(CVT.content());
+ if (auto EC = I.Mapping.visitTypeBegin(CVT))
+ return EC;
+ if (auto EC = I.Mapping.visitKnownRecord(CVT, Record))
+ return EC;
+ if (auto EC = I.Mapping.visitTypeEnd(CVT))
+ return EC;
+ return Error::success();
+ }
+
Error visitTypeBegin(CVType &Record) override {
assert(!Mapping && "Already in a type mapping!");
Mapping = llvm::make_unique<MappingInfo>(Record.content());
return Mapping->Mapping.visitTypeBegin(Record);
}
+ Error visitTypeBegin(CVType &Record, TypeIndex Index) override {
+ return visitTypeBegin(Record);
+ }
+
Error visitTypeEnd(CVType &Record) override {
assert(Mapping && "Not in a type mapping!");
auto EC = Mapping->Mapping.visitTypeEnd(Record);
@@ -59,7 +76,7 @@ public:
#define MEMBER_RECORD(EnumName, EnumVal, Name)
#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
-#include "TypeRecords.def"
+#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
private:
template <typename RecordType>
@@ -72,16 +89,16 @@ private:
class FieldListDeserializer : public TypeVisitorCallbacks {
struct MappingInfo {
- explicit MappingInfo(msf::StreamReader &R)
+ explicit MappingInfo(BinaryStreamReader &R)
: Reader(R), Mapping(Reader), StartOffset(0) {}
- msf::StreamReader &Reader;
+ BinaryStreamReader &Reader;
TypeRecordMapping Mapping;
uint32_t StartOffset;
};
public:
- explicit FieldListDeserializer(msf::StreamReader &Reader) : Mapping(Reader) {
+ explicit FieldListDeserializer(BinaryStreamReader &Reader) : Mapping(Reader) {
CVType FieldList;
FieldList.Type = TypeLeafKind::LF_FIELDLIST;
consumeError(Mapping.Mapping.visitTypeBegin(FieldList));
@@ -111,7 +128,7 @@ public:
}
#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
-#include "TypeRecords.def"
+#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
private:
template <typename RecordType>
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeDumpVisitor.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeDumpVisitor.h
index a466e42..afb8b36 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeDumpVisitor.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeDumpVisitor.h
@@ -12,7 +12,6 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringSet.h"
-#include "llvm/DebugInfo/CodeView/TypeDatabase.h"
#include "llvm/DebugInfo/CodeView/TypeIndex.h"
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
#include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
@@ -22,14 +21,25 @@ class ScopedPrinter;
namespace codeview {
+class TypeCollection;
+
/// Dumper for CodeView type streams found in COFF object files and PDB files.
class TypeDumpVisitor : public TypeVisitorCallbacks {
public:
- TypeDumpVisitor(TypeDatabase &TypeDB, ScopedPrinter *W, bool PrintRecordBytes)
- : W(W), PrintRecordBytes(PrintRecordBytes), TypeDB(TypeDB) {}
+ TypeDumpVisitor(TypeCollection &TpiTypes, ScopedPrinter *W,
+ bool PrintRecordBytes)
+ : W(W), PrintRecordBytes(PrintRecordBytes), TpiTypes(TpiTypes) {}
+
+ /// When dumping types from an IPI stream in a PDB, a type index may refer to
+ /// a type or an item ID. The dumper will lookup the "name" of the index in
+ /// the item database if appropriate. If ItemDB is null, it will use TypeDB,
+ /// which is correct when dumping types from an object file (/Z7).
+ void setIpiTypes(TypeCollection &Types) { IpiTypes = &Types; }
void printTypeIndex(StringRef FieldName, TypeIndex TI) const;
+ void printItemIndex(StringRef FieldName, TypeIndex TI) const;
+
/// Action to take on unknown types. By default, they are ignored.
Error visitUnknownType(CVType &Record) override;
Error visitUnknownMember(CVMemberRecord &Record) override;
@@ -37,6 +47,7 @@ public:
/// Paired begin/end actions for all types. Receives all record data,
/// including the fixed-length record prefix.
Error visitTypeBegin(CVType &Record) override;
+ Error visitTypeBegin(CVType &Record, TypeIndex Index) override;
Error visitTypeEnd(CVType &Record) override;
Error visitMemberBegin(CVMemberRecord &Record) override;
Error visitMemberEnd(CVMemberRecord &Record) override;
@@ -47,18 +58,26 @@ public:
Error visitKnownMember(CVMemberRecord &CVR, Name##Record &Record) override;
#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
-#include "TypeRecords.def"
+#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
private:
void printMemberAttributes(MemberAttributes Attrs);
void printMemberAttributes(MemberAccess Access, MethodKind Kind,
MethodOptions Options);
+ /// Get the database of indices for the stream that we are dumping. If ItemDB
+ /// is set, then we must be dumping an item (IPI) stream. This will also
+ /// always get the appropriate DB for printing item names.
+ TypeCollection &getSourceTypes() const {
+ return IpiTypes ? *IpiTypes : TpiTypes;
+ }
+
ScopedPrinter *W;
bool PrintRecordBytes = false;
- TypeDatabase &TypeDB;
+ TypeCollection &TpiTypes;
+ TypeCollection *IpiTypes = nullptr;
};
} // end namespace codeview
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeDumperBase.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeDumperBase.h
deleted file mode 100644
index e69de29..0000000
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeDumperBase.h
+++ /dev/null
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeIndex.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeIndex.h
index 3c11d24..e0c2226 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeIndex.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeIndex.h
@@ -10,13 +10,20 @@
#ifndef LLVM_DEBUGINFO_CODEVIEW_TYPEINDEX_H
#define LLVM_DEBUGINFO_CODEVIEW_TYPEINDEX_H
+#include "llvm/ADT/DenseMapInfo.h"
#include "llvm/Support/Endian.h"
#include <cassert>
#include <cinttypes>
+#include <functional>
namespace llvm {
+
+class ScopedPrinter;
+
namespace codeview {
+class TypeCollection;
+
enum class SimpleTypeKind : uint32_t {
None = 0x0000, // uncharacterized type (no type)
Void = 0x0003, // void
@@ -106,6 +113,15 @@ public:
bool isNoneType() const { return *this == None(); }
+ uint32_t toArrayIndex() const {
+ assert(!isSimple());
+ return getIndex() - FirstNonSimpleIndex;
+ }
+
+ static TypeIndex fromArrayIndex(uint32_t Index) {
+ return TypeIndex(Index + FirstNonSimpleIndex);
+ }
+
SimpleTypeKind getSimpleKind() const {
assert(isSimple());
return static_cast<SimpleTypeKind>(Index & SimpleKindMask);
@@ -159,6 +175,39 @@ public:
static TypeIndex Float32() { return TypeIndex(SimpleTypeKind::Float32); }
static TypeIndex Float64() { return TypeIndex(SimpleTypeKind::Float64); }
+ TypeIndex &operator+=(unsigned N) {
+ Index += N;
+ return *this;
+ }
+
+ TypeIndex &operator++() {
+ Index += 1;
+ return *this;
+ }
+
+ TypeIndex operator++(int) {
+ TypeIndex Copy = *this;
+ operator++();
+ return Copy;
+ }
+
+ TypeIndex &operator-=(unsigned N) {
+ assert(Index >= N);
+ Index -= N;
+ return *this;
+ }
+
+ TypeIndex &operator--() {
+ Index -= 1;
+ return *this;
+ }
+
+ TypeIndex operator--(int) {
+ TypeIndex Copy = *this;
+ operator--();
+ return Copy;
+ }
+
friend inline bool operator==(const TypeIndex &A, const TypeIndex &B) {
return A.getIndex() == B.getIndex();
}
@@ -183,11 +232,58 @@ public:
return A.getIndex() >= B.getIndex();
}
+ friend inline TypeIndex operator+(const TypeIndex &A, uint32_t N) {
+ TypeIndex Result(A);
+ Result += N;
+ return Result;
+ }
+
+ friend inline TypeIndex operator-(const TypeIndex &A, uint32_t N) {
+ assert(A.getIndex() >= N);
+ TypeIndex Result(A);
+ Result -= N;
+ return Result;
+ }
+
+ friend inline uint32_t operator-(const TypeIndex &A, const TypeIndex &B) {
+ assert(A >= B);
+ return A.toArrayIndex() - B.toArrayIndex();
+ }
+
+ static StringRef simpleTypeName(TypeIndex TI);
+
private:
support::ulittle32_t Index;
};
+// Used for pseudo-indexing an array of type records. An array of such records
+// sorted by TypeIndex can allow log(N) lookups even though such a type record
+// stream does not provide random access.
+struct TypeIndexOffset {
+ TypeIndex Type;
+ support::ulittle32_t Offset;
+};
+
+void printTypeIndex(ScopedPrinter &Printer, StringRef FieldName, TypeIndex TI,
+ TypeCollection &Types);
}
-}
+
+template <> struct DenseMapInfo<codeview::TypeIndex> {
+ static inline codeview::TypeIndex getEmptyKey() {
+ return codeview::TypeIndex{DenseMapInfo<uint32_t>::getEmptyKey()};
+ }
+ static inline codeview::TypeIndex getTombstoneKey() {
+ return codeview::TypeIndex{DenseMapInfo<uint32_t>::getTombstoneKey()};
+ }
+ static unsigned getHashValue(const codeview::TypeIndex &TI) {
+ return DenseMapInfo<uint32_t>::getHashValue(TI.getIndex());
+ }
+ static bool isEqual(const codeview::TypeIndex &LHS,
+ const codeview::TypeIndex &RHS) {
+ return LHS == RHS;
+ }
+};
+
+} // namespace llvm
#endif
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeIndexDiscovery.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeIndexDiscovery.h
new file mode 100644
index 0000000..afe8942
--- /dev/null
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeIndexDiscovery.h
@@ -0,0 +1,41 @@
+//===- TypeIndexDiscovery.h -------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_CODEVIEW_TYPEINDEXDISCOVERY_H
+#define LLVM_DEBUGINFO_CODEVIEW_TYPEINDEXDISCOVERY_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
+#include "llvm/DebugInfo/CodeView/TypeRecord.h"
+#include "llvm/Support/Error.h"
+
+namespace llvm {
+namespace codeview {
+enum class TiRefKind { TypeRef, IndexRef };
+struct TiReference {
+ TiRefKind Kind;
+ uint32_t Offset;
+ uint32_t Count;
+};
+
+void discoverTypeIndices(ArrayRef<uint8_t> RecordData,
+ SmallVectorImpl<TiReference> &Refs);
+void discoverTypeIndices(const CVType &Type,
+ SmallVectorImpl<TiReference> &Refs);
+void discoverTypeIndices(const CVType &Type,
+ SmallVectorImpl<TypeIndex> &Indices);
+
+/// Discover type indices in symbol records. Returns false if this is an unknown
+/// record.
+bool discoverTypeIndices(const CVSymbol &Symbol,
+ SmallVectorImpl<TiReference> &Refs);
+}
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeName.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeName.h
new file mode 100644
index 0000000..a987b4a
--- /dev/null
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeName.h
@@ -0,0 +1,22 @@
+//===- TypeName.h --------------------------------------------- *- C++ --*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_CODEVIEW_TYPENAME_H
+#define LLVM_DEBUGINFO_CODEVIEW_TYPENAME_H
+
+#include "llvm/DebugInfo/CodeView/TypeCollection.h"
+#include "llvm/DebugInfo/CodeView/TypeIndex.h"
+
+namespace llvm {
+namespace codeview {
+std::string computeTypeName(TypeCollection &Types, TypeIndex Index);
+}
+} // namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeRecord.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeRecord.h
index 4f1c047..7942c0c 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeRecord.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeRecord.h
@@ -15,41 +15,42 @@
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/iterator_range.h"
#include "llvm/DebugInfo/CodeView/CVRecord.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/GUID.h"
#include "llvm/DebugInfo/CodeView/TypeIndex.h"
-#include "llvm/DebugInfo/MSF/StreamArray.h"
+#include "llvm/Support/BinaryStreamArray.h"
#include "llvm/Support/Endian.h"
#include <algorithm>
#include <cstdint>
#include <vector>
namespace llvm {
-
-namespace msf {
-class StreamReader;
-} // end namespace msf
-
namespace codeview {
using support::little32_t;
using support::ulittle16_t;
using support::ulittle32_t;
-typedef CVRecord<TypeLeafKind> CVType;
+using CVType = CVRecord<TypeLeafKind>;
+using RemappedType = RemappedRecord<TypeLeafKind>;
struct CVMemberRecord {
TypeLeafKind Kind;
ArrayRef<uint8_t> Data;
};
-typedef msf::VarStreamArray<CVType> CVTypeArray;
+using CVTypeArray = VarStreamArray<CVType>;
+using CVTypeRange = iterator_range<CVTypeArray::Iterator>;
/// Equvalent to CV_fldattr_t in cvinfo.h.
struct MemberAttributes {
uint16_t Attrs = 0;
+
enum {
MethodKindShift = 2,
};
+
MemberAttributes() = default;
explicit MemberAttributes(MemberAccess Access)
@@ -106,10 +107,6 @@ public:
PointerToMemberRepresentation Representation)
: ContainingType(ContainingType), Representation(Representation) {}
- /// Rewrite member type indices with IndexMap. Returns false if a type index
- /// is not in the map.
- bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
-
TypeIndex getContainingType() const { return ContainingType; }
PointerToMemberRepresentation getRepresentation() const {
return Representation;
@@ -127,22 +124,18 @@ protected:
public:
TypeRecordKind getKind() const { return Kind; }
-private:
TypeRecordKind Kind;
};
// LF_MODIFIER
class ModifierRecord : public TypeRecord {
public:
+ ModifierRecord() = default;
explicit ModifierRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
ModifierRecord(TypeIndex ModifiedType, ModifierOptions Modifiers)
: TypeRecord(TypeRecordKind::Modifier), ModifiedType(ModifiedType),
Modifiers(Modifiers) {}
- /// Rewrite member type indices with IndexMap. Returns false if a type index
- /// is not in the map.
- bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
-
TypeIndex getModifiedType() const { return ModifiedType; }
ModifierOptions getModifiers() const { return Modifiers; }
@@ -153,6 +146,7 @@ public:
// LF_PROCEDURE
class ProcedureRecord : public TypeRecord {
public:
+ ProcedureRecord() = default;
explicit ProcedureRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
ProcedureRecord(TypeIndex ReturnType, CallingConvention CallConv,
FunctionOptions Options, uint16_t ParameterCount,
@@ -161,10 +155,6 @@ public:
CallConv(CallConv), Options(Options), ParameterCount(ParameterCount),
ArgumentList(ArgumentList) {}
- /// Rewrite member type indices with IndexMap. Returns false if a type index
- /// is not in the map.
- bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
-
TypeIndex getReturnType() const { return ReturnType; }
CallingConvention getCallConv() const { return CallConv; }
FunctionOptions getOptions() const { return Options; }
@@ -181,6 +171,7 @@ public:
// LF_MFUNCTION
class MemberFunctionRecord : public TypeRecord {
public:
+ MemberFunctionRecord() = default;
explicit MemberFunctionRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
MemberFunctionRecord(TypeIndex ReturnType, TypeIndex ClassType,
@@ -193,10 +184,6 @@ public:
ArgumentList(ArgumentList),
ThisPointerAdjustment(ThisPointerAdjustment) {}
- /// Rewrite member type indices with IndexMap. Returns false if a type index
- /// is not in the map.
- bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
-
TypeIndex getReturnType() const { return ReturnType; }
TypeIndex getClassType() const { return ClassType; }
TypeIndex getThisType() const { return ThisType; }
@@ -216,38 +203,58 @@ public:
int32_t ThisPointerAdjustment;
};
+// LF_LABEL
+class LabelRecord : public TypeRecord {
+public:
+ LabelRecord() = default;
+ explicit LabelRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
+
+ LabelRecord(LabelType Mode) : TypeRecord(TypeRecordKind::Label), Mode(Mode) {}
+
+ LabelType Mode;
+};
+
// LF_MFUNC_ID
class MemberFuncIdRecord : public TypeRecord {
public:
+ MemberFuncIdRecord() = default;
explicit MemberFuncIdRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
MemberFuncIdRecord(TypeIndex ClassType, TypeIndex FunctionType,
StringRef Name)
: TypeRecord(TypeRecordKind::MemberFuncId), ClassType(ClassType),
FunctionType(FunctionType), Name(Name) {}
- /// Rewrite member type indices with IndexMap. Returns false if a type index
- /// is not in the map.
- bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
-
TypeIndex getClassType() const { return ClassType; }
TypeIndex getFunctionType() const { return FunctionType; }
StringRef getName() const { return Name; }
+
TypeIndex ClassType;
TypeIndex FunctionType;
StringRef Name;
};
-// LF_ARGLIST, LF_SUBSTR_LIST
+// LF_ARGLIST
class ArgListRecord : public TypeRecord {
public:
+ ArgListRecord() = default;
explicit ArgListRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
ArgListRecord(TypeRecordKind Kind, ArrayRef<TypeIndex> Indices)
- : TypeRecord(Kind), StringIndices(Indices) {}
+ : TypeRecord(Kind), ArgIndices(Indices) {}
- /// Rewrite member type indices with IndexMap. Returns false if a type index
- /// is not in the map.
- bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
+ ArrayRef<TypeIndex> getIndices() const { return ArgIndices; }
+
+ std::vector<TypeIndex> ArgIndices;
+};
+
+// LF_SUBSTR_LIST
+class StringListRecord : public TypeRecord {
+public:
+ StringListRecord() = default;
+ explicit StringListRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
+
+ StringListRecord(TypeRecordKind Kind, ArrayRef<TypeIndex> Indices)
+ : TypeRecord(Kind), StringIndices(Indices) {}
ArrayRef<TypeIndex> getIndices() const { return StringIndices; }
@@ -268,6 +275,7 @@ public:
static const uint32_t PointerSizeShift = 13;
static const uint32_t PointerSizeMask = 0xFF;
+ PointerRecord() = default;
explicit PointerRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
PointerRecord(TypeIndex ReferentType, uint32_t Attrs)
@@ -280,19 +288,9 @@ public:
Attrs(calcAttrs(PK, PM, PO, Size)) {}
PointerRecord(TypeIndex ReferentType, PointerKind PK, PointerMode PM,
- PointerOptions PO, uint8_t Size,
- const MemberPointerInfo &Member)
- : TypeRecord(TypeRecordKind::Pointer), ReferentType(ReferentType),
- Attrs(calcAttrs(PK, PM, PO, Size)), MemberInfo(Member) {}
-
- PointerRecord(TypeIndex ReferentType, uint32_t Attrs,
- const MemberPointerInfo &Member)
+ PointerOptions PO, uint8_t Size, const MemberPointerInfo &MPI)
: TypeRecord(TypeRecordKind::Pointer), ReferentType(ReferentType),
- Attrs(Attrs), MemberInfo(Member) {}
-
- /// Rewrite member type indices with IndexMap. Returns false if a type index
- /// is not in the map.
- bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
+ Attrs(calcAttrs(PK, PM, PO, Size)), MemberInfo(MPI) {}
TypeIndex getReferentType() const { return ReferentType; }
@@ -334,7 +332,6 @@ public:
TypeIndex ReferentType;
uint32_t Attrs;
-
Optional<MemberPointerInfo> MemberInfo;
private:
@@ -352,14 +349,11 @@ private:
// LF_NESTTYPE
class NestedTypeRecord : public TypeRecord {
public:
+ NestedTypeRecord() = default;
explicit NestedTypeRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
NestedTypeRecord(TypeIndex Type, StringRef Name)
: TypeRecord(TypeRecordKind::NestedType), Type(Type), Name(Name) {}
- /// Rewrite member type indices with IndexMap. Returns false if a type index
- /// is not in the map.
- bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
-
TypeIndex getNestedType() const { return Type; }
StringRef getName() const { return Name; }
@@ -370,30 +364,24 @@ public:
// LF_FIELDLIST
class FieldListRecord : public TypeRecord {
public:
+ FieldListRecord() = default;
explicit FieldListRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
explicit FieldListRecord(ArrayRef<uint8_t> Data)
: TypeRecord(TypeRecordKind::FieldList), Data(Data) {}
- /// Rewrite member type indices with IndexMap. Returns false if a type index
- /// is not in the map.
- bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap) { return false; }
-
ArrayRef<uint8_t> Data;
};
// LF_ARRAY
class ArrayRecord : public TypeRecord {
public:
+ ArrayRecord() = default;
explicit ArrayRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
ArrayRecord(TypeIndex ElementType, TypeIndex IndexType, uint64_t Size,
StringRef Name)
: TypeRecord(TypeRecordKind::Array), ElementType(ElementType),
IndexType(IndexType), Size(Size), Name(Name) {}
- /// Rewrite member type indices with IndexMap. Returns false if a type index
- /// is not in the map.
- bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
-
TypeIndex getElementType() const { return ElementType; }
TypeIndex getIndexType() const { return IndexType; }
uint64_t getSize() const { return Size; }
@@ -407,6 +395,7 @@ public:
class TagRecord : public TypeRecord {
protected:
+ TagRecord() = default;
explicit TagRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
TagRecord(TypeRecordKind Kind, uint16_t MemberCount, ClassOptions Options,
TypeIndex FieldList, StringRef Name, StringRef UniqueName)
@@ -414,10 +403,6 @@ protected:
FieldList(FieldList), Name(Name), UniqueName(UniqueName) {}
public:
- /// Rewrite member type indices with IndexMap. Returns false if a type index
- /// is not in the map.
- bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
-
static const int HfaKindShift = 11;
static const int HfaKindMask = 0x1800;
static const int WinRTKindShift = 14;
@@ -443,6 +428,7 @@ public:
// LF_CLASS, LF_STRUCTURE, LF_INTERFACE
class ClassRecord : public TagRecord {
public:
+ ClassRecord() = default;
explicit ClassRecord(TypeRecordKind Kind) : TagRecord(Kind) {}
ClassRecord(TypeRecordKind Kind, uint16_t MemberCount, ClassOptions Options,
TypeIndex FieldList, TypeIndex DerivationList,
@@ -451,10 +437,6 @@ public:
: TagRecord(Kind, MemberCount, Options, FieldList, Name, UniqueName),
DerivationList(DerivationList), VTableShape(VTableShape), Size(Size) {}
- /// Rewrite member type indices with IndexMap. Returns false if a type index
- /// is not in the map.
- bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
-
HfaKind getHfa() const {
uint16_t Value = static_cast<uint16_t>(Options);
Value = (Value & HfaKindMask) >> HfaKindShift;
@@ -478,6 +460,7 @@ public:
// LF_UNION
struct UnionRecord : public TagRecord {
+ UnionRecord() = default;
explicit UnionRecord(TypeRecordKind Kind) : TagRecord(Kind) {}
UnionRecord(uint16_t MemberCount, ClassOptions Options, TypeIndex FieldList,
uint64_t Size, StringRef Name, StringRef UniqueName)
@@ -499,6 +482,7 @@ struct UnionRecord : public TagRecord {
// LF_ENUM
class EnumRecord : public TagRecord {
public:
+ EnumRecord() = default;
explicit EnumRecord(TypeRecordKind Kind) : TagRecord(Kind) {}
EnumRecord(uint16_t MemberCount, ClassOptions Options, TypeIndex FieldList,
StringRef Name, StringRef UniqueName, TypeIndex UnderlyingType)
@@ -506,28 +490,24 @@ public:
UniqueName),
UnderlyingType(UnderlyingType) {}
- /// Rewrite member type indices with IndexMap. Returns false if a type index is not in the map.
- bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
-
TypeIndex getUnderlyingType() const { return UnderlyingType; }
+
TypeIndex UnderlyingType;
};
// LF_BITFIELD
class BitFieldRecord : public TypeRecord {
public:
+ BitFieldRecord() = default;
explicit BitFieldRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
BitFieldRecord(TypeIndex Type, uint8_t BitSize, uint8_t BitOffset)
: TypeRecord(TypeRecordKind::BitField), Type(Type), BitSize(BitSize),
BitOffset(BitOffset) {}
- /// Rewrite member type indices with IndexMap. Returns false if a type index
- /// is not in the map.
- bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
-
TypeIndex getType() const { return Type; }
uint8_t getBitOffset() const { return BitOffset; }
uint8_t getBitSize() const { return BitSize; }
+
TypeIndex Type;
uint8_t BitSize;
uint8_t BitOffset;
@@ -536,16 +516,13 @@ public:
// LF_VTSHAPE
class VFTableShapeRecord : public TypeRecord {
public:
+ VFTableShapeRecord() = default;
explicit VFTableShapeRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
explicit VFTableShapeRecord(ArrayRef<VFTableSlotKind> Slots)
: TypeRecord(TypeRecordKind::VFTableShape), SlotsRef(Slots) {}
explicit VFTableShapeRecord(std::vector<VFTableSlotKind> Slots)
: TypeRecord(TypeRecordKind::VFTableShape), Slots(std::move(Slots)) {}
- /// Rewrite member type indices with IndexMap. Returns false if a type index
- /// is not in the map.
- bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
-
ArrayRef<VFTableSlotKind> getSlots() const {
if (!SlotsRef.empty())
return SlotsRef;
@@ -553,6 +530,7 @@ public:
}
uint32_t getEntryCount() const { return getSlots().size(); }
+
ArrayRef<VFTableSlotKind> SlotsRef;
std::vector<VFTableSlotKind> Slots;
};
@@ -560,22 +538,19 @@ public:
// LF_TYPESERVER2
class TypeServer2Record : public TypeRecord {
public:
+ TypeServer2Record() = default;
explicit TypeServer2Record(TypeRecordKind Kind) : TypeRecord(Kind) {}
- TypeServer2Record(StringRef Guid, uint32_t Age, StringRef Name)
- : TypeRecord(TypeRecordKind::TypeServer2), Guid(Guid), Age(Age),
- Name(Name) {}
-
- /// Rewrite member type indices with IndexMap. Returns false if a type index
- /// is not in the map.
- bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
-
- StringRef getGuid() const { return Guid; }
+ TypeServer2Record(StringRef GuidStr, uint32_t Age, StringRef Name)
+ : TypeRecord(TypeRecordKind::TypeServer2), Age(Age), Name(Name) {
+ assert(GuidStr.size() == 16 && "guid isn't 16 bytes");
+ ::memcpy(Guid.Guid, GuidStr.data(), 16);
+ }
+ const GUID &getGuid() const { return Guid; }
uint32_t getAge() const { return Age; }
-
StringRef getName() const { return Name; }
- StringRef Guid;
+ GUID Guid;
uint32_t Age;
StringRef Name;
};
@@ -583,17 +558,14 @@ public:
// LF_STRING_ID
class StringIdRecord : public TypeRecord {
public:
+ StringIdRecord() = default;
explicit StringIdRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
StringIdRecord(TypeIndex Id, StringRef String)
: TypeRecord(TypeRecordKind::StringId), Id(Id), String(String) {}
- /// Rewrite member type indices with IndexMap. Returns false if a type index
- /// is not in the map.
- bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
-
TypeIndex getId() const { return Id; }
-
StringRef getString() const { return String; }
+
TypeIndex Id;
StringRef String;
};
@@ -601,19 +573,14 @@ public:
// LF_FUNC_ID
class FuncIdRecord : public TypeRecord {
public:
+ FuncIdRecord() = default;
explicit FuncIdRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
FuncIdRecord(TypeIndex ParentScope, TypeIndex FunctionType, StringRef Name)
: TypeRecord(TypeRecordKind::FuncId), ParentScope(ParentScope),
FunctionType(FunctionType), Name(Name) {}
- /// Rewrite member type indices with IndexMap. Returns false if a type index
- /// is not in the map.
- bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
-
TypeIndex getParentScope() const { return ParentScope; }
-
TypeIndex getFunctionType() const { return FunctionType; }
-
StringRef getName() const { return Name; }
TypeIndex ParentScope;
@@ -624,15 +591,12 @@ public:
// LF_UDT_SRC_LINE
class UdtSourceLineRecord : public TypeRecord {
public:
+ UdtSourceLineRecord() = default;
explicit UdtSourceLineRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
UdtSourceLineRecord(TypeIndex UDT, TypeIndex SourceFile, uint32_t LineNumber)
: TypeRecord(TypeRecordKind::UdtSourceLine), UDT(UDT),
SourceFile(SourceFile), LineNumber(LineNumber) {}
- /// Rewrite member type indices with IndexMap. Returns false if a type index
- /// is not in the map.
- bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
-
TypeIndex getUDT() const { return UDT; }
TypeIndex getSourceFile() const { return SourceFile; }
uint32_t getLineNumber() const { return LineNumber; }
@@ -645,14 +609,13 @@ public:
// LF_UDT_MOD_SRC_LINE
class UdtModSourceLineRecord : public TypeRecord {
public:
+ UdtModSourceLineRecord() = default;
explicit UdtModSourceLineRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
UdtModSourceLineRecord(TypeIndex UDT, TypeIndex SourceFile,
uint32_t LineNumber, uint16_t Module)
: TypeRecord(TypeRecordKind::UdtSourceLine), UDT(UDT),
SourceFile(SourceFile), LineNumber(LineNumber), Module(Module) {}
- bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
-
TypeIndex getUDT() const { return UDT; }
TypeIndex getSourceFile() const { return SourceFile; }
uint32_t getLineNumber() const { return LineNumber; }
@@ -667,22 +630,21 @@ public:
// LF_BUILDINFO
class BuildInfoRecord : public TypeRecord {
public:
+ BuildInfoRecord() = default;
explicit BuildInfoRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
BuildInfoRecord(ArrayRef<TypeIndex> ArgIndices)
: TypeRecord(TypeRecordKind::BuildInfo),
ArgIndices(ArgIndices.begin(), ArgIndices.end()) {}
- /// Rewrite member type indices with IndexMap. Returns false if a type index
- /// is not in the map.
- bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
-
ArrayRef<TypeIndex> getArgs() const { return ArgIndices; }
+
SmallVector<TypeIndex, 4> ArgIndices;
};
// LF_VFTABLE
class VFTableRecord : public TypeRecord {
public:
+ VFTableRecord() = default;
explicit VFTableRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
VFTableRecord(TypeIndex CompleteClass, TypeIndex OverriddenVFTable,
uint32_t VFPtrOffset, StringRef Name,
@@ -693,14 +655,11 @@ public:
MethodNames.insert(MethodNames.end(), Methods.begin(), Methods.end());
}
- /// Rewrite member type indices with IndexMap. Returns false if a type index
- /// is not in the map.
- bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
-
TypeIndex getCompleteClass() const { return CompleteClass; }
TypeIndex getOverriddenVTable() const { return OverriddenVFTable; }
uint32_t getVFPtrOffset() const { return VFPtrOffset; }
StringRef getName() const { return makeArrayRef(MethodNames).front(); }
+
ArrayRef<StringRef> getMethodNames() const {
return makeArrayRef(MethodNames).drop_front();
}
@@ -714,7 +673,7 @@ public:
// LF_ONEMETHOD
class OneMethodRecord : public TypeRecord {
public:
- OneMethodRecord() : TypeRecord(TypeRecordKind::OneMethod) {}
+ OneMethodRecord() = default;
explicit OneMethodRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
OneMethodRecord(TypeIndex Type, MemberAttributes Attrs, int32_t VFTableOffset,
StringRef Name)
@@ -725,10 +684,6 @@ public:
: TypeRecord(TypeRecordKind::OneMethod), Type(Type),
Attrs(Access, MK, Options), VFTableOffset(VFTableOffset), Name(Name) {}
- /// Rewrite member type indices with IndexMap. Returns false if a type index
- /// is not in the map.
- bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
-
TypeIndex getType() const { return Type; }
MethodKind getMethodKind() const { return Attrs.getMethodKind(); }
MethodOptions getOptions() const { return Attrs.getFlags(); }
@@ -750,34 +705,30 @@ public:
// LF_METHODLIST
class MethodOverloadListRecord : public TypeRecord {
public:
+ MethodOverloadListRecord() = default;
explicit MethodOverloadListRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
MethodOverloadListRecord(ArrayRef<OneMethodRecord> Methods)
: TypeRecord(TypeRecordKind::MethodOverloadList), Methods(Methods) {}
- /// Rewrite member type indices with IndexMap. Returns false if a type index
- /// is not in the map.
- bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
-
ArrayRef<OneMethodRecord> getMethods() const { return Methods; }
+
std::vector<OneMethodRecord> Methods;
};
/// For method overload sets. LF_METHOD
class OverloadedMethodRecord : public TypeRecord {
public:
+ OverloadedMethodRecord() = default;
explicit OverloadedMethodRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
OverloadedMethodRecord(uint16_t NumOverloads, TypeIndex MethodList,
StringRef Name)
: TypeRecord(TypeRecordKind::OverloadedMethod),
NumOverloads(NumOverloads), MethodList(MethodList), Name(Name) {}
- /// Rewrite member type indices with IndexMap. Returns false if a type index
- /// is not in the map.
- bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
-
uint16_t getNumOverloads() const { return NumOverloads; }
TypeIndex getMethodList() const { return MethodList; }
StringRef getName() const { return Name; }
+
uint16_t NumOverloads;
TypeIndex MethodList;
StringRef Name;
@@ -786,6 +737,7 @@ public:
// LF_MEMBER
class DataMemberRecord : public TypeRecord {
public:
+ DataMemberRecord() = default;
explicit DataMemberRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
DataMemberRecord(MemberAttributes Attrs, TypeIndex Type, uint64_t Offset,
StringRef Name)
@@ -796,10 +748,6 @@ public:
: TypeRecord(TypeRecordKind::DataMember), Attrs(Access), Type(Type),
FieldOffset(Offset), Name(Name) {}
- /// Rewrite member type indices with IndexMap. Returns false if a type index
- /// is not in the map.
- bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
-
MemberAccess getAccess() const { return Attrs.getAccess(); }
TypeIndex getType() const { return Type; }
uint64_t getFieldOffset() const { return FieldOffset; }
@@ -814,6 +762,7 @@ public:
// LF_STMEMBER
class StaticDataMemberRecord : public TypeRecord {
public:
+ StaticDataMemberRecord() = default;
explicit StaticDataMemberRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
StaticDataMemberRecord(MemberAttributes Attrs, TypeIndex Type, StringRef Name)
: TypeRecord(TypeRecordKind::StaticDataMember), Attrs(Attrs), Type(Type),
@@ -822,10 +771,6 @@ public:
: TypeRecord(TypeRecordKind::StaticDataMember), Attrs(Access), Type(Type),
Name(Name) {}
- /// Rewrite member type indices with IndexMap. Returns false if a type index
- /// is not in the map.
- bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
-
MemberAccess getAccess() const { return Attrs.getAccess(); }
TypeIndex getType() const { return Type; }
StringRef getName() const { return Name; }
@@ -838,6 +783,7 @@ public:
// LF_ENUMERATE
class EnumeratorRecord : public TypeRecord {
public:
+ EnumeratorRecord() = default;
explicit EnumeratorRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
EnumeratorRecord(MemberAttributes Attrs, APSInt Value, StringRef Name)
: TypeRecord(TypeRecordKind::Enumerator), Attrs(Attrs),
@@ -846,10 +792,6 @@ public:
: TypeRecord(TypeRecordKind::Enumerator), Attrs(Access),
Value(std::move(Value)), Name(Name) {}
- /// Rewrite member type indices with IndexMap. Returns false if a type index
- /// is not in the map.
- bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
-
MemberAccess getAccess() const { return Attrs.getAccess(); }
APSInt getValue() const { return Value; }
StringRef getName() const { return Name; }
@@ -862,14 +804,11 @@ public:
// LF_VFUNCTAB
class VFPtrRecord : public TypeRecord {
public:
+ VFPtrRecord() = default;
explicit VFPtrRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
VFPtrRecord(TypeIndex Type)
: TypeRecord(TypeRecordKind::VFPtr), Type(Type) {}
- /// Rewrite member type indices with IndexMap. Returns false if a type index
- /// is not in the map.
- bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
-
TypeIndex getType() const { return Type; }
TypeIndex Type;
@@ -878,6 +817,7 @@ public:
// LF_BCLASS, LF_BINTERFACE
class BaseClassRecord : public TypeRecord {
public:
+ BaseClassRecord() = default;
explicit BaseClassRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
BaseClassRecord(MemberAttributes Attrs, TypeIndex Type, uint64_t Offset)
: TypeRecord(TypeRecordKind::BaseClass), Attrs(Attrs), Type(Type),
@@ -886,10 +826,6 @@ public:
: TypeRecord(TypeRecordKind::BaseClass), Attrs(Access), Type(Type),
Offset(Offset) {}
- /// Rewrite member type indices with IndexMap. Returns false if a type index
- /// is not in the map.
- bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
-
MemberAccess getAccess() const { return Attrs.getAccess(); }
TypeIndex getBaseType() const { return Type; }
uint64_t getBaseOffset() const { return Offset; }
@@ -902,6 +838,7 @@ public:
// LF_VBCLASS, LF_IVBCLASS
class VirtualBaseClassRecord : public TypeRecord {
public:
+ VirtualBaseClassRecord() = default;
explicit VirtualBaseClassRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
VirtualBaseClassRecord(TypeRecordKind Kind, MemberAttributes Attrs,
TypeIndex BaseType, TypeIndex VBPtrType,
@@ -914,10 +851,6 @@ public:
: TypeRecord(Kind), Attrs(Access), BaseType(BaseType),
VBPtrType(VBPtrType), VBPtrOffset(Offset), VTableIndex(Index) {}
- /// Rewrite member type indices with IndexMap. Returns false if a type index
- /// is not in the map.
- bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
-
MemberAccess getAccess() const { return Attrs.getAccess(); }
TypeIndex getBaseType() const { return BaseType; }
TypeIndex getVBPtrType() const { return VBPtrType; }
@@ -935,6 +868,7 @@ public:
/// together. The first will end in an LF_INDEX record that points to the next.
class ListContinuationRecord : public TypeRecord {
public:
+ ListContinuationRecord() = default;
explicit ListContinuationRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
ListContinuationRecord(TypeIndex ContinuationIndex)
: TypeRecord(TypeRecordKind::ListContinuation),
@@ -942,13 +876,10 @@ public:
TypeIndex getContinuationIndex() const { return ContinuationIndex; }
- bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
-
TypeIndex ContinuationIndex;
};
} // end namespace codeview
-
} // end namespace llvm
#endif // LLVM_DEBUGINFO_CODEVIEW_TYPERECORD_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeRecordMapping.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeRecordMapping.h
index fe470a7..cbe8d60 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeRecordMapping.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeRecordMapping.h
@@ -16,16 +16,16 @@
#include "llvm/Support/Error.h"
namespace llvm {
-namespace msf {
-class StreamReader;
-class StreamWriter;
-}
+class BinaryStreamReader;
+class BinaryStreamWriter;
+
namespace codeview {
class TypeRecordMapping : public TypeVisitorCallbacks {
public:
- explicit TypeRecordMapping(msf::StreamReader &Reader) : IO(Reader) {}
- explicit TypeRecordMapping(msf::StreamWriter &Writer) : IO(Writer) {}
+ explicit TypeRecordMapping(BinaryStreamReader &Reader) : IO(Reader) {}
+ explicit TypeRecordMapping(BinaryStreamWriter &Writer) : IO(Writer) {}
+ using TypeVisitorCallbacks::visitTypeBegin;
Error visitTypeBegin(CVType &Record) override;
Error visitTypeEnd(CVType &Record) override;
@@ -38,7 +38,7 @@ public:
Error visitKnownMember(CVMemberRecord &CVR, Name##Record &Record) override;
#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
-#include "TypeRecords.def"
+#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
private:
Optional<TypeLeafKind> TypeKind;
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeSerializer.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeSerializer.h
index e059221..0e734a8 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeSerializer.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeSerializer.h
@@ -10,22 +10,29 @@
#ifndef LLVM_DEBUGINFO_CODEVIEW_TYPESERIALIZER_H
#define LLVM_DEBUGINFO_CODEVIEW_TYPESERIALIZER_H
-#include "llvm/DebugInfo/CodeView/TypeRecordMapping.h"
-#include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
-#include "llvm/DebugInfo/MSF/ByteStream.h"
-#include "llvm/DebugInfo/MSF/StreamWriter.h"
-
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringMap.h"
-#include "llvm/ADT/StringRef.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 TypeHasher;
+
class TypeSerializer : public TypeVisitorCallbacks {
struct SubRecord {
SubRecord(TypeLeafKind K, uint32_t S) : Kind(K), Size(S) {}
@@ -45,43 +52,54 @@ class TypeSerializer : public TypeVisitorCallbacks {
}
};
- typedef SmallVector<MutableArrayRef<uint8_t>, 2> RecordList;
+ using MutableRecordList = SmallVector<MutableArrayRef<uint8_t>, 2>;
static constexpr uint8_t ContinuationLength = 8;
BumpPtrAllocator &RecordStorage;
RecordSegment CurrentSegment;
- RecordList FieldListSegments;
+ MutableRecordList FieldListSegments;
- TypeIndex LastTypeIndex;
Optional<TypeLeafKind> TypeKind;
Optional<TypeLeafKind> MemberKind;
std::vector<uint8_t> RecordBuffer;
- msf::MutableByteStream Stream;
- msf::StreamWriter Writer;
+ MutableBinaryByteStream Stream;
+ BinaryStreamWriter Writer;
TypeRecordMapping Mapping;
- RecordList SeenRecords;
- StringMap<TypeIndex> HashedRecords;
+ /// Private type record hashing implementation details are handled here.
+ std::unique_ptr<TypeHasher> Hasher;
+
+ /// Contains a list of all records indexed by TypeIndex.toArrayIndex().
+ SmallVector<ArrayRef<uint8_t>, 2> SeenRecords;
+
+ /// Temporary storage that we use to copy a record's data while re-writing
+ /// its type indices.
+ SmallVector<uint8_t, 256> RemapStorage;
+
+ TypeIndex nextTypeIndex() const;
bool isInFieldList() const;
- TypeIndex calcNextTypeIndex() const;
- TypeIndex incrementTypeIndex();
MutableArrayRef<uint8_t> getCurrentSubRecordData();
MutableArrayRef<uint8_t> getCurrentRecordData();
Error writeRecordPrefix(TypeLeafKind Kind);
- TypeIndex insertRecordBytesPrivate(MutableArrayRef<uint8_t> Record);
Expected<MutableArrayRef<uint8_t>>
addPadding(MutableArrayRef<uint8_t> Record);
public:
- explicit TypeSerializer(BumpPtrAllocator &Storage);
+ explicit TypeSerializer(BumpPtrAllocator &Storage, bool Hash = true);
+ ~TypeSerializer() override;
- ArrayRef<MutableArrayRef<uint8_t>> records() const;
- TypeIndex getLastTypeIndex() const;
- TypeIndex insertRecordBytes(MutableArrayRef<uint8_t> Record);
+ void reset();
+
+ BumpPtrAllocator &getAllocator() { return RecordStorage; }
+
+ ArrayRef<ArrayRef<uint8_t>> records() const;
+ TypeIndex insertRecordBytes(ArrayRef<uint8_t> &Record);
+ TypeIndex insertRecord(const RemappedType &Record);
Expected<TypeIndex> visitTypeEndGetIndex(CVType &Record);
+ using TypeVisitorCallbacks::visitTypeBegin;
Error visitTypeBegin(CVType &Record) override;
Error visitTypeEnd(CVType &Record) override;
Error visitMemberBegin(CVMemberRecord &Record) override;
@@ -97,7 +115,7 @@ public:
return visitKnownMemberImpl<Name##Record>(CVR, Record); \
}
#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
-#include "llvm/DebugInfo/CodeView/TypeRecords.def"
+#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
private:
template <typename RecordKind>
@@ -134,7 +152,8 @@ private:
return Error::success();
}
};
-}
-}
-#endif
+} // end namespace codeview
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_CODEVIEW_TYPESERIALIZER_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeStreamMerger.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeStreamMerger.h
index af396c7..d78fab4 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeStreamMerger.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeStreamMerger.h
@@ -12,13 +12,76 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/DebugInfo/CodeView/TypeTableBuilder.h"
+#include "llvm/DebugInfo/CodeView/TypeRecord.h"
+#include "llvm/Support/Error.h"
namespace llvm {
namespace codeview {
-/// Merges one type stream into another. Returns true on success.
-bool mergeTypeStreams(TypeTableBuilder &DestStream, const CVTypeArray &Types);
+class TypeIndex;
+class TypeTableBuilder;
+
+/// \brief Merge one set of type records into another. This method assumes
+/// that all records are type records, and there are no Id records present.
+///
+/// \param Dest The table to store the re-written type records into.
+///
+/// \param SourceToDest A vector, indexed by the TypeIndex in the source
+/// type stream, that contains the index of the corresponding type record
+/// in the destination stream.
+///
+/// \param Types The collection of types to merge in.
+///
+/// \returns Error::success() if the operation succeeded, otherwise an
+/// appropriate error code.
+Error mergeTypeRecords(TypeTableBuilder &Dest,
+ SmallVectorImpl<TypeIndex> &SourceToDest,
+ const CVTypeArray &Types);
+
+/// \brief Merge one set of id records into another. This method assumes
+/// that all records are id records, and there are no Type records present.
+/// However, since Id records can refer back to Type records, this method
+/// assumes that the referenced type records have also been merged into
+/// another type stream (for example using the above method), and accepts
+/// the mapping from source to dest for that stream so that it can re-write
+/// the type record mappings accordingly.
+///
+/// \param Dest The table to store the re-written id records into.
+///
+/// \param Types The mapping to use for the type records that these id
+/// records refer to.
+///
+/// \param SourceToDest A vector, indexed by the TypeIndex in the source
+/// id stream, that contains the index of the corresponding id record
+/// in the destination stream.
+///
+/// \param Ids The collection of id records to merge in.
+///
+/// \returns Error::success() if the operation succeeded, otherwise an
+/// appropriate error code.
+Error mergeIdRecords(TypeTableBuilder &Dest, ArrayRef<TypeIndex> Types,
+ SmallVectorImpl<TypeIndex> &SourceToDest,
+ const CVTypeArray &Ids);
+
+/// \brief Merge a unified set of type and id records, splitting them into
+/// separate output streams.
+///
+/// \param DestIds The table to store the re-written id records into.
+///
+/// \param DestTypes the table to store the re-written type records into.
+///
+/// \param SourceToDest A vector, indexed by the TypeIndex in the source
+/// id stream, that contains the index of the corresponding id record
+/// in the destination stream.
+///
+/// \param IdsAndTypes The collection of id records to merge in.
+///
+/// \returns Error::success() if the operation succeeded, otherwise an
+/// appropriate error code.
+Error mergeTypeAndIdRecords(TypeTableBuilder &DestIds,
+ TypeTableBuilder &DestTypes,
+ SmallVectorImpl<TypeIndex> &SourceToDest,
+ const CVTypeArray &IdsAndTypes);
} // end namespace codeview
} // end namespace llvm
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeTableBuilder.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeTableBuilder.h
index 4e6d81e..1069dcd 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeTableBuilder.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeTableBuilder.h
@@ -13,8 +13,8 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/DebugInfo/CodeView/TypeIndex.h"
-#include "llvm/DebugInfo/CodeView/TypeSerializer.h"
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
+#include "llvm/DebugInfo/CodeView/TypeSerializer.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Error.h"
#include <algorithm>
@@ -37,8 +37,9 @@ private:
TypeSerializer Serializer;
public:
- explicit TypeTableBuilder(BumpPtrAllocator &Allocator)
- : Allocator(Allocator), Serializer(Allocator) {}
+ explicit TypeTableBuilder(BumpPtrAllocator &Allocator,
+ bool WriteUnique = true)
+ : Allocator(Allocator), Serializer(Allocator, WriteUnique) {}
TypeTableBuilder(const TypeTableBuilder &) = delete;
TypeTableBuilder &operator=(const TypeTableBuilder &) = delete;
@@ -64,10 +65,14 @@ public:
return *ExpectedIndex;
}
- TypeIndex writeSerializedRecord(MutableArrayRef<uint8_t> Record) {
+ TypeIndex writeSerializedRecord(ArrayRef<uint8_t> Record) {
return Serializer.insertRecordBytes(Record);
}
+ TypeIndex writeSerializedRecord(const RemappedType &Record) {
+ return Serializer.insertRecord(Record);
+ }
+
template <typename TFunc> void ForEachRecord(TFunc Func) {
uint32_t Index = TypeIndex::FirstNonSimpleIndex;
@@ -77,23 +82,24 @@ public:
}
}
- ArrayRef<MutableArrayRef<uint8_t>> records() const {
- return Serializer.records();
- }
+ ArrayRef<ArrayRef<uint8_t>> records() const { return Serializer.records(); }
};
class FieldListRecordBuilder {
TypeTableBuilder &TypeTable;
+ BumpPtrAllocator Allocator;
TypeSerializer TempSerializer;
CVType Type;
public:
explicit FieldListRecordBuilder(TypeTableBuilder &TypeTable)
- : TypeTable(TypeTable), TempSerializer(TypeTable.getAllocator()) {
+ : TypeTable(TypeTable), TempSerializer(Allocator, false) {
Type.Type = TypeLeafKind::LF_FIELDLIST;
}
void begin() {
+ TempSerializer.reset();
+
if (auto EC = TempSerializer.visitTypeBegin(Type))
consumeError(std::move(EC));
}
@@ -109,16 +115,18 @@ public:
consumeError(std::move(EC));
}
- TypeIndex end() {
+ TypeIndex end(bool Write) {
+ TypeIndex Index;
if (auto EC = TempSerializer.visitTypeEnd(Type)) {
consumeError(std::move(EC));
return TypeIndex();
}
- TypeIndex Index;
- for (auto Record : TempSerializer.records()) {
- Index = TypeTable.writeSerializedRecord(Record);
+ if (Write) {
+ for (auto Record : TempSerializer.records())
+ Index = TypeTable.writeSerializedRecord(Record);
}
+
return Index;
}
};
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeTableCollection.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeTableCollection.h
new file mode 100644
index 0000000..80326a0
--- /dev/null
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeTableCollection.h
@@ -0,0 +1,43 @@
+//===- TypeTableCollection.h ---------------------------------- *- C++ --*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_CODEVIEW_TYPETABLECOLLECTION_H
+#define LLVM_DEBUGINFO_CODEVIEW_TYPETABLECOLLECTION_H
+
+#include "llvm/DebugInfo/CodeView/TypeCollection.h"
+#include "llvm/Support/StringSaver.h"
+
+#include <vector>
+
+namespace llvm {
+namespace codeview {
+
+class TypeTableCollection : public TypeCollection {
+public:
+ explicit TypeTableCollection(ArrayRef<ArrayRef<uint8_t>> Records);
+
+ Optional<TypeIndex> getFirst() override;
+ Optional<TypeIndex> getNext(TypeIndex Prev) override;
+
+ CVType getType(TypeIndex Index) override;
+ StringRef getTypeName(TypeIndex Index) override;
+ bool contains(TypeIndex Index) override;
+ uint32_t size() override;
+ uint32_t capacity() override;
+
+private:
+ BumpPtrAllocator Allocator;
+ StringSaver NameStorage;
+ std::vector<StringRef> Names;
+ ArrayRef<ArrayRef<uint8_t>> Records;
+};
+}
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h
index f251296..126fb8a 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h
@@ -47,6 +47,14 @@ public:
return Error::success();
}
+ Error visitTypeBegin(CVType &Record, TypeIndex Index) override {
+ for (auto Visitor : Pipeline) {
+ if (auto EC = Visitor->visitTypeBegin(Record, Index))
+ return EC;
+ }
+ return Error::success();
+ }
+
Error visitTypeEnd(CVType &Record) override {
for (auto Visitor : Pipeline) {
if (auto EC = Visitor->visitTypeEnd(Record))
@@ -86,7 +94,7 @@ public:
}
#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
-#include "llvm/DebugInfo/CodeView/TypeRecords.def"
+#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
private:
template <typename T> Error visitKnownRecordImpl(CVType &CVR, T &Record) {
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h
index 5e27df3..d7a4733 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h
@@ -17,8 +17,6 @@ namespace llvm {
namespace codeview {
class TypeVisitorCallbacks {
- friend class CVTypeVisitor;
-
public:
virtual ~TypeVisitorCallbacks() = default;
@@ -26,8 +24,15 @@ public:
virtual Error visitUnknownType(CVType &Record) { return Error::success(); }
/// Paired begin/end actions for all types. Receives all record data,
/// including the fixed-length record prefix. visitTypeBegin() should return
- /// the type of the Record, or an error if it cannot be determined.
+ /// the type of the Record, or an error if it cannot be determined. Exactly
+ /// one of the two visitTypeBegin methods will be called, depending on whether
+ /// records are being visited sequentially or randomly. An implementation
+ /// should be prepared to handle both (or assert if it can't handle random
+ /// access visitation).
virtual Error visitTypeBegin(CVType &Record) { return Error::success(); }
+ virtual Error visitTypeBegin(CVType &Record, TypeIndex Index) {
+ return Error::success();
+ }
virtual Error visitTypeEnd(CVType &Record) { return Error::success(); }
virtual Error visitUnknownMember(CVMemberRecord &Record) {
@@ -53,7 +58,11 @@ public:
#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
-#include "TypeRecords.def"
+#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
+#undef TYPE_RECORD
+#undef TYPE_RECORD_ALIAS
+#undef MEMBER_RECORD
+#undef MEMBER_RECORD_ALIAS
};
} // end namespace codeview
diff --git a/contrib/llvm/include/llvm/DebugInfo/DIContext.h b/contrib/llvm/include/llvm/DebugInfo/DIContext.h
index 804419c5..936813d 100644
--- a/contrib/llvm/include/llvm/DebugInfo/DIContext.h
+++ b/contrib/llvm/include/llvm/DebugInfo/DIContext.h
@@ -1,4 +1,4 @@
-//===-- DIContext.h ---------------------------------------------*- C++ -*-===//
+//===- DIContext.h ----------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -32,30 +32,32 @@ class raw_ostream;
struct DILineInfo {
std::string FileName;
std::string FunctionName;
- uint32_t Line;
- uint32_t Column;
+ uint32_t Line = 0;
+ uint32_t Column = 0;
+ uint32_t StartLine = 0;
// DWARF-specific.
- uint32_t Discriminator;
+ uint32_t Discriminator = 0;
- DILineInfo()
- : FileName("<invalid>"), FunctionName("<invalid>"), Line(0), Column(0),
- Discriminator(0) {}
+ DILineInfo() : FileName("<invalid>"), FunctionName("<invalid>") {}
bool operator==(const DILineInfo &RHS) const {
return Line == RHS.Line && Column == RHS.Column &&
- FileName == RHS.FileName && FunctionName == RHS.FunctionName;
+ FileName == RHS.FileName && FunctionName == RHS.FunctionName &&
+ StartLine == RHS.StartLine && Discriminator == RHS.Discriminator;
}
bool operator!=(const DILineInfo &RHS) const {
return !(*this == RHS);
}
bool operator<(const DILineInfo &RHS) const {
- return std::tie(FileName, FunctionName, Line, Column) <
- std::tie(RHS.FileName, RHS.FunctionName, RHS.Line, RHS.Column);
+ return std::tie(FileName, FunctionName, Line, Column, StartLine,
+ Discriminator) <
+ std::tie(RHS.FileName, RHS.FunctionName, RHS.Line, RHS.Column,
+ RHS.StartLine, RHS.Discriminator);
}
};
-typedef SmallVector<std::pair<uint64_t, DILineInfo>, 16> DILineInfoTable;
+using DILineInfoTable = SmallVector<std::pair<uint64_t, DILineInfo>, 16>;
/// DIInliningInfo - a format-neutral container for inlined code description.
class DIInliningInfo {
@@ -86,10 +88,10 @@ public:
/// DIGlobal - container for description of a global variable.
struct DIGlobal {
std::string Name;
- uint64_t Start;
- uint64_t Size;
+ uint64_t Start = 0;
+ uint64_t Size = 0;
- DIGlobal() : Name("<invalid>"), Start(0), Size(0) {}
+ DIGlobal() : Name("<invalid>") {}
};
/// A DINameKind is passed to name search methods to specify a
@@ -100,7 +102,7 @@ enum class DINameKind { None, ShortName, LinkageName };
/// should be filled with data.
struct DILineInfoSpecifier {
enum class FileLineInfoKind { None, Default, AbsoluteFilePath };
- typedef DINameKind FunctionNameKind;
+ using FunctionNameKind = DINameKind;
FileLineInfoKind FLIKind;
FunctionNameKind FNKind;
@@ -133,6 +135,7 @@ enum DIDumpType {
DIDT_GnuPubnames,
DIDT_GnuPubtypes,
DIDT_Str,
+ DIDT_StrOffsets,
DIDT_StrDwo,
DIDT_StrOffsetsDwo,
DIDT_AppleNames,
@@ -144,6 +147,15 @@ enum DIDumpType {
DIDT_TUIndex,
};
+/// Container for dump options that control which debug information will be
+/// dumped.
+struct DIDumpOptions {
+ DIDumpType DumpType = DIDT_All;
+ bool DumpEH = false;
+ bool SummarizeTypes = false;
+ bool Brief = false;
+};
+
class DIContext {
public:
enum DIContextKind {
@@ -156,8 +168,12 @@ public:
DIContextKind getKind() const { return Kind; }
- virtual void dump(raw_ostream &OS, DIDumpType DumpType = DIDT_All,
- bool DumpEH = false, bool SummarizeTypes = false) = 0;
+ virtual void dump(raw_ostream &OS, DIDumpOptions DumpOpts) = 0;
+
+ virtual bool verify(raw_ostream &OS, DIDumpType DumpType = DIDT_All) {
+ // No verifier? Just say things went well.
+ return true;
+ }
virtual DILineInfo getLineInfoForAddress(uint64_t Address,
DILineInfoSpecifier Specifier = DILineInfoSpecifier()) = 0;
@@ -175,8 +191,8 @@ private:
/// on the fly.
class LoadedObjectInfo {
protected:
- LoadedObjectInfo(const LoadedObjectInfo &) = default;
LoadedObjectInfo() = default;
+ LoadedObjectInfo(const LoadedObjectInfo &) = default;
public:
virtual ~LoadedObjectInfo() = default;
@@ -188,7 +204,9 @@ public:
/// need to be consistent with the addresses used to query the DIContext and
/// the output of this function should be deterministic, i.e. repeated calls with
/// the same Sec should give the same address.
- virtual uint64_t getSectionLoadAddress(const object::SectionRef &Sec) const = 0;
+ virtual uint64_t getSectionLoadAddress(const object::SectionRef &Sec) const {
+ return 0;
+ }
/// If conveniently available, return the content of the given Section.
///
@@ -205,12 +223,28 @@ public:
return false;
}
+ // FIXME: This is untested and unused anywhere in the LLVM project, it's
+ // used/needed by Julia (an external project). It should have some coverage
+ // (at least tests, but ideally example functionality).
/// Obtain a copy of this LoadedObjectInfo.
- ///
- /// The caller is responsible for deallocation once the copy is no longer required.
virtual std::unique_ptr<LoadedObjectInfo> clone() const = 0;
};
+template <typename Derived, typename Base = LoadedObjectInfo>
+struct LoadedObjectInfoHelper : Base {
+protected:
+ LoadedObjectInfoHelper(const LoadedObjectInfoHelper &) = default;
+ LoadedObjectInfoHelper() = default;
+
+public:
+ template <typename... Ts>
+ LoadedObjectInfoHelper(Ts &&... Args) : Base(std::forward<Ts>(Args)...) {}
+
+ std::unique_ptr<llvm::LoadedObjectInfo> clone() const override {
+ return llvm::make_unique<Derived>(static_cast<const Derived &>(*this));
+ }
+};
+
} // end namespace llvm
#endif // LLVM_DEBUGINFO_DICONTEXT_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h b/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h
index db9bd50..190a69b 100644
--- a/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h
+++ b/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h
@@ -1,4 +1,4 @@
-//===-- DWARFAbbreviationDeclaration.h --------------------------*- C++ -*-===//
+//===- DWARFAbbreviationDeclaration.h ---------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,17 +7,22 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIB_DEBUGINFO_DWARFABBREVIATIONDECLARATION_H
-#define LLVM_LIB_DEBUGINFO_DWARFABBREVIATIONDECLARATION_H
+#ifndef LLVM_DEBUGINFO_DWARFABBREVIATIONDECLARATION_H
+#define LLVM_DEBUGINFO_DWARFABBREVIATIONDECLARATION_H
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/Support/DataExtractor.h"
-#include "llvm/Support/Dwarf.h"
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
+
namespace llvm {
-class DWARFUnit;
class DWARFFormValue;
+class DWARFUnit;
class raw_ostream;
class DWARFAbbreviationDeclaration {
@@ -25,8 +30,10 @@ public:
struct AttributeSpec {
AttributeSpec(dwarf::Attribute A, dwarf::Form F, Optional<int64_t> V)
: Attr(A), Form(F), ByteSizeOrValue(V) {}
+
dwarf::Attribute Attr;
dwarf::Form Form;
+
/// The following field is used for ByteSize for non-implicit_const
/// attributes and as value for implicit_const ones, indicated by
/// Form == DW_FORM_implicit_const.
@@ -41,34 +48,45 @@ public:
/// * Form == DW_FORM_implicit_const:
/// ByteSizeOrValue contains value for the implicit_const attribute.
Optional<int64_t> ByteSizeOrValue;
+
bool isImplicitConst() const {
return Form == dwarf::DW_FORM_implicit_const;
}
+
/// Get the fixed byte size of this Form if possible. This function might
/// use the DWARFUnit to calculate the size of the Form, like for
/// DW_AT_address and DW_AT_ref_addr, so this isn't just an accessor for
/// the ByteSize member.
Optional<int64_t> getByteSize(const DWARFUnit &U) const;
};
- typedef SmallVector<AttributeSpec, 8> AttributeSpecVector;
+ using AttributeSpecVector = SmallVector<AttributeSpec, 8>;
DWARFAbbreviationDeclaration();
uint32_t getCode() const { return Code; }
+ uint8_t getCodeByteSize() const { return CodeByteSize; }
dwarf::Tag getTag() const { return Tag; }
bool hasChildren() const { return HasChildren; }
- typedef iterator_range<AttributeSpecVector::const_iterator>
- attr_iterator_range;
+ using attr_iterator_range =
+ iterator_range<AttributeSpecVector::const_iterator>;
attr_iterator_range attributes() const {
return attr_iterator_range(AttributeSpecs.begin(), AttributeSpecs.end());
}
dwarf::Form getFormByIndex(uint32_t idx) const {
- if (idx < AttributeSpecs.size())
- return AttributeSpecs[idx].Form;
- return dwarf::Form(0);
+ assert(idx < AttributeSpecs.size());
+ return AttributeSpecs[idx].Form;
+ }
+
+ size_t getNumAttributes() const {
+ return AttributeSpecs.size();
+ }
+
+ dwarf::Attribute getAttrByIndex(uint32_t idx) const {
+ assert(idx < AttributeSpecs.size());
+ return AttributeSpecs[idx].Attr;
}
/// Get the index of the specified attribute.
@@ -109,16 +127,16 @@ private:
/// abbreviation declaration.
struct FixedSizeInfo {
/// The fixed byte size for fixed size forms.
- uint16_t NumBytes;
+ uint16_t NumBytes = 0;
/// Number of DW_FORM_address forms in this abbrevation declaration.
- uint8_t NumAddrs;
+ uint8_t NumAddrs = 0;
/// Number of DW_FORM_ref_addr forms in this abbrevation declaration.
- uint8_t NumRefAddrs;
+ uint8_t NumRefAddrs = 0;
/// Number of 4 byte in DWARF32 and 8 byte in DWARF64 forms.
- uint8_t NumDwarfOffsets;
- /// Constructor
- FixedSizeInfo()
- : NumBytes(0), NumAddrs(0), NumRefAddrs(0), NumDwarfOffsets(0) {}
+ uint8_t NumDwarfOffsets = 0;
+
+ FixedSizeInfo() = default;
+
/// Calculate the fixed size in bytes given a DWARFUnit.
///
/// \param U the DWARFUnit to use when determing the byte size.
@@ -138,6 +156,6 @@ private:
Optional<FixedSizeInfo> FixedAttributeSize;
};
-}
+} // end namespace llvm
-#endif
+#endif // LLVM_DEBUGINFO_DWARFABBREVIATIONDECLARATION_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h b/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h
index 6334372..eb6d0f5 100644
--- a/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h
+++ b/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h
@@ -1,4 +1,4 @@
-//===--- DWARFAcceleratorTable.h --------------------------------*- C++ -*-===//
+//===- DWARFAcceleratorTable.h ----------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,19 +7,21 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIB_DEBUGINFO_DWARFACCELERATORTABLE_H
-#define LLVM_LIB_DEBUGINFO_DWARFACCELERATORTABLE_H
+#ifndef LLVM_DEBUGINFO_DWARFACCELERATORTABLE_H
+#define LLVM_DEBUGINFO_DWARFACCELERATORTABLE_H
#include "llvm/ADT/SmallVector.h"
-#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
+#include "llvm/BinaryFormat/Dwarf.h"
+#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
#include "llvm/DebugInfo/DWARF/DWARFRelocMap.h"
-#include "llvm/Support/Dwarf.h"
#include <cstdint>
+#include <utility>
namespace llvm {
-class DWARFAcceleratorTable {
+class raw_ostream;
+class DWARFAcceleratorTable {
struct Header {
uint32_t Magic;
uint16_t Version;
@@ -30,26 +32,43 @@ class DWARFAcceleratorTable {
};
struct HeaderData {
- typedef uint16_t AtomType;
- typedef dwarf::Form Form;
+ using AtomType = uint16_t;
+ using Form = dwarf::Form;
+
uint32_t DIEOffsetBase;
SmallVector<std::pair<AtomType, Form>, 3> Atoms;
};
struct Header Hdr;
struct HeaderData HdrData;
- DataExtractor AccelSection;
+ DWARFDataExtractor AccelSection;
DataExtractor StringSection;
- const RelocAddrMap& Relocs;
+
public:
- DWARFAcceleratorTable(DataExtractor AccelSection, DataExtractor StringSection,
- const RelocAddrMap &Relocs)
- : AccelSection(AccelSection), StringSection(StringSection), Relocs(Relocs) {}
+ DWARFAcceleratorTable(const DWARFDataExtractor &AccelSection,
+ DataExtractor StringSection)
+ : AccelSection(AccelSection), StringSection(StringSection) {}
bool extract();
+ uint32_t getNumBuckets();
+ uint32_t getNumHashes();
+ uint32_t getSizeHdr();
+ uint32_t getHeaderDataLength();
+ ArrayRef<std::pair<HeaderData::AtomType, HeaderData::Form>> getAtomsDesc();
+ bool validateForms();
+
+ /// Return information related to the DWARF DIE we're looking for when
+ /// performing a lookup by name.
+ ///
+ /// \param HashDataOffset an offset into the hash data table
+ /// \returns DIEOffset the offset into the .debug_info section for the DIE
+ /// related to the input hash data offset. Currently this function returns
+ /// only the DIEOffset but it can be modified to return more data regarding
+ /// the DIE
+ uint32_t readAtoms(uint32_t &HashDataOffset);
void dump(raw_ostream &OS) const;
};
-}
+} // end namespace llvm
-#endif
+#endif // LLVM_DEBUGINFO_DWARFACCELERATORTABLE_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFAttribute.h b/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFAttribute.h
new file mode 100644
index 0000000..f0672bb
--- /dev/null
+++ b/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFAttribute.h
@@ -0,0 +1,56 @@
+//===- DWARFAttribute.h -----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_DWARFATTRIBUTE_H
+#define LLVM_DEBUGINFO_DWARFATTRIBUTE_H
+
+#include "llvm/BinaryFormat/Dwarf.h"
+#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
+#include <cstdint>
+
+namespace llvm {
+
+//===----------------------------------------------------------------------===//
+/// Encapsulates a DWARF attribute value and all of the data required to
+/// describe the attribute value.
+///
+/// This class is designed to be used by clients that want to iterate across all
+/// attributes in a DWARFDie.
+struct DWARFAttribute {
+ /// The debug info/types offset for this attribute.
+ uint32_t Offset = 0;
+ /// The debug info/types section byte size of the data for this attribute.
+ uint32_t ByteSize = 0;
+ /// The attribute enumeration of this attribute.
+ dwarf::Attribute Attr;
+ /// The form and value for this attribute.
+ DWARFFormValue Value;
+
+ DWARFAttribute(uint32_t O, dwarf::Attribute A = dwarf::Attribute(0),
+ dwarf::Form F = dwarf::Form(0)) : Attr(A), Value(F) {}
+
+ bool isValid() const {
+ return Offset != 0 && Attr != dwarf::Attribute(0);
+ }
+
+ explicit operator bool() const {
+ return isValid();
+ }
+
+ void clear() {
+ Offset = 0;
+ ByteSize = 0;
+ Attr = dwarf::Attribute(0);
+ Value = DWARFFormValue();
+ }
+};
+
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_DWARFATTRIBUTE_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFCompileUnit.h b/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFCompileUnit.h
index bba3abe..a18adf8 100644
--- a/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFCompileUnit.h
+++ b/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFCompileUnit.h
@@ -1,4 +1,4 @@
-//===-- DWARFCompileUnit.h --------------------------------------*- C++ -*-===//
+//===- DWARFCompileUnit.h ---------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,28 +7,33 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIB_DEBUGINFO_DWARFCOMPILEUNIT_H
-#define LLVM_LIB_DEBUGINFO_DWARFCOMPILEUNIT_H
+#ifndef LLVM_DEBUGINFO_DWARFCOMPILEUNIT_H
+#define LLVM_DEBUGINFO_DWARFCOMPILEUNIT_H
#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
+#include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h"
namespace llvm {
class DWARFCompileUnit : public DWARFUnit {
public:
DWARFCompileUnit(DWARFContext &Context, const DWARFSection &Section,
- const DWARFDebugAbbrev *DA, StringRef RS, StringRef SS,
- StringRef SOS, StringRef AOS, StringRef LS, bool LE,
+ const DWARFDebugAbbrev *DA, const DWARFSection *RS,
+ StringRef SS, const DWARFSection &SOS,
+ const DWARFSection *AOS, const DWARFSection &LS, bool LE,
bool IsDWO, const DWARFUnitSectionBase &UnitSection,
const DWARFUnitIndex::Entry *Entry)
: DWARFUnit(Context, Section, DA, RS, SS, SOS, AOS, LS, LE, IsDWO,
UnitSection, Entry) {}
- void dump(raw_ostream &OS);
- static const DWARFSectionKind Section = DW_SECT_INFO;
+
// VTable anchor.
~DWARFCompileUnit() override;
+
+ void dump(raw_ostream &OS, DIDumpOptions DumpOpts);
+
+ static const DWARFSectionKind Section = DW_SECT_INFO;
};
-}
+} // end namespace llvm
-#endif
+#endif // LLVM_DEBUGINFO_DWARFCOMPILEUNIT_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h b/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h
index ef310e7..ee2e805 100644
--- a/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h
+++ b/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h
@@ -1,4 +1,4 @@
-//===-- DWARFContext.h ------------------------------------------*- C++ -*-===//
+//===- DWARFContext.h -------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,15 +7,15 @@
//
//===----------------------------------------------------------------------===/
-#ifndef LLVM_LIB_DEBUGINFO_DWARFCONTEXT_H
-#define LLVM_LIB_DEBUGINFO_DWARFCONTEXT_H
+#ifndef LLVM_DEBUGINFO_DWARF_DWARFCONTEXT_H
+#define LLVM_DEBUGINFO_DWARF_DWARFCONTEXT_H
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/iterator_range.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/iterator_range.h"
#include "llvm/DebugInfo/DIContext.h"
#include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
@@ -24,26 +24,26 @@
#include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugMacro.h"
+#include "llvm/DebugInfo/DWARF/DWARFDie.h"
#include "llvm/DebugInfo/DWARF/DWARFGdbIndex.h"
#include "llvm/DebugInfo/DWARF/DWARFSection.h"
#include "llvm/DebugInfo/DWARF/DWARFTypeUnit.h"
#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
#include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h"
+#include "llvm/Object/Binary.h"
#include "llvm/Object/ObjectFile.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/Host.h"
#include <cstdint>
#include <deque>
#include <map>
#include <memory>
-#include <utility>
namespace llvm {
-// In place of applying the relocations to the data we've read from disk we use
-// a separate mapping table to the side and checking that at locations in the
-// dwarf where we expect relocated values. This adds a bit of complexity to the
-// dwarf parsing/extraction at the benefit of not allocating memory for the
-// entire size of the debug info sections.
-typedef DenseMap<uint64_t, std::pair<uint8_t, int64_t>> RelocAddrMap;
+class DataExtractor;
+class MemoryBuffer;
+class raw_ostream;
/// DWARFContext
/// This data structure is the top level entity that deals with dwarf debug
@@ -68,6 +68,17 @@ class DWARFContext : public DIContext {
std::unique_ptr<DWARFDebugAbbrev> AbbrevDWO;
std::unique_ptr<DWARFDebugLocDWO> LocDWO;
+ /// The maximum DWARF version of all units.
+ unsigned MaxVersion = 0;
+
+ struct DWOFile {
+ object::OwningBinary<object::ObjectFile> File;
+ std::unique_ptr<DWARFContext> Context;
+ };
+ StringMap<std::weak_ptr<DWOFile>> DWOFiles;
+ std::weak_ptr<DWOFile> DWP;
+ bool CheckedForDWP = false;
+
/// Read compile units from the debug_info section (if necessary)
/// and store them in CUs.
void parseCompileUnits();
@@ -93,12 +104,13 @@ public:
return DICtx->getKind() == CK_DWARF;
}
- void dump(raw_ostream &OS, DIDumpType DumpType = DIDT_All,
- bool DumpEH = false, bool SummarizeTypes = false) override;
+ void dump(raw_ostream &OS, DIDumpOptions DumpOpts) override;
- typedef DWARFUnitSection<DWARFCompileUnit>::iterator_range cu_iterator_range;
- typedef DWARFUnitSection<DWARFTypeUnit>::iterator_range tu_iterator_range;
- typedef iterator_range<decltype(TUs)::iterator> tu_section_iterator_range;
+ bool verify(raw_ostream &OS, DIDumpType DumpType = DIDT_All) override;
+
+ using cu_iterator_range = DWARFUnitSection<DWARFCompileUnit>::iterator_range;
+ using tu_iterator_range = DWARFUnitSection<DWARFTypeUnit>::iterator_range;
+ using tu_section_iterator_range = iterator_range<decltype(TUs)::iterator>;
/// Get compile units in this context.
cu_iterator_range compile_units() {
@@ -160,6 +172,18 @@ public:
return DWOCUs[index].get();
}
+ DWARFCompileUnit *getDWOCompileUnitForHash(uint64_t Hash);
+
+ /// Get a DIE given an exact offset.
+ DWARFDie getDIEForOffset(uint32_t Offset);
+
+ unsigned getMaxVersion() const { return MaxVersion; }
+
+ void setMaxVersionIfGreater(unsigned Version) {
+ if (Version > MaxVersion)
+ MaxVersion = Version;
+ }
+
const DWARFUnitIndex &getCUIndex();
DWARFGdbIndex &getGdbIndex();
const DWARFUnitIndex &getTUIndex();
@@ -198,12 +222,11 @@ public:
DIInliningInfo getInliningInfoForAddress(uint64_t Address,
DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
+ virtual StringRef getFileName() const = 0;
virtual bool isLittleEndian() const = 0;
virtual uint8_t getAddressSize() const = 0;
virtual const DWARFSection &getInfoSection() = 0;
- typedef MapVector<object::SectionRef, DWARFSection,
- std::map<object::SectionRef, unsigned>> TypeSectionMap;
- virtual const TypeSectionMap &getTypesSections() = 0;
+ virtual void forEachTypesSections(function_ref<void(DWARFSection &)> F) = 0;
virtual StringRef getAbbrevSection() = 0;
virtual const DWARFSection &getLocSection() = 0;
virtual StringRef getARangeSection() = 0;
@@ -211,23 +234,29 @@ public:
virtual StringRef getEHFrameSection() = 0;
virtual const DWARFSection &getLineSection() = 0;
virtual StringRef getStringSection() = 0;
- virtual StringRef getRangeSection() = 0;
+ virtual const DWARFSection& getRangeSection() = 0;
virtual StringRef getMacinfoSection() = 0;
virtual StringRef getPubNamesSection() = 0;
virtual StringRef getPubTypesSection() = 0;
virtual StringRef getGnuPubNamesSection() = 0;
virtual StringRef getGnuPubTypesSection() = 0;
+ /// DWARF v5
+ /// @{
+ virtual const DWARFSection &getStringOffsetSection() = 0;
+ /// @}
+
// Sections for DWARF5 split dwarf proposal.
virtual const DWARFSection &getInfoDWOSection() = 0;
- virtual const TypeSectionMap &getTypesDWOSections() = 0;
+ virtual void
+ forEachTypesDWOSections(function_ref<void(DWARFSection &)> F) = 0;
virtual StringRef getAbbrevDWOSection() = 0;
virtual const DWARFSection &getLineDWOSection() = 0;
virtual const DWARFSection &getLocDWOSection() = 0;
virtual StringRef getStringDWOSection() = 0;
- virtual StringRef getStringOffsetDWOSection() = 0;
- virtual StringRef getRangeDWOSection() = 0;
- virtual StringRef getAddrSection() = 0;
+ virtual const DWARFSection &getStringOffsetDWOSection() = 0;
+ virtual const DWARFSection &getRangeDWOSection() = 0;
+ virtual const DWARFSection &getAddrSection() = 0;
virtual const DWARFSection& getAppleNamesSection() = 0;
virtual const DWARFSection& getAppleTypesSection() = 0;
virtual const DWARFSection& getAppleNamespacesSection() = 0;
@@ -240,6 +269,8 @@ public:
return version == 2 || version == 3 || version == 4 || version == 5;
}
+ std::shared_ptr<DWARFContext> getDWOContext(StringRef AbsolutePath);
+
private:
/// Return the compile unit that includes an offset (relative to .debug_info).
DWARFCompileUnit *getCompileUnitForOffset(uint32_t Offset);
@@ -249,12 +280,21 @@ private:
DWARFCompileUnit *getCompileUnitForAddress(uint64_t Address);
};
+/// 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 };
+
/// DWARFContextInMemory is the simplest possible implementation of a
/// DWARFContext. It assumes all content is available in memory and stores
/// pointers to it.
class DWARFContextInMemory : public DWARFContext {
virtual void anchor();
+ using TypeSectionMap = MapVector<object::SectionRef, DWARFSection,
+ std::map<object::SectionRef, unsigned>>;
+
+ StringRef FileName;
bool IsLittleEndian;
uint8_t AddressSize;
DWARFSection InfoSection;
@@ -266,13 +306,18 @@ class DWARFContextInMemory : public DWARFContext {
StringRef EHFrameSection;
DWARFSection LineSection;
StringRef StringSection;
- StringRef RangeSection;
+ DWARFSection RangeSection;
StringRef MacinfoSection;
StringRef PubNamesSection;
StringRef PubTypesSection;
StringRef GnuPubNamesSection;
StringRef GnuPubTypesSection;
+ /// DWARF v5
+ /// @{
+ DWARFSection StringOffsetSection;
+ /// @}
+
// Sections for DWARF5 split dwarf proposal.
DWARFSection InfoDWOSection;
TypeSectionMap TypesDWOSections;
@@ -280,9 +325,9 @@ class DWARFContextInMemory : public DWARFContext {
DWARFSection LineDWOSection;
DWARFSection LocDWOSection;
StringRef StringDWOSection;
- StringRef StringOffsetDWOSection;
- StringRef RangeDWOSection;
- StringRef AddrSection;
+ DWARFSection StringOffsetDWOSection;
+ DWARFSection RangeDWOSection;
+ DWARFSection AddrSection;
DWARFSection AppleNamesSection;
DWARFSection AppleTypesSection;
DWARFSection AppleNamespacesSection;
@@ -293,14 +338,35 @@ class DWARFContextInMemory : public DWARFContext {
SmallVector<SmallString<32>, 4> UncompressedSections;
+ DWARFSection *mapNameToDWARFSection(StringRef Name);
+ StringRef *mapSectionToMember(StringRef Name);
+
+ /// If Sec is compressed section, decompresses and updates its contents
+ /// provided by Data. Otherwise leaves it unchanged.
+ Error maybeDecompress(const object::SectionRef &Sec, StringRef Name,
+ StringRef &Data);
+
+ /// 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);
+
public:
- DWARFContextInMemory(const object::ObjectFile &Obj,
- const LoadedObjectInfo *L = nullptr);
+ DWARFContextInMemory(
+ const object::ObjectFile &Obj, const LoadedObjectInfo *L = nullptr,
+ function_ref<ErrorPolicy(Error)> HandleError = defaultErrorHandler);
+
+ DWARFContextInMemory(const StringMap<std::unique_ptr<MemoryBuffer>> &Sections,
+ uint8_t AddrSize,
+ bool isLittleEndian = sys::IsLittleEndianHost);
+ StringRef getFileName() const override { return FileName; }
bool isLittleEndian() const override { return IsLittleEndian; }
uint8_t getAddressSize() const override { return AddressSize; }
const DWARFSection &getInfoSection() override { return InfoSection; }
- const TypeSectionMap &getTypesSections() override { return TypesSections; }
+ void forEachTypesSections(function_ref<void(DWARFSection &)> F) override {
+ for (auto &P : TypesSections)
+ F(P.second);
+ }
StringRef getAbbrevSection() override { return AbbrevSection; }
const DWARFSection &getLocSection() override { return LocSection; }
StringRef getARangeSection() override { return ARangeSection; }
@@ -308,7 +374,7 @@ public:
StringRef getEHFrameSection() override { return EHFrameSection; }
const DWARFSection &getLineSection() override { return LineSection; }
StringRef getStringSection() override { return StringSection; }
- StringRef getRangeSection() override { return RangeSection; }
+ const DWARFSection &getRangeSection() override { return RangeSection; }
StringRef getMacinfoSection() override { return MacinfoSection; }
StringRef getPubNamesSection() override { return PubNamesSection; }
StringRef getPubTypesSection() override { return PubTypesSection; }
@@ -319,22 +385,32 @@ public:
const DWARFSection& getAppleNamespacesSection() override { return AppleNamespacesSection; }
const DWARFSection& getAppleObjCSection() override { return AppleObjCSection; }
+ // DWARF v5
+ const DWARFSection &getStringOffsetSection() override {
+ return StringOffsetSection;
+ }
+
// Sections for DWARF5 split dwarf proposal.
const DWARFSection &getInfoDWOSection() override { return InfoDWOSection; }
- const TypeSectionMap &getTypesDWOSections() override {
- return TypesDWOSections;
+
+ void forEachTypesDWOSections(function_ref<void(DWARFSection &)> F) override {
+ for (auto &P : TypesDWOSections)
+ F(P.second);
}
+
StringRef getAbbrevDWOSection() override { return AbbrevDWOSection; }
const DWARFSection &getLineDWOSection() override { return LineDWOSection; }
const DWARFSection &getLocDWOSection() override { return LocDWOSection; }
StringRef getStringDWOSection() override { return StringDWOSection; }
- StringRef getStringOffsetDWOSection() override {
+
+ const DWARFSection &getStringOffsetDWOSection() override {
return StringOffsetDWOSection;
}
- StringRef getRangeDWOSection() override { return RangeDWOSection; }
- StringRef getAddrSection() override {
- return AddrSection;
- }
+
+ const DWARFSection &getRangeDWOSection() override { return RangeDWOSection; }
+
+ const DWARFSection &getAddrSection() override { return AddrSection; }
+
StringRef getCUIndexSection() override { return CUIndexSection; }
StringRef getGdbIndexSection() override { return GdbIndexSection; }
StringRef getTUIndexSection() override { return TUIndexSection; }
@@ -342,4 +418,4 @@ public:
} // end namespace llvm
-#endif // LLVM_LIB_DEBUGINFO_DWARFCONTEXT_H
+#endif // LLVM_DEBUGINFO_DWARF_DWARFCONTEXT_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFDataExtractor.h b/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFDataExtractor.h
new file mode 100644
index 0000000..ef4360f
--- /dev/null
+++ b/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFDataExtractor.h
@@ -0,0 +1,48 @@
+//===- DWARFDataExtractor.h -------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_DWARFDATAEXTRACTOR_H
+#define LLVM_DEBUGINFO_DWARFDATAEXTRACTOR_H
+
+#include "llvm/DebugInfo/DWARF/DWARFSection.h"
+#include "llvm/Support/DataExtractor.h"
+
+namespace llvm {
+
+/// A DataExtractor (typically for an in-memory copy of an object-file section)
+/// plus a relocation map for that section, if there is one.
+class DWARFDataExtractor : public DataExtractor {
+ const RelocAddrMap *RelocMap = nullptr;
+public:
+ /// Constructor for the normal case of extracting data from a DWARF section.
+ /// The DWARFSection's lifetime must be at least as long as the extractor's.
+ DWARFDataExtractor(const DWARFSection &Section, bool IsLittleEndian,
+ uint8_t AddressSize)
+ : DataExtractor(Section.Data, IsLittleEndian, AddressSize),
+ RelocMap(&Section.Relocs) {}
+
+ /// Constructor for cases when there are no relocations.
+ DWARFDataExtractor(StringRef Data, bool IsLittleEndian, uint8_t AddressSize)
+ : DataExtractor(Data, IsLittleEndian, AddressSize) {}
+
+ /// Extracts a value and applies a relocation to the result if
+ /// one exists for the given offset.
+ uint64_t getRelocatedValue(uint32_t Size, uint32_t *Off,
+ uint64_t *SectionIndex = nullptr) const;
+
+ /// Extracts an address-sized value and applies a relocation to the result if
+ /// one exists for the given offset.
+ uint64_t getRelocatedAddress(uint32_t *Off, uint64_t *SecIx = nullptr) const {
+ return getRelocatedValue(getAddressSize(), Off, SecIx);
+ }
+};
+
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_DWARFDATAEXTRACTOR_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h b/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h
index f732dee..6557159 100644
--- a/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h
+++ b/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h
@@ -1,4 +1,4 @@
-//===-- DWARFDebugAbbrev.h --------------------------------------*- C++ -*-===//
+//===- DWARFDebugAbbrev.h ---------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,15 +7,19 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIB_DEBUGINFO_DWARFDEBUGABBREV_H
-#define LLVM_LIB_DEBUGINFO_DWARFDEBUGABBREV_H
+#ifndef LLVM_DEBUGINFO_DWARFDEBUGABBREV_H
+#define LLVM_DEBUGINFO_DWARFDEBUGABBREV_H
#include "llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h"
+#include "llvm/Support/DataExtractor.h"
+#include <cstdint>
#include <map>
#include <vector>
namespace llvm {
+class raw_ostream;
+
class DWARFAbbreviationDeclarationSet {
uint32_t Offset;
/// Code of the first abbreviation, if all abbreviations in the set have
@@ -23,8 +27,8 @@ class DWARFAbbreviationDeclarationSet {
uint32_t FirstAbbrCode;
std::vector<DWARFAbbreviationDeclaration> Decls;
- typedef std::vector<DWARFAbbreviationDeclaration>::const_iterator
- const_iterator;
+ using const_iterator =
+ std::vector<DWARFAbbreviationDeclaration>::const_iterator;
public:
DWARFAbbreviationDeclarationSet();
@@ -49,8 +53,8 @@ private:
};
class DWARFDebugAbbrev {
- typedef std::map<uint64_t, DWARFAbbreviationDeclarationSet>
- DWARFAbbreviationDeclarationSetMap;
+ using DWARFAbbreviationDeclarationSetMap =
+ std::map<uint64_t, DWARFAbbreviationDeclarationSet>;
DWARFAbbreviationDeclarationSetMap AbbrDeclSets;
mutable DWARFAbbreviationDeclarationSetMap::const_iterator PrevAbbrOffsetPos;
@@ -76,6 +80,6 @@ private:
void clear();
};
-}
+} // end namespace llvm
-#endif
+#endif // LLVM_DEBUGINFO_DWARFDEBUGABBREV_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h b/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h
index 5a60239..dfbbb95 100644
--- a/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h
+++ b/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h
@@ -1,4 +1,4 @@
-//===-- DWARFDebugArangeSet.h -----------------------------------*- C++ -*-===//
+//===- DWARFDebugArangeSet.h ------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,11 +7,12 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIB_DEBUGINFO_DWARFDEBUGARANGESET_H
-#define LLVM_LIB_DEBUGINFO_DWARFDEBUGARANGESET_H
+#ifndef LLVM_DEBUGINFO_DWARFDEBUGARANGESET_H
+#define LLVM_DEBUGINFO_DWARFDEBUGARANGESET_H
#include "llvm/ADT/iterator_range.h"
#include "llvm/Support/DataExtractor.h"
+#include <cstdint>
#include <vector>
namespace llvm {
@@ -21,31 +22,32 @@ class raw_ostream;
class DWARFDebugArangeSet {
public:
struct Header {
- // The total length of the entries for that set, not including the length
- // field itself.
+ /// The total length of the entries for that set, not including the length
+ /// field itself.
uint32_t Length;
- // The offset from the beginning of the .debug_info section of the
- // compilation unit entry referenced by the table.
+ /// The offset from the beginning of the .debug_info section of the
+ /// compilation unit entry referenced by the table.
uint32_t CuOffset;
- // The DWARF version number.
+ /// 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.
+ /// 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 descriptor on the target architecture.
- // If the target system uses a flat address space, this value is 0.
+ /// The size in bytes of a segment descriptor on the target architecture.
+ /// If the target system uses a flat address space, this value is 0.
uint8_t SegSize;
};
struct Descriptor {
uint64_t Address;
uint64_t Length;
+
uint64_t getEndAddress() const { return Address + Length; }
};
private:
- typedef std::vector<Descriptor> DescriptorColl;
- typedef iterator_range<DescriptorColl::const_iterator> desc_iterator_range;
+ using DescriptorColl = std::vector<Descriptor>;
+ using desc_iterator_range = iterator_range<DescriptorColl::const_iterator>;
uint32_t Offset;
Header HeaderData;
@@ -53,6 +55,7 @@ private:
public:
DWARFDebugArangeSet() { clear(); }
+
void clear();
bool extract(DataExtractor data, uint32_t *offset_ptr);
void dump(raw_ostream &OS) const;
@@ -67,6 +70,6 @@ public:
}
};
-}
+} // end namespace llvm
-#endif
+#endif // LLVM_DEBUGINFO_DWARFDEBUGARANGESET_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugAranges.h b/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugAranges.h
index 791f010..ea71a50 100644
--- a/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugAranges.h
+++ b/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugAranges.h
@@ -1,4 +1,4 @@
-//===-- DWARFDebugAranges.h -------------------------------------*- C++ -*-===//
+//===- DWARFDebugAranges.h --------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,11 +7,12 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIB_DEBUGINFO_DWARFDEBUGARANGES_H
-#define LLVM_LIB_DEBUGINFO_DWARFDEBUGARANGES_H
+#ifndef LLVM_DEBUGINFO_DWARFDEBUGARANGES_H
+#define LLVM_DEBUGINFO_DWARFDEBUGARANGES_H
#include "llvm/ADT/DenseSet.h"
#include "llvm/Support/DataExtractor.h"
+#include <cstdint>
#include <vector>
namespace llvm {
@@ -27,7 +28,7 @@ private:
void clear();
void extract(DataExtractor DebugArangesData);
- // Call appendRange multiple times and then call construct.
+ /// Call appendRange multiple times and then call construct.
void appendRange(uint32_t CUOffset, uint64_t LowPC, uint64_t HighPC);
void construct();
@@ -42,6 +43,7 @@ private:
else
Length = HighPC - LowPC;
}
+
uint64_t HighPC() const {
if (Length)
return LowPC + Length;
@@ -51,13 +53,14 @@ private:
bool containsAddress(uint64_t Address) const {
return LowPC <= Address && Address < HighPC();
}
+
bool operator<(const Range &other) const {
return LowPC < other.LowPC;
}
- uint64_t LowPC; // Start of address range.
- uint32_t Length; // End of address range (not including this address).
- uint32_t CUOffset; // Offset of the compile unit or die.
+ uint64_t LowPC; /// Start of address range.
+ uint32_t Length; /// End of address range (not including this address).
+ uint32_t CUOffset; /// Offset of the compile unit or die.
};
struct RangeEndpoint {
@@ -73,15 +76,14 @@ private:
}
};
-
- typedef std::vector<Range> RangeColl;
- typedef RangeColl::const_iterator RangeCollIterator;
+ using RangeColl = std::vector<Range>;
+ using RangeCollIterator = RangeColl::const_iterator;
std::vector<RangeEndpoint> Endpoints;
RangeColl Aranges;
DenseSet<uint32_t> ParsedCUOffsets;
};
-}
+} // end namespace llvm
-#endif
+#endif // LLVM_DEBUGINFO_DWARFDEBUGARANGES_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h b/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h
index cd76c90..e0a779b 100644
--- a/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h
+++ b/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h
@@ -1,4 +1,4 @@
-//===-- DWARFDebugFrame.h - Parsing of .debug_frame -------------*- C++ -*-===//
+//===- DWARFDebugFrame.h - Parsing of .debug_frame --------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,23 +7,24 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIB_DEBUGINFO_DWARFDEBUGFRAME_H
-#define LLVM_LIB_DEBUGINFO_DWARFDEBUGFRAME_H
+#ifndef LLVM_DEBUGINFO_DWARF_DWARFDEBUGFRAME_H
+#define LLVM_DEBUGINFO_DWARF_DWARFDEBUGFRAME_H
#include "llvm/Support/DataExtractor.h"
-#include "llvm/Support/raw_ostream.h"
#include <memory>
#include <vector>
namespace llvm {
class FrameEntry;
+class raw_ostream;
/// \brief A parsed .debug_frame or .eh_frame section
///
class DWARFDebugFrame {
// True if this is parsing an eh_frame section.
bool IsEH;
+
public:
DWARFDebugFrame(bool IsEH);
~DWARFDebugFrame();
@@ -39,7 +40,6 @@ private:
std::vector<std::unique_ptr<FrameEntry>> Entries;
};
+} // end namespace llvm
-} // namespace llvm
-
-#endif
+#endif // LLVM_DEBUGINFO_DWARF_DWARFDEBUGFRAME_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h b/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h
index f36f470..88c8f57 100644
--- a/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h
+++ b/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h
@@ -1,4 +1,4 @@
-//===-- DWARFDebugInfoEntry.h -----------------------------------*- C++ -*-===//
+//===- DWARFDebugInfoEntry.h ------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,60 +7,57 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIB_DEBUGINFO_DWARFDEBUGINFOENTRY_H
-#define LLVM_LIB_DEBUGINFO_DWARFDEBUGINFOENTRY_H
+#ifndef LLVM_DEBUGINFO_DWARFDEBUGINFOENTRY_H
+#define LLVM_DEBUGINFO_DWARFDEBUGINFOENTRY_H
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/DebugInfo/DIContext.h"
+#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h"
-#include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
-#include "llvm/Support/DataTypes.h"
-#include "llvm/Support/Dwarf.h"
+#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
+#include <cstdint>
namespace llvm {
-class DWARFDebugAranges;
-class DWARFCompileUnit;
+class DataExtractor;
class DWARFUnit;
-class DWARFContext;
-class DWARFFormValue;
-struct DWARFDebugInfoEntryInlinedChain;
/// DWARFDebugInfoEntry - A DIE with only the minimum required data.
class DWARFDebugInfoEntry {
/// Offset within the .debug_info of the start of this entry.
- uint32_t Offset;
+ uint32_t Offset = 0;
/// The integer depth of this DIE within the compile unit DIEs where the
/// compile/type unit DIE has a depth of zero.
- uint32_t Depth;
+ uint32_t Depth = 0;
+
+ const DWARFAbbreviationDeclaration *AbbrevDecl = nullptr;
- const DWARFAbbreviationDeclaration *AbbrevDecl;
public:
- DWARFDebugInfoEntry()
- : Offset(0), Depth(0), AbbrevDecl(nullptr) {}
+ DWARFDebugInfoEntry() = default;
/// Extracts a debug info entry, which is a child of a given unit,
/// starting at a given offset. If DIE can't be extracted, returns false and
/// doesn't change OffsetPtr.
bool extractFast(const DWARFUnit &U, uint32_t *OffsetPtr);
+
/// High performance extraction should use this call.
bool extractFast(const DWARFUnit &U, uint32_t *OffsetPtr,
- const DataExtractor &DebugInfoData,
- uint32_t UEndOffset,
+ const DWARFDataExtractor &DebugInfoData, uint32_t UEndOffset,
uint32_t Depth);
uint32_t getOffset() const { return Offset; }
uint32_t getDepth() const { return Depth; }
+
dwarf::Tag getTag() const {
return AbbrevDecl ? AbbrevDecl->getTag() : dwarf::DW_TAG_null;
}
+
bool hasChildren() const { return AbbrevDecl && AbbrevDecl->hasChildren(); }
+
const DWARFAbbreviationDeclaration *getAbbreviationDeclarationPtr() const {
return AbbrevDecl;
}
};
-}
+} // end namespace llvm
-#endif
+#endif // LLVM_DEBUGINFO_DWARFDEBUGINFOENTRY_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h b/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h
index 878f1c7..0c8f98a 100644
--- a/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h
+++ b/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h
@@ -1,4 +1,4 @@
-//===-- DWARFDebugLine.h ----------------------------------------*- C++ -*-===//
+//===- DWARFDebugLine.h -----------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,12 +7,15 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIB_DEBUGINFO_DWARFDEBUGLINE_H
-#define LLVM_LIB_DEBUGINFO_DWARFDEBUGLINE_H
+#ifndef LLVM_DEBUGINFO_DWARFDEBUGLINE_H
+#define LLVM_DEBUGINFO_DWARFDEBUGLINE_H
+#include "llvm/ADT/StringRef.h"
#include "llvm/DebugInfo/DIContext.h"
+#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
+#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
#include "llvm/DebugInfo/DWARF/DWARFRelocMap.h"
-#include "llvm/Support/DataExtractor.h"
+#include <cstdint>
#include <map>
#include <string>
#include <vector>
@@ -23,181 +26,189 @@ class raw_ostream;
class DWARFDebugLine {
public:
- DWARFDebugLine(const RelocAddrMap* LineInfoRelocMap) : RelocMap(LineInfoRelocMap) {}
struct FileNameEntry {
- FileNameEntry() : Name(nullptr), DirIdx(0), ModTime(0), Length(0) {}
+ FileNameEntry() = default;
- const char *Name;
- uint64_t DirIdx;
- uint64_t ModTime;
- uint64_t Length;
+ StringRef Name;
+ uint64_t DirIdx = 0;
+ uint64_t ModTime = 0;
+ uint64_t Length = 0;
};
struct Prologue {
Prologue();
- // The size in bytes of the statement information for this compilation unit
- // (not including the total_length field itself).
+ /// The size in bytes of the statement information for this compilation unit
+ /// (not including the total_length field itself).
uint64_t TotalLength;
- // Version identifier for the statement information format.
- uint16_t Version;
- // The number of bytes following the prologue_length field to the beginning
- // of the first byte of the statement program itself.
+ /// Version, address size (starting in v5), and DWARF32/64 format; these
+ /// parameters affect interpretation of forms (used in the directory and
+ /// file tables starting with v5).
+ DWARFFormParams FormParams;
+ /// In v5, size in bytes of a segment selector.
+ uint8_t SegSelectorSize;
+ /// The number of bytes following the prologue_length field to the beginning
+ /// of the first byte of the statement program itself.
uint64_t PrologueLength;
- // The size in bytes of the smallest target machine instruction. Statement
- // program opcodes that alter the address register first multiply their
- // operands by this value.
+ /// The size in bytes of the smallest target machine instruction. Statement
+ /// program opcodes that alter the address register first multiply their
+ /// operands by this value.
uint8_t MinInstLength;
- // The maximum number of individual operations that may be encoded in an
- // instruction.
+ /// The maximum number of individual operations that may be encoded in an
+ /// instruction.
uint8_t MaxOpsPerInst;
- // The initial value of theis_stmtregister.
+ /// The initial value of theis_stmtregister.
uint8_t DefaultIsStmt;
- // This parameter affects the meaning of the special opcodes. See below.
+ /// This parameter affects the meaning of the special opcodes. See below.
int8_t LineBase;
- // This parameter affects the meaning of the special opcodes. See below.
+ /// This parameter affects the meaning of the special opcodes. See below.
uint8_t LineRange;
- // The number assigned to the first special opcode.
+ /// The number assigned to the first special opcode.
uint8_t OpcodeBase;
std::vector<uint8_t> StandardOpcodeLengths;
- std::vector<const char*> IncludeDirectories;
+ std::vector<StringRef> IncludeDirectories;
std::vector<FileNameEntry> FileNames;
- bool IsDWARF64;
- uint32_t sizeofTotalLength() const {
- return IsDWARF64 ? 12 : 4;
- }
- uint32_t sizeofPrologueLength() const {
- return IsDWARF64 ? 8 : 4;
- }
+ const DWARFFormParams getFormParams() const { return FormParams; }
+ uint16_t getVersion() const { return FormParams.Version; }
+ uint8_t getAddressSize() const { return FormParams.AddrSize; }
+ bool isDWARF64() const { return FormParams.Format == dwarf::DWARF64; }
+
+ uint32_t sizeofTotalLength() const { return isDWARF64() ? 12 : 4; }
- // Length of the prologue in bytes.
+ uint32_t sizeofPrologueLength() const { return isDWARF64() ? 8 : 4; }
+
+ /// Length of the prologue in bytes.
uint32_t getLength() const {
- return PrologueLength + sizeofTotalLength() + sizeof(Version) +
+ return PrologueLength + sizeofTotalLength() + sizeof(getVersion()) +
sizeofPrologueLength();
}
- // Length of the line table data in bytes (not including the prologue).
+
+ /// Length of the line table data in bytes (not including the prologue).
uint32_t getStatementTableLength() const {
return TotalLength + sizeofTotalLength() - getLength();
}
+
int32_t getMaxLineIncrementForSpecialOpcode() const {
return LineBase + (int8_t)LineRange - 1;
}
void clear();
void dump(raw_ostream &OS) const;
- bool parse(DataExtractor debug_line_data, uint32_t *offset_ptr);
+ bool parse(const DWARFDataExtractor &DebugLineData, uint32_t *OffsetPtr);
};
- // Standard .debug_line state machine structure.
+ /// Standard .debug_line state machine structure.
struct Row {
- explicit Row(bool default_is_stmt = false);
+ explicit Row(bool DefaultIsStmt = false);
/// Called after a row is appended to the matrix.
void postAppend();
- void reset(bool default_is_stmt);
+ void reset(bool DefaultIsStmt);
void dump(raw_ostream &OS) const;
- static bool orderByAddress(const Row& LHS, const Row& RHS) {
+ static void dumpTableHeader(raw_ostream &OS);
+
+ static bool orderByAddress(const Row &LHS, const Row &RHS) {
return LHS.Address < RHS.Address;
}
- // The program-counter value corresponding to a machine instruction
- // generated by the compiler.
+ /// The program-counter value corresponding to a machine instruction
+ /// generated by the compiler.
uint64_t Address;
- // An unsigned integer indicating a source line number. Lines are numbered
- // beginning at 1. The compiler may emit the value 0 in cases where an
- // instruction cannot be attributed to any source line.
+ /// An unsigned integer indicating a source line number. Lines are numbered
+ /// beginning at 1. The compiler may emit the value 0 in cases where an
+ /// instruction cannot be attributed to any source line.
uint32_t Line;
- // An unsigned integer indicating a column number within a source line.
- // Columns are numbered beginning at 1. The value 0 is reserved to indicate
- // that a statement begins at the 'left edge' of the line.
+ /// An unsigned integer indicating a column number within a source line.
+ /// Columns are numbered beginning at 1. The value 0 is reserved to indicate
+ /// that a statement begins at the 'left edge' of the line.
uint16_t Column;
- // An unsigned integer indicating the identity of the source file
- // corresponding to a machine instruction.
+ /// An unsigned integer indicating the identity of the source file
+ /// corresponding to a machine instruction.
uint16_t File;
- // An unsigned integer representing the DWARF path discriminator value
- // for this location.
+ /// An unsigned integer representing the DWARF path discriminator value
+ /// for this location.
uint32_t Discriminator;
- // An unsigned integer whose value encodes the applicable instruction set
- // architecture for the current instruction.
+ /// An unsigned integer whose value encodes the applicable instruction set
+ /// architecture for the current instruction.
uint8_t Isa;
- // A boolean indicating that the current instruction is the beginning of a
- // statement.
- uint8_t IsStmt:1,
- // A boolean indicating that the current instruction is the
- // beginning of a basic block.
- BasicBlock:1,
- // A boolean indicating that the current address is that of the
- // first byte after the end of a sequence of target machine
- // instructions.
- EndSequence:1,
- // A boolean indicating that the current address is one (of possibly
- // many) where execution should be suspended for an entry breakpoint
- // of a function.
- PrologueEnd:1,
- // A boolean indicating that the current address is one (of possibly
- // many) where execution should be suspended for an exit breakpoint
- // of a function.
- EpilogueBegin:1;
+ /// A boolean indicating that the current instruction is the beginning of a
+ /// statement.
+ uint8_t IsStmt : 1,
+ /// A boolean indicating that the current instruction is the
+ /// beginning of a basic block.
+ BasicBlock : 1,
+ /// A boolean indicating that the current address is that of the
+ /// first byte after the end of a sequence of target machine
+ /// instructions.
+ EndSequence : 1,
+ /// A boolean indicating that the current address is one (of possibly
+ /// many) where execution should be suspended for an entry breakpoint
+ /// of a function.
+ PrologueEnd : 1,
+ /// A boolean indicating that the current address is one (of possibly
+ /// many) where execution should be suspended for an exit breakpoint
+ /// of a function.
+ EpilogueBegin : 1;
};
- // Represents a series of contiguous machine instructions. Line table for each
- // compilation unit may consist of multiple sequences, which are not
- // guaranteed to be in the order of ascending instruction address.
+ /// Represents a series of contiguous machine instructions. Line table for
+ /// each compilation unit may consist of multiple sequences, which are not
+ /// guaranteed to be in the order of ascending instruction address.
struct Sequence {
- // Sequence describes instructions at address range [LowPC, HighPC)
- // and is described by line table rows [FirstRowIndex, LastRowIndex).
+ Sequence();
+
+ /// Sequence describes instructions at address range [LowPC, HighPC)
+ /// and is described by line table rows [FirstRowIndex, LastRowIndex).
uint64_t LowPC;
uint64_t HighPC;
unsigned FirstRowIndex;
unsigned LastRowIndex;
bool Empty;
- Sequence();
void reset();
- static bool orderByLowPC(const Sequence& LHS, const Sequence& RHS) {
+ static bool orderByLowPC(const Sequence &LHS, const Sequence &RHS) {
return LHS.LowPC < RHS.LowPC;
}
+
bool isValid() const {
return !Empty && (LowPC < HighPC) && (FirstRowIndex < LastRowIndex);
}
- bool containsPC(uint64_t pc) const {
- return (LowPC <= pc && pc < HighPC);
- }
+
+ bool containsPC(uint64_t PC) const { return (LowPC <= PC && PC < HighPC); }
};
struct LineTable {
LineTable();
- // Represents an invalid row
+ /// Represents an invalid row
const uint32_t UnknownRowIndex = UINT32_MAX;
- void appendRow(const DWARFDebugLine::Row &R) {
- Rows.push_back(R);
- }
+ void appendRow(const DWARFDebugLine::Row &R) { Rows.push_back(R); }
+
void appendSequence(const DWARFDebugLine::Sequence &S) {
Sequences.push_back(S);
}
- // Returns the index of the row with file/line info for a given address,
- // or UnknownRowIndex if there is no such row.
- uint32_t lookupAddress(uint64_t address) const;
+ /// Returns the index of the row with file/line info for a given address,
+ /// or UnknownRowIndex if there is no such row.
+ uint32_t lookupAddress(uint64_t Address) const;
- bool lookupAddressRange(uint64_t address, uint64_t size,
- std::vector<uint32_t> &result) const;
+ bool lookupAddressRange(uint64_t Address, uint64_t Size,
+ std::vector<uint32_t> &Result) const;
bool hasFileAtIndex(uint64_t FileIndex) const;
- // Extracts filename by its index in filename table in prologue.
- // Returns true on success.
+ /// Extracts filename by its index in filename table in prologue.
+ /// Returns true on success.
bool getFileNameByIndex(uint64_t FileIndex, const char *CompDir,
DILineInfoSpecifier::FileLineInfoKind Kind,
std::string &Result) const;
- // Fills the Result argument with the file and line information
- // corresponding to Address. Returns true on success.
+ /// Fills the Result argument with the file and line information
+ /// corresponding to Address. Returns true on success.
bool getFileLineInfoForAddress(uint64_t Address, const char *CompDir,
DILineInfoSpecifier::FileLineInfoKind Kind,
DILineInfo &Result) const;
@@ -206,49 +217,49 @@ public:
void clear();
/// Parse prologue and all rows.
- bool parse(DataExtractor debug_line_data, const RelocAddrMap *RMap,
- uint32_t *offset_ptr);
+ bool parse(const DWARFDataExtractor &DebugLineData, uint32_t *OffsetPtr);
+
+ using RowVector = std::vector<Row>;
+ using RowIter = RowVector::const_iterator;
+ using SequenceVector = std::vector<Sequence>;
+ using SequenceIter = SequenceVector::const_iterator;
struct Prologue Prologue;
- typedef std::vector<Row> RowVector;
- typedef RowVector::const_iterator RowIter;
- typedef std::vector<Sequence> SequenceVector;
- typedef SequenceVector::const_iterator SequenceIter;
RowVector Rows;
SequenceVector Sequences;
private:
- uint32_t findRowInSeq(const DWARFDebugLine::Sequence &seq,
- uint64_t address) const;
+ uint32_t findRowInSeq(const DWARFDebugLine::Sequence &Seq,
+ uint64_t Address) const;
};
- const LineTable *getLineTable(uint32_t offset) const;
- const LineTable *getOrParseLineTable(DataExtractor debug_line_data,
- uint32_t offset);
+ const LineTable *getLineTable(uint32_t Offset) const;
+ const LineTable *getOrParseLineTable(const DWARFDataExtractor &DebugLineData,
+ uint32_t Offset);
private:
struct ParsingState {
ParsingState(struct LineTable *LT);
void resetRowAndSequence();
- void appendRowToMatrix(uint32_t offset);
+ void appendRowToMatrix(uint32_t Offset);
- // Line table we're currently parsing.
+ /// Line table we're currently parsing.
struct LineTable *LineTable;
- // The row number that starts at zero for the prologue, and increases for
- // each row added to the matrix.
- unsigned RowNumber;
+ /// The row number that starts at zero for the prologue, and increases for
+ /// each row added to the matrix.
+ unsigned RowNumber = 0;
struct Row Row;
struct Sequence Sequence;
};
- typedef std::map<uint32_t, LineTable> LineTableMapTy;
- typedef LineTableMapTy::iterator LineTableIter;
- typedef LineTableMapTy::const_iterator LineTableConstIter;
+ using LineTableMapTy = std::map<uint32_t, LineTable>;
+ using LineTableIter = LineTableMapTy::iterator;
+ using LineTableConstIter = LineTableMapTy::const_iterator;
- const RelocAddrMap *RelocMap;
LineTableMapTy LineTableMap;
};
-}
-#endif
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_DWARFDEBUGLINE_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h b/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h
index bd44c2e..c2b8d0c 100644
--- a/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h
+++ b/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h
@@ -1,4 +1,4 @@
-//===-- DWARFDebugLoc.h -----------------------------------------*- C++ -*-===//
+//===- DWARFDebugLoc.h ------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,12 +7,13 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIB_DEBUGINFO_DWARFDEBUGLOC_H
-#define LLVM_LIB_DEBUGINFO_DWARFDEBUGLOC_H
+#ifndef LLVM_DEBUGINFO_DWARF_DWARFDEBUGLOC_H
+#define LLVM_DEBUGINFO_DWARF_DWARFDEBUGLOC_H
#include "llvm/ADT/SmallVector.h"
+#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
#include "llvm/DebugInfo/DWARF/DWARFRelocMap.h"
-#include "llvm/Support/DataExtractor.h"
+#include <cstdint>
namespace llvm {
@@ -38,22 +39,19 @@ class DWARFDebugLoc {
SmallVector<Entry, 2> Entries;
};
- typedef SmallVector<LocationList, 4> LocationLists;
+ using LocationLists = SmallVector<LocationList, 4>;
/// A list of all the variables in the debug_loc section, each one describing
/// the locations in which the variable is stored.
LocationLists Locations;
- /// A map used to resolve binary relocations.
- const RelocAddrMap &RelocMap;
-
public:
- DWARFDebugLoc(const RelocAddrMap &LocRelocMap) : RelocMap(LocRelocMap) {}
/// Print the location lists found within the debug_loc section.
void dump(raw_ostream &OS) const;
+
/// Parse the debug_loc section accessible via the 'data' parameter using the
- /// specified address size to interpret the address ranges.
- void parse(DataExtractor data, unsigned AddressSize);
+ /// address size also given in 'data' to interpret the address ranges.
+ void parse(const DWARFDataExtractor &data);
};
class DWARFDebugLocDWO {
@@ -68,7 +66,7 @@ class DWARFDebugLocDWO {
SmallVector<Entry, 2> Entries;
};
- typedef SmallVector<LocationList, 4> LocationLists;
+ using LocationLists = SmallVector<LocationList, 4>;
LocationLists Locations;
@@ -76,6 +74,7 @@ public:
void parse(DataExtractor data);
void dump(raw_ostream &OS) const;
};
-}
-#endif
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_DWARF_DWARFDEBUGLOC_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugMacro.h b/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugMacro.h
index 5a0352d..135c507 100644
--- a/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugMacro.h
+++ b/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugMacro.h
@@ -1,4 +1,4 @@
-//===-- DWARFDebugMacro.h ---------------------------------------*- C++ -*-===//
+//===- DWARFDebugMacro.h ----------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -40,7 +40,7 @@ class DWARFDebugMacro {
};
};
- typedef SmallVector<Entry, 4> MacroList;
+ using MacroList = SmallVector<Entry, 4>;
/// A list of all the macro entries in the debug_macinfo section.
MacroList Macros;
@@ -50,6 +50,7 @@ public:
/// Print the macro list found within the debug_macinfo section.
void dump(raw_ostream &OS) const;
+
/// Parse the debug_macinfo section accessible via the 'data' parameter.
void parse(DataExtractor data);
};
diff --git a/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugPubTable.h b/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugPubTable.h
index 2b23837..a309fd1 100644
--- a/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugPubTable.h
+++ b/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugPubTable.h
@@ -1,4 +1,4 @@
-//===-- DWARFDebugPubTable.h ------------------------------------*- C++ -*-===//
+//===- DWARFDebugPubTable.h -------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,13 +7,13 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIB_DEBUGINFO_DWARFDEBUGPUBTABLE_H
-#define LLVM_LIB_DEBUGINFO_DWARFDEBUGPUBTABLE_H
+#ifndef LLVM_DEBUGINFO_DWARF_DWARFDEBUGPUBTABLE_H
+#define LLVM_DEBUGINFO_DWARF_DWARFDEBUGPUBTABLE_H
-#include "llvm/ADT/iterator_range.h"
#include "llvm/ADT/ArrayRef.h"
-#include "llvm/Support/DataExtractor.h"
-#include "llvm/Support/Dwarf.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/BinaryFormat/Dwarf.h"
+#include <cstdint>
#include <vector>
namespace llvm {
@@ -28,7 +28,7 @@ public:
uint32_t SecOffset;
/// An entry of the various gnu_pub* debug sections.
- llvm::dwarf::PubIndexEntryDescriptor Descriptor;
+ dwarf::PubIndexEntryDescriptor Descriptor;
/// The name of the object as given by the DW_AT_name attribute of the
/// referenced DIE.
@@ -68,10 +68,12 @@ private:
public:
DWARFDebugPubTable(StringRef Data, bool LittleEndian, bool GnuStyle);
+
void dump(StringRef Name, raw_ostream &OS) const;
ArrayRef<Set> getData() { return Sets; }
};
-}
-#endif
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_DWARF_DWARFDEBUGPUBTABLE_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h b/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h
index c930bd6..bcba14b 100644
--- a/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h
+++ b/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h
@@ -1,4 +1,4 @@
-//===-- DWARFDebugRangeList.h -----------------------------------*- C++ -*-===//
+//===- DWARFDebugRangeList.h ------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,45 +7,58 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIB_DEBUGINFO_DWARFDEBUGRANGELIST_H
-#define LLVM_LIB_DEBUGINFO_DWARFDEBUGRANGELIST_H
+#ifndef LLVM_DEBUGINFO_DWARF_DWARFDEBUGRANGELIST_H
+#define LLVM_DEBUGINFO_DWARF_DWARFDEBUGRANGELIST_H
-#include "llvm/Support/DataExtractor.h"
+#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
+#include "llvm/DebugInfo/DWARF/DWARFRelocMap.h"
+#include <cassert>
+#include <cstdint>
#include <vector>
namespace llvm {
class raw_ostream;
+struct DWARFAddressRange {
+ uint64_t LowPC;
+ uint64_t HighPC;
+ uint64_t SectionIndex;
+};
+
/// DWARFAddressRangesVector - represents a set of absolute address ranges.
-typedef std::vector<std::pair<uint64_t, uint64_t>> DWARFAddressRangesVector;
+using DWARFAddressRangesVector = std::vector<DWARFAddressRange>;
class DWARFDebugRangeList {
public:
struct RangeListEntry {
- // A beginning address offset. This address offset has the size of an
- // address and is relative to the applicable base address of the
- // compilation unit referencing this range list. It marks the beginning
- // of an address range.
+ /// A beginning address offset. This address offset has the size of an
+ /// address and is relative to the applicable base address of the
+ /// compilation unit referencing this range list. It marks the beginning
+ /// of an address range.
uint64_t StartAddress;
- // An ending address offset. This address offset again has the size of
- // an address and is relative to the applicable base address of the
- // compilation unit referencing this range list. It marks the first
- // address past the end of the address range. The ending address must
- // be greater than or equal to the beginning address.
+ /// An ending address offset. This address offset again has the size of
+ /// an address and is relative to the applicable base address of the
+ /// compilation unit referencing this range list. It marks the first
+ /// address past the end of the address range. The ending address must
+ /// be greater than or equal to the beginning address.
uint64_t EndAddress;
- // The end of any given range list is marked by an end of list entry,
- // which consists of a 0 for the beginning address offset
- // and a 0 for the ending address offset.
+ /// A section index this range belongs to.
+ uint64_t SectionIndex;
+
+ /// The end of any given range list is marked by an end of list entry,
+ /// which consists of a 0 for the beginning address offset
+ /// and a 0 for the ending address offset.
bool isEndOfListEntry() const {
return (StartAddress == 0) && (EndAddress == 0);
}
- // A base address selection entry consists of:
- // 1. The value of the largest representable address offset
- // (for example, 0xffffffff when the size of an address is 32 bits).
- // 2. An address, which defines the appropriate base address for
- // use in interpreting the beginning and ending address offsets of
- // subsequent entries of the location list.
+
+ /// A base address selection entry consists of:
+ /// 1. The value of the largest representable address offset
+ /// (for example, 0xffffffff when the size of an address is 32 bits).
+ /// 2. An address, which defines the appropriate base address for
+ /// use in interpreting the beginning and ending address offsets of
+ /// subsequent entries of the location list.
bool isBaseAddressSelectionEntry(uint8_t AddressSize) const {
assert(AddressSize == 4 || AddressSize == 8);
if (AddressSize == 4)
@@ -56,16 +69,17 @@ public:
};
private:
- // Offset in .debug_ranges section.
+ /// Offset in .debug_ranges section.
uint32_t Offset;
uint8_t AddressSize;
std::vector<RangeListEntry> Entries;
public:
DWARFDebugRangeList() { clear(); }
+
void clear();
void dump(raw_ostream &OS) const;
- bool extract(DataExtractor data, uint32_t *offset_ptr);
+ bool extract(const DWARFDataExtractor &data, uint32_t *offset_ptr);
const std::vector<RangeListEntry> &getEntries() { return Entries; }
/// getAbsoluteRanges - Returns absolute address ranges defined by this range
@@ -74,6 +88,6 @@ public:
DWARFAddressRangesVector getAbsoluteRanges(uint64_t BaseAddress) const;
};
-} // namespace llvm
+} // end namespace llvm
-#endif // LLVM_DEBUGINFO_DWARFDEBUGRANGELIST_H
+#endif // LLVM_DEBUGINFO_DWARF_DWARFDEBUGRANGELIST_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFDie.h b/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFDie.h
index e335e28..b216491 100644
--- a/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFDie.h
+++ b/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFDie.h
@@ -1,4 +1,4 @@
-//===-- DWARFDie.h --------------------------------------------------------===//
+//===- DWARFDie.h -----------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,20 +7,27 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIB_DEBUGINFO_DWARFDIE_H
-#define LLVM_LIB_DEBUGINFO_DWARFDIE_H
+#ifndef LLVM_DEBUGINFO_DWARFDIE_H
+#define LLVM_DEBUGINFO_DWARFDIE_H
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/Optional.h"
#include "llvm/ADT/iterator.h"
#include "llvm/ADT/iterator_range.h"
-#include "llvm/ADT/Optional.h"
+#include "llvm/BinaryFormat/Dwarf.h"
+#include "llvm/DebugInfo/DIContext.h"
+#include "llvm/DebugInfo/DWARF/DWARFAttribute.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h"
+#include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
+#include <cassert>
+#include <cstdint>
+#include <iterator>
namespace llvm {
-
+
class DWARFUnit;
-class DWARFDebugInfoEntry;
class raw_ostream;
-
+
//===----------------------------------------------------------------------===//
/// Utility class that carries the DWARF compile/type unit and the debug info
/// entry in an object.
@@ -34,18 +41,18 @@ class raw_ostream;
/// also simplifies the attribute extraction calls by not having to specify the
/// DWARFUnit for each call.
class DWARFDie {
- DWARFUnit *U;
- const DWARFDebugInfoEntry *Die;
+ DWARFUnit *U = nullptr;
+ const DWARFDebugInfoEntry *Die = nullptr;
+
public:
- DWARFDie() : U(nullptr), Die(nullptr) {}
+ DWARFDie() = default;
DWARFDie(DWARFUnit *Unit, const DWARFDebugInfoEntry * D) : U(Unit), Die(D) {}
-
+
bool isValid() const { return U && Die; }
explicit operator bool() const { return isValid(); }
const DWARFDebugInfoEntry *getDebugInfoEntry() const { return Die; }
DWARFUnit *getDwarfUnit() const { return U; }
-
/// Get the abbreviation declaration for this DIE.
///
/// \returns the abbreviation declaration or NULL for null tags.
@@ -61,7 +68,7 @@ public:
assert(isValid() && "must check validity prior to calling");
return Die->getOffset();
}
-
+
dwarf::Tag getTag() const {
auto AbbrevDecl = getAbbreviationDeclarationPtr();
if (AbbrevDecl)
@@ -73,11 +80,12 @@ public:
assert(isValid() && "must check validity prior to calling");
return Die->hasChildren();
}
-
+
/// Returns true for a valid DIE that terminates a sibling chain.
bool isNULL() const {
return getAbbreviationDeclarationPtr() == nullptr;
}
+
/// Returns true if DIE represents a subprogram (not inlined).
bool isSubprogramDIE() const;
@@ -89,13 +97,13 @@ public:
/// \returns a valid DWARFDie instance if this object has a parent or an
/// invalid DWARFDie instance if it doesn't.
DWARFDie getParent() const;
-
+
/// Get the sibling of this DIE object.
///
/// \returns a valid DWARFDie instance if this object has a sibling or an
/// invalid DWARFDie instance if it doesn't.
DWARFDie getSibling() const;
-
+
/// Get the first child of this DIE object.
///
/// \returns a valid DWARFDie instance if this object has children or an
@@ -105,15 +113,16 @@ public:
return DWARFDie(U, Die + 1);
return DWARFDie();
}
-
+
/// Dump the DIE and all of its attributes to the supplied stream.
///
/// \param OS the stream to use for output.
/// \param recurseDepth the depth to recurse to when dumping this DIE and its
/// children.
/// \param indent the number of characters to indent each line that is output.
- void dump(raw_ostream &OS, unsigned recurseDepth, unsigned indent = 0) const;
-
+ void dump(raw_ostream &OS, unsigned recurseDepth, unsigned indent = 0,
+ DIDumpOptions DumpOpts = DIDumpOptions()) const;
+
/// Extract the specified attribute from this DIE.
///
/// Extract an attribute value from this DIE only. This call doesn't look
@@ -123,76 +132,33 @@ public:
/// \param Attr the attribute to extract.
/// \returns an optional DWARFFormValue that will have the form value if the
/// attribute was successfully extracted.
- Optional<DWARFFormValue> getAttributeValue(dwarf::Attribute Attr) const;
-
- /// Extract the specified attribute from this DIE as a C string.
- ///
- /// Extract an attribute value from this DIE only. This call doesn't look
- /// for the attribute value in any DW_AT_specification or
- /// DW_AT_abstract_origin referenced DIEs.
- ///
- /// \param Attr the attribute to extract.
- /// \param FailValue the value to return if this DIE doesn't have this
- /// attribute.
- /// \returns the NULL terminated C string value owned by the DWARF section
- /// that contains the string or FailValue if the attribute doesn't exist or
- /// if the attribute's form isn't a form that describes an string.
- const char *getAttributeValueAsString(dwarf::Attribute Attr,
- const char *FailValue) const;
-
- /// Extract the specified attribute from this DIE as an address.
- ///
- /// Extract an attribute value from this DIE only. This call doesn't look
- /// for the attribute value in any DW_AT_specification or
- /// DW_AT_abstract_origin referenced DIEs.
- ///
- /// \param Attr the attribute to extract.
- /// \returns an optional value for the attribute.
- Optional<uint64_t> getAttributeValueAsAddress(dwarf::Attribute Attr) const;
-
- /// Extract the specified attribute from this DIE as a signed integer.
- ///
- /// Extract an attribute value from this DIE only. This call doesn't look
- /// for the attribute value in any DW_AT_specification or
- /// DW_AT_abstract_origin referenced DIEs.
- ///
- /// \param Attr the attribute to extract.
- /// \returns an optional value for the attribute.
- Optional<int64_t>
- getAttributeValueAsSignedConstant(dwarf::Attribute Attr) const;
-
- /// Extract the specified attribute from this DIE as an unsigned integer.
- ///
- /// Extract an attribute value from this DIE only. This call doesn't look
- /// for the attribute value in any DW_AT_specification or
- /// DW_AT_abstract_origin referenced DIEs.
- ///
- /// \param Attr the attribute to extract.
- /// \returns an optional value for the attribute.
- Optional<uint64_t>
- getAttributeValueAsUnsignedConstant(dwarf::Attribute Attr) const;
+ Optional<DWARFFormValue> find(dwarf::Attribute Attr) const;
+
+ /// Extract the first value of any attribute in Attrs from this DIE.
+ ///
+ /// Extract the first attribute that matches from this DIE only. This call
+ /// doesn't look for the attribute value in any DW_AT_specification or
+ /// DW_AT_abstract_origin referenced DIEs. The attributes will be searched
+ /// linearly in the order they are specified within Attrs.
+ ///
+ /// \param Attrs an array of DWARF attribute to look for.
+ /// \returns an optional that has a valid DWARFFormValue for the first
+ /// matching attribute in Attrs, or None if none of the attributes in Attrs
+ /// exist in this DIE.
+ Optional<DWARFFormValue> find(ArrayRef<dwarf::Attribute> Attrs) const;
+
+ /// Extract the first value of any attribute in Attrs from this DIE and
+ /// recurse into any DW_AT_specification or DW_AT_abstract_origin referenced
+ /// DIEs.
+ ///
+ /// \param Attrs an array of DWARF attribute to look for.
+ /// \returns an optional that has a valid DWARFFormValue for the first
+ /// matching attribute in Attrs, or None if none of the attributes in Attrs
+ /// exist in this DIE or in any DW_AT_specification or DW_AT_abstract_origin
+ /// DIEs.
+ Optional<DWARFFormValue>
+ findRecursively(ArrayRef<dwarf::Attribute> Attrs) const;
- /// Extract the specified attribute from this DIE as absolute DIE Offset.
- ///
- /// Extract an attribute value from this DIE only. This call doesn't look
- /// for the attribute value in any DW_AT_specification or
- /// DW_AT_abstract_origin referenced DIEs.
- ///
- /// \param Attr the attribute to extract.
- /// \returns an optional value for the attribute.
- Optional<uint64_t> getAttributeValueAsReference(dwarf::Attribute Attr) const;
-
- /// Extract the specified attribute from this DIE as absolute section offset.
- ///
- /// Extract an attribute value from this DIE only. This call doesn't look
- /// for the attribute value in any DW_AT_specification or
- /// DW_AT_abstract_origin referenced DIEs.
- ///
- /// \param Attr the attribute to extract.
- /// \returns an optional value for the attribute.
- Optional<uint64_t>
- getAttributeValueAsSectionOffset(dwarf::Attribute Attr) const;
-
/// Extract the specified attribute from this DIE as the referenced DIE.
///
/// Regardless of the reference type, return the correct DWARFDie instance if
@@ -215,7 +181,7 @@ public:
///
/// \returns anm optional absolute section offset value for the attribute.
Optional<uint64_t> getRangesBaseAttribute() const;
-
+
/// Get the DW_AT_high_pc attribute value as an address.
///
/// In DWARF version 4 and later the high PC can be encoded as an offset from
@@ -230,8 +196,9 @@ public:
/// Retrieves DW_AT_low_pc and DW_AT_high_pc from CU.
/// Returns true if both attributes are present.
- bool getLowAndHighPC(uint64_t &LowPC, uint64_t &HighPC) const;
-
+ bool getLowAndHighPC(uint64_t &LowPC, uint64_t &HighPC,
+ uint64_t &SectionIndex) const;
+
/// Get the address ranges for this DIE.
///
/// Get the hi/low PC range if both attributes are available or exrtracts the
@@ -243,7 +210,7 @@ public:
/// \returns a address range vector that might be empty if no address range
/// information is available.
DWARFAddressRangesVector getAddressRanges() const;
-
+
/// Get all address ranges for any DW_TAG_subprogram DIEs in this DIE or any
/// of its children.
///
@@ -253,19 +220,25 @@ public:
///
/// \param Ranges the addres range vector to fill in.
void collectChildrenAddressRanges(DWARFAddressRangesVector &Ranges) const;
-
+
bool addressRangeContainsAddress(const uint64_t Address) const;
-
+
/// If a DIE represents a subprogram (or inlined subroutine), returns its
/// mangled name (or short name, if mangled is missing). This name may be
/// fetched from specification or abstract origin for this subprogram.
/// 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.
const char *getName(DINameKind Kind) 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
+ /// DW_AT_abstract_origin references if necessary.
+ uint64_t getDeclLine() const;
+
/// Retrieves values of DW_AT_call_file, DW_AT_call_line and DW_AT_call_column
/// from DIE (or zeroes if they are missing). This function looks for
/// DW_AT_call attributes in this DIE only, it will not resolve the attribute
@@ -276,24 +249,52 @@ public:
/// DW_AT_call_line attribute in this DIE.
/// \param CallColumn filled in with non-zero if successful, zero if there is
/// no DW_AT_call_column attribute in this DIE.
+ /// \param CallDiscriminator filled in with non-zero if successful, zero if
+ /// there is no DW_AT_GNU_discriminator attribute in this DIE.
void getCallerFrame(uint32_t &CallFile, uint32_t &CallLine,
- uint32_t &CallColumn) const;
-
- /// Get inlined chain for a given address, rooted at the current DIE.
- /// Returns empty chain if address is not contained in address range
- /// of current DIE.
- void
- getInlinedChainForAddress(const uint64_t Address,
- SmallVectorImpl<DWARFDie> &InlinedChain) const;
+ uint32_t &CallColumn, uint32_t &CallDiscriminator) const;
+
+ class attribute_iterator;
+
+ /// Get an iterator range to all attributes in the current DIE only.
+ ///
+ /// \returns an iterator range for the attributes of the current DIE.
+ iterator_range<attribute_iterator> attributes() const;
class iterator;
-
+
iterator begin() const;
iterator end() const;
iterator_range<iterator> children() const;
};
-
+class DWARFDie::attribute_iterator :
+ public iterator_facade_base<attribute_iterator, std::forward_iterator_tag,
+ const DWARFAttribute> {
+ /// The DWARF DIE we are extracting attributes from.
+ DWARFDie Die;
+ /// The value vended to clients via the operator*() or operator->().
+ DWARFAttribute AttrValue;
+ /// The attribute index within the abbreviation declaration in Die.
+ uint32_t Index;
+
+ /// Update the attribute index and attempt to read the attribute value. If the
+ /// attribute is able to be read, update AttrValue and the Index member
+ /// variable. If the attribute value is not able to be read, an appropriate
+ /// error will be set if the Err member variable is non-NULL and the iterator
+ /// will be set to the end value so iteration stops.
+ void updateForIndex(const DWARFAbbreviationDeclaration &AbbrDecl, uint32_t I);
+
+public:
+ attribute_iterator() = delete;
+ explicit attribute_iterator(DWARFDie D, bool End);
+
+ attribute_iterator &operator++();
+ explicit operator bool() const { return AttrValue.isValid(); }
+ const DWARFAttribute &operator*() const { return AttrValue; }
+ bool operator==(const attribute_iterator &X) const { return Index == X.Index; }
+};
+
inline bool operator==(const DWARFDie &LHS, const DWARFDie &RHS) {
return LHS.getDebugInfoEntry() == RHS.getDebugInfoEntry() &&
LHS.getDwarfUnit() == RHS.getDwarfUnit();
@@ -313,16 +314,19 @@ class DWARFDie::iterator : public iterator_facade_base<iterator,
}
public:
iterator() = default;
+
explicit iterator(DWARFDie D) : Die(D) {
// If we start out with only a Null DIE then invalidate.
skipNull();
}
+
iterator &operator++() {
Die = Die.getSibling();
// Don't include the NULL die when iterating.
skipNull();
return *this;
}
+
explicit operator bool() const { return Die.isValid(); }
const DWARFDie &operator*() const { return Die; }
bool operator==(const iterator &X) const { return Die == X.Die; }
@@ -344,4 +348,4 @@ inline iterator_range<DWARFDie::iterator> DWARFDie::children() const {
} // end namespace llvm
-#endif // LLVM_LIB_DEBUGINFO_DWARFDIE_H
+#endif // LLVM_DEBUGINFO_DWARFDIE_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFFormValue.h b/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFFormValue.h
index 1b7659d..008dba9 100644
--- a/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFFormValue.h
+++ b/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFFormValue.h
@@ -1,4 +1,4 @@
-//===-- DWARFFormValue.h ----------------------------------------*- C++ -*-===//
+//===- DWARFFormValue.h -----------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -10,16 +10,47 @@
#ifndef LLVM_DEBUGINFO_DWARFFORMVALUE_H
#define LLVM_DEBUGINFO_DWARFFORMVALUE_H
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/None.h"
#include "llvm/ADT/Optional.h"
-#include "llvm/Support/DataExtractor.h"
-#include "llvm/Support/Dwarf.h"
+#include "llvm/BinaryFormat/Dwarf.h"
+#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
+#include <cstdint>
namespace llvm {
-template <typename T> class ArrayRef;
class DWARFUnit;
class raw_ostream;
+/// A helper struct for DWARFFormValue methods, providing information that
+/// allows it to know the byte size of DW_FORM values that vary in size
+/// depending on the DWARF version, address byte size, or DWARF32/DWARF64.
+struct DWARFFormParams {
+ uint16_t Version;
+ uint8_t AddrSize;
+ dwarf::DwarfFormat Format;
+
+ /// The definition of the size of form DW_FORM_ref_addr depends on the
+ /// version. In DWARF v2 it's the size of an address; after that, it's the
+ /// size of a reference.
+ uint8_t getRefAddrByteSize() const {
+ if (Version == 2)
+ return AddrSize;
+ return getDwarfOffsetByteSize();
+ }
+
+ /// The size of a reference is determined by the DWARF 32/64-bit format.
+ uint8_t getDwarfOffsetByteSize() const {
+ switch (Format) {
+ case dwarf::DwarfFormat::DWARF32:
+ return 4;
+ case dwarf::DwarfFormat::DWARF64:
+ return 8;
+ }
+ llvm_unreachable("Invalid Format value");
+ }
+};
+
class DWARFFormValue {
public:
enum FormClass {
@@ -37,43 +68,54 @@ public:
private:
struct ValueType {
- ValueType() : data(nullptr) {
- uval = 0;
- }
+ ValueType() { uval = 0; }
union {
uint64_t uval;
int64_t sval;
- const char* cstr;
+ const char *cstr;
};
- const uint8_t* data;
+ const uint8_t *data = nullptr;
+ uint64_t SectionIndex; /// Section index for reference forms.
};
- dwarf::Form Form; // Form for this value.
- ValueType Value; // Contains all data for the form.
- const DWARFUnit *U; // Remember the DWARFUnit at extract time.
+ dwarf::Form Form; /// Form for this value.
+ ValueType Value; /// Contains all data for the form.
+ const DWARFUnit *U = nullptr; /// Remember the DWARFUnit at extract time.
public:
- DWARFFormValue(dwarf::Form F = dwarf::Form(0)) : Form(F), U(nullptr) {}
+ DWARFFormValue(dwarf::Form F = dwarf::Form(0)) : Form(F) {}
+
dwarf::Form getForm() const { return Form; }
+ uint64_t getRawUValue() const { return Value.uval; }
+ uint64_t getSectionIndex() const { return Value.SectionIndex; }
void setForm(dwarf::Form F) { Form = F; }
void setUValue(uint64_t V) { Value.uval = V; }
void setSValue(int64_t V) { Value.sval = V; }
void setPValue(const char *V) { Value.cstr = V; }
+
+ void setBlockValue(const ArrayRef<uint8_t> &Data) {
+ Value.data = Data.data();
+ setUValue(Data.size());
+ }
+
bool isFormClass(FormClass FC) const;
const DWARFUnit *getUnit() const { return U; }
void dump(raw_ostream &OS) const;
- /// \brief extracts a value in data at offset *offset_ptr.
+ /// Extracts a value in \p Data at offset \p *OffsetPtr.
///
- /// The passed DWARFUnit is allowed to be nullptr, in which
- /// case no relocation processing will be performed and some
+ /// The passed DWARFUnit is allowed to be nullptr, in which case some
/// kind of forms that depend on Unit information are disallowed.
+ /// \param Data The DWARFDataExtractor to use.
+ /// \param OffsetPtr The offset within \p Data where the data starts.
+ /// \param U The optional DWARFUnit supplying information for some forms.
/// \returns whether the extraction succeeded.
- bool extractValue(const DataExtractor &Data, uint32_t *OffsetPtr,
+ bool extractValue(const DWARFDataExtractor &Data, uint32_t *OffsetPtr,
const DWARFUnit *U);
+
bool isInlinedCStr() const {
- return Value.data != nullptr && Value.data == (const uint8_t*)Value.cstr;
+ return Value.data != nullptr && Value.data == (const uint8_t *)Value.cstr;
}
/// getAsFoo functions below return the extracted value as Foo if only
@@ -87,83 +129,196 @@ public:
Optional<ArrayRef<uint8_t>> getAsBlock() const;
Optional<uint64_t> getAsCStringOffset() const;
Optional<uint64_t> getAsReferenceUVal() const;
+
/// Get the fixed byte size for a given form.
///
- /// If the form always has a fixed valid byte size that doesn't depend on a
- /// DWARFUnit, then an Optional with a value will be returned. If the form
- /// can vary in size depending on the DWARFUnit (DWARF version, address byte
- /// size, or DWARF 32/64) and the DWARFUnit is valid, then an Optional with a
- /// valid value is returned. If the form is always encoded using a variable
- /// length storage format (ULEB or SLEB numbers or blocks) or the size
- /// depends on a DWARFUnit and the DWARFUnit is NULL, then None will be
- /// returned.
- /// \param Form The DWARF form to get the fixed byte size for
- /// \param U The DWARFUnit that can be used to help determine the byte size.
- ///
- /// \returns Optional<uint8_t> value with the fixed byte size or None if
- /// \p Form doesn't have a fixed byte size or a DWARFUnit wasn't supplied
- /// and was needed to calculate the byte size.
- static Optional<uint8_t> getFixedByteSize(dwarf::Form Form,
- const DWARFUnit *U = nullptr);
- /// Get the fixed byte size for a given form.
- ///
- /// If the form has a fixed byte size given a valid DWARF version and address
- /// byte size, then an Optional with a valid value is returned. If the form
- /// is always encoded using a variable length storage format (ULEB or SLEB
- /// numbers or blocks) then None will be returned.
+ /// If the form has a fixed byte size, then an Optional with a value will be
+ /// returned. If the form is always encoded using a variable length storage
+ /// format (ULEB or SLEB numbers or blocks) then None will be returned.
///
- /// \param Form DWARF form to get the fixed byte size for
- /// \param Version DWARF version number.
- /// \param AddrSize size of an address in bytes.
- /// \param Format enum value from llvm::dwarf::DwarfFormat.
+ /// \param Form DWARF form to get the fixed byte size for.
+ /// \param FormParams DWARF parameters to help interpret forms.
/// \returns Optional<uint8_t> value with the fixed byte size or None if
/// \p Form doesn't have a fixed byte size.
- static Optional<uint8_t> getFixedByteSize(dwarf::Form Form, uint16_t Version,
- uint8_t AddrSize,
- llvm::dwarf::DwarfFormat Format);
+ static Optional<uint8_t> getFixedByteSize(dwarf::Form Form,
+ const DWARFFormParams FormParams);
- /// Skip a form in \p debug_info_data at offset specified by \p offset_ptr.
+ /// Skip a form's value in \p DebugInfoData at the offset specified by
+ /// \p OffsetPtr.
///
- /// Skips the bytes for this form in the debug info and updates the offset.
+ /// Skips the bytes for the current form and updates the offset.
///
- /// \param debug_info_data the .debug_info data to use to skip the value.
- /// \param offset_ptr a reference to the offset that will be updated.
- /// \param U the DWARFUnit to use when skipping the form in case the form
- /// size differs according to data in the DWARFUnit.
+ /// \param DebugInfoData The data where we want to skip the value.
+ /// \param OffsetPtr A reference to the offset that will be updated.
+ /// \param Params DWARF parameters to help interpret forms.
/// \returns true on success, false if the form was not skipped.
- bool skipValue(DataExtractor debug_info_data, uint32_t *offset_ptr,
- const DWARFUnit *U) const;
- /// Skip a form in \p debug_info_data at offset specified by \p offset_ptr.
- ///
- /// Skips the bytes for this form in the debug info and updates the offset.
- ///
- /// \param form the DW_FORM enumeration that indicates the form to skip.
- /// \param debug_info_data the .debug_info data to use to skip the value.
- /// \param offset_ptr a reference to the offset that will be updated.
- /// \param U the DWARFUnit to use when skipping the form in case the form
- /// size differs according to data in the DWARFUnit.
- /// \returns true on success, false if the form was not skipped.
- static bool skipValue(dwarf::Form form, DataExtractor debug_info_data,
- uint32_t *offset_ptr, const DWARFUnit *U);
- /// Skip a form in \p debug_info_data at offset specified by \p offset_ptr.
+ bool skipValue(DataExtractor DebugInfoData, uint32_t *OffsetPtr,
+ const DWARFFormParams Params) const {
+ return DWARFFormValue::skipValue(Form, DebugInfoData, OffsetPtr, Params);
+ }
+
+ /// Skip a form's value in \p DebugInfoData at the offset specified by
+ /// \p OffsetPtr.
///
- /// Skips the bytes for this form in the debug info and updates the offset.
+ /// Skips the bytes for the specified form and updates the offset.
///
- /// \param form the DW_FORM enumeration that indicates the form to skip.
- /// \param debug_info_data the .debug_info data to use to skip the value.
- /// \param offset_ptr a reference to the offset that will be updated.
- /// \param Version DWARF version number.
- /// \param AddrSize size of an address in bytes.
- /// \param Format enum value from llvm::dwarf::DwarfFormat.
+ /// \param Form The DW_FORM enumeration that indicates the form to skip.
+ /// \param DebugInfoData The data where we want to skip the value.
+ /// \param OffsetPtr A reference to the offset that will be updated.
+ /// \param FormParams DWARF parameters to help interpret forms.
/// \returns true on success, false if the form was not skipped.
- static bool skipValue(dwarf::Form form, DataExtractor debug_info_data,
- uint32_t *offset_ptr, uint16_t Version,
- uint8_t AddrSize, llvm::dwarf::DwarfFormat Format);
+ static bool skipValue(dwarf::Form Form, DataExtractor DebugInfoData,
+ uint32_t *OffsetPtr, const DWARFFormParams FormParams);
private:
void dumpString(raw_ostream &OS) const;
};
+namespace dwarf {
+
+/// Take an optional DWARFFormValue and try to extract a string value from it.
+///
+/// \param V and optional DWARFFormValue to attempt to extract the value from.
+/// \returns an optional value that contains a value if the form value
+/// was valid and was a string.
+inline Optional<const char *> toString(const Optional<DWARFFormValue> &V) {
+ if (V)
+ return V->getAsCString();
+ return None;
}
-#endif
+/// Take an optional DWARFFormValue and extract a string value from it.
+///
+/// \param V and optional DWARFFormValue to attempt to extract the value from.
+/// \param Default the default value to return in case of failure.
+/// \returns the string value or Default if the V doesn't have a value or the
+/// form value's encoding wasn't a string.
+inline const char *toString(const Optional<DWARFFormValue> &V,
+ const char *Default) {
+ return toString(V).getValueOr(Default);
+}
+
+/// Take an optional DWARFFormValue and try to extract an unsigned constant.
+///
+/// \param V and optional DWARFFormValue to attempt to extract the value from.
+/// \returns an optional value that contains a value if the form value
+/// was valid and has a unsigned constant form.
+inline Optional<uint64_t> toUnsigned(const Optional<DWARFFormValue> &V) {
+ if (V)
+ return V->getAsUnsignedConstant();
+ return None;
+}
+
+/// Take an optional DWARFFormValue and extract a unsigned constant.
+///
+/// \param V and optional DWARFFormValue to attempt to extract the value from.
+/// \param Default the default value to return in case of failure.
+/// \returns the extracted unsigned value or Default if the V doesn't have a
+/// value or the form value's encoding wasn't an unsigned constant form.
+inline uint64_t toUnsigned(const Optional<DWARFFormValue> &V,
+ uint64_t Default) {
+ return toUnsigned(V).getValueOr(Default);
+}
+
+/// Take an optional DWARFFormValue and try to extract an reference.
+///
+/// \param V and optional DWARFFormValue to attempt to extract the value from.
+/// \returns an optional value that contains a value if the form value
+/// was valid and has a reference form.
+inline Optional<uint64_t> toReference(const Optional<DWARFFormValue> &V) {
+ if (V)
+ return V->getAsReference();
+ return None;
+}
+
+/// Take an optional DWARFFormValue and extract a reference.
+///
+/// \param V and optional DWARFFormValue to attempt to extract the value from.
+/// \param Default the default value to return in case of failure.
+/// \returns the extracted reference value or Default if the V doesn't have a
+/// value or the form value's encoding wasn't a reference form.
+inline uint64_t toReference(const Optional<DWARFFormValue> &V,
+ uint64_t Default) {
+ return toReference(V).getValueOr(Default);
+}
+
+/// Take an optional DWARFFormValue and try to extract an signed constant.
+///
+/// \param V and optional DWARFFormValue to attempt to extract the value from.
+/// \returns an optional value that contains a value if the form value
+/// was valid and has a signed constant form.
+inline Optional<int64_t> toSigned(const Optional<DWARFFormValue> &V) {
+ if (V)
+ return V->getAsSignedConstant();
+ return None;
+}
+
+/// Take an optional DWARFFormValue and extract a signed integer.
+///
+/// \param V and optional DWARFFormValue to attempt to extract the value from.
+/// \param Default the default value to return in case of failure.
+/// \returns the extracted signed integer value or Default if the V doesn't
+/// have a value or the form value's encoding wasn't a signed integer form.
+inline int64_t toSigned(const Optional<DWARFFormValue> &V, int64_t Default) {
+ return toSigned(V).getValueOr(Default);
+}
+
+/// Take an optional DWARFFormValue and try to extract an address.
+///
+/// \param V and optional DWARFFormValue to attempt to extract the value from.
+/// \returns an optional value that contains a value if the form value
+/// was valid and has a address form.
+inline Optional<uint64_t> toAddress(const Optional<DWARFFormValue> &V) {
+ if (V)
+ return V->getAsAddress();
+ return None;
+}
+
+/// Take an optional DWARFFormValue and extract a address.
+///
+/// \param V and optional DWARFFormValue to attempt to extract the value from.
+/// \param Default the default value to return in case of failure.
+/// \returns the extracted address value or Default if the V doesn't have a
+/// value or the form value's encoding wasn't an address form.
+inline uint64_t toAddress(const Optional<DWARFFormValue> &V, uint64_t Default) {
+ return toAddress(V).getValueOr(Default);
+}
+
+/// Take an optional DWARFFormValue and try to extract an section offset.
+///
+/// \param V and optional DWARFFormValue to attempt to extract the value from.
+/// \returns an optional value that contains a value if the form value
+/// was valid and has a section offset form.
+inline Optional<uint64_t> toSectionOffset(const Optional<DWARFFormValue> &V) {
+ if (V)
+ return V->getAsSectionOffset();
+ return None;
+}
+
+/// Take an optional DWARFFormValue and extract a section offset.
+///
+/// \param V and optional DWARFFormValue to attempt to extract the value from.
+/// \param Default the default value to return in case of failure.
+/// \returns the extracted section offset value or Default if the V doesn't
+/// have a value or the form value's encoding wasn't a section offset form.
+inline uint64_t toSectionOffset(const Optional<DWARFFormValue> &V,
+ uint64_t Default) {
+ return toSectionOffset(V).getValueOr(Default);
+}
+
+/// Take an optional DWARFFormValue and try to extract block data.
+///
+/// \param V and optional DWARFFormValue to attempt to extract the value from.
+/// \returns an optional value that contains a value if the form value
+/// was valid and has a block form.
+inline Optional<ArrayRef<uint8_t>> toBlock(const Optional<DWARFFormValue> &V) {
+ if (V)
+ return V->getAsBlock();
+ return None;
+}
+
+} // end namespace dwarf
+
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_DWARFFORMVALUE_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFGdbIndex.h b/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFGdbIndex.h
index 66041be..8d1ac5c 100644
--- a/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFGdbIndex.h
+++ b/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFGdbIndex.h
@@ -1,4 +1,4 @@
-//===-- DWARFGdbIndex.h -----------------------------------------*- C++ -*-===//
+//===- DWARFGdbIndex.h ------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,14 +7,19 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIB_DEBUGINFO_DWARFGDBINDEX_H
-#define LLVM_LIB_DEBUGINFO_DWARFGDBINDEX_H
+#ifndef LLVM_DEBUGINFO_DWARF_DWARFGDBINDEX_H
+#define LLVM_DEBUGINFO_DWARF_DWARFGDBINDEX_H
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/Support/DataExtractor.h"
-#include "llvm/Support/Error.h"
-#include "llvm/Support/raw_ostream.h"
+#include <cstdint>
+#include <utility>
namespace llvm {
+
+class raw_ostream;
+
class DWARFGdbIndex {
uint32_t Version;
@@ -24,25 +29,25 @@ class DWARFGdbIndex {
uint32_t ConstantPoolOffset;
struct CompUnitEntry {
- uint64_t Offset; // Offset of a CU in the .debug_info section.
- uint64_t Length; // Length of that CU.
+ uint64_t Offset; /// Offset of a CU in the .debug_info section.
+ uint64_t Length; /// Length of that CU.
};
SmallVector<CompUnitEntry, 0> CuList;
struct AddressEntry {
- uint64_t LowAddress; // The low address.
- uint64_t HighAddress; // The high address.
- uint32_t CuIndex; // The CU index.
+ uint64_t LowAddress; /// The low address.
+ uint64_t HighAddress; /// The high address.
+ uint32_t CuIndex; /// The CU index.
};
SmallVector<AddressEntry, 0> AddressArea;
struct SymTableEntry {
- uint32_t NameOffset; // Offset of the symbol's name in the constant pool.
- uint32_t VecOffset; // Offset of the CU vector in the constant pool.
+ uint32_t NameOffset; /// Offset of the symbol's name in the constant pool.
+ uint32_t VecOffset; /// Offset of the CU vector in the constant pool.
};
SmallVector<SymTableEntry, 0> SymbolTable;
- // Each value is CU index + attributes.
+ /// Each value is CU index + attributes.
SmallVector<std::pair<uint32_t, SmallVector<uint32_t, 0>>, 0>
ConstantPoolVectors;
@@ -63,6 +68,7 @@ public:
bool HasContent = false;
bool HasError = false;
};
-}
-#endif // LLVM_LIB_DEBUGINFO_DWARFGDBINDEX_H
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_DWARF_DWARFGDBINDEX_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFRelocMap.h b/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFRelocMap.h
index d7fe303..f5183842 100644
--- a/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFRelocMap.h
+++ b/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFRelocMap.h
@@ -1,4 +1,4 @@
-//===-- DWARFRelocMap.h -----------------------------------------*- C++ -*-===//
+//===- DWARFRelocMap.h ------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,16 +7,28 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIB_DEBUGINFO_DWARFRELOCMAP_H
-#define LLVM_LIB_DEBUGINFO_DWARFRELOCMAP_H
+#ifndef LLVM_DEBUGINFO_DWARF_DWARFRELOCMAP_H
+#define LLVM_DEBUGINFO_DWARF_DWARFRELOCMAP_H
#include "llvm/ADT/DenseMap.h"
+#include <cstdint>
namespace llvm {
-typedef DenseMap<uint64_t, std::pair<uint8_t, int64_t> > RelocAddrMap;
+/// RelocAddrEntry contains relocated value and section index.
+/// Section index is -1LL if relocation points to absolute symbol.
+struct RelocAddrEntry {
+ uint64_t SectionIndex;
+ uint64_t Value;
+};
-} // namespace llvm
+/// In place of applying the relocations to the data we've read from disk we use
+/// a separate mapping table to the side and checking that at locations in the
+/// dwarf where we expect relocated values. This adds a bit of complexity to the
+/// dwarf parsing/extraction at the benefit of not allocating memory for the
+/// entire size of the debug info sections.
+using RelocAddrMap = DenseMap<uint64_t, RelocAddrEntry>;
-#endif
+} // end namespace llvm
+#endif // LLVM_DEBUGINFO_DWARF_DWARFRELOCMAP_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFSection.h b/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFSection.h
index 3e27b52..2b8a53a 100644
--- a/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFSection.h
+++ b/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFSection.h
@@ -1,4 +1,4 @@
-//===-- DWARFSection.h ------------------------------------------*- C++ -*-===//
+//===- DWARFSection.h -------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,11 +7,11 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIB_DEBUGINFO_DWARFSECTION_H
-#define LLVM_LIB_DEBUGINFO_DWARFSECTION_H
+#ifndef LLVM_DEBUGINFO_DWARF_DWARFSECTION_H
+#define LLVM_DEBUGINFO_DWARF_DWARFSECTION_H
-#include "llvm/DebugInfo/DWARF/DWARFRelocMap.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/DebugInfo/DWARF/DWARFRelocMap.h"
namespace llvm {
@@ -20,6 +20,6 @@ struct DWARFSection {
RelocAddrMap Relocs;
};
-}
+} // end namespace llvm
-#endif
+#endif // LLVM_DEBUGINFO_DWARF_DWARFSECTION_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h b/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h
index 4f1e129..4a5793e 100644
--- a/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h
+++ b/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h
@@ -1,4 +1,4 @@
-//===-- DWARFTypeUnit.h -----------------------------------------*- C++ -*-===//
+//===- DWARFTypeUnit.h ------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,28 +7,41 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIB_DEBUGINFO_DWARFTYPEUNIT_H
-#define LLVM_LIB_DEBUGINFO_DWARFTYPEUNIT_H
+#ifndef LLVM_DEBUGINFO_DWARF_DWARFTYPEUNIT_H
+#define LLVM_DEBUGINFO_DWARF_DWARFTYPEUNIT_H
+#include "llvm/ADT/StringRef.h"
#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
+#include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h"
+#include "llvm/Support/DataExtractor.h"
+#include <cstdint>
namespace llvm {
+class DWARFContext;
+class DWARFDebugAbbrev;
+struct DWARFSection;
+class raw_ostream;
+
class DWARFTypeUnit : public DWARFUnit {
private:
uint64_t TypeHash;
uint32_t TypeOffset;
+
public:
DWARFTypeUnit(DWARFContext &Context, const DWARFSection &Section,
- const DWARFDebugAbbrev *DA, StringRef RS, StringRef SS,
- StringRef SOS, StringRef AOS, StringRef LS, bool LE, bool IsDWO,
+ const DWARFDebugAbbrev *DA, const DWARFSection *RS,
+ StringRef SS, const DWARFSection &SOS, const DWARFSection *AOS,
+ const DWARFSection &LS, bool LE, bool IsDWO,
const DWARFUnitSectionBase &UnitSection,
const DWARFUnitIndex::Entry *Entry)
: DWARFUnit(Context, Section, DA, RS, SS, SOS, AOS, LS, LE, IsDWO,
UnitSection, Entry) {}
+
uint32_t getHeaderSize() const override {
return DWARFUnit::getHeaderSize() + 12;
}
+
void dump(raw_ostream &OS, bool Brief = false);
static const DWARFSectionKind Section = DW_SECT_TYPES;
@@ -36,7 +49,6 @@ protected:
bool extractImpl(DataExtractor debug_info, uint32_t *offset_ptr) override;
};
-}
-
-#endif
+} // end namespace llvm
+#endif // LLVM_DEBUGINFO_DWARF_DWARFTYPEUNIT_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h b/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h
index db7b59b..056c1b7 100644
--- a/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h
+++ b/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h
@@ -1,4 +1,4 @@
-//===-- DWARFUnit.h ---------------------------------------------*- C++ -*-===//
+//===- DWARFUnit.h ----------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,32 +7,38 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIB_DEBUGINFO_DWARFUNIT_H
-#define LLVM_LIB_DEBUGINFO_DWARFUNIT_H
+#ifndef LLVM_DEBUGINFO_DWARF_DWARFUNIT_H
+#define LLVM_DEBUGINFO_DWARF_DWARFUNIT_H
#include "llvm/ADT/Optional.h"
-#include "llvm/ADT/iterator_range.h"
#include "llvm/ADT/STLExtras.h"
-#include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
#include "llvm/DebugInfo/DWARF/DWARFDie.h"
+#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
#include "llvm/DebugInfo/DWARF/DWARFRelocMap.h"
#include "llvm/DebugInfo/DWARF/DWARFSection.h"
#include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h"
+#include "llvm/Support/DataExtractor.h"
+#include <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
+#include <map>
+#include <memory>
+#include <utility>
#include <vector>
namespace llvm {
-namespace object {
-class ObjectFile;
-}
-
+class DWARFAbbreviationDeclarationSet;
class DWARFContext;
class DWARFDebugAbbrev;
class DWARFUnit;
-class StringRef;
-class raw_ostream;
/// Base class for all DWARFUnitSection classes. This provides the
/// functionality common to all unit types.
@@ -47,12 +53,13 @@ public:
DWARFUnitIndex *Index = nullptr);
protected:
+ ~DWARFUnitSectionBase() = default;
+
virtual void parseImpl(DWARFContext &Context, const DWARFSection &Section,
- const DWARFDebugAbbrev *DA, StringRef RS, StringRef SS,
- StringRef SOS, StringRef AOS, StringRef LS,
+ const DWARFDebugAbbrev *DA, const DWARFSection *RS,
+ StringRef SS, const DWARFSection &SOS,
+ const DWARFSection *AOS, const DWARFSection &LS,
bool isLittleEndian, bool isDWO) = 0;
-
- ~DWARFUnitSectionBase() = default;
};
const DWARFUnitIndex &getDWARFUnitIndex(DWARFContext &Context,
@@ -65,9 +72,9 @@ class DWARFUnitSection final : public SmallVector<std::unique_ptr<UnitType>, 1>,
bool Parsed = false;
public:
- typedef llvm::SmallVectorImpl<std::unique_ptr<UnitType>> UnitVector;
- typedef typename UnitVector::iterator iterator;
- typedef llvm::iterator_range<typename UnitVector::iterator> iterator_range;
+ using UnitVector = SmallVectorImpl<std::unique_ptr<UnitType>>;
+ using iterator = typename UnitVector::iterator;
+ using iterator_range = llvm::iterator_range<typename UnitVector::iterator>;
UnitType *getUnitForOffset(uint32_t Offset) const override {
auto *CU = std::upper_bound(
@@ -82,9 +89,9 @@ public:
private:
void parseImpl(DWARFContext &Context, const DWARFSection &Section,
- const DWARFDebugAbbrev *DA, StringRef RS, StringRef SS,
- StringRef SOS, StringRef AOS, StringRef LS, bool LE,
- bool IsDWO) override {
+ const DWARFDebugAbbrev *DA, const DWARFSection *RS,
+ StringRef SS, const DWARFSection &SOS, const DWARFSection *AOS,
+ const DWARFSection &LS, bool LE, bool IsDWO) override {
if (Parsed)
return;
const auto &Index = getDWARFUnitIndex(Context, UnitType::Section);
@@ -105,41 +112,42 @@ private:
class DWARFUnit {
DWARFContext &Context;
- // Section containing this DWARFUnit.
+ /// Section containing this DWARFUnit.
const DWARFSection &InfoSection;
const DWARFDebugAbbrev *Abbrev;
- StringRef RangeSection;
+ const DWARFSection *RangeSection;
uint32_t RangeSectionBase;
- StringRef LineSection;
+ const DWARFSection &LineSection;
StringRef StringSection;
- StringRef StringOffsetSection;
- StringRef AddrOffsetSection;
+ const DWARFSection &StringOffsetSection;
+ uint64_t StringOffsetSectionBase = 0;
+ const DWARFSection *AddrOffsetSection;
uint32_t AddrOffsetSectionBase;
bool isLittleEndian;
bool isDWO;
const DWARFUnitSectionBase &UnitSection;
+ // Version, address size, and DWARF format.
+ DWARFFormParams FormParams;
+
uint32_t Offset;
uint32_t Length;
- uint16_t Version;
const DWARFAbbreviationDeclarationSet *Abbrevs;
- uint8_t AddrSize;
+ uint8_t UnitType;
uint64_t BaseAddr;
- // The compile unit debug information entry items.
+ /// The compile unit debug information entry items.
std::vector<DWARFDebugInfoEntry> DieArray;
- typedef iterator_range<std::vector<DWARFDebugInfoEntry>::iterator>
- die_iterator_range;
-
- class DWOHolder {
- object::OwningBinary<object::ObjectFile> DWOFile;
- std::unique_ptr<DWARFContext> DWOContext;
- DWARFUnit *DWOU;
- public:
- DWOHolder(StringRef DWOPath);
- DWARFUnit *getUnit() const { return DWOU; }
- };
- std::unique_ptr<DWOHolder> DWO;
+
+ /// Map from range's start address to end address and corresponding DIE.
+ /// IntervalMap does not support range removal, as a result, we use the
+ /// std::map::upper_bound for address range lookup.
+ std::map<uint64_t, std::pair<uint64_t, DWARFDie>> AddrDieMap;
+
+ using die_iterator_range =
+ iterator_range<std::vector<DWARFDebugInfoEntry>::iterator>;
+
+ std::shared_ptr<DWARFUnit> DWO;
const DWARFUnitIndex::Entry *IndexEntry;
@@ -151,13 +159,15 @@ class DWARFUnit {
protected:
virtual bool extractImpl(DataExtractor debug_info, uint32_t *offset_ptr);
+
/// Size in bytes of the unit header.
- virtual uint32_t getHeaderSize() const { return 11; }
+ virtual uint32_t getHeaderSize() const { return getVersion() <= 4 ? 11 : 12; }
public:
DWARFUnit(DWARFContext &Context, const DWARFSection &Section,
- const DWARFDebugAbbrev *DA, StringRef RS, StringRef SS,
- StringRef SOS, StringRef AOS, StringRef LS, bool LE, bool IsDWO,
+ const DWARFDebugAbbrev *DA, const DWARFSection *RS, StringRef SS,
+ const DWARFSection &SOS, const DWARFSection *AOS,
+ const DWARFSection &LS, bool LE, bool IsDWO,
const DWARFUnitSectionBase &UnitSection,
const DWARFUnitIndex::Entry *IndexEntry = nullptr);
@@ -165,30 +175,41 @@ public:
DWARFContext& getContext() const { return Context; }
- StringRef getLineSection() const { return LineSection; }
+ const DWARFSection &getLineSection() const { return LineSection; }
StringRef getStringSection() const { return StringSection; }
- StringRef getStringOffsetSection() const { return StringOffsetSection; }
- void setAddrOffsetSection(StringRef AOS, uint32_t Base) {
+ const DWARFSection &getStringOffsetSection() const {
+ return StringOffsetSection;
+ }
+
+ void setAddrOffsetSection(const DWARFSection *AOS, uint32_t Base) {
AddrOffsetSection = AOS;
AddrOffsetSectionBase = Base;
}
- void setRangesSection(StringRef RS, uint32_t Base) {
+
+ /// Recursively update address to Die map.
+ void updateAddressDieMap(DWARFDie Die);
+
+ void setRangesSection(const DWARFSection *RS, uint32_t Base) {
RangeSection = RS;
RangeSectionBase = Base;
}
bool getAddrOffsetSectionItem(uint32_t Index, uint64_t &Result) const;
- // FIXME: Result should be uint64_t in DWARF64.
- bool getStringOffsetSectionItem(uint32_t Index, uint32_t &Result) const;
+ bool getStringOffsetSectionItem(uint32_t Index, uint64_t &Result) const;
- DataExtractor getDebugInfoExtractor() const {
- return DataExtractor(InfoSection.Data, isLittleEndian, AddrSize);
+ DWARFDataExtractor getDebugInfoExtractor() const {
+ return DWARFDataExtractor(InfoSection, isLittleEndian,
+ getAddressByteSize());
}
+
DataExtractor getStringExtractor() const {
return DataExtractor(StringSection, false, 0);
}
const RelocAddrMap *getRelocMap() const { return &InfoSection.Relocs; }
+ const RelocAddrMap &getStringOffsetsRelocMap() const {
+ return StringOffsetSection.Relocs;
+ }
bool extract(DataExtractor debug_info, uint32_t* offset_ptr);
@@ -201,24 +222,50 @@ public:
uint32_t getOffset() const { return Offset; }
uint32_t getNextUnitOffset() const { return Offset + Length + 4; }
uint32_t getLength() const { return Length; }
- uint16_t getVersion() const { return Version; }
- dwarf::DwarfFormat getFormat() const {
- return dwarf::DwarfFormat::DWARF32; // FIXME: Support DWARF64.
+
+ const DWARFFormParams &getFormParams() const { return FormParams; }
+ uint16_t getVersion() const { return FormParams.Version; }
+ dwarf::DwarfFormat getFormat() const { return FormParams.Format; }
+ uint8_t getAddressByteSize() const { return FormParams.AddrSize; }
+ uint8_t getRefAddrByteSize() const { return FormParams.getRefAddrByteSize(); }
+ uint8_t getDwarfOffsetByteSize() const {
+ return FormParams.getDwarfOffsetByteSize();
}
+
const DWARFAbbreviationDeclarationSet *getAbbreviations() const {
return Abbrevs;
}
- uint8_t getAddressByteSize() const { return AddrSize; }
- uint8_t getRefAddrByteSize() const {
- if (Version == 2)
- return AddrSize;
- return getDwarfOffsetByteSize();
+
+ uint8_t getUnitType() const { return UnitType; }
+
+ static bool isValidUnitType(uint8_t UnitType) {
+ return UnitType == dwarf::DW_UT_compile || UnitType == dwarf::DW_UT_type ||
+ UnitType == dwarf::DW_UT_partial ||
+ UnitType == dwarf::DW_UT_skeleton ||
+ UnitType == dwarf::DW_UT_split_compile ||
+ UnitType == dwarf::DW_UT_split_type;
}
- uint8_t getDwarfOffsetByteSize() const {
- if (getFormat() == dwarf::DwarfFormat::DWARF64)
- return 8;
- return 4;
+
+ /// \brief 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.");
}
+
uint64_t getBaseAddress() const { return BaseAddr; }
void setBaseAddress(uint64_t base_addr) {
@@ -284,9 +331,9 @@ public:
[](const DWARFDebugInfoEntry &LHS, uint32_t Offset) {
return LHS.getOffset() < Offset;
});
- if (it == DieArray.end())
- return DWARFDie();
- return DWARFDie(this, &*it);
+ if (it != DieArray.end() && it->getOffset() == Offset)
+ return DWARFDie(this, &*it);
+ return DWARFDie();
}
uint32_t getLineTableOffset() const {
@@ -308,9 +355,11 @@ private:
/// extractDIEsIfNeeded - Parses a compile unit and indexes its DIEs if it
/// hasn't already been done. Returns the number of DIEs parsed at this call.
size_t extractDIEsIfNeeded(bool CUDieOnly);
+
/// extractDIEsToVector - Appends all parsed DIEs to a vector.
void extractDIEsToVector(bool AppendCUDie, bool AppendNonCUDIEs,
std::vector<DWARFDebugInfoEntry> &DIEs) const;
+
/// clearDIEs - Clear parsed DIEs to keep memory usage low.
void clearDIEs(bool KeepCUDie);
@@ -318,12 +367,12 @@ private:
/// it was actually constructed.
bool parseDWO();
- /// getSubprogramForAddress - Returns subprogram DIE with address range
+ /// getSubroutineForAddress - Returns subprogram DIE with address range
/// encompassing the provided address. The pointer is alive as long as parsed
/// compile unit DIEs are not cleared.
- DWARFDie getSubprogramForAddress(uint64_t Address);
+ DWARFDie getSubroutineForAddress(uint64_t Address);
};
-}
+} // end namespace llvm
-#endif
+#endif // LLVM_DEBUGINFO_DWARF_DWARFUNIT_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFUnitIndex.h b/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFUnitIndex.h
index 9f051cd..8e2ce02 100644
--- a/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFUnitIndex.h
+++ b/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFUnitIndex.h
@@ -1,4 +1,4 @@
-//===-- DWARFUnitIndex.h --------------------------------------------------===//
+//===- DWARFUnitIndex.h -----------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,17 +7,19 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIB_DEBUGINFO_DWARFUNITINDEX_H
-#define LLVM_LIB_DEBUGINFO_DWARFUNITINDEX_H
+#ifndef LLVM_DEBUGINFO_DWARF_DWARFUNITINDEX_H
+#define LLVM_DEBUGINFO_DWARF_DWARFUNITINDEX_H
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/Support/DataExtractor.h"
-#include "llvm/Support/Format.h"
-#include "llvm/Support/raw_ostream.h"
#include <cstdint>
+#include <memory>
namespace llvm {
+class raw_ostream;
+
enum DWARFSectionKind {
DW_SECT_INFO = 1,
DW_SECT_TYPES,
@@ -57,9 +59,11 @@ public:
public:
const SectionContribution *getOffset(DWARFSectionKind Sec) const;
const SectionContribution *getOffset() const;
+
const SectionContribution *getOffsets() const {
return Contributions.get();
}
+
uint64_t getSignature() const { return Signature; }
};
@@ -72,21 +76,26 @@ private:
std::unique_ptr<Entry[]> Rows;
static StringRef getColumnHeader(DWARFSectionKind DS);
+
bool parseImpl(DataExtractor IndexData);
public:
- bool parse(DataExtractor IndexData);
DWARFUnitIndex(DWARFSectionKind InfoColumnKind)
: InfoColumnKind(InfoColumnKind) {}
+
+ bool parse(DataExtractor IndexData);
void dump(raw_ostream &OS) const;
const Entry *getFromOffset(uint32_t Offset) const;
+
ArrayRef<DWARFSectionKind> getColumnKinds() const {
return makeArrayRef(ColumnKinds.get(), Header.NumColumns);
}
+
ArrayRef<Entry> getRows() const {
return makeArrayRef(Rows.get(), Header.NumBuckets);
}
};
-}
-#endif
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_DWARF_DWARFUNITINDEX_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFVerifier.h b/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFVerifier.h
new file mode 100644
index 0000000..c0291a8
--- /dev/null
+++ b/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFVerifier.h
@@ -0,0 +1,144 @@
+//===- DWARFVerifier.h ----------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_DWARF_DWARFVERIFIER_H
+#define LLVM_DEBUGINFO_DWARF_DWARFVERIFIER_H
+
+#include <cstdint>
+#include <map>
+#include <set>
+
+namespace llvm {
+class raw_ostream;
+struct DWARFAttribute;
+class DWARFContext;
+class DWARFDie;
+class DWARFUnit;
+class DWARFAcceleratorTable;
+class DWARFDataExtractor;
+
+/// A class that verifies DWARF debug information given a DWARF Context.
+class DWARFVerifier {
+ raw_ostream &OS;
+ DWARFContext &DCtx;
+ /// A map that tracks all references (converted absolute references) so we
+ /// can verify each reference points to a valid DIE and not an offset that
+ /// lies between to valid DIEs.
+ std::map<uint64_t, std::set<uint32_t>> ReferenceToDIEOffsets;
+ uint32_t NumDebugLineErrors = 0;
+ uint32_t NumAppleNamesErrors = 0;
+
+ /// Verifies the header of a unit in the .debug_info section.
+ ///
+ /// This function currently checks for:
+ /// - Unit is in 32-bit DWARF format. The function can be modified to
+ /// support 64-bit format.
+ /// - The DWARF version is valid
+ /// - The unit type is valid (if unit is in version >=5)
+ /// - The unit doesn't extend beyond .debug_info section
+ /// - The address size is valid
+ /// - The offset in the .debug_abbrev section is valid
+ ///
+ /// \param DebugInfoData The .debug_info section data
+ /// \param Offset A reference to the offset start of the unit. The offset will
+ /// be updated to point to the next unit in .debug_info
+ /// \param UnitIndex The index of the unit to be verified
+ /// \param UnitType A reference to the type of the unit
+ /// \param isUnitDWARF64 A reference to a flag that shows whether the unit is
+ /// in 64-bit format.
+ ///
+ /// \returns true if the header is verified successfully, false otherwise.
+ bool verifyUnitHeader(const DWARFDataExtractor DebugInfoData,
+ uint32_t *Offset, unsigned UnitIndex, uint8_t &UnitType,
+ bool &isUnitDWARF64);
+
+
+ bool verifyUnitContents(DWARFUnit Unit);
+ /// Verifies the attribute's DWARF attribute and its value.
+ ///
+ /// This function currently checks for:
+ /// - DW_AT_ranges values is a valid .debug_ranges offset
+ /// - DW_AT_stmt_list is a valid .debug_line offset
+ ///
+ /// \param Die The DWARF DIE that owns the attribute value
+ /// \param AttrValue The DWARF attribute value to check
+ ///
+ /// \returns NumErrors The number of errors occured during verification of
+ /// attributes' values in a .debug_info section unit
+ unsigned verifyDebugInfoAttribute(const DWARFDie &Die,
+ DWARFAttribute &AttrValue);
+
+ /// Verifies the attribute's DWARF form.
+ ///
+ /// This function currently checks for:
+ /// - All DW_FORM_ref values that are CU relative have valid CU offsets
+ /// - All DW_FORM_ref_addr values have valid .debug_info offsets
+ /// - All DW_FORM_strp values have valid .debug_str offsets
+ ///
+ /// \param Die The DWARF DIE that owns the attribute value
+ /// \param AttrValue The DWARF attribute value to check
+ ///
+ /// \returns NumErrors The number of errors occured during verification of
+ /// attributes' forms in a .debug_info section unit
+ unsigned verifyDebugInfoForm(const DWARFDie &Die, DWARFAttribute &AttrValue);
+
+ /// Verifies the all valid references that were found when iterating through
+ /// all of the DIE attributes.
+ ///
+ /// This function will verify that all references point to DIEs whose DIE
+ /// offset matches. This helps to ensure if a DWARF link phase moved things
+ /// around, that it doesn't create invalid references by failing to relocate
+ /// CU relative and absolute references.
+ ///
+ /// \returns NumErrors The number of errors occured during verification of
+ /// references for the .debug_info section
+ unsigned verifyDebugInfoReferences();
+
+ /// Verify the the DW_AT_stmt_list encoding and value and ensure that no
+ /// compile units that have the same DW_AT_stmt_list value.
+ void verifyDebugLineStmtOffsets();
+
+ /// Verify that all of the rows in the line table are valid.
+ ///
+ /// This function currently checks for:
+ /// - addresses within a sequence that decrease in value
+ /// - invalid file indexes
+ void verifyDebugLineRows();
+
+public:
+ DWARFVerifier(raw_ostream &S, DWARFContext &D)
+ : OS(S), DCtx(D) {}
+ /// Verify the information in the .debug_info section.
+ ///
+ /// Any errors are reported to the stream that was this object was
+ /// constructed with.
+ ///
+ /// \returns true if the .debug_info verifies successfully, false otherwise.
+ bool handleDebugInfo();
+
+ /// Verify the information in the .debug_line section.
+ ///
+ /// Any errors are reported to the stream that was this object was
+ /// constructed with.
+ ///
+ /// \returns true if the .debug_line verifies successfully, false otherwise.
+ bool handleDebugLine();
+
+ /// Verify the information in the .apple_names accelerator table.
+ ///
+ /// Any errors are reported to the stream that was this object was
+ /// constructed with.
+ ///
+ /// \returns true if the .apple_names verifies successfully, false otherwise.
+ bool handleAppleNames();
+};
+
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_DWARF_DWARFCONTEXT_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/MSF/ByteStream.h b/contrib/llvm/include/llvm/DebugInfo/MSF/ByteStream.h
deleted file mode 100644
index 547844b..0000000
--- a/contrib/llvm/include/llvm/DebugInfo/MSF/ByteStream.h
+++ /dev/null
@@ -1,169 +0,0 @@
-//===- ByteStream.h - Reads stream data from a byte sequence ----*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_DEBUGINFO_MSF_BYTESTREAM_H
-#define LLVM_DEBUGINFO_MSF_BYTESTREAM_H
-
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/DebugInfo/MSF/MSFError.h"
-#include "llvm/DebugInfo/MSF/StreamInterface.h"
-#include "llvm/Support/Error.h"
-#include "llvm/Support/FileOutputBuffer.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include <algorithm>
-#include <cstdint>
-#include <cstring>
-#include <memory>
-
-namespace llvm {
-namespace msf {
-
-class ByteStream : public ReadableStream {
-public:
- ByteStream() = default;
- explicit ByteStream(ArrayRef<uint8_t> Data) : Data(Data) {}
- explicit ByteStream(StringRef Data)
- : Data(Data.bytes_begin(), Data.bytes_end()) {}
-
- Error readBytes(uint32_t Offset, uint32_t Size,
- ArrayRef<uint8_t> &Buffer) const override {
- if (Offset > Data.size())
- return make_error<MSFError>(msf_error_code::insufficient_buffer);
- if (Data.size() < Size + Offset)
- return make_error<MSFError>(msf_error_code::insufficient_buffer);
- Buffer = Data.slice(Offset, Size);
- return Error::success();
- }
-
- Error readLongestContiguousChunk(uint32_t Offset,
- ArrayRef<uint8_t> &Buffer) const override {
- if (Offset >= Data.size())
- return make_error<MSFError>(msf_error_code::insufficient_buffer);
- Buffer = Data.slice(Offset);
- return Error::success();
- }
-
- uint32_t getLength() const override { return Data.size(); }
-
- ArrayRef<uint8_t> data() const { return Data; }
-
- StringRef str() const {
- const char *CharData = reinterpret_cast<const char *>(Data.data());
- return StringRef(CharData, Data.size());
- }
-
-protected:
- ArrayRef<uint8_t> Data;
-};
-
-// MemoryBufferByteStream behaves like a read-only ByteStream, but has its data
-// backed by an llvm::MemoryBuffer. It also owns the underlying MemoryBuffer.
-class MemoryBufferByteStream : public ByteStream {
-public:
- explicit MemoryBufferByteStream(std::unique_ptr<MemoryBuffer> Buffer)
- : ByteStream(ArrayRef<uint8_t>(Buffer->getBuffer().bytes_begin(),
- Buffer->getBuffer().bytes_end())),
- MemBuffer(std::move(Buffer)) {}
-
- std::unique_ptr<MemoryBuffer> MemBuffer;
-};
-
-class MutableByteStream : public WritableStream {
-public:
- MutableByteStream() = default;
- explicit MutableByteStream(MutableArrayRef<uint8_t> Data)
- : Data(Data), ImmutableStream(Data) {}
-
- Error readBytes(uint32_t Offset, uint32_t Size,
- ArrayRef<uint8_t> &Buffer) const override {
- return ImmutableStream.readBytes(Offset, Size, Buffer);
- }
-
- Error readLongestContiguousChunk(uint32_t Offset,
- ArrayRef<uint8_t> &Buffer) const override {
- return ImmutableStream.readLongestContiguousChunk(Offset, Buffer);
- }
-
- uint32_t getLength() const override { return ImmutableStream.getLength(); }
-
- Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Buffer) const override {
- if (Buffer.empty())
- return Error::success();
-
- if (Data.size() < Buffer.size())
- return make_error<MSFError>(msf_error_code::insufficient_buffer);
- if (Offset > Buffer.size() - Data.size())
- return make_error<MSFError>(msf_error_code::insufficient_buffer);
-
- uint8_t *DataPtr = const_cast<uint8_t *>(Data.data());
- ::memcpy(DataPtr + Offset, Buffer.data(), Buffer.size());
- return Error::success();
- }
-
- Error commit() const override { return Error::success(); }
-
- MutableArrayRef<uint8_t> data() const { return Data; }
-
-private:
- MutableArrayRef<uint8_t> Data;
- ByteStream ImmutableStream;
-};
-
-// A simple adapter that acts like a ByteStream but holds ownership over
-// and underlying FileOutputBuffer.
-class FileBufferByteStream : public WritableStream {
-private:
- class StreamImpl : public MutableByteStream {
- public:
- StreamImpl(std::unique_ptr<FileOutputBuffer> Buffer)
- : MutableByteStream(MutableArrayRef<uint8_t>(Buffer->getBufferStart(),
- Buffer->getBufferEnd())),
- FileBuffer(std::move(Buffer)) {}
-
- Error commit() const override {
- if (FileBuffer->commit())
- return llvm::make_error<MSFError>(msf_error_code::not_writable);
- return Error::success();
- }
-
- private:
- std::unique_ptr<FileOutputBuffer> FileBuffer;
- };
-
-public:
- explicit FileBufferByteStream(std::unique_ptr<FileOutputBuffer> Buffer)
- : Impl(std::move(Buffer)) {}
-
- Error readBytes(uint32_t Offset, uint32_t Size,
- ArrayRef<uint8_t> &Buffer) const override {
- return Impl.readBytes(Offset, Size, Buffer);
- }
-
- Error readLongestContiguousChunk(uint32_t Offset,
- ArrayRef<uint8_t> &Buffer) const override {
- return Impl.readLongestContiguousChunk(Offset, Buffer);
- }
-
- uint32_t getLength() const override { return Impl.getLength(); }
-
- Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Data) const override {
- return Impl.writeBytes(Offset, Data);
- }
-
- Error commit() const override { return Impl.commit(); }
-
-private:
- StreamImpl Impl;
-};
-
-} // end namespace msf
-} // end namespace llvm
-
-#endif // LLVM_DEBUGINFO_MSF_BYTESTREAM_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/MSF/MSFBuilder.h b/contrib/llvm/include/llvm/DebugInfo/MSF/MSFBuilder.h
index 6d067cc..b2c8f2d 100644
--- a/contrib/llvm/include/llvm/DebugInfo/MSF/MSFBuilder.h
+++ b/contrib/llvm/include/llvm/DebugInfo/MSF/MSFBuilder.h
@@ -12,18 +12,16 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/BitVector.h"
-
#include "llvm/DebugInfo/MSF/MSFCommon.h"
-
#include "llvm/Support/Allocator.h"
-#include "llvm/Support/Endian.h"
#include "llvm/Support/Error.h"
-
+#include <cstdint>
#include <utility>
#include <vector>
namespace llvm {
namespace msf {
+
class MSFBuilder {
public:
/// \brief Create a new `MSFBuilder`.
@@ -122,7 +120,7 @@ private:
Error allocateBlocks(uint32_t NumBlocks, MutableArrayRef<uint32_t> Blocks);
uint32_t computeDirectoryByteSize() const;
- typedef std::vector<uint32_t> BlockList;
+ using BlockList = std::vector<uint32_t>;
BumpPtrAllocator &Allocator;
@@ -136,7 +134,8 @@ private:
std::vector<uint32_t> DirectoryBlocks;
std::vector<std::pair<uint32_t, BlockList>> StreamData;
};
-} // namespace msf
-} // namespace llvm
+
+} // end namespace msf
+} // end namespace llvm
#endif // LLVM_DEBUGINFO_MSF_MSFBUILDER_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/MSF/MSFCommon.h b/contrib/llvm/include/llvm/DebugInfo/MSF/MSFCommon.h
index 93a9c80..eca1b8b 100644
--- a/contrib/llvm/include/llvm/DebugInfo/MSF/MSFCommon.h
+++ b/contrib/llvm/include/llvm/DebugInfo/MSF/MSFCommon.h
@@ -12,15 +12,15 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/BitVector.h"
-
#include "llvm/Support/Endian.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/MathExtras.h"
-
+#include <cstdint>
#include <vector>
namespace llvm {
namespace msf {
+
static const char Magic[] = {'M', 'i', 'c', 'r', 'o', 's', 'o', 'f',
't', ' ', 'C', '/', 'C', '+', '+', ' ',
'M', 'S', 'F', ' ', '7', '.', '0', '0',
@@ -50,8 +50,9 @@ struct SuperBlock {
};
struct MSFLayout {
- MSFLayout() : SB(nullptr) {}
- const SuperBlock *SB;
+ MSFLayout() = default;
+
+ const SuperBlock *SB = nullptr;
BitVector FreePageMap;
ArrayRef<support::ulittle32_t> DirectoryBlocks;
ArrayRef<support::ulittle32_t> StreamSizes;
@@ -90,15 +91,16 @@ inline uint32_t getFpmIntervalLength(const MSFLayout &L) {
inline uint32_t getNumFpmIntervals(const MSFLayout &L) {
uint32_t Length = getFpmIntervalLength(L);
- return llvm::alignTo(L.SB->NumBlocks, Length) / Length;
+ return alignTo(L.SB->NumBlocks, Length) / Length;
}
inline uint32_t getFullFpmByteSize(const MSFLayout &L) {
- return llvm::alignTo(L.SB->NumBlocks, 8) / 8;
+ return alignTo(L.SB->NumBlocks, 8) / 8;
}
Error validateSuperBlock(const SuperBlock &SB);
-} // namespace msf
-} // namespace llvm
+
+} // end namespace msf
+} // end namespace llvm
#endif // LLVM_DEBUGINFO_MSF_MSFCOMMON_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/MSF/MappedBlockStream.h b/contrib/llvm/include/llvm/DebugInfo/MSF/MappedBlockStream.h
index fff4e9c..6d88d2b 100644
--- a/contrib/llvm/include/llvm/DebugInfo/MSF/MappedBlockStream.h
+++ b/contrib/llvm/include/llvm/DebugInfo/MSF/MappedBlockStream.h
@@ -1,5 +1,4 @@
-//===- MappedBlockStream.h - Discontiguous stream data in an MSF -*- C++
-//-*-===//
+//==- MappedBlockStream.h - Discontiguous stream data in an MSF --*- C++ -*-==//
//
// The LLVM Compiler Infrastructure
//
@@ -13,13 +12,14 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/STLExtras.h"
#include "llvm/DebugInfo/MSF/MSFStreamLayout.h"
-#include "llvm/DebugInfo/MSF/StreamInterface.h"
#include "llvm/Support/Allocator.h"
+#include "llvm/Support/BinaryStream.h"
+#include "llvm/Support/BinaryStreamRef.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/Error.h"
#include <cstdint>
+#include <memory>
#include <vector>
namespace llvm {
@@ -37,105 +37,124 @@ struct MSFLayout;
/// the MSF. MappedBlockStream provides methods for reading from and writing
/// to one of these streams transparently, as if it were a contiguous sequence
/// of bytes.
-class MappedBlockStream : public ReadableStream {
+class MappedBlockStream : public BinaryStream {
friend class WritableMappedBlockStream;
+
public:
static std::unique_ptr<MappedBlockStream>
- createStream(uint32_t BlockSize, uint32_t NumBlocks,
- const MSFStreamLayout &Layout, const ReadableStream &MsfData);
+ createStream(uint32_t BlockSize, const MSFStreamLayout &Layout,
+ BinaryStreamRef MsfData, BumpPtrAllocator &Allocator);
static std::unique_ptr<MappedBlockStream>
- createIndexedStream(const MSFLayout &Layout, const ReadableStream &MsfData,
- uint32_t StreamIndex);
+ createIndexedStream(const MSFLayout &Layout, BinaryStreamRef MsfData,
+ uint32_t StreamIndex, BumpPtrAllocator &Allocator);
static std::unique_ptr<MappedBlockStream>
- createFpmStream(const MSFLayout &Layout, const ReadableStream &MsfData);
+ createFpmStream(const MSFLayout &Layout, BinaryStreamRef MsfData,
+ BumpPtrAllocator &Allocator);
static std::unique_ptr<MappedBlockStream>
- createDirectoryStream(const MSFLayout &Layout, const ReadableStream &MsfData);
+ createDirectoryStream(const MSFLayout &Layout, BinaryStreamRef MsfData,
+ BumpPtrAllocator &Allocator);
+
+ support::endianness getEndian() const override {
+ return support::little;
+ }
Error readBytes(uint32_t Offset, uint32_t Size,
- ArrayRef<uint8_t> &Buffer) const override;
+ ArrayRef<uint8_t> &Buffer) override;
Error readLongestContiguousChunk(uint32_t Offset,
- ArrayRef<uint8_t> &Buffer) const override;
+ ArrayRef<uint8_t> &Buffer) override;
- uint32_t getLength() const override;
+ uint32_t getLength() override;
- uint32_t getNumBytesCopied() const;
-
- llvm::BumpPtrAllocator &getAllocator() { return Pool; }
+ BumpPtrAllocator &getAllocator() { return Allocator; }
void invalidateCache();
uint32_t getBlockSize() const { return BlockSize; }
- uint32_t getNumBlocks() const { return NumBlocks; }
+ uint32_t getNumBlocks() const { return StreamLayout.Blocks.size(); }
uint32_t getStreamLength() const { return StreamLayout.Length; }
protected:
- MappedBlockStream(uint32_t BlockSize, uint32_t NumBlocks,
- const MSFStreamLayout &StreamLayout,
- const ReadableStream &MsfData);
+ MappedBlockStream(uint32_t BlockSize, const MSFStreamLayout &StreamLayout,
+ BinaryStreamRef MsfData, BumpPtrAllocator &Allocator);
private:
const MSFStreamLayout &getStreamLayout() const { return StreamLayout; }
void fixCacheAfterWrite(uint32_t Offset, ArrayRef<uint8_t> Data) const;
- Error readBytes(uint32_t Offset, MutableArrayRef<uint8_t> Buffer) const;
+ Error readBytes(uint32_t Offset, MutableArrayRef<uint8_t> Buffer);
bool tryReadContiguously(uint32_t Offset, uint32_t Size,
- ArrayRef<uint8_t> &Buffer) const;
+ ArrayRef<uint8_t> &Buffer);
const uint32_t BlockSize;
- const uint32_t NumBlocks;
const MSFStreamLayout StreamLayout;
- const ReadableStream &MsfData;
-
- typedef MutableArrayRef<uint8_t> CacheEntry;
- mutable llvm::BumpPtrAllocator Pool;
- mutable DenseMap<uint32_t, std::vector<CacheEntry>> CacheMap;
+ BinaryStreamRef MsfData;
+
+ using CacheEntry = MutableArrayRef<uint8_t>;
+
+ // We just store the allocator by reference. We use this to allocate
+ // contiguous memory for things like arrays or strings that cross a block
+ // boundary, and this memory is expected to outlive the stream. For example,
+ // someone could create a stream, read some stuff, then close the stream, and
+ // we would like outstanding references to fields to remain valid since the
+ // entire file is mapped anyway. Because of that, the user must supply the
+ // allocator to allocate broken records from.
+ BumpPtrAllocator &Allocator;
+ DenseMap<uint32_t, std::vector<CacheEntry>> CacheMap;
};
-class WritableMappedBlockStream : public WritableStream {
+class WritableMappedBlockStream : public WritableBinaryStream {
public:
static std::unique_ptr<WritableMappedBlockStream>
- createStream(uint32_t BlockSize, uint32_t NumBlocks,
- const MSFStreamLayout &Layout, const WritableStream &MsfData);
+ createStream(uint32_t BlockSize, const MSFStreamLayout &Layout,
+ WritableBinaryStreamRef MsfData, BumpPtrAllocator &Allocator);
static std::unique_ptr<WritableMappedBlockStream>
- createIndexedStream(const MSFLayout &Layout, const WritableStream &MsfData,
- uint32_t StreamIndex);
+ createIndexedStream(const MSFLayout &Layout, WritableBinaryStreamRef MsfData,
+ uint32_t StreamIndex, BumpPtrAllocator &Allocator);
static std::unique_ptr<WritableMappedBlockStream>
- createDirectoryStream(const MSFLayout &Layout, const WritableStream &MsfData);
+ createDirectoryStream(const MSFLayout &Layout,
+ WritableBinaryStreamRef MsfData,
+ BumpPtrAllocator &Allocator);
static std::unique_ptr<WritableMappedBlockStream>
- createFpmStream(const MSFLayout &Layout, const WritableStream &MsfData);
+ createFpmStream(const MSFLayout &Layout, WritableBinaryStreamRef MsfData,
+ BumpPtrAllocator &Allocator);
+
+ support::endianness getEndian() const override {
+ return support::little;
+ }
Error readBytes(uint32_t Offset, uint32_t Size,
- ArrayRef<uint8_t> &Buffer) const override;
+ ArrayRef<uint8_t> &Buffer) override;
Error readLongestContiguousChunk(uint32_t Offset,
- ArrayRef<uint8_t> &Buffer) const override;
- uint32_t getLength() const override;
+ ArrayRef<uint8_t> &Buffer) override;
+ uint32_t getLength() override;
- Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Buffer) const override;
+ Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Buffer) override;
- Error commit() const override;
+ Error commit() override;
const MSFStreamLayout &getStreamLayout() const {
return ReadInterface.getStreamLayout();
}
+
uint32_t getBlockSize() const { return ReadInterface.getBlockSize(); }
uint32_t getNumBlocks() const { return ReadInterface.getNumBlocks(); }
uint32_t getStreamLength() const { return ReadInterface.getStreamLength(); }
protected:
- WritableMappedBlockStream(uint32_t BlockSize, uint32_t NumBlocks,
+ WritableMappedBlockStream(uint32_t BlockSize,
const MSFStreamLayout &StreamLayout,
- const WritableStream &MsfData);
+ WritableBinaryStreamRef MsfData,
+ BumpPtrAllocator &Allocator);
private:
MappedBlockStream ReadInterface;
-
- const WritableStream &WriteInterface;
+ WritableBinaryStreamRef WriteInterface;
};
} // end namespace pdb
diff --git a/contrib/llvm/include/llvm/DebugInfo/MSF/SequencedItemStream.h b/contrib/llvm/include/llvm/DebugInfo/MSF/SequencedItemStream.h
deleted file mode 100644
index 1949bee..0000000
--- a/contrib/llvm/include/llvm/DebugInfo/MSF/SequencedItemStream.h
+++ /dev/null
@@ -1,93 +0,0 @@
-//===- SequencedItemStream.h ------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_DEBUGINFO_MSF_SEQUENCEDITEMSTREAM_H
-#define LLVM_DEBUGINFO_MSF_SEQUENCEDITEMSTREAM_H
-
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/DebugInfo/MSF/MSFError.h"
-#include "llvm/DebugInfo/MSF/StreamInterface.h"
-#include "llvm/Support/Error.h"
-#include <cstddef>
-#include <cstdint>
-
-namespace llvm {
-namespace msf {
-
-template <typename T> struct SequencedItemTraits {
- static size_t length(const T &Item) = delete;
- static ArrayRef<uint8_t> bytes(const T &Item) = delete;
-};
-
-/// SequencedItemStream represents a sequence of objects stored in a
-/// standard container but for which it is useful to view as a stream of
-/// contiguous bytes. An example of this might be if you have a std::vector
-/// of TPI records, where each record contains a byte sequence that
-/// represents that one record serialized, but where each consecutive item
-/// might not be allocated immediately after the previous item. Using a
-/// SequencedItemStream, we can adapt the VarStreamArray class to trivially
-/// extract one item at a time, allowing the data to be used anywhere a
-/// VarStreamArray could be used.
-template <typename T, typename Traits = SequencedItemTraits<T>>
-class SequencedItemStream : public ReadableStream {
-public:
- SequencedItemStream() = default;
-
- Error readBytes(uint32_t Offset, uint32_t Size,
- ArrayRef<uint8_t> &Buffer) const override {
- auto ExpectedIndex = translateOffsetIndex(Offset);
- if (!ExpectedIndex)
- return ExpectedIndex.takeError();
- const auto &Item = Items[*ExpectedIndex];
- if (Size > Traits::length(Item))
- return make_error<MSFError>(msf_error_code::insufficient_buffer);
- Buffer = Traits::bytes(Item).take_front(Size);
- return Error::success();
- }
-
- Error readLongestContiguousChunk(uint32_t Offset,
- ArrayRef<uint8_t> &Buffer) const override {
- auto ExpectedIndex = translateOffsetIndex(Offset);
- if (!ExpectedIndex)
- return ExpectedIndex.takeError();
- Buffer = Traits::bytes(Items[*ExpectedIndex]);
- return Error::success();
- }
-
- void setItems(ArrayRef<T> ItemArray) { Items = ItemArray; }
-
- uint32_t getLength() const override {
- uint32_t Size = 0;
- for (const auto &Item : Items)
- Size += Traits::length(Item);
- return Size;
- }
-
-private:
- Expected<uint32_t> translateOffsetIndex(uint32_t Offset) const {
- uint32_t CurrentOffset = 0;
- uint32_t CurrentIndex = 0;
- for (const auto &Item : Items) {
- if (CurrentOffset >= Offset)
- break;
- CurrentOffset += Traits::length(Item);
- ++CurrentIndex;
- }
- if (CurrentOffset != Offset)
- return make_error<MSFError>(msf_error_code::insufficient_buffer);
- return CurrentIndex;
- }
-
- ArrayRef<T> Items;
-};
-
-} // end namespace msf
-} // end namespace llvm
-
-#endif // LLVM_DEBUGINFO_MSF_SEQUENCEDITEMSTREAM_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/MSF/StreamInterface.h b/contrib/llvm/include/llvm/DebugInfo/MSF/StreamInterface.h
deleted file mode 100644
index 09782d8..0000000
--- a/contrib/llvm/include/llvm/DebugInfo/MSF/StreamInterface.h
+++ /dev/null
@@ -1,53 +0,0 @@
-//===- StreamInterface.h - Base interface for a stream of data --*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_DEBUGINFO_MSF_STREAMINTERFACE_H
-#define LLVM_DEBUGINFO_MSF_STREAMINTERFACE_H
-
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/Support/Error.h"
-#include <cstdint>
-
-namespace llvm {
-namespace msf {
-
-class ReadableStream {
-public:
- virtual ~ReadableStream() = default;
-
- // Given an offset into the stream and a number of bytes, attempt to read
- // the bytes and set the output ArrayRef to point to a reference into the
- // stream, without copying any data.
- virtual Error readBytes(uint32_t Offset, uint32_t Size,
- ArrayRef<uint8_t> &Buffer) const = 0;
-
- // Given an offset into the stream, read as much as possible without copying
- // any data.
- virtual Error readLongestContiguousChunk(uint32_t Offset,
- ArrayRef<uint8_t> &Buffer) const = 0;
-
- virtual uint32_t getLength() const = 0;
-};
-
-class WritableStream : public ReadableStream {
-public:
- ~WritableStream() override = default;
-
- // Attempt to write the given bytes into the stream at the desired offset.
- // This will always necessitate a copy. Cannot shrink or grow the stream,
- // only writes into existing allocated space.
- virtual Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Data) const = 0;
-
- virtual Error commit() const = 0;
-};
-
-} // end namespace msf
-} // end namespace llvm
-
-#endif // LLVM_DEBUGINFO_MSF_STREAMINTERFACE_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/MSF/StreamReader.h b/contrib/llvm/include/llvm/DebugInfo/MSF/StreamReader.h
deleted file mode 100644
index fc2ca78..0000000
--- a/contrib/llvm/include/llvm/DebugInfo/MSF/StreamReader.h
+++ /dev/null
@@ -1,121 +0,0 @@
-//===- StreamReader.h - Reads bytes and objects from a stream ---*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_DEBUGINFO_MSF_STREAMREADER_H
-#define LLVM_DEBUGINFO_MSF_STREAMREADER_H
-
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/DebugInfo/MSF/MSFError.h"
-#include "llvm/DebugInfo/MSF/StreamArray.h"
-#include "llvm/DebugInfo/MSF/StreamInterface.h"
-#include "llvm/DebugInfo/MSF/StreamRef.h"
-#include "llvm/Support/Endian.h"
-#include "llvm/Support/Error.h"
-
-#include <string>
-
-namespace llvm {
-namespace msf {
-
-class StreamReader {
-public:
- StreamReader(ReadableStreamRef Stream);
-
- Error readLongestContiguousChunk(ArrayRef<uint8_t> &Buffer);
- Error readBytes(ArrayRef<uint8_t> &Buffer, uint32_t Size);
- Error readInteger(uint8_t &Dest);
- Error readInteger(uint16_t &Dest);
- Error readInteger(uint32_t &Dest);
- Error readInteger(uint64_t &Dest);
- Error readInteger(int8_t &Dest);
- Error readInteger(int16_t &Dest);
- Error readInteger(int32_t &Dest);
- Error readInteger(int64_t &Dest);
- Error readZeroString(StringRef &Dest);
- Error readFixedString(StringRef &Dest, uint32_t Length);
- Error readStreamRef(ReadableStreamRef &Ref);
- Error readStreamRef(ReadableStreamRef &Ref, uint32_t Length);
-
- template <typename T> Error readEnum(T &Dest) {
- typename std::underlying_type<T>::type N;
- if (auto EC = readInteger(N))
- return EC;
- Dest = static_cast<T>(N);
- return Error::success();
- }
-
- template <typename T> Error readObject(const T *&Dest) {
- ArrayRef<uint8_t> Buffer;
- if (auto EC = readBytes(Buffer, sizeof(T)))
- return EC;
- Dest = reinterpret_cast<const T *>(Buffer.data());
- return Error::success();
- }
-
- template <typename T>
- Error readArray(ArrayRef<T> &Array, uint32_t NumElements) {
- ArrayRef<uint8_t> Bytes;
- if (NumElements == 0) {
- Array = ArrayRef<T>();
- return Error::success();
- }
-
- if (NumElements > UINT32_MAX / sizeof(T))
- return make_error<MSFError>(msf_error_code::insufficient_buffer);
-
- if (auto EC = readBytes(Bytes, NumElements * sizeof(T)))
- return EC;
- Array = ArrayRef<T>(reinterpret_cast<const T *>(Bytes.data()), NumElements);
- return Error::success();
- }
-
- template <typename T, typename U>
- Error readArray(VarStreamArray<T, U> &Array, uint32_t Size) {
- ReadableStreamRef S;
- if (auto EC = readStreamRef(S, Size))
- return EC;
- Array = VarStreamArray<T, U>(S, Array.getExtractor());
- return Error::success();
- }
-
- template <typename T>
- Error readArray(FixedStreamArray<T> &Array, uint32_t NumItems) {
- if (NumItems == 0) {
- Array = FixedStreamArray<T>();
- return Error::success();
- }
- uint32_t Length = NumItems * sizeof(T);
- if (Length / sizeof(T) != NumItems)
- return make_error<MSFError>(msf_error_code::invalid_format);
- if (Offset + Length > Stream.getLength())
- return make_error<MSFError>(msf_error_code::insufficient_buffer);
- ReadableStreamRef View = Stream.slice(Offset, Length);
- Array = FixedStreamArray<T>(View);
- Offset += Length;
- return Error::success();
- }
-
- bool empty() const { return bytesRemaining() == 0; }
- void setOffset(uint32_t Off) { Offset = Off; }
- uint32_t getOffset() const { return Offset; }
- uint32_t getLength() const { return Stream.getLength(); }
- uint32_t bytesRemaining() const { return getLength() - getOffset(); }
-
- Error skip(uint32_t Amount);
-
- uint8_t peek() const;
-
-private:
- ReadableStreamRef Stream;
- uint32_t Offset;
-};
-} // namespace msf
-} // namespace llvm
-
-#endif // LLVM_DEBUGINFO_MSF_STREAMREADER_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/MSF/StreamRef.h b/contrib/llvm/include/llvm/DebugInfo/MSF/StreamRef.h
deleted file mode 100644
index eee71e5..0000000
--- a/contrib/llvm/include/llvm/DebugInfo/MSF/StreamRef.h
+++ /dev/null
@@ -1,135 +0,0 @@
-//===- StreamRef.h - A copyable reference to a stream -----------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_DEBUGINFO_MSF_STREAMREF_H
-#define LLVM_DEBUGINFO_MSF_STREAMREF_H
-
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/DebugInfo/MSF/MSFError.h"
-#include "llvm/DebugInfo/MSF/StreamInterface.h"
-#include "llvm/Support/Error.h"
-#include <algorithm>
-#include <cstdint>
-
-namespace llvm {
-namespace msf {
-
-template <class StreamType, class RefType> class StreamRefBase {
-public:
- StreamRefBase() : Stream(nullptr), ViewOffset(0), Length(0) {}
- StreamRefBase(const StreamType &Stream, uint32_t Offset, uint32_t Length)
- : Stream(&Stream), ViewOffset(Offset), Length(Length) {}
-
- uint32_t getLength() const { return Length; }
- const StreamType *getStream() const { return Stream; }
-
- RefType drop_front(uint32_t N) const {
- if (!Stream)
- return RefType();
-
- N = std::min(N, Length);
- return RefType(*Stream, ViewOffset + N, Length - N);
- }
-
- RefType keep_front(uint32_t N) const {
- if (!Stream)
- return RefType();
- N = std::min(N, Length);
- return RefType(*Stream, ViewOffset, N);
- }
-
- RefType slice(uint32_t Offset, uint32_t Len) const {
- return drop_front(Offset).keep_front(Len);
- }
-
- bool operator==(const RefType &Other) const {
- if (Stream != Other.Stream)
- return false;
- if (ViewOffset != Other.ViewOffset)
- return false;
- if (Length != Other.Length)
- return false;
- return true;
- }
-
-protected:
- const StreamType *Stream;
- uint32_t ViewOffset;
- uint32_t Length;
-};
-
-class ReadableStreamRef
- : public StreamRefBase<ReadableStream, ReadableStreamRef> {
-public:
- ReadableStreamRef() = default;
- ReadableStreamRef(const ReadableStream &Stream)
- : StreamRefBase(Stream, 0, Stream.getLength()) {}
- ReadableStreamRef(const ReadableStream &Stream, uint32_t Offset,
- uint32_t Length)
- : StreamRefBase(Stream, Offset, Length) {}
-
- // Use StreamRef.slice() instead.
- ReadableStreamRef(const ReadableStreamRef &S, uint32_t Offset,
- uint32_t Length) = delete;
-
- Error readBytes(uint32_t Offset, uint32_t Size,
- ArrayRef<uint8_t> &Buffer) const {
- if (ViewOffset + Offset < Offset)
- return make_error<MSFError>(msf_error_code::insufficient_buffer);
- if (Size + Offset > Length)
- return make_error<MSFError>(msf_error_code::insufficient_buffer);
- return Stream->readBytes(ViewOffset + Offset, Size, Buffer);
- }
-
- // Given an offset into the stream, read as much as possible without copying
- // any data.
- Error readLongestContiguousChunk(uint32_t Offset,
- ArrayRef<uint8_t> &Buffer) const {
- if (Offset >= Length)
- return make_error<MSFError>(msf_error_code::insufficient_buffer);
-
- if (auto EC = Stream->readLongestContiguousChunk(Offset, Buffer))
- return EC;
- // This StreamRef might refer to a smaller window over a larger stream. In
- // that case we will have read out more bytes than we should return, because
- // we should not read past the end of the current view.
- uint32_t MaxLength = Length - Offset;
- if (Buffer.size() > MaxLength)
- Buffer = Buffer.slice(0, MaxLength);
- return Error::success();
- }
-};
-
-class WritableStreamRef
- : public StreamRefBase<WritableStream, WritableStreamRef> {
-public:
- WritableStreamRef() = default;
- WritableStreamRef(const WritableStream &Stream)
- : StreamRefBase(Stream, 0, Stream.getLength()) {}
- WritableStreamRef(const WritableStream &Stream, uint32_t Offset,
- uint32_t Length)
- : StreamRefBase(Stream, Offset, Length) {}
-
- // Use StreamRef.slice() instead.
- WritableStreamRef(const WritableStreamRef &S, uint32_t Offset,
- uint32_t Length) = delete;
-
- Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Data) const {
- if (Data.size() + Offset > Length)
- return make_error<MSFError>(msf_error_code::insufficient_buffer);
- return Stream->writeBytes(ViewOffset + Offset, Data);
- }
-
- Error commit() const { return Stream->commit(); }
-};
-
-} // end namespace msf
-} // end namespace llvm
-
-#endif // LLVM_DEBUGINFO_MSF_STREAMREF_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/MSF/StreamWriter.h b/contrib/llvm/include/llvm/DebugInfo/MSF/StreamWriter.h
deleted file mode 100644
index 2bb1443..0000000
--- a/contrib/llvm/include/llvm/DebugInfo/MSF/StreamWriter.h
+++ /dev/null
@@ -1,92 +0,0 @@
-//===- StreamWriter.h - Writes bytes and objects to a stream ----*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_DEBUGINFO_MSF_STREAMWRITER_H
-#define LLVM_DEBUGINFO_MSF_STREAMWRITER_H
-
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/DebugInfo/MSF/MSFError.h"
-#include "llvm/DebugInfo/MSF/StreamArray.h"
-#include "llvm/DebugInfo/MSF/StreamRef.h"
-#include "llvm/Support/Error.h"
-#include <cstdint>
-#include <type_traits>
-
-namespace llvm {
-namespace msf {
-
-class StreamWriter {
-public:
- StreamWriter() = default;
- explicit StreamWriter(WritableStreamRef Stream);
-
- Error writeBytes(ArrayRef<uint8_t> Buffer);
- Error writeInteger(uint8_t Int);
- Error writeInteger(uint16_t Dest);
- Error writeInteger(uint32_t Dest);
- Error writeInteger(uint64_t Dest);
- Error writeInteger(int8_t Int);
- Error writeInteger(int16_t Dest);
- Error writeInteger(int32_t Dest);
- Error writeInteger(int64_t Dest);
- Error writeZeroString(StringRef Str);
- Error writeFixedString(StringRef Str);
- Error writeStreamRef(ReadableStreamRef Ref);
- Error writeStreamRef(ReadableStreamRef Ref, uint32_t Size);
-
- template <typename T> Error writeEnum(T Num) {
- return writeInteger(
- static_cast<typename std::underlying_type<T>::type>(Num));
- }
-
- template <typename T> Error writeObject(const T &Obj) {
- static_assert(!std::is_pointer<T>::value,
- "writeObject should not be used with pointers, to write "
- "the pointed-to value dereference the pointer before calling "
- "writeObject");
- return writeBytes(
- ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(&Obj), sizeof(T)));
- }
-
- template <typename T> Error writeArray(ArrayRef<T> Array) {
- if (Array.empty())
- return Error::success();
-
- if (Array.size() > UINT32_MAX / sizeof(T))
- return make_error<MSFError>(msf_error_code::insufficient_buffer);
-
- return writeBytes(
- ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(Array.data()),
- Array.size() * sizeof(T)));
- }
-
- template <typename T, typename U>
- Error writeArray(VarStreamArray<T, U> Array) {
- return writeStreamRef(Array.getUnderlyingStream());
- }
-
- template <typename T> Error writeArray(FixedStreamArray<T> Array) {
- return writeStreamRef(Array.getUnderlyingStream());
- }
-
- void setOffset(uint32_t Off) { Offset = Off; }
- uint32_t getOffset() const { return Offset; }
- uint32_t getLength() const { return Stream.getLength(); }
- uint32_t bytesRemaining() const { return getLength() - getOffset(); }
-
-private:
- WritableStreamRef Stream;
- uint32_t Offset = 0;
-};
-
-} // end namespace msf
-} // end namespace llvm
-
-#endif // LLVM_DEBUGINFO_MSF_STREAMWRITER_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/ConcreteSymbolEnumerator.h b/contrib/llvm/include/llvm/DebugInfo/PDB/ConcreteSymbolEnumerator.h
index 9bf0738..9713dce 100644
--- a/contrib/llvm/include/llvm/DebugInfo/PDB/ConcreteSymbolEnumerator.h
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/ConcreteSymbolEnumerator.h
@@ -34,12 +34,11 @@ public:
std::unique_ptr<ChildType> getChildAtIndex(uint32_t Index) const override {
std::unique_ptr<PDBSymbol> Child = Enumerator->getChildAtIndex(Index);
- return make_concrete_child(std::move(Child));
+ return unique_dyn_cast_or_null<ChildType>(Child);
}
std::unique_ptr<ChildType> getNext() override {
- std::unique_ptr<PDBSymbol> Child = Enumerator->getNext();
- return make_concrete_child(std::move(Child));
+ return unique_dyn_cast_or_null<ChildType>(Enumerator->getNext());
}
void reset() override { Enumerator->reset(); }
@@ -50,11 +49,6 @@ public:
}
private:
- std::unique_ptr<ChildType>
- make_concrete_child(std::unique_ptr<PDBSymbol> Child) const {
- ChildType *ConcreteChild = dyn_cast_or_null<ChildType>(Child.release());
- return std::unique_ptr<ChildType>(ConcreteChild);
- }
std::unique_ptr<IPDBEnumSymbols> Enumerator;
};
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/DIA/DIAEnumDebugStreams.h b/contrib/llvm/include/llvm/DebugInfo/PDB/DIA/DIAEnumDebugStreams.h
index 941e16a..ffae664 100644
--- a/contrib/llvm/include/llvm/DebugInfo/PDB/DIA/DIAEnumDebugStreams.h
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/DIA/DIAEnumDebugStreams.h
@@ -11,6 +11,7 @@
#define LLVM_DEBUGINFO_PDB_DIA_DIAENUMDEBUGSTREAMS_H
#include "DIASupport.h"
+#include "llvm/DebugInfo/PDB/IPDBDataStream.h"
#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
namespace llvm {
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/DIA/DIAEnumLineNumbers.h b/contrib/llvm/include/llvm/DebugInfo/PDB/DIA/DIAEnumLineNumbers.h
index 106b84c..08f0de1 100644
--- a/contrib/llvm/include/llvm/DebugInfo/PDB/DIA/DIAEnumLineNumbers.h
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/DIA/DIAEnumLineNumbers.h
@@ -12,6 +12,7 @@
#include "DIASupport.h"
#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
+#include "llvm/DebugInfo/PDB/IPDBLineNumber.h"
namespace llvm {
namespace pdb {
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/DIA/DIAEnumSourceFiles.h b/contrib/llvm/include/llvm/DebugInfo/PDB/DIA/DIAEnumSourceFiles.h
index 6c00d6a..e69d18f 100644
--- a/contrib/llvm/include/llvm/DebugInfo/PDB/DIA/DIAEnumSourceFiles.h
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/DIA/DIAEnumSourceFiles.h
@@ -12,6 +12,7 @@
#include "DIASupport.h"
#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
+#include "llvm/DebugInfo/PDB/IPDBSourceFile.h"
namespace llvm {
namespace pdb {
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/DIA/DIAEnumSymbols.h b/contrib/llvm/include/llvm/DebugInfo/PDB/DIA/DIAEnumSymbols.h
index b206ff5..f779cd1 100644
--- a/contrib/llvm/include/llvm/DebugInfo/PDB/DIA/DIAEnumSymbols.h
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/DIA/DIAEnumSymbols.h
@@ -12,6 +12,7 @@
#include "DIASupport.h"
#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
+#include "llvm/DebugInfo/PDB/PDBSymbol.h"
namespace llvm {
namespace pdb {
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/DIA/DIARawSymbol.h b/contrib/llvm/include/llvm/DebugInfo/PDB/DIA/DIARawSymbol.h
index 1e40c46..d37b485 100644
--- a/contrib/llvm/include/llvm/DebugInfo/PDB/DIA/DIARawSymbol.h
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/DIA/DIARawSymbol.h
@@ -102,9 +102,11 @@ public:
uint32_t getVirtualBaseDispIndex() const override;
uint32_t getVirtualBaseOffset() const override;
uint32_t getVirtualTableShapeId() const override;
+ std::unique_ptr<PDBSymbolTypeBuiltin>
+ getVirtualBaseTableType() const override;
PDB_DataKind getDataKind() const override;
PDB_SymType getSymTag() const override;
- PDB_UniqueId getGuid() const override;
+ codeview::GUID getGuid() const override;
int32_t getOffset() const override;
int32_t getThisAdjust() const override;
int32_t getVirtualBasePointerOffset() const override;
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/DIA/DIASession.h b/contrib/llvm/include/llvm/DebugInfo/PDB/DIA/DIASession.h
index 3f58186..3504425 100644
--- a/contrib/llvm/include/llvm/DebugInfo/PDB/DIA/DIASession.h
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/DIA/DIASession.h
@@ -31,7 +31,7 @@ public:
uint64_t getLoadAddress() const override;
void setLoadAddress(uint64_t Address) override;
- std::unique_ptr<PDBSymbolExe> getGlobalScope() const override;
+ std::unique_ptr<PDBSymbolExe> getGlobalScope() override;
std::unique_ptr<PDBSymbol> getSymbolById(uint32_t SymbolId) const override;
std::unique_ptr<PDBSymbol>
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/GenericError.h b/contrib/llvm/include/llvm/DebugInfo/PDB/GenericError.h
index 466cb45..03205a9 100644
--- a/contrib/llvm/include/llvm/DebugInfo/PDB/GenericError.h
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/GenericError.h
@@ -19,6 +19,7 @@ namespace pdb {
enum class generic_error_code {
invalid_path = 1,
dia_sdk_not_present,
+ type_server_not_found,
unspecified,
};
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/IPDBDataStream.h b/contrib/llvm/include/llvm/DebugInfo/PDB/IPDBDataStream.h
index 9594dc1..67b5a06 100644
--- a/contrib/llvm/include/llvm/DebugInfo/PDB/IPDBDataStream.h
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/IPDBDataStream.h
@@ -1,4 +1,4 @@
-//===- IPDBDataStream.h - base interface for child enumerator -*- C++ ---*-===//
+//===- IPDBDataStream.h - base interface for child enumerator ---*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -10,9 +10,10 @@
#ifndef LLVM_DEBUGINFO_PDB_IPDBDATASTREAM_H
#define LLVM_DEBUGINFO_PDB_IPDBDATASTREAM_H
-#include "PDBTypes.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallVector.h"
+#include <cstdint>
+#include <string>
namespace llvm {
namespace pdb {
@@ -22,18 +23,19 @@ namespace pdb {
/// stream type.
class IPDBDataStream {
public:
- typedef llvm::SmallVector<uint8_t, 32> RecordType;
+ using RecordType = SmallVector<uint8_t, 32>;
virtual ~IPDBDataStream();
virtual uint32_t getRecordCount() const = 0;
virtual std::string getName() const = 0;
- virtual llvm::Optional<RecordType> getItemAtIndex(uint32_t Index) const = 0;
+ virtual Optional<RecordType> getItemAtIndex(uint32_t Index) const = 0;
virtual bool getNext(RecordType &Record) = 0;
virtual void reset() = 0;
virtual IPDBDataStream *clone() const = 0;
};
-}
-}
-#endif
+} // end namespace pdb
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_PDB_IPDBDATASTREAM_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/IPDBEnumChildren.h b/contrib/llvm/include/llvm/DebugInfo/PDB/IPDBEnumChildren.h
index e48dc25..b6b7d95 100644
--- a/contrib/llvm/include/llvm/DebugInfo/PDB/IPDBEnumChildren.h
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/IPDBEnumChildren.h
@@ -18,8 +18,8 @@ namespace pdb {
template <typename ChildType> class IPDBEnumChildren {
public:
- typedef std::unique_ptr<ChildType> ChildTypePtr;
- typedef IPDBEnumChildren<ChildType> MyType;
+ using ChildTypePtr = std::unique_ptr<ChildType>;
+ using MyType = IPDBEnumChildren<ChildType>;
virtual ~IPDBEnumChildren() = default;
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/IPDBRawSymbol.h b/contrib/llvm/include/llvm/DebugInfo/PDB/IPDBRawSymbol.h
index 49866b8..eefc365 100644
--- a/contrib/llvm/include/llvm/DebugInfo/PDB/IPDBRawSymbol.h
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/IPDBRawSymbol.h
@@ -21,6 +21,9 @@ class raw_ostream;
namespace pdb {
+class PDBSymbolTypeVTable;
+class PDBSymbolTypeVTableShape;
+
/// IPDBRawSymbol defines an interface used to represent an arbitrary symbol.
/// It exposes a monolithic interface consisting of accessors for the union of
/// all properties that are valid for any symbol type. This interface is then
@@ -110,10 +113,12 @@ public:
virtual Variant getValue() const = 0;
virtual uint32_t getVirtualBaseDispIndex() const = 0;
virtual uint32_t getVirtualBaseOffset() const = 0;
+ virtual std::unique_ptr<PDBSymbolTypeBuiltin>
+ getVirtualBaseTableType() const = 0;
virtual uint32_t getVirtualTableShapeId() const = 0;
virtual PDB_DataKind getDataKind() const = 0;
virtual PDB_SymType getSymTag() const = 0;
- virtual PDB_UniqueId getGuid() const = 0;
+ virtual codeview::GUID getGuid() const = 0;
virtual int32_t getOffset() const = 0;
virtual int32_t getThisAdjust() const = 0;
virtual int32_t getVirtualBasePointerOffset() const = 0;
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/IPDBSession.h b/contrib/llvm/include/llvm/DebugInfo/PDB/IPDBSession.h
index 15e97ac..cf19509 100644
--- a/contrib/llvm/include/llvm/DebugInfo/PDB/IPDBSession.h
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/IPDBSession.h
@@ -10,6 +10,7 @@
#ifndef LLVM_DEBUGINFO_PDB_IPDBSESSION_H
#define LLVM_DEBUGINFO_PDB_IPDBSESSION_H
+#include "PDBSymbol.h"
#include "PDBTypes.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Casting.h"
@@ -28,20 +29,12 @@ public:
virtual uint64_t getLoadAddress() const = 0;
virtual void setLoadAddress(uint64_t Address) = 0;
- virtual std::unique_ptr<PDBSymbolExe> getGlobalScope() const = 0;
+ virtual std::unique_ptr<PDBSymbolExe> getGlobalScope() = 0;
virtual std::unique_ptr<PDBSymbol> getSymbolById(uint32_t SymbolId) const = 0;
template <typename T>
std::unique_ptr<T> getConcreteSymbolById(uint32_t SymbolId) const {
- auto Symbol(getSymbolById(SymbolId));
- if (!Symbol)
- return nullptr;
-
- T *ConcreteSymbol = dyn_cast<T>(Symbol.get());
- if (!ConcreteSymbol)
- return nullptr;
- (void)Symbol.release();
- return std::unique_ptr<T>(ConcreteSymbol);
+ return unique_dyn_cast_or_null<T>(getSymbolById(SymbolId));
}
virtual std::unique_ptr<PDBSymbol>
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/Raw/ModInfo.h b/contrib/llvm/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h
index bf5cf53..8200f51 100644
--- a/contrib/llvm/include/llvm/DebugInfo/PDB/Raw/ModInfo.h
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h
@@ -1,4 +1,4 @@
-//===- ModInfo.h - PDB module information -----------------------*- C++ -*-===//
+//===- DbiModuleDescriptor.h - PDB module information -----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,13 +7,13 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_DEBUGINFO_PDB_RAW_MODINFO_H
-#define LLVM_DEBUGINFO_PDB_RAW_MODINFO_H
+#ifndef LLVM_DEBUGINFO_PDB_RAW_DBIMODULEDESCRIPTOR_H
+#define LLVM_DEBUGINFO_PDB_RAW_DBIMODULEDESCRIPTOR_H
#include "llvm/ADT/StringRef.h"
-#include "llvm/DebugInfo/MSF/StreamArray.h"
-#include "llvm/DebugInfo/MSF/StreamRef.h"
-#include "llvm/DebugInfo/PDB/Raw/RawTypes.h"
+#include "llvm/DebugInfo/PDB/Native/RawTypes.h"
+#include "llvm/Support/BinaryStreamArray.h"
+#include "llvm/Support/BinaryStreamRef.h"
#include "llvm/Support/Error.h"
#include <cstdint>
#include <vector>
@@ -22,21 +22,21 @@ namespace llvm {
namespace pdb {
-class ModInfo {
+class DbiModuleDescriptor {
friend class DbiStreamBuilder;
public:
- ModInfo();
- ModInfo(const ModInfo &Info);
- ~ModInfo();
+ DbiModuleDescriptor();
+ DbiModuleDescriptor(const DbiModuleDescriptor &Info);
+ ~DbiModuleDescriptor();
- static Error initialize(msf::ReadableStreamRef Stream, ModInfo &Info);
+ static Error initialize(BinaryStreamRef Stream, DbiModuleDescriptor &Info);
bool hasECInfo() const;
uint16_t getTypeServerIndex() const;
uint16_t getModuleStreamIndex() const;
uint32_t getSymbolDebugInfoByteSize() const;
- uint32_t getLineInfoByteSize() const;
+ uint32_t getC11LineInfoByteSize() const;
uint32_t getC13LineInfoByteSize() const;
uint32_t getNumberOfFiles() const;
uint32_t getSourceFileNameIndex() const;
@@ -53,30 +53,18 @@ private:
const ModuleInfoHeader *Layout = nullptr;
};
-struct ModuleInfoEx {
- ModuleInfoEx(const ModInfo &Info) : Info(Info) {}
- ModuleInfoEx(const ModuleInfoEx &Ex) = default;
-
- ModInfo Info;
- std::vector<StringRef> SourceFiles;
-};
-
} // end namespace pdb
-namespace msf {
-
-template <> struct VarStreamArrayExtractor<pdb::ModInfo> {
- Error operator()(ReadableStreamRef Stream, uint32_t &Length,
- pdb::ModInfo &Info) const {
- if (auto EC = pdb::ModInfo::initialize(Stream, Info))
+template <> struct VarStreamArrayExtractor<pdb::DbiModuleDescriptor> {
+ Error operator()(BinaryStreamRef Stream, uint32_t &Length,
+ pdb::DbiModuleDescriptor &Info) {
+ if (auto EC = pdb::DbiModuleDescriptor::initialize(Stream, Info))
return EC;
Length = Info.getRecordLength();
return Error::success();
}
};
-} // end namespace msf
-
} // end namespace llvm
-#endif // LLVM_DEBUGINFO_PDB_RAW_MODINFO_H
+#endif // LLVM_DEBUGINFO_PDB_RAW_DBIMODULEDESCRIPTOR_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h b/contrib/llvm/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h
new file mode 100644
index 0000000..c918a5d
--- /dev/null
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h
@@ -0,0 +1,105 @@
+//===- DbiModuleDescriptorBuilder.h - PDB module information ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_PDB_RAW_DBIMODULEDESCRIPTORBUILDER_H
+#define LLVM_DEBUGINFO_PDB_RAW_DBIMODULEDESCRIPTORBUILDER_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h"
+#include "llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h"
+#include "llvm/DebugInfo/CodeView/DebugLinesSubsection.h"
+#include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h"
+#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
+#include "llvm/DebugInfo/PDB/Native/RawTypes.h"
+#include "llvm/Support/Error.h"
+#include <cstdint>
+#include <string>
+#include <vector>
+
+namespace llvm {
+class BinaryStreamWriter;
+
+namespace codeview {
+class DebugSubsectionRecordBuilder;
+}
+
+namespace msf {
+class MSFBuilder;
+struct MSFLayout;
+}
+namespace pdb {
+
+class DbiModuleDescriptorBuilder {
+ friend class DbiStreamBuilder;
+
+public:
+ DbiModuleDescriptorBuilder(StringRef ModuleName, uint32_t ModIndex,
+ msf::MSFBuilder &Msf);
+ ~DbiModuleDescriptorBuilder();
+
+ DbiModuleDescriptorBuilder(const DbiModuleDescriptorBuilder &) = delete;
+ DbiModuleDescriptorBuilder &
+ operator=(const DbiModuleDescriptorBuilder &) = delete;
+
+ void setPdbFilePathNI(uint32_t NI);
+ void setObjFileName(StringRef Name);
+ void addSymbol(codeview::CVSymbol Symbol);
+
+ void
+ addDebugSubsection(std::shared_ptr<codeview::DebugSubsection> Subsection);
+
+ void
+ addDebugSubsection(const codeview::DebugSubsectionRecord &SubsectionContents);
+
+ uint16_t getStreamIndex() const;
+ StringRef getModuleName() const { return ModuleName; }
+ StringRef getObjFileName() const { return ObjFileName; }
+
+ unsigned getModuleIndex() const { return Layout.Mod; }
+
+ ArrayRef<std::string> source_files() const {
+ return makeArrayRef(SourceFiles);
+ }
+
+ uint32_t calculateSerializedLength() const;
+
+ /// Return the offset within the module symbol stream of the next symbol
+ /// record passed to addSymbol. Add four to account for the signature.
+ uint32_t getNextSymbolOffset() const { return SymbolByteSize + 4; }
+
+ void finalize();
+ Error finalizeMsfLayout();
+
+ Error commit(BinaryStreamWriter &ModiWriter, const msf::MSFLayout &MsfLayout,
+ WritableBinaryStreamRef MsfBuffer);
+
+private:
+ uint32_t calculateC13DebugInfoSize() const;
+
+ void addSourceFile(StringRef Path);
+ msf::MSFBuilder &MSF;
+
+ uint32_t SymbolByteSize = 0;
+ uint32_t PdbFilePathNI = 0;
+ std::string ModuleName;
+ std::string ObjFileName;
+ std::vector<std::string> SourceFiles;
+ std::vector<codeview::CVSymbol> Symbols;
+
+ std::vector<std::unique_ptr<codeview::DebugSubsectionRecordBuilder>>
+ C13Builders;
+
+ ModuleInfoHeader Layout;
+};
+
+} // end namespace pdb
+
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_PDB_RAW_DBIMODULEDESCRIPTORBUILDER_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/Native/DbiModuleList.h b/contrib/llvm/include/llvm/DebugInfo/PDB/Native/DbiModuleList.h
new file mode 100644
index 0000000..5f6e7ab9
--- /dev/null
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/Native/DbiModuleList.h
@@ -0,0 +1,118 @@
+//===- DbiModuleList.h - PDB module information list ------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_PDB_NATIVE_DBIMODULELIST_H
+#define LLVM_DEBUGINFO_PDB_NATIVE_DBIMODULELIST_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/iterator.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h"
+#include "llvm/Support/BinaryStreamArray.h"
+#include "llvm/Support/BinaryStreamRef.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
+#include <cstddef>
+#include <cstdint>
+#include <iterator>
+#include <vector>
+
+namespace llvm {
+namespace pdb {
+
+class DbiModuleList;
+struct FileInfoSubstreamHeader;
+
+class DbiModuleSourceFilesIterator
+ : public iterator_facade_base<DbiModuleSourceFilesIterator,
+ std::random_access_iterator_tag, StringRef> {
+ using BaseType =
+ iterator_facade_base<DbiModuleSourceFilesIterator,
+ std::random_access_iterator_tag, StringRef>;
+
+public:
+ DbiModuleSourceFilesIterator(const DbiModuleList &Modules, uint32_t Modi,
+ uint16_t Filei);
+ DbiModuleSourceFilesIterator() = default;
+ DbiModuleSourceFilesIterator &
+ operator=(const DbiModuleSourceFilesIterator &R) = default;
+
+ bool operator==(const DbiModuleSourceFilesIterator &R) const;
+
+ const StringRef &operator*() const { return ThisValue; }
+ StringRef &operator*() { return ThisValue; }
+
+ bool operator<(const DbiModuleSourceFilesIterator &RHS) const;
+ std::ptrdiff_t operator-(const DbiModuleSourceFilesIterator &R) const;
+ DbiModuleSourceFilesIterator &operator+=(std::ptrdiff_t N);
+ DbiModuleSourceFilesIterator &operator-=(std::ptrdiff_t N);
+
+private:
+ void setValue();
+
+ bool isEnd() const;
+ bool isCompatible(const DbiModuleSourceFilesIterator &R) const;
+ bool isUniversalEnd() const;
+
+ StringRef ThisValue;
+ const DbiModuleList *Modules{nullptr};
+ uint32_t Modi{0};
+ uint16_t Filei{0};
+};
+
+class DbiModuleList {
+ friend DbiModuleSourceFilesIterator;
+
+public:
+ Error initialize(BinaryStreamRef ModInfo, BinaryStreamRef FileInfo);
+
+ Expected<StringRef> getFileName(uint32_t Index) const;
+ uint32_t getModuleCount() const;
+ uint32_t getSourceFileCount() const;
+ uint16_t getSourceFileCount(uint32_t Modi) const;
+
+ iterator_range<DbiModuleSourceFilesIterator>
+ source_files(uint32_t Modi) const;
+
+ DbiModuleDescriptor getModuleDescriptor(uint32_t Modi) const;
+
+private:
+ Error initializeModInfo(BinaryStreamRef ModInfo);
+ Error initializeFileInfo(BinaryStreamRef FileInfo);
+
+ VarStreamArray<DbiModuleDescriptor> Descriptors;
+
+ FixedStreamArray<support::little32_t> FileNameOffsets;
+ FixedStreamArray<support::ulittle16_t> ModFileCountArray;
+
+ // For each module, there are multiple filenames, which can be obtained by
+ // knowing the index of the file. Given the index of the file, one can use
+ // that as an offset into the FileNameOffsets array, which contains the
+ // absolute offset of the file name in NamesBuffer. Thus, for each module
+ // we store the first index in the FileNameOffsets array for this module.
+ // The number of files for the corresponding module is stored in
+ // ModFileCountArray.
+ std::vector<uint32_t> ModuleInitialFileIndex;
+
+ // In order to provide random access into the Descriptors array, we iterate it
+ // once up front to find the offsets of the individual items and store them in
+ // this array.
+ std::vector<uint32_t> ModuleDescriptorOffsets;
+
+ const FileInfoSubstreamHeader *FileInfoHeader = nullptr;
+
+ BinaryStreamRef ModInfoSubstream;
+ BinaryStreamRef FileInfoSubstream;
+ BinaryStreamRef NamesBuffer;
+};
+
+} // end namespace pdb
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_PDB_NATIVE_DBIMODULELIST_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/Raw/DbiStream.h b/contrib/llvm/include/llvm/DebugInfo/PDB/Native/DbiStream.h
index c97ca32..4be113f 100644
--- a/contrib/llvm/include/llvm/DebugInfo/PDB/Raw/DbiStream.h
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/Native/DbiStream.h
@@ -10,15 +10,16 @@
#ifndef LLVM_DEBUGINFO_PDB_RAW_PDBDBISTREAM_H
#define LLVM_DEBUGINFO_PDB_RAW_PDBDBISTREAM_H
-#include "llvm/DebugInfo/CodeView/ModuleSubstream.h"
+#include "llvm/DebugInfo/CodeView/DebugSubsection.h"
#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
-#include "llvm/DebugInfo/MSF/StreamArray.h"
-#include "llvm/DebugInfo/MSF/StreamRef.h"
+#include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h"
+#include "llvm/DebugInfo/PDB/Native/DbiModuleList.h"
+#include "llvm/DebugInfo/PDB/Native/PDBStringTable.h"
+#include "llvm/DebugInfo/PDB/Native/RawConstants.h"
+#include "llvm/DebugInfo/PDB/Native/RawTypes.h"
#include "llvm/DebugInfo/PDB/PDBTypes.h"
-#include "llvm/DebugInfo/PDB/Raw/ModInfo.h"
-#include "llvm/DebugInfo/PDB/Raw/NameHashTable.h"
-#include "llvm/DebugInfo/PDB/Raw/RawConstants.h"
-#include "llvm/DebugInfo/PDB/Raw/RawTypes.h"
+#include "llvm/Support/BinaryStreamArray.h"
+#include "llvm/Support/BinaryStreamRef.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/Error.h"
@@ -62,57 +63,61 @@ public:
PDB_Machine getMachineType() const;
+ BinarySubstreamRef getSectionContributionData() const;
+ BinarySubstreamRef getSecMapSubstreamData() const;
+ BinarySubstreamRef getModiSubstreamData() const;
+ BinarySubstreamRef getFileInfoSubstreamData() const;
+ BinarySubstreamRef getTypeServerMapSubstreamData() const;
+ BinarySubstreamRef getECSubstreamData() const;
+
/// If the given stream type is present, returns its stream index. If it is
/// not present, returns InvalidStreamIndex.
uint32_t getDebugStreamIndex(DbgHeaderType Type) const;
- ArrayRef<ModuleInfoEx> modules() const;
-
- Expected<StringRef> getFileNameForIndex(uint32_t Index) const;
+ const DbiModuleList &modules() const;
- msf::FixedStreamArray<object::coff_section> getSectionHeaders();
+ FixedStreamArray<object::coff_section> getSectionHeaders();
- msf::FixedStreamArray<object::FpoData> getFpoRecords();
+ FixedStreamArray<object::FpoData> getFpoRecords();
- msf::FixedStreamArray<SecMapEntry> getSectionMap() const;
+ FixedStreamArray<SecMapEntry> getSectionMap() const;
void visitSectionContributions(ISectionContribVisitor &Visitor) const;
+ Expected<StringRef> getECName(uint32_t NI) const;
+
private:
- Error initializeModInfoArray();
Error initializeSectionContributionData();
Error initializeSectionHeadersData();
Error initializeSectionMapData();
- Error initializeFileInfo();
Error initializeFpoRecords();
PDBFile &Pdb;
std::unique_ptr<msf::MappedBlockStream> Stream;
- std::vector<ModuleInfoEx> ModuleInfos;
- NameHashTable ECNames;
+ PDBStringTable ECNames;
- msf::ReadableStreamRef ModInfoSubstream;
- msf::ReadableStreamRef SecContrSubstream;
- msf::ReadableStreamRef SecMapSubstream;
- msf::ReadableStreamRef FileInfoSubstream;
- msf::ReadableStreamRef TypeServerMapSubstream;
- msf::ReadableStreamRef ECSubstream;
+ BinarySubstreamRef SecContrSubstream;
+ BinarySubstreamRef SecMapSubstream;
+ BinarySubstreamRef ModiSubstream;
+ BinarySubstreamRef FileInfoSubstream;
+ BinarySubstreamRef TypeServerMapSubstream;
+ BinarySubstreamRef ECSubstream;
- msf::ReadableStreamRef NamesBuffer;
+ DbiModuleList Modules;
- msf::FixedStreamArray<support::ulittle16_t> DbgStreams;
+ FixedStreamArray<support::ulittle16_t> DbgStreams;
- PdbRaw_DbiSecContribVer SectionContribVersion;
- msf::FixedStreamArray<SectionContrib> SectionContribs;
- msf::FixedStreamArray<SectionContrib2> SectionContribs2;
- msf::FixedStreamArray<SecMapEntry> SectionMap;
- msf::FixedStreamArray<support::little32_t> FileNameOffsets;
+ PdbRaw_DbiSecContribVer SectionContribVersion =
+ PdbRaw_DbiSecContribVer::DbiSecContribVer60;
+ FixedStreamArray<SectionContrib> SectionContribs;
+ FixedStreamArray<SectionContrib2> SectionContribs2;
+ FixedStreamArray<SecMapEntry> SectionMap;
std::unique_ptr<msf::MappedBlockStream> SectionHeaderStream;
- msf::FixedStreamArray<object::coff_section> SectionHeaders;
+ FixedStreamArray<object::coff_section> SectionHeaders;
std::unique_ptr<msf::MappedBlockStream> FpoStream;
- msf::FixedStreamArray<object::FpoData> FpoRecords;
+ FixedStreamArray<object::FpoData> FpoRecords;
const DbiStreamHeader *Header;
};
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/Raw/DbiStreamBuilder.h b/contrib/llvm/include/llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h
index 99a3ac7..63eb34f 100644
--- a/contrib/llvm/include/llvm/DebugInfo/PDB/Raw/DbiStreamBuilder.h
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h
@@ -14,11 +14,12 @@
#include "llvm/ADT/StringSet.h"
#include "llvm/Support/Error.h"
-#include "llvm/DebugInfo/MSF/ByteStream.h"
-#include "llvm/DebugInfo/MSF/StreamReader.h"
+#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
+#include "llvm/DebugInfo/PDB/Native/PDBStringTableBuilder.h"
+#include "llvm/DebugInfo/PDB/Native/RawConstants.h"
#include "llvm/DebugInfo/PDB/PDBTypes.h"
-#include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
-#include "llvm/DebugInfo/PDB/Raw/RawConstants.h"
+#include "llvm/Support/BinaryByteStream.h"
+#include "llvm/Support/BinaryStreamReader.h"
#include "llvm/Support/Endian.h"
namespace llvm {
@@ -31,11 +32,13 @@ struct coff_section;
namespace pdb {
class DbiStream;
struct DbiStreamHeader;
+class DbiModuleDescriptorBuilder;
class PDBFile;
class DbiStreamBuilder {
public:
DbiStreamBuilder(msf::MSFBuilder &Msf);
+ ~DbiStreamBuilder();
DbiStreamBuilder(const DbiStreamBuilder &) = delete;
DbiStreamBuilder &operator=(const DbiStreamBuilder &) = delete;
@@ -47,26 +50,29 @@ public:
void setPdbDllRbld(uint16_t R);
void setFlags(uint16_t F);
void setMachineType(PDB_Machine M);
- void setSectionContribs(ArrayRef<SectionContrib> SecMap);
void setSectionMap(ArrayRef<SecMapEntry> SecMap);
// Add given bytes as a new stream.
Error addDbgStream(pdb::DbgHeaderType Type, ArrayRef<uint8_t> Data);
+ uint32_t addECName(StringRef Name);
+
uint32_t calculateSerializedLength() const;
- Error addModuleInfo(StringRef ObjFile, StringRef Module);
+ void setPublicsStreamIndex(uint32_t Index);
+ void setSymbolRecordStreamIndex(uint32_t Index);
+
+ Expected<DbiModuleDescriptorBuilder &> addModuleInfo(StringRef ModuleName);
Error addModuleSourceFile(StringRef Module, StringRef File);
+ Error addModuleSourceFile(DbiModuleDescriptorBuilder &Module, StringRef File);
+ Expected<uint32_t> getSourceFileNameIndex(StringRef FileName);
Error finalizeMsfLayout();
- Error commit(const msf::MSFLayout &Layout,
- const msf::WritableStream &Buffer);
+ Error commit(const msf::MSFLayout &Layout, WritableBinaryStreamRef MsfBuffer);
- // A helper function to create Section Contributions from COFF input
- // section headers.
- static std::vector<SectionContrib>
- createSectionContribs(ArrayRef<llvm::object::coff_section> SecHdrs);
+ void addSectionContrib(DbiModuleDescriptorBuilder *ModuleDbi,
+ const llvm::object::coff_section *SecHdr);
// A helper function to create a Section Map from a COFF section header.
static std::vector<SecMapEntry>
@@ -75,26 +81,20 @@ public:
private:
struct DebugStream {
ArrayRef<uint8_t> Data;
- uint16_t StreamNumber = 0;
+ uint16_t StreamNumber = kInvalidStreamIndex;
};
Error finalize();
uint32_t calculateModiSubstreamSize() const;
+ uint32_t calculateNamesOffset() const;
uint32_t calculateSectionContribsStreamSize() const;
uint32_t calculateSectionMapStreamSize() const;
uint32_t calculateFileInfoSubstreamSize() const;
uint32_t calculateNamesBufferSize() const;
uint32_t calculateDbgStreamsSize() const;
- Error generateModiSubstream();
Error generateFileInfoSubstream();
- struct ModuleInfo {
- std::vector<StringRef> SourceFiles;
- StringRef Obj;
- StringRef Mod;
- };
-
msf::MSFBuilder &Msf;
BumpPtrAllocator &Allocator;
@@ -105,18 +105,20 @@ private:
uint16_t PdbDllRbld;
uint16_t Flags;
PDB_Machine MachineType;
+ uint32_t PublicsStreamIndex = kInvalidStreamIndex;
+ uint32_t SymRecordStreamIndex = kInvalidStreamIndex;
const DbiStreamHeader *Header;
- StringMap<std::unique_ptr<ModuleInfo>> ModuleInfos;
- std::vector<ModuleInfo *> ModuleInfoList;
+ StringMap<std::unique_ptr<DbiModuleDescriptorBuilder>> ModiMap;
+ std::vector<DbiModuleDescriptorBuilder *> ModiList;
StringMap<uint32_t> SourceFileNames;
- msf::WritableStreamRef NamesBuffer;
- msf::MutableByteStream ModInfoBuffer;
- msf::MutableByteStream FileInfoBuffer;
- ArrayRef<SectionContrib> SectionContribs;
+ PDBStringTableBuilder ECNamesBuilder;
+ WritableBinaryStreamRef NamesBuffer;
+ MutableBinaryByteStream FileInfoBuffer;
+ std::vector<SectionContrib> SectionContribs;
ArrayRef<SecMapEntry> SectionMap;
llvm::SmallVector<DebugStream, (int)DbgHeaderType::Max> DbgStreams;
};
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/Raw/EnumTables.h b/contrib/llvm/include/llvm/DebugInfo/PDB/Native/EnumTables.h
index c018445..c018445 100644
--- a/contrib/llvm/include/llvm/DebugInfo/PDB/Raw/EnumTables.h
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/Native/EnumTables.h
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/Native/Formatters.h b/contrib/llvm/include/llvm/DebugInfo/PDB/Native/Formatters.h
new file mode 100644
index 0000000..7d5eab2
--- /dev/null
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/Native/Formatters.h
@@ -0,0 +1,45 @@
+//===- Formatters.h ---------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_PDB_NATIVE_FORMATTERS_H
+#define LLVM_DEBUGINFO_PDB_NATIVE_FORMATTERS_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/DebugInfo/CodeView/Formatters.h"
+#include "llvm/DebugInfo/PDB/Native/RawConstants.h"
+#include "llvm/DebugInfo/PDB/Native/RawTypes.h"
+#include "llvm/Support/FormatProviders.h"
+
+#define FORMAT_CASE(Value, Name) \
+ case Value: \
+ Stream << Name; \
+ break;
+
+namespace llvm {
+template <> struct format_provider<pdb::PdbRaw_ImplVer> {
+ static void format(const pdb::PdbRaw_ImplVer &V, llvm::raw_ostream &Stream,
+ StringRef Style) {
+ switch (V) {
+ FORMAT_CASE(pdb::PdbRaw_ImplVer::PdbImplVC110, "VC110")
+ FORMAT_CASE(pdb::PdbRaw_ImplVer::PdbImplVC140, "VC140")
+ FORMAT_CASE(pdb::PdbRaw_ImplVer::PdbImplVC2, "VC2")
+ FORMAT_CASE(pdb::PdbRaw_ImplVer::PdbImplVC4, "VC4")
+ FORMAT_CASE(pdb::PdbRaw_ImplVer::PdbImplVC41, "VC41")
+ FORMAT_CASE(pdb::PdbRaw_ImplVer::PdbImplVC50, "VC50")
+ FORMAT_CASE(pdb::PdbRaw_ImplVer::PdbImplVC70, "VC70")
+ FORMAT_CASE(pdb::PdbRaw_ImplVer::PdbImplVC70Dep, "VC70Dep")
+ FORMAT_CASE(pdb::PdbRaw_ImplVer::PdbImplVC80, "VC80")
+ FORMAT_CASE(pdb::PdbRaw_ImplVer::PdbImplVC98, "VC98")
+ }
+ }
+};
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/Raw/GlobalsStream.h b/contrib/llvm/include/llvm/DebugInfo/PDB/Native/GlobalsStream.h
index 175f093..dcea3d3 100644
--- a/contrib/llvm/include/llvm/DebugInfo/PDB/Raw/GlobalsStream.h
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/Native/GlobalsStream.h
@@ -11,10 +11,10 @@
#define LLVM_DEBUGINFO_PDB_RAW_GLOBALS_STREAM_H
#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
-#include "llvm/DebugInfo/MSF/StreamArray.h"
+#include "llvm/DebugInfo/PDB/Native/RawConstants.h"
+#include "llvm/DebugInfo/PDB/Native/RawTypes.h"
#include "llvm/DebugInfo/PDB/PDBTypes.h"
-#include "llvm/DebugInfo/PDB/Raw/RawConstants.h"
-#include "llvm/DebugInfo/PDB/Raw/RawTypes.h"
+#include "llvm/Support/BinaryStreamArray.h"
#include "llvm/Support/Error.h"
namespace llvm {
@@ -27,15 +27,15 @@ public:
explicit GlobalsStream(std::unique_ptr<msf::MappedBlockStream> Stream);
~GlobalsStream();
Error commit();
- msf::FixedStreamArray<support::ulittle32_t> getHashBuckets() const {
+ FixedStreamArray<support::ulittle32_t> getHashBuckets() const {
return HashBuckets;
}
uint32_t getNumBuckets() const { return NumBuckets; }
Error reload();
private:
- msf::FixedStreamArray<support::ulittle32_t> HashBuckets;
- msf::FixedStreamArray<PSHashRecord> HashRecords;
+ FixedStreamArray<support::ulittle32_t> HashBuckets;
+ FixedStreamArray<PSHashRecord> HashRecords;
uint32_t NumBuckets;
std::unique_ptr<msf::MappedBlockStream> Stream;
};
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/Raw/Hash.h b/contrib/llvm/include/llvm/DebugInfo/PDB/Native/Hash.h
index 0340554..1f11d43 100644
--- a/contrib/llvm/include/llvm/DebugInfo/PDB/Raw/Hash.h
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/Native/Hash.h
@@ -7,19 +7,21 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_DEBUGINFO_PDB_RAW_HASH_H
-#define LLVM_DEBUGINFO_PDB_RAW_HASH_H
+#ifndef LLVM_DEBUGINFO_PDB_NATIVE_HASH_H
+#define LLVM_DEBUGINFO_PDB_NATIVE_HASH_H
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h"
-#include <stdint.h>
+#include <cstdint>
namespace llvm {
namespace pdb {
+
uint32_t hashStringV1(StringRef Str);
uint32_t hashStringV2(StringRef Str);
uint32_t hashBufferV8(ArrayRef<uint8_t> Data);
-}
-}
-#endif
+} // end namespace pdb
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_PDB_NATIVE_HASH_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/Native/HashTable.h b/contrib/llvm/include/llvm/DebugInfo/PDB/Native/HashTable.h
new file mode 100644
index 0000000..05c70c4
--- /dev/null
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/Native/HashTable.h
@@ -0,0 +1,109 @@
+//===- HashTable.h - PDB Hash Table -----------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_PDB_NATIVE_HASHTABLE_H
+#define LLVM_DEBUGINFO_PDB_NATIVE_HASHTABLE_H
+
+#include "llvm/ADT/SparseBitVector.h"
+#include "llvm/ADT/iterator.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
+#include <cstdint>
+#include <iterator>
+#include <utility>
+#include <vector>
+
+namespace llvm {
+
+class BinaryStreamReader;
+class BinaryStreamWriter;
+
+namespace pdb {
+
+class HashTableIterator;
+
+class HashTable {
+ friend class HashTableIterator;
+
+ struct Header {
+ support::ulittle32_t Size;
+ support::ulittle32_t Capacity;
+ };
+
+ using BucketList = std::vector<std::pair<uint32_t, uint32_t>>;
+
+public:
+ HashTable();
+ explicit HashTable(uint32_t Capacity);
+
+ Error load(BinaryStreamReader &Stream);
+
+ uint32_t calculateSerializedLength() const;
+ Error commit(BinaryStreamWriter &Writer) const;
+
+ void clear();
+
+ uint32_t capacity() const;
+ uint32_t size() const;
+
+ HashTableIterator begin() const;
+ HashTableIterator end() const;
+ HashTableIterator find(uint32_t K);
+
+ void set(uint32_t K, uint32_t V);
+ void remove(uint32_t K);
+ uint32_t get(uint32_t K);
+
+protected:
+ bool isPresent(uint32_t K) const { return Present.test(K); }
+ bool isDeleted(uint32_t K) const { return Deleted.test(K); }
+
+ BucketList Buckets;
+ mutable SparseBitVector<> Present;
+ mutable SparseBitVector<> Deleted;
+
+private:
+ static uint32_t maxLoad(uint32_t capacity);
+ void grow();
+
+ static Error readSparseBitVector(BinaryStreamReader &Stream,
+ SparseBitVector<> &V);
+ static Error writeSparseBitVector(BinaryStreamWriter &Writer,
+ SparseBitVector<> &Vec);
+};
+
+class HashTableIterator
+ : public iterator_facade_base<HashTableIterator, std::forward_iterator_tag,
+ std::pair<uint32_t, uint32_t>> {
+ friend class HashTable;
+
+ HashTableIterator(const HashTable &Map, uint32_t Index, bool IsEnd);
+
+public:
+ HashTableIterator(const HashTable &Map);
+
+ HashTableIterator &operator=(const HashTableIterator &R);
+ bool operator==(const HashTableIterator &R) const;
+ const std::pair<uint32_t, uint32_t> &operator*() const;
+ HashTableIterator &operator++();
+
+private:
+ bool isEnd() const { return IsEnd; }
+ uint32_t index() const { return Index; }
+
+ const HashTable *Map;
+ uint32_t Index;
+ bool IsEnd;
+};
+
+} // end namespace pdb
+
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_PDB_NATIVE_HASHTABLE_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/Raw/ISectionContribVisitor.h b/contrib/llvm/include/llvm/DebugInfo/PDB/Native/ISectionContribVisitor.h
index fb00d6a..fb00d6a 100644
--- a/contrib/llvm/include/llvm/DebugInfo/PDB/Raw/ISectionContribVisitor.h
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/Native/ISectionContribVisitor.h
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/Raw/InfoStream.h b/contrib/llvm/include/llvm/DebugInfo/PDB/Native/InfoStream.h
index 6b8b94f..fb8271c 100644
--- a/contrib/llvm/include/llvm/DebugInfo/PDB/Raw/InfoStream.h
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/Native/InfoStream.h
@@ -10,11 +10,13 @@
#ifndef LLVM_DEBUGINFO_PDB_RAW_PDBINFOSTREAM_H
#define LLVM_DEBUGINFO_PDB_RAW_PDBINFOSTREAM_H
+#include "llvm/ADT/BitmaskEnum.h"
#include "llvm/ADT/StringMap.h"
+#include "llvm/DebugInfo/CodeView/GUID.h"
#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
+#include "llvm/DebugInfo/PDB/Native/NamedStreamMap.h"
+#include "llvm/DebugInfo/PDB/Native/RawConstants.h"
#include "llvm/DebugInfo/PDB/PDBTypes.h"
-#include "llvm/DebugInfo/PDB/Raw/NameMap.h"
-#include "llvm/DebugInfo/PDB/Raw/RawConstants.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/Error.h"
@@ -32,10 +34,21 @@ public:
Error reload();
+ uint32_t getStreamSize() const;
+
+ bool containsIdStream() const;
PdbRaw_ImplVer getVersion() const;
uint32_t getSignature() const;
uint32_t getAge() const;
- PDB_UniqueId getGuid() const;
+ codeview::GUID getGuid() const;
+ uint32_t getNamedStreamMapByteSize() const;
+
+ PdbRaw_Features getFeatures() const;
+ ArrayRef<PdbRaw_FeatureSig> getFeatureSignatures() const;
+
+ const NamedStreamMap &getNamedStreams() const;
+
+ BinarySubstreamRef getNamedStreamsBuffer() const;
uint32_t getNamedStreamIndex(llvm::StringRef Name) const;
iterator_range<StringMapConstIterator<uint32_t>> named_streams() const;
@@ -59,9 +72,16 @@ private:
// Due to the aforementioned limitations with `Signature`, this is a new
// signature present on VC70 and higher PDBs which is guaranteed to be
// universally unique.
- PDB_UniqueId Guid;
+ codeview::GUID Guid;
+
+ BinarySubstreamRef SubNamedStreams;
+
+ std::vector<PdbRaw_FeatureSig> FeatureSignatures;
+ PdbRaw_Features Features = PdbFeatureNone;
+
+ uint32_t NamedStreamMapByteSize = 0;
- NameMap NamedStreams;
+ NamedStreamMap NamedStreams;
};
}
}
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/Raw/InfoStreamBuilder.h b/contrib/llvm/include/llvm/DebugInfo/PDB/Native/InfoStreamBuilder.h
index cb60b1e..c6cb0e2 100644
--- a/contrib/llvm/include/llvm/DebugInfo/PDB/Raw/InfoStreamBuilder.h
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/Native/InfoStreamBuilder.h
@@ -13,48 +13,50 @@
#include "llvm/ADT/Optional.h"
#include "llvm/Support/Error.h"
+#include "llvm/DebugInfo/PDB/Native/NamedStreamMap.h"
+#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
+#include "llvm/DebugInfo/PDB/Native/RawConstants.h"
#include "llvm/DebugInfo/PDB/PDBTypes.h"
-#include "llvm/DebugInfo/PDB/Raw/NameMapBuilder.h"
-#include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
-#include "llvm/DebugInfo/PDB/Raw/RawConstants.h"
namespace llvm {
+class WritableBinaryStreamRef;
+
namespace msf {
class MSFBuilder;
-class StreamWriter;
}
namespace pdb {
class PDBFile;
+class NamedStreamMap;
class InfoStreamBuilder {
public:
- InfoStreamBuilder(msf::MSFBuilder &Msf);
+ InfoStreamBuilder(msf::MSFBuilder &Msf, NamedStreamMap &NamedStreams);
InfoStreamBuilder(const InfoStreamBuilder &) = delete;
InfoStreamBuilder &operator=(const InfoStreamBuilder &) = delete;
void setVersion(PdbRaw_ImplVer V);
void setSignature(uint32_t S);
void setAge(uint32_t A);
- void setGuid(PDB_UniqueId G);
-
- NameMapBuilder &getNamedStreamsBuilder();
+ void setGuid(codeview::GUID G);
+ void addFeature(PdbRaw_FeatureSig Sig);
- uint32_t calculateSerializedLength() const;
+ uint32_t finalize();
Error finalizeMsfLayout();
Error commit(const msf::MSFLayout &Layout,
- const msf::WritableStream &Buffer) const;
+ WritableBinaryStreamRef Buffer) const;
private:
msf::MSFBuilder &Msf;
+ std::vector<PdbRaw_FeatureSig> Features;
PdbRaw_ImplVer Ver;
uint32_t Sig;
uint32_t Age;
- PDB_UniqueId Guid;
+ codeview::GUID Guid;
- NameMapBuilder NamedStreams;
+ NamedStreamMap &NamedStreams;
};
}
}
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/Native/ModuleDebugStream.h b/contrib/llvm/include/llvm/DebugInfo/PDB/Native/ModuleDebugStream.h
new file mode 100644
index 0000000..f413fd1
--- /dev/null
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/Native/ModuleDebugStream.h
@@ -0,0 +1,82 @@
+//===- ModuleDebugStream.h - PDB Module Info Stream Access ------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_PDB_NATIVE_MODULEDEBUGSTREAM_H
+#define LLVM_DEBUGINFO_PDB_NATIVE_MODULEDEBUGSTREAM_H
+
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h"
+#include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h"
+#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
+#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
+#include "llvm/Support/BinaryStreamRef.h"
+#include "llvm/Support/Error.h"
+#include <cstdint>
+#include <memory>
+
+namespace llvm {
+namespace pdb {
+
+class DbiModuleDescriptor;
+
+class ModuleDebugStreamRef {
+ using DebugSubsectionIterator = codeview::DebugSubsectionArray::Iterator;
+
+public:
+ ModuleDebugStreamRef(const DbiModuleDescriptor &Module,
+ std::unique_ptr<msf::MappedBlockStream> Stream);
+ ModuleDebugStreamRef(ModuleDebugStreamRef &&Other) = default;
+ ~ModuleDebugStreamRef();
+
+ Error reload();
+
+ uint32_t signature() const { return Signature; }
+
+ iterator_range<codeview::CVSymbolArray::Iterator>
+ symbols(bool *HadError) const;
+
+ const codeview::CVSymbolArray &getSymbolArray() const { return SymbolArray; }
+
+ BinarySubstreamRef getSymbolsSubstream() const;
+ BinarySubstreamRef getC11LinesSubstream() const;
+ BinarySubstreamRef getC13LinesSubstream() const;
+ BinarySubstreamRef getGlobalRefsSubstream() const;
+
+ ModuleDebugStreamRef &operator=(ModuleDebugStreamRef &&Other) = default;
+
+ iterator_range<DebugSubsectionIterator> subsections() const;
+
+ bool hasDebugSubsections() const;
+
+ Error commit();
+
+ Expected<codeview::DebugChecksumsSubsectionRef>
+ findChecksumsSubsection() const;
+
+private:
+ const DbiModuleDescriptor &Mod;
+
+ uint32_t Signature;
+
+ std::shared_ptr<msf::MappedBlockStream> Stream;
+
+ codeview::CVSymbolArray SymbolArray;
+
+ BinarySubstreamRef SymbolsSubstream;
+ BinarySubstreamRef C11LinesSubstream;
+ BinarySubstreamRef C13LinesSubstream;
+ BinarySubstreamRef GlobalRefsSubstream;
+
+ codeview::DebugSubsectionArray Subsections;
+};
+
+} // end namespace pdb
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_PDB_NATIVE_MODULEDEBUGSTREAM_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/Native/NamedStreamMap.h b/contrib/llvm/include/llvm/DebugInfo/PDB/Native/NamedStreamMap.h
new file mode 100644
index 0000000..17a82b7
--- /dev/null
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/Native/NamedStreamMap.h
@@ -0,0 +1,60 @@
+//===- NamedStreamMap.h - PDB Named Stream Map ------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_PDB_NATIVE_NAMEDSTREAMMAP_H
+#define LLVM_DEBUGINFO_PDB_NATIVE_NAMEDSTREAMMAP_H
+
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/DebugInfo/PDB/Native/HashTable.h"
+#include "llvm/Support/Error.h"
+#include <cstdint>
+
+namespace llvm {
+
+class BinaryStreamReader;
+class BinaryStreamWriter;
+
+namespace pdb {
+
+class NamedStreamMap {
+ friend class NamedStreamMapBuilder;
+
+ struct FinalizationInfo {
+ uint32_t StringDataBytes = 0;
+ uint32_t SerializedLength = 0;
+ };
+
+public:
+ NamedStreamMap();
+
+ Error load(BinaryStreamReader &Stream);
+ Error commit(BinaryStreamWriter &Writer) const;
+ uint32_t finalize();
+
+ uint32_t size() const;
+ bool get(StringRef Stream, uint32_t &StreamNo) const;
+ void set(StringRef Stream, uint32_t StreamNo);
+ void remove(StringRef Stream);
+ const StringMap<uint32_t> &getStringMap() const { return Mapping; }
+ iterator_range<StringMapConstIterator<uint32_t>> entries() const;
+
+private:
+ Optional<FinalizationInfo> FinalizedInfo;
+ HashTable FinalizedHashTable;
+ StringMap<uint32_t> Mapping;
+};
+
+} // end namespace pdb
+
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_PDB_NATIVE_NAMEDSTREAMMAP_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/Native/NativeBuiltinSymbol.h b/contrib/llvm/include/llvm/DebugInfo/PDB/Native/NativeBuiltinSymbol.h
new file mode 100644
index 0000000..4f532c6
--- /dev/null
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/Native/NativeBuiltinSymbol.h
@@ -0,0 +1,49 @@
+//===- NativeBuiltinSymbol.h -------------------------------------- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_PDB_NATIVE_NATIVEBUILTINSYMBOL_H
+#define LLVM_DEBUGINFO_PDB_NATIVE_NATIVEBUILTINSYMBOL_H
+
+#include "llvm/DebugInfo/PDB/Native/NativeRawSymbol.h"
+
+#include "llvm/DebugInfo/PDB/PDBTypes.h"
+
+namespace llvm {
+namespace pdb {
+
+class NativeSession;
+
+class NativeBuiltinSymbol : public NativeRawSymbol {
+public:
+ NativeBuiltinSymbol(NativeSession &PDBSession, SymIndexId Id,
+ PDB_BuiltinType T, uint64_t L);
+ ~NativeBuiltinSymbol() override;
+
+ virtual std::unique_ptr<NativeRawSymbol> clone() const override;
+
+ void dump(raw_ostream &OS, int Indent) const override;
+
+ PDB_SymType getSymTag() const override;
+
+ PDB_BuiltinType getBuiltinType() const override;
+ bool isConstType() const override;
+ uint64_t getLength() const override;
+ bool isUnalignedType() const override;
+ bool isVolatileType() const override;
+
+protected:
+ NativeSession &Session;
+ PDB_BuiltinType Type;
+ uint64_t Length;
+};
+
+} // namespace pdb
+} // namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/Native/NativeCompilandSymbol.h b/contrib/llvm/include/llvm/DebugInfo/PDB/Native/NativeCompilandSymbol.h
new file mode 100644
index 0000000..bd5c09e
--- /dev/null
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/Native/NativeCompilandSymbol.h
@@ -0,0 +1,39 @@
+//===- NativeCompilandSymbol.h - native impl for compiland syms -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_PDB_NATIVE_NATIVECOMPILANDSYMBOL_H
+#define LLVM_DEBUGINFO_PDB_NATIVE_NATIVECOMPILANDSYMBOL_H
+
+#include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h"
+#include "llvm/DebugInfo/PDB/Native/NativeRawSymbol.h"
+
+namespace llvm {
+namespace pdb {
+
+class NativeCompilandSymbol : public NativeRawSymbol {
+public:
+ NativeCompilandSymbol(NativeSession &Session, SymIndexId SymbolId,
+ DbiModuleDescriptor MI);
+
+ std::unique_ptr<NativeRawSymbol> clone() const override;
+
+ PDB_SymType getSymTag() const override;
+ bool isEditAndContinueEnabled() const override;
+ uint32_t getLexicalParentId() const override;
+ std::string getLibraryName() const override;
+ std::string getName() const override;
+
+private:
+ DbiModuleDescriptor Module;
+};
+
+} // namespace pdb
+} // namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/Native/NativeEnumModules.h b/contrib/llvm/include/llvm/DebugInfo/PDB/Native/NativeEnumModules.h
new file mode 100644
index 0000000..6aa1460
--- /dev/null
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/Native/NativeEnumModules.h
@@ -0,0 +1,41 @@
+//==- NativeEnumModules.h - Native Module Enumerator impl --------*- C++ -*-==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_PDB_NATIVE_NATIVEENUMMODULES_H
+#define LLVM_DEBUGINFO_PDB_NATIVE_NATIVEENUMMODULES_H
+
+#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
+#include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h"
+#include "llvm/DebugInfo/PDB/PDBSymbol.h"
+namespace llvm {
+namespace pdb {
+
+class DbiModuleList;
+class NativeSession;
+
+class NativeEnumModules : public IPDBEnumChildren<PDBSymbol> {
+public:
+ NativeEnumModules(NativeSession &Session, const DbiModuleList &Modules,
+ uint32_t Index = 0);
+
+ uint32_t getChildCount() const override;
+ std::unique_ptr<PDBSymbol> getChildAtIndex(uint32_t Index) const override;
+ std::unique_ptr<PDBSymbol> getNext() override;
+ void reset() override;
+ NativeEnumModules *clone() const override;
+
+private:
+ NativeSession &Session;
+ const DbiModuleList &Modules;
+ uint32_t Index;
+};
+}
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/Native/NativeExeSymbol.h b/contrib/llvm/include/llvm/DebugInfo/PDB/Native/NativeExeSymbol.h
new file mode 100644
index 0000000..587c7ff
--- /dev/null
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/Native/NativeExeSymbol.h
@@ -0,0 +1,41 @@
+//===- NativeExeSymbol.h - native impl for PDBSymbolExe ---------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_PDB_NATIVE_NATIVEEXESYMBOL_H
+#define LLVM_DEBUGINFO_PDB_NATIVE_NATIVEEXESYMBOL_H
+
+#include "llvm/DebugInfo/PDB/Native/NativeRawSymbol.h"
+#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
+
+namespace llvm {
+namespace pdb {
+
+class NativeExeSymbol : public NativeRawSymbol {
+public:
+ NativeExeSymbol(NativeSession &Session, SymIndexId SymbolId);
+
+ std::unique_ptr<NativeRawSymbol> clone() const override;
+
+ std::unique_ptr<IPDBEnumSymbols>
+ findChildren(PDB_SymType Type) const override;
+
+ uint32_t getAge() const override;
+ std::string getSymbolsFileName() const override;
+ codeview::GUID getGuid() const override;
+ bool hasCTypes() const override;
+ bool hasPrivateSymbols() const override;
+
+private:
+ PDBFile &File;
+};
+
+} // namespace pdb
+} // namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/Native/NativeRawSymbol.h b/contrib/llvm/include/llvm/DebugInfo/PDB/Native/NativeRawSymbol.h
new file mode 100644
index 0000000..2c6548d
--- /dev/null
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/Native/NativeRawSymbol.h
@@ -0,0 +1,216 @@
+//==- NativeRawSymbol.h - Native implementation of IPDBRawSymbol -*- C++ -*-==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_PDB_NATIVE_NATIVERAWSYMBOL_H
+#define LLVM_DEBUGINFO_PDB_NATIVE_NATIVERAWSYMBOL_H
+
+#include "llvm/DebugInfo/PDB/IPDBRawSymbol.h"
+#include <cstdint>
+#include <memory>
+
+namespace llvm {
+namespace pdb {
+
+class NativeSession;
+
+typedef uint32_t SymIndexId;
+
+class NativeRawSymbol : public IPDBRawSymbol {
+public:
+ NativeRawSymbol(NativeSession &PDBSession, SymIndexId SymbolId);
+
+ virtual std::unique_ptr<NativeRawSymbol> clone() const = 0;
+
+ void dump(raw_ostream &OS, int Indent) const override;
+
+ std::unique_ptr<IPDBEnumSymbols>
+ findChildren(PDB_SymType Type) const override;
+ std::unique_ptr<IPDBEnumSymbols>
+ findChildren(PDB_SymType Type, StringRef Name,
+ PDB_NameSearchFlags Flags) const override;
+ std::unique_ptr<IPDBEnumSymbols>
+ findChildrenByRVA(PDB_SymType Type, StringRef Name, PDB_NameSearchFlags Flags,
+ uint32_t RVA) const override;
+ std::unique_ptr<IPDBEnumSymbols>
+ findInlineFramesByRVA(uint32_t RVA) const override;
+
+ void getDataBytes(SmallVector<uint8_t, 32> &Bytes) const override;
+ void getFrontEndVersion(VersionInfo &Version) const override;
+ void getBackEndVersion(VersionInfo &Version) const override;
+ PDB_MemberAccess getAccess() const override;
+ uint32_t getAddressOffset() const override;
+ uint32_t getAddressSection() const override;
+ uint32_t getAge() const override;
+ uint32_t getArrayIndexTypeId() const override;
+ uint32_t getBaseDataOffset() const override;
+ uint32_t getBaseDataSlot() const override;
+ uint32_t getBaseSymbolId() const override;
+ PDB_BuiltinType getBuiltinType() const override;
+ uint32_t getBitPosition() const override;
+ PDB_CallingConv getCallingConvention() const override;
+ uint32_t getClassParentId() const override;
+ std::string getCompilerName() const override;
+ uint32_t getCount() const override;
+ uint32_t getCountLiveRanges() const override;
+ PDB_Lang getLanguage() const override;
+ uint32_t getLexicalParentId() const override;
+ std::string getLibraryName() const override;
+ uint32_t getLiveRangeStartAddressOffset() const override;
+ uint32_t getLiveRangeStartAddressSection() const override;
+ uint32_t getLiveRangeStartRelativeVirtualAddress() const override;
+ codeview::RegisterId getLocalBasePointerRegisterId() const override;
+ uint32_t getLowerBoundId() const override;
+ uint32_t getMemorySpaceKind() const override;
+ std::string getName() const override;
+ uint32_t getNumberOfAcceleratorPointerTags() const override;
+ uint32_t getNumberOfColumns() const override;
+ uint32_t getNumberOfModifiers() const override;
+ uint32_t getNumberOfRegisterIndices() const override;
+ uint32_t getNumberOfRows() const override;
+ std::string getObjectFileName() const override;
+ uint32_t getOemId() const override;
+ uint32_t getOemSymbolId() const override;
+ uint32_t getOffsetInUdt() const override;
+ PDB_Cpu getPlatform() const override;
+ uint32_t getRank() const override;
+ codeview::RegisterId getRegisterId() const override;
+ uint32_t getRegisterType() const override;
+ uint32_t getRelativeVirtualAddress() const override;
+ uint32_t getSamplerSlot() const override;
+ uint32_t getSignature() const override;
+ uint32_t getSizeInUdt() const override;
+ uint32_t getSlot() const override;
+ std::string getSourceFileName() const override;
+ uint32_t getStride() const override;
+ uint32_t getSubTypeId() const override;
+ std::string getSymbolsFileName() const override;
+ uint32_t getSymIndexId() const override;
+ uint32_t getTargetOffset() const override;
+ uint32_t getTargetRelativeVirtualAddress() const override;
+ uint64_t getTargetVirtualAddress() const override;
+ uint32_t getTargetSection() const override;
+ uint32_t getTextureSlot() const override;
+ uint32_t getTimeStamp() const override;
+ uint32_t getToken() const override;
+ uint32_t getTypeId() const override;
+ uint32_t getUavSlot() const override;
+ std::string getUndecoratedName() const override;
+ uint32_t getUnmodifiedTypeId() const override;
+ uint32_t getUpperBoundId() const override;
+ Variant getValue() const override;
+ uint32_t getVirtualBaseDispIndex() const override;
+ uint32_t getVirtualBaseOffset() const override;
+ uint32_t getVirtualTableShapeId() const override;
+ std::unique_ptr<PDBSymbolTypeBuiltin>
+ getVirtualBaseTableType() const override;
+ PDB_DataKind getDataKind() const override;
+ PDB_SymType getSymTag() const override;
+ codeview::GUID getGuid() const override;
+ int32_t getOffset() const override;
+ int32_t getThisAdjust() const override;
+ int32_t getVirtualBasePointerOffset() const override;
+ PDB_LocType getLocationType() const override;
+ PDB_Machine getMachineType() const override;
+ codeview::ThunkOrdinal getThunkOrdinal() const override;
+ uint64_t getLength() const override;
+ uint64_t getLiveRangeLength() const override;
+ uint64_t getVirtualAddress() const override;
+ PDB_UdtType getUdtKind() const override;
+ bool hasConstructor() const override;
+ bool hasCustomCallingConvention() const override;
+ bool hasFarReturn() const override;
+ bool isCode() const override;
+ bool isCompilerGenerated() const override;
+ bool isConstType() const override;
+ bool isEditAndContinueEnabled() const override;
+ bool isFunction() const override;
+ bool getAddressTaken() const override;
+ bool getNoStackOrdering() const override;
+ bool hasAlloca() const override;
+ bool hasAssignmentOperator() const override;
+ bool hasCTypes() const override;
+ bool hasCastOperator() const override;
+ bool hasDebugInfo() const override;
+ bool hasEH() const override;
+ bool hasEHa() const override;
+ bool hasInlAsm() const override;
+ bool hasInlineAttribute() const override;
+ bool hasInterruptReturn() const override;
+ bool hasFramePointer() const override;
+ bool hasLongJump() const override;
+ bool hasManagedCode() const override;
+ bool hasNestedTypes() const override;
+ bool hasNoInlineAttribute() const override;
+ bool hasNoReturnAttribute() const override;
+ bool hasOptimizedCodeDebugInfo() const override;
+ bool hasOverloadedOperator() const override;
+ bool hasSEH() const override;
+ bool hasSecurityChecks() const override;
+ bool hasSetJump() const override;
+ bool hasStrictGSCheck() const override;
+ bool isAcceleratorGroupSharedLocal() const override;
+ bool isAcceleratorPointerTagLiveRange() const override;
+ bool isAcceleratorStubFunction() const override;
+ bool isAggregated() const override;
+ bool isIntroVirtualFunction() const override;
+ bool isCVTCIL() const override;
+ bool isConstructorVirtualBase() const override;
+ bool isCxxReturnUdt() const override;
+ bool isDataAligned() const override;
+ bool isHLSLData() const override;
+ bool isHotpatchable() const override;
+ bool isIndirectVirtualBaseClass() const override;
+ bool isInterfaceUdt() const override;
+ bool isIntrinsic() const override;
+ bool isLTCG() const override;
+ bool isLocationControlFlowDependent() const override;
+ bool isMSILNetmodule() const override;
+ bool isMatrixRowMajor() const override;
+ bool isManagedCode() const override;
+ bool isMSILCode() const override;
+ bool isMultipleInheritance() const override;
+ bool isNaked() const override;
+ bool isNested() const override;
+ bool isOptimizedAway() const override;
+ bool isPacked() const override;
+ bool isPointerBasedOnSymbolValue() const override;
+ bool isPointerToDataMember() const override;
+ bool isPointerToMemberFunction() const override;
+ bool isPureVirtual() const override;
+ bool isRValueReference() const override;
+ bool isRefUdt() const override;
+ bool isReference() const override;
+ bool isRestrictedType() const override;
+ bool isReturnValue() const override;
+ bool isSafeBuffers() const override;
+ bool isScoped() const override;
+ bool isSdl() const override;
+ bool isSingleInheritance() const override;
+ bool isSplitted() const override;
+ bool isStatic() const override;
+ bool hasPrivateSymbols() const override;
+ bool isUnalignedType() const override;
+ bool isUnreached() const override;
+ bool isValueUdt() const override;
+ bool isVirtual() const override;
+ bool isVirtualBaseClass() const override;
+ bool isVirtualInheritance() const override;
+ bool isVolatileType() const override;
+ bool wasInlined() const override;
+ std::string getUnused() const override;
+
+protected:
+ NativeSession &Session;
+ SymIndexId SymbolId;
+};
+
+} // end namespace pdb
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_PDB_NATIVE_NATIVERAWSYMBOL_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/Raw/RawSession.h b/contrib/llvm/include/llvm/DebugInfo/PDB/Native/NativeSession.h
index 5a6c469..b16ce23 100644
--- a/contrib/llvm/include/llvm/DebugInfo/PDB/Raw/RawSession.h
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/Native/NativeSession.h
@@ -1,4 +1,4 @@
-//===- RawSession.h - Native implementation of IPDBSession ------*- C++ -*-===//
+//===- NativeSession.h - Native implementation of IPDBSession ---*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,11 +7,17 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_DEBUGINFO_PDB_RAW_RAWSESSION_H
-#define LLVM_DEBUGINFO_PDB_RAW_RAWSESSION_H
+#ifndef LLVM_DEBUGINFO_PDB_NATIVE_NATIVESESSION_H
+#define LLVM_DEBUGINFO_PDB_NATIVE_NATIVESESSION_H
+#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/DebugInfo/CodeView/TypeIndex.h"
+#include "llvm/DebugInfo/PDB/IPDBRawSymbol.h"
#include "llvm/DebugInfo/PDB/IPDBSession.h"
+#include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h"
+#include "llvm/DebugInfo/PDB/Native/NativeBuiltinSymbol.h"
+#include "llvm/DebugInfo/PDB/Native/NativeRawSymbol.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Error.h"
@@ -19,20 +25,25 @@ namespace llvm {
namespace pdb {
class PDBFile;
-class RawSession : public IPDBSession {
+class NativeSession : public IPDBSession {
public:
- RawSession(std::unique_ptr<PDBFile> PdbFile,
- std::unique_ptr<BumpPtrAllocator> Allocator);
- ~RawSession() override;
+ NativeSession(std::unique_ptr<PDBFile> PdbFile,
+ std::unique_ptr<BumpPtrAllocator> Allocator);
+ ~NativeSession() override;
static Error createFromPdb(StringRef Path,
std::unique_ptr<IPDBSession> &Session);
static Error createFromExe(StringRef Path,
std::unique_ptr<IPDBSession> &Session);
+ std::unique_ptr<PDBSymbolCompiland>
+ createCompilandSymbol(DbiModuleDescriptor MI);
+
+ SymIndexId findSymbolByTypeIndex(codeview::TypeIndex TI);
+
uint64_t getLoadAddress() const override;
void setLoadAddress(uint64_t Address) override;
- std::unique_ptr<PDBSymbolExe> getGlobalScope() const override;
+ std::unique_ptr<PDBSymbolExe> getGlobalScope() override;
std::unique_ptr<PDBSymbol> getSymbolById(uint32_t SymbolId) const override;
std::unique_ptr<PDBSymbol>
@@ -71,6 +82,8 @@ public:
private:
std::unique_ptr<PDBFile> Pdb;
std::unique_ptr<BumpPtrAllocator> Allocator;
+ std::vector<std::unique_ptr<NativeRawSymbol>> SymbolCache;
+ DenseMap<codeview::TypeIndex, SymIndexId> TypeIndexToSymbolId;
};
}
}
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/Raw/PDBFile.h b/contrib/llvm/include/llvm/DebugInfo/PDB/Native/PDBFile.h
index 29f5b21..4f6ad11 100644
--- a/contrib/llvm/include/llvm/DebugInfo/PDB/Raw/PDBFile.h
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/Native/PDBFile.h
@@ -13,9 +13,9 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/DebugInfo/MSF/IMSFFile.h"
#include "llvm/DebugInfo/MSF/MSFCommon.h"
-#include "llvm/DebugInfo/MSF/StreamArray.h"
-#include "llvm/DebugInfo/MSF/StreamInterface.h"
+#include "llvm/DebugInfo/MSF/MSFStreamLayout.h"
#include "llvm/Support/Allocator.h"
+#include "llvm/Support/BinaryStreamRef.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/MathExtras.h"
@@ -24,6 +24,8 @@
namespace llvm {
+class BinaryStream;
+
namespace msf {
class MappedBlockStream;
}
@@ -32,7 +34,7 @@ namespace pdb {
class DbiStream;
class GlobalsStream;
class InfoStream;
-class NameHashTable;
+class PDBStringTable;
class PDBFileBuilder;
class PublicsStream;
class SymbolStream;
@@ -42,10 +44,13 @@ class PDBFile : public msf::IMSFFile {
friend PDBFileBuilder;
public:
- PDBFile(std::unique_ptr<msf::ReadableStream> PdbFileBuffer,
+ PDBFile(StringRef Path, std::unique_ptr<BinaryStream> PdbFileBuffer,
BumpPtrAllocator &Allocator);
~PDBFile() override;
+ StringRef getFileDirectory() const;
+ StringRef getFilePath() const;
+
uint32_t getFreeBlockMapBlock() const;
uint32_t getUnknown1() const;
@@ -77,10 +82,12 @@ public:
}
const msf::MSFLayout &getMsfLayout() const { return ContainerLayout; }
- const msf::ReadableStream &getMsfBuffer() const { return *Buffer; }
+ BinaryStreamRef getMsfBuffer() const { return *Buffer; }
ArrayRef<support::ulittle32_t> getDirectoryBlockArray() const;
+ msf::MSFStreamLayout getStreamLayout(uint32_t StreamIdx) const;
+
Error parseFileHeaders();
Error parseStreamData();
@@ -91,7 +98,7 @@ public:
Expected<TpiStream &> getPDBIpiStream();
Expected<PublicsStream &> getPDBPublicsStream();
Expected<SymbolStream &> getPDBSymbolStream();
- Expected<NameHashTable &> getStringTable();
+ Expected<PDBStringTable &> getStringTable();
BumpPtrAllocator &getAllocator() { return Allocator; }
@@ -102,16 +109,20 @@ public:
bool hasPDBPublicsStream();
bool hasPDBSymbolStream();
bool hasPDBTpiStream() const;
- bool hasStringTable();
+ bool hasPDBStringTable();
+
+ uint32_t getPointerSize();
- private:
- Expected<std::unique_ptr<msf::MappedBlockStream>> safelyCreateIndexedStream(
- const msf::MSFLayout &Layout, const msf::ReadableStream &MsfData,
- uint32_t StreamIndex) const;
+private:
+ Expected<std::unique_ptr<msf::MappedBlockStream>>
+ safelyCreateIndexedStream(const msf::MSFLayout &Layout,
+ BinaryStreamRef MsfData,
+ uint32_t StreamIndex) const;
+ std::string FilePath;
BumpPtrAllocator &Allocator;
- std::unique_ptr<msf::ReadableStream> Buffer;
+ std::unique_ptr<BinaryStream> Buffer;
std::vector<uint32_t> FpmPages;
msf::MSFLayout ContainerLayout;
@@ -125,7 +136,7 @@ public:
std::unique_ptr<SymbolStream> Symbols;
std::unique_ptr<msf::MappedBlockStream> DirectoryStream;
std::unique_ptr<msf::MappedBlockStream> StringTableStream;
- std::unique_ptr<NameHashTable> StringTable;
+ std::unique_ptr<PDBStringTable> Strings;
};
}
}
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/Raw/PDBFileBuilder.h b/contrib/llvm/include/llvm/DebugInfo/PDB/Native/PDBFileBuilder.h
index 27fc4b5..2dc23f8 100644
--- a/contrib/llvm/include/llvm/DebugInfo/PDB/Raw/PDBFileBuilder.h
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/Native/PDBFileBuilder.h
@@ -13,8 +13,10 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/Optional.h"
-#include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
-#include "llvm/DebugInfo/PDB/Raw/RawConstants.h"
+#include "llvm/DebugInfo/PDB/Native/NamedStreamMap.h"
+#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
+#include "llvm/DebugInfo/PDB/Native/PDBStringTableBuilder.h"
+#include "llvm/DebugInfo/PDB/Native/RawConstants.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/Error.h"
@@ -29,11 +31,13 @@ class MSFBuilder;
namespace pdb {
class DbiStreamBuilder;
class InfoStreamBuilder;
+class PublicsStreamBuilder;
class TpiStreamBuilder;
class PDBFileBuilder {
public:
explicit PDBFileBuilder(BumpPtrAllocator &Allocator);
+ ~PDBFileBuilder();
PDBFileBuilder(const PDBFileBuilder &) = delete;
PDBFileBuilder &operator=(const PDBFileBuilder &) = delete;
@@ -44,19 +48,28 @@ public:
DbiStreamBuilder &getDbiBuilder();
TpiStreamBuilder &getTpiBuilder();
TpiStreamBuilder &getIpiBuilder();
+ PDBStringTableBuilder &getStringTableBuilder();
+ PublicsStreamBuilder &getPublicsBuilder();
Error commit(StringRef Filename);
+ Expected<uint32_t> getNamedStreamIndex(StringRef Name) const;
+ Error addNamedStream(StringRef Name, uint32_t Size);
+
private:
- Expected<msf::MSFLayout> finalizeMsfLayout() const;
+ Expected<msf::MSFLayout> finalizeMsfLayout();
BumpPtrAllocator &Allocator;
std::unique_ptr<msf::MSFBuilder> Msf;
std::unique_ptr<InfoStreamBuilder> Info;
std::unique_ptr<DbiStreamBuilder> Dbi;
+ std::unique_ptr<PublicsStreamBuilder> Publics;
std::unique_ptr<TpiStreamBuilder> Tpi;
std::unique_ptr<TpiStreamBuilder> Ipi;
+
+ PDBStringTableBuilder Strings;
+ NamedStreamMap NamedStreams;
};
}
}
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/Native/PDBStringTable.h b/contrib/llvm/include/llvm/DebugInfo/PDB/Native/PDBStringTable.h
new file mode 100644
index 0000000..29167c9
--- /dev/null
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/Native/PDBStringTable.h
@@ -0,0 +1,65 @@
+//===- PDBStringTable.h - PDB String Table -----------------------*- C++-*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_PDB_RAW_PDBSTRINGTABLE_H
+#define LLVM_DEBUGINFO_PDB_RAW_PDBSTRINGTABLE_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h"
+#include "llvm/Support/BinaryStreamArray.h"
+#include "llvm/Support/BinaryStreamRef.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
+#include <cstdint>
+#include <vector>
+
+namespace llvm {
+class BinaryStreamReader;
+
+namespace msf {
+class MappedBlockStream;
+}
+
+namespace pdb {
+
+struct PDBStringTableHeader;
+
+class PDBStringTable {
+public:
+ Error reload(BinaryStreamReader &Reader);
+
+ uint32_t getByteSize() const;
+ uint32_t getNameCount() const;
+ uint32_t getHashVersion() const;
+ uint32_t getSignature() const;
+
+ Expected<StringRef> getStringForID(uint32_t ID) const;
+ Expected<uint32_t> getIDForString(StringRef Str) const;
+
+ FixedStreamArray<support::ulittle32_t> name_ids() const;
+
+ const codeview::DebugStringTableSubsectionRef &getStringTable() const;
+
+private:
+ Error readHeader(BinaryStreamReader &Reader);
+ Error readStrings(BinaryStreamReader &Reader);
+ Error readHashTable(BinaryStreamReader &Reader);
+ Error readEpilogue(BinaryStreamReader &Reader);
+
+ const PDBStringTableHeader *Header = nullptr;
+ codeview::DebugStringTableSubsectionRef Strings;
+ FixedStreamArray<support::ulittle32_t> IDs;
+ uint32_t NameCount = 0;
+};
+
+} // end namespace pdb
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_PDB_RAW_STRINGTABLE_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/Native/PDBStringTableBuilder.h b/contrib/llvm/include/llvm/DebugInfo/PDB/Native/PDBStringTableBuilder.h
new file mode 100644
index 0000000..b57707e
--- /dev/null
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/Native/PDBStringTableBuilder.h
@@ -0,0 +1,59 @@
+//===- PDBStringTableBuilder.h - PDB String Table Builder -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file creates the "/names" stream.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_PDB_RAW_PDBSTRINGTABLEBUILDER_H
+#define LLVM_DEBUGINFO_PDB_RAW_PDBSTRINGTABLEBUILDER_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h"
+#include "llvm/Support/Error.h"
+#include <vector>
+
+namespace llvm {
+class BinaryStreamWriter;
+class WritableBinaryStreamRef;
+
+namespace msf {
+struct MSFLayout;
+}
+
+namespace pdb {
+
+class PDBFileBuilder;
+
+class PDBStringTableBuilder {
+public:
+ // If string S does not exist in the string table, insert it.
+ // Returns the ID for S.
+ uint32_t insert(StringRef S);
+
+ uint32_t calculateSerializedSize() const;
+ Error commit(BinaryStreamWriter &Writer) const;
+
+ void setStrings(const codeview::DebugStringTableSubsection &Strings);
+
+private:
+ uint32_t calculateHashTableSize() const;
+ Error writeHeader(BinaryStreamWriter &Writer) const;
+ Error writeStrings(BinaryStreamWriter &Writer) const;
+ Error writeHashTable(BinaryStreamWriter &Writer) const;
+ Error writeEpilogue(BinaryStreamWriter &Writer) const;
+
+ codeview::DebugStringTableSubsection Strings;
+};
+
+} // end namespace pdb
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_PDB_RAW_PDBSTRINGTABLEBUILDER_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/Raw/PublicsStream.h b/contrib/llvm/include/llvm/DebugInfo/PDB/Native/PublicsStream.h
index 577f298..9ace826 100644
--- a/contrib/llvm/include/llvm/DebugInfo/PDB/Raw/PublicsStream.h
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/Native/PublicsStream.h
@@ -12,11 +12,10 @@
#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
-#include "llvm/DebugInfo/MSF/StreamArray.h"
+#include "llvm/DebugInfo/PDB/Native/RawConstants.h"
+#include "llvm/DebugInfo/PDB/Native/RawTypes.h"
#include "llvm/DebugInfo/PDB/PDBTypes.h"
-#include "llvm/DebugInfo/PDB/Raw/RawConstants.h"
-#include "llvm/DebugInfo/PDB/Raw/RawTypes.h"
-
+#include "llvm/Support/BinaryStreamArray.h"
#include "llvm/Support/Error.h"
namespace llvm {
@@ -26,8 +25,6 @@ struct GSIHashHeader;
class PDBFile;
class PublicsStream {
- struct HeaderInfo;
-
public:
PublicsStream(PDBFile &File, std::unique_ptr<msf::MappedBlockStream> Stream);
~PublicsStream();
@@ -36,18 +33,19 @@ public:
uint32_t getSymHash() const;
uint32_t getAddrMap() const;
uint32_t getNumBuckets() const { return NumBuckets; }
+ Expected<const codeview::CVSymbolArray &> getSymbolArray() const;
iterator_range<codeview::CVSymbolArray::Iterator>
getSymbols(bool *HadError) const;
- msf::FixedStreamArray<support::ulittle32_t> getHashBuckets() const {
+ FixedStreamArray<support::ulittle32_t> getHashBuckets() const {
return HashBuckets;
}
- msf::FixedStreamArray<support::ulittle32_t> getAddressMap() const {
+ FixedStreamArray<support::ulittle32_t> getAddressMap() const {
return AddressMap;
}
- msf::FixedStreamArray<support::ulittle32_t> getThunkMap() const {
+ FixedStreamArray<support::ulittle32_t> getThunkMap() const {
return ThunkMap;
}
- msf::FixedStreamArray<SectionOffset> getSectionOffsets() const {
+ FixedStreamArray<SectionOffset> getSectionOffsets() const {
return SectionOffsets;
}
@@ -59,13 +57,13 @@ private:
std::unique_ptr<msf::MappedBlockStream> Stream;
uint32_t NumBuckets = 0;
ArrayRef<uint8_t> Bitmap;
- msf::FixedStreamArray<PSHashRecord> HashRecords;
- msf::FixedStreamArray<support::ulittle32_t> HashBuckets;
- msf::FixedStreamArray<support::ulittle32_t> AddressMap;
- msf::FixedStreamArray<support::ulittle32_t> ThunkMap;
- msf::FixedStreamArray<SectionOffset> SectionOffsets;
+ FixedStreamArray<PSHashRecord> HashRecords;
+ FixedStreamArray<support::ulittle32_t> HashBuckets;
+ FixedStreamArray<support::ulittle32_t> AddressMap;
+ FixedStreamArray<support::ulittle32_t> ThunkMap;
+ FixedStreamArray<SectionOffset> SectionOffsets;
- const HeaderInfo *Header;
+ const PublicsStreamHeader *Header;
const GSIHashHeader *HashHdr;
};
}
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/Native/PublicsStreamBuilder.h b/contrib/llvm/include/llvm/DebugInfo/PDB/Native/PublicsStreamBuilder.h
new file mode 100644
index 0000000..5ab57eb
--- /dev/null
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/Native/PublicsStreamBuilder.h
@@ -0,0 +1,54 @@
+//===- PublicsStreamBuilder.h - PDB Publics Stream Creation -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_PDB_RAW_PDBPUBLICSTREAMBUILDER_H
+#define LLVM_DEBUGINFO_PDB_RAW_PDBPUBLICSTREAMBUILDER_H
+
+#include "llvm/DebugInfo/PDB/Native/RawConstants.h"
+#include "llvm/DebugInfo/PDB/Native/RawTypes.h"
+#include "llvm/Support/BinaryByteStream.h"
+#include "llvm/Support/BinaryStreamRef.h"
+#include "llvm/Support/BinaryStreamWriter.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
+
+namespace llvm {
+namespace msf {
+class MSFBuilder;
+}
+namespace pdb {
+class PublicsStream;
+struct PublicsStreamHeader;
+
+class PublicsStreamBuilder {
+public:
+ explicit PublicsStreamBuilder(msf::MSFBuilder &Msf);
+ ~PublicsStreamBuilder();
+
+ PublicsStreamBuilder(const PublicsStreamBuilder &) = delete;
+ PublicsStreamBuilder &operator=(const PublicsStreamBuilder &) = delete;
+
+ Error finalizeMsfLayout();
+ uint32_t calculateSerializedLength() const;
+
+ Error commit(BinaryStreamWriter &PublicsWriter);
+
+ uint32_t getStreamIndex() const { return StreamIdx; }
+ uint32_t getRecordStreamIdx() const { return RecordStreamIdx; }
+
+private:
+ uint32_t StreamIdx = kInvalidStreamIndex;
+ uint32_t RecordStreamIdx = kInvalidStreamIndex;
+ std::vector<PSHashRecord> HashRecords;
+ msf::MSFBuilder &Msf;
+};
+} // namespace pdb
+} // namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/Raw/RawConstants.h b/contrib/llvm/include/llvm/DebugInfo/PDB/Native/RawConstants.h
index af114ff..bb1d097 100644
--- a/contrib/llvm/include/llvm/DebugInfo/PDB/Raw/RawConstants.h
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/Native/RawConstants.h
@@ -10,8 +10,8 @@
#ifndef LLVM_DEBUGINFO_PDB_RAW_PDBRAWCONSTANTS_H
#define LLVM_DEBUGINFO_PDB_RAW_PDBRAWCONSTANTS_H
+#include "llvm/ADT/BitmaskEnum.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
-
#include <cstdint>
namespace llvm {
@@ -32,6 +32,21 @@ enum PdbRaw_ImplVer : uint32_t {
PdbImplVC140 = 20140508,
};
+enum class PdbRaw_FeatureSig : uint32_t {
+ VC110 = PdbImplVC110,
+ VC140 = PdbImplVC140,
+ NoTypeMerge = 0x4D544F4E,
+ MinimalDebugInfo = 0x494E494D,
+};
+
+enum PdbRaw_Features : uint32_t {
+ PdbFeatureNone = 0x0,
+ PdbFeatureContainsIdStream = 0x1,
+ PdbFeatureMinimalDebugInfo = 0x2,
+ PdbFeatureNoTypeMerging = 0x4,
+ LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ PdbFeatureNoTypeMerging)
+};
+
enum PdbRaw_DbiVer : uint32_t {
PdbDbiVC41 = 930803,
PdbDbiV50 = 19960307,
@@ -83,15 +98,19 @@ enum class DbgHeaderType : uint16_t {
};
enum class OMFSegDescFlags : uint16_t {
+ None = 0,
Read = 1 << 0, // Segment is readable.
Write = 1 << 1, // Segment is writable.
Execute = 1 << 2, // Segment is executable.
AddressIs32Bit = 1 << 3, // Descriptor describes a 32-bit linear address.
IsSelector = 1 << 8, // Frame represents a selector.
IsAbsoluteAddress = 1 << 9, // Frame represents an absolute address.
- IsGroup = 1 << 10 // If set, descriptor represents a group.
+ IsGroup = 1 << 10, // If set, descriptor represents a group.
+ LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ IsGroup)
};
+LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
+
} // end namespace pdb
} // end namespace llvm
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/Raw/RawError.h b/contrib/llvm/include/llvm/DebugInfo/PDB/Native/RawError.h
index f96b806..3624a76 100644
--- a/contrib/llvm/include/llvm/DebugInfo/PDB/Raw/RawError.h
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/Native/RawError.h
@@ -28,6 +28,7 @@ enum class raw_error_code {
duplicate_entry,
no_entry,
not_writable,
+ stream_too_long,
invalid_tpi_hash,
};
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/Raw/RawTypes.h b/contrib/llvm/include/llvm/DebugInfo/PDB/Native/RawTypes.h
index d404b39..b6321cb 100644
--- a/contrib/llvm/include/llvm/DebugInfo/PDB/Raw/RawTypes.h
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/Native/RawTypes.h
@@ -10,6 +10,7 @@
#ifndef LLVM_DEBUGINFO_PDB_RAW_RAWTYPES_H
#define LLVM_DEBUGINFO_PDB_RAW_RAWTYPES_H
+#include "llvm/DebugInfo/CodeView/GUID.h"
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
#include "llvm/Support/Endian.h"
@@ -73,13 +74,6 @@ struct SecMapEntry {
support::ulittle32_t SecByteLength; // Byte count of the segment or group.
};
-// Used for serialized hash table in TPI stream.
-// In the reference, it is an array of TI and cbOff pair.
-struct TypeIndexOffset {
- codeview::TypeIndex Type;
- support::ulittle32_t Offset;
-};
-
/// Some of the values are stored in bitfields. Since this needs to be portable
/// across compilers and architectures (big / little endian in particular) we
/// can't use the actual structures below, but must instead do the shifting
@@ -200,7 +194,7 @@ struct FileInfoSubstreamHeader {
};
struct ModInfoFlags {
- /// uint16_t fWritten : 1; // True if ModInfo is dirty
+ /// uint16_t fWritten : 1; // True if DbiModuleDescriptor is dirty
/// uint16_t fECEnabled : 1; // Is EC symbolic info present? (What is EC?)
/// uint16_t unused : 6; // Reserved
/// uint16_t iTSM : 8; // Type Server Index for this module
@@ -211,7 +205,7 @@ struct ModInfoFlags {
};
/// The header preceeding each entry in the Module Info substream of the DBI
-/// stream.
+/// stream. Corresponds to the type MODI in the reference implementation.
struct ModuleInfoHeader {
/// Currently opened module. This field is a pointer in the reference
/// implementation, but that won't work on 64-bit systems, and anyway it
@@ -231,8 +225,8 @@ struct ModuleInfoHeader {
/// Size of local symbol debug info in above stream
support::ulittle32_t SymBytes;
- /// Size of line number debug info in above stream
- support::ulittle32_t LineBytes;
+ /// Size of C11 line number info in above stream
+ support::ulittle32_t C11Bytes;
/// Size of C13 line number info in above stream
support::ulittle32_t C13Bytes;
@@ -243,9 +237,12 @@ struct ModuleInfoHeader {
/// Padding so the next field is 4-byte aligned.
char Padding1[2];
- /// Array of [0..NumFiles) DBI name buffer offsets. This field is a pointer
- /// in the reference implementation, but as with `Mod`, we ignore it for now
- /// since it is unused.
+ /// Array of [0..NumFiles) DBI name buffer offsets. In the reference
+ /// implementation this field is a pointer. But since you can't portably
+ /// serialize a pointer, on 64-bit platforms they copy all the values except
+ /// this one into the 32-bit version of the struct and use that for
+ /// serialization. Regardless, this field is unused, it is only there to
+ /// store a pointer that can be accessed at runtime.
support::ulittle32_t FileNameOffs;
/// Name Index for src file name
@@ -259,11 +256,17 @@ struct ModuleInfoHeader {
/// char ObjFileName[];
};
-/// Defines a 128-bit unique identifier. This maps to a GUID on Windows, but
-/// is abstracted here for the purposes of non-Windows platforms that don't have
-/// the GUID structure defined.
-struct PDB_UniqueId {
- uint8_t Guid[16];
+// This is PSGSIHDR struct defined in
+// https://github.com/Microsoft/microsoft-pdb/blob/master/PDB/dbi/gsi.h
+struct PublicsStreamHeader {
+ support::ulittle32_t SymHash;
+ support::ulittle32_t AddrMap;
+ support::ulittle32_t NumThunks;
+ support::ulittle32_t SizeOfThunk;
+ support::ulittle16_t ISectThunkTable;
+ char Padding[2];
+ support::ulittle32_t OffThunkTable;
+ support::ulittle32_t NumSections;
};
// The header preceeding the global TPI stream.
@@ -299,9 +302,18 @@ struct InfoStreamHeader {
support::ulittle32_t Version;
support::ulittle32_t Signature;
support::ulittle32_t Age;
- PDB_UniqueId Guid;
+ codeview::GUID Guid;
};
+/// The header preceeding the /names stream.
+struct PDBStringTableHeader {
+ support::ulittle32_t Signature; // PDBStringTableSignature
+ support::ulittle32_t HashVersion; // 1 or 2
+ support::ulittle32_t ByteSize; // Number of bytes of names buffer.
+};
+
+const uint32_t PDBStringTableSignature = 0xEFFEEFFE;
+
} // namespace pdb
} // namespace llvm
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/Raw/SymbolStream.h b/contrib/llvm/include/llvm/DebugInfo/PDB/Native/SymbolStream.h
index 41d5e6a..17695f5 100644
--- a/contrib/llvm/include/llvm/DebugInfo/PDB/Raw/SymbolStream.h
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/Native/SymbolStream.h
@@ -27,6 +27,10 @@ public:
~SymbolStream();
Error reload();
+ const codeview::CVSymbolArray &getSymbolArray() const {
+ return SymbolRecords;
+ }
+
iterator_range<codeview::CVSymbolArray::Iterator>
getSymbols(bool *HadError) const;
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/Native/TpiHashing.h b/contrib/llvm/include/llvm/DebugInfo/PDB/Native/TpiHashing.h
new file mode 100644
index 0000000..c1edec7
--- /dev/null
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/Native/TpiHashing.h
@@ -0,0 +1,24 @@
+//===- TpiHashing.h ---------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_PDB_TPIHASHING_H
+#define LLVM_DEBUGINFO_PDB_TPIHASHING_H
+
+#include "llvm/DebugInfo/CodeView/TypeRecord.h"
+#include "llvm/Support/Error.h"
+
+namespace llvm {
+namespace pdb {
+
+Expected<uint32_t> hashTypeRecord(const llvm::codeview::CVType &Type);
+
+} // end namespace pdb
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_PDB_TPIHASHING_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/Raw/TpiStream.h b/contrib/llvm/include/llvm/DebugInfo/PDB/Native/TpiStream.h
index de21abe..d347520 100644
--- a/contrib/llvm/include/llvm/DebugInfo/PDB/Raw/TpiStream.h
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/Native/TpiStream.h
@@ -11,15 +11,20 @@
#define LLVM_DEBUGINFO_PDB_RAW_PDBTPISTREAM_H
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
-#include "llvm/DebugInfo/MSF/StreamArray.h"
+#include "llvm/DebugInfo/PDB/Native/HashTable.h"
+#include "llvm/DebugInfo/PDB/Native/RawConstants.h"
+#include "llvm/DebugInfo/PDB/Native/RawTypes.h"
#include "llvm/DebugInfo/PDB/PDBTypes.h"
-#include "llvm/DebugInfo/PDB/Raw/RawConstants.h"
-#include "llvm/DebugInfo/PDB/Raw/RawTypes.h"
+#include "llvm/Support/BinaryStreamArray.h"
+#include "llvm/Support/BinaryStreamRef.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/Error.h"
namespace llvm {
+namespace codeview {
+class LazyRandomTypeCollection;
+}
namespace msf {
class MappedBlockStream;
}
@@ -30,8 +35,7 @@ class TpiStream {
friend class TpiStreamBuilder;
public:
- TpiStream(const PDBFile &File,
- std::unique_ptr<msf::MappedBlockStream> Stream);
+ TpiStream(PDBFile &File, std::unique_ptr<msf::MappedBlockStream> Stream);
~TpiStream();
Error reload();
@@ -39,32 +43,39 @@ public:
uint32_t TypeIndexBegin() const;
uint32_t TypeIndexEnd() const;
- uint32_t NumTypeRecords() const;
+ uint32_t getNumTypeRecords() const;
uint16_t getTypeHashStreamIndex() const;
uint16_t getTypeHashStreamAuxIndex() const;
uint32_t getHashKeySize() const;
- uint32_t NumHashBuckets() const;
- msf::FixedStreamArray<support::ulittle32_t> getHashValues() const;
- msf::FixedStreamArray<TypeIndexOffset> getTypeIndexOffsets() const;
- msf::FixedStreamArray<TypeIndexOffset> getHashAdjustments() const;
+ uint32_t getNumHashBuckets() const;
+ FixedStreamArray<support::ulittle32_t> getHashValues() const;
+ FixedStreamArray<codeview::TypeIndexOffset> getTypeIndexOffsets() const;
+ HashTable &getHashAdjusters();
+
+ codeview::CVTypeRange types(bool *HadError) const;
+ const codeview::CVTypeArray &typeArray() const { return TypeRecords; }
+
+ codeview::LazyRandomTypeCollection &typeCollection() { return *Types; }
- iterator_range<codeview::CVTypeArray::Iterator> types(bool *HadError) const;
+ BinarySubstreamRef getTypeRecordsSubstream() const;
Error commit();
private:
- Error verifyHashValues();
-
- const PDBFile &Pdb;
+ PDBFile &Pdb;
std::unique_ptr<msf::MappedBlockStream> Stream;
+ std::unique_ptr<codeview::LazyRandomTypeCollection> Types;
+
+ BinarySubstreamRef TypeRecordsSubstream;
+
codeview::CVTypeArray TypeRecords;
- std::unique_ptr<msf::ReadableStream> HashStream;
- msf::FixedStreamArray<support::ulittle32_t> HashValues;
- msf::FixedStreamArray<TypeIndexOffset> TypeIndexOffsets;
- msf::FixedStreamArray<TypeIndexOffset> HashAdjustments;
+ std::unique_ptr<BinaryStream> HashStream;
+ FixedStreamArray<support::ulittle32_t> HashValues;
+ FixedStreamArray<codeview::TypeIndexOffset> TypeIndexOffsets;
+ HashTable HashAdjusters;
const TpiStreamHeader *Header;
};
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/Raw/TpiStreamBuilder.h b/contrib/llvm/include/llvm/DebugInfo/PDB/Native/TpiStreamBuilder.h
index f9a6421..411720d 100644
--- a/contrib/llvm/include/llvm/DebugInfo/PDB/Raw/TpiStreamBuilder.h
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/Native/TpiStreamBuilder.h
@@ -12,31 +12,33 @@
#include "llvm/ADT/Optional.h"
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
-#include "llvm/DebugInfo/MSF/ByteStream.h"
-#include "llvm/DebugInfo/MSF/SequencedItemStream.h"
-#include "llvm/DebugInfo/PDB/Raw/RawConstants.h"
+#include "llvm/DebugInfo/PDB/Native/RawConstants.h"
+#include "llvm/DebugInfo/PDB/Native/RawTypes.h"
#include "llvm/Support/Allocator.h"
+#include "llvm/Support/BinaryByteStream.h"
+#include "llvm/Support/BinaryItemStream.h"
+#include "llvm/Support/BinaryStreamRef.h"
#include "llvm/Support/Error.h"
#include <vector>
namespace llvm {
-namespace codeview {
-class TypeRecord;
-}
-namespace msf {
-class ByteStream;
-class MSFBuilder;
-struct MSFLayout;
-class ReadableStreamRef;
-class WritableStream;
+class BinaryByteStream;
+class WritableBinaryStreamRef;
-template <> struct SequencedItemTraits<llvm::codeview::CVType> {
+template <> struct BinaryItemTraits<llvm::codeview::CVType> {
static size_t length(const codeview::CVType &Item) { return Item.length(); }
static ArrayRef<uint8_t> bytes(const codeview::CVType &Item) {
return Item.data();
}
};
+
+namespace codeview {
+class TypeRecord;
+}
+namespace msf {
+class MSFBuilder;
+struct MSFLayout;
}
namespace pdb {
class PDBFile;
@@ -52,26 +54,32 @@ public:
TpiStreamBuilder &operator=(const TpiStreamBuilder &) = delete;
void setVersionHeader(PdbRaw_TpiVer Version);
- void addTypeRecord(const codeview::CVType &Record);
+ void addTypeRecord(ArrayRef<uint8_t> Type, Optional<uint32_t> Hash);
Error finalizeMsfLayout();
- Error commit(const msf::MSFLayout &Layout, const msf::WritableStream &Buffer);
+ uint32_t getRecordCount() const { return TypeRecords.size(); }
+
+ Error commit(const msf::MSFLayout &Layout, WritableBinaryStreamRef Buffer);
- uint32_t calculateSerializedLength() const;
+ uint32_t calculateSerializedLength();
private:
uint32_t calculateHashBufferSize() const;
+ uint32_t calculateIndexOffsetSize() const;
Error finalize();
msf::MSFBuilder &Msf;
BumpPtrAllocator &Allocator;
- Optional<PdbRaw_TpiVer> VerHeader;
- std::vector<codeview::CVType> TypeRecords;
- msf::SequencedItemStream<codeview::CVType> TypeRecordStream;
+ size_t TypeRecordBytes = 0;
+
+ PdbRaw_TpiVer VerHeader = PdbRaw_TpiVer::PdbTpiV80;
+ std::vector<ArrayRef<uint8_t>> TypeRecords;
+ std::vector<uint32_t> TypeHashes;
+ std::vector<codeview::TypeIndexOffset> TypeIndexOffsets;
uint32_t HashStreamIndex = kInvalidStreamIndex;
- std::unique_ptr<msf::ByteStream> HashValueStream;
+ std::unique_ptr<BinaryByteStream> HashValueStream;
const TpiStreamHeader *Header;
uint32_t Idx;
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/PDB.h b/contrib/llvm/include/llvm/DebugInfo/PDB/PDB.h
index 1f5a066..9f9da39 100644
--- a/contrib/llvm/include/llvm/DebugInfo/PDB/PDB.h
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/PDB.h
@@ -10,21 +10,23 @@
#ifndef LLVM_DEBUGINFO_PDB_PDB_H
#define LLVM_DEBUGINFO_PDB_PDB_H
-#include "PDBTypes.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/DebugInfo/PDB/PDBTypes.h"
#include "llvm/Support/Error.h"
#include <memory>
-#include <system_error>
namespace llvm {
-class StringRef;
-
namespace pdb {
+class IPDBSession;
+
Error loadDataForPDB(PDB_ReaderType Type, StringRef Path,
std::unique_ptr<IPDBSession> &Session);
Error loadDataForEXE(PDB_ReaderType Type, StringRef Path,
std::unique_ptr<IPDBSession> &Session);
-}
-}
-#endif
+
+} // end namespace pdb
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_PDB_PDB_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/PDBContext.h b/contrib/llvm/include/llvm/DebugInfo/PDB/PDBContext.h
index 84ab8ed..0ce49f5 100644
--- a/contrib/llvm/include/llvm/DebugInfo/PDB/PDBContext.h
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/PDBContext.h
@@ -41,8 +41,7 @@ namespace pdb {
return DICtx->getKind() == CK_PDB;
}
- void dump(raw_ostream &OS, DIDumpType DumpType = DIDT_All,
- bool DumpEH = false, bool SummarizeTypes = false) override;
+ void dump(raw_ostream &OS, DIDumpOptions DIDumpOpts) override;
DILineInfo getLineInfoForAddress(
uint64_t Address,
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/PDBExtras.h b/contrib/llvm/include/llvm/DebugInfo/PDB/PDBExtras.h
index 5a7422d..778121c 100644
--- a/contrib/llvm/include/llvm/DebugInfo/PDB/PDBExtras.h
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/PDBExtras.h
@@ -1,4 +1,4 @@
-//===- PDBExtras.h - helper functions and classes for PDBs -------*- C++-*-===//
+//===- PDBExtras.h - helper functions and classes for PDBs ------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -10,15 +10,17 @@
#ifndef LLVM_DEBUGINFO_PDB_PDBEXTRAS_H
#define LLVM_DEBUGINFO_PDB_PDBEXTRAS_H
-#include "PDBTypes.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
-#include "llvm/Support/raw_ostream.h"
+#include "llvm/DebugInfo/PDB/PDBTypes.h"
#include <unordered_map>
namespace llvm {
+class raw_ostream;
+
namespace pdb {
-typedef std::unordered_map<PDB_SymType, int> TagStats;
+
+using TagStats = std::unordered_map<PDB_SymType, int>;
raw_ostream &operator<<(raw_ostream &OS, const PDB_VariantType &Value);
raw_ostream &operator<<(raw_ostream &OS, const PDB_CallingConv &Conv);
@@ -31,13 +33,14 @@ raw_ostream &operator<<(raw_ostream &OS, const PDB_Lang &Lang);
raw_ostream &operator<<(raw_ostream &OS, const PDB_SymType &Tag);
raw_ostream &operator<<(raw_ostream &OS, const PDB_MemberAccess &Access);
raw_ostream &operator<<(raw_ostream &OS, const PDB_UdtType &Type);
-raw_ostream &operator<<(raw_ostream &OS, const PDB_UniqueId &Id);
raw_ostream &operator<<(raw_ostream &OS, const PDB_Machine &Machine);
raw_ostream &operator<<(raw_ostream &OS, const Variant &Value);
raw_ostream &operator<<(raw_ostream &OS, const VersionInfo &Version);
raw_ostream &operator<<(raw_ostream &OS, const TagStats &Stats);
-}
-}
-#endif
+} // end namespace pdb
+
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_PDB_PDBEXTRAS_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymDumper.h b/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymDumper.h
index 095c33c..c976935 100644
--- a/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymDumper.h
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymDumper.h
@@ -54,6 +54,22 @@ public:
virtual void dump(const PDBSymbolUnknown &Symbol);
virtual void dump(const PDBSymbolUsingNamespace &Symbol);
+ virtual void dumpRight(const PDBSymbolTypeArray &Symbol) {}
+ virtual void dumpRight(const PDBSymbolTypeBaseClass &Symbol) {}
+ virtual void dumpRight(const PDBSymbolTypeBuiltin &Symbol) {}
+ virtual void dumpRight(const PDBSymbolTypeCustom &Symbol) {}
+ virtual void dumpRight(const PDBSymbolTypeDimension &Symbol) {}
+ virtual void dumpRight(const PDBSymbolTypeEnum &Symbol) {}
+ virtual void dumpRight(const PDBSymbolTypeFriend &Symbol) {}
+ virtual void dumpRight(const PDBSymbolTypeFunctionArg &Symbol) {}
+ virtual void dumpRight(const PDBSymbolTypeFunctionSig &Symbol) {}
+ virtual void dumpRight(const PDBSymbolTypeManaged &Symbol) {}
+ virtual void dumpRight(const PDBSymbolTypePointer &Symbol) {}
+ virtual void dumpRight(const PDBSymbolTypeTypedef &Symbol) {}
+ virtual void dumpRight(const PDBSymbolTypeUDT &Symbol) {}
+ virtual void dumpRight(const PDBSymbolTypeVTable &Symbol) {}
+ virtual void dumpRight(const PDBSymbolTypeVTableShape &Symbol) {}
+
private:
bool RequireImpl;
};
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbol.h b/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbol.h
index bf51188..9e883d2 100644
--- a/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbol.h
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbol.h
@@ -22,6 +22,23 @@
return RawSymbol->MethodName(); \
}
+#define FORWARD_CONCRETE_SYMBOL_ID_METHOD_WITH_NAME(ConcreteType, PrivateName, \
+ PublicName) \
+ auto PublicName##Id() const->decltype(RawSymbol->PrivateName##Id()) { \
+ return RawSymbol->PrivateName##Id(); \
+ } \
+ std::unique_ptr<ConcreteType> PublicName() const { \
+ uint32_t Id = PublicName##Id(); \
+ return getConcreteSymbolByIdHelper<ConcreteType>(Id); \
+ }
+
+#define FORWARD_SYMBOL_ID_METHOD_WITH_NAME(PrivateName, PublicName) \
+ FORWARD_CONCRETE_SYMBOL_ID_METHOD_WITH_NAME(PDBSymbol, PrivateName, \
+ PublicName)
+
+#define FORWARD_SYMBOL_ID_METHOD(MethodName) \
+ FORWARD_SYMBOL_ID_METHOD_WITH_NAME(MethodName, MethodName)
+
namespace llvm {
class StringRef;
@@ -29,6 +46,7 @@ class raw_ostream;
namespace pdb {
class IPDBRawSymbol;
+class IPDBSession;
#define DECLARE_PDB_SYMBOL_CONCRETE_TYPE(TagValue) \
static const PDB_SymType Tag = TagValue; \
@@ -44,6 +62,7 @@ class PDBSymbol {
protected:
PDBSymbol(const IPDBSession &PDBSession,
std::unique_ptr<IPDBRawSymbol> Symbol);
+ PDBSymbol(PDBSymbol &Symbol);
public:
static std::unique_ptr<PDBSymbol>
@@ -56,19 +75,32 @@ public:
/// unknown properties, but individual implementations of PDBSymbol may
/// override the behavior to only dump known fields.
virtual void dump(PDBSymDumper &Dumper) const = 0;
+
+ /// For certain PDBSymbolTypes, dumps additional information for the type that
+ /// normally goes on the right side of the symbol.
+ virtual void dumpRight(PDBSymDumper &Dumper) const {}
+
void defaultDump(raw_ostream &OS, int Indent) const;
+ void dumpProperties() const;
+ void dumpChildStats() const;
PDB_SymType getSymTag() const;
uint32_t getSymIndexId() const;
template <typename T> std::unique_ptr<T> findOneChild() const {
auto Enumerator(findAllChildren<T>());
+ if (!Enumerator)
+ return nullptr;
return Enumerator->getNext();
}
+ std::unique_ptr<PDBSymbol> clone() const;
+
template <typename T>
std::unique_ptr<ConcreteSymbolEnumerator<T>> findAllChildren() const {
auto BaseIter = RawSymbol->findChildren(T::Tag);
+ if (!BaseIter)
+ return nullptr;
return llvm::make_unique<ConcreteSymbolEnumerator<T>>(std::move(BaseIter));
}
std::unique_ptr<IPDBEnumSymbols> findAllChildren(PDB_SymType Type) const;
@@ -91,8 +123,15 @@ public:
std::unique_ptr<IPDBEnumSymbols> getChildStats(TagStats &Stats) const;
protected:
+ std::unique_ptr<PDBSymbol> getSymbolByIdHelper(uint32_t Id) const;
+
+ template <typename ConcreteType>
+ std::unique_ptr<ConcreteType> getConcreteSymbolByIdHelper(uint32_t Id) const {
+ return unique_dyn_cast_or_null<ConcreteType>(getSymbolByIdHelper(Id));
+ }
+
const IPDBSession &Session;
- const std::unique_ptr<IPDBRawSymbol> RawSymbol;
+ std::unique_ptr<IPDBRawSymbol> RawSymbol;
};
} // namespace llvm
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolBlock.h b/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolBlock.h
index d0ff62c..d81da1e 100644
--- a/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolBlock.h
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolBlock.h
@@ -30,7 +30,7 @@ public:
FORWARD_SYMBOL_METHOD(getAddressOffset)
FORWARD_SYMBOL_METHOD(getAddressSection)
FORWARD_SYMBOL_METHOD(getLength)
- FORWARD_SYMBOL_METHOD(getLexicalParentId)
+ FORWARD_SYMBOL_ID_METHOD(getLexicalParent)
FORWARD_SYMBOL_METHOD(getLocationType)
FORWARD_SYMBOL_METHOD(getName)
FORWARD_SYMBOL_METHOD(getRelativeVirtualAddress)
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolCompiland.h b/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolCompiland.h
index f1983b3..2678801 100644
--- a/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolCompiland.h
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolCompiland.h
@@ -29,7 +29,7 @@ public:
void dump(PDBSymDumper &Dumper) const override;
FORWARD_SYMBOL_METHOD(isEditAndContinueEnabled)
- FORWARD_SYMBOL_METHOD(getLexicalParentId)
+ FORWARD_SYMBOL_ID_METHOD(getLexicalParent)
FORWARD_SYMBOL_METHOD(getLibraryName)
FORWARD_SYMBOL_METHOD(getName)
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolCompilandDetails.h b/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolCompilandDetails.h
index bb4a78f..dba50c4 100644
--- a/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolCompilandDetails.h
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolCompilandDetails.h
@@ -46,7 +46,7 @@ public:
FORWARD_SYMBOL_METHOD(isLTCG)
FORWARD_SYMBOL_METHOD(isMSILNetmodule)
FORWARD_SYMBOL_METHOD(getLanguage)
- FORWARD_SYMBOL_METHOD(getLexicalParentId)
+ FORWARD_SYMBOL_ID_METHOD(getLexicalParent)
FORWARD_SYMBOL_METHOD(getPlatform)
FORWARD_SYMBOL_METHOD(getSourceFileName)
};
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolCompilandEnv.h b/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolCompilandEnv.h
index a71a0ba..7868f045 100644
--- a/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolCompilandEnv.h
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolCompilandEnv.h
@@ -26,7 +26,7 @@ public:
void dump(PDBSymDumper &Dumper) const override;
- FORWARD_SYMBOL_METHOD(getLexicalParentId)
+ FORWARD_SYMBOL_ID_METHOD(getLexicalParent)
FORWARD_SYMBOL_METHOD(getName)
std::string getValue() const;
};
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolData.h b/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolData.h
index 36f32ab..ad4285d 100644
--- a/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolData.h
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolData.h
@@ -26,8 +26,6 @@ public:
DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::Data)
- std::unique_ptr<PDBSymbol> getType() const;
-
void dump(PDBSymDumper &Dumper) const override;
FORWARD_SYMBOL_METHOD(getAccess)
@@ -35,14 +33,14 @@ public:
FORWARD_SYMBOL_METHOD(getAddressSection)
FORWARD_SYMBOL_METHOD(getAddressTaken)
FORWARD_SYMBOL_METHOD(getBitPosition)
- FORWARD_SYMBOL_METHOD(getClassParentId)
+ FORWARD_SYMBOL_ID_METHOD(getClassParent)
FORWARD_SYMBOL_METHOD(isCompilerGenerated)
FORWARD_SYMBOL_METHOD(isConstType)
FORWARD_SYMBOL_METHOD(getDataKind)
FORWARD_SYMBOL_METHOD(isAggregated)
FORWARD_SYMBOL_METHOD(isSplitted)
FORWARD_SYMBOL_METHOD(getLength)
- FORWARD_SYMBOL_METHOD(getLexicalParentId)
+ FORWARD_SYMBOL_ID_METHOD(getLexicalParent)
FORWARD_SYMBOL_METHOD(getLocationType)
FORWARD_SYMBOL_METHOD(getName)
FORWARD_SYMBOL_METHOD(getOffset)
@@ -50,7 +48,7 @@ public:
FORWARD_SYMBOL_METHOD(getRelativeVirtualAddress)
FORWARD_SYMBOL_METHOD(getSlot)
FORWARD_SYMBOL_METHOD(getToken)
- FORWARD_SYMBOL_METHOD(getTypeId)
+ FORWARD_SYMBOL_ID_METHOD(getType)
FORWARD_SYMBOL_METHOD(isUnalignedType)
FORWARD_SYMBOL_METHOD(getValue)
FORWARD_SYMBOL_METHOD(getVirtualAddress)
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolExe.h b/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolExe.h
index 5b3f50d..2c2d746 100644
--- a/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolExe.h
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolExe.h
@@ -37,6 +37,8 @@ public:
FORWARD_SYMBOL_METHOD(getSignature)
FORWARD_SYMBOL_METHOD(getSymbolsFileName)
+ uint32_t getPointerByteSize() const;
+
private:
void dumpChildren(raw_ostream &OS, StringRef Label, PDB_SymType ChildType,
int Indent) const;
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolFunc.h b/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolFunc.h
index 7170bcb..c2f02ea 100644
--- a/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolFunc.h
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolFunc.h
@@ -11,6 +11,7 @@
#define LLVM_DEBUGINFO_PDB_PDBSYMBOLFUNC_H
#include "PDBSymbol.h"
+#include "PDBSymbolTypeFunctionSig.h"
#include "PDBTypes.h"
namespace llvm {
@@ -26,8 +27,8 @@ public:
void dump(PDBSymDumper &Dumper) const override;
- std::unique_ptr<PDBSymbolTypeFunctionSig> getSignature() const;
- std::unique_ptr<PDBSymbolTypeUDT> getClassParent() const;
+ bool isDestructor() const;
+
std::unique_ptr<IPDBEnumChildren<PDBSymbolData>> getArguments() const;
DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::Function)
@@ -35,7 +36,7 @@ public:
FORWARD_SYMBOL_METHOD(getAccess)
FORWARD_SYMBOL_METHOD(getAddressOffset)
FORWARD_SYMBOL_METHOD(getAddressSection)
- FORWARD_SYMBOL_METHOD(getClassParentId)
+ FORWARD_SYMBOL_ID_METHOD(getClassParent)
FORWARD_SYMBOL_METHOD(isCompilerGenerated)
FORWARD_SYMBOL_METHOD(isConstType)
FORWARD_SYMBOL_METHOD(hasCustomCallingConvention)
@@ -54,7 +55,7 @@ public:
FORWARD_SYMBOL_METHOD(isNaked)
FORWARD_SYMBOL_METHOD(isStatic)
FORWARD_SYMBOL_METHOD(getLength)
- FORWARD_SYMBOL_METHOD(getLexicalParentId)
+ FORWARD_SYMBOL_ID_METHOD(getLexicalParent)
FORWARD_SYMBOL_METHOD(getLocalBasePointerRegisterId)
FORWARD_SYMBOL_METHOD(getLocationType)
FORWARD_SYMBOL_METHOD(getName)
@@ -67,7 +68,8 @@ public:
FORWARD_SYMBOL_METHOD(isPureVirtual)
FORWARD_SYMBOL_METHOD(getRelativeVirtualAddress)
FORWARD_SYMBOL_METHOD(getToken)
- FORWARD_SYMBOL_METHOD(getTypeId)
+ FORWARD_CONCRETE_SYMBOL_ID_METHOD_WITH_NAME(PDBSymbolTypeFunctionSig, getType,
+ getSignature)
FORWARD_SYMBOL_METHOD(isUnalignedType)
FORWARD_SYMBOL_METHOD(getUndecoratedName)
FORWARD_SYMBOL_METHOD(isVirtual)
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolFuncDebugEnd.h b/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolFuncDebugEnd.h
index 4643895..3341bd9 100644
--- a/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolFuncDebugEnd.h
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolFuncDebugEnd.h
@@ -34,7 +34,7 @@ public:
FORWARD_SYMBOL_METHOD(hasFarReturn)
FORWARD_SYMBOL_METHOD(hasInterruptReturn)
FORWARD_SYMBOL_METHOD(isStatic)
- FORWARD_SYMBOL_METHOD(getLexicalParentId)
+ FORWARD_SYMBOL_ID_METHOD(getLexicalParent)
FORWARD_SYMBOL_METHOD(getLocationType)
FORWARD_SYMBOL_METHOD(hasNoInlineAttribute)
FORWARD_SYMBOL_METHOD(hasNoReturnAttribute)
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolFuncDebugStart.h b/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolFuncDebugStart.h
index c2e3dd3..6729838 100644
--- a/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolFuncDebugStart.h
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolFuncDebugStart.h
@@ -33,7 +33,7 @@ public:
FORWARD_SYMBOL_METHOD(hasFarReturn)
FORWARD_SYMBOL_METHOD(hasInterruptReturn)
FORWARD_SYMBOL_METHOD(isStatic)
- FORWARD_SYMBOL_METHOD(getLexicalParentId)
+ FORWARD_SYMBOL_ID_METHOD(getLexicalParent)
FORWARD_SYMBOL_METHOD(getLocationType)
FORWARD_SYMBOL_METHOD(hasNoInlineAttribute)
FORWARD_SYMBOL_METHOD(hasNoReturnAttribute)
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolLabel.h b/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolLabel.h
index 3aeae10..c2b1c28 100644
--- a/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolLabel.h
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolLabel.h
@@ -32,7 +32,7 @@ public:
FORWARD_SYMBOL_METHOD(hasCustomCallingConvention)
FORWARD_SYMBOL_METHOD(hasFarReturn)
FORWARD_SYMBOL_METHOD(hasInterruptReturn)
- FORWARD_SYMBOL_METHOD(getLexicalParentId)
+ FORWARD_SYMBOL_ID_METHOD(getLexicalParent)
FORWARD_SYMBOL_METHOD(getLocationType)
FORWARD_SYMBOL_METHOD(getName)
FORWARD_SYMBOL_METHOD(hasNoInlineAttribute)
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolPublicSymbol.h b/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolPublicSymbol.h
index be07344..c9e6ee6 100644
--- a/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolPublicSymbol.h
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolPublicSymbol.h
@@ -32,7 +32,7 @@ public:
FORWARD_SYMBOL_METHOD(isCode)
FORWARD_SYMBOL_METHOD(isFunction)
FORWARD_SYMBOL_METHOD(getLength)
- FORWARD_SYMBOL_METHOD(getLexicalParentId)
+ FORWARD_SYMBOL_ID_METHOD(getLexicalParent)
FORWARD_SYMBOL_METHOD(getLocationType)
FORWARD_SYMBOL_METHOD(isManagedCode)
FORWARD_SYMBOL_METHOD(isMSILCode)
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolThunk.h b/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolThunk.h
index 63f7a09..614fad8 100644
--- a/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolThunk.h
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolThunk.h
@@ -30,12 +30,12 @@ public:
FORWARD_SYMBOL_METHOD(getAccess)
FORWARD_SYMBOL_METHOD(getAddressOffset)
FORWARD_SYMBOL_METHOD(getAddressSection)
- FORWARD_SYMBOL_METHOD(getClassParentId)
+ FORWARD_SYMBOL_ID_METHOD(getClassParent)
FORWARD_SYMBOL_METHOD(isConstType)
FORWARD_SYMBOL_METHOD(isIntroVirtualFunction)
FORWARD_SYMBOL_METHOD(isStatic)
FORWARD_SYMBOL_METHOD(getLength)
- FORWARD_SYMBOL_METHOD(getLexicalParentId)
+ FORWARD_SYMBOL_ID_METHOD(getLexicalParent)
FORWARD_SYMBOL_METHOD(getName)
FORWARD_SYMBOL_METHOD(isPureVirtual)
FORWARD_SYMBOL_METHOD(getRelativeVirtualAddress)
@@ -44,7 +44,7 @@ public:
FORWARD_SYMBOL_METHOD(getTargetVirtualAddress)
FORWARD_SYMBOL_METHOD(getTargetSection)
FORWARD_SYMBOL_METHOD(getThunkOrdinal)
- FORWARD_SYMBOL_METHOD(getTypeId)
+ FORWARD_SYMBOL_ID_METHOD(getType)
FORWARD_SYMBOL_METHOD(isUnalignedType)
FORWARD_SYMBOL_METHOD(isVirtual)
FORWARD_SYMBOL_METHOD(getVirtualAddress)
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolTypeArray.h b/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolTypeArray.h
index 57db036..39b7d3b 100644
--- a/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolTypeArray.h
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolTypeArray.h
@@ -25,17 +25,16 @@ public:
DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::ArrayType)
- std::unique_ptr<PDBSymbol> getElementType() const;
-
void dump(PDBSymDumper &Dumper) const override;
+ void dumpRight(PDBSymDumper &Dumper) const override;
- FORWARD_SYMBOL_METHOD(getArrayIndexTypeId)
+ FORWARD_SYMBOL_ID_METHOD(getArrayIndexType)
FORWARD_SYMBOL_METHOD(isConstType)
FORWARD_SYMBOL_METHOD(getCount)
FORWARD_SYMBOL_METHOD(getLength)
- FORWARD_SYMBOL_METHOD(getLexicalParentId)
+ FORWARD_SYMBOL_ID_METHOD(getLexicalParent)
FORWARD_SYMBOL_METHOD(getRank)
- FORWARD_SYMBOL_METHOD(getTypeId)
+ FORWARD_SYMBOL_ID_METHOD_WITH_NAME(getType, getElementType)
FORWARD_SYMBOL_METHOD(isUnalignedType)
FORWARD_SYMBOL_METHOD(isVolatileType)
};
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h b/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h
index aaa3ab7..d607a3d 100644
--- a/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h
@@ -13,6 +13,9 @@
#include "PDBSymbol.h"
#include "PDBTypes.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeVTable.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeVTableShape.h"
+
namespace llvm {
class raw_ostream;
@@ -28,7 +31,7 @@ public:
void dump(PDBSymDumper &Dumper) const override;
FORWARD_SYMBOL_METHOD(getAccess)
- FORWARD_SYMBOL_METHOD(getClassParentId)
+ FORWARD_SYMBOL_ID_METHOD(getClassParent)
FORWARD_SYMBOL_METHOD(hasConstructor)
FORWARD_SYMBOL_METHOD(isConstType)
FORWARD_SYMBOL_METHOD(hasAssignmentOperator)
@@ -36,14 +39,14 @@ public:
FORWARD_SYMBOL_METHOD(hasNestedTypes)
FORWARD_SYMBOL_METHOD(isIndirectVirtualBaseClass)
FORWARD_SYMBOL_METHOD(getLength)
- FORWARD_SYMBOL_METHOD(getLexicalParentId)
+ FORWARD_SYMBOL_ID_METHOD(getLexicalParent)
FORWARD_SYMBOL_METHOD(getName)
FORWARD_SYMBOL_METHOD(isNested)
FORWARD_SYMBOL_METHOD(getOffset)
FORWARD_SYMBOL_METHOD(hasOverloadedOperator)
FORWARD_SYMBOL_METHOD(isPacked)
FORWARD_SYMBOL_METHOD(isScoped)
- FORWARD_SYMBOL_METHOD(getTypeId)
+ FORWARD_SYMBOL_ID_METHOD(getType)
FORWARD_SYMBOL_METHOD(getUdtKind)
FORWARD_SYMBOL_METHOD(isUnalignedType)
@@ -51,7 +54,7 @@ public:
FORWARD_SYMBOL_METHOD(getVirtualBaseDispIndex)
FORWARD_SYMBOL_METHOD(getVirtualBasePointerOffset)
// FORWARD_SYMBOL_METHOD(getVirtualBaseTableType)
- FORWARD_SYMBOL_METHOD(getVirtualTableShapeId)
+ FORWARD_SYMBOL_ID_METHOD(getVirtualTableShape)
FORWARD_SYMBOL_METHOD(isVolatileType)
};
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h b/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h
index c8f59f1..5b1863c 100644
--- a/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h
@@ -30,7 +30,7 @@ public:
FORWARD_SYMBOL_METHOD(getBuiltinType)
FORWARD_SYMBOL_METHOD(isConstType)
FORWARD_SYMBOL_METHOD(getLength)
- FORWARD_SYMBOL_METHOD(getLexicalParentId)
+ FORWARD_SYMBOL_ID_METHOD(getLexicalParent)
FORWARD_SYMBOL_METHOD(isUnalignedType)
FORWARD_SYMBOL_METHOD(isVolatileType)
};
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h b/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h
index ade2887..c5ae3c5 100644
--- a/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h
@@ -11,6 +11,7 @@
#define LLVM_DEBUGINFO_PDB_PDBSYMBOLTYPEENUM_H
#include "PDBSymbol.h"
+#include "PDBSymbolTypeBuiltin.h"
#include "PDBTypes.h"
namespace llvm {
@@ -27,25 +28,22 @@ public:
void dump(PDBSymDumper &Dumper) const override;
- std::unique_ptr<PDBSymbolTypeUDT> getClassParent() const;
- std::unique_ptr<PDBSymbolTypeBuiltin> getUnderlyingType() const;
-
FORWARD_SYMBOL_METHOD(getBuiltinType)
- FORWARD_SYMBOL_METHOD(getClassParentId)
- FORWARD_SYMBOL_METHOD(getUnmodifiedTypeId)
+ FORWARD_SYMBOL_ID_METHOD(getClassParent)
FORWARD_SYMBOL_METHOD(hasConstructor)
FORWARD_SYMBOL_METHOD(isConstType)
FORWARD_SYMBOL_METHOD(hasAssignmentOperator)
FORWARD_SYMBOL_METHOD(hasCastOperator)
FORWARD_SYMBOL_METHOD(hasNestedTypes)
FORWARD_SYMBOL_METHOD(getLength)
- FORWARD_SYMBOL_METHOD(getLexicalParentId)
+ FORWARD_SYMBOL_ID_METHOD(getLexicalParent)
FORWARD_SYMBOL_METHOD(getName)
FORWARD_SYMBOL_METHOD(isNested)
FORWARD_SYMBOL_METHOD(hasOverloadedOperator)
FORWARD_SYMBOL_METHOD(isPacked)
FORWARD_SYMBOL_METHOD(isScoped)
- FORWARD_SYMBOL_METHOD(getTypeId)
+ FORWARD_CONCRETE_SYMBOL_ID_METHOD_WITH_NAME(PDBSymbolTypeBuiltin, getType,
+ getUnderlyingType)
FORWARD_SYMBOL_METHOD(isUnalignedType)
FORWARD_SYMBOL_METHOD(isVolatileType)
};
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolTypeFriend.h b/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolTypeFriend.h
index 196d149..24c1312 100644
--- a/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolTypeFriend.h
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolTypeFriend.h
@@ -27,9 +27,9 @@ public:
void dump(PDBSymDumper &Dumper) const override;
- FORWARD_SYMBOL_METHOD(getClassParentId)
+ FORWARD_SYMBOL_ID_METHOD(getClassParent)
FORWARD_SYMBOL_METHOD(getName)
- FORWARD_SYMBOL_METHOD(getTypeId)
+ FORWARD_SYMBOL_ID_METHOD(getType)
};
} // namespace llvm
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolTypeFunctionArg.h b/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolTypeFunctionArg.h
index 5561341..3855999 100644
--- a/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolTypeFunctionArg.h
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolTypeFunctionArg.h
@@ -27,9 +27,9 @@ public:
void dump(PDBSymDumper &Dumper) const override;
- FORWARD_SYMBOL_METHOD(getClassParentId)
- FORWARD_SYMBOL_METHOD(getLexicalParentId)
- FORWARD_SYMBOL_METHOD(getTypeId)
+ FORWARD_SYMBOL_ID_METHOD(getClassParent)
+ FORWARD_SYMBOL_ID_METHOD(getLexicalParent)
+ FORWARD_SYMBOL_ID_METHOD(getType)
};
} // namespace llvm
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h b/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h
index 516011f..8de54e7 100644
--- a/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h
@@ -25,22 +25,21 @@ public:
DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::FunctionSig)
- std::unique_ptr<PDBSymbol> getReturnType() const;
std::unique_ptr<IPDBEnumSymbols> getArguments() const;
- std::unique_ptr<PDBSymbol> getClassParent() const;
void dump(PDBSymDumper &Dumper) const override;
+ void dumpRight(PDBSymDumper &Dumper) const override;
void dumpArgList(raw_ostream &OS) const;
FORWARD_SYMBOL_METHOD(getCallingConvention)
- FORWARD_SYMBOL_METHOD(getClassParentId)
- FORWARD_SYMBOL_METHOD(getUnmodifiedTypeId)
+ FORWARD_SYMBOL_ID_METHOD(getClassParent)
+ FORWARD_SYMBOL_ID_METHOD(getUnmodifiedType)
FORWARD_SYMBOL_METHOD(isConstType)
FORWARD_SYMBOL_METHOD(getCount)
- FORWARD_SYMBOL_METHOD(getLexicalParentId)
+ FORWARD_SYMBOL_ID_METHOD(getLexicalParent)
// FORWARD_SYMBOL_METHOD(getObjectPointerType)
FORWARD_SYMBOL_METHOD(getThisAdjust)
- FORWARD_SYMBOL_METHOD(getTypeId)
+ FORWARD_SYMBOL_ID_METHOD_WITH_NAME(getType, getReturnType)
FORWARD_SYMBOL_METHOD(isUnalignedType)
FORWARD_SYMBOL_METHOD(isVolatileType)
};
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolTypePointer.h b/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolTypePointer.h
index 7a57272..c502d4e 100644
--- a/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolTypePointer.h
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolTypePointer.h
@@ -25,15 +25,14 @@ public:
DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::PointerType)
- std::unique_ptr<PDBSymbol> getPointeeType() const;
-
void dump(PDBSymDumper &Dumper) const override;
+ void dumpRight(PDBSymDumper &Dumper) const override;
FORWARD_SYMBOL_METHOD(isConstType)
FORWARD_SYMBOL_METHOD(getLength)
- FORWARD_SYMBOL_METHOD(getLexicalParentId)
+ FORWARD_SYMBOL_ID_METHOD(getLexicalParent)
FORWARD_SYMBOL_METHOD(isReference)
- FORWARD_SYMBOL_METHOD(getTypeId)
+ FORWARD_SYMBOL_ID_METHOD_WITH_NAME(getType, getPointeeType)
FORWARD_SYMBOL_METHOD(isUnalignedType)
FORWARD_SYMBOL_METHOD(isVolatileType)
};
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h b/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h
index 5ed4f8d..16c1d1b 100644
--- a/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h
@@ -28,24 +28,24 @@ public:
void dump(PDBSymDumper &Dumper) const override;
FORWARD_SYMBOL_METHOD(getBuiltinType)
- FORWARD_SYMBOL_METHOD(getClassParentId)
+ FORWARD_SYMBOL_ID_METHOD(getClassParent)
FORWARD_SYMBOL_METHOD(hasConstructor)
FORWARD_SYMBOL_METHOD(isConstType)
FORWARD_SYMBOL_METHOD(hasAssignmentOperator)
FORWARD_SYMBOL_METHOD(hasCastOperator)
FORWARD_SYMBOL_METHOD(hasNestedTypes)
FORWARD_SYMBOL_METHOD(getLength)
- FORWARD_SYMBOL_METHOD(getLexicalParentId)
+ FORWARD_SYMBOL_ID_METHOD(getLexicalParent)
FORWARD_SYMBOL_METHOD(getName)
FORWARD_SYMBOL_METHOD(isNested)
FORWARD_SYMBOL_METHOD(hasOverloadedOperator)
FORWARD_SYMBOL_METHOD(isPacked)
FORWARD_SYMBOL_METHOD(isReference)
FORWARD_SYMBOL_METHOD(isScoped)
- FORWARD_SYMBOL_METHOD(getTypeId)
+ FORWARD_SYMBOL_ID_METHOD(getType)
FORWARD_SYMBOL_METHOD(getUdtKind)
FORWARD_SYMBOL_METHOD(isUnalignedType)
- FORWARD_SYMBOL_METHOD(getVirtualTableShapeId)
+ FORWARD_SYMBOL_ID_METHOD(getVirtualTableShape)
FORWARD_SYMBOL_METHOD(isVolatileType)
};
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h b/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h
index 1874dfe..e9e7fe8 100644
--- a/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h
@@ -10,7 +10,9 @@
#ifndef LLVM_DEBUGINFO_PDB_PDBSYMBOLTYPEUDT_H
#define LLVM_DEBUGINFO_PDB_PDBSYMBOLTYPEUDT_H
+#include "IPDBSession.h"
#include "PDBSymbol.h"
+#include "PDBSymbolTypeBaseClass.h"
#include "PDBTypes.h"
namespace llvm {
@@ -18,24 +20,30 @@ namespace llvm {
class raw_ostream;
namespace pdb {
+
class PDBSymbolTypeUDT : public PDBSymbol {
public:
PDBSymbolTypeUDT(const IPDBSession &PDBSession,
std::unique_ptr<IPDBRawSymbol> UDTSymbol);
+ std::unique_ptr<PDBSymbolTypeUDT> clone() const {
+ return getSession().getConcreteSymbolById<PDBSymbolTypeUDT>(
+ getSymIndexId());
+ }
+
DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::UDT)
void dump(PDBSymDumper &Dumper) const override;
- FORWARD_SYMBOL_METHOD(getClassParentId)
- FORWARD_SYMBOL_METHOD(getUnmodifiedTypeId)
+ FORWARD_SYMBOL_ID_METHOD(getClassParent)
+ FORWARD_SYMBOL_ID_METHOD(getUnmodifiedType)
FORWARD_SYMBOL_METHOD(hasConstructor)
FORWARD_SYMBOL_METHOD(isConstType)
FORWARD_SYMBOL_METHOD(hasAssignmentOperator)
FORWARD_SYMBOL_METHOD(hasCastOperator)
FORWARD_SYMBOL_METHOD(hasNestedTypes)
FORWARD_SYMBOL_METHOD(getLength)
- FORWARD_SYMBOL_METHOD(getLexicalParentId)
+ FORWARD_SYMBOL_ID_METHOD(getLexicalParent)
FORWARD_SYMBOL_METHOD(getName)
FORWARD_SYMBOL_METHOD(isNested)
FORWARD_SYMBOL_METHOD(hasOverloadedOperator)
@@ -43,7 +51,7 @@ public:
FORWARD_SYMBOL_METHOD(isScoped)
FORWARD_SYMBOL_METHOD(getUdtKind)
FORWARD_SYMBOL_METHOD(isUnalignedType)
- FORWARD_SYMBOL_METHOD(getVirtualTableShapeId)
+ FORWARD_SYMBOL_ID_METHOD(getVirtualTableShape)
FORWARD_SYMBOL_METHOD(isVolatileType)
};
}
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolTypeVTable.h b/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolTypeVTable.h
index baf7ab7..e270c2b 100644
--- a/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolTypeVTable.h
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolTypeVTable.h
@@ -27,10 +27,11 @@ public:
void dump(PDBSymDumper &Dumper) const override;
- FORWARD_SYMBOL_METHOD(getClassParentId)
+ FORWARD_SYMBOL_ID_METHOD(getClassParent)
+ FORWARD_SYMBOL_METHOD(getOffset)
FORWARD_SYMBOL_METHOD(isConstType)
- FORWARD_SYMBOL_METHOD(getLexicalParentId)
- FORWARD_SYMBOL_METHOD(getTypeId)
+ FORWARD_SYMBOL_ID_METHOD(getLexicalParent)
+ FORWARD_SYMBOL_ID_METHOD(getType)
FORWARD_SYMBOL_METHOD(isUnalignedType)
FORWARD_SYMBOL_METHOD(isVolatileType)
};
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolTypeVTableShape.h b/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolTypeVTableShape.h
index 431fc1a..8acaabe 100644
--- a/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolTypeVTableShape.h
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolTypeVTableShape.h
@@ -29,7 +29,7 @@ public:
FORWARD_SYMBOL_METHOD(isConstType)
FORWARD_SYMBOL_METHOD(getCount)
- FORWARD_SYMBOL_METHOD(getLexicalParentId)
+ FORWARD_SYMBOL_ID_METHOD(getLexicalParent)
FORWARD_SYMBOL_METHOD(isUnalignedType)
FORWARD_SYMBOL_METHOD(isVolatileType)
};
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolUsingNamespace.h b/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolUsingNamespace.h
index a273fe1..70fbd5b 100644
--- a/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolUsingNamespace.h
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/PDBSymbolUsingNamespace.h
@@ -27,7 +27,7 @@ public:
void dump(PDBSymDumper &Dumper) const override;
- FORWARD_SYMBOL_METHOD(getLexicalParentId)
+ FORWARD_SYMBOL_ID_METHOD(getLexicalParent)
FORWARD_SYMBOL_METHOD(getName)
};
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/PDBTypes.h b/contrib/llvm/include/llvm/DebugInfo/PDB/PDBTypes.h
index 0d232f1..79ec7ce 100644
--- a/contrib/llvm/include/llvm/DebugInfo/PDB/PDBTypes.h
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/PDBTypes.h
@@ -1,4 +1,4 @@
-//===- PDBTypes.h - Defines enums for various fields contained in PDB ---*-===//
+//===- PDBTypes.h - Defines enums for various fields contained in PDB ----====//
//
// The LLVM Compiler Infrastructure
//
@@ -10,9 +10,10 @@
#ifndef LLVM_DEBUGINFO_PDB_PDBTYPES_H
#define LLVM_DEBUGINFO_PDB_PDBTYPES_H
-#include "llvm/Config/llvm-config.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
-#include "llvm/DebugInfo/PDB/Raw/RawTypes.h"
+#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
+#include "llvm/DebugInfo/PDB/Native/RawTypes.h"
+#include <cstddef>
#include <cstdint>
#include <cstring>
#include <functional>
@@ -20,21 +21,11 @@
namespace llvm {
namespace pdb {
-class PDBSymDumper;
-class PDBSymbol;
-
class IPDBDataStream;
-template <class T> class IPDBEnumChildren;
class IPDBLineNumber;
-class IPDBRawSymbol;
-class IPDBSession;
class IPDBSourceFile;
-
-typedef IPDBEnumChildren<PDBSymbol> IPDBEnumSymbols;
-typedef IPDBEnumChildren<IPDBSourceFile> IPDBEnumSourceFiles;
-typedef IPDBEnumChildren<IPDBDataStream> IPDBEnumDataStreams;
-typedef IPDBEnumChildren<IPDBLineNumber> IPDBEnumLineNumbers;
-
+class PDBSymDumper;
+class PDBSymbol;
class PDBSymbolExe;
class PDBSymbolCompiland;
class PDBSymbolCompilandDetails;
@@ -67,11 +58,16 @@ class PDBSymbolTypeManaged;
class PDBSymbolTypeDimension;
class PDBSymbolUnknown;
+using IPDBEnumSymbols = IPDBEnumChildren<PDBSymbol>;
+using IPDBEnumSourceFiles = IPDBEnumChildren<IPDBSourceFile>;
+using IPDBEnumDataStreams = IPDBEnumChildren<IPDBDataStream>;
+using IPDBEnumLineNumbers = IPDBEnumChildren<IPDBLineNumber>;
+
/// Specifies which PDB reader implementation is to be used. Only a value
-/// of PDB_ReaderType::DIA is supported.
+/// of PDB_ReaderType::DIA is currently supported, but Native is in the works.
enum class PDB_ReaderType {
DIA = 0,
- Raw = 1,
+ Native = 1,
};
/// An enumeration indicating the type of data contained in this table.
@@ -104,7 +100,7 @@ enum class PDB_Checksum { None = 0, MD5 = 1, SHA1 = 2 };
/// These values correspond to the CV_CPU_TYPE_e enumeration, and are documented
/// here: https://msdn.microsoft.com/en-us/library/b2fc64ek.aspx
-typedef codeview::CPUType PDB_Cpu;
+using PDB_Cpu = codeview::CPUType;
enum class PDB_Machine {
Invalid = 0xffff,
@@ -135,12 +131,11 @@ enum class PDB_Machine {
/// at the following locations:
/// https://msdn.microsoft.com/en-us/library/b2fc64ek.aspx
/// https://msdn.microsoft.com/en-us/library/windows/desktop/ms680207(v=vs.85).aspx
-///
-typedef codeview::CallingConvention PDB_CallingConv;
+using PDB_CallingConv = codeview::CallingConvention;
/// These values correspond to the CV_CFL_LANG enumeration, and are documented
/// here: https://msdn.microsoft.com/en-us/library/bw3aekw6.aspx
-typedef codeview::SourceLanguage PDB_Lang;
+using PDB_Lang = codeview::SourceLanguage;
/// These values correspond to the DataKind enumeration, and are documented
/// here: https://msdn.microsoft.com/en-us/library/b2x2t313.aspx
@@ -273,9 +268,9 @@ enum PDB_VariantType {
};
struct Variant {
- Variant() : Type(PDB_VariantType::Empty) {}
+ Variant() = default;
- Variant(const Variant &Other) : Type(PDB_VariantType::Empty) {
+ Variant(const Variant &Other) {
*this = Other;
}
@@ -284,7 +279,7 @@ struct Variant {
delete[] Value.String;
}
- PDB_VariantType Type;
+ PDB_VariantType Type = PDB_VariantType::Empty;
union {
bool Bool;
int8_t Int8;
@@ -344,18 +339,20 @@ struct Variant {
}
};
+} // end namespace pdb
} // end namespace llvm
-}
namespace std {
+
template <> struct hash<llvm::pdb::PDB_SymType> {
- typedef llvm::pdb::PDB_SymType argument_type;
- typedef std::size_t result_type;
+ using argument_type = llvm::pdb::PDB_SymType;
+ using result_type = std::size_t;
result_type operator()(const argument_type &Arg) const {
return std::hash<int>()(static_cast<int>(Arg));
}
};
+
} // end namespace std
#endif // LLVM_DEBUGINFO_PDB_PDBTYPES_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/Raw/ModStream.h b/contrib/llvm/include/llvm/DebugInfo/PDB/Raw/ModStream.h
deleted file mode 100644
index d5e7a68..0000000
--- a/contrib/llvm/include/llvm/DebugInfo/PDB/Raw/ModStream.h
+++ /dev/null
@@ -1,62 +0,0 @@
-//===- ModStream.h - PDB Module Info Stream Access ------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_DEBUGINFO_PDB_RAW_MODSTREAM_H
-#define LLVM_DEBUGINFO_PDB_RAW_MODSTREAM_H
-
-#include "llvm/ADT/iterator_range.h"
-#include "llvm/DebugInfo/CodeView/CVRecord.h"
-#include "llvm/DebugInfo/CodeView/ModuleSubstream.h"
-#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
-#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
-#include "llvm/DebugInfo/MSF/StreamArray.h"
-#include "llvm/DebugInfo/MSF/StreamRef.h"
-#include "llvm/Support/Error.h"
-
-namespace llvm {
-namespace pdb {
-class PDBFile;
-class ModInfo;
-
-class ModStream {
-public:
- ModStream(const ModInfo &Module,
- std::unique_ptr<msf::MappedBlockStream> Stream);
- ~ModStream();
-
- Error reload();
-
- uint32_t signature() const { return Signature; }
-
- iterator_range<codeview::CVSymbolArray::Iterator>
- symbols(bool *HadError) const;
-
- iterator_range<codeview::ModuleSubstreamArray::Iterator>
- lines(bool *HadError) const;
-
- Error commit();
-
-private:
- const ModInfo &Mod;
-
- uint32_t Signature;
-
- std::unique_ptr<msf::MappedBlockStream> Stream;
-
- codeview::CVSymbolArray SymbolsSubstream;
- msf::ReadableStreamRef LinesSubstream;
- msf::ReadableStreamRef C13LinesSubstream;
- msf::ReadableStreamRef GlobalRefsSubstream;
-
- codeview::ModuleSubstreamArray LineInfo;
-};
-}
-}
-
-#endif
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/Raw/NameHashTable.h b/contrib/llvm/include/llvm/DebugInfo/PDB/Raw/NameHashTable.h
deleted file mode 100644
index 00d022d..0000000
--- a/contrib/llvm/include/llvm/DebugInfo/PDB/Raw/NameHashTable.h
+++ /dev/null
@@ -1,54 +0,0 @@
-//===- NameHashTable.h - PDB Name Hash Table --------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_DEBUGINFO_PDB_RAW_NAMEHASHTABLE_H
-#define LLVM_DEBUGINFO_PDB_RAW_NAMEHASHTABLE_H
-
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/DebugInfo/MSF/StreamArray.h"
-#include "llvm/DebugInfo/MSF/StreamRef.h"
-#include "llvm/Support/Endian.h"
-#include "llvm/Support/Error.h"
-#include <cstdint>
-#include <vector>
-
-namespace llvm {
-namespace msf {
-class StreamReader;
-}
-namespace pdb {
-
-class NameHashTable {
-public:
- NameHashTable();
-
- Error load(msf::StreamReader &Stream);
-
- uint32_t getNameCount() const { return NameCount; }
- uint32_t getHashVersion() const { return HashVersion; }
- uint32_t getSignature() const { return Signature; }
-
- StringRef getStringForID(uint32_t ID) const;
- uint32_t getIDForString(StringRef Str) const;
-
- msf::FixedStreamArray<support::ulittle32_t> name_ids() const;
-
-private:
- msf::ReadableStreamRef NamesBuffer;
- msf::FixedStreamArray<support::ulittle32_t> IDs;
- uint32_t Signature;
- uint32_t HashVersion;
- uint32_t NameCount;
-};
-
-} // end namespace pdb
-} // end namespace llvm
-
-#endif // LLVM_DEBUGINFO_PDB_RAW_NAMEHASHTABLE_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/Raw/NameMap.h b/contrib/llvm/include/llvm/DebugInfo/PDB/Raw/NameMap.h
deleted file mode 100644
index de1163b..0000000
--- a/contrib/llvm/include/llvm/DebugInfo/PDB/Raw/NameMap.h
+++ /dev/null
@@ -1,44 +0,0 @@
-//===- NameMap.h - PDB Name Map ---------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_DEBUGINFO_PDB_RAW_PDBNAMEMAP_H
-#define LLVM_DEBUGINFO_PDB_RAW_PDBNAMEMAP_H
-
-#include "llvm/ADT/StringMap.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/Error.h"
-#include <cstdint>
-
-namespace llvm {
-namespace msf {
-class StreamReader;
-class StreamWriter;
-}
-namespace pdb {
-class NameMapBuilder;
-class NameMap {
- friend NameMapBuilder;
-
-public:
- NameMap();
-
- Error load(msf::StreamReader &Stream);
-
- bool tryGetValue(StringRef Name, uint32_t &Value) const;
-
- iterator_range<StringMapConstIterator<uint32_t>> entries() const;
-
-private:
- StringMap<uint32_t> Mapping;
-};
-
-} // end namespace pdb
-} // end namespace llvm
-
-#endif // LLVM_DEBUGINFO_PDB_RAW_PDBNAMEMAP_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/Raw/NameMapBuilder.h b/contrib/llvm/include/llvm/DebugInfo/PDB/Raw/NameMapBuilder.h
deleted file mode 100644
index f5244ac..0000000
--- a/contrib/llvm/include/llvm/DebugInfo/PDB/Raw/NameMapBuilder.h
+++ /dev/null
@@ -1,45 +0,0 @@
-//===- NameMapBuilder.h - PDB Name Map Builder ------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_DEBUGINFO_PDB_RAW_PDBNAMEMAPBUILDER_H
-#define LLVM_DEBUGINFO_PDB_RAW_PDBNAMEMAPBUILDER_H
-
-#include "llvm/ADT/StringMap.h"
-#include "llvm/Support/Error.h"
-
-#include <cstdint>
-#include <memory>
-
-namespace llvm {
-namespace msf {
-class StreamWriter;
-}
-namespace pdb {
-class NameMap;
-
-class NameMapBuilder {
-public:
- NameMapBuilder();
-
- void addMapping(StringRef Name, uint32_t Mapping);
-
- Expected<std::unique_ptr<NameMap>> build();
- Error commit(msf::StreamWriter &Writer) const;
-
- uint32_t calculateSerializedLength() const;
-
-private:
- StringMap<uint32_t> Map;
- uint32_t StringDataBytes = 0;
-};
-
-} // end namespace pdb
-} // end namespace llvm
-
-#endif // LLVM_DEBUGINFO_PDB_RAW_PDBNAMEMAPBUILDER_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/Raw/TpiHashing.h b/contrib/llvm/include/llvm/DebugInfo/PDB/Raw/TpiHashing.h
deleted file mode 100644
index 67a4952..0000000
--- a/contrib/llvm/include/llvm/DebugInfo/PDB/Raw/TpiHashing.h
+++ /dev/null
@@ -1,95 +0,0 @@
-//===- TpiHashing.h ---------------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_DEBUGINFO_PDB_TPIHASHING_H
-#define LLVM_DEBUGINFO_PDB_TPIHASHING_H
-
-#include "llvm/ADT/Optional.h"
-#include "llvm/ADT/StringExtras.h"
-#include "llvm/DebugInfo/CodeView/TypeIndex.h"
-#include "llvm/DebugInfo/CodeView/TypeRecord.h"
-#include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
-#include "llvm/DebugInfo/MSF/StreamArray.h"
-#include "llvm/DebugInfo/PDB/Raw/RawError.h"
-#include "llvm/Support/Endian.h"
-#include "llvm/Support/Error.h"
-#include <cstdint>
-#include <string>
-
-namespace llvm {
-namespace pdb {
-
-class TpiHashUpdater : public codeview::TypeVisitorCallbacks {
-public:
- TpiHashUpdater() = default;
-
-#define TYPE_RECORD(EnumName, EnumVal, Name) \
- virtual Error visitKnownRecord(codeview::CVType &CVR, \
- codeview::Name##Record &Record) override { \
- visitKnownRecordImpl(CVR, Record); \
- return Error::success(); \
- }
-#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
-#define MEMBER_RECORD(EnumName, EnumVal, Name)
-#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
-#include "llvm/DebugInfo/CodeView/TypeRecords.def"
-
-private:
- template <typename RecordKind>
- void visitKnownRecordImpl(codeview::CVType &CVR, RecordKind &Record) {
- CVR.Hash = 0;
- }
-
- void visitKnownRecordImpl(codeview::CVType &CVR,
- codeview::UdtSourceLineRecord &Rec);
- void visitKnownRecordImpl(codeview::CVType &CVR,
- codeview::UdtModSourceLineRecord &Rec);
- void visitKnownRecordImpl(codeview::CVType &CVR, codeview::ClassRecord &Rec);
- void visitKnownRecordImpl(codeview::CVType &CVR, codeview::EnumRecord &Rec);
- void visitKnownRecordImpl(codeview::CVType &CVR, codeview::UnionRecord &Rec);
-};
-
-class TpiHashVerifier : public codeview::TypeVisitorCallbacks {
-public:
- TpiHashVerifier(msf::FixedStreamArray<support::ulittle32_t> &HashValues,
- uint32_t NumHashBuckets)
- : HashValues(HashValues), NumHashBuckets(NumHashBuckets) {}
-
- Error visitKnownRecord(codeview::CVType &CVR,
- codeview::UdtSourceLineRecord &Rec) override;
- Error visitKnownRecord(codeview::CVType &CVR,
- codeview::UdtModSourceLineRecord &Rec) override;
- Error visitKnownRecord(codeview::CVType &CVR,
- codeview::ClassRecord &Rec) override;
- Error visitKnownRecord(codeview::CVType &CVR,
- codeview::EnumRecord &Rec) override;
- Error visitKnownRecord(codeview::CVType &CVR,
- codeview::UnionRecord &Rec) override;
- Error visitTypeBegin(codeview::CVType &CVR) override;
-
-private:
- Error verifySourceLine(codeview::TypeIndex TI);
-
- Error errorInvalidHash() {
- return make_error<RawError>(
- raw_error_code::invalid_tpi_hash,
- "Type index is 0x" +
- utohexstr(codeview::TypeIndex::FirstNonSimpleIndex + Index));
- }
-
- msf::FixedStreamArray<support::ulittle32_t> HashValues;
- codeview::CVType RawRecord;
- uint32_t NumHashBuckets;
- uint32_t Index = -1;
-};
-
-} // end namespace pdb
-} // end namespace llvm
-
-#endif // LLVM_DEBUGINFO_PDB_TPIHASHING_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/UDTLayout.h b/contrib/llvm/include/llvm/DebugInfo/PDB/UDTLayout.h
new file mode 100644
index 0000000..c4234c1
--- /dev/null
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/UDTLayout.h
@@ -0,0 +1,182 @@
+//===- UDTLayout.h - UDT layout info ----------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_PDB_UDTLAYOUT_H
+#define LLVM_DEBUGINFO_PDB_UDTLAYOUT_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/BitVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/DebugInfo/PDB/PDBSymbol.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolData.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeVTable.h"
+#include "llvm/DebugInfo/PDB/PDBTypes.h"
+#include <cstdint>
+#include <memory>
+#include <string>
+#include <vector>
+
+namespace llvm {
+namespace pdb {
+
+class BaseClassLayout;
+class ClassLayout;
+class UDTLayoutBase;
+
+class LayoutItemBase {
+public:
+ LayoutItemBase(const UDTLayoutBase *Parent, const PDBSymbol *Symbol,
+ const std::string &Name, uint32_t OffsetInParent,
+ uint32_t Size, bool IsElided);
+ virtual ~LayoutItemBase() = default;
+
+ uint32_t deepPaddingSize() const;
+ virtual uint32_t immediatePadding() const { return 0; }
+ virtual uint32_t tailPadding() const;
+
+ const UDTLayoutBase *getParent() const { return Parent; }
+ StringRef getName() const { return Name; }
+ uint32_t getOffsetInParent() const { return OffsetInParent; }
+ uint32_t getSize() const { return SizeOf; }
+ uint32_t getLayoutSize() const { return LayoutSize; }
+ const PDBSymbol *getSymbol() const { return Symbol; }
+ const BitVector &usedBytes() const { return UsedBytes; }
+ bool isElided() const { return IsElided; }
+ virtual bool isVBPtr() const { return false; }
+
+ uint32_t containsOffset(uint32_t Off) const {
+ uint32_t Begin = getOffsetInParent();
+ uint32_t End = Begin + getSize();
+ return (Off >= Begin && Off < End);
+ }
+
+protected:
+ const PDBSymbol *Symbol = nullptr;
+ const UDTLayoutBase *Parent = nullptr;
+ BitVector UsedBytes;
+ std::string Name;
+ uint32_t OffsetInParent = 0;
+ uint32_t SizeOf = 0;
+ uint32_t LayoutSize = 0;
+ bool IsElided = false;
+};
+
+class VBPtrLayoutItem : public LayoutItemBase {
+public:
+ VBPtrLayoutItem(const UDTLayoutBase &Parent,
+ std::unique_ptr<PDBSymbolTypeBuiltin> Sym, uint32_t Offset,
+ uint32_t Size);
+
+ bool isVBPtr() const override { return true; }
+
+private:
+ std::unique_ptr<PDBSymbolTypeBuiltin> Type;
+};
+
+class DataMemberLayoutItem : public LayoutItemBase {
+public:
+ DataMemberLayoutItem(const UDTLayoutBase &Parent,
+ std::unique_ptr<PDBSymbolData> DataMember);
+
+ const PDBSymbolData &getDataMember();
+ bool hasUDTLayout() const;
+ const ClassLayout &getUDTLayout() const;
+
+private:
+ std::unique_ptr<PDBSymbolData> DataMember;
+ std::unique_ptr<ClassLayout> UdtLayout;
+};
+
+class VTableLayoutItem : public LayoutItemBase {
+public:
+ VTableLayoutItem(const UDTLayoutBase &Parent,
+ std::unique_ptr<PDBSymbolTypeVTable> VTable);
+
+ uint32_t getElementSize() const { return ElementSize; }
+
+private:
+ uint32_t ElementSize = 0;
+ std::unique_ptr<PDBSymbolTypeVTable> VTable;
+};
+
+class UDTLayoutBase : public LayoutItemBase {
+ template <typename T> using UniquePtrVector = std::vector<std::unique_ptr<T>>;
+
+public:
+ UDTLayoutBase(const UDTLayoutBase *Parent, const PDBSymbol &Sym,
+ const std::string &Name, uint32_t OffsetInParent, uint32_t Size,
+ bool IsElided);
+
+ uint32_t tailPadding() const override;
+ ArrayRef<LayoutItemBase *> layout_items() const { return LayoutItems; }
+ ArrayRef<BaseClassLayout *> bases() const { return AllBases; }
+ ArrayRef<BaseClassLayout *> regular_bases() const { return NonVirtualBases; }
+ ArrayRef<BaseClassLayout *> virtual_bases() const { return VirtualBases; }
+ uint32_t directVirtualBaseCount() const { return DirectVBaseCount; }
+ ArrayRef<std::unique_ptr<PDBSymbolFunc>> funcs() const { return Funcs; }
+ ArrayRef<std::unique_ptr<PDBSymbol>> other_items() const { return Other; }
+
+protected:
+ bool hasVBPtrAtOffset(uint32_t Off) const;
+ void initializeChildren(const PDBSymbol &Sym);
+
+ void addChildToLayout(std::unique_ptr<LayoutItemBase> Child);
+
+ uint32_t DirectVBaseCount = 0;
+
+ UniquePtrVector<PDBSymbol> Other;
+ UniquePtrVector<PDBSymbolFunc> Funcs;
+ UniquePtrVector<LayoutItemBase> ChildStorage;
+ std::vector<LayoutItemBase *> LayoutItems;
+
+ std::vector<BaseClassLayout *> AllBases;
+ ArrayRef<BaseClassLayout *> NonVirtualBases;
+ ArrayRef<BaseClassLayout *> VirtualBases;
+
+ VTableLayoutItem *VTable = nullptr;
+ VBPtrLayoutItem *VBPtr = nullptr;
+};
+
+class BaseClassLayout : public UDTLayoutBase {
+public:
+ BaseClassLayout(const UDTLayoutBase &Parent, uint32_t OffsetInParent,
+ bool Elide, std::unique_ptr<PDBSymbolTypeBaseClass> Base);
+
+ const PDBSymbolTypeBaseClass &getBase() const { return *Base; }
+ bool isVirtualBase() const { return IsVirtualBase; }
+ bool isEmptyBase() { return SizeOf == 1 && LayoutSize == 0; }
+
+private:
+ std::unique_ptr<PDBSymbolTypeBaseClass> Base;
+ bool IsVirtualBase;
+};
+
+class ClassLayout : public UDTLayoutBase {
+public:
+ explicit ClassLayout(const PDBSymbolTypeUDT &UDT);
+ explicit ClassLayout(std::unique_ptr<PDBSymbolTypeUDT> UDT);
+
+ ClassLayout(ClassLayout &&Other) = default;
+
+ const PDBSymbolTypeUDT &getClass() const { return UDT; }
+ uint32_t immediatePadding() const override;
+
+private:
+ BitVector ImmediateUsedBytes;
+ std::unique_ptr<PDBSymbolTypeUDT> OwnedStorage;
+ const PDBSymbolTypeUDT &UDT;
+};
+
+} // end namespace pdb
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_PDB_UDTLAYOUT_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/Symbolize/DIPrinter.h b/contrib/llvm/include/llvm/DebugInfo/Symbolize/DIPrinter.h
index 49f86ea..ab82be3 100644
--- a/contrib/llvm/include/llvm/DebugInfo/Symbolize/DIPrinter.h
+++ b/contrib/llvm/include/llvm/DebugInfo/Symbolize/DIPrinter.h
@@ -29,15 +29,18 @@ class DIPrinter {
bool PrintFunctionNames;
bool PrintPretty;
int PrintSourceContext;
+ bool Verbose;
void print(const DILineInfo &Info, bool Inlined);
void printContext(const std::string &FileName, int64_t Line);
public:
DIPrinter(raw_ostream &OS, bool PrintFunctionNames = true,
- bool PrintPretty = false, int PrintSourceContext = 0)
+ bool PrintPretty = false, int PrintSourceContext = 0,
+ bool Verbose = false)
: OS(OS), PrintFunctionNames(PrintFunctionNames),
- PrintPretty(PrintPretty), PrintSourceContext(PrintSourceContext) {}
+ PrintPretty(PrintPretty), PrintSourceContext(PrintSourceContext),
+ Verbose(Verbose) {}
DIPrinter &operator<<(const DILineInfo &Info);
DIPrinter &operator<<(const DIInliningInfo &Info);
diff --git a/contrib/llvm/include/llvm/DebugInfo/Symbolize/SymbolizableModule.h b/contrib/llvm/include/llvm/DebugInfo/Symbolize/SymbolizableModule.h
index e0bec6f..e576a91 100644
--- a/contrib/llvm/include/llvm/DebugInfo/Symbolize/SymbolizableModule.h
+++ b/contrib/llvm/include/llvm/DebugInfo/Symbolize/SymbolizableModule.h
@@ -1,4 +1,4 @@
-//===-- SymbolizableModule.h ------------------------------------ C++ -----===//
+//===- SymbolizableModule.h -------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,12 +14,7 @@
#define LLVM_DEBUGINFO_SYMBOLIZE_SYMBOLIZABLEMODULE_H
#include "llvm/DebugInfo/DIContext.h"
-
-namespace llvm {
-namespace object {
-class ObjectFile;
-}
-}
+#include <cstdint>
namespace llvm {
namespace symbolize {
@@ -28,7 +23,8 @@ using FunctionNameKind = DILineInfoSpecifier::FunctionNameKind;
class SymbolizableModule {
public:
- virtual ~SymbolizableModule() {}
+ virtual ~SymbolizableModule() = default;
+
virtual DILineInfo symbolizeCode(uint64_t ModuleOffset,
FunctionNameKind FNKind,
bool UseSymbolTable) const = 0;
@@ -45,7 +41,7 @@ public:
virtual uint64_t getModulePreferredBase() const = 0;
};
-} // namespace symbolize
-} // namespace llvm
+} // end namespace symbolize
+} // end namespace llvm
#endif // LLVM_DEBUGINFO_SYMBOLIZE_SYMBOLIZABLEMODULE_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h b/contrib/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h
index 9253adf..d98d49b 100644
--- a/contrib/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h
+++ b/contrib/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h
@@ -1,4 +1,4 @@
-//===-- Symbolize.h --------------------------------------------- C++ -----===//
+//===- Symbolize.h ----------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -10,21 +10,27 @@
// Header for LLVM symbolization library.
//
//===----------------------------------------------------------------------===//
+
#ifndef LLVM_DEBUGINFO_SYMBOLIZE_SYMBOLIZE_H
#define LLVM_DEBUGINFO_SYMBOLIZE_SYMBOLIZE_H
#include "llvm/DebugInfo/Symbolize/SymbolizableModule.h"
+#include "llvm/Object/Binary.h"
#include "llvm/Object/ObjectFile.h"
-#include "llvm/Support/ErrorOr.h"
+#include "llvm/Support/Error.h"
+#include <algorithm>
+#include <cstdint>
#include <map>
#include <memory>
#include <string>
#include <utility>
+#include <vector>
namespace llvm {
namespace symbolize {
using namespace object;
+
using FunctionNameKind = DILineInfoSpecifier::FunctionNameKind;
class LLVMSymbolizer {
@@ -36,6 +42,7 @@ public:
bool RelativeAddresses : 1;
std::string DefaultArch;
std::vector<std::string> DsymHints;
+
Options(FunctionNameKind PrintFunctions = FunctionNameKind::LinkageName,
bool UseSymbolTable = true, bool Demangle = true,
bool RelativeAddresses = false, std::string DefaultArch = "")
@@ -45,6 +52,7 @@ public:
};
LLVMSymbolizer(const Options &Opts = Options()) : Opts(Opts) {}
+
~LLVMSymbolizer() {
flush();
}
@@ -56,13 +64,15 @@ public:
Expected<DIGlobal> symbolizeData(const std::string &ModuleName,
uint64_t ModuleOffset);
void flush();
- static std::string DemangleName(const std::string &Name,
- const SymbolizableModule *ModInfo);
+
+ static std::string
+ DemangleName(const std::string &Name,
+ const SymbolizableModule *DbiModuleDescriptor);
private:
// Bundles together object file with code/data and object file with
// corresponding debug info. These objects can be the same.
- typedef std::pair<ObjectFile*, ObjectFile*> ObjectPair;
+ using ObjectPair = std::pair<ObjectFile *, ObjectFile *>;
/// Returns a SymbolizableModule or an error if loading debug info failed.
/// Only one attempt is made to load a module, and errors during loading are
@@ -105,7 +115,7 @@ private:
Options Opts;
};
-} // namespace symbolize
-} // namespace llvm
+} // end namespace symbolize
+} // end namespace llvm
-#endif
+#endif // LLVM_DEBUGINFO_SYMBOLIZE_SYMBOLIZE_H
diff --git a/contrib/llvm/include/llvm/ExecutionEngine/ExecutionEngine.h b/contrib/llvm/include/llvm/ExecutionEngine/ExecutionEngine.h
index f68337c..2830a26 100644
--- a/contrib/llvm/include/llvm/ExecutionEngine/ExecutionEngine.h
+++ b/contrib/llvm/include/llvm/ExecutionEngine/ExecutionEngine.h
@@ -15,54 +15,58 @@
#ifndef LLVM_EXECUTIONENGINE_EXECUTIONENGINE_H
#define LLVM_EXECUTIONENGINE_EXECUTIONENGINE_H
-#include "RuntimeDyld.h"
#include "llvm-c/ExecutionEngine.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/ExecutionEngine/JITSymbol.h"
+#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Module.h"
-#include "llvm/IR/ValueHandle.h"
-#include "llvm/IR/ValueMap.h"
#include "llvm/Object/Binary.h"
+#include "llvm/Support/CBindingWrapping.h"
+#include "llvm/Support/CodeGen.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Mutex.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
+#include <algorithm>
+#include <cstdint>
+#include <functional>
#include <map>
+#include <memory>
#include <string>
#include <vector>
-#include <functional>
namespace llvm {
-struct GenericValue;
class Constant;
-class DataLayout;
-class ExecutionEngine;
class Function;
-class GlobalVariable;
+struct GenericValue;
class GlobalValue;
+class GlobalVariable;
class JITEventListener;
-class MachineCodeInfo;
class MCJITMemoryManager;
-class MutexGuard;
class ObjectCache;
class RTDyldMemoryManager;
class Triple;
class Type;
namespace object {
- class Archive;
- class ObjectFile;
-}
+
+class Archive;
+class ObjectFile;
+
+} // end namespace object
/// \brief Helper class for helping synchronize access to the global address map
/// table. Access to this class should be serialized under a mutex.
class ExecutionEngineState {
public:
- typedef StringMap<uint64_t> GlobalAddressMapTy;
+ using GlobalAddressMapTy = StringMap<uint64_t>;
private:
-
/// GlobalAddressMap - A mapping between LLVM global symbol names values and
/// their actualized version...
GlobalAddressMapTy GlobalAddressMap;
@@ -74,7 +78,6 @@ private:
std::map<uint64_t, std::string> GlobalAddressReverseMap;
public:
-
GlobalAddressMapTy &getGlobalAddressMap() {
return GlobalAddressMap;
}
@@ -509,13 +512,15 @@ private:
};
namespace EngineKind {
+
// These are actually bitmasks that get or-ed together.
enum Kind {
JIT = 0x1,
Interpreter = 0x2
};
const static Kind Either = (Kind)(JIT | Interpreter);
-}
+
+} // end namespace EngineKind
/// Builder class for ExecutionEngines. Use this by stack-allocating a builder,
/// chaining the various set* methods, and terminating it with a .create()
@@ -655,6 +660,6 @@ public:
// Create wrappers for C Binding types (see CBindingWrapping.h).
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ExecutionEngine, LLVMExecutionEngineRef)
-} // End llvm namespace
+} // end namespace llvm
-#endif
+#endif // LLVM_EXECUTIONENGINE_EXECUTIONENGINE_H
diff --git a/contrib/llvm/include/llvm/ExecutionEngine/GenericValue.h b/contrib/llvm/include/llvm/ExecutionEngine/GenericValue.h
index 5377455..504e30a 100644
--- a/contrib/llvm/include/llvm/ExecutionEngine/GenericValue.h
+++ b/contrib/llvm/include/llvm/ExecutionEngine/GenericValue.h
@@ -1,4 +1,4 @@
-//===-- GenericValue.h - Represent any type of LLVM value -------*- C++ -*-===//
+//===- GenericValue.h - Represent any type of LLVM value --------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -11,18 +11,15 @@
//
//===----------------------------------------------------------------------===//
-
#ifndef LLVM_EXECUTIONENGINE_GENERICVALUE_H
#define LLVM_EXECUTIONENGINE_GENERICVALUE_H
#include "llvm/ADT/APInt.h"
-#include "llvm/Support/DataTypes.h"
#include <vector>
namespace llvm {
-typedef void* PointerTy;
-class APInt;
+using PointerTy = void *;
struct GenericValue {
struct IntPair {
@@ -30,25 +27,29 @@ struct GenericValue {
unsigned int second;
};
union {
- double DoubleVal;
- float FloatVal;
- PointerTy PointerVal;
- struct IntPair UIntPairVal;
- unsigned char Untyped[8];
+ double DoubleVal;
+ float FloatVal;
+ PointerTy PointerVal;
+ struct IntPair UIntPairVal;
+ unsigned char Untyped[8];
};
- APInt IntVal; // also used for long doubles.
+ APInt IntVal; // also used for long doubles.
// For aggregate data types.
std::vector<GenericValue> AggregateVal;
// to make code faster, set GenericValue to zero could be omitted, but it is
// potentially can cause problems, since GenericValue to store garbage
// instead of zero.
- GenericValue() : IntVal(1,0) {UIntPairVal.first = 0; UIntPairVal.second = 0;}
- explicit GenericValue(void *V) : PointerVal(V), IntVal(1,0) { }
+ GenericValue() : IntVal(1, 0) {
+ UIntPairVal.first = 0;
+ UIntPairVal.second = 0;
+ }
+ explicit GenericValue(void *V) : PointerVal(V), IntVal(1, 0) {}
};
inline GenericValue PTOGV(void *P) { return GenericValue(P); }
-inline void* GVTOP(const GenericValue &GV) { return GV.PointerVal; }
+inline void *GVTOP(const GenericValue &GV) { return GV.PointerVal; }
+
+} // end namespace llvm
-} // End llvm namespace.
-#endif
+#endif // LLVM_EXECUTIONENGINE_GENERICVALUE_H
diff --git a/contrib/llvm/include/llvm/ExecutionEngine/JITEventListener.h b/contrib/llvm/include/llvm/ExecutionEngine/JITEventListener.h
index 94ec4e3..ff7840f 100644
--- a/contrib/llvm/include/llvm/ExecutionEngine/JITEventListener.h
+++ b/contrib/llvm/include/llvm/ExecutionEngine/JITEventListener.h
@@ -15,8 +15,8 @@
#ifndef LLVM_EXECUTIONENGINE_JITEVENTLISTENER_H
#define LLVM_EXECUTIONENGINE_JITEVENTLISTENER_H
-#include "RuntimeDyld.h"
#include "llvm/Config/llvm-config.h"
+#include "llvm/ExecutionEngine/RuntimeDyld.h"
#include "llvm/IR/DebugLoc.h"
#include <cstdint>
#include <vector>
@@ -28,7 +28,9 @@ class MachineFunction;
class OProfileWrapper;
namespace object {
- class ObjectFile;
+
+class ObjectFile;
+
} // end namespace object
/// JITEvent_EmittedFunctionDetails - Helper struct for containing information
@@ -57,7 +59,7 @@ struct JITEvent_EmittedFunctionDetails {
/// The default implementation of each method does nothing.
class JITEventListener {
public:
- typedef JITEvent_EmittedFunctionDetails EmittedFunctionDetails;
+ using EmittedFunctionDetails = JITEvent_EmittedFunctionDetails;
public:
JITEventListener() = default;
diff --git a/contrib/llvm/include/llvm/ExecutionEngine/JITSymbol.h b/contrib/llvm/include/llvm/ExecutionEngine/JITSymbol.h
index 8892948..4172f24 100644
--- a/contrib/llvm/include/llvm/ExecutionEngine/JITSymbol.h
+++ b/contrib/llvm/include/llvm/ExecutionEngine/JITSymbol.h
@@ -1,4 +1,4 @@
-//===----------- JITSymbol.h - JIT symbol abstraction -----------*- C++ -*-===//
+//===- JITSymbol.h - JIT symbol abstraction ---------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -21,36 +21,46 @@
#include <functional>
#include <string>
+#include "llvm/Support/Error.h"
+
namespace llvm {
class GlobalValue;
namespace object {
- class BasicSymbolRef;
+
+class BasicSymbolRef;
+
} // end namespace object
/// @brief Represents an address in the target process's address space.
-typedef uint64_t JITTargetAddress;
+using JITTargetAddress = uint64_t;
/// @brief Flags for symbols in the JIT.
class JITSymbolFlags {
public:
- typedef uint8_t UnderlyingType;
+ using UnderlyingType = uint8_t;
enum FlagNames : UnderlyingType {
None = 0,
- Weak = 1U << 0,
- Common = 1U << 1,
- Absolute = 1U << 2,
- Exported = 1U << 3
+ HasError = 1U << 0,
+ Weak = 1U << 1,
+ Common = 1U << 2,
+ Absolute = 1U << 3,
+ Exported = 1U << 4
};
/// @brief Default-construct a JITSymbolFlags instance.
- JITSymbolFlags() : Flags(None) {}
+ JITSymbolFlags() = default;
/// @brief Construct a JITSymbolFlags instance from the given flags.
JITSymbolFlags(FlagNames Flags) : Flags(Flags) {}
+ /// @brief Return true if there was an error retrieving this symbol.
+ bool hasError() const {
+ return (Flags & HasError) == HasError;
+ }
+
/// @brief Returns true is the Weak flag is set.
bool isWeak() const {
return (Flags & Weak) == Weak;
@@ -81,15 +91,14 @@ public:
static JITSymbolFlags fromObjectSymbol(const object::BasicSymbolRef &Symbol);
private:
- UnderlyingType Flags;
+ UnderlyingType Flags = None;
};
/// @brief Represents a symbol that has been evaluated to an address already.
class JITEvaluatedSymbol {
public:
/// @brief Create a 'null' symbol.
- JITEvaluatedSymbol(std::nullptr_t)
- : Address(0) {}
+ JITEvaluatedSymbol(std::nullptr_t) {}
/// @brief Create a symbol for the given address and flags.
JITEvaluatedSymbol(JITTargetAddress Address, JITSymbolFlags Flags)
@@ -105,20 +114,25 @@ public:
JITSymbolFlags getFlags() const { return Flags; }
private:
- JITTargetAddress Address;
+ JITTargetAddress Address = 0;
JITSymbolFlags Flags;
};
/// @brief Represents a symbol in the JIT.
class JITSymbol {
public:
- typedef std::function<JITTargetAddress()> GetAddressFtor;
+ using GetAddressFtor = std::function<Expected<JITTargetAddress>()>;
- /// @brief Create a 'null' symbol that represents failure to find a symbol
- /// definition.
+ /// @brief Create a 'null' symbol, used to represent a "symbol not found"
+ /// result from a successful (non-erroneous) lookup.
JITSymbol(std::nullptr_t)
: CachedAddr(0) {}
+ /// @brief Create a JITSymbol representing an error in the symbol lookup
+ /// process (e.g. a network failure during a remote lookup).
+ JITSymbol(Error Err)
+ : Err(std::move(Err)), Flags(JITSymbolFlags::HasError) {}
+
/// @brief Create a symbol for a definition with a known address.
JITSymbol(JITTargetAddress Addr, JITSymbolFlags Flags)
: CachedAddr(Addr), Flags(Flags) {}
@@ -139,16 +153,57 @@ public:
JITSymbol(GetAddressFtor GetAddress, JITSymbolFlags Flags)
: GetAddress(std::move(GetAddress)), CachedAddr(0), Flags(Flags) {}
+ JITSymbol(const JITSymbol&) = delete;
+ JITSymbol& operator=(const JITSymbol&) = delete;
+
+ JITSymbol(JITSymbol &&Other)
+ : GetAddress(std::move(Other.GetAddress)), Flags(std::move(Other.Flags)) {
+ if (Flags.hasError())
+ Err = std::move(Other.Err);
+ else
+ CachedAddr = std::move(Other.CachedAddr);
+ }
+
+ JITSymbol& operator=(JITSymbol &&Other) {
+ GetAddress = std::move(Other.GetAddress);
+ Flags = std::move(Other.Flags);
+ if (Flags.hasError())
+ Err = std::move(Other.Err);
+ else
+ CachedAddr = std::move(Other.CachedAddr);
+ return *this;
+ }
+
+ ~JITSymbol() {
+ if (Flags.hasError())
+ Err.~Error();
+ else
+ CachedAddr.~JITTargetAddress();
+ }
+
/// @brief Returns true if the symbol exists, false otherwise.
- explicit operator bool() const { return CachedAddr || GetAddress; }
+ explicit operator bool() const {
+ return !Flags.hasError() && (CachedAddr || GetAddress);
+ }
+
+ /// @brief Move the error field value out of this JITSymbol.
+ Error takeError() {
+ if (Flags.hasError())
+ return std::move(Err);
+ return Error::success();
+ }
/// @brief Get the address of the symbol in the target address space. Returns
/// '0' if the symbol does not exist.
- JITTargetAddress getAddress() {
+ Expected<JITTargetAddress> getAddress() {
+ assert(!Flags.hasError() && "getAddress called on error value");
if (GetAddress) {
- CachedAddr = GetAddress();
- assert(CachedAddr && "Symbol could not be materialized.");
- GetAddress = nullptr;
+ if (auto CachedAddrOrErr = GetAddress()) {
+ GetAddress = nullptr;
+ CachedAddr = *CachedAddrOrErr;
+ assert(CachedAddr && "Symbol could not be materialized.");
+ } else
+ return CachedAddrOrErr.takeError();
}
return CachedAddr;
}
@@ -157,7 +212,10 @@ public:
private:
GetAddressFtor GetAddress;
- JITTargetAddress CachedAddr;
+ union {
+ JITTargetAddress CachedAddr;
+ Error Err;
+ };
JITSymbolFlags Flags;
};
diff --git a/contrib/llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h b/contrib/llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h
index aa09647..27b5457 100644
--- a/contrib/llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h
+++ b/contrib/llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h
@@ -20,20 +20,25 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/ExecutionEngine/JITSymbol.h"
-#include "llvm/ExecutionEngine/RuntimeDyld.h"
#include "llvm/ExecutionEngine/Orc/IndirectionUtils.h"
#include "llvm/ExecutionEngine/Orc/LambdaResolver.h"
+#include "llvm/ExecutionEngine/Orc/OrcError.h"
+#include "llvm/ExecutionEngine/RuntimeDyld.h"
#include "llvm/IR/Attributes.h"
+#include "llvm/IR/Constant.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/GlobalAlias.h"
#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/GlobalVariable.h"
+#include "llvm/IR/Instruction.h"
#include "llvm/IR/Mangler.h"
#include "llvm/IR/Module.h"
+#include "llvm/IR/Type.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/raw_ostream.h"
+#include "llvm/Transforms/Utils/ValueMapper.h"
#include <algorithm>
#include <cassert>
#include <functional>
@@ -46,6 +51,9 @@
#include <vector>
namespace llvm {
+
+class Value;
+
namespace orc {
/// @brief Compile-on-demand layer.
@@ -77,15 +85,15 @@ private:
return LambdaMaterializer<MaterializerFtor>(std::move(M));
}
- typedef typename BaseLayerT::ModuleSetHandleT BaseLayerModuleSetHandleT;
+ using BaseLayerModuleHandleT = typename BaseLayerT::ModuleHandleT;
// Provide type-erasure for the Modules and MemoryManagers.
template <typename ResourceT>
class ResourceOwner {
public:
ResourceOwner() = default;
- ResourceOwner(const ResourceOwner&) = delete;
- ResourceOwner& operator=(const ResourceOwner&) = delete;
+ ResourceOwner(const ResourceOwner &) = delete;
+ ResourceOwner &operator=(const ResourceOwner &) = delete;
virtual ~ResourceOwner() = default;
virtual ResourceT& getResource() const = 0;
@@ -106,7 +114,7 @@ private:
template <typename ResourceT, typename ResourcePtrT>
std::unique_ptr<ResourceOwner<ResourceT>>
wrapOwnership(ResourcePtrT ResourcePtr) {
- typedef ResourceOwnerImpl<ResourceT, ResourcePtrT> RO;
+ using RO = ResourceOwnerImpl<ResourceT, ResourcePtrT>;
return llvm::make_unique<RO>(std::move(ResourcePtr));
}
@@ -130,24 +138,24 @@ private:
};
struct LogicalDylib {
- typedef std::function<JITSymbol(const std::string&)> SymbolResolverFtor;
+ using SymbolResolverFtor = std::function<JITSymbol(const std::string&)>;
- typedef std::function<typename BaseLayerT::ModuleSetHandleT(
- BaseLayerT&,
- std::unique_ptr<Module>,
- std::unique_ptr<JITSymbolResolver>)>
- ModuleAdderFtor;
+ using ModuleAdderFtor =
+ std::function<typename BaseLayerT::ModuleHandleT(
+ BaseLayerT&,
+ std::unique_ptr<Module>,
+ std::unique_ptr<JITSymbolResolver>)>;
struct SourceModuleEntry {
- std::unique_ptr<ResourceOwner<Module>> SourceMod;
+ std::shared_ptr<Module> SourceMod;
std::set<Function*> StubsToClone;
};
- typedef std::vector<SourceModuleEntry> SourceModulesList;
- typedef typename SourceModulesList::size_type SourceModuleHandle;
+ using SourceModulesList = std::vector<SourceModuleEntry>;
+ using SourceModuleHandle = typename SourceModulesList::size_type;
SourceModuleHandle
- addSourceModule(std::unique_ptr<ResourceOwner<Module>> M) {
+ addSourceModule(std::shared_ptr<Module> M) {
SourceModuleHandle H = SourceModules.size();
SourceModules.push_back(SourceModuleEntry());
SourceModules.back().SourceMod = std::move(M);
@@ -155,7 +163,7 @@ private:
}
Module& getSourceModule(SourceModuleHandle H) {
- return SourceModules[H].SourceMod->getResource();
+ return *SourceModules[H].SourceMod;
}
std::set<Function*>& getStubsToClone(SourceModuleHandle H) {
@@ -169,30 +177,38 @@ private:
for (auto BLH : BaseLayerHandles)
if (auto Sym = BaseLayer.findSymbolIn(BLH, Name, ExportedSymbolsOnly))
return Sym;
+ else if (auto Err = Sym.takeError())
+ return std::move(Err);
return nullptr;
}
- std::unique_ptr<JITSymbolResolver> ExternalSymbolResolver;
- std::unique_ptr<ResourceOwner<RuntimeDyld::MemoryManager>> MemMgr;
+ Error removeModulesFromBaseLayer(BaseLayerT &BaseLayer) {
+ for (auto &BLH : BaseLayerHandles)
+ if (auto Err = BaseLayer.removeModule(BLH))
+ return Err;
+ return Error::success();
+ }
+
+ std::shared_ptr<JITSymbolResolver> ExternalSymbolResolver;
std::unique_ptr<IndirectStubsMgrT> StubsMgr;
StaticGlobalRenamer StaticRenamer;
- ModuleAdderFtor ModuleAdder;
SourceModulesList SourceModules;
- std::vector<BaseLayerModuleSetHandleT> BaseLayerHandles;
+ std::vector<BaseLayerModuleHandleT> BaseLayerHandles;
};
- typedef std::list<LogicalDylib> LogicalDylibList;
+ using LogicalDylibList = std::list<LogicalDylib>;
public:
- /// @brief Handle to a set of loaded modules.
- typedef typename LogicalDylibList::iterator ModuleSetHandleT;
+
+ /// @brief Handle to loaded module.
+ using ModuleHandleT = typename LogicalDylibList::iterator;
/// @brief Module partitioning functor.
- typedef std::function<std::set<Function*>(Function&)> PartitioningFtor;
+ using PartitioningFtor = std::function<std::set<Function*>(Function&)>;
/// @brief Builder for IndirectStubsManagers.
- typedef std::function<std::unique_ptr<IndirectStubsMgrT>()>
- IndirectStubsManagerBuilderT;
+ using IndirectStubsManagerBuilderT =
+ std::function<std::unique_ptr<IndirectStubsMgrT>()>;
/// @brief Construct a compile-on-demand layer instance.
CompileOnDemandLayer(BaseLayerT &BaseLayer, PartitioningFtor Partition,
@@ -204,42 +220,42 @@ public:
CreateIndirectStubsManager(std::move(CreateIndirectStubsManager)),
CloneStubsIntoPartitions(CloneStubsIntoPartitions) {}
+ ~CompileOnDemandLayer() {
+ // FIXME: Report error on log.
+ while (!LogicalDylibs.empty())
+ consumeError(removeModule(LogicalDylibs.begin()));
+ }
+
/// @brief Add a module to the compile-on-demand layer.
- template <typename ModuleSetT, typename MemoryManagerPtrT,
- typename SymbolResolverPtrT>
- ModuleSetHandleT addModuleSet(ModuleSetT Ms,
- MemoryManagerPtrT MemMgr,
- SymbolResolverPtrT Resolver) {
+ Expected<ModuleHandleT>
+ addModule(std::shared_ptr<Module> M,
+ std::shared_ptr<JITSymbolResolver> Resolver) {
LogicalDylibs.push_back(LogicalDylib());
auto &LD = LogicalDylibs.back();
LD.ExternalSymbolResolver = std::move(Resolver);
LD.StubsMgr = CreateIndirectStubsManager();
- auto &MemMgrRef = *MemMgr;
- LD.MemMgr = wrapOwnership<RuntimeDyld::MemoryManager>(std::move(MemMgr));
-
- LD.ModuleAdder =
- [&MemMgrRef](BaseLayerT &B, std::unique_ptr<Module> M,
- std::unique_ptr<JITSymbolResolver> R) {
- std::vector<std::unique_ptr<Module>> Ms;
- Ms.push_back(std::move(M));
- return B.addModuleSet(std::move(Ms), &MemMgrRef, std::move(R));
- };
-
// Process each of the modules in this module set.
- for (auto &M : Ms)
- addLogicalModule(LogicalDylibs.back(), std::move(M));
+ if (auto Err = addLogicalModule(LD, std::move(M)))
+ return std::move(Err);
return std::prev(LogicalDylibs.end());
}
+ /// @brief Add extra modules to an existing logical module.
+ Error addExtraModule(ModuleHandleT H, std::shared_ptr<Module> M) {
+ return addLogicalModule(*H, std::move(M));
+ }
+
/// @brief Remove the module represented by the given handle.
///
/// This will remove all modules in the layers below that were derived from
/// the module represented by H.
- void removeModuleSet(ModuleSetHandleT H) {
+ Error removeModule(ModuleHandleT H) {
+ auto Err = H->removeModulesFromBaseLayer(BaseLayer);
LogicalDylibs.erase(H);
+ return Err;
}
/// @brief Search for the given named symbol.
@@ -253,13 +269,15 @@ public:
return Sym;
if (auto Sym = findSymbolIn(LDI, Name, ExportedSymbolsOnly))
return Sym;
+ else if (auto Err = Sym.takeError())
+ return std::move(Err);
}
return BaseLayer.findSymbol(Name, ExportedSymbolsOnly);
}
/// @brief Get the address of a symbol provided by this layer, or some layer
/// below this one.
- JITSymbol findSymbolIn(ModuleSetHandleT H, const std::string &Name,
+ JITSymbol findSymbolIn(ModuleHandleT H, const std::string &Name,
bool ExportedSymbolsOnly) {
return H->findSymbol(BaseLayer, Name, ExportedSymbolsOnly);
}
@@ -272,26 +290,26 @@ public:
// FIXME: We should track and free associated resources (unused compile
// callbacks, uncompiled IR, and no-longer-needed/reachable function
// implementations).
- // FIXME: Return Error once the JIT APIs are Errorized.
- bool updatePointer(std::string FuncName, JITTargetAddress FnBodyAddr) {
+ Error updatePointer(std::string FuncName, JITTargetAddress FnBodyAddr) {
//Find out which logical dylib contains our symbol
auto LDI = LogicalDylibs.begin();
for (auto LDE = LogicalDylibs.end(); LDI != LDE; ++LDI) {
- if (auto LMResources = LDI->getLogicalModuleResourcesForSymbol(FuncName, false)) {
+ if (auto LMResources =
+ LDI->getLogicalModuleResourcesForSymbol(FuncName, false)) {
Module &SrcM = LMResources->SourceModule->getResource();
std::string CalledFnName = mangle(FuncName, SrcM.getDataLayout());
- if (auto EC = LMResources->StubsMgr->updatePointer(CalledFnName, FnBodyAddr))
- return false;
- else
- return true;
+ if (auto Err = LMResources->StubsMgr->updatePointer(CalledFnName,
+ FnBodyAddr))
+ return Err;
+ return Error::success();
}
}
- return false;
+ return make_error<JITSymbolNotFound>(FuncName);
}
private:
- template <typename ModulePtrT>
- void addLogicalModule(LogicalDylib &LD, ModulePtrT SrcMPtr) {
+
+ Error addLogicalModule(LogicalDylib &LD, std::shared_ptr<Module> SrcMPtr) {
// Rename all static functions / globals to $static.X :
// This will unique the names across all modules in the logical dylib,
@@ -304,7 +322,7 @@ private:
// Create a logical module handle for SrcM within the logical dylib.
Module &SrcM = *SrcMPtr;
- auto LMId = LD.addSourceModule(wrapOwnership<Module>(std::move(SrcMPtr)));
+ auto LMId = LD.addSourceModule(std::move(SrcMPtr));
// Create stub functions.
const DataLayout &DL = SrcM.getDataLayout();
@@ -317,9 +335,12 @@ private:
// Skip weak functions for which we already have definitions.
auto MangledName = mangle(F.getName(), DL);
- if (F.hasWeakLinkage() || F.hasLinkOnceLinkage())
+ if (F.hasWeakLinkage() || F.hasLinkOnceLinkage()) {
if (auto Sym = LD.findSymbol(BaseLayer, MangledName, false))
continue;
+ else if (auto Err = Sym.takeError())
+ return std::move(Err);
+ }
// Record all functions defined by this module.
if (CloneStubsIntoPartitions)
@@ -332,16 +353,19 @@ private:
StubInits[MangledName] =
std::make_pair(CCInfo.getAddress(),
JITSymbolFlags::fromGlobalValue(F));
- CCInfo.setCompileAction([this, &LD, LMId, &F]() {
- return this->extractAndCompile(LD, LMId, F);
- });
+ CCInfo.setCompileAction([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;
+ }
+ });
}
- auto EC = LD.StubsMgr->createStubs(StubInits);
- (void)EC;
- // FIXME: This should be propagated back to the user. Stub creation may
- // fail for remote JITs.
- assert(!EC && "Error generating stubs");
+ if (auto Err = LD.StubsMgr->createStubs(StubInits))
+ return Err;
}
// If this module doesn't contain any globals, aliases, or module flags then
@@ -349,7 +373,7 @@ private:
// empty globals module.
if (SrcM.global_empty() && SrcM.alias_empty() &&
!SrcM.getModuleFlagsMetadata())
- return;
+ return Error::success();
// Create the GlobalValues module.
auto GVsM = llvm::make_unique<Module>((SrcM.getName() + ".globals").str(),
@@ -375,8 +399,9 @@ private:
// Initializers may refer to functions declared (but not defined) in this
// module. Build a materializer to clone decls on demand.
+ Error MaterializerErrors = Error::success();
auto Materializer = createLambdaMaterializer(
- [this, &LD, &GVsM](Value *V) -> Value* {
+ [&LD, &GVsM, &MaterializerErrors](Value *V) -> Value* {
if (auto *F = dyn_cast<Function>(V)) {
// Decls in the original module just get cloned.
if (F->isDeclaration())
@@ -387,13 +412,24 @@ private:
// instead.
const DataLayout &DL = GVsM->getDataLayout();
std::string FName = mangle(F->getName(), DL);
- auto StubSym = LD.StubsMgr->findStub(FName, false);
unsigned PtrBitWidth = DL.getPointerTypeSizeInBits(F->getType());
- ConstantInt *StubAddr =
- ConstantInt::get(GVsM->getContext(),
- APInt(PtrBitWidth, StubSym.getAddress()));
+ JITTargetAddress StubAddr = 0;
+
+ // Get the address for the stub. If we encounter an error while
+ // doing so, stash it in the MaterializerErrors variable and use a
+ // null address as a placeholder.
+ if (auto StubSym = LD.StubsMgr->findStub(FName, false)) {
+ if (auto StubAddrOrErr = StubSym.getAddress())
+ StubAddr = *StubAddrOrErr;
+ else
+ MaterializerErrors = joinErrors(std::move(MaterializerErrors),
+ StubAddrOrErr.takeError());
+ }
+
+ ConstantInt *StubAddrCI =
+ ConstantInt::get(GVsM->getContext(), APInt(PtrBitWidth, StubAddr));
Constant *Init = ConstantExpr::getCast(Instruction::IntToPtr,
- StubAddr, F->getType());
+ StubAddrCI, F->getType());
return GlobalAlias::create(F->getFunctionType(),
F->getType()->getAddressSpace(),
F->getLinkage(), F->getName(),
@@ -417,22 +453,31 @@ private:
NewA->setAliasee(cast<Constant>(Init));
}
+ if (MaterializerErrors)
+ return MaterializerErrors;
+
// Build a resolver for the globals module and add it to the base layer.
auto GVsResolver = createLambdaResolver(
- [this, &LD, LMId](const std::string &Name) {
+ [this, &LD](const std::string &Name) -> JITSymbol {
if (auto Sym = LD.StubsMgr->findStub(Name, false))
return Sym;
if (auto Sym = LD.findSymbol(BaseLayer, Name, false))
return Sym;
+ else if (auto Err = Sym.takeError())
+ return std::move(Err);
return LD.ExternalSymbolResolver->findSymbolInLogicalDylib(Name);
},
[&LD](const std::string &Name) {
return LD.ExternalSymbolResolver->findSymbol(Name);
});
- auto GVsH = LD.ModuleAdder(BaseLayer, std::move(GVsM),
- std::move(GVsResolver));
- LD.BaseLayerHandles.push_back(GVsH);
+ if (auto GVsHOrErr =
+ BaseLayer.addModule(std::move(GVsM), std::move(GVsResolver)))
+ LD.BaseLayerHandles.push_back(*GVsHOrErr);
+ else
+ return GVsHOrErr.takeError();
+
+ return Error::success();
}
static std::string mangle(StringRef Name, const DataLayout &DL) {
@@ -444,7 +489,7 @@ private:
return MangledName;
}
- JITTargetAddress
+ Expected<JITTargetAddress>
extractAndCompile(LogicalDylib &LD,
typename LogicalDylib::SourceModuleHandle LMId,
Function &F) {
@@ -457,32 +502,42 @@ private:
// Grab the name of the function being called here.
std::string CalledFnName = mangle(F.getName(), SrcM.getDataLayout());
- auto Part = Partition(F);
- auto PartH = emitPartition(LD, LMId, Part);
-
JITTargetAddress CalledAddr = 0;
- for (auto *SubF : Part) {
- std::string FnName = mangle(SubF->getName(), SrcM.getDataLayout());
- auto FnBodySym = BaseLayer.findSymbolIn(PartH, FnName, false);
- assert(FnBodySym && "Couldn't find function body.");
-
- JITTargetAddress FnBodyAddr = FnBodySym.getAddress();
+ auto Part = Partition(F);
+ if (auto PartHOrErr = emitPartition(LD, LMId, Part)) {
+ auto &PartH = *PartHOrErr;
+ for (auto *SubF : Part) {
+ std::string FnName = mangle(SubF->getName(), SrcM.getDataLayout());
+ if (auto FnBodySym = BaseLayer.findSymbolIn(PartH, FnName, false)) {
+ if (auto FnBodyAddrOrErr = FnBodySym.getAddress()) {
+ JITTargetAddress FnBodyAddr = *FnBodyAddrOrErr;
+
+ // If this is the function we're calling record the address so we can
+ // return it from this function.
+ if (SubF == &F)
+ CalledAddr = FnBodyAddr;
+
+ // Update the function body pointer for the stub.
+ if (auto EC = LD.StubsMgr->updatePointer(FnName, FnBodyAddr))
+ return 0;
+
+ } else
+ return FnBodyAddrOrErr.takeError();
+ } else if (auto Err = FnBodySym.takeError())
+ return std::move(Err);
+ else
+ llvm_unreachable("Function not emitted for partition");
+ }
- // If this is the function we're calling record the address so we can
- // return it from this function.
- if (SubF == &F)
- CalledAddr = FnBodyAddr;
-
- // Update the function body pointer for the stub.
- if (auto EC = LD.StubsMgr->updatePointer(FnName, FnBodyAddr))
- return 0;
- }
+ LD.BaseLayerHandles.push_back(PartH);
+ } else
+ return PartHOrErr.takeError();
return CalledAddr;
}
template <typename PartitionT>
- BaseLayerModuleSetHandleT
+ Expected<BaseLayerModuleHandleT>
emitPartition(LogicalDylib &LD,
typename LogicalDylib::SourceModuleHandle LMId,
const PartitionT &Part) {
@@ -499,8 +554,8 @@ private:
M->setDataLayout(SrcM.getDataLayout());
ValueToValueMapTy VMap;
- auto Materializer = createLambdaMaterializer([this, &LD, &LMId, &M,
- &VMap](Value *V) -> Value * {
+ auto Materializer = createLambdaMaterializer([&LD, &LMId,
+ &M](Value *V) -> Value * {
if (auto *GV = dyn_cast<GlobalVariable>(V))
return cloneGlobalVariableDecl(*M, *GV);
@@ -546,16 +601,18 @@ private:
// Create memory manager and symbol resolver.
auto Resolver = createLambdaResolver(
- [this, &LD, LMId](const std::string &Name) {
+ [this, &LD](const std::string &Name) -> JITSymbol {
if (auto Sym = LD.findSymbol(BaseLayer, Name, false))
return Sym;
+ else if (auto Err = Sym.takeError())
+ return std::move(Err);
return LD.ExternalSymbolResolver->findSymbolInLogicalDylib(Name);
},
- [this, &LD](const std::string &Name) {
+ [&LD](const std::string &Name) {
return LD.ExternalSymbolResolver->findSymbol(Name);
});
- return LD.ModuleAdder(BaseLayer, std::move(M), std::move(Resolver));
+ return BaseLayer.addModule(std::move(M), std::move(Resolver));
}
BaseLayerT &BaseLayer;
@@ -568,6 +625,7 @@ private:
};
} // end namespace orc
+
} // end namespace llvm
#endif // LLVM_EXECUTIONENGINE_ORC_COMPILEONDEMANDLAYER_H
diff --git a/contrib/llvm/include/llvm/ExecutionEngine/Orc/CompileUtils.h b/contrib/llvm/include/llvm/ExecutionEngine/Orc/CompileUtils.h
index ce0864f..b9f7d6a 100644
--- a/contrib/llvm/include/llvm/ExecutionEngine/Orc/CompileUtils.h
+++ b/contrib/llvm/include/llvm/ExecutionEngine/Orc/CompileUtils.h
@@ -1,4 +1,4 @@
-//===-- CompileUtils.h - Utilities for compiling IR in the JIT --*- C++ -*-===//
+//===- CompileUtils.h - Utilities for compiling IR in the JIT ---*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,24 +14,47 @@
#ifndef LLVM_EXECUTIONENGINE_ORC_COMPILEUTILS_H
#define LLVM_EXECUTIONENGINE_ORC_COMPILEUTILS_H
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ExecutionEngine/ObjectCache.h"
#include "llvm/ExecutionEngine/ObjectMemoryBuffer.h"
#include "llvm/IR/LegacyPassManager.h"
-#include "llvm/MC/MCContext.h"
+#include "llvm/Object/Binary.h"
#include "llvm/Object/ObjectFile.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetMachine.h"
+#include <algorithm>
+#include <memory>
namespace llvm {
+
+class MCContext;
+class Module;
+
namespace orc {
/// @brief Simple compile functor: Takes a single IR module and returns an
/// ObjectFile.
class SimpleCompiler {
public:
+
+ using CompileResult = object::OwningBinary<object::ObjectFile>;
+
/// @brief Construct a simple compile functor with the given target.
- SimpleCompiler(TargetMachine &TM) : TM(TM) {}
+ SimpleCompiler(TargetMachine &TM, ObjectCache *ObjCache = nullptr)
+ : TM(TM), ObjCache(ObjCache) {}
+
+ /// @brief Set an ObjectCache to query before compiling.
+ void setObjectCache(ObjectCache *NewCache) { ObjCache = NewCache; }
/// @brief Compile a Module to an ObjectFile.
- object::OwningBinary<object::ObjectFile> operator()(Module &M) const {
+ CompileResult operator()(Module &M) {
+ CompileResult CachedObject = tryToLoadFromObjectCache(M);
+ if (CachedObject.getBinary())
+ return CachedObject;
+
SmallVector<char, 0> ObjBufferSV;
raw_svector_ostream ObjStream(ObjBufferSV);
@@ -44,19 +67,47 @@ public:
new ObjectMemoryBuffer(std::move(ObjBufferSV)));
Expected<std::unique_ptr<object::ObjectFile>> Obj =
object::ObjectFile::createObjectFile(ObjBuffer->getMemBufferRef());
- typedef object::OwningBinary<object::ObjectFile> OwningObj;
- if (Obj)
- return OwningObj(std::move(*Obj), std::move(ObjBuffer));
+ if (Obj) {
+ notifyObjectCompiled(M, *ObjBuffer);
+ return CompileResult(std::move(*Obj), std::move(ObjBuffer));
+ }
// TODO: Actually report errors helpfully.
consumeError(Obj.takeError());
- return OwningObj(nullptr, nullptr);
+ return CompileResult(nullptr, nullptr);
}
private:
+
+ CompileResult tryToLoadFromObjectCache(const Module &M) {
+ if (!ObjCache)
+ return CompileResult();
+
+ std::unique_ptr<MemoryBuffer> ObjBuffer = ObjCache->getObject(&M);
+ if (!ObjBuffer)
+ return CompileResult();
+
+ Expected<std::unique_ptr<object::ObjectFile>> Obj =
+ object::ObjectFile::createObjectFile(ObjBuffer->getMemBufferRef());
+ if (!Obj) {
+ // TODO: Actually report errors helpfully.
+ consumeError(Obj.takeError());
+ return CompileResult();
+ }
+
+ return CompileResult(std::move(*Obj), std::move(ObjBuffer));
+ }
+
+ void notifyObjectCompiled(const Module &M, const MemoryBuffer &ObjBuffer) {
+ if (ObjCache)
+ ObjCache->notifyObjectCompiled(&M, ObjBuffer.getMemBufferRef());
+ }
+
TargetMachine &TM;
+ ObjectCache *ObjCache = nullptr;
};
-} // End namespace orc.
-} // End namespace llvm.
+} // end namespace orc
+
+} // end namespace llvm
#endif // LLVM_EXECUTIONENGINE_ORC_COMPILEUTILS_H
diff --git a/contrib/llvm/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h b/contrib/llvm/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h
index a32278b..d9b45c6 100644
--- a/contrib/llvm/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h
+++ b/contrib/llvm/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h
@@ -1,4 +1,4 @@
-//===-- ExecutionUtils.h - Utilities for executing code in Orc --*- C++ -*-===//
+//===- ExecutionUtils.h - Utilities for executing code in Orc ---*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,11 +14,16 @@
#ifndef LLVM_EXECUTIONENGINE_ORC_EXECUTIONUTILS_H
#define LLVM_EXECUTIONENGINE_ORC_EXECUTIONUTILS_H
-#include "llvm/ADT/iterator_range.h"
#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/iterator_range.h"
#include "llvm/ExecutionEngine/JITSymbol.h"
#include "llvm/ExecutionEngine/RuntimeDyld.h"
+#include "llvm/ExecutionEngine/Orc/OrcError.h"
+#include <algorithm>
+#include <cstdint>
+#include <string>
#include <vector>
+#include <utility>
namespace llvm {
@@ -37,7 +42,6 @@ namespace orc {
/// getConstructors/getDestructors functions.
class CtorDtorIterator {
public:
-
/// @brief Accessor for an element of the global_ctors/global_dtors array.
///
/// This class provides a read-only view of the element with any casts on
@@ -89,33 +93,37 @@ iterator_range<CtorDtorIterator> getDestructors(const Module &M);
template <typename JITLayerT>
class CtorDtorRunner {
public:
-
/// @brief Construct a CtorDtorRunner for the given range using the given
/// name mangling function.
CtorDtorRunner(std::vector<std::string> CtorDtorNames,
- typename JITLayerT::ModuleSetHandleT H)
+ typename JITLayerT::ModuleHandleT H)
: CtorDtorNames(std::move(CtorDtorNames)), H(H) {}
/// @brief Run the recorded constructors/destructors through the given JIT
/// layer.
- bool runViaLayer(JITLayerT &JITLayer) const {
- typedef void (*CtorDtorTy)();
+ Error runViaLayer(JITLayerT &JITLayer) const {
+ using CtorDtorTy = void (*)();
- bool Error = false;
for (const auto &CtorDtorName : CtorDtorNames)
if (auto CtorDtorSym = JITLayer.findSymbolIn(H, CtorDtorName, false)) {
- CtorDtorTy CtorDtor =
- reinterpret_cast<CtorDtorTy>(
- static_cast<uintptr_t>(CtorDtorSym.getAddress()));
- CtorDtor();
- } else
- Error = true;
- return !Error;
+ if (auto AddrOrErr = CtorDtorSym.getAddress()) {
+ CtorDtorTy CtorDtor =
+ reinterpret_cast<CtorDtorTy>(static_cast<uintptr_t>(*AddrOrErr));
+ CtorDtor();
+ } else
+ return AddrOrErr.takeError();
+ } else {
+ if (auto Err = CtorDtorSym.takeError())
+ return Err;
+ else
+ return make_error<JITSymbolNotFound>(CtorDtorName);
+ }
+ return Error::success();
}
private:
std::vector<std::string> CtorDtorNames;
- typename JITLayerT::ModuleSetHandleT H;
+ typename JITLayerT::ModuleHandleT H;
};
/// @brief Support class for static dtor execution. For hosted (in-process) JITs
@@ -135,7 +143,6 @@ private:
/// called.
class LocalCXXRuntimeOverrides {
public:
-
/// Create a runtime-overrides class.
template <typename MangleFtorT>
LocalCXXRuntimeOverrides(const MangleFtorT &Mangle) {
@@ -156,7 +163,6 @@ public:
void runDestructors();
private:
-
template <typename PtrTy>
JITTargetAddress toTargetAddress(PtrTy* P) {
return static_cast<JITTargetAddress>(reinterpret_cast<uintptr_t>(P));
@@ -168,15 +174,16 @@ private:
StringMap<JITTargetAddress> CXXRuntimeOverrides;
- typedef void (*DestructorPtr)(void*);
- typedef std::pair<DestructorPtr, void*> CXXDestructorDataPair;
- typedef std::vector<CXXDestructorDataPair> CXXDestructorDataPairList;
+ using DestructorPtr = void (*)(void *);
+ using CXXDestructorDataPair = std::pair<DestructorPtr, void *>;
+ using CXXDestructorDataPairList = std::vector<CXXDestructorDataPair>;
CXXDestructorDataPairList DSOHandleOverride;
static int CXAAtExitOverride(DestructorPtr Destructor, void *Arg,
void *DSOHandle);
};
-} // End namespace orc.
-} // End namespace llvm.
+} // end namespace orc
+
+} // end namespace llvm
#endif // LLVM_EXECUTIONENGINE_ORC_EXECUTIONUTILS_H
diff --git a/contrib/llvm/include/llvm/ExecutionEngine/Orc/GlobalMappingLayer.h b/contrib/llvm/include/llvm/ExecutionEngine/Orc/GlobalMappingLayer.h
index 634d148..ff54ef6 100644
--- a/contrib/llvm/include/llvm/ExecutionEngine/Orc/GlobalMappingLayer.h
+++ b/contrib/llvm/include/llvm/ExecutionEngine/Orc/GlobalMappingLayer.h
@@ -1,4 +1,4 @@
-//===---- GlobalMappingLayer.h - Run all IR through a functor ---*- C++ -*-===//
+//===- GlobalMappingLayer.h - Run all IR through a functor ------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -17,8 +17,14 @@
#include "llvm/ExecutionEngine/JITSymbol.h"
#include <map>
+#include <memory>
+#include <string>
namespace llvm {
+
+class Module;
+class JITSymbolResolver;
+
namespace orc {
/// @brief Global mapping layer.
@@ -31,25 +37,22 @@ namespace orc {
template <typename BaseLayerT>
class GlobalMappingLayer {
public:
- /// @brief Handle to a set of added modules.
- typedef typename BaseLayerT::ModuleSetHandleT ModuleSetHandleT;
+
+ /// @brief Handle to an added module.
+ using ModuleHandleT = typename BaseLayerT::ModuleHandleT;
/// @brief Construct an GlobalMappingLayer with the given BaseLayer
GlobalMappingLayer(BaseLayerT &BaseLayer) : BaseLayer(BaseLayer) {}
- /// @brief Add the given module set to the JIT.
+ /// @brief Add the given module to the JIT.
/// @return A handle for the added modules.
- template <typename ModuleSetT, typename MemoryManagerPtrT,
- typename SymbolResolverPtrT>
- ModuleSetHandleT addModuleSet(ModuleSetT Ms,
- MemoryManagerPtrT MemMgr,
- SymbolResolverPtrT Resolver) {
- return BaseLayer.addModuleSet(std::move(Ms), std::move(MemMgr),
- std::move(Resolver));
+ ModuleHandleT addModule(std::shared_ptr<Module> M,
+ std::shared_ptr<JITSymbolResolver> Resolver) {
+ return BaseLayer.addModule(std::move(M), std::move(Resolver));
}
/// @brief Remove the module set associated with the handle H.
- void removeModuleSet(ModuleSetHandleT H) { BaseLayer.removeModuleSet(H); }
+ void removeModule(ModuleHandleT H) { BaseLayer.removeModule(H); }
/// @brief Manually set the address to return for the given symbol.
void setGlobalMapping(const std::string &Name, JITTargetAddress Addr) {
@@ -77,15 +80,15 @@ public:
return BaseLayer.findSymbol(Name, ExportedSymbolsOnly);
}
- /// @brief Get the address of the given symbol in the context of the set of
- /// modules represented by the handle H. This call is forwarded to the
+ /// @brief Get the address of the given symbol in the context of the of the
+ /// module represented by the handle H. This call is forwarded to the
/// base layer's implementation.
- /// @param H The handle for the module set to search in.
+ /// @param H The handle for the module to search in.
/// @param Name The name of the symbol to search for.
/// @param ExportedSymbolsOnly If true, search only for exported symbols.
/// @return A handle for the given named symbol, if it is found in the
- /// given module set.
- JITSymbol findSymbolIn(ModuleSetHandleT H, const std::string &Name,
+ /// given module.
+ JITSymbol findSymbolIn(ModuleHandleT H, const std::string &Name,
bool ExportedSymbolsOnly) {
return BaseLayer.findSymbolIn(H, Name, ExportedSymbolsOnly);
}
@@ -93,7 +96,7 @@ public:
/// @brief Immediately emit and finalize the module set represented by the
/// given handle.
/// @param H Handle for module set to emit/finalize.
- void emitAndFinalize(ModuleSetHandleT H) {
+ void emitAndFinalize(ModuleHandleT H) {
BaseLayer.emitAndFinalize(H);
}
@@ -102,7 +105,7 @@ private:
std::map<std::string, JITTargetAddress> SymbolTable;
};
-} // End namespace orc.
-} // End namespace llvm.
+} // end namespace orc
+} // end namespace llvm
#endif // LLVM_EXECUTIONENGINE_ORC_GLOBALMAPPINGLAYER_H
diff --git a/contrib/llvm/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h b/contrib/llvm/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h
index f16dd02..fadd334 100644
--- a/contrib/llvm/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h
+++ b/contrib/llvm/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h
@@ -1,4 +1,4 @@
-//===------ IRCompileLayer.h -- Eagerly compile IR for JIT ------*- C++ -*-===//
+//===- IRCompileLayer.h -- Eagerly compile IR for JIT -----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,79 +14,54 @@
#ifndef LLVM_EXECUTIONENGINE_ORC_IRCOMPILELAYER_H
#define LLVM_EXECUTIONENGINE_ORC_IRCOMPILELAYER_H
-#include "llvm/ExecutionEngine/ObjectCache.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ExecutionEngine/JITSymbol.h"
-#include "llvm/Object/ObjectFile.h"
+#include "llvm/Support/Error.h"
#include <memory>
+#include <string>
namespace llvm {
+
+class Module;
+
namespace orc {
/// @brief Eager IR compiling layer.
///
-/// This layer accepts sets of LLVM IR Modules (via addModuleSet). It
-/// immediately compiles each IR module to an object file (each IR Module is
-/// compiled separately). The resulting set of object files is then added to
-/// the layer below, which must implement the object layer concept.
-template <typename BaseLayerT> class IRCompileLayer {
+/// This layer immediately compiles each IR module added via addModule to an
+/// object file and adds this module file to the layer below, which must
+/// implement the object layer concept.
+template <typename BaseLayerT, typename CompileFtor>
+class IRCompileLayer {
public:
- typedef std::function<object::OwningBinary<object::ObjectFile>(Module &)>
- CompileFtor;
-private:
- typedef typename BaseLayerT::ObjSetHandleT ObjSetHandleT;
-
-public:
- /// @brief Handle to a set of compiled modules.
- typedef ObjSetHandleT ModuleSetHandleT;
+ /// @brief Handle to a compiled module.
+ using ModuleHandleT = typename BaseLayerT::ObjHandleT;
/// @brief Construct an IRCompileLayer with the given BaseLayer, which must
/// implement the ObjectLayer concept.
IRCompileLayer(BaseLayerT &BaseLayer, CompileFtor Compile)
- : BaseLayer(BaseLayer), Compile(std::move(Compile)), ObjCache(nullptr) {}
+ : BaseLayer(BaseLayer), Compile(std::move(Compile)) {}
- /// @brief Set an ObjectCache to query before compiling.
- void setObjectCache(ObjectCache *NewCache) { ObjCache = NewCache; }
+ /// @brief Get a reference to the compiler functor.
+ CompileFtor& getCompiler() { return Compile; }
- /// @brief Compile each module in the given module set, then add the resulting
- /// set of objects to the base layer along with the memory manager and
- /// symbol resolver.
+ /// @brief Compile the module, and add the resulting object to the base layer
+ /// along with the given memory manager and symbol resolver.
///
- /// @return A handle for the added modules.
- template <typename ModuleSetT, typename MemoryManagerPtrT,
- typename SymbolResolverPtrT>
- ModuleSetHandleT addModuleSet(ModuleSetT Ms,
- MemoryManagerPtrT MemMgr,
- SymbolResolverPtrT Resolver) {
- std::vector<std::unique_ptr<object::OwningBinary<object::ObjectFile>>>
- Objects;
-
- for (const auto &M : Ms) {
- auto Object =
- llvm::make_unique<object::OwningBinary<object::ObjectFile>>();
-
- if (ObjCache)
- *Object = tryToLoadFromObjectCache(*M);
-
- if (!Object->getBinary()) {
- *Object = Compile(*M);
- if (ObjCache)
- ObjCache->notifyObjectCompiled(&*M,
- Object->getBinary()->getMemoryBufferRef());
- }
-
- Objects.push_back(std::move(Object));
- }
-
- ModuleSetHandleT H =
- BaseLayer.addObjectSet(std::move(Objects), std::move(MemMgr),
- std::move(Resolver));
-
- return H;
+ /// @return A handle for the added module.
+ Expected<ModuleHandleT>
+ addModule(std::shared_ptr<Module> M,
+ std::shared_ptr<JITSymbolResolver> Resolver) {
+ using CompileResult = decltype(Compile(*M));
+ auto Obj = std::make_shared<CompileResult>(Compile(*M));
+ return BaseLayer.addObject(std::move(Obj), std::move(Resolver));
}
- /// @brief Remove the module set associated with the handle H.
- void removeModuleSet(ModuleSetHandleT H) { BaseLayer.removeObjectSet(H); }
+ /// @brief Remove the module associated with the handle H.
+ Error removeModule(ModuleHandleT H) {
+ return BaseLayer.removeObject(H);
+ }
/// @brief Search for the given named symbol.
/// @param Name The name of the symbol to search for.
@@ -96,51 +71,33 @@ public:
return BaseLayer.findSymbol(Name, ExportedSymbolsOnly);
}
- /// @brief Get the address of the given symbol in the context of the set of
- /// compiled modules represented by the handle H. This call is
- /// forwarded to the base layer's implementation.
- /// @param H The handle for the module set to search in.
+ /// @brief Get the address of the given symbol in compiled module represented
+ /// by the handle H. This call is forwarded to the base layer's
+ /// implementation.
+ /// @param H The handle for the module to search in.
/// @param Name The name of the symbol to search for.
/// @param ExportedSymbolsOnly If true, search only for exported symbols.
/// @return A handle for the given named symbol, if it is found in the
- /// given module set.
- JITSymbol findSymbolIn(ModuleSetHandleT H, const std::string &Name,
+ /// given module.
+ JITSymbol findSymbolIn(ModuleHandleT H, const std::string &Name,
bool ExportedSymbolsOnly) {
return BaseLayer.findSymbolIn(H, Name, ExportedSymbolsOnly);
}
- /// @brief Immediately emit and finalize the moduleOB set represented by the
- /// given handle.
- /// @param H Handle for module set to emit/finalize.
- void emitAndFinalize(ModuleSetHandleT H) {
- BaseLayer.emitAndFinalize(H);
+ /// @brief Immediately emit and finalize the module represented by the given
+ /// handle.
+ /// @param H Handle for module to emit/finalize.
+ Error emitAndFinalize(ModuleHandleT H) {
+ return BaseLayer.emitAndFinalize(H);
}
private:
- object::OwningBinary<object::ObjectFile>
- tryToLoadFromObjectCache(const Module &M) {
- std::unique_ptr<MemoryBuffer> ObjBuffer = ObjCache->getObject(&M);
- if (!ObjBuffer)
- return object::OwningBinary<object::ObjectFile>();
-
- Expected<std::unique_ptr<object::ObjectFile>> Obj =
- object::ObjectFile::createObjectFile(ObjBuffer->getMemBufferRef());
- if (!Obj) {
- // TODO: Actually report errors helpfully.
- consumeError(Obj.takeError());
- return object::OwningBinary<object::ObjectFile>();
- }
-
- return object::OwningBinary<object::ObjectFile>(std::move(*Obj),
- std::move(ObjBuffer));
- }
-
BaseLayerT &BaseLayer;
CompileFtor Compile;
- ObjectCache *ObjCache;
};
-} // End namespace orc.
-} // End namespace llvm.
+} // end namespace orc
+
+} // end namespace llvm
#endif // LLVM_EXECUTIONENGINE_ORC_IRCOMPILINGLAYER_H
diff --git a/contrib/llvm/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h b/contrib/llvm/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h
index c67297b..476061a 100644
--- a/contrib/llvm/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h
+++ b/contrib/llvm/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h
@@ -1,4 +1,4 @@
-//===----- IRTransformLayer.h - Run all IR through a functor ----*- C++ -*-===//
+//===- IRTransformLayer.h - Run all IR through a functor --------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -15,46 +15,41 @@
#define LLVM_EXECUTIONENGINE_ORC_IRTRANSFORMLAYER_H
#include "llvm/ExecutionEngine/JITSymbol.h"
+#include <memory>
+#include <string>
namespace llvm {
+class Module;
namespace orc {
/// @brief IR mutating layer.
///
-/// This layer accepts sets of LLVM IR Modules (via addModuleSet). It
-/// immediately applies the user supplied functor to each module, then adds
-/// the set of transformed modules to the layer below.
+/// This layer applies a user supplied transform to each module that is added,
+/// then adds the transformed module to the layer below.
template <typename BaseLayerT, typename TransformFtor>
class IRTransformLayer {
public:
+
/// @brief Handle to a set of added modules.
- typedef typename BaseLayerT::ModuleSetHandleT ModuleSetHandleT;
+ using ModuleHandleT = typename BaseLayerT::ModuleHandleT;
/// @brief Construct an IRTransformLayer with the given BaseLayer
IRTransformLayer(BaseLayerT &BaseLayer,
TransformFtor Transform = TransformFtor())
: BaseLayer(BaseLayer), Transform(std::move(Transform)) {}
- /// @brief Apply the transform functor to each module in the module set, then
- /// add the resulting set of modules to the base layer, along with the
- /// memory manager and symbol resolver.
+ /// @brief Apply the transform functor to the module, then add the module to
+ /// the layer below, along with the memory manager and symbol resolver.
///
/// @return A handle for the added modules.
- template <typename ModuleSetT, typename MemoryManagerPtrT,
- typename SymbolResolverPtrT>
- ModuleSetHandleT addModuleSet(ModuleSetT Ms,
- MemoryManagerPtrT MemMgr,
- SymbolResolverPtrT Resolver) {
-
- for (auto I = Ms.begin(), E = Ms.end(); I != E; ++I)
- *I = Transform(std::move(*I));
-
- return BaseLayer.addModuleSet(std::move(Ms), std::move(MemMgr),
- std::move(Resolver));
+ Expected<ModuleHandleT>
+ addModule(std::shared_ptr<Module> M,
+ std::shared_ptr<JITSymbolResolver> Resolver) {
+ return BaseLayer.addModule(Transform(std::move(M)), std::move(Resolver));
}
- /// @brief Remove the module set associated with the handle H.
- void removeModuleSet(ModuleSetHandleT H) { BaseLayer.removeModuleSet(H); }
+ /// @brief Remove the module associated with the handle H.
+ Error removeModule(ModuleHandleT H) { return BaseLayer.removeModule(H); }
/// @brief Search for the given named symbol.
/// @param Name The name of the symbol to search for.
@@ -64,24 +59,24 @@ public:
return BaseLayer.findSymbol(Name, ExportedSymbolsOnly);
}
- /// @brief Get the address of the given symbol in the context of the set of
- /// modules represented by the handle H. This call is forwarded to the
- /// base layer's implementation.
- /// @param H The handle for the module set to search in.
+ /// @brief Get the address of the given symbol in the context of the module
+ /// represented by the handle H. This call is forwarded to the base
+ /// layer's implementation.
+ /// @param H The handle for the module to search in.
/// @param Name The name of the symbol to search for.
/// @param ExportedSymbolsOnly If true, search only for exported symbols.
/// @return A handle for the given named symbol, if it is found in the
- /// given module set.
- JITSymbol findSymbolIn(ModuleSetHandleT H, const std::string &Name,
+ /// given module.
+ JITSymbol findSymbolIn(ModuleHandleT H, const std::string &Name,
bool ExportedSymbolsOnly) {
return BaseLayer.findSymbolIn(H, Name, ExportedSymbolsOnly);
}
- /// @brief Immediately emit and finalize the module set represented by the
- /// given handle.
- /// @param H Handle for module set to emit/finalize.
- void emitAndFinalize(ModuleSetHandleT H) {
- BaseLayer.emitAndFinalize(H);
+ /// @brief Immediately emit and finalize the module represented by the given
+ /// handle.
+ /// @param H Handle for module to emit/finalize.
+ Error emitAndFinalize(ModuleHandleT H) {
+ return BaseLayer.emitAndFinalize(H);
}
/// @brief Access the transform functor directly.
@@ -95,7 +90,7 @@ private:
TransformFtor Transform;
};
-} // End namespace orc.
-} // End namespace llvm.
+} // end namespace orc
+} // end namespace llvm
#endif // LLVM_EXECUTIONENGINE_ORC_IRTRANSFORMLAYER_H
diff --git a/contrib/llvm/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h b/contrib/llvm/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h
index 07bbd92..e038093 100644
--- a/contrib/llvm/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h
+++ b/contrib/llvm/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h
@@ -1,4 +1,4 @@
-//===-- IndirectionUtils.h - Utilities for adding indirections --*- C++ -*-===//
+//===- IndirectionUtils.h - Utilities for adding indirections ---*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -18,9 +18,6 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/ExecutionEngine/JITSymbol.h"
-#include "llvm/IR/IRBuilder.h"
-#include "llvm/IR/Mangler.h"
-#include "llvm/IR/Module.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/Memory.h"
#include "llvm/Support/Process.h"
@@ -36,12 +33,23 @@
#include <vector>
namespace llvm {
+
+class Constant;
+class Function;
+class FunctionType;
+class GlobalAlias;
+class GlobalVariable;
+class Module;
+class PointerType;
+class Triple;
+class Value;
+
namespace orc {
/// @brief Target-independent base class for compile callback management.
class JITCompileCallbackManager {
public:
- typedef std::function<JITTargetAddress()> CompileFtor;
+ using CompileFtor = std::function<JITTargetAddress()>;
/// @brief Handle to a newly created compile callback. Can be used to get an
/// IR constant representing the address of the trampoline, and to set
@@ -125,7 +133,7 @@ public:
protected:
JITTargetAddress ErrorHandlerAddress;
- typedef std::map<JITTargetAddress, CompileFtor> TrampolineMapT;
+ using TrampolineMapT = std::map<JITTargetAddress, CompileFtor>;
TrampolineMapT ActiveTrampolines;
std::vector<JITTargetAddress> AvailableTrampolines;
@@ -155,7 +163,6 @@ public:
/// process to be used if a compile callback fails.
LocalJITCompileCallbackManager(JITTargetAddress ErrorHandlerAddress)
: JITCompileCallbackManager(ErrorHandlerAddress) {
-
/// Set up the resolver block.
std::error_code EC;
ResolverBlock = sys::OwningMemoryBlock(sys::Memory::allocateMappedMemory(
@@ -220,7 +227,7 @@ private:
class IndirectStubsManager {
public:
/// @brief Map type for initializing the manager. See init.
- typedef StringMap<std::pair<JITTargetAddress, JITSymbolFlags>> StubInitsMap;
+ using StubInitsMap = StringMap<std::pair<JITTargetAddress, JITSymbolFlags>>;
virtual ~IndirectStubsManager() = default;
@@ -336,7 +343,7 @@ private:
}
std::vector<typename TargetT::IndirectStubsInfo> IndirectStubsInfos;
- typedef std::pair<uint16_t, uint16_t> StubKey;
+ using StubKey = std::pair<uint16_t, uint16_t>;
std::vector<StubKey> FreeStubs;
StringMap<std::pair<StubKey, JITSymbolFlags>> StubIndexes;
};
@@ -432,6 +439,7 @@ void cloneModuleFlagsMetadata(Module &Dst, const Module &Src,
ValueToValueMapTy &VMap);
} // end namespace orc
+
} // end namespace llvm
#endif // LLVM_EXECUTIONENGINE_ORC_INDIRECTIONUTILS_H
diff --git a/contrib/llvm/include/llvm/ExecutionEngine/Orc/LambdaResolver.h b/contrib/llvm/include/llvm/ExecutionEngine/Orc/LambdaResolver.h
index cbe2a80..228392a 100644
--- a/contrib/llvm/include/llvm/ExecutionEngine/Orc/LambdaResolver.h
+++ b/contrib/llvm/include/llvm/ExecutionEngine/Orc/LambdaResolver.h
@@ -1,4 +1,4 @@
-//===-- LambdaResolverMM - Redirect symbol lookup via a functor -*- C++ -*-===//
+//===- LambdaResolverMM - Redirect symbol lookup via a functor --*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -16,7 +16,7 @@
#define LLVM_EXECUTIONENGINE_ORC_LAMBDARESOLVER_H
#include "llvm/ADT/STLExtras.h"
-#include "llvm/ExecutionEngine/RuntimeDyld.h"
+#include "llvm/ExecutionEngine/JITSymbol.h"
#include <memory>
namespace llvm {
@@ -25,7 +25,6 @@ namespace orc {
template <typename DylibLookupFtorT, typename ExternalLookupFtorT>
class LambdaResolver : public JITSymbolResolver {
public:
-
LambdaResolver(DylibLookupFtorT DylibLookupFtor,
ExternalLookupFtorT ExternalLookupFtor)
: DylibLookupFtor(DylibLookupFtor),
@@ -46,15 +45,15 @@ private:
template <typename DylibLookupFtorT,
typename ExternalLookupFtorT>
-std::unique_ptr<LambdaResolver<DylibLookupFtorT, ExternalLookupFtorT>>
+std::shared_ptr<LambdaResolver<DylibLookupFtorT, ExternalLookupFtorT>>
createLambdaResolver(DylibLookupFtorT DylibLookupFtor,
ExternalLookupFtorT ExternalLookupFtor) {
- typedef LambdaResolver<DylibLookupFtorT, ExternalLookupFtorT> LR;
+ using LR = LambdaResolver<DylibLookupFtorT, ExternalLookupFtorT>;
return make_unique<LR>(std::move(DylibLookupFtor),
std::move(ExternalLookupFtor));
}
-} // End namespace orc.
-} // End namespace llvm.
+} // end namespace orc
+} // end namespace llvm
#endif // LLVM_EXECUTIONENGINE_ORC_LAMBDARESOLVER_H
diff --git a/contrib/llvm/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h b/contrib/llvm/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h
index 53d4c0c..b7e462e 100644
--- a/contrib/llvm/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h
+++ b/contrib/llvm/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h
@@ -34,19 +34,21 @@ namespace orc {
/// @brief Lazy-emitting IR layer.
///
-/// This layer accepts sets of LLVM IR Modules (via addModuleSet), but does
-/// not immediately emit them the layer below. Instead, emissing to the base
-/// layer is deferred until the first time the client requests the address
-/// (via JITSymbol::getAddress) for a symbol contained in this layer.
+/// This layer accepts LLVM IR Modules (via addModule), but does not
+/// immediately emit them the layer below. Instead, emissing to the base layer
+/// is deferred until the first time the client requests the address (via
+/// JITSymbol::getAddress) for a symbol contained in this layer.
template <typename BaseLayerT> class LazyEmittingLayer {
public:
- typedef typename BaseLayerT::ModuleSetHandleT BaseLayerHandleT;
+
+ using BaseLayerHandleT = typename BaseLayerT::ModuleHandleT;
private:
- class EmissionDeferredSet {
+ class EmissionDeferredModule {
public:
- EmissionDeferredSet() = default;
- virtual ~EmissionDeferredSet() = default;
+ EmissionDeferredModule(std::shared_ptr<Module> M,
+ std::shared_ptr<JITSymbolResolver> Resolver)
+ : M(std::move(M)), Resolver(std::move(Resolver)) {}
JITSymbol find(StringRef Name, bool ExportedSymbolsOnly, BaseLayerT &B) {
switch (EmitState) {
@@ -58,16 +60,24 @@ private:
std::string PName = Name;
JITSymbolFlags Flags = JITSymbolFlags::fromGlobalValue(*GV);
auto GetAddress =
- [this, ExportedSymbolsOnly, PName, &B]() -> JITTargetAddress {
+ [this, ExportedSymbolsOnly, PName, &B]() -> Expected<JITTargetAddress> {
if (this->EmitState == Emitting)
return 0;
else if (this->EmitState == NotEmitted) {
this->EmitState = Emitting;
- Handle = this->emitToBaseLayer(B);
+ if (auto HandleOrErr = this->emitToBaseLayer(B))
+ Handle = std::move(*HandleOrErr);
+ else
+ return HandleOrErr.takeError();
this->EmitState = Emitted;
}
- auto Sym = B.findSymbolIn(Handle, PName, ExportedSymbolsOnly);
- return Sym.getAddress();
+ if (auto Sym = B.findSymbolIn(Handle, PName, ExportedSymbolsOnly))
+ return Sym.getAddress();
+ else if (auto Err = Sym.takeError())
+ return std::move(Err);
+ else
+ llvm_unreachable("Successful symbol lookup should return "
+ "definition address here");
};
return JITSymbol(std::move(GetAddress), Flags);
} else
@@ -84,9 +94,9 @@ private:
llvm_unreachable("Invalid emit-state.");
}
- void removeModulesFromBaseLayer(BaseLayerT &BaseLayer) {
- if (EmitState != NotEmitted)
- BaseLayer.removeModuleSet(Handle);
+ Error removeModuleFromBaseLayer(BaseLayerT& BaseLayer) {
+ return EmitState != NotEmitted ? BaseLayer.removeModule(Handle)
+ : Error::success();
}
void emitAndFinalize(BaseLayerT &BaseLayer) {
@@ -100,35 +110,10 @@ private:
BaseLayer.emitAndFinalize(Handle);
}
- template <typename ModuleSetT, typename MemoryManagerPtrT,
- typename SymbolResolverPtrT>
- static std::unique_ptr<EmissionDeferredSet>
- create(BaseLayerT &B, ModuleSetT Ms, MemoryManagerPtrT MemMgr,
- SymbolResolverPtrT Resolver);
-
- protected:
- virtual const GlobalValue* searchGVs(StringRef Name,
- bool ExportedSymbolsOnly) const = 0;
- virtual BaseLayerHandleT emitToBaseLayer(BaseLayerT &BaseLayer) = 0;
-
private:
- enum { NotEmitted, Emitting, Emitted } EmitState = NotEmitted;
- BaseLayerHandleT Handle;
- };
-
- template <typename ModuleSetT, typename MemoryManagerPtrT,
- typename SymbolResolverPtrT>
- class EmissionDeferredSetImpl : public EmissionDeferredSet {
- public:
- EmissionDeferredSetImpl(ModuleSetT Ms,
- MemoryManagerPtrT MemMgr,
- SymbolResolverPtrT Resolver)
- : Ms(std::move(Ms)), MemMgr(std::move(MemMgr)),
- Resolver(std::move(Resolver)) {}
- protected:
const GlobalValue* searchGVs(StringRef Name,
- bool ExportedSymbolsOnly) const override {
+ bool ExportedSymbolsOnly) const {
// FIXME: We could clean all this up if we had a way to reliably demangle
// names: We could just demangle name and search, rather than
// mangling everything else.
@@ -150,15 +135,13 @@ private:
return buildMangledSymbols(Name, ExportedSymbolsOnly);
}
- BaseLayerHandleT emitToBaseLayer(BaseLayerT &BaseLayer) override {
+ Expected<BaseLayerHandleT> emitToBaseLayer(BaseLayerT &BaseLayer) {
// We don't need the mangled names set any more: Once we've emitted this
// to the base layer we'll just look for symbols there.
MangledSymbols.reset();
- return BaseLayer.addModuleSet(std::move(Ms), std::move(MemMgr),
- std::move(Resolver));
+ return BaseLayer.addModule(std::move(M), std::move(Resolver));
}
- private:
// If the mangled name of the given GlobalValue matches the given search
// name (and its visibility conforms to the ExportedSymbolsOnly flag) then
// return the symbol. Otherwise, add the mangled name to the Names map and
@@ -197,56 +180,55 @@ private:
auto Symbols = llvm::make_unique<StringMap<const GlobalValue*>>();
- for (const auto &M : Ms) {
- Mangler Mang;
+ Mangler Mang;
- for (const auto &GO : M->global_objects())
+ for (const auto &GO : M->global_objects())
if (auto GV = addGlobalValue(*Symbols, GO, Mang, SearchName,
ExportedSymbolsOnly))
return GV;
- }
MangledSymbols = std::move(Symbols);
return nullptr;
}
- ModuleSetT Ms;
- MemoryManagerPtrT MemMgr;
- SymbolResolverPtrT Resolver;
+ enum { NotEmitted, Emitting, Emitted } EmitState = NotEmitted;
+ BaseLayerHandleT Handle;
+ std::shared_ptr<Module> M;
+ std::shared_ptr<JITSymbolResolver> Resolver;
mutable std::unique_ptr<StringMap<const GlobalValue*>> MangledSymbols;
};
- typedef std::list<std::unique_ptr<EmissionDeferredSet>> ModuleSetListT;
+ using ModuleListT = std::list<std::unique_ptr<EmissionDeferredModule>>;
BaseLayerT &BaseLayer;
- ModuleSetListT ModuleSetList;
+ ModuleListT ModuleList;
public:
- /// @brief Handle to a set of loaded modules.
- typedef typename ModuleSetListT::iterator ModuleSetHandleT;
+
+ /// @brief Handle to a loaded module.
+ using ModuleHandleT = typename ModuleListT::iterator;
/// @brief Construct a lazy emitting layer.
LazyEmittingLayer(BaseLayerT &BaseLayer) : BaseLayer(BaseLayer) {}
- /// @brief Add the given set of modules to the lazy emitting layer.
- template <typename ModuleSetT, typename MemoryManagerPtrT,
- typename SymbolResolverPtrT>
- ModuleSetHandleT addModuleSet(ModuleSetT Ms,
- MemoryManagerPtrT MemMgr,
- SymbolResolverPtrT Resolver) {
- return ModuleSetList.insert(
- ModuleSetList.end(),
- EmissionDeferredSet::create(BaseLayer, std::move(Ms), std::move(MemMgr),
- std::move(Resolver)));
+ /// @brief Add the given module to the lazy emitting layer.
+ Expected<ModuleHandleT>
+ addModule(std::shared_ptr<Module> M,
+ std::shared_ptr<JITSymbolResolver> Resolver) {
+ return ModuleList.insert(
+ ModuleList.end(),
+ llvm::make_unique<EmissionDeferredModule>(std::move(M),
+ std::move(Resolver)));
}
- /// @brief Remove the module set represented by the given handle.
+ /// @brief Remove the module represented by the given handle.
///
- /// This method will free the memory associated with the given module set,
- /// both in this layer, and the base layer.
- void removeModuleSet(ModuleSetHandleT H) {
- (*H)->removeModulesFromBaseLayer(BaseLayer);
- ModuleSetList.erase(H);
+ /// This method will free the memory associated with the given module, both
+ /// in this layer, and the base layer.
+ Error removeModule(ModuleHandleT H) {
+ Error Err = (*H)->removeModuleFromBaseLayer(BaseLayer);
+ ModuleList.erase(H);
+ return Err;
}
/// @brief Search for the given named symbol.
@@ -258,45 +240,32 @@ public:
if (auto Symbol = BaseLayer.findSymbol(Name, ExportedSymbolsOnly))
return Symbol;
- // If not found then search the deferred sets. If any of these contain a
+ // If not found then search the deferred modules. If any of these contain a
// definition of 'Name' then they will return a JITSymbol that will emit
// the corresponding module when the symbol address is requested.
- for (auto &DeferredSet : ModuleSetList)
- if (auto Symbol = DeferredSet->find(Name, ExportedSymbolsOnly, BaseLayer))
+ for (auto &DeferredMod : ModuleList)
+ if (auto Symbol = DeferredMod->find(Name, ExportedSymbolsOnly, BaseLayer))
return Symbol;
// If no definition found anywhere return a null symbol.
return nullptr;
}
- /// @brief Get the address of the given symbol in the context of the set of
+ /// @brief Get the address of the given symbol in the context of the of
/// compiled modules represented by the handle H.
- JITSymbol findSymbolIn(ModuleSetHandleT H, const std::string &Name,
+ JITSymbol findSymbolIn(ModuleHandleT H, const std::string &Name,
bool ExportedSymbolsOnly) {
return (*H)->find(Name, ExportedSymbolsOnly, BaseLayer);
}
- /// @brief Immediately emit and finalize the moduleOB set represented by the
- /// given handle.
- /// @param H Handle for module set to emit/finalize.
- void emitAndFinalize(ModuleSetHandleT H) {
- (*H)->emitAndFinalize(BaseLayer);
+ /// @brief Immediately emit and finalize the module represented by the given
+ /// handle.
+ /// @param H Handle for module to emit/finalize.
+ Error emitAndFinalize(ModuleHandleT H) {
+ return (*H)->emitAndFinalize(BaseLayer);
}
};
-template <typename BaseLayerT>
-template <typename ModuleSetT, typename MemoryManagerPtrT,
- typename SymbolResolverPtrT>
-std::unique_ptr<typename LazyEmittingLayer<BaseLayerT>::EmissionDeferredSet>
-LazyEmittingLayer<BaseLayerT>::EmissionDeferredSet::create(
- BaseLayerT &B, ModuleSetT Ms, MemoryManagerPtrT MemMgr,
- SymbolResolverPtrT Resolver) {
- typedef EmissionDeferredSetImpl<ModuleSetT, MemoryManagerPtrT, SymbolResolverPtrT>
- EDS;
- return llvm::make_unique<EDS>(std::move(Ms), std::move(MemMgr),
- std::move(Resolver));
-}
-
} // end namespace orc
} // end namespace llvm
diff --git a/contrib/llvm/include/llvm/ExecutionEngine/Orc/ObjectTransformLayer.h b/contrib/llvm/include/llvm/ExecutionEngine/Orc/ObjectTransformLayer.h
index 173c106..cb47e75 100644
--- a/contrib/llvm/include/llvm/ExecutionEngine/Orc/ObjectTransformLayer.h
+++ b/contrib/llvm/include/llvm/ExecutionEngine/Orc/ObjectTransformLayer.h
@@ -15,20 +15,23 @@
#define LLVM_EXECUTIONENGINE_ORC_OBJECTTRANSFORMLAYER_H
#include "llvm/ExecutionEngine/JITSymbol.h"
+#include <algorithm>
+#include <memory>
+#include <string>
namespace llvm {
namespace orc {
/// @brief Object mutating layer.
///
-/// This layer accepts sets of ObjectFiles (via addObjectSet). It
+/// This layer accepts sets of ObjectFiles (via addObject). It
/// immediately applies the user supplied functor to each object, then adds
/// the set of transformed objects to the layer below.
template <typename BaseLayerT, typename TransformFtor>
class ObjectTransformLayer {
public:
/// @brief Handle to a set of added objects.
- typedef typename BaseLayerT::ObjSetHandleT ObjSetHandleT;
+ using ObjHandleT = typename BaseLayerT::ObjHandleT;
/// @brief Construct an ObjectTransformLayer with the given BaseLayer
ObjectTransformLayer(BaseLayerT &BaseLayer,
@@ -40,20 +43,14 @@ public:
/// memory manager and symbol resolver.
///
/// @return A handle for the added objects.
- template <typename ObjSetT, typename MemoryManagerPtrT,
- typename SymbolResolverPtrT>
- ObjSetHandleT addObjectSet(ObjSetT Objects, MemoryManagerPtrT MemMgr,
- SymbolResolverPtrT Resolver) {
-
- for (auto I = Objects.begin(), E = Objects.end(); I != E; ++I)
- *I = Transform(std::move(*I));
-
- return BaseLayer.addObjectSet(std::move(Objects), std::move(MemMgr),
- std::move(Resolver));
+ template <typename ObjectPtr>
+ Expected<ObjHandleT> addObject(ObjectPtr Obj,
+ std::shared_ptr<JITSymbolResolver> Resolver) {
+ return BaseLayer.addObject(Transform(std::move(Obj)), std::move(Resolver));
}
/// @brief Remove the object set associated with the handle H.
- void removeObjectSet(ObjSetHandleT H) { BaseLayer.removeObjectSet(H); }
+ Error removeObject(ObjHandleT H) { return BaseLayer.removeObject(H); }
/// @brief Search for the given named symbol.
/// @param Name The name of the symbol to search for.
@@ -71,7 +68,7 @@ public:
/// @param ExportedSymbolsOnly If true, search only for exported symbols.
/// @return A handle for the given named symbol, if it is found in the
/// given object set.
- JITSymbol findSymbolIn(ObjSetHandleT H, const std::string &Name,
+ JITSymbol findSymbolIn(ObjHandleT H, const std::string &Name,
bool ExportedSymbolsOnly) {
return BaseLayer.findSymbolIn(H, Name, ExportedSymbolsOnly);
}
@@ -79,10 +76,12 @@ public:
/// @brief Immediately emit and finalize the object set represented by the
/// given handle.
/// @param H Handle for object set to emit/finalize.
- void emitAndFinalize(ObjSetHandleT H) { BaseLayer.emitAndFinalize(H); }
+ Error emitAndFinalize(ObjHandleT H) {
+ return BaseLayer.emitAndFinalize(H);
+ }
/// @brief Map section addresses for the objects associated with the handle H.
- void mapSectionAddress(ObjSetHandleT H, const void *LocalAddress,
+ void mapSectionAddress(ObjHandleT H, const void *LocalAddress,
JITTargetAddress TargetAddr) {
BaseLayer.mapSectionAddress(H, LocalAddress, TargetAddr);
}
@@ -98,7 +97,7 @@ private:
TransformFtor Transform;
};
-} // End namespace orc.
-} // End namespace llvm.
+} // end namespace orc
+} // end namespace llvm
#endif // LLVM_EXECUTIONENGINE_ORC_OBJECTTRANSFORMLAYER_H
diff --git a/contrib/llvm/include/llvm/ExecutionEngine/Orc/OrcABISupport.h b/contrib/llvm/include/llvm/ExecutionEngine/Orc/OrcABISupport.h
index fa236b0..e1b5564 100644
--- a/contrib/llvm/include/llvm/ExecutionEngine/Orc/OrcABISupport.h
+++ b/contrib/llvm/include/llvm/ExecutionEngine/Orc/OrcABISupport.h
@@ -1,4 +1,4 @@
-//===-------------- OrcABISupport.h - ABI support code ---------*- C++ -*-===//
+//===- OrcABISupport.h - ABI support code -----------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -18,9 +18,12 @@
#ifndef LLVM_EXECUTIONENGINE_ORC_ORCABISUPPORT_H
#define LLVM_EXECUTIONENGINE_ORC_ORCABISUPPORT_H
-#include "IndirectionUtils.h"
+#include "llvm/ExecutionEngine/JITSymbol.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Memory.h"
-#include "llvm/Support/Process.h"
+#include <algorithm>
+#include <cstdint>
namespace llvm {
namespace orc {
@@ -37,8 +40,8 @@ public:
static const unsigned TrampolineSize = 1;
static const unsigned ResolverCodeSize = 1;
- typedef JITTargetAddress (*JITReentryFn)(void *CallbackMgr,
- void *TrampolineId);
+ using JITReentryFn = JITTargetAddress (*)(void *CallbackMgr,
+ void *TrampolineId);
static void writeResolverCode(uint8_t *ResolveMem, JITReentryFn Reentry,
void *CallbackMgr) {
@@ -55,6 +58,7 @@ public:
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"); }
@@ -73,13 +77,14 @@ template <unsigned StubSizeVal> class GenericIndirectStubsInfo {
public:
const static unsigned StubSize = StubSizeVal;
- GenericIndirectStubsInfo() : NumStubs(0) {}
+ 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;
@@ -104,7 +109,7 @@ public:
}
private:
- unsigned NumStubs;
+ unsigned NumStubs = 0;
sys::OwningMemoryBlock StubsMem;
};
@@ -114,10 +119,10 @@ public:
static const unsigned TrampolineSize = 12;
static const unsigned ResolverCodeSize = 0x120;
- typedef GenericIndirectStubsInfo<8> IndirectStubsInfo;
+ using IndirectStubsInfo = GenericIndirectStubsInfo<8>;
- typedef JITTargetAddress (*JITReentryFn)(void *CallbackMgr,
- void *TrampolineId);
+ using JITReentryFn = JITTargetAddress (*)(void *CallbackMgr,
+ void *TrampolineId);
/// @brief Write the resolver code into the given memory. The user is be
/// responsible for allocating the memory and setting permissions.
@@ -148,7 +153,7 @@ public:
static const unsigned PointerSize = 8;
static const unsigned TrampolineSize = 8;
- typedef GenericIndirectStubsInfo<8> IndirectStubsInfo;
+ using IndirectStubsInfo = GenericIndirectStubsInfo<8>;
/// @brief Write the requsted number of trampolines into the given memory,
/// which must be big enough to hold 1 pointer, plus NumTrampolines
@@ -172,8 +177,9 @@ public:
class OrcX86_64_SysV : public OrcX86_64_Base {
public:
static const unsigned ResolverCodeSize = 0x6C;
- typedef JITTargetAddress (*JITReentryFn)(void *CallbackMgr,
- void *TrampolineId);
+
+ using JITReentryFn = JITTargetAddress (*)(void *CallbackMgr,
+ void *TrampolineId);
/// @brief Write the resolver code into the given memory. The user is be
/// responsible for allocating the memory and setting permissions.
@@ -187,8 +193,9 @@ public:
class OrcX86_64_Win32 : public OrcX86_64_Base {
public:
static const unsigned ResolverCodeSize = 0x74;
- typedef JITTargetAddress (*JITReentryFn)(void *CallbackMgr,
- void *TrampolineId);
+
+ using JITReentryFn = JITTargetAddress (*)(void *CallbackMgr,
+ void *TrampolineId);
/// @brief Write the resolver code into the given memory. The user is be
/// responsible for allocating the memory and setting permissions.
@@ -205,10 +212,10 @@ public:
static const unsigned TrampolineSize = 8;
static const unsigned ResolverCodeSize = 0x4a;
- typedef GenericIndirectStubsInfo<8> IndirectStubsInfo;
+ using IndirectStubsInfo = GenericIndirectStubsInfo<8>;
- typedef JITTargetAddress (*JITReentryFn)(void *CallbackMgr,
- void *TrampolineId);
+ using JITReentryFn = JITTargetAddress (*)(void *CallbackMgr,
+ void *TrampolineId);
/// @brief Write the resolver code into the given memory. The user is be
/// responsible for allocating the memory and setting permissions.
@@ -231,7 +238,7 @@ public:
unsigned MinStubs, void *InitialPtrVal);
};
-} // End namespace orc.
-} // End namespace llvm.
+} // end namespace orc
+} // end namespace llvm
#endif // LLVM_EXECUTIONENGINE_ORC_ORCABISUPPORT_H
diff --git a/contrib/llvm/include/llvm/ExecutionEngine/Orc/OrcError.h b/contrib/llvm/include/llvm/ExecutionEngine/Orc/OrcError.h
index b74988c..e6374b7 100644
--- a/contrib/llvm/include/llvm/ExecutionEngine/Orc/OrcError.h
+++ b/contrib/llvm/include/llvm/ExecutionEngine/Orc/OrcError.h
@@ -22,18 +22,33 @@ namespace orc {
enum class OrcErrorCode : int {
// RPC Errors
- RemoteAllocatorDoesNotExist = 1,
+ JITSymbolNotFound = 1,
+ RemoteAllocatorDoesNotExist,
RemoteAllocatorIdAlreadyInUse,
RemoteMProtectAddrUnrecognized,
RemoteIndirectStubsOwnerDoesNotExist,
RemoteIndirectStubsOwnerIdAlreadyInUse,
+ RPCConnectionClosed,
+ RPCCouldNotNegotiateFunction,
RPCResponseAbandoned,
UnexpectedRPCCall,
UnexpectedRPCResponse,
- UnknownRPCFunction
+ UnknownErrorCodeFromRemote
};
-Error orcError(OrcErrorCode ErrCode);
+std::error_code orcError(OrcErrorCode ErrCode);
+
+class JITSymbolNotFound : public ErrorInfo<JITSymbolNotFound> {
+public:
+ static char ID;
+
+ JITSymbolNotFound(std::string SymbolName);
+ std::error_code convertToErrorCode() const override;
+ void log(raw_ostream &OS) const override;
+ const std::string &getSymbolName() const;
+private:
+ std::string SymbolName;
+};
} // End namespace orc.
} // End namespace llvm.
diff --git a/contrib/llvm/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h b/contrib/llvm/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h
index 8647db5..da02250 100644
--- a/contrib/llvm/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h
+++ b/contrib/llvm/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h
@@ -1,4 +1,4 @@
-//===---- OrcRemoteTargetClient.h - Orc Remote-target Client ----*- C++ -*-===//
+//===- OrcRemoteTargetClient.h - Orc Remote-target Client -------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -16,9 +16,29 @@
#ifndef LLVM_EXECUTIONENGINE_ORC_ORCREMOTETARGETCLIENT_H
#define LLVM_EXECUTIONENGINE_ORC_ORCREMOTETARGETCLIENT_H
-#include "IndirectionUtils.h"
-#include "OrcRemoteTargetRPCAPI.h"
-#include <system_error>
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ExecutionEngine/JITSymbol.h"
+#include "llvm/ExecutionEngine/Orc/IndirectionUtils.h"
+#include "llvm/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.h"
+#include "llvm/ExecutionEngine/RuntimeDyld.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/Memory.h"
+#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+#include <cassert>
+#include <cstdint>
+#include <memory>
+#include <string>
+#include <tuple>
+#include <utility>
+#include <vector>
#define DEBUG_TYPE "orc-remote"
@@ -143,16 +163,16 @@ public:
void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr,
size_t Size) override {
- UnfinalizedEHFrames.push_back(
- std::make_pair(LoadAddr, static_cast<uint32_t>(Size)));
+ UnfinalizedEHFrames.push_back({LoadAddr, Size});
}
- void deregisterEHFrames(uint8_t *Addr, uint64_t LoadAddr,
- size_t Size) override {
- auto Err = Client.deregisterEHFrames(LoadAddr, Size);
- // FIXME: Add error poll.
- assert(!Err && "Failed to register remote EH frames.");
- (void)Err;
+ void deregisterEHFrames() override {
+ for (auto &Frame : RegisteredEHFrames) {
+ auto Err = Client.deregisterEHFrames(Frame.Addr, Frame.Size);
+ // FIXME: Add error poll.
+ assert(!Err && "Failed to register remote EH frames.");
+ (void)Err;
+ }
}
void notifyObjectLoaded(RuntimeDyld &Dyld,
@@ -206,7 +226,6 @@ public:
DEBUG(dbgs() << "Allocator " << Id << " finalizing:\n");
for (auto &ObjAllocs : Unfinalized) {
-
for (auto &Alloc : ObjAllocs.CodeAllocs) {
DEBUG(dbgs() << " copying code: "
<< static_cast<void *>(Alloc.getLocalAddress()) << " -> "
@@ -319,7 +338,7 @@ public:
Unfinalized.clear();
for (auto &EHFrame : UnfinalizedEHFrames) {
- if (auto Err = Client.registerEHFrames(EHFrame.first, EHFrame.second)) {
+ if (auto Err = Client.registerEHFrames(EHFrame.Addr, EHFrame.Size)) {
// FIXME: Replace this once finalizeMemory can return an Error.
handleAllErrors(std::move(Err), [&](ErrorInfoBase &EIB) {
if (ErrMsg) {
@@ -330,7 +349,8 @@ public:
return false;
}
}
- UnfinalizedEHFrames.clear();
+ RegisteredEHFrames = std::move(UnfinalizedEHFrames);
+ UnfinalizedEHFrames = {};
return false;
}
@@ -386,7 +406,13 @@ public:
ResourceIdMgr::ResourceId Id;
std::vector<ObjectAllocs> Unmapped;
std::vector<ObjectAllocs> Unfinalized;
- std::vector<std::pair<uint64_t, uint32_t>> UnfinalizedEHFrames;
+
+ struct EHFrame {
+ JITTargetAddress Addr;
+ uint64_t Size;
+ };
+ std::vector<EHFrame> UnfinalizedEHFrames;
+ std::vector<EHFrame> RegisteredEHFrames;
};
/// Remote indirect stubs manager.
@@ -461,7 +487,7 @@ public:
OrcRemoteTargetClient &Remote;
ResourceIdMgr::ResourceId Id;
std::vector<RemoteIndirectStubsInfo> RemoteIndirectStubsInfos;
- typedef std::pair<uint16_t, uint16_t> StubKey;
+ using StubKey = std::pair<uint16_t, uint16_t>;
std::vector<StubKey> FreeStubs;
StringMap<std::pair<StubKey, JITSymbolFlags>> StubIndexes;
@@ -702,7 +728,6 @@ private:
Expected<JITTargetAddress> reserveMem(ResourceIdMgr::ResourceId Id,
uint64_t Size, uint32_t Align) {
-
// Check for an 'out-of-band' error, e.g. from an MM destructor.
if (ExistingError)
return std::move(ExistingError);
diff --git a/contrib/llvm/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.h b/contrib/llvm/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.h
index 3086ef0..07ae7f0 100644
--- a/contrib/llvm/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.h
+++ b/contrib/llvm/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.h
@@ -1,4 +1,4 @@
-//===--- OrcRemoteTargetRPCAPI.h - Orc Remote-target RPC API ----*- C++ -*-===//
+//===- OrcRemoteTargetRPCAPI.h - Orc Remote-target RPC API ------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -16,12 +16,13 @@
#ifndef LLVM_EXECUTIONENGINE_ORC_ORCREMOTETARGETRPCAPI_H
#define LLVM_EXECUTIONENGINE_ORC_ORCREMOTETARGETRPCAPI_H
-#include "RPCUtils.h"
-#include "RawByteChannel.h"
#include "llvm/ExecutionEngine/JITSymbol.h"
+#include "llvm/ExecutionEngine/Orc/RPCUtils.h"
+#include "llvm/ExecutionEngine/Orc/RawByteChannel.h"
namespace llvm {
namespace orc {
+
namespace remote {
class DirectBufferWriter {
@@ -72,7 +73,7 @@ public:
return EC;
char *Addr = reinterpret_cast<char *>(static_cast<uintptr_t>(Dst));
- DBW = remote::DirectBufferWriter(0, Dst, Size);
+ DBW = remote::DirectBufferWriter(nullptr, Dst, Size);
return C.readBytes(Addr, Size);
}
@@ -87,7 +88,7 @@ class OrcRemoteTargetRPCAPI
protected:
class ResourceIdMgr {
public:
- typedef uint64_t ResourceId;
+ using ResourceId = uint64_t;
static const ResourceId InvalidId = ~0U;
ResourceId getNext() {
@@ -98,6 +99,7 @@ protected:
}
return NextId++;
}
+
void release(ResourceId I) { FreeIds.push_back(I); }
private:
@@ -261,7 +263,8 @@ public:
};
} // end namespace remote
+
} // end namespace orc
} // end namespace llvm
-#endif
+#endif // LLVM_EXECUTIONENGINE_ORC_ORCREMOTETARGETRPCAPI_H
diff --git a/contrib/llvm/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h b/contrib/llvm/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h
index 506330f..e7b6d64 100644
--- a/contrib/llvm/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h
+++ b/contrib/llvm/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h
@@ -1,4 +1,4 @@
-//===---- OrcRemoteTargetServer.h - Orc Remote-target Server ----*- C++ -*-===//
+//===- OrcRemoteTargetServer.h - Orc Remote-target Server -------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -15,10 +15,9 @@
#ifndef LLVM_EXECUTIONENGINE_ORC_ORCREMOTETARGETSERVER_H
#define LLVM_EXECUTIONENGINE_ORC_ORCREMOTETARGETSERVER_H
-#include "OrcRemoteTargetRPCAPI.h"
#include "llvm/ExecutionEngine/JITSymbol.h"
#include "llvm/ExecutionEngine/Orc/OrcError.h"
-#include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
+#include "llvm/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/Format.h"
@@ -48,20 +47,18 @@ namespace remote {
template <typename ChannelT, typename TargetT>
class OrcRemoteTargetServer : public OrcRemoteTargetRPCAPI {
public:
- typedef std::function<JITTargetAddress(const std::string &Name)>
- SymbolLookupFtor;
+ using SymbolLookupFtor =
+ std::function<JITTargetAddress(const std::string &Name)>;
- typedef std::function<void(uint8_t *Addr, uint32_t Size)>
- EHFrameRegistrationFtor;
+ using EHFrameRegistrationFtor =
+ std::function<void(uint8_t *Addr, uint32_t Size)>;
OrcRemoteTargetServer(ChannelT &Channel, SymbolLookupFtor SymbolLookup,
EHFrameRegistrationFtor EHFramesRegister,
EHFrameRegistrationFtor EHFramesDeregister)
: OrcRemoteTargetRPCAPI(Channel), SymbolLookup(std::move(SymbolLookup)),
EHFramesRegister(std::move(EHFramesRegister)),
- EHFramesDeregister(std::move(EHFramesDeregister)),
- TerminateFlag(false) {
-
+ EHFramesDeregister(std::move(EHFramesDeregister)) {
using ThisT = typename std::remove_reference<decltype(*this)>::type;
addHandler<CallIntVoid>(*this, &ThisT::handleCallIntVoid);
addHandler<CallMain>(*this, &ThisT::handleCallMain);
@@ -106,6 +103,7 @@ private:
struct Allocator {
Allocator() = default;
Allocator(Allocator &&Other) : Allocs(std::move(Other.Allocs)) {}
+
Allocator &operator=(Allocator &&Other) {
Allocs = std::move(Other.Allocs);
return *this;
@@ -132,7 +130,7 @@ private:
Error setProtections(void *block, unsigned Flags) {
auto I = Allocs.find(block);
if (I == Allocs.end())
- return orcError(OrcErrorCode::RemoteMProtectAddrUnrecognized);
+ return errorCodeToError(orcError(OrcErrorCode::RemoteMProtectAddrUnrecognized));
return errorCodeToError(
sys::Memory::protectMappedMemory(I->second, Flags));
}
@@ -153,7 +151,8 @@ private:
}
Expected<int32_t> handleCallIntVoid(JITTargetAddress Addr) {
- typedef int (*IntVoidFnTy)();
+ using IntVoidFnTy = int (*)();
+
IntVoidFnTy Fn =
reinterpret_cast<IntVoidFnTy>(static_cast<uintptr_t>(Addr));
@@ -166,7 +165,7 @@ private:
Expected<int32_t> handleCallMain(JITTargetAddress Addr,
std::vector<std::string> Args) {
- typedef int (*MainFnTy)(int, const char *[]);
+ using MainFnTy = int (*)(int, const char *[]);
MainFnTy Fn = reinterpret_cast<MainFnTy>(static_cast<uintptr_t>(Addr));
int ArgC = Args.size() + 1;
@@ -175,6 +174,12 @@ private:
ArgV[0] = "<jit process>";
for (auto &Arg : Args)
ArgV[Idx++] = Arg.c_str();
+ ArgV[ArgC] = 0;
+ DEBUG(
+ for (int Idx = 0; Idx < ArgC; ++Idx) {
+ llvm::dbgs() << "Arg " << Idx << ": " << ArgV[Idx] << "\n";
+ }
+ );
DEBUG(dbgs() << " Calling " << format("0x%016x", Addr) << "\n");
int Result = Fn(ArgC, ArgV.get());
@@ -184,7 +189,8 @@ private:
}
Error handleCallVoidVoid(JITTargetAddress Addr) {
- typedef void (*VoidVoidFnTy)();
+ using VoidVoidFnTy = void (*)();
+
VoidVoidFnTy Fn =
reinterpret_cast<VoidVoidFnTy>(static_cast<uintptr_t>(Addr));
@@ -198,7 +204,8 @@ private:
Error handleCreateRemoteAllocator(ResourceIdMgr::ResourceId Id) {
auto I = Allocators.find(Id);
if (I != Allocators.end())
- return orcError(OrcErrorCode::RemoteAllocatorIdAlreadyInUse);
+ return errorCodeToError(
+ orcError(OrcErrorCode::RemoteAllocatorIdAlreadyInUse));
DEBUG(dbgs() << " Created allocator " << Id << "\n");
Allocators[Id] = Allocator();
return Error::success();
@@ -207,7 +214,8 @@ private:
Error handleCreateIndirectStubsOwner(ResourceIdMgr::ResourceId Id) {
auto I = IndirectStubsOwners.find(Id);
if (I != IndirectStubsOwners.end())
- return orcError(OrcErrorCode::RemoteIndirectStubsOwnerIdAlreadyInUse);
+ return errorCodeToError(
+ orcError(OrcErrorCode::RemoteIndirectStubsOwnerIdAlreadyInUse));
DEBUG(dbgs() << " Create indirect stubs owner " << Id << "\n");
IndirectStubsOwners[Id] = ISBlockOwnerList();
return Error::success();
@@ -224,7 +232,8 @@ private:
Error handleDestroyRemoteAllocator(ResourceIdMgr::ResourceId Id) {
auto I = Allocators.find(Id);
if (I == Allocators.end())
- return orcError(OrcErrorCode::RemoteAllocatorDoesNotExist);
+ return errorCodeToError(
+ orcError(OrcErrorCode::RemoteAllocatorDoesNotExist));
Allocators.erase(I);
DEBUG(dbgs() << " Destroyed allocator " << Id << "\n");
return Error::success();
@@ -233,7 +242,8 @@ private:
Error handleDestroyIndirectStubsOwner(ResourceIdMgr::ResourceId Id) {
auto I = IndirectStubsOwners.find(Id);
if (I == IndirectStubsOwners.end())
- return orcError(OrcErrorCode::RemoteIndirectStubsOwnerDoesNotExist);
+ return errorCodeToError(
+ orcError(OrcErrorCode::RemoteIndirectStubsOwnerDoesNotExist));
IndirectStubsOwners.erase(I);
return Error::success();
}
@@ -246,7 +256,8 @@ private:
auto StubOwnerItr = IndirectStubsOwners.find(Id);
if (StubOwnerItr == IndirectStubsOwners.end())
- return orcError(OrcErrorCode::RemoteIndirectStubsOwnerDoesNotExist);
+ return errorCodeToError(
+ orcError(OrcErrorCode::RemoteIndirectStubsOwnerDoesNotExist));
typename TargetT::IndirectStubsInfo IS;
if (auto Err =
@@ -361,7 +372,8 @@ private:
uint64_t Size, uint32_t Align) {
auto I = Allocators.find(Id);
if (I == Allocators.end())
- return orcError(OrcErrorCode::RemoteAllocatorDoesNotExist);
+ return errorCodeToError(
+ orcError(OrcErrorCode::RemoteAllocatorDoesNotExist));
auto &Allocator = I->second;
void *LocalAllocAddr = nullptr;
if (auto Err = Allocator.allocate(LocalAllocAddr, Size, Align))
@@ -380,7 +392,8 @@ private:
JITTargetAddress Addr, uint32_t Flags) {
auto I = Allocators.find(Id);
if (I == Allocators.end())
- return orcError(OrcErrorCode::RemoteAllocatorDoesNotExist);
+ return errorCodeToError(
+ orcError(OrcErrorCode::RemoteAllocatorDoesNotExist));
auto &Allocator = I->second;
void *LocalAddr = reinterpret_cast<void *>(static_cast<uintptr_t>(Addr));
DEBUG(dbgs() << " Allocator " << Id << " set permissions on " << LocalAddr
@@ -413,11 +426,11 @@ private:
SymbolLookupFtor SymbolLookup;
EHFrameRegistrationFtor EHFramesRegister, EHFramesDeregister;
std::map<ResourceIdMgr::ResourceId, Allocator> Allocators;
- typedef std::vector<typename TargetT::IndirectStubsInfo> ISBlockOwnerList;
+ using ISBlockOwnerList = std::vector<typename TargetT::IndirectStubsInfo>;
std::map<ResourceIdMgr::ResourceId, ISBlockOwnerList> IndirectStubsOwners;
sys::OwningMemoryBlock ResolverBlock;
std::vector<sys::OwningMemoryBlock> TrampolineBlocks;
- bool TerminateFlag;
+ bool TerminateFlag = false;
};
} // end namespace remote
@@ -426,4 +439,4 @@ private:
#undef DEBUG_TYPE
-#endif
+#endif // LLVM_EXECUTIONENGINE_ORC_ORCREMOTETARGETSERVER_H
diff --git a/contrib/llvm/include/llvm/ExecutionEngine/Orc/RPCSerialization.h b/contrib/llvm/include/llvm/ExecutionEngine/Orc/RPCSerialization.h
index 359a9d8..1cb2448 100644
--- a/contrib/llvm/include/llvm/ExecutionEngine/Orc/RPCSerialization.h
+++ b/contrib/llvm/include/llvm/ExecutionEngine/Orc/RPCSerialization.h
@@ -12,6 +12,7 @@
#include "OrcError.h"
#include "llvm/Support/thread.h"
+#include <map>
#include <mutex>
#include <sstream>
@@ -114,6 +115,35 @@ public:
static const char* getName() { return "std::string"; }
};
+template <>
+class RPCTypeName<Error> {
+public:
+ static const char* getName() { return "Error"; }
+};
+
+template <typename T>
+class RPCTypeName<Expected<T>> {
+public:
+ static const char* getName() {
+ std::lock_guard<std::mutex> Lock(NameMutex);
+ if (Name.empty())
+ raw_string_ostream(Name) << "Expected<"
+ << RPCTypeNameSequence<T>()
+ << ">";
+ return Name.data();
+ }
+
+private:
+ static std::mutex NameMutex;
+ static std::string Name;
+};
+
+template <typename T>
+std::mutex RPCTypeName<Expected<T>>::NameMutex;
+
+template <typename T>
+std::string RPCTypeName<Expected<T>>::Name;
+
template <typename T1, typename T2>
class RPCTypeName<std::pair<T1, T2>> {
public:
@@ -243,8 +273,10 @@ class SequenceSerialization<ChannelT, ArgT> {
public:
template <typename CArgT>
- static Error serialize(ChannelT &C, const CArgT &CArg) {
- return SerializationTraits<ChannelT, ArgT, CArgT>::serialize(C, CArg);
+ static Error serialize(ChannelT &C, CArgT &&CArg) {
+ return SerializationTraits<ChannelT, ArgT,
+ typename std::decay<CArgT>::type>::
+ serialize(C, std::forward<CArgT>(CArg));
}
template <typename CArgT>
@@ -258,19 +290,21 @@ class SequenceSerialization<ChannelT, ArgT, ArgTs...> {
public:
template <typename CArgT, typename... CArgTs>
- static Error serialize(ChannelT &C, const CArgT &CArg,
- const CArgTs&... CArgs) {
+ static Error serialize(ChannelT &C, CArgT &&CArg,
+ CArgTs &&... CArgs) {
if (auto Err =
- SerializationTraits<ChannelT, ArgT, CArgT>::serialize(C, CArg))
+ SerializationTraits<ChannelT, ArgT, typename std::decay<CArgT>::type>::
+ serialize(C, std::forward<CArgT>(CArg)))
return Err;
if (auto Err = SequenceTraits<ChannelT>::emitSeparator(C))
return Err;
- return SequenceSerialization<ChannelT, ArgTs...>::serialize(C, CArgs...);
+ return SequenceSerialization<ChannelT, ArgTs...>::
+ serialize(C, std::forward<CArgTs>(CArgs)...);
}
template <typename CArgT, typename... CArgTs>
static Error deserialize(ChannelT &C, CArgT &CArg,
- CArgTs&... CArgs) {
+ CArgTs &... CArgs) {
if (auto Err =
SerializationTraits<ChannelT, ArgT, CArgT>::deserialize(C, CArg))
return Err;
@@ -281,8 +315,9 @@ public:
};
template <typename ChannelT, typename... ArgTs>
-Error serializeSeq(ChannelT &C, const ArgTs &... Args) {
- return SequenceSerialization<ChannelT, ArgTs...>::serialize(C, Args...);
+Error serializeSeq(ChannelT &C, ArgTs &&... Args) {
+ return SequenceSerialization<ChannelT, typename std::decay<ArgTs>::type...>::
+ serialize(C, std::forward<ArgTs>(Args)...);
}
template <typename ChannelT, typename... ArgTs>
@@ -290,6 +325,207 @@ Error deserializeSeq(ChannelT &C, ArgTs &... Args) {
return SequenceSerialization<ChannelT, ArgTs...>::deserialize(C, Args...);
}
+template <typename ChannelT>
+class SerializationTraits<ChannelT, Error> {
+public:
+
+ using WrappedErrorSerializer =
+ std::function<Error(ChannelT &C, const ErrorInfoBase&)>;
+
+ using WrappedErrorDeserializer =
+ std::function<Error(ChannelT &C, Error &Err)>;
+
+ template <typename ErrorInfoT, typename SerializeFtor,
+ typename DeserializeFtor>
+ static void registerErrorType(std::string Name, SerializeFtor Serialize,
+ DeserializeFtor Deserialize) {
+ assert(!Name.empty() &&
+ "The empty string is reserved for the Success value");
+
+ const std::string *KeyName = nullptr;
+ {
+ // We're abusing the stability of std::map here: We take a reference to the
+ // key of the deserializers map to save us from duplicating the string in
+ // the serializer. This should be changed to use a stringpool if we switch
+ // to a map type that may move keys in memory.
+ std::lock_guard<std::recursive_mutex> Lock(DeserializersMutex);
+ auto I =
+ Deserializers.insert(Deserializers.begin(),
+ std::make_pair(std::move(Name),
+ std::move(Deserialize)));
+ KeyName = &I->first;
+ }
+
+ {
+ assert(KeyName != nullptr && "No keyname pointer");
+ std::lock_guard<std::recursive_mutex> Lock(SerializersMutex);
+ // FIXME: Move capture Serialize once we have C++14.
+ Serializers[ErrorInfoT::classID()] =
+ [KeyName, Serialize](ChannelT &C, const ErrorInfoBase &EIB) -> Error {
+ assert(EIB.dynamicClassID() == ErrorInfoT::classID() &&
+ "Serializer called for wrong error type");
+ if (auto Err = serializeSeq(C, *KeyName))
+ return Err;
+ return Serialize(C, static_cast<const ErrorInfoT&>(EIB));
+ };
+ }
+ }
+
+ static Error serialize(ChannelT &C, Error &&Err) {
+ std::lock_guard<std::recursive_mutex> Lock(SerializersMutex);
+
+ if (!Err)
+ return serializeSeq(C, std::string());
+
+ return handleErrors(std::move(Err),
+ [&C](const ErrorInfoBase &EIB) {
+ auto SI = Serializers.find(EIB.dynamicClassID());
+ if (SI == Serializers.end())
+ return serializeAsStringError(C, EIB);
+ return (SI->second)(C, EIB);
+ });
+ }
+
+ static Error deserialize(ChannelT &C, Error &Err) {
+ std::lock_guard<std::recursive_mutex> Lock(DeserializersMutex);
+
+ std::string Key;
+ if (auto Err = deserializeSeq(C, Key))
+ return Err;
+
+ if (Key.empty()) {
+ ErrorAsOutParameter EAO(&Err);
+ Err = Error::success();
+ return Error::success();
+ }
+
+ auto DI = Deserializers.find(Key);
+ assert(DI != Deserializers.end() && "No deserializer for error type");
+ return (DI->second)(C, Err);
+ }
+
+private:
+
+ static Error serializeAsStringError(ChannelT &C, const ErrorInfoBase &EIB) {
+ std::string ErrMsg;
+ {
+ raw_string_ostream ErrMsgStream(ErrMsg);
+ EIB.log(ErrMsgStream);
+ }
+ return serialize(C, make_error<StringError>(std::move(ErrMsg),
+ inconvertibleErrorCode()));
+ }
+
+ static std::recursive_mutex SerializersMutex;
+ static std::recursive_mutex DeserializersMutex;
+ static std::map<const void*, WrappedErrorSerializer> Serializers;
+ static std::map<std::string, WrappedErrorDeserializer> Deserializers;
+};
+
+template <typename ChannelT>
+std::recursive_mutex SerializationTraits<ChannelT, Error>::SerializersMutex;
+
+template <typename ChannelT>
+std::recursive_mutex SerializationTraits<ChannelT, Error>::DeserializersMutex;
+
+template <typename ChannelT>
+std::map<const void*,
+ typename SerializationTraits<ChannelT, Error>::WrappedErrorSerializer>
+SerializationTraits<ChannelT, Error>::Serializers;
+
+template <typename ChannelT>
+std::map<std::string,
+ typename SerializationTraits<ChannelT, Error>::WrappedErrorDeserializer>
+SerializationTraits<ChannelT, Error>::Deserializers;
+
+/// Registers a serializer and deserializer for the given error type on the
+/// given channel type.
+template <typename ChannelT, typename ErrorInfoT, typename SerializeFtor,
+ typename DeserializeFtor>
+void registerErrorSerialization(std::string Name, SerializeFtor &&Serialize,
+ DeserializeFtor &&Deserialize) {
+ SerializationTraits<ChannelT, Error>::template registerErrorType<ErrorInfoT>(
+ std::move(Name),
+ std::forward<SerializeFtor>(Serialize),
+ std::forward<DeserializeFtor>(Deserialize));
+}
+
+/// Registers serialization/deserialization for StringError.
+template <typename ChannelT>
+void registerStringError() {
+ static bool AlreadyRegistered = false;
+ if (!AlreadyRegistered) {
+ registerErrorSerialization<ChannelT, StringError>(
+ "StringError",
+ [](ChannelT &C, const StringError &SE) {
+ return serializeSeq(C, SE.getMessage());
+ },
+ [](ChannelT &C, Error &Err) -> Error {
+ ErrorAsOutParameter EAO(&Err);
+ std::string Msg;
+ if (auto E2 = deserializeSeq(C, Msg))
+ return E2;
+ Err =
+ make_error<StringError>(std::move(Msg),
+ orcError(
+ OrcErrorCode::UnknownErrorCodeFromRemote));
+ return Error::success();
+ });
+ AlreadyRegistered = true;
+ }
+}
+
+/// SerializationTraits for Expected<T1> from an Expected<T2>.
+template <typename ChannelT, typename T1, typename T2>
+class SerializationTraits<ChannelT, Expected<T1>, Expected<T2>> {
+public:
+
+ static Error serialize(ChannelT &C, Expected<T2> &&ValOrErr) {
+ if (ValOrErr) {
+ if (auto Err = serializeSeq(C, true))
+ return Err;
+ return SerializationTraits<ChannelT, T1, T2>::serialize(C, *ValOrErr);
+ }
+ if (auto Err = serializeSeq(C, false))
+ return Err;
+ return serializeSeq(C, ValOrErr.takeError());
+ }
+
+ static Error deserialize(ChannelT &C, Expected<T2> &ValOrErr) {
+ ExpectedAsOutParameter<T2> EAO(&ValOrErr);
+ bool HasValue;
+ if (auto Err = deserializeSeq(C, HasValue))
+ return Err;
+ if (HasValue)
+ return SerializationTraits<ChannelT, T1, T2>::deserialize(C, *ValOrErr);
+ Error Err = Error::success();
+ if (auto E2 = deserializeSeq(C, Err))
+ return E2;
+ ValOrErr = std::move(Err);
+ return Error::success();
+ }
+};
+
+/// SerializationTraits for Expected<T1> from a T2.
+template <typename ChannelT, typename T1, typename T2>
+class SerializationTraits<ChannelT, Expected<T1>, T2> {
+public:
+
+ static Error serialize(ChannelT &C, T2 &&Val) {
+ return serializeSeq(C, Expected<T2>(std::forward<T2>(Val)));
+ }
+};
+
+/// SerializationTraits for Expected<T1> from an Error.
+template <typename ChannelT, typename T>
+class SerializationTraits<ChannelT, Expected<T>, Error> {
+public:
+
+ static Error serialize(ChannelT &C, Error &&Err) {
+ return serializeSeq(C, Expected<T>(std::move(Err)));
+ }
+};
+
/// SerializationTraits default specialization for std::pair.
template <typename ChannelT, typename T1, typename T2>
class SerializationTraits<ChannelT, std::pair<T1, T2>> {
diff --git a/contrib/llvm/include/llvm/ExecutionEngine/Orc/RPCUtils.h b/contrib/llvm/include/llvm/ExecutionEngine/Orc/RPCUtils.h
index 37e2e66..6212f64 100644
--- a/contrib/llvm/include/llvm/ExecutionEngine/Orc/RPCUtils.h
+++ b/contrib/llvm/include/llvm/ExecutionEngine/Orc/RPCUtils.h
@@ -26,27 +26,115 @@
#include "llvm/ExecutionEngine/Orc/OrcError.h"
#include "llvm/ExecutionEngine/Orc/RPCSerialization.h"
-#ifdef _MSC_VER
-// concrt.h depends on eh.h for __uncaught_exception declaration
-// even if we disable exceptions.
-#include <eh.h>
-
-// Disable warnings from ppltasks.h transitively included by <future>.
-#pragma warning(push)
-#pragma warning(disable : 4530)
-#pragma warning(disable : 4062)
-#endif
-
#include <future>
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
-
namespace llvm {
namespace orc {
namespace rpc {
+/// Base class of all fatal RPC errors (those that necessarily result in the
+/// termination of the RPC session).
+class RPCFatalError : public ErrorInfo<RPCFatalError> {
+public:
+ static char ID;
+};
+
+/// RPCConnectionClosed is returned from RPC operations if the RPC connection
+/// has already been closed due to either an error or graceful disconnection.
+class ConnectionClosed : public ErrorInfo<ConnectionClosed> {
+public:
+ static char ID;
+ std::error_code convertToErrorCode() const override;
+ void log(raw_ostream &OS) const override;
+};
+
+/// BadFunctionCall is returned from handleOne when the remote makes a call with
+/// an unrecognized function id.
+///
+/// This error is fatal because Orc RPC needs to know how to parse a function
+/// call to know where the next call starts, and if it doesn't recognize the
+/// function id it cannot parse the call.
+template <typename FnIdT, typename SeqNoT>
+class BadFunctionCall
+ : public ErrorInfo<BadFunctionCall<FnIdT, SeqNoT>, RPCFatalError> {
+public:
+ static char ID;
+
+ BadFunctionCall(FnIdT FnId, SeqNoT SeqNo)
+ : FnId(std::move(FnId)), SeqNo(std::move(SeqNo)) {}
+
+ std::error_code convertToErrorCode() const override {
+ return orcError(OrcErrorCode::UnexpectedRPCCall);
+ }
+
+ void log(raw_ostream &OS) const override {
+ OS << "Call to invalid RPC function id '" << FnId << "' with "
+ "sequence number " << SeqNo;
+ }
+
+private:
+ FnIdT FnId;
+ SeqNoT SeqNo;
+};
+
+template <typename FnIdT, typename SeqNoT>
+char BadFunctionCall<FnIdT, SeqNoT>::ID = 0;
+
+/// InvalidSequenceNumberForResponse is returned from handleOne when a response
+/// call arrives with a sequence number that doesn't correspond to any in-flight
+/// function call.
+///
+/// This error is fatal because Orc RPC needs to know how to parse the rest of
+/// the response call to know where the next call starts, and if it doesn't have
+/// a result parser for this sequence number it can't do that.
+template <typename SeqNoT>
+class InvalidSequenceNumberForResponse
+ : public ErrorInfo<InvalidSequenceNumberForResponse<SeqNoT>, RPCFatalError> {
+public:
+ static char ID;
+
+ InvalidSequenceNumberForResponse(SeqNoT SeqNo)
+ : SeqNo(std::move(SeqNo)) {}
+
+ std::error_code convertToErrorCode() const override {
+ return orcError(OrcErrorCode::UnexpectedRPCCall);
+ };
+
+ void log(raw_ostream &OS) const override {
+ OS << "Response has unknown sequence number " << SeqNo;
+ }
+private:
+ SeqNoT SeqNo;
+};
+
+template <typename SeqNoT>
+char InvalidSequenceNumberForResponse<SeqNoT>::ID = 0;
+
+/// This non-fatal error will be passed to asynchronous result handlers in place
+/// of a result if the connection goes down before a result returns, or if the
+/// function to be called cannot be negotiated with the remote.
+class ResponseAbandoned : public ErrorInfo<ResponseAbandoned> {
+public:
+ static char ID;
+
+ std::error_code convertToErrorCode() const override;
+ void log(raw_ostream &OS) const override;
+};
+
+/// This error is returned if the remote does not have a handler installed for
+/// the given RPC function.
+class CouldNotNegotiate : public ErrorInfo<CouldNotNegotiate> {
+public:
+ static char ID;
+
+ CouldNotNegotiate(std::string Signature);
+ std::error_code convertToErrorCode() const override;
+ void log(raw_ostream &OS) const override;
+ const std::string &getSignature() const { return Signature; }
+private:
+ std::string Signature;
+};
+
template <typename DerivedFunc, typename FnT> class Function;
// RPC Function class.
@@ -82,16 +170,6 @@ std::mutex Function<DerivedFunc, RetT(ArgTs...)>::NameMutex;
template <typename DerivedFunc, typename RetT, typename... ArgTs>
std::string Function<DerivedFunc, RetT(ArgTs...)>::Name;
-/// Provides a typedef for a tuple containing the decayed argument types.
-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...>;
-};
-
/// Allocates RPC function ids during autonegotiation.
/// Specializations of this class must provide four members:
///
@@ -196,6 +274,16 @@ public:
#endif // _MSC_VER
+/// Provides a typedef for a tuple containing the decayed argument types.
+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...>;
+};
+
// ResultTraits provides typedefs and utilities specific to the return type
// of functions.
template <typename RetT> class ResultTraits {
@@ -274,43 +362,132 @@ template <> class ResultTraits<Error> : public ResultTraits<void> {};
template <typename RetT>
class ResultTraits<Expected<RetT>> : public ResultTraits<RetT> {};
+// Determines whether an RPC function's defined error return type supports
+// error return value.
+template <typename T>
+class SupportsErrorReturn {
+public:
+ static const bool value = false;
+};
+
+template <>
+class SupportsErrorReturn<Error> {
+public:
+ static const bool value = true;
+};
+
+template <typename T>
+class SupportsErrorReturn<Expected<T>> {
+public:
+ static const bool value = true;
+};
+
+// RespondHelper packages return values based on whether or not the declared
+// RPC function return type supports error returns.
+template <bool FuncSupportsErrorReturn>
+class RespondHelper;
+
+// RespondHelper specialization for functions that support error returns.
+template <>
+class RespondHelper<true> {
+public:
+
+ // Send Expected<T>.
+ template <typename WireRetT, typename HandlerRetT, typename ChannelT,
+ typename FunctionIdT, typename SequenceNumberT>
+ static Error sendResult(ChannelT &C, const FunctionIdT &ResponseId,
+ SequenceNumberT SeqNo,
+ Expected<HandlerRetT> ResultOrErr) {
+ if (!ResultOrErr && ResultOrErr.template errorIsA<RPCFatalError>())
+ return ResultOrErr.takeError();
+
+ // Open the response message.
+ if (auto Err = C.startSendMessage(ResponseId, SeqNo))
+ return Err;
+
+ // Serialize the result.
+ if (auto Err =
+ SerializationTraits<ChannelT, WireRetT,
+ Expected<HandlerRetT>>::serialize(
+ C, std::move(ResultOrErr)))
+ return Err;
+
+ // Close the response message.
+ return C.endSendMessage();
+ }
+
+ template <typename ChannelT, typename FunctionIdT, typename SequenceNumberT>
+ static Error sendResult(ChannelT &C, const FunctionIdT &ResponseId,
+ SequenceNumberT SeqNo, Error Err) {
+ if (Err && Err.isA<RPCFatalError>())
+ return Err;
+ if (auto Err2 = C.startSendMessage(ResponseId, SeqNo))
+ return Err2;
+ if (auto Err2 = serializeSeq(C, std::move(Err)))
+ return Err2;
+ return C.endSendMessage();
+ }
+
+};
+
+// RespondHelper specialization for functions that do not support error returns.
+template <>
+class RespondHelper<false> {
+public:
+
+ template <typename WireRetT, typename HandlerRetT, typename ChannelT,
+ typename FunctionIdT, typename SequenceNumberT>
+ static Error sendResult(ChannelT &C, const FunctionIdT &ResponseId,
+ SequenceNumberT SeqNo,
+ Expected<HandlerRetT> ResultOrErr) {
+ if (auto Err = ResultOrErr.takeError())
+ return Err;
+
+ // Open the response message.
+ if (auto Err = C.startSendMessage(ResponseId, SeqNo))
+ return Err;
+
+ // Serialize the result.
+ if (auto Err =
+ SerializationTraits<ChannelT, WireRetT, HandlerRetT>::serialize(
+ C, *ResultOrErr))
+ return Err;
+
+ // Close the response message.
+ return C.endSendMessage();
+ }
+
+ template <typename ChannelT, typename FunctionIdT, typename SequenceNumberT>
+ static Error sendResult(ChannelT &C, const FunctionIdT &ResponseId,
+ SequenceNumberT SeqNo, Error Err) {
+ if (Err)
+ return Err;
+ if (auto Err2 = C.startSendMessage(ResponseId, SeqNo))
+ return Err2;
+ return C.endSendMessage();
+ }
+
+};
+
+
// Send a response of the given wire return type (WireRetT) over the
// channel, with the given sequence number.
template <typename WireRetT, typename HandlerRetT, typename ChannelT,
typename FunctionIdT, typename SequenceNumberT>
-static Error respond(ChannelT &C, const FunctionIdT &ResponseId,
- SequenceNumberT SeqNo, Expected<HandlerRetT> ResultOrErr) {
- // If this was an error bail out.
- // FIXME: Send an "error" message to the client if this is not a channel
- // failure?
- if (auto Err = ResultOrErr.takeError())
- return Err;
-
- // Open the response message.
- if (auto Err = C.startSendMessage(ResponseId, SeqNo))
- return Err;
-
- // Serialize the result.
- if (auto Err =
- SerializationTraits<ChannelT, WireRetT, HandlerRetT>::serialize(
- C, *ResultOrErr))
- return Err;
-
- // Close the response message.
- return C.endSendMessage();
+Error respond(ChannelT &C, const FunctionIdT &ResponseId,
+ SequenceNumberT SeqNo, Expected<HandlerRetT> ResultOrErr) {
+ return RespondHelper<SupportsErrorReturn<WireRetT>::value>::
+ template sendResult<WireRetT>(C, ResponseId, SeqNo, std::move(ResultOrErr));
}
// Send an empty response message on the given channel to indicate that
// the handler ran.
template <typename WireRetT, typename ChannelT, typename FunctionIdT,
typename SequenceNumberT>
-static Error respond(ChannelT &C, const FunctionIdT &ResponseId,
- SequenceNumberT SeqNo, Error Err) {
- if (Err)
- return Err;
- if (auto Err2 = C.startSendMessage(ResponseId, SeqNo))
- return Err2;
- return C.endSendMessage();
+Error respond(ChannelT &C, const FunctionIdT &ResponseId, SequenceNumberT SeqNo,
+ Error Err) {
+ return RespondHelper<SupportsErrorReturn<WireRetT>::value>::
+ sendResult(C, ResponseId, SeqNo, std::move(Err));
}
// Converts a given type to the equivalent error return type.
@@ -339,6 +516,29 @@ public:
using Type = Error;
};
+// Traits class that strips the response function from the list of handler
+// arguments.
+template <typename FnT> class AsyncHandlerTraits;
+
+template <typename ResultT, typename... ArgTs>
+class AsyncHandlerTraits<Error(std::function<Error(Expected<ResultT>)>, ArgTs...)> {
+public:
+ using Type = Error(ArgTs...);
+ using ResultType = Expected<ResultT>;
+};
+
+template <typename... ArgTs>
+class AsyncHandlerTraits<Error(std::function<Error(Error)>, ArgTs...)> {
+public:
+ using Type = Error(ArgTs...);
+ using ResultType = Error;
+};
+
+template <typename ResponseHandlerT, typename... ArgTs>
+class AsyncHandlerTraits<Error(ResponseHandlerT, ArgTs...)> :
+ public AsyncHandlerTraits<Error(typename std::decay<ResponseHandlerT>::type,
+ ArgTs...)> {};
+
// This template class provides utilities related to RPC function handlers.
// The base case applies to non-function types (the template class is
// specialized for function types) and inherits from the appropriate
@@ -358,15 +558,20 @@ public:
// Return type of the handler.
using ReturnType = RetT;
- // A std::tuple wrapping the handler arguments.
- using ArgStorage = typename FunctionArgsTuple<RetT(ArgTs...)>::Type;
-
// Call the given handler with the given arguments.
- template <typename HandlerT>
+ template <typename HandlerT, typename... TArgTs>
static typename WrappedHandlerReturn<RetT>::Type
- unpackAndRun(HandlerT &Handler, ArgStorage &Args) {
+ unpackAndRun(HandlerT &Handler, std::tuple<TArgTs...> &Args) {
return unpackAndRunHelper(Handler, Args,
- llvm::index_sequence_for<ArgTs...>());
+ llvm::index_sequence_for<TArgTs...>());
+ }
+
+ // Call the given handler with the given arguments.
+ template <typename HandlerT, typename ResponderT, typename... TArgTs>
+ static Error unpackAndRunAsync(HandlerT &Handler, ResponderT &Responder,
+ std::tuple<TArgTs...> &Args) {
+ return unpackAndRunAsyncHelper(Handler, Responder, Args,
+ llvm::index_sequence_for<TArgTs...>());
}
// Call the given handler with the given arguments.
@@ -379,11 +584,11 @@ public:
return Error::success();
}
- template <typename HandlerT>
+ template <typename HandlerT, typename... TArgTs>
static typename std::enable_if<
!std::is_void<typename HandlerTraits<HandlerT>::ReturnType>::value,
typename HandlerTraits<HandlerT>::ReturnType>::type
- run(HandlerT &Handler, ArgTs... Args) {
+ run(HandlerT &Handler, TArgTs... Args) {
return Handler(std::move(Args)...);
}
@@ -408,15 +613,31 @@ private:
C, std::get<Indexes>(Args)...);
}
- template <typename HandlerT, size_t... Indexes>
+ template <typename HandlerT, typename ArgTuple, size_t... Indexes>
static typename WrappedHandlerReturn<
typename HandlerTraits<HandlerT>::ReturnType>::Type
- unpackAndRunHelper(HandlerT &Handler, ArgStorage &Args,
+ unpackAndRunHelper(HandlerT &Handler, ArgTuple &Args,
llvm::index_sequence<Indexes...>) {
return run(Handler, std::move(std::get<Indexes>(Args))...);
}
+
+
+ template <typename HandlerT, typename ResponderT, typename ArgTuple,
+ size_t... Indexes>
+ static typename WrappedHandlerReturn<
+ typename HandlerTraits<HandlerT>::ReturnType>::Type
+ unpackAndRunAsyncHelper(HandlerT &Handler, ResponderT &Responder,
+ ArgTuple &Args,
+ llvm::index_sequence<Indexes...>) {
+ return run(Handler, Responder, std::move(std::get<Indexes>(Args))...);
+ }
};
+// Handler traits for free functions.
+template <typename RetT, typename... ArgTs>
+class HandlerTraits<RetT(*)(ArgTs...)>
+ : public HandlerTraits<RetT(ArgTs...)> {};
+
// Handler traits for class methods (especially call operators for lambdas).
template <typename Class, typename RetT, typename... ArgTs>
class HandlerTraits<RetT (Class::*)(ArgTs...)>
@@ -471,7 +692,7 @@ public:
// Create an error instance representing an abandoned response.
static Error createAbandonedResponseError() {
- return orcError(OrcErrorCode::RPCResponseAbandoned);
+ return make_error<ResponseAbandoned>();
}
};
@@ -493,7 +714,7 @@ public:
return Err;
if (auto Err = C.endReceiveMessage())
return Err;
- return Handler(Result);
+ return Handler(std::move(Result));
}
// Abandon this response by calling the handler with an 'abandoned response'
@@ -538,6 +759,72 @@ private:
HandlerT Handler;
};
+template <typename ChannelT, typename FuncRetT, typename HandlerT>
+class ResponseHandlerImpl<ChannelT, Expected<FuncRetT>, HandlerT>
+ : public ResponseHandler<ChannelT> {
+public:
+ ResponseHandlerImpl(HandlerT Handler) : Handler(std::move(Handler)) {}
+
+ // Handle the result by deserializing it from the channel then passing it
+ // to the user defined handler.
+ Error handleResponse(ChannelT &C) override {
+ using HandlerArgType = typename ResponseHandlerArg<
+ typename HandlerTraits<HandlerT>::Type>::ArgType;
+ HandlerArgType Result((typename HandlerArgType::value_type()));
+
+ if (auto Err =
+ SerializationTraits<ChannelT, Expected<FuncRetT>,
+ HandlerArgType>::deserialize(C, Result))
+ return Err;
+ if (auto Err = C.endReceiveMessage())
+ return Err;
+ return Handler(std::move(Result));
+ }
+
+ // Abandon this response by calling the handler with an 'abandoned response'
+ // error.
+ void abandon() override {
+ if (auto Err = Handler(this->createAbandonedResponseError())) {
+ // Handlers should not fail when passed an abandoned response error.
+ report_fatal_error(std::move(Err));
+ }
+ }
+
+private:
+ HandlerT Handler;
+};
+
+template <typename ChannelT, typename HandlerT>
+class ResponseHandlerImpl<ChannelT, Error, HandlerT>
+ : public ResponseHandler<ChannelT> {
+public:
+ ResponseHandlerImpl(HandlerT Handler) : Handler(std::move(Handler)) {}
+
+ // Handle the result by deserializing it from the channel then passing it
+ // to the user defined handler.
+ Error handleResponse(ChannelT &C) override {
+ Error Result = Error::success();
+ if (auto Err =
+ SerializationTraits<ChannelT, Error, Error>::deserialize(C, Result))
+ return Err;
+ if (auto Err = C.endReceiveMessage())
+ return Err;
+ return Handler(std::move(Result));
+ }
+
+ // Abandon this response by calling the handler with an 'abandoned response'
+ // error.
+ void abandon() override {
+ if (auto Err = Handler(this->createAbandonedResponseError())) {
+ // Handlers should not fail when passed an abandoned response error.
+ report_fatal_error(std::move(Err));
+ }
+ }
+
+private:
+ HandlerT Handler;
+};
+
// Create a ResponseHandler from a given user handler.
template <typename ChannelT, typename FuncRetT, typename HandlerT>
std::unique_ptr<ResponseHandler<ChannelT>> createResponseHandler(HandlerT H) {
@@ -758,8 +1045,13 @@ public:
auto NegotiateId = FnIdAllocator.getNegotiateId();
RemoteFunctionIds[OrcRPCNegotiate::getPrototype()] = NegotiateId;
Handlers[NegotiateId] = wrapHandler<OrcRPCNegotiate>(
- [this](const std::string &Name) { return handleNegotiate(Name); },
- LaunchPolicy());
+ [this](const std::string &Name) { return handleNegotiate(Name); });
+ }
+
+
+ /// Negotiate a function id for Func with the other end of the channel.
+ template <typename Func> Error negotiateFunction(bool Retry = false) {
+ return getRemoteFunctionId<Func>(true, Retry).takeError();
}
/// Append a call Func, does not call send on the channel.
@@ -777,14 +1069,12 @@ public:
// Look up the function ID.
FunctionIdT FnId;
- if (auto FnIdOrErr = getRemoteFunctionId<Func>())
+ if (auto FnIdOrErr = getRemoteFunctionId<Func>(LazyAutoNegotiation, false))
FnId = *FnIdOrErr;
else {
- // This isn't a channel error so we don't want to abandon other pending
- // responses, but we still need to run the user handler with an error to
- // let them know the call failed.
- if (auto Err = Handler(orcError(OrcErrorCode::UnknownRPCFunction)))
- report_fatal_error(std::move(Err));
+ // Negotiation failed. Notify the handler then return the negotiate-failed
+ // error.
+ cantFail(Handler(make_error<ResponseAbandoned>()));
return FnIdOrErr.takeError();
}
@@ -807,20 +1097,20 @@ public:
// Open the function call message.
if (auto Err = C.startSendMessage(FnId, SeqNo)) {
abandonPendingResponses();
- return joinErrors(std::move(Err), C.endSendMessage());
+ return Err;
}
// Serialize the call arguments.
if (auto Err = detail::HandlerTraits<typename Func::Type>::serializeArgs(
C, Args...)) {
abandonPendingResponses();
- return joinErrors(std::move(Err), C.endSendMessage());
+ return Err;
}
// Close the function call messagee.
if (auto Err = C.endSendMessage()) {
abandonPendingResponses();
- return std::move(Err);
+ return Err;
}
return Error::success();
@@ -839,8 +1129,10 @@ public:
Error handleOne() {
FunctionIdT FnId;
SequenceNumberT SeqNo;
- if (auto Err = C.startReceiveMessage(FnId, SeqNo))
+ if (auto Err = C.startReceiveMessage(FnId, SeqNo)) {
+ abandonPendingResponses();
return Err;
+ }
if (FnId == ResponseId)
return handleResponse(SeqNo);
auto I = Handlers.find(FnId);
@@ -848,7 +1140,8 @@ public:
return I->second(C, SeqNo);
// else: No handler found. Report error to client?
- return orcError(OrcErrorCode::UnexpectedRPCCall);
+ return make_error<BadFunctionCall<FunctionIdT, SequenceNumberT>>(FnId,
+ SeqNo);
}
/// Helper for handling setter procedures - this method returns a functor that
@@ -887,10 +1180,25 @@ public:
SequenceNumberMgr.reset();
}
+ /// Remove the handler for the given function.
+ /// A handler must currently be registered for this function.
+ template <typename Func>
+ void removeHandler() {
+ auto IdItr = LocalFunctionIds.find(Func::getPrototype());
+ assert(IdItr != LocalFunctionIds.end() &&
+ "Function does not have a registered handler");
+ auto HandlerItr = Handlers.find(IdItr->second);
+ assert(HandlerItr != Handlers.end() &&
+ "Function does not have a registered handler");
+ Handlers.erase(HandlerItr);
+ }
+
+ /// Clear all handlers.
+ void clearHandlers() {
+ Handlers.clear();
+ }
+
protected:
- // The LaunchPolicy type allows a launch policy to be specified when adding
- // a function handler. See addHandlerImpl.
- using LaunchPolicy = std::function<Error(std::function<Error()>)>;
FunctionIdT getInvalidFunctionId() const {
return FnIdAllocator.getInvalidId();
@@ -899,7 +1207,7 @@ protected:
/// Add the given handler to the handler map and make it available for
/// autonegotiation and execution.
template <typename Func, typename HandlerT>
- void addHandlerImpl(HandlerT Handler, LaunchPolicy Launch) {
+ void addHandlerImpl(HandlerT Handler) {
static_assert(detail::RPCArgTypeCheck<
CanDeserializeCheck, typename Func::Type,
@@ -908,8 +1216,22 @@ protected:
FunctionIdT NewFnId = FnIdAllocator.template allocate<Func>();
LocalFunctionIds[Func::getPrototype()] = NewFnId;
- Handlers[NewFnId] =
- wrapHandler<Func>(std::move(Handler), std::move(Launch));
+ Handlers[NewFnId] = wrapHandler<Func>(std::move(Handler));
+ }
+
+ template <typename Func, typename HandlerT>
+ void addAsyncHandlerImpl(HandlerT Handler) {
+
+ static_assert(detail::RPCArgTypeCheck<
+ CanDeserializeCheck, typename Func::Type,
+ typename detail::AsyncHandlerTraits<
+ typename detail::HandlerTraits<HandlerT>::Type
+ >::Type>::value,
+ "");
+
+ FunctionIdT NewFnId = FnIdAllocator.template allocate<Func>();
+ LocalFunctionIds[Func::getPrototype()] = NewFnId;
+ Handlers[NewFnId] = wrapAsyncHandler<Func>(std::move(Handler));
}
Error handleResponse(SequenceNumberT SeqNo) {
@@ -929,7 +1251,8 @@ protected:
// Unlock the pending results map to prevent recursive lock.
Lock.unlock();
abandonPendingResponses();
- return orcError(OrcErrorCode::UnexpectedRPCResponse);
+ return make_error<
+ InvalidSequenceNumberForResponse<SequenceNumberT>>(SeqNo);
}
}
@@ -951,41 +1274,39 @@ protected:
return I->second;
}
- // Find the remote FunctionId for the given function, which must be in the
- // RemoteFunctionIds map.
- template <typename Func> Expected<FunctionIdT> getRemoteFunctionId() {
- // Try to find the id for the given function.
- auto I = RemoteFunctionIds.find(Func::getPrototype());
+ // Find the remote FunctionId for the given function.
+ template <typename Func>
+ Expected<FunctionIdT> getRemoteFunctionId(bool NegotiateIfNotInMap,
+ bool NegotiateIfInvalid) {
+ bool DoNegotiate;
- // If we have it in the map, return it.
- if (I != RemoteFunctionIds.end())
- return I->second;
+ // Check if we already have a function id...
+ auto I = RemoteFunctionIds.find(Func::getPrototype());
+ if (I != RemoteFunctionIds.end()) {
+ // If it's valid there's nothing left to do.
+ if (I->second != getInvalidFunctionId())
+ return I->second;
+ DoNegotiate = NegotiateIfInvalid;
+ } else
+ DoNegotiate = NegotiateIfNotInMap;
- // Otherwise, if we have auto-negotiation enabled, try to negotiate it.
- if (LazyAutoNegotiation) {
+ // We don't have a function id for Func yet, but we're allowed to try to
+ // negotiate one.
+ if (DoNegotiate) {
auto &Impl = static_cast<ImplT &>(*this);
if (auto RemoteIdOrErr =
- Impl.template callB<OrcRPCNegotiate>(Func::getPrototype())) {
- auto &RemoteId = *RemoteIdOrErr;
-
- // If autonegotiation indicates that the remote end doesn't support this
- // function, return an unknown function error.
- if (RemoteId == getInvalidFunctionId())
- return orcError(OrcErrorCode::UnknownRPCFunction);
-
- // Autonegotiation succeeded and returned a valid id. Update the map and
- // return the id.
- RemoteFunctionIds[Func::getPrototype()] = RemoteId;
- return RemoteId;
- } else {
- // Autonegotiation failed. Return the error.
+ Impl.template callB<OrcRPCNegotiate>(Func::getPrototype())) {
+ RemoteFunctionIds[Func::getPrototype()] = *RemoteIdOrErr;
+ if (*RemoteIdOrErr == getInvalidFunctionId())
+ return make_error<CouldNotNegotiate>(Func::getPrototype());
+ return *RemoteIdOrErr;
+ } else
return RemoteIdOrErr.takeError();
- }
}
- // No key was available in the map and autonegotiation wasn't enabled.
- // Return an unknown function error.
- return orcError(OrcErrorCode::UnknownRPCFunction);
+ // No key was available in the map and we weren't allowed to try to
+ // negotiate one, so return an unknown function error.
+ return make_error<CouldNotNegotiate>(Func::getPrototype());
}
using WrappedHandlerFn = std::function<Error(ChannelT &, SequenceNumberT)>;
@@ -993,12 +1314,15 @@ protected:
// Wrap the given user handler in the necessary argument-deserialization code,
// result-serialization code, and call to the launch policy (if present).
template <typename Func, typename HandlerT>
- WrappedHandlerFn wrapHandler(HandlerT Handler, LaunchPolicy Launch) {
- return [this, Handler, Launch](ChannelT &Channel,
- SequenceNumberT SeqNo) mutable -> Error {
+ WrappedHandlerFn wrapHandler(HandlerT Handler) {
+ return [this, Handler](ChannelT &Channel,
+ SequenceNumberT SeqNo) mutable -> Error {
// Start by deserializing the arguments.
- auto Args = std::make_shared<
- typename detail::HandlerTraits<HandlerT>::ArgStorage>();
+ using ArgsTuple =
+ typename detail::FunctionArgsTuple<
+ typename detail::HandlerTraits<HandlerT>::Type>::Type;
+ auto Args = std::make_shared<ArgsTuple>();
+
if (auto Err =
detail::HandlerTraits<typename Func::Type>::deserializeArgs(
Channel, *Args))
@@ -1013,22 +1337,49 @@ protected:
if (auto Err = Channel.endReceiveMessage())
return Err;
- // Build the handler/responder.
- auto Responder = [this, Handler, Args, &Channel,
- SeqNo]() mutable -> Error {
- using HTraits = detail::HandlerTraits<HandlerT>;
- using FuncReturn = typename Func::ReturnType;
- return detail::respond<FuncReturn>(
- Channel, ResponseId, SeqNo, HTraits::unpackAndRun(Handler, *Args));
- };
-
- // If there is an explicit launch policy then use it to launch the
- // handler.
- if (Launch)
- return Launch(std::move(Responder));
-
- // Otherwise run the handler on the listener thread.
- return Responder();
+ using HTraits = detail::HandlerTraits<HandlerT>;
+ using FuncReturn = typename Func::ReturnType;
+ return detail::respond<FuncReturn>(Channel, ResponseId, SeqNo,
+ HTraits::unpackAndRun(Handler, *Args));
+ };
+ }
+
+ // Wrap the given user handler in the necessary argument-deserialization code,
+ // result-serialization code, and call to the launch policy (if present).
+ template <typename Func, typename HandlerT>
+ WrappedHandlerFn wrapAsyncHandler(HandlerT Handler) {
+ return [this, Handler](ChannelT &Channel,
+ SequenceNumberT SeqNo) mutable -> Error {
+ // Start by deserializing the arguments.
+ using AHTraits = detail::AsyncHandlerTraits<
+ typename detail::HandlerTraits<HandlerT>::Type>;
+ using ArgsTuple =
+ typename detail::FunctionArgsTuple<typename AHTraits::Type>::Type;
+ auto Args = std::make_shared<ArgsTuple>();
+
+ if (auto Err =
+ detail::HandlerTraits<typename Func::Type>::deserializeArgs(
+ Channel, *Args))
+ return Err;
+
+ // GCC 4.7 and 4.8 incorrectly issue a -Wunused-but-set-variable warning
+ // for RPCArgs. Void cast RPCArgs to work around this for now.
+ // FIXME: Remove this workaround once we can assume a working GCC version.
+ (void)Args;
+
+ // End receieve message, unlocking the channel for reading.
+ if (auto Err = Channel.endReceiveMessage())
+ return Err;
+
+ using HTraits = detail::HandlerTraits<HandlerT>;
+ using FuncReturn = typename Func::ReturnType;
+ auto Responder =
+ [this, SeqNo](typename AHTraits::ResultType RetVal) -> Error {
+ return detail::respond<FuncReturn>(C, ResponseId, SeqNo,
+ std::move(RetVal));
+ };
+
+ return HTraits::unpackAndRunAsync(Handler, Responder, *Args);
};
}
@@ -1068,66 +1419,31 @@ public:
MultiThreadedRPCEndpoint(ChannelT &C, bool LazyAutoNegotiation)
: BaseClass(C, LazyAutoNegotiation) {}
- /// The LaunchPolicy type allows a launch policy to be specified when adding
- /// a function handler. See addHandler.
- using LaunchPolicy = typename BaseClass::LaunchPolicy;
-
/// Add a handler for the given RPC function.
/// This installs the given handler functor for the given RPC Function, and
/// makes the RPC function available for negotiation/calling from the remote.
- ///
- /// The optional LaunchPolicy argument can be used to control how the handler
- /// is run when called:
- ///
- /// * If no LaunchPolicy is given, the handler code will be run on the RPC
- /// handler thread that is reading from the channel. This handler cannot
- /// make blocking RPC calls (since it would be blocking the thread used to
- /// get the result), but can make non-blocking calls.
- ///
- /// * If a LaunchPolicy is given, the user's handler will be wrapped in a
- /// call to serialize and send the result, and the resulting functor (with
- /// type 'Error()' will be passed to the LaunchPolicy. The user can then
- /// choose to add the wrapped handler to a work queue, spawn a new thread,
- /// or anything else.
template <typename Func, typename HandlerT>
- void addHandler(HandlerT Handler, LaunchPolicy Launch = LaunchPolicy()) {
- return this->template addHandlerImpl<Func>(std::move(Handler),
- std::move(Launch));
+ void addHandler(HandlerT Handler) {
+ return this->template addHandlerImpl<Func>(std::move(Handler));
}
/// Add a class-method as a handler.
template <typename Func, typename ClassT, typename RetT, typename... ArgTs>
- void addHandler(ClassT &Object, RetT (ClassT::*Method)(ArgTs...),
- LaunchPolicy Launch = LaunchPolicy()) {
+ void addHandler(ClassT &Object, RetT (ClassT::*Method)(ArgTs...)) {
addHandler<Func>(
- detail::MemberFnWrapper<ClassT, RetT, ArgTs...>(Object, Method),
- Launch);
+ detail::MemberFnWrapper<ClassT, RetT, ArgTs...>(Object, Method));
}
- /// Negotiate a function id for Func with the other end of the channel.
- template <typename Func> Error negotiateFunction(bool Retry = false) {
- using OrcRPCNegotiate = typename BaseClass::OrcRPCNegotiate;
-
- // Check if we already have a function id...
- auto I = this->RemoteFunctionIds.find(Func::getPrototype());
- if (I != this->RemoteFunctionIds.end()) {
- // If it's valid there's nothing left to do.
- if (I->second != this->getInvalidFunctionId())
- return Error::success();
- // If it's invalid and we can't re-attempt negotiation, throw an error.
- if (!Retry)
- return orcError(OrcErrorCode::UnknownRPCFunction);
- }
+ template <typename Func, typename HandlerT>
+ void addAsyncHandler(HandlerT Handler) {
+ return this->template addAsyncHandlerImpl<Func>(std::move(Handler));
+ }
- // We don't have a function id for Func yet, call the remote to try to
- // negotiate one.
- if (auto RemoteIdOrErr = callB<OrcRPCNegotiate>(Func::getPrototype())) {
- this->RemoteFunctionIds[Func::getPrototype()] = *RemoteIdOrErr;
- if (*RemoteIdOrErr == this->getInvalidFunctionId())
- return orcError(OrcErrorCode::UnknownRPCFunction);
- return Error::success();
- } else
- return RemoteIdOrErr.takeError();
+ /// Add a class-method as a handler.
+ template <typename Func, typename ClassT, typename RetT, typename... ArgTs>
+ void addAsyncHandler(ClassT &Object, RetT (ClassT::*Method)(ArgTs...)) {
+ addAsyncHandler<Func>(
+ detail::MemberFnWrapper<ClassT, RetT, ArgTs...>(Object, Method));
}
/// Return type for non-blocking call primitives.
@@ -1159,7 +1475,6 @@ public:
return Error::success();
},
Args...)) {
- this->abandonPendingResponses();
RTraits::consumeAbandoned(FutureResult.get());
return std::move(Err);
}
@@ -1191,15 +1506,9 @@ public:
typename AltRetT = typename Func::ReturnType>
typename detail::ResultTraits<AltRetT>::ErrorReturnType
callB(const ArgTs &... Args) {
- if (auto FutureResOrErr = callNB<Func>(Args...)) {
- if (auto Err = this->C.send()) {
- this->abandonPendingResponses();
- detail::ResultTraits<typename Func::ReturnType>::consumeAbandoned(
- std::move(FutureResOrErr->get()));
- return std::move(Err);
- }
+ if (auto FutureResOrErr = callNB<Func>(Args...))
return FutureResOrErr->get();
- } else
+ else
return FutureResOrErr.takeError();
}
@@ -1224,16 +1533,13 @@ private:
SingleThreadedRPCEndpoint<ChannelT, FunctionIdT, SequenceNumberT>,
ChannelT, FunctionIdT, SequenceNumberT>;
- using LaunchPolicy = typename BaseClass::LaunchPolicy;
-
public:
SingleThreadedRPCEndpoint(ChannelT &C, bool LazyAutoNegotiation)
: BaseClass(C, LazyAutoNegotiation) {}
template <typename Func, typename HandlerT>
void addHandler(HandlerT Handler) {
- return this->template addHandlerImpl<Func>(std::move(Handler),
- LaunchPolicy());
+ return this->template addHandlerImpl<Func>(std::move(Handler));
}
template <typename Func, typename ClassT, typename RetT, typename... ArgTs>
@@ -1242,30 +1548,16 @@ public:
detail::MemberFnWrapper<ClassT, RetT, ArgTs...>(Object, Method));
}
- /// Negotiate a function id for Func with the other end of the channel.
- template <typename Func> Error negotiateFunction(bool Retry = false) {
- using OrcRPCNegotiate = typename BaseClass::OrcRPCNegotiate;
-
- // Check if we already have a function id...
- auto I = this->RemoteFunctionIds.find(Func::getPrototype());
- if (I != this->RemoteFunctionIds.end()) {
- // If it's valid there's nothing left to do.
- if (I->second != this->getInvalidFunctionId())
- return Error::success();
- // If it's invalid and we can't re-attempt negotiation, throw an error.
- if (!Retry)
- return orcError(OrcErrorCode::UnknownRPCFunction);
- }
+ template <typename Func, typename HandlerT>
+ void addAsyncHandler(HandlerT Handler) {
+ return this->template addAsyncHandlerImpl<Func>(std::move(Handler));
+ }
- // We don't have a function id for Func yet, call the remote to try to
- // negotiate one.
- if (auto RemoteIdOrErr = callB<OrcRPCNegotiate>(Func::getPrototype())) {
- this->RemoteFunctionIds[Func::getPrototype()] = *RemoteIdOrErr;
- if (*RemoteIdOrErr == this->getInvalidFunctionId())
- return orcError(OrcErrorCode::UnknownRPCFunction);
- return Error::success();
- } else
- return RemoteIdOrErr.takeError();
+ /// Add a class-method as a handler.
+ template <typename Func, typename ClassT, typename RetT, typename... ArgTs>
+ void addAsyncHandler(ClassT &Object, RetT (ClassT::*Method)(ArgTs...)) {
+ addAsyncHandler<Func>(
+ detail::MemberFnWrapper<ClassT, RetT, ArgTs...>(Object, Method));
}
template <typename Func, typename... ArgTs,
@@ -1287,7 +1579,6 @@ public:
return Error::success();
},
Args...)) {
- this->abandonPendingResponses();
detail::ResultTraits<typename Func::ReturnType>::consumeAbandoned(
std::move(Result));
return std::move(Err);
@@ -1295,7 +1586,6 @@ public:
while (!ReceivedResponse) {
if (auto Err = this->handleOne()) {
- this->abandonPendingResponses();
detail::ResultTraits<typename Func::ReturnType>::consumeAbandoned(
std::move(Result));
return std::move(Err);
@@ -1306,24 +1596,40 @@ public:
}
};
+/// Asynchronous dispatch for a function on an RPC endpoint.
+template <typename RPCClass, typename Func>
+class RPCAsyncDispatch {
+public:
+ RPCAsyncDispatch(RPCClass &Endpoint) : Endpoint(Endpoint) {}
+
+ template <typename HandlerT, typename... ArgTs>
+ Error operator()(HandlerT Handler, const ArgTs &... Args) const {
+ return Endpoint.template appendCallAsync<Func>(std::move(Handler), Args...);
+ }
+
+private:
+ RPCClass &Endpoint;
+};
+
+/// Construct an asynchronous dispatcher from an RPC endpoint and a Func.
+template <typename Func, typename RPCEndpointT>
+RPCAsyncDispatch<RPCEndpointT, Func> rpcAsyncDispatch(RPCEndpointT &Endpoint) {
+ return RPCAsyncDispatch<RPCEndpointT, Func>(Endpoint);
+}
+
/// \brief Allows a set of asynchrounous calls to be dispatched, and then
/// waited on as a group.
-template <typename RPCClass> class ParallelCallGroup {
+class ParallelCallGroup {
public:
- /// \brief Construct a parallel call group for the given RPC.
- ParallelCallGroup(RPCClass &RPC) : RPC(RPC), NumOutstandingCalls(0) {}
-
+ ParallelCallGroup() = default;
ParallelCallGroup(const ParallelCallGroup &) = delete;
ParallelCallGroup &operator=(const ParallelCallGroup &) = delete;
/// \brief Make as asynchronous call.
- ///
- /// Does not issue a send call to the RPC's channel. The channel may use this
- /// to batch up subsequent calls. A send will automatically be sent when wait
- /// is called.
- template <typename Func, typename HandlerT, typename... ArgTs>
- Error appendCall(HandlerT Handler, const ArgTs &... Args) {
+ template <typename AsyncDispatcher, typename HandlerT, typename... ArgTs>
+ Error call(const AsyncDispatcher &AsyncDispatch, HandlerT Handler,
+ const ArgTs &... Args) {
// Increment the count of outstanding calls. This has to happen before
// we invoke the call, as the handler may (depending on scheduling)
// be run immediately on another thread, and we don't want the decrement
@@ -1346,38 +1652,21 @@ public:
return Err;
};
- return RPC.template appendCallAsync<Func>(std::move(WrappedHandler),
- Args...);
- }
-
- /// \brief Make an asynchronous call.
- ///
- /// The same as appendCall, but also calls send on the channel immediately.
- /// Prefer appendCall if you are about to issue a "wait" call shortly, as
- /// this may allow the channel to better batch the calls.
- template <typename Func, typename HandlerT, typename... ArgTs>
- Error call(HandlerT Handler, const ArgTs &... Args) {
- if (auto Err = appendCall(std::move(Handler), Args...))
- return Err;
- return RPC.sendAppendedCalls();
+ return AsyncDispatch(std::move(WrappedHandler), Args...);
}
/// \brief Blocks until all calls have been completed and their return value
/// handlers run.
- Error wait() {
- if (auto Err = RPC.sendAppendedCalls())
- return Err;
+ void wait() {
std::unique_lock<std::mutex> Lock(M);
while (NumOutstandingCalls > 0)
CV.wait(Lock);
- return Error::success();
}
private:
- RPCClass &RPC;
std::mutex M;
std::condition_variable CV;
- uint32_t NumOutstandingCalls;
+ uint32_t NumOutstandingCalls = 0;
};
/// @brief Convenience class for grouping RPC Functions into APIs that can be
diff --git a/contrib/llvm/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h b/contrib/llvm/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h
index 0588d22..e1016ef 100644
--- a/contrib/llvm/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h
+++ b/contrib/llvm/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h
@@ -1,4 +1,4 @@
-//===- ObjectLinkingLayer.h - Add object files to a JIT process -*- C++ -*-===//
+//===- RTDyldObjectLinkingLayer.h - RTDyld-based jit linking ---*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,24 +7,22 @@
//
//===----------------------------------------------------------------------===//
//
-// Contains the definition for the object layer of the JIT.
+// Contains the definition for an RTDyld-based, in-process object linking layer.
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_EXECUTIONENGINE_ORC_OBJECTLINKINGLAYER_H
-#define LLVM_EXECUTIONENGINE_ORC_OBJECTLINKINGLAYER_H
+#ifndef LLVM_EXECUTIONENGINE_ORC_RTDYLDOBJECTLINKINGLAYER_H
+#define LLVM_EXECUTIONENGINE_ORC_RTDYLDOBJECTLINKINGLAYER_H
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/ExecutionEngine/JITSymbol.h"
#include "llvm/ExecutionEngine/RuntimeDyld.h"
-#include "llvm/ExecutionEngine/SectionMemoryManager.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/Error.h"
-#include <cassert>
#include <algorithm>
+#include <cassert>
#include <functional>
#include <list>
#include <memory>
@@ -35,21 +33,27 @@
namespace llvm {
namespace orc {
-class ObjectLinkingLayerBase {
+class RTDyldObjectLinkingLayerBase {
+public:
+
+ using ObjectPtr =
+ std::shared_ptr<object::OwningBinary<object::ObjectFile>>;
+
protected:
+
/// @brief Holds a set of objects to be allocated/linked as a unit in the JIT.
///
/// An instance of this class will be created for each set of objects added
- /// via JITObjectLayer::addObjectSet. Deleting the instance (via
- /// removeObjectSet) frees its memory, removing all symbol definitions that
+ /// via JITObjectLayer::addObject. Deleting the instance (via
+ /// removeObject) frees its memory, removing all symbol definitions that
/// had been provided by this instance. Higher level layers are responsible
/// for taking any action required to handle the missing symbols.
- class LinkedObjectSet {
+ class LinkedObject {
public:
- LinkedObjectSet() = default;
- LinkedObjectSet(const LinkedObjectSet&) = delete;
- void operator=(const LinkedObjectSet&) = delete;
- virtual ~LinkedObjectSet() = default;
+ LinkedObject() = default;
+ LinkedObject(const LinkedObject&) = delete;
+ void operator=(const LinkedObject&) = delete;
+ virtual ~LinkedObject() = default;
virtual void finalize() = 0;
@@ -76,19 +80,11 @@ protected:
bool Finalized = false;
};
- typedef std::list<std::unique_ptr<LinkedObjectSet>> LinkedObjectSetListT;
+ using LinkedObjectListT = std::list<std::unique_ptr<LinkedObject>>;
public:
/// @brief Handle to a set of loaded objects.
- typedef LinkedObjectSetListT::iterator ObjSetHandleT;
-};
-
-/// @brief Default (no-op) action to perform when loading objects.
-class DoNothingOnNotifyLoaded {
-public:
- template <typename ObjSetT, typename LoadResult>
- void operator()(ObjectLinkingLayerBase::ObjSetHandleT, const ObjSetT &,
- const LoadResult &) {}
+ using ObjHandleT = LinkedObjectListT::iterator;
};
/// @brief Bare bones object linking layer.
@@ -97,42 +93,54 @@ public:
/// object files to be loaded into memory, linked, and the addresses of their
/// symbols queried. All objects added to this layer can see each other's
/// symbols.
-template <typename NotifyLoadedFtor = DoNothingOnNotifyLoaded>
-class ObjectLinkingLayer : public ObjectLinkingLayerBase {
+class RTDyldObjectLinkingLayer : public RTDyldObjectLinkingLayerBase {
public:
+
+ using RTDyldObjectLinkingLayerBase::ObjectPtr;
+
+ /// @brief Functor for receiving object-loaded notifications.
+ using NotifyLoadedFtor = std::function<void(ObjHandleT, const ObjectPtr &Obj,
+ const LoadedObjectInfo &)>;
+
/// @brief Functor for receiving finalization notifications.
- typedef std::function<void(ObjSetHandleT)> NotifyFinalizedFtor;
+ using NotifyFinalizedFtor = std::function<void(ObjHandleT)>;
private:
- template <typename ObjSetT, typename MemoryManagerPtrT,
- typename SymbolResolverPtrT, typename FinalizerFtor>
- class ConcreteLinkedObjectSet : public LinkedObjectSet {
+
+
+ template <typename MemoryManagerPtrT, typename SymbolResolverPtrT,
+ typename FinalizerFtor>
+ class ConcreteLinkedObject : public LinkedObject {
public:
- ConcreteLinkedObjectSet(ObjSetT Objects, MemoryManagerPtrT MemMgr,
- SymbolResolverPtrT Resolver,
- FinalizerFtor Finalizer,
- bool ProcessAllSections)
+ ConcreteLinkedObject(ObjectPtr Obj, MemoryManagerPtrT MemMgr,
+ SymbolResolverPtrT Resolver,
+ FinalizerFtor Finalizer,
+ bool ProcessAllSections)
: MemMgr(std::move(MemMgr)),
- PFC(llvm::make_unique<PreFinalizeContents>(std::move(Objects),
+ PFC(llvm::make_unique<PreFinalizeContents>(std::move(Obj),
std::move(Resolver),
std::move(Finalizer),
ProcessAllSections)) {
- buildInitialSymbolTable(PFC->Objects);
+ buildInitialSymbolTable(PFC->Obj);
}
- void setHandle(ObjSetHandleT H) {
+ ~ConcreteLinkedObject() override {
+ MemMgr->deregisterEHFrames();
+ }
+
+ void setHandle(ObjHandleT H) {
PFC->Handle = H;
}
void finalize() override {
- assert(PFC && "mapSectionAddress called on finalized LinkedObjectSet");
+ assert(PFC && "mapSectionAddress called on finalized LinkedObject");
RuntimeDyld RTDyld(*MemMgr, *PFC->Resolver);
RTDyld.setProcessAllSections(PFC->ProcessAllSections);
PFC->RTDyld = &RTDyld;
this->Finalized = true;
- PFC->Finalizer(PFC->Handle, RTDyld, std::move(PFC->Objects),
+ PFC->Finalizer(PFC->Handle, RTDyld, std::move(PFC->Obj),
[&]() {
this->updateSymbolTable(RTDyld);
});
@@ -154,27 +162,27 @@ private:
void mapSectionAddress(const void *LocalAddress,
JITTargetAddress TargetAddr) const override {
- assert(PFC && "mapSectionAddress called on finalized LinkedObjectSet");
- assert(PFC->RTDyld && "mapSectionAddress called on raw LinkedObjectSet");
+ assert(PFC && "mapSectionAddress called on finalized LinkedObject");
+ assert(PFC->RTDyld && "mapSectionAddress called on raw LinkedObject");
PFC->RTDyld->mapSectionAddress(LocalAddress, TargetAddr);
}
private:
- void buildInitialSymbolTable(const ObjSetT &Objects) {
- for (const auto &Obj : Objects)
- for (auto &Symbol : getObject(*Obj).symbols()) {
- if (Symbol.getFlags() & object::SymbolRef::SF_Undefined)
- continue;
- Expected<StringRef> SymbolName = Symbol.getName();
- // FIXME: Raise an error for bad symbols.
- if (!SymbolName) {
- consumeError(SymbolName.takeError());
- continue;
- }
- auto Flags = JITSymbolFlags::fromObjectSymbol(Symbol);
- SymbolTable.insert(
- std::make_pair(*SymbolName, JITEvaluatedSymbol(0, Flags)));
+
+ void buildInitialSymbolTable(const ObjectPtr &Obj) {
+ for (auto &Symbol : Obj->getBinary()->symbols()) {
+ if (Symbol.getFlags() & object::SymbolRef::SF_Undefined)
+ continue;
+ Expected<StringRef> SymbolName = Symbol.getName();
+ // FIXME: Raise an error for bad symbols.
+ if (!SymbolName) {
+ consumeError(SymbolName.takeError());
+ continue;
}
+ auto Flags = JITSymbolFlags::fromObjectSymbol(Symbol);
+ SymbolTable.insert(
+ std::make_pair(*SymbolName, JITEvaluatedSymbol(0, Flags)));
+ }
}
void updateSymbolTable(const RuntimeDyld &RTDyld) {
@@ -185,17 +193,17 @@ private:
// Contains the information needed prior to finalization: the object files,
// memory manager, resolver, and flags needed for RuntimeDyld.
struct PreFinalizeContents {
- PreFinalizeContents(ObjSetT Objects, SymbolResolverPtrT Resolver,
+ PreFinalizeContents(ObjectPtr Obj, SymbolResolverPtrT Resolver,
FinalizerFtor Finalizer, bool ProcessAllSections)
- : Objects(std::move(Objects)), Resolver(std::move(Resolver)),
+ : Obj(std::move(Obj)), Resolver(std::move(Resolver)),
Finalizer(std::move(Finalizer)),
ProcessAllSections(ProcessAllSections) {}
- ObjSetT Objects;
+ ObjectPtr Obj;
SymbolResolverPtrT Resolver;
FinalizerFtor Finalizer;
bool ProcessAllSections;
- ObjSetHandleT Handle;
+ ObjHandleT Handle;
RuntimeDyld *RTDyld;
};
@@ -203,34 +211,35 @@ private:
std::unique_ptr<PreFinalizeContents> PFC;
};
- template <typename ObjSetT, typename MemoryManagerPtrT,
- typename SymbolResolverPtrT, typename FinalizerFtor>
+ template <typename MemoryManagerPtrT, typename SymbolResolverPtrT,
+ typename FinalizerFtor>
std::unique_ptr<
- ConcreteLinkedObjectSet<ObjSetT, MemoryManagerPtrT,
- SymbolResolverPtrT, FinalizerFtor>>
- createLinkedObjectSet(ObjSetT Objects, MemoryManagerPtrT MemMgr,
- SymbolResolverPtrT Resolver,
- FinalizerFtor Finalizer,
- bool ProcessAllSections) {
- typedef ConcreteLinkedObjectSet<ObjSetT, MemoryManagerPtrT,
- SymbolResolverPtrT, FinalizerFtor> LOS;
- return llvm::make_unique<LOS>(std::move(Objects), std::move(MemMgr),
+ ConcreteLinkedObject<MemoryManagerPtrT, SymbolResolverPtrT, FinalizerFtor>>
+ createLinkedObject(ObjectPtr Obj, MemoryManagerPtrT MemMgr,
+ SymbolResolverPtrT Resolver,
+ FinalizerFtor Finalizer,
+ bool ProcessAllSections) {
+ using LOS = ConcreteLinkedObject<MemoryManagerPtrT, SymbolResolverPtrT,
+ FinalizerFtor>;
+ return llvm::make_unique<LOS>(std::move(Obj), std::move(MemMgr),
std::move(Resolver), std::move(Finalizer),
ProcessAllSections);
}
public:
- /// @brief LoadedObjectInfo list. Contains a list of owning pointers to
- /// RuntimeDyld::LoadedObjectInfo instances.
- typedef std::vector<std::unique_ptr<RuntimeDyld::LoadedObjectInfo>>
- LoadedObjInfoList;
+
+ /// @brief Functor for creating memory managers.
+ using MemoryManagerGetter =
+ std::function<std::shared_ptr<RuntimeDyld::MemoryManager>()>;
/// @brief Construct an ObjectLinkingLayer with the given NotifyLoaded,
/// and NotifyFinalized functors.
- ObjectLinkingLayer(
+ RTDyldObjectLinkingLayer(
+ MemoryManagerGetter GetMemMgr,
NotifyLoadedFtor NotifyLoaded = NotifyLoadedFtor(),
NotifyFinalizedFtor NotifyFinalized = NotifyFinalizedFtor())
- : NotifyLoaded(std::move(NotifyLoaded)),
+ : GetMemMgr(GetMemMgr),
+ NotifyLoaded(std::move(NotifyLoaded)),
NotifyFinalized(std::move(NotifyFinalized)),
ProcessAllSections(false) {}
@@ -249,23 +258,18 @@ public:
///
/// @return A handle that can be used to refer to the loaded objects (for
/// symbol searching, finalization, freeing memory, etc.).
- template <typename ObjSetT,
- typename MemoryManagerPtrT,
- typename SymbolResolverPtrT>
- ObjSetHandleT addObjectSet(ObjSetT Objects,
- MemoryManagerPtrT MemMgr,
- SymbolResolverPtrT Resolver) {
- auto Finalizer = [&](ObjSetHandleT H, RuntimeDyld &RTDyld,
- const ObjSetT &Objs,
+ Expected<ObjHandleT> addObject(ObjectPtr Obj,
+ std::shared_ptr<JITSymbolResolver> Resolver) {
+ auto Finalizer = [&](ObjHandleT H, RuntimeDyld &RTDyld,
+ const ObjectPtr &ObjToLoad,
std::function<void()> LOSHandleLoad) {
- LoadedObjInfoList LoadedObjInfos;
-
- for (auto &Obj : Objs)
- LoadedObjInfos.push_back(RTDyld.loadObject(this->getObject(*Obj)));
+ std::unique_ptr<RuntimeDyld::LoadedObjectInfo> Info =
+ RTDyld.loadObject(*ObjToLoad->getBinary());
LOSHandleLoad();
- this->NotifyLoaded(H, Objs, LoadedObjInfos);
+ if (this->NotifyLoaded)
+ this->NotifyLoaded(H, ObjToLoad, *Info);
RTDyld.finalizeWithMemoryManagerLocking();
@@ -273,17 +277,16 @@ public:
this->NotifyFinalized(H);
};
- auto LOS =
- createLinkedObjectSet(std::move(Objects), std::move(MemMgr),
- std::move(Resolver), std::move(Finalizer),
- ProcessAllSections);
+ auto LO =
+ createLinkedObject(std::move(Obj), GetMemMgr(),
+ std::move(Resolver), std::move(Finalizer),
+ ProcessAllSections);
// LOS is an owning-ptr. Keep a non-owning one so that we can set the handle
// below.
- auto *LOSPtr = LOS.get();
+ auto *LOPtr = LO.get();
- ObjSetHandleT Handle = LinkedObjSetList.insert(LinkedObjSetList.end(),
- std::move(LOS));
- LOSPtr->setHandle(Handle);
+ ObjHandleT Handle = LinkedObjList.insert(LinkedObjList.end(), std::move(LO));
+ LOPtr->setHandle(Handle);
return Handle;
}
@@ -296,9 +299,10 @@ public:
/// indirectly) will result in undefined behavior. If dependence tracking is
/// required to detect or resolve such issues it should be added at a higher
/// layer.
- void removeObjectSet(ObjSetHandleT H) {
+ Error removeObject(ObjHandleT H) {
// How do we invalidate the symbols in H?
- LinkedObjSetList.erase(H);
+ LinkedObjList.erase(H);
+ return Error::success();
}
/// @brief Search for the given named symbol.
@@ -306,7 +310,7 @@ public:
/// @param ExportedSymbolsOnly If true, search only for exported symbols.
/// @return A handle for the given named symbol, if it exists.
JITSymbol findSymbol(StringRef Name, bool ExportedSymbolsOnly) {
- for (auto I = LinkedObjSetList.begin(), E = LinkedObjSetList.end(); I != E;
+ for (auto I = LinkedObjList.begin(), E = LinkedObjList.end(); I != E;
++I)
if (auto Symbol = findSymbolIn(I, Name, ExportedSymbolsOnly))
return Symbol;
@@ -321,13 +325,13 @@ public:
/// @param ExportedSymbolsOnly If true, search only for exported symbols.
/// @return A handle for the given named symbol, if it is found in the
/// given object set.
- JITSymbol findSymbolIn(ObjSetHandleT H, StringRef Name,
+ JITSymbol findSymbolIn(ObjHandleT H, StringRef Name,
bool ExportedSymbolsOnly) {
return (*H)->getSymbol(Name, ExportedSymbolsOnly);
}
/// @brief Map section addresses for the objects associated with the handle H.
- void mapSectionAddress(ObjSetHandleT H, const void *LocalAddress,
+ void mapSectionAddress(ObjHandleT H, const void *LocalAddress,
JITTargetAddress TargetAddr) {
(*H)->mapSectionAddress(LocalAddress, TargetAddr);
}
@@ -335,28 +339,21 @@ public:
/// @brief Immediately emit and finalize the object set represented by the
/// given handle.
/// @param H Handle for object set to emit/finalize.
- void emitAndFinalize(ObjSetHandleT H) {
+ Error emitAndFinalize(ObjHandleT H) {
(*H)->finalize();
+ return Error::success();
}
private:
- static const object::ObjectFile& getObject(const object::ObjectFile &Obj) {
- return Obj;
- }
-
- template <typename ObjT>
- static const object::ObjectFile&
- getObject(const object::OwningBinary<ObjT> &Obj) {
- return *Obj.getBinary();
- }
- LinkedObjectSetListT LinkedObjSetList;
+ LinkedObjectListT LinkedObjList;
+ MemoryManagerGetter GetMemMgr;
NotifyLoadedFtor NotifyLoaded;
NotifyFinalizedFtor NotifyFinalized;
- bool ProcessAllSections;
+ bool ProcessAllSections = false;
};
} // end namespace orc
} // end namespace llvm
-#endif // LLVM_EXECUTIONENGINE_ORC_OBJECTLINKINGLAYER_H
+#endif // LLVM_EXECUTIONENGINE_ORC_RTDYLDOBJECTLINKINGLAYER_H
diff --git a/contrib/llvm/include/llvm/ExecutionEngine/Orc/RawByteChannel.h b/contrib/llvm/include/llvm/ExecutionEngine/Orc/RawByteChannel.h
index 3b6c84e..db810f4 100644
--- a/contrib/llvm/include/llvm/ExecutionEngine/Orc/RawByteChannel.h
+++ b/contrib/llvm/include/llvm/ExecutionEngine/Orc/RawByteChannel.h
@@ -10,20 +10,14 @@
#ifndef LLVM_EXECUTIONENGINE_ORC_RAWBYTECHANNEL_H
#define LLVM_EXECUTIONENGINE_ORC_RAWBYTECHANNEL_H
-#include "OrcError.h"
-#include "RPCSerialization.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/ExecutionEngine/Orc/RPCSerialization.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/Error.h"
-#include <cstddef>
#include <cstdint>
#include <mutex>
#include <string>
-#include <tuple>
#include <type_traits>
-#include <vector>
namespace llvm {
namespace orc {
@@ -32,7 +26,7 @@ namespace rpc {
/// Interface for byte-streams to be used with RPC.
class RawByteChannel {
public:
- virtual ~RawByteChannel() {}
+ virtual ~RawByteChannel() = default;
/// Read Size bytes from the stream into *Dst.
virtual Error readBytes(char *Dst, unsigned Size) = 0;
@@ -48,7 +42,11 @@ public:
template <typename FunctionIdT, typename SequenceIdT>
Error startSendMessage(const FunctionIdT &FnId, const SequenceIdT &SeqNo) {
writeLock.lock();
- return serializeSeq(*this, FnId, SeqNo);
+ if (auto Err = serializeSeq(*this, FnId, SeqNo)) {
+ writeLock.unlock();
+ return Err;
+ }
+ return Error::success();
}
/// Notify the channel that we're ending a message send.
@@ -63,7 +61,11 @@ public:
template <typename FunctionIdT, typename SequenceNumberT>
Error startReceiveMessage(FunctionIdT &FnId, SequenceNumberT &SeqNo) {
readLock.lock();
- return deserializeSeq(*this, FnId, SeqNo);
+ if (auto Err = deserializeSeq(*this, FnId, SeqNo)) {
+ readLock.unlock();
+ return Err;
+ }
+ return Error::success();
}
/// Notify the channel that we're ending a message receive.
@@ -113,11 +115,19 @@ class SerializationTraits<ChannelT, bool, bool,
RawByteChannel, ChannelT>::value>::type> {
public:
static Error serialize(ChannelT &C, bool V) {
- return C.appendBytes(reinterpret_cast<const char *>(&V), 1);
+ uint8_t Tmp = V ? 1 : 0;
+ if (auto Err =
+ C.appendBytes(reinterpret_cast<const char *>(&Tmp), 1))
+ return Err;
+ return Error::success();
}
static Error deserialize(ChannelT &C, bool &V) {
- return C.readBytes(reinterpret_cast<char *>(&V), 1);
+ uint8_t Tmp = 0;
+ if (auto Err = C.readBytes(reinterpret_cast<char *>(&Tmp), 1))
+ return Err;
+ V = Tmp != 0;
+ return Error::success();
}
};
@@ -134,10 +144,12 @@ public:
}
};
-template <typename ChannelT>
-class SerializationTraits<ChannelT, std::string, const char *,
- typename std::enable_if<std::is_base_of<
- RawByteChannel, ChannelT>::value>::type> {
+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> {
public:
static Error serialize(RawByteChannel &C, const char *S) {
return SerializationTraits<ChannelT, std::string, StringRef>::serialize(C,
diff --git a/contrib/llvm/include/llvm/ExecutionEngine/RTDyldMemoryManager.h b/contrib/llvm/include/llvm/ExecutionEngine/RTDyldMemoryManager.h
index 5638717..0c1862c 100644
--- a/contrib/llvm/include/llvm/ExecutionEngine/RTDyldMemoryManager.h
+++ b/contrib/llvm/include/llvm/ExecutionEngine/RTDyldMemoryManager.h
@@ -14,10 +14,10 @@
#ifndef LLVM_EXECUTIONENGINE_RTDYLDMEMORYMANAGER_H
#define LLVM_EXECUTIONENGINE_RTDYLDMEMORYMANAGER_H
+#include "llvm-c/ExecutionEngine.h"
#include "llvm/ExecutionEngine/JITSymbol.h"
#include "llvm/ExecutionEngine/RuntimeDyld.h"
#include "llvm/Support/CBindingWrapping.h"
-#include "llvm-c/ExecutionEngine.h"
#include <cstddef>
#include <cstdint>
#include <string>
@@ -69,13 +69,8 @@ public:
/// Deregister EH frames in the current proces.
static void deregisterEHFramesInProcess(uint8_t *Addr, size_t Size);
- void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size) override {
- registerEHFramesInProcess(Addr, Size);
- }
-
- void deregisterEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size) override {
- deregisterEHFramesInProcess(Addr, Size);
- }
+ void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size) override;
+ void deregisterEHFrames() override;
/// This method returns the address of the specified function or variable in
/// the current process.
@@ -139,6 +134,14 @@ public:
/// MCJIT or RuntimeDyld. Use getSymbolAddress instead.
virtual void *getPointerToNamedFunction(const std::string &Name,
bool AbortOnFailure = true);
+
+protected:
+ struct EHFrame {
+ uint8_t *Addr;
+ size_t Size;
+ };
+ typedef std::vector<EHFrame> EHFrameInfos;
+ EHFrameInfos EHFrames;
};
// Create wrappers for C Binding types (see CBindingWrapping.h).
diff --git a/contrib/llvm/include/llvm/ExecutionEngine/RuntimeDyld.h b/contrib/llvm/include/llvm/ExecutionEngine/RuntimeDyld.h
index 13a5f99..56aa04c 100644
--- a/contrib/llvm/include/llvm/ExecutionEngine/RuntimeDyld.h
+++ b/contrib/llvm/include/llvm/ExecutionEngine/RuntimeDyld.h
@@ -1,4 +1,4 @@
-//===-- RuntimeDyld.h - Run-time dynamic linker for MC-JIT ------*- C++ -*-===//
+//===- RuntimeDyld.h - Run-time dynamic linker for MC-JIT -------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -32,7 +32,9 @@
namespace llvm {
namespace object {
- template <typename T> class OwningBinary;
+
+template <typename T> class OwningBinary;
+
} // end namespace object
/// Base class for errors originating in RuntimeDyld, e.g. missing relocation
@@ -51,8 +53,8 @@ private:
std::string ErrMsg;
};
-class RuntimeDyldImpl;
class RuntimeDyldCheckerImpl;
+class RuntimeDyldImpl;
class RuntimeDyld {
friend class RuntimeDyldCheckerImpl;
@@ -68,7 +70,7 @@ public:
friend class RuntimeDyldImpl;
public:
- typedef std::map<object::SectionRef, unsigned> ObjSectionToIDMap;
+ using ObjSectionToIDMap = std::map<object::SectionRef, unsigned>;
LoadedObjectInfo(RuntimeDyldImpl &RTDyld, ObjSectionToIDMap ObjSecToIDMap)
: RTDyld(RTDyld), ObjSecToIDMap(std::move(ObjSecToIDMap)) {}
@@ -86,21 +88,6 @@ public:
ObjSectionToIDMap ObjSecToIDMap;
};
- template <typename Derived> struct LoadedObjectInfoHelper : LoadedObjectInfo {
- protected:
- LoadedObjectInfoHelper(const LoadedObjectInfoHelper &) = default;
- LoadedObjectInfoHelper() = default;
-
- public:
- LoadedObjectInfoHelper(RuntimeDyldImpl &RTDyld,
- LoadedObjectInfo::ObjSectionToIDMap ObjSecToIDMap)
- : LoadedObjectInfo(RTDyld, std::move(ObjSecToIDMap)) {}
-
- std::unique_ptr<llvm::LoadedObjectInfo> clone() const override {
- return llvm::make_unique<Derived>(static_cast<const Derived &>(*this));
- }
- };
-
/// \brief Memory Management.
class MemoryManager {
friend class RuntimeDyld;
@@ -150,8 +137,7 @@ public:
/// be the case for local execution) these two values will be the same.
virtual void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr,
size_t Size) = 0;
- virtual void deregisterEHFrames(uint8_t *addr, uint64_t LoadAddr,
- size_t Size) = 0;
+ virtual void deregisterEHFrames() = 0;
/// This method is called when object loading is complete and section page
/// permissions can be applied. It is up to the memory manager implementation
@@ -187,7 +173,7 @@ public:
/// \brief Construct a RuntimeDyld instance.
RuntimeDyld(MemoryManager &MemMgr, JITSymbolResolver &Resolver);
RuntimeDyld(const RuntimeDyld &) = delete;
- void operator=(const RuntimeDyld &) = delete;
+ RuntimeDyld &operator=(const RuntimeDyld &) = delete;
~RuntimeDyld();
/// Add the referenced object file to the list of objects to be loaded and
diff --git a/contrib/llvm/include/llvm/ExecutionEngine/RuntimeDyldChecker.h b/contrib/llvm/include/llvm/ExecutionEngine/RuntimeDyldChecker.h
index f5f52b5..de89f40 100644
--- a/contrib/llvm/include/llvm/ExecutionEngine/RuntimeDyldChecker.h
+++ b/contrib/llvm/include/llvm/ExecutionEngine/RuntimeDyldChecker.h
@@ -10,6 +10,8 @@
#ifndef LLVM_EXECUTIONENGINE_RUNTIMEDYLDCHECKER_H
#define LLVM_EXECUTIONENGINE_RUNTIMEDYLDCHECKER_H
+#include "llvm/ADT/Optional.h"
+
#include <cstdint>
#include <memory>
#include <string>
@@ -97,6 +99,10 @@ public:
StringRef SectionName,
bool LocalAddress);
+ /// \brief If there is a section at the given local address, return its load
+ /// address, otherwise return none.
+ Optional<uint64_t> getSectionLoadAddress(void *LocalAddress) const;
+
private:
std::unique_ptr<RuntimeDyldCheckerImpl> Impl;
};
diff --git a/contrib/llvm/include/llvm/IR/Argument.h b/contrib/llvm/include/llvm/IR/Argument.h
index d8b280a..497dca4 100644
--- a/contrib/llvm/include/llvm/IR/Argument.h
+++ b/contrib/llvm/include/llvm/IR/Argument.h
@@ -21,128 +21,106 @@
namespace llvm {
-template <typename NodeTy> class SymbolTableListTraits;
-
-/// \brief LLVM Argument representation
-///
/// This class represents an incoming formal argument to a Function. A formal
/// argument, since it is ``formal'', does not contain an actual value but
/// instead represents the type, argument number, and attributes of an argument
/// for a specific function. When used in the body of said function, the
/// argument of course represents the value of the actual argument that the
/// function was called with.
-class Argument : public Value, public ilist_node<Argument> {
- virtual void anchor();
+class Argument final : public Value {
Function *Parent;
+ unsigned ArgNo;
- friend class SymbolTableListTraits<Argument>;
+ friend class Function;
void setParent(Function *parent);
public:
- /// \brief Constructor.
- ///
- /// If \p F is specified, the argument is inserted at the end of the argument
- /// list for \p F.
- explicit Argument(Type *Ty, const Twine &Name = "", Function *F = nullptr);
+ /// Argument constructor.
+ explicit Argument(Type *Ty, const Twine &Name = "", Function *F = nullptr,
+ unsigned ArgNo = 0);
inline const Function *getParent() const { return Parent; }
inline Function *getParent() { return Parent; }
- /// \brief Return the index of this formal argument in its containing
- /// function.
+ /// Return the index of this formal argument in its containing function.
///
/// For example in "void foo(int a, float b)" a is 0 and b is 1.
- unsigned getArgNo() const;
+ unsigned getArgNo() const {
+ assert(Parent && "can't get number of unparented arg");
+ return ArgNo;
+ }
- /// \brief Return true if this argument has the nonnull attribute on it in
- /// its containing function. Also returns true if at least one byte is known
- /// to be dereferenceable and the pointer is in addrspace(0).
+ /// Return true if this argument has the nonnull attribute. Also returns true
+ /// if at least one byte is known to be dereferenceable and the pointer is in
+ /// addrspace(0).
bool hasNonNullAttr() const;
- /// \brief If this argument has the dereferenceable attribute on it in its
- /// containing function, return the number of bytes known to be
- /// dereferenceable. Otherwise, zero is returned.
+ /// If this argument has the dereferenceable attribute, return the number of
+ /// bytes known to be dereferenceable. Otherwise, zero is returned.
uint64_t getDereferenceableBytes() const;
- /// \brief If this argument has the dereferenceable_or_null attribute on
- /// it in its containing function, return the number of bytes known to be
- /// dereferenceable. Otherwise, zero is returned.
+ /// If this argument has the dereferenceable_or_null attribute, return the
+ /// number of bytes known to be dereferenceable. Otherwise, zero is returned.
uint64_t getDereferenceableOrNullBytes() const;
- /// \brief Return true if this argument has the byval attribute on it in its
- /// containing function.
+ /// Return true if this argument has the byval attribute.
bool hasByValAttr() const;
- /// \brief Return true if this argument has the swiftself attribute.
+ /// Return true if this argument has the swiftself attribute.
bool hasSwiftSelfAttr() const;
- /// \brief Return true if this argument has the swifterror attribute.
+ /// Return true if this argument has the swifterror attribute.
bool hasSwiftErrorAttr() const;
- /// \brief Return true if this argument has the byval attribute or inalloca
- /// attribute on it in its containing function. These attributes both
- /// represent arguments being passed by value.
+ /// Return true if this argument has the byval attribute or inalloca
+ /// attribute. These attributes represent arguments being passed by value.
bool hasByValOrInAllocaAttr() const;
- /// \brief If this is a byval or inalloca argument, return its alignment.
+ /// If this is a byval or inalloca argument, return its alignment.
unsigned getParamAlignment() const;
- /// \brief Return true if this argument has the nest attribute on it in its
- /// containing function.
+ /// Return true if this argument has the nest attribute.
bool hasNestAttr() const;
- /// \brief Return true if this argument has the noalias attribute on it in its
- /// containing function.
+ /// Return true if this argument has the noalias attribute.
bool hasNoAliasAttr() const;
- /// \brief Return true if this argument has the nocapture attribute on it in
- /// its containing function.
+ /// Return true if this argument has the nocapture attribute.
bool hasNoCaptureAttr() const;
- /// \brief Return true if this argument has the sret attribute on it in its
- /// containing function.
+ /// Return true if this argument has the sret attribute.
bool hasStructRetAttr() const;
- /// \brief Return true if this argument has the returned attribute on it in
- /// its containing function.
+ /// Return true if this argument has the returned attribute.
bool hasReturnedAttr() const;
- /// \brief Return true if this argument has the readonly or readnone attribute
- /// on it in its containing function.
+ /// Return true if this argument has the readonly or readnone attribute.
bool onlyReadsMemory() const;
- /// \brief Return true if this argument has the inalloca attribute on it in
- /// its containing function.
+ /// Return true if this argument has the inalloca attribute.
bool hasInAllocaAttr() const;
- /// \brief Return true if this argument has the zext attribute on it in its
- /// containing function.
+ /// Return true if this argument has the zext attribute.
bool hasZExtAttr() const;
- /// \brief Return true if this argument has the sext attribute on it in its
- /// containing function.
+ /// Return true if this argument has the sext attribute.
bool hasSExtAttr() const;
- /// \brief Add a Attribute to an argument.
- void addAttr(AttributeSet AS);
+ /// Add attributes to an argument.
+ void addAttrs(AttrBuilder &B);
- void addAttr(Attribute::AttrKind Kind) {
- addAttr(AttributeSet::get(getContext(), getArgNo() + 1, Kind));
- }
+ void addAttr(Attribute::AttrKind Kind);
- /// \brief Remove a Attribute from an argument.
- void removeAttr(AttributeSet AS);
+ void addAttr(Attribute Attr);
- void removeAttr(Attribute::AttrKind Kind) {
- removeAttr(AttributeSet::get(getContext(), getArgNo() + 1, Kind));
- }
+ /// Remove attributes from an argument.
+ void removeAttr(Attribute::AttrKind Kind);
- /// \brief Checks if an argument has a given attribute.
+ /// Check if an argument has a given attribute.
bool hasAttribute(Attribute::AttrKind Kind) const;
- /// \brief Method for support type inquiry through isa, cast, and
- /// dyn_cast.
- static inline bool classof(const Value *V) {
+ /// Method for support type inquiry through isa, cast, and dyn_cast.
+ static bool classof(const Value *V) {
return V->getValueID() == ArgumentVal;
}
};
diff --git a/contrib/llvm/include/llvm/IR/Attributes.h b/contrib/llvm/include/llvm/IR/Attributes.h
index 1578385..0cab8bb 100644
--- a/contrib/llvm/include/llvm/IR/Attributes.h
+++ b/contrib/llvm/include/llvm/IR/Attributes.h
@@ -1,4 +1,4 @@
-//===-- llvm/Attributes.h - Container for Attributes ------------*- C++ -*-===//
+//===- llvm/Attributes.h - Container for Attributes -------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -16,24 +16,27 @@
#ifndef LLVM_IR_ATTRIBUTES_H
#define LLVM_IR_ATTRIBUTES_H
+#include "llvm-c/Types.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/Optional.h"
-#include "llvm/Support/Compiler.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/iterator_range.h"
#include "llvm/Support/PointerLikeTypeTraits.h"
-#include "llvm-c/Types.h"
#include <bitset>
#include <cassert>
+#include <cstdint>
#include <map>
#include <string>
+#include <utility>
namespace llvm {
class AttrBuilder;
class AttributeImpl;
-class AttributeSetImpl;
+class AttributeListImpl;
+class AttributeList;
class AttributeSetNode;
-class Constant;
template<typename T> struct DenseMapInfo;
class Function;
class LLVMContext;
@@ -73,11 +76,12 @@ public:
};
private:
- AttributeImpl *pImpl;
+ AttributeImpl *pImpl = nullptr;
+
Attribute(AttributeImpl *A) : pImpl(A) {}
public:
- Attribute() : pImpl(nullptr) {}
+ Attribute() = default;
//===--------------------------------------------------------------------===//
// Attribute Construction
@@ -194,130 +198,327 @@ inline Attribute unwrap(LLVMAttributeRef Attr) {
//===----------------------------------------------------------------------===//
/// \class
+/// This class holds the attributes for a particular argument, parameter,
+/// function, or return value. It is an immutable value type that is cheap to
+/// copy. Adding and removing enum attributes is intended to be fast, but adding
+/// and removing string or integer attributes involves a FoldingSet lookup.
+class AttributeSet {
+ // TODO: Extract AvailableAttrs from AttributeSetNode and store them here.
+ // This will allow an efficient implementation of addAttribute and
+ // removeAttribute for enum attrs.
+
+ /// Private implementation pointer.
+ AttributeSetNode *SetNode = nullptr;
+
+ friend AttributeListImpl;
+ template <typename Ty> friend struct DenseMapInfo;
+
+private:
+ explicit AttributeSet(AttributeSetNode *ASN) : SetNode(ASN) {}
+
+public:
+ /// AttributeSet is a trivially copyable value type.
+ AttributeSet() = default;
+ AttributeSet(const AttributeSet &) = default;
+ ~AttributeSet() = default;
+
+ static AttributeSet get(LLVMContext &C, const AttrBuilder &B);
+ static AttributeSet get(LLVMContext &C, ArrayRef<Attribute> Attrs);
+
+ bool operator==(const AttributeSet &O) { return SetNode == O.SetNode; }
+ bool operator!=(const AttributeSet &O) { return !(*this == O); }
+
+ /// Add an argument attribute. Returns a new set because attribute sets are
+ /// immutable.
+ AttributeSet addAttribute(LLVMContext &C, Attribute::AttrKind Kind) const;
+
+ /// Add a target-dependent attribute. Returns a new set because attribute sets
+ /// are immutable.
+ AttributeSet addAttribute(LLVMContext &C, StringRef Kind,
+ StringRef Value = StringRef()) const;
+
+ /// Add attributes to the attribute set. Returns a new set because attribute
+ /// sets are immutable.
+ AttributeSet addAttributes(LLVMContext &C, AttributeSet AS) const;
+
+ /// Remove the specified attribute from this set. Returns a new set because
+ /// attribute sets are immutable.
+ AttributeSet removeAttribute(LLVMContext &C, Attribute::AttrKind Kind) const;
+
+ /// Remove the specified attribute from this set. Returns a new set because
+ /// attribute sets are immutable.
+ AttributeSet removeAttribute(LLVMContext &C, StringRef Kind) const;
+
+ /// Remove the specified attributes from this set. Returns a new set because
+ /// attribute sets are immutable.
+ AttributeSet removeAttributes(LLVMContext &C,
+ const AttrBuilder &AttrsToRemove) const;
+
+ /// Return the number of attributes in this set.
+ unsigned getNumAttributes() const;
+
+ /// Return true if attributes exists in this set.
+ bool hasAttributes() const { return SetNode != nullptr; }
+
+ /// Return true if the attribute exists in this set.
+ bool hasAttribute(Attribute::AttrKind Kind) const;
+
+ /// Return true if the attribute exists in this set.
+ bool hasAttribute(StringRef Kind) const;
+
+ /// Return the attribute object.
+ Attribute getAttribute(Attribute::AttrKind Kind) const;
+
+ /// Return the target-dependent attribute object.
+ Attribute getAttribute(StringRef Kind) const;
+
+ unsigned getAlignment() const;
+ unsigned getStackAlignment() const;
+ uint64_t getDereferenceableBytes() const;
+ uint64_t getDereferenceableOrNullBytes() const;
+ std::pair<unsigned, Optional<unsigned>> getAllocSizeArgs() const;
+ std::string getAsString(bool InAttrGrp = false) const;
+
+ using iterator = const Attribute *;
+
+ iterator begin() const;
+ iterator end() const;
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
+ void dump() const;
+#endif
+};
+
+//===----------------------------------------------------------------------===//
+/// \class
+/// \brief Provide DenseMapInfo for AttributeSet.
+template <> struct DenseMapInfo<AttributeSet> {
+ static inline AttributeSet getEmptyKey() {
+ uintptr_t Val = static_cast<uintptr_t>(-1);
+ Val <<= PointerLikeTypeTraits<void *>::NumLowBitsAvailable;
+ return AttributeSet(reinterpret_cast<AttributeSetNode *>(Val));
+ }
+
+ static inline AttributeSet getTombstoneKey() {
+ uintptr_t Val = static_cast<uintptr_t>(-2);
+ Val <<= PointerLikeTypeTraits<void *>::NumLowBitsAvailable;
+ return AttributeSet(reinterpret_cast<AttributeSetNode *>(Val));
+ }
+
+ static unsigned getHashValue(AttributeSet AS) {
+ return (unsigned((uintptr_t)AS.SetNode) >> 4) ^
+ (unsigned((uintptr_t)AS.SetNode) >> 9);
+ }
+
+ static bool isEqual(AttributeSet LHS, AttributeSet RHS) { return LHS == RHS; }
+};
+
+//===----------------------------------------------------------------------===//
+/// \class
/// \brief This class holds the attributes for a function, its return value, and
/// its parameters. You access the attributes for each of them via an index into
-/// the AttributeSet object. The function attributes are at index
-/// `AttributeSet::FunctionIndex', the return value is at index
-/// `AttributeSet::ReturnIndex', and the attributes for the parameters start at
-/// index `1'.
-class AttributeSet {
+/// the AttributeList object. The function attributes are at index
+/// `AttributeList::FunctionIndex', the return value is at index
+/// `AttributeList::ReturnIndex', and the attributes for the parameters start at
+/// index `AttributeList::FirstArgIndex'.
+class AttributeList {
public:
enum AttrIndex : unsigned {
ReturnIndex = 0U,
- FunctionIndex = ~0U
+ FunctionIndex = ~0U,
+ FirstArgIndex = 1,
};
private:
friend class AttrBuilder;
- friend class AttributeSetImpl;
+ friend class AttributeListImpl;
+ friend class AttributeSet;
friend class AttributeSetNode;
+
template <typename Ty> friend struct DenseMapInfo;
/// \brief The attributes that we are managing. This can be null to represent
/// the empty attributes list.
- AttributeSetImpl *pImpl;
+ AttributeListImpl *pImpl = nullptr;
- /// \brief The attributes for the specified index are returned.
- AttributeSetNode *getAttributes(unsigned Index) const;
-
- /// \brief Create an AttributeSet with the specified parameters in it.
- static AttributeSet get(LLVMContext &C,
- ArrayRef<std::pair<unsigned, Attribute> > Attrs);
- static AttributeSet get(LLVMContext &C,
- ArrayRef<std::pair<unsigned,
- AttributeSetNode*> > Attrs);
+public:
+ /// \brief Create an AttributeList with the specified parameters in it.
+ static AttributeList get(LLVMContext &C,
+ ArrayRef<std::pair<unsigned, Attribute>> Attrs);
+ static AttributeList get(LLVMContext &C,
+ ArrayRef<std::pair<unsigned, AttributeSet>> Attrs);
+
+ /// \brief Create an AttributeList from attribute sets for a function, its
+ /// return value, and all of its arguments.
+ static AttributeList get(LLVMContext &C, AttributeSet FnAttrs,
+ AttributeSet RetAttrs,
+ ArrayRef<AttributeSet> ArgAttrs);
- static AttributeSet getImpl(LLVMContext &C,
- ArrayRef<std::pair<unsigned,
- AttributeSetNode*> > Attrs);
+private:
+ explicit AttributeList(AttributeListImpl *LI) : pImpl(LI) {}
- explicit AttributeSet(AttributeSetImpl *LI) : pImpl(LI) {}
+ static AttributeList getImpl(LLVMContext &C, ArrayRef<AttributeSet> AttrSets);
public:
- AttributeSet() : pImpl(nullptr) {}
+ AttributeList() = default;
//===--------------------------------------------------------------------===//
- // AttributeSet Construction and Mutation
+ // AttributeList Construction and Mutation
//===--------------------------------------------------------------------===//
- /// \brief Return an AttributeSet with the specified parameters in it.
- static AttributeSet get(LLVMContext &C, ArrayRef<AttributeSet> Attrs);
- static AttributeSet get(LLVMContext &C, unsigned Index,
- ArrayRef<Attribute::AttrKind> Kinds);
- static AttributeSet get(LLVMContext &C, unsigned Index,
- ArrayRef<StringRef> Kind);
- static AttributeSet get(LLVMContext &C, unsigned Index, const AttrBuilder &B);
-
- /// \brief Add an attribute to the attribute set at the given index. Because
- /// attribute sets are immutable, this returns a new set.
- AttributeSet addAttribute(LLVMContext &C, unsigned Index,
- Attribute::AttrKind Kind) const;
-
- /// \brief Add an attribute to the attribute set at the given index. Because
- /// attribute sets are immutable, this returns a new set.
- AttributeSet addAttribute(LLVMContext &C, unsigned Index, StringRef Kind,
- StringRef Value = StringRef()) const;
+ /// \brief Return an AttributeList with the specified parameters in it.
+ static AttributeList get(LLVMContext &C, ArrayRef<AttributeList> Attrs);
+ static AttributeList get(LLVMContext &C, unsigned Index,
+ ArrayRef<Attribute::AttrKind> Kinds);
+ static AttributeList get(LLVMContext &C, unsigned Index,
+ ArrayRef<StringRef> Kind);
+ static AttributeList get(LLVMContext &C, unsigned Index,
+ const AttrBuilder &B);
+
+ /// \brief Add an attribute to the attribute set at the given index.
+ /// Returns a new list because attribute lists are immutable.
+ AttributeList addAttribute(LLVMContext &C, unsigned Index,
+ Attribute::AttrKind Kind) const;
+
+ /// \brief Add an attribute to the attribute set at the given index.
+ /// Returns a new list because attribute lists are immutable.
+ AttributeList addAttribute(LLVMContext &C, unsigned Index, StringRef Kind,
+ StringRef Value = StringRef()) const;
+
+ /// Add an attribute to the attribute set at the given index.
+ /// Returns a new list because attribute lists are immutable.
+ AttributeList addAttribute(LLVMContext &C, unsigned Index, Attribute A) const;
+
+ /// \brief Add attributes to the attribute set at the given index.
+ /// Returns a new list because attribute lists are immutable.
+ AttributeList addAttributes(LLVMContext &C, unsigned Index,
+ const AttrBuilder &B) const;
+
+ /// Add an argument attribute to the list. Returns a new list because
+ /// attribute lists are immutable.
+ AttributeList addParamAttribute(LLVMContext &C, unsigned ArgNo,
+ Attribute::AttrKind Kind) const {
+ return addAttribute(C, ArgNo + FirstArgIndex, Kind);
+ }
+
+ /// Add an argument attribute to the list. Returns a new list because
+ /// attribute lists are immutable.
+ AttributeList addParamAttribute(LLVMContext &C, unsigned ArgNo,
+ StringRef Kind,
+ StringRef Value = StringRef()) const {
+ return addAttribute(C, ArgNo + FirstArgIndex, Kind, Value);
+ }
- /// Add an attribute to the attribute set at the given indices. Because
- /// attribute sets are immutable, this returns a new set.
- AttributeSet addAttribute(LLVMContext &C, ArrayRef<unsigned> Indices,
- Attribute A) const;
+ /// Add an attribute to the attribute list at the given arg indices. Returns a
+ /// new list because attribute lists are immutable.
+ AttributeList addParamAttribute(LLVMContext &C, ArrayRef<unsigned> ArgNos,
+ Attribute A) const;
- /// \brief Add attributes to the attribute set at the given index. Because
- /// attribute sets are immutable, this returns a new set.
- AttributeSet addAttributes(LLVMContext &C, unsigned Index,
- AttributeSet Attrs) const;
+ /// Add an argument attribute to the list. Returns a new list because
+ /// attribute lists are immutable.
+ AttributeList addParamAttributes(LLVMContext &C, unsigned ArgNo,
+ const AttrBuilder &B) const {
+ return addAttributes(C, ArgNo + FirstArgIndex, B);
+ }
/// \brief Remove the specified attribute at the specified index from this
- /// attribute list. Because attribute lists are immutable, this returns the
- /// new list.
- AttributeSet removeAttribute(LLVMContext &C, unsigned Index,
- Attribute::AttrKind Kind) const;
+ /// attribute list. Returns a new list because attribute lists are immutable.
+ AttributeList removeAttribute(LLVMContext &C, unsigned Index,
+ Attribute::AttrKind Kind) const;
/// \brief Remove the specified attribute at the specified index from this
- /// attribute list. Because attribute lists are immutable, this returns the
- /// new list.
- AttributeSet removeAttribute(LLVMContext &C, unsigned Index,
- StringRef Kind) const;
+ /// attribute list. Returns a new list because attribute lists are immutable.
+ AttributeList removeAttribute(LLVMContext &C, unsigned Index,
+ StringRef Kind) const;
/// \brief Remove the specified attributes at the specified index from this
- /// attribute list. Because attribute lists are immutable, this returns the
- /// new list.
- AttributeSet removeAttributes(LLVMContext &C, unsigned Index,
- AttributeSet Attrs) const;
+ /// attribute list. Returns a new list because attribute lists are immutable.
+ AttributeList removeAttributes(LLVMContext &C, unsigned Index,
+ const AttrBuilder &AttrsToRemove) const;
+
+ /// \brief Remove all attributes at the specified index from this
+ /// attribute list. Returns a new list because attribute lists are immutable.
+ AttributeList removeAttributes(LLVMContext &C, unsigned Index) const;
+
+ /// \brief Remove the specified attribute at the specified arg index from this
+ /// attribute list. Returns a new list because attribute lists are immutable.
+ AttributeList removeParamAttribute(LLVMContext &C, unsigned ArgNo,
+ Attribute::AttrKind Kind) const {
+ return removeAttribute(C, ArgNo + FirstArgIndex, Kind);
+ }
- /// \brief Remove the specified attributes at the specified index from this
- /// attribute list. Because attribute lists are immutable, this returns the
- /// new list.
- AttributeSet removeAttributes(LLVMContext &C, unsigned Index,
- const AttrBuilder &Attrs) const;
+ /// \brief Remove the specified attribute at the specified arg index from this
+ /// attribute list. Returns a new list because attribute lists are immutable.
+ AttributeList removeParamAttribute(LLVMContext &C, unsigned ArgNo,
+ StringRef Kind) const {
+ return removeAttribute(C, ArgNo + FirstArgIndex, Kind);
+ }
+
+ /// \brief Remove the specified attribute at the specified arg index from this
+ /// attribute list. Returns a new list because attribute lists are immutable.
+ AttributeList removeParamAttributes(LLVMContext &C, unsigned ArgNo,
+ const AttrBuilder &AttrsToRemove) const {
+ return removeAttributes(C, ArgNo + FirstArgIndex, AttrsToRemove);
+ }
+
+ /// \brief Remove all attributes at the specified arg index from this
+ /// attribute list. Returns a new list because attribute lists are immutable.
+ AttributeList removeParamAttributes(LLVMContext &C, unsigned ArgNo) const {
+ return removeAttributes(C, ArgNo + FirstArgIndex);
+ }
+
+ /// \Brief Add the dereferenceable attribute to the attribute set at the given
+ /// index. Returns a new list because attribute lists are immutable.
+ AttributeList addDereferenceableAttr(LLVMContext &C, unsigned Index,
+ uint64_t Bytes) const;
+
+ /// \Brief Add the dereferenceable attribute to the attribute set at the given
+ /// arg index. Returns a new list because attribute lists are immutable.
+ AttributeList addDereferenceableParamAttr(LLVMContext &C, unsigned ArgNo,
+ uint64_t Bytes) const {
+ return addDereferenceableAttr(C, ArgNo + FirstArgIndex, Bytes);
+ }
- /// \brief Add the dereferenceable attribute to the attribute set at the given
- /// index. Because attribute sets are immutable, this returns a new set.
- AttributeSet addDereferenceableAttr(LLVMContext &C, unsigned Index,
- uint64_t Bytes) const;
+ /// \brief Add the dereferenceable_or_null attribute to the attribute set at
+ /// the given index. Returns a new list because attribute lists are immutable.
+ AttributeList addDereferenceableOrNullAttr(LLVMContext &C, unsigned Index,
+ uint64_t Bytes) const;
/// \brief Add the dereferenceable_or_null attribute to the attribute set at
- /// the given index. Because attribute sets are immutable, this returns a new
- /// set.
- AttributeSet addDereferenceableOrNullAttr(LLVMContext &C, unsigned Index,
- uint64_t Bytes) const;
+ /// the given arg index. Returns a new list because attribute lists are
+ /// immutable.
+ AttributeList addDereferenceableOrNullParamAttr(LLVMContext &C,
+ unsigned ArgNo,
+ uint64_t Bytes) const {
+ return addDereferenceableOrNullAttr(C, ArgNo + FirstArgIndex, Bytes);
+ }
/// Add the allocsize attribute to the attribute set at the given index.
- /// Because attribute sets are immutable, this returns a new set.
- AttributeSet addAllocSizeAttr(LLVMContext &C, unsigned Index,
- unsigned ElemSizeArg,
- const Optional<unsigned> &NumElemsArg);
+ /// Returns a new list because attribute lists are immutable.
+ AttributeList addAllocSizeAttr(LLVMContext &C, unsigned Index,
+ unsigned ElemSizeArg,
+ const Optional<unsigned> &NumElemsArg);
+
+ /// Add the allocsize attribute to the attribute set at the given arg index.
+ /// Returns a new list because attribute lists are immutable.
+ AttributeList addAllocSizeParamAttr(LLVMContext &C, unsigned ArgNo,
+ unsigned ElemSizeArg,
+ const Optional<unsigned> &NumElemsArg) {
+ return addAllocSizeAttr(C, ArgNo + FirstArgIndex, ElemSizeArg, NumElemsArg);
+ }
//===--------------------------------------------------------------------===//
- // AttributeSet Accessors
+ // AttributeList Accessors
//===--------------------------------------------------------------------===//
/// \brief Retrieve the LLVM context.
LLVMContext &getContext() const;
/// \brief The attributes for the specified index are returned.
- AttributeSet getParamAttributes(unsigned Index) const;
+ AttributeSet getAttributes(unsigned Index) const;
+
+ /// \brief The attributes for the argument or parameter at the given index are
+ /// returned.
+ AttributeSet getParamAttributes(unsigned ArgNo) const;
/// \brief The attributes for the ret value are returned.
AttributeSet getRetAttributes() const;
@@ -334,14 +535,32 @@ public:
/// \brief Return true if attribute exists at the given index.
bool hasAttributes(unsigned Index) const;
- /// \brief Equivalent to hasAttribute(AttributeSet::FunctionIndex, Kind) but
+ /// \brief Return true if the attribute exists for the given argument
+ bool hasParamAttr(unsigned ArgNo, Attribute::AttrKind Kind) const {
+ return hasAttribute(ArgNo + FirstArgIndex, Kind);
+ }
+
+ /// \brief Return true if the attribute exists for the given argument
+ bool hasParamAttr(unsigned ArgNo, StringRef Kind) const {
+ return hasAttribute(ArgNo + FirstArgIndex, Kind);
+ }
+
+ /// \brief Return true if attributes exists for the given argument
+ bool hasParamAttrs(unsigned ArgNo) const {
+ return hasAttributes(ArgNo + FirstArgIndex);
+ }
+
+ /// \brief Equivalent to hasAttribute(AttributeList::FunctionIndex, Kind) but
/// may be faster.
bool hasFnAttribute(Attribute::AttrKind Kind) const;
- /// \brief Equivalent to hasAttribute(AttributeSet::FunctionIndex, Kind) but
+ /// \brief Equivalent to hasAttribute(AttributeList::FunctionIndex, Kind) but
/// may be faster.
bool hasFnAttribute(StringRef Kind) const;
+ /// \brief Equivalent to hasAttribute(ArgNo + FirstArgIndex, Kind).
+ bool hasParamAttribute(unsigned ArgNo, Attribute::AttrKind Kind) const;
+
/// \brief Return true if the specified attribute is set for at least one
/// parameter or for the return value. If Index is not nullptr, the index
/// of a parameter with the specified attribute is provided.
@@ -354,8 +573,21 @@ public:
/// \brief Return the attribute object that exists at the given index.
Attribute getAttribute(unsigned Index, StringRef Kind) const;
+ /// \brief Return the attribute object that exists at the arg index.
+ Attribute getParamAttr(unsigned ArgNo, Attribute::AttrKind Kind) const {
+ return getAttribute(ArgNo + FirstArgIndex, Kind);
+ }
+
+ /// \brief Return the attribute object that exists at the given index.
+ Attribute getParamAttr(unsigned ArgNo, StringRef Kind) const {
+ return getAttribute(ArgNo + FirstArgIndex, Kind);
+ }
+
+ /// \brief Return the alignment of the return value.
+ unsigned getRetAlignment() const;
+
/// \brief Return the alignment for the specified function parameter.
- unsigned getParamAlignment(unsigned Index) const;
+ unsigned getParamAlignment(unsigned ArgNo) const;
/// \brief Get the stack alignment.
unsigned getStackAlignment(unsigned Index) const;
@@ -363,10 +595,22 @@ public:
/// \brief Get the number of dereferenceable bytes (or zero if unknown).
uint64_t getDereferenceableBytes(unsigned Index) const;
+ /// \brief Get the number of dereferenceable bytes (or zero if unknown) of an
+ /// arg.
+ uint64_t getParamDereferenceableBytes(unsigned ArgNo) const {
+ return getDereferenceableBytes(ArgNo + FirstArgIndex);
+ }
+
/// \brief Get the number of dereferenceable_or_null bytes (or zero if
/// unknown).
uint64_t getDereferenceableOrNullBytes(unsigned Index) const;
+ /// \brief Get the number of dereferenceable_or_null bytes (or zero if
+ /// unknown) of an arg.
+ uint64_t getParamDereferenceableOrNullBytes(unsigned ArgNo) const {
+ return getDereferenceableOrNullBytes(ArgNo + FirstArgIndex);
+ }
+
/// Get the allocsize argument numbers (or pair(0, 0) if unknown).
std::pair<unsigned, Optional<unsigned>>
getAllocSizeArgs(unsigned Index) const;
@@ -374,22 +618,24 @@ public:
/// \brief Return the attributes at the index as a string.
std::string getAsString(unsigned Index, bool InAttrGrp = false) const;
- typedef ArrayRef<Attribute>::iterator iterator;
+ //===--------------------------------------------------------------------===//
+ // AttributeList Introspection
+ //===--------------------------------------------------------------------===//
+
+ using iterator = const AttributeSet *;
- iterator begin(unsigned Slot) const;
- iterator end(unsigned Slot) const;
+ iterator begin() const;
+ iterator end() const;
- /// operator==/!= - Provide equality predicates.
- bool operator==(const AttributeSet &RHS) const {
- return pImpl == RHS.pImpl;
- }
- bool operator!=(const AttributeSet &RHS) const {
- return pImpl != RHS.pImpl;
- }
+ unsigned getNumAttrSets() const;
- //===--------------------------------------------------------------------===//
- // AttributeSet Introspection
- //===--------------------------------------------------------------------===//
+ /// Use these to iterate over the valid attribute indices.
+ unsigned index_begin() const { return AttributeList::FunctionIndex; }
+ unsigned index_end() const { return getNumAttrSets() - 1; }
+
+ /// operator==/!= - Provide equality predicates.
+ bool operator==(const AttributeList &RHS) const { return pImpl == RHS.pImpl; }
+ bool operator!=(const AttributeList &RHS) const { return pImpl != RHS.pImpl; }
/// \brief Return a raw pointer that uniquely identifies this attribute list.
void *getRawPointer() const {
@@ -397,43 +643,35 @@ public:
}
/// \brief Return true if there are no attributes.
- bool isEmpty() const {
- return getNumSlots() == 0;
- }
-
- /// \brief Return the number of slots used in this attribute list. This is
- /// the number of arguments that have an attribute set on them (including the
- /// function itself).
- unsigned getNumSlots() const;
-
- /// \brief Return the index for the given slot.
- unsigned getSlotIndex(unsigned Slot) const;
-
- /// \brief Return the attributes at the given slot.
- AttributeSet getSlotAttributes(unsigned Slot) const;
+ bool isEmpty() const { return pImpl == nullptr; }
void dump() const;
};
//===----------------------------------------------------------------------===//
/// \class
-/// \brief Provide DenseMapInfo for AttributeSet.
-template<> struct DenseMapInfo<AttributeSet> {
- static inline AttributeSet getEmptyKey() {
+/// \brief Provide DenseMapInfo for AttributeList.
+template <> struct DenseMapInfo<AttributeList> {
+ static inline AttributeList getEmptyKey() {
uintptr_t Val = static_cast<uintptr_t>(-1);
Val <<= PointerLikeTypeTraits<void*>::NumLowBitsAvailable;
- return AttributeSet(reinterpret_cast<AttributeSetImpl*>(Val));
+ return AttributeList(reinterpret_cast<AttributeListImpl *>(Val));
}
- static inline AttributeSet getTombstoneKey() {
+
+ static inline AttributeList getTombstoneKey() {
uintptr_t Val = static_cast<uintptr_t>(-2);
Val <<= PointerLikeTypeTraits<void*>::NumLowBitsAvailable;
- return AttributeSet(reinterpret_cast<AttributeSetImpl*>(Val));
+ return AttributeList(reinterpret_cast<AttributeListImpl *>(Val));
}
- static unsigned getHashValue(AttributeSet AS) {
+
+ static unsigned getHashValue(AttributeList AS) {
return (unsigned((uintptr_t)AS.pImpl) >> 4) ^
(unsigned((uintptr_t)AS.pImpl) >> 9);
}
- static bool isEqual(AttributeSet LHS, AttributeSet RHS) { return LHS == RHS; }
+
+ static bool isEqual(AttributeList LHS, AttributeList RHS) {
+ return LHS == RHS;
+ }
};
//===----------------------------------------------------------------------===//
@@ -445,22 +683,19 @@ template<> struct DenseMapInfo<AttributeSet> {
class AttrBuilder {
std::bitset<Attribute::EndAttrKinds> Attrs;
std::map<std::string, std::string> TargetDepAttrs;
- uint64_t Alignment;
- uint64_t StackAlignment;
- uint64_t DerefBytes;
- uint64_t DerefOrNullBytes;
- uint64_t AllocSizeArgs;
+ uint64_t Alignment = 0;
+ uint64_t StackAlignment = 0;
+ uint64_t DerefBytes = 0;
+ uint64_t DerefOrNullBytes = 0;
+ uint64_t AllocSizeArgs = 0;
public:
- AttrBuilder()
- : Attrs(0), Alignment(0), StackAlignment(0), DerefBytes(0),
- DerefOrNullBytes(0), AllocSizeArgs(0) {}
- AttrBuilder(const Attribute &A)
- : Attrs(0), Alignment(0), StackAlignment(0), DerefBytes(0),
- DerefOrNullBytes(0), AllocSizeArgs(0) {
+ AttrBuilder() = default;
+ AttrBuilder(const Attribute &A) {
addAttribute(A);
}
- AttrBuilder(AttributeSet AS, unsigned Idx);
+ AttrBuilder(AttributeList AS, unsigned Idx);
+ AttrBuilder(AttributeSet AS);
void clear();
@@ -477,7 +712,7 @@ public:
AttrBuilder &removeAttribute(Attribute::AttrKind Val);
/// \brief Remove the attributes from the builder.
- AttrBuilder &removeAttributes(AttributeSet A, uint64_t Index);
+ AttrBuilder &removeAttributes(AttributeList A, uint64_t WithoutIndex);
/// \brief Remove the target-dependent attribute to the builder.
AttrBuilder &removeAttribute(StringRef A);
@@ -507,7 +742,7 @@ public:
/// \brief Return true if the builder has any attribute that's in the
/// specified attribute.
- bool hasAttributes(AttributeSet A, uint64_t Index) const;
+ bool hasAttributes(AttributeList A, uint64_t Index) const;
/// \brief Return true if the builder has an alignment attribute.
bool hasAlignmentAttr() const;
@@ -559,11 +794,11 @@ public:
bool empty() const { return Attrs.none(); }
// Iterators for target-dependent attributes.
- typedef std::pair<std::string, std::string> td_type;
- typedef std::map<std::string, std::string>::iterator td_iterator;
- typedef std::map<std::string, std::string>::const_iterator td_const_iterator;
- typedef llvm::iterator_range<td_iterator> td_range;
- typedef llvm::iterator_range<td_const_iterator> td_const_range;
+ 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_range = iterator_range<td_iterator>;
+ using td_const_range = iterator_range<td_const_iterator>;
td_iterator td_begin() { return TargetDepAttrs.begin(); }
td_iterator td_end() { return TargetDepAttrs.end(); }
@@ -596,8 +831,8 @@ bool areInlineCompatible(const Function &Caller, const Function &Callee);
/// \brief Merge caller's and callee's attributes.
void mergeAttributesForInlining(Function &Caller, const Function &Callee);
-} // end AttributeFuncs namespace
+} // end namespace AttributeFuncs
-} // end llvm namespace
+} // end namespace llvm
-#endif
+#endif // LLVM_IR_ATTRIBUTES_H
diff --git a/contrib/llvm/include/llvm/IR/Attributes.td b/contrib/llvm/include/llvm/IR/Attributes.td
index 7b63638..6163878 100644
--- a/contrib/llvm/include/llvm/IR/Attributes.td
+++ b/contrib/llvm/include/llvm/IR/Attributes.td
@@ -137,6 +137,9 @@ def SExt : EnumAttr<"signext">;
/// +1 bias 0 means unaligned (different from alignstack=(1)).
def StackAlignment : EnumAttr<"alignstack">;
+/// Function can be speculated.
+def Speculatable : EnumAttr<"speculatable">;
+
/// Stack protection.
def StackProtect : EnumAttr<"ssp">;
@@ -211,3 +214,5 @@ def : MergeRule<"setAND<UnsafeFPMathAttr>">;
def : MergeRule<"setOR<NoImplicitFloatAttr>">;
def : MergeRule<"setOR<NoJumpTablesAttr>">;
def : MergeRule<"adjustCallerSSPLevel">;
+def : MergeRule<"adjustCallerStackProbes">;
+def : MergeRule<"adjustCallerStackProbeSize">;
diff --git a/contrib/llvm/include/llvm/IR/BasicBlock.h b/contrib/llvm/include/llvm/IR/BasicBlock.h
index 93dbd57..6714f2c 100644
--- a/contrib/llvm/include/llvm/IR/BasicBlock.h
+++ b/contrib/llvm/include/llvm/IR/BasicBlock.h
@@ -1,4 +1,4 @@
-//===-- llvm/BasicBlock.h - Represent a basic block in the VM ---*- C++ -*-===//
+//===- llvm/BasicBlock.h - Represent a basic block in the VM ----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,16 +14,21 @@
#ifndef LLVM_IR_BASICBLOCK_H
#define LLVM_IR_BASICBLOCK_H
+#include "llvm-c/Types.h"
+#include "llvm/ADT/Twine.h"
#include "llvm/ADT/ilist.h"
#include "llvm/ADT/ilist_node.h"
-#include "llvm/ADT/Twine.h"
+#include "llvm/ADT/iterator.h"
+#include "llvm/ADT/iterator_range.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/SymbolTableListTraits.h"
#include "llvm/IR/Value.h"
#include "llvm/Support/CBindingWrapping.h"
-#include "llvm-c/Types.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/Compiler.h"
#include <cassert>
#include <cstddef>
+#include <iterator>
namespace llvm {
@@ -31,7 +36,10 @@ class CallInst;
class Function;
class LandingPadInst;
class LLVMContext;
+class Module;
+class PHINode;
class TerminatorInst;
+class ValueSymbolTable;
/// \brief LLVM Basic Block Representation
///
@@ -48,10 +56,10 @@ class TerminatorInst;
/// occur because it may be useful in the intermediate stage of constructing or
/// modifying a program. However, the verifier will ensure that basic blocks
/// are "well formed".
-class BasicBlock : public Value, // Basic blocks are data objects also
- public ilist_node_with_parent<BasicBlock, Function> {
+class BasicBlock final : public Value, // Basic blocks are data objects also
+ public ilist_node_with_parent<BasicBlock, Function> {
public:
- typedef SymbolTableList<Instruction> InstListType;
+ using InstListType = SymbolTableList<Instruction>;
private:
friend class BlockAddress;
@@ -74,16 +82,16 @@ private:
public:
BasicBlock(const BasicBlock &) = delete;
BasicBlock &operator=(const BasicBlock &) = delete;
- ~BasicBlock() override;
+ ~BasicBlock();
/// \brief Get the context in which this basic block lives.
LLVMContext &getContext() const;
/// Instruction iterators...
- typedef InstListType::iterator iterator;
- typedef InstListType::const_iterator const_iterator;
- typedef InstListType::reverse_iterator reverse_iterator;
- typedef InstListType::const_reverse_iterator const_reverse_iterator;
+ using iterator = InstListType::iterator;
+ using const_iterator = InstListType::const_iterator;
+ using reverse_iterator = InstListType::reverse_iterator;
+ using const_reverse_iterator = InstListType::const_reverse_iterator;
/// \brief Creates a new BasicBlock.
///
@@ -105,27 +113,35 @@ public:
///
/// Note: this is undefined behavior if the block does not have a parent.
const Module *getModule() const;
- Module *getModule();
+ Module *getModule() {
+ return const_cast<Module *>(
+ static_cast<const BasicBlock *>(this)->getModule());
+ }
/// \brief Returns the terminator instruction if the block is well formed or
/// null if the block is not well formed.
- TerminatorInst *getTerminator();
- const TerminatorInst *getTerminator() const;
+ const TerminatorInst *getTerminator() const LLVM_READONLY;
+ TerminatorInst *getTerminator() {
+ return const_cast<TerminatorInst *>(
+ static_cast<const BasicBlock *>(this)->getTerminator());
+ }
/// \brief Returns the call instruction calling @llvm.experimental.deoptimize
/// prior to the terminating return instruction of this basic block, if such a
/// call is present. Otherwise, returns null.
- CallInst *getTerminatingDeoptimizeCall();
- const CallInst *getTerminatingDeoptimizeCall() const {
- return const_cast<BasicBlock *>(this)->getTerminatingDeoptimizeCall();
+ const CallInst *getTerminatingDeoptimizeCall() const;
+ CallInst *getTerminatingDeoptimizeCall() {
+ return const_cast<CallInst *>(
+ static_cast<const BasicBlock *>(this)->getTerminatingDeoptimizeCall());
}
/// \brief 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.
- CallInst *getTerminatingMustTailCall();
- const CallInst *getTerminatingMustTailCall() const {
- return const_cast<BasicBlock *>(this)->getTerminatingMustTailCall();
+ const CallInst *getTerminatingMustTailCall() const;
+ CallInst *getTerminatingMustTailCall() {
+ return const_cast<CallInst *>(
+ static_cast<const BasicBlock *>(this)->getTerminatingMustTailCall());
}
/// \brief Returns a pointer to the first instruction in this block that is
@@ -134,32 +150,36 @@ public:
/// When adding instructions to the beginning of the basic block, they should
/// be added before the returned value, not before the first instruction,
/// which might be PHI. Returns 0 is there's no non-PHI instruction.
- Instruction* getFirstNonPHI();
- const Instruction* getFirstNonPHI() const {
- return const_cast<BasicBlock*>(this)->getFirstNonPHI();
+ const Instruction* getFirstNonPHI() const;
+ Instruction* getFirstNonPHI() {
+ return const_cast<Instruction *>(
+ static_cast<const BasicBlock *>(this)->getFirstNonPHI());
}
/// \brief Returns a pointer to the first instruction in this block that is not
/// a PHINode or a debug intrinsic.
- Instruction* getFirstNonPHIOrDbg();
- const Instruction* getFirstNonPHIOrDbg() const {
- return const_cast<BasicBlock*>(this)->getFirstNonPHIOrDbg();
+ const Instruction* getFirstNonPHIOrDbg() const;
+ Instruction* getFirstNonPHIOrDbg() {
+ return const_cast<Instruction *>(
+ static_cast<const BasicBlock *>(this)->getFirstNonPHIOrDbg());
}
/// \brief Returns a pointer to the first instruction in this block that is not
/// a PHINode, a debug intrinsic, or a lifetime intrinsic.
- Instruction* getFirstNonPHIOrDbgOrLifetime();
- const Instruction* getFirstNonPHIOrDbgOrLifetime() const {
- return const_cast<BasicBlock*>(this)->getFirstNonPHIOrDbgOrLifetime();
+ const Instruction* getFirstNonPHIOrDbgOrLifetime() const;
+ Instruction* getFirstNonPHIOrDbgOrLifetime() {
+ return const_cast<Instruction *>(
+ static_cast<const BasicBlock *>(this)->getFirstNonPHIOrDbgOrLifetime());
}
/// \brief Returns an iterator to the first instruction in this block that is
/// suitable for inserting a non-PHI instruction.
///
/// In particular, it skips all PHIs and LandingPad instructions.
- iterator getFirstInsertionPt();
- const_iterator getFirstInsertionPt() const {
- return const_cast<BasicBlock*>(this)->getFirstInsertionPt();
+ const_iterator getFirstInsertionPt() const;
+ iterator getFirstInsertionPt() {
+ return static_cast<const BasicBlock *>(this)
+ ->getFirstInsertionPt().getNonConst();
}
/// \brief Unlink 'this' from the containing function, but do not delete it.
@@ -188,9 +208,10 @@ public:
/// \brief Return the predecessor of this block if it has a single predecessor
/// block. Otherwise return a null pointer.
- BasicBlock *getSinglePredecessor();
- const BasicBlock *getSinglePredecessor() const {
- return const_cast<BasicBlock*>(this)->getSinglePredecessor();
+ const BasicBlock *getSinglePredecessor() const;
+ BasicBlock *getSinglePredecessor() {
+ return const_cast<BasicBlock *>(
+ static_cast<const BasicBlock *>(this)->getSinglePredecessor());
}
/// \brief Return the predecessor of this block if it has a unique predecessor
@@ -199,27 +220,30 @@ public:
/// Note that unique predecessor doesn't mean single edge, there can be
/// multiple edges from the unique predecessor to this block (for example a
/// switch statement with multiple cases having the same destination).
- BasicBlock *getUniquePredecessor();
- const BasicBlock *getUniquePredecessor() const {
- return const_cast<BasicBlock*>(this)->getUniquePredecessor();
+ const BasicBlock *getUniquePredecessor() const;
+ BasicBlock *getUniquePredecessor() {
+ return const_cast<BasicBlock *>(
+ static_cast<const BasicBlock *>(this)->getUniquePredecessor());
}
/// \brief Return the successor of this block if it has a single successor.
/// Otherwise return a null pointer.
///
/// This method is analogous to getSinglePredecessor above.
- BasicBlock *getSingleSuccessor();
- const BasicBlock *getSingleSuccessor() const {
- return const_cast<BasicBlock*>(this)->getSingleSuccessor();
+ const BasicBlock *getSingleSuccessor() const;
+ BasicBlock *getSingleSuccessor() {
+ return const_cast<BasicBlock *>(
+ static_cast<const BasicBlock *>(this)->getSingleSuccessor());
}
/// \brief Return the successor of this block if it has a unique successor.
/// Otherwise return a null pointer.
///
/// This method is analogous to getUniquePredecessor above.
- BasicBlock *getUniqueSuccessor();
- const BasicBlock *getUniqueSuccessor() const {
- return const_cast<BasicBlock*>(this)->getUniqueSuccessor();
+ const BasicBlock *getUniqueSuccessor() const;
+ BasicBlock *getUniqueSuccessor() {
+ return const_cast<BasicBlock *>(
+ static_cast<const BasicBlock *>(this)->getUniqueSuccessor());
}
//===--------------------------------------------------------------------===//
@@ -242,6 +266,50 @@ public:
inline const Instruction &back() const { return InstList.back(); }
inline Instruction &back() { return InstList.back(); }
+ /// Iterator to walk just the phi nodes in the basic block.
+ template <typename PHINodeT = PHINode, typename BBIteratorT = iterator>
+ class phi_iterator_impl
+ : public iterator_facade_base<phi_iterator_impl<PHINodeT, BBIteratorT>,
+ std::forward_iterator_tag, PHINodeT> {
+ friend BasicBlock;
+
+ PHINodeT *PN;
+
+ phi_iterator_impl(PHINodeT *PN) : PN(PN) {}
+
+ public:
+ // Allow default construction to build variables, but this doesn't build
+ // a useful iterator.
+ phi_iterator_impl() = default;
+
+ // Allow conversion between instantiations where valid.
+ template <typename PHINodeU, typename BBIteratorU>
+ phi_iterator_impl(const phi_iterator_impl<PHINodeU, BBIteratorU> &Arg)
+ : PN(Arg.PN) {}
+
+ bool operator==(const phi_iterator_impl &Arg) const { return PN == Arg.PN; }
+
+ PHINodeT &operator*() const { return *PN; }
+
+ using phi_iterator_impl::iterator_facade_base::operator++;
+ phi_iterator_impl &operator++() {
+ assert(PN && "Cannot increment the end iterator!");
+ PN = dyn_cast<PHINodeT>(std::next(BBIteratorT(PN)));
+ return *this;
+ }
+ };
+ using phi_iterator = phi_iterator_impl<>;
+ using const_phi_iterator =
+ phi_iterator_impl<const PHINode, BasicBlock::const_iterator>;
+
+ /// Returns a range that iterates over the phis in the basic block.
+ ///
+ /// Note that this cannot be used with basic blocks that have no terminator.
+ iterator_range<const_phi_iterator> phis() const {
+ return const_cast<BasicBlock *>(this)->phis();
+ }
+ iterator_range<phi_iterator> phis();
+
/// \brief Return the underlying instruction list container.
///
/// Currently you need to access the underlying instruction list container
@@ -258,7 +326,7 @@ public:
ValueSymbolTable *getValueSymbolTable();
/// \brief Methods for support type inquiry through isa, cast, and dyn_cast.
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return V->getValueID() == Value::BasicBlockVal;
}
@@ -321,8 +389,14 @@ public:
bool isLandingPad() const;
/// \brief Return the landingpad instruction associated with the landing pad.
- LandingPadInst *getLandingPadInst();
const LandingPadInst *getLandingPadInst() const;
+ LandingPadInst *getLandingPadInst() {
+ return const_cast<LandingPadInst *>(
+ static_cast<const BasicBlock *>(this)->getLandingPadInst());
+ }
+
+ /// \brief Return true if it is legal to hoist instructions into this block.
+ bool isLegalToHoistInto() const;
private:
/// \brief Increment the internal refcount of the number of BlockAddresses
diff --git a/contrib/llvm/include/llvm/IR/CFG.h b/contrib/llvm/include/llvm/IR/CFG.h
index 52de11a..e259e42 100644
--- a/contrib/llvm/include/llvm/IR/CFG.h
+++ b/contrib/llvm/include/llvm/IR/CFG.h
@@ -37,9 +37,9 @@ namespace llvm {
template <class Ptr, class USE_iterator> // Predecessor Iterator
class PredIterator : public std::iterator<std::forward_iterator_tag,
Ptr, ptrdiff_t, Ptr*, Ptr*> {
- typedef std::iterator<std::forward_iterator_tag, Ptr, ptrdiff_t, Ptr*,
- Ptr*> super;
- typedef PredIterator<Ptr, USE_iterator> Self;
+ using super =
+ std::iterator<std::forward_iterator_tag, Ptr, ptrdiff_t, Ptr*, Ptr*>;
+ using Self = PredIterator<Ptr, USE_iterator>;
USE_iterator It;
inline void advancePastNonTerminators() {
@@ -49,8 +49,8 @@ class PredIterator : public std::iterator<std::forward_iterator_tag,
}
public:
- typedef typename super::pointer pointer;
- typedef typename super::reference reference;
+ using pointer = typename super::pointer;
+ using reference = typename super::reference;
PredIterator() = default;
explicit inline PredIterator(Ptr *bb) : It(bb->user_begin()) {
@@ -90,11 +90,11 @@ public:
}
};
-typedef PredIterator<BasicBlock, Value::user_iterator> pred_iterator;
-typedef PredIterator<const BasicBlock,
- Value::const_user_iterator> const_pred_iterator;
-typedef iterator_range<pred_iterator> pred_range;
-typedef iterator_range<const_pred_iterator> pred_const_range;
+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>;
inline pred_iterator pred_begin(BasicBlock *BB) { return pred_iterator(BB); }
inline const_pred_iterator pred_begin(const BasicBlock *BB) {
@@ -118,12 +118,12 @@ inline pred_const_range predecessors(const BasicBlock *BB) {
// BasicBlock succ_iterator helpers
//===----------------------------------------------------------------------===//
-typedef TerminatorInst::SuccIterator<TerminatorInst *, BasicBlock>
- succ_iterator;
-typedef TerminatorInst::SuccIterator<const TerminatorInst *, const BasicBlock>
- succ_const_iterator;
-typedef iterator_range<succ_iterator> succ_range;
-typedef iterator_range<succ_const_iterator> succ_const_range;
+using succ_iterator =
+ TerminatorInst::SuccIterator<TerminatorInst *, BasicBlock>;
+using succ_const_iterator =
+ TerminatorInst::SuccIterator<const TerminatorInst *, const BasicBlock>;
+using succ_range = iterator_range<succ_iterator>;
+using succ_const_range = iterator_range<succ_const_iterator>;
inline succ_iterator succ_begin(BasicBlock *BB) {
return succ_iterator(BB->getTerminator());
@@ -160,8 +160,8 @@ struct isPodLike<TerminatorInst::SuccIterator<T, U>> {
// graph of basic blocks...
template <> struct GraphTraits<BasicBlock*> {
- typedef BasicBlock *NodeRef;
- typedef succ_iterator ChildIteratorType;
+ using NodeRef = BasicBlock *;
+ using ChildIteratorType = succ_iterator;
static NodeRef getEntryNode(BasicBlock *BB) { return BB; }
static ChildIteratorType child_begin(NodeRef N) { return succ_begin(N); }
@@ -169,8 +169,8 @@ template <> struct GraphTraits<BasicBlock*> {
};
template <> struct GraphTraits<const BasicBlock*> {
- typedef const BasicBlock *NodeRef;
- typedef succ_const_iterator ChildIteratorType;
+ using NodeRef = const BasicBlock *;
+ using ChildIteratorType = succ_const_iterator;
static NodeRef getEntryNode(const BasicBlock *BB) { return BB; }
@@ -184,16 +184,18 @@ template <> struct GraphTraits<const BasicBlock*> {
// instead of the successor edges.
//
template <> struct GraphTraits<Inverse<BasicBlock*>> {
- typedef BasicBlock *NodeRef;
- typedef pred_iterator ChildIteratorType;
+ using NodeRef = BasicBlock *;
+ using ChildIteratorType = pred_iterator;
+
static NodeRef getEntryNode(Inverse<BasicBlock *> G) { return G.Graph; }
static ChildIteratorType child_begin(NodeRef N) { return pred_begin(N); }
static ChildIteratorType child_end(NodeRef N) { return pred_end(N); }
};
template <> struct GraphTraits<Inverse<const BasicBlock*>> {
- typedef const BasicBlock *NodeRef;
- typedef const_pred_iterator ChildIteratorType;
+ using NodeRef = const BasicBlock *;
+ using ChildIteratorType = const_pred_iterator;
+
static NodeRef getEntryNode(Inverse<const BasicBlock *> G) { return G.Graph; }
static ChildIteratorType child_begin(NodeRef N) { return pred_begin(N); }
static ChildIteratorType child_end(NodeRef N) { return pred_end(N); }
@@ -211,7 +213,7 @@ template <> struct GraphTraits<Function*> : public GraphTraits<BasicBlock*> {
static NodeRef getEntryNode(Function *F) { return &F->getEntryBlock(); }
// nodes_iterator/begin/end - Allow iteration over all nodes in the graph
- typedef pointer_iterator<Function::iterator> nodes_iterator;
+ using nodes_iterator = pointer_iterator<Function::iterator>;
static nodes_iterator nodes_begin(Function *F) {
return nodes_iterator(F->begin());
@@ -228,7 +230,7 @@ template <> struct GraphTraits<const Function*> :
static NodeRef getEntryNode(const Function *F) { return &F->getEntryBlock(); }
// nodes_iterator/begin/end - Allow iteration over all nodes in the graph
- typedef pointer_iterator<Function::const_iterator> nodes_iterator;
+ using nodes_iterator = pointer_iterator<Function::const_iterator>;
static nodes_iterator nodes_begin(const Function *F) {
return nodes_iterator(F->begin());
diff --git a/contrib/llvm/include/llvm/IR/CallSite.h b/contrib/llvm/include/llvm/IR/CallSite.h
index b02c894..96fbebf 100644
--- a/contrib/llvm/include/llvm/IR/CallSite.h
+++ b/contrib/llvm/include/llvm/IR/CallSite.h
@@ -26,9 +26,9 @@
#ifndef LLVM_IR_CALLSITE_H
#define LLVM_IR_CALLSITE_H
-#include "llvm/ADT/iterator_range.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"
@@ -36,10 +36,10 @@
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Intrinsics.h"
-#include "llvm/Support/Casting.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>
@@ -65,11 +65,9 @@ protected:
explicit CallSiteBase(ValTy *II) { *this = get(II); }
private:
- /// CallSiteBase::get - This static method is sort of like a constructor. It
- /// will create an appropriate call site for a Call or Invoke instruction, but
- /// it can also create a null initialized CallSiteBase object for something
- /// which is NOT a call site.
- ///
+ /// This static method is like a constructor. It will create an appropriate
+ /// call site for a Call or Invoke 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)
@@ -81,38 +79,47 @@ private:
}
public:
- /// isCall - true if a CallInst is enclosed.
- /// Note that !isCall() does not mean it is an InvokeInst enclosed,
- /// it also could signify a NULL Instruction pointer.
+ /// Return true if a CallInst is enclosed. Note that !isCall() does not mean
+ /// an InvokeInst is enclosed. It may also signify a NULL instruction pointer.
bool isCall() const { return I.getInt(); }
- /// isInvoke - true if a InvokeInst is enclosed.
- ///
+ /// Return true if a InvokeInst is enclosed.
bool isInvoke() const { return getInstruction() && !I.getInt(); }
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
+ /// Get the basic block containing the call site.
BBTy* getParent() const { return getInstruction()->getParent(); }
- /// getCalledValue - Return the pointer to function that is being called.
- ///
+ /// Return the pointer to function that is being called.
ValTy *getCalledValue() const {
assert(getInstruction() && "Not a call or invoke instruction!");
return *getCallee();
}
- /// getCalledFunction - Return the function being called if this is a direct
- /// call, otherwise return null (if it's an indirect call).
- ///
+ /// 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());
}
- /// setCalledFunction - Set the callee to the specified value.
- ///
+ /// Return true if the callsite is an indirect call.
+ bool isIndirectCall() const {
+ Value *V = getCalledValue();
+ if (!V)
+ return false;
+ if (isa<FunTy>(V) || isa<Constant>(V))
+ return false;
+ if (CallInst *CI = dyn_cast<CallInst>(getInstruction())) {
+ if (CI->isInlineAsm())
+ return false;
+ }
+ return true;
+ }
+
+ /// Set the callee to the specified value.
void setCalledFunction(Value *V) {
assert(getInstruction() && "Not a call or invoke instruction!");
*getCallee() = V;
@@ -129,8 +136,7 @@ public:
return static_cast<Intrinsic::ID>(0);
}
- /// isCallee - Determine whether the passed iterator points to the
- /// callee operand's Use.
+ /// Determine whether the passed iterator points to the callee operand's Use.
bool isCallee(Value::const_user_iterator UI) const {
return isCallee(&UI.getUse());
}
@@ -138,24 +144,23 @@ public:
/// Determine whether this Use is the callee operand's Use.
bool isCallee(const Use *U) const { return getCallee() == U; }
- /// \brief Determine whether the passed iterator points to an argument
- /// operand.
+ /// Determine whether the passed iterator points to an argument operand.
bool isArgOperand(Value::const_user_iterator UI) const {
return isArgOperand(&UI.getUse());
}
- /// \brief Determine whether the passed use points to an argument operand.
+ /// 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();
}
- /// \brief Determine whether the passed iterator points to a bundle operand.
+ /// Determine whether the passed iterator points to a bundle operand.
bool isBundleOperand(Value::const_user_iterator UI) const {
return isBundleOperand(&UI.getUse());
}
- /// \brief Determine whether the passed use points to a bundle operand.
+ /// Determine whether the passed use points to a bundle operand.
bool isBundleOperand(const Use *U) const {
assert(getInstruction() == U->getUser());
if (!hasOperandBundles())
@@ -165,12 +170,12 @@ public:
OperandNo < getBundleOperandsEndIndex();
}
- /// \brief Determine whether the passed iterator points to a data operand.
+ /// Determine whether the passed iterator points to a data operand.
bool isDataOperand(Value::const_user_iterator UI) const {
return isDataOperand(&UI.getUse());
}
- /// \brief Determine whether the passed use points to a data operand.
+ /// 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();
}
@@ -200,9 +205,9 @@ public:
return U - arg_begin();
}
- /// arg_iterator - The type of iterator to use when looping over actual
- /// arguments at this call site.
- typedef IterTy arg_iterator;
+ /// 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());
@@ -210,8 +215,7 @@ public:
bool arg_empty() const { return arg_end() == arg_begin(); }
unsigned arg_size() const { return unsigned(arg_end() - arg_begin()); }
- /// Given a value use iterator, returns the data operand that corresponds to
- /// it.
+ /// 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());
@@ -227,7 +231,7 @@ public:
/// Type of iterator to use when looping over data operands at this call site
/// (see below).
- typedef IterTy data_operand_iterator;
+ using data_operand_iterator = IterTy;
/// data_operands_begin/data_operands_end - Return iterators iterating over
/// the call / invoke argument list and bundle operands. For invokes, this is
@@ -253,21 +257,19 @@ public:
return std::distance(data_operands_begin(), data_operands_end());
}
- /// getType - Return the type of the instruction that generated this call site
- ///
+ /// Return the type of the instruction that generated this call site.
Type *getType() const { return (*this)->getType(); }
- /// getCaller - Return the caller function for this call site
- ///
+ /// Return the caller function for this call site.
FunTy *getCaller() const { return (*this)->getParent()->getParent(); }
- /// \brief Tests if this call site must be tail call optimized. Only a
- /// CallInst can be tail call optimized.
+ /// 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();
}
- /// \brief Tests if this call site is marked as a tail call.
+ /// Tests if this call site is marked as a tail call.
bool isTailCall() const {
return isCall() && cast<CallInst>(getInstruction())->isTailCall();
}
@@ -303,11 +305,11 @@ public:
return false;
}
- /// getCallingConv/setCallingConv - get or set the calling convention of the
- /// call.
+ /// 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));
}
@@ -320,12 +322,12 @@ public:
CALLSITE_DELEGATE_SETTER(mutateFunctionType(Ty));
}
- /// getAttributes/setAttributes - get or set the parameter attributes of
- /// the call.
- AttributeSet getAttributes() const {
+ /// Get the parameter attributes of the call.
+ AttributeList getAttributes() const {
CALLSITE_DELEGATE_GETTER(getAttributes());
}
- void setAttributes(AttributeSet PAL) {
+ /// Set the parameter attributes of the call.
+ void setAttributes(AttributeList PAL) {
CALLSITE_DELEGATE_SETTER(setAttributes(PAL));
}
@@ -337,6 +339,10 @@ public:
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));
}
@@ -345,19 +351,28 @@ public:
CALLSITE_DELEGATE_SETTER(removeAttribute(i, Kind));
}
- /// \brief Return true if this function has the given attribute.
+ 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));
}
- /// \brief Return true if this function has the given attribute.
+ /// Return true if this function has the given attribute.
bool hasFnAttr(StringRef Kind) const {
CALLSITE_DELEGATE_GETTER(hasFnAttr(Kind));
}
- /// \brief Return true if the call or the callee has the given attribute.
- bool paramHasAttr(unsigned i, Attribute::AttrKind Kind) const {
- CALLSITE_DELEGATE_GETTER(paramHasAttr(i, 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 {
@@ -368,8 +383,8 @@ public:
CALLSITE_DELEGATE_GETTER(getAttribute(i, Kind));
}
- /// \brief Return true if the data operand at index \p i directly or
- /// indirectly has the attribute \p A.
+ /// Return true if the data operand at index \p i directly or indirectly has
+ /// the attribute \p A.
///
/// Normal call or invoke arguments have per operand attributes, as specified
/// in the attribute set attached to this instruction, while operand bundle
@@ -379,37 +394,39 @@ public:
CALLSITE_DELEGATE_GETTER(dataOperandHasImpliedAttr(i, Kind));
}
- /// @brief Extract the alignment for a call or parameter (0=unknown).
- uint16_t getParamAlignment(uint16_t i) const {
- CALLSITE_DELEGATE_GETTER(getParamAlignment(i));
+ /// Extract the alignment of the return value.
+ unsigned getRetAlignment() const {
+ CALLSITE_DELEGATE_GETTER(getRetAlignment());
}
- /// @brief Extract the number of dereferenceable bytes for a call or
- /// parameter (0=unknown).
- uint64_t getDereferenceableBytes(uint16_t i) const {
+ /// Extract the alignment for a call or parameter (0=unknown).
+ unsigned getParamAlignment(unsigned ArgNo) const {
+ CALLSITE_DELEGATE_GETTER(getParamAlignment(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));
}
- /// @brief Extract the number of dereferenceable_or_null bytes for a call or
+ /// Extract the number of dereferenceable_or_null bytes for a call or
/// parameter (0=unknown).
- uint64_t getDereferenceableOrNullBytes(uint16_t i) const {
+ uint64_t getDereferenceableOrNullBytes(unsigned i) const {
CALLSITE_DELEGATE_GETTER(getDereferenceableOrNullBytes(i));
}
- /// @brief Determine if the parameter or return value is marked with NoAlias
- /// attribute.
- /// @param n The parameter to check. 1 is the first parameter, 0 is the return
- bool doesNotAlias(unsigned n) const {
- CALLSITE_DELEGATE_GETTER(doesNotAlias(n));
+ /// Determine if the return value is marked with NoAlias attribute.
+ bool returnDoesNotAlias() const {
+ CALLSITE_DELEGATE_GETTER(returnDoesNotAlias());
}
- /// \brief Return true if the call should not be treated as a call to a
- /// builtin.
+ /// Return true if the call should not be treated as a call to a builtin.
bool isNoBuiltin() const {
CALLSITE_DELEGATE_GETTER(isNoBuiltin());
}
- /// @brief Return true if the call should not be inlined.
+ /// Return true if the call should not be inlined.
bool isNoInline() const {
CALLSITE_DELEGATE_GETTER(isNoInline());
}
@@ -417,7 +434,7 @@ public:
CALLSITE_DELEGATE_SETTER(setIsNoInline(Value));
}
- /// @brief Determine if the call does not access memory.
+ /// Determine if the call does not access memory.
bool doesNotAccessMemory() const {
CALLSITE_DELEGATE_GETTER(doesNotAccessMemory());
}
@@ -425,7 +442,7 @@ public:
CALLSITE_DELEGATE_SETTER(setDoesNotAccessMemory());
}
- /// @brief Determine if the call does not access or only reads memory.
+ /// Determine if the call does not access or only reads memory.
bool onlyReadsMemory() const {
CALLSITE_DELEGATE_GETTER(onlyReadsMemory());
}
@@ -433,7 +450,7 @@ public:
CALLSITE_DELEGATE_SETTER(setOnlyReadsMemory());
}
- /// @brief Determine if the call does not access or only writes memory.
+ /// Determine if the call does not access or only writes memory.
bool doesNotReadMemory() const {
CALLSITE_DELEGATE_GETTER(doesNotReadMemory());
}
@@ -441,7 +458,7 @@ public:
CALLSITE_DELEGATE_SETTER(setDoesNotReadMemory());
}
- /// @brief Determine if the call can access memmory only using pointers based
+ /// Determine if the call can access memmory only using pointers based
/// on its arguments.
bool onlyAccessesArgMemory() const {
CALLSITE_DELEGATE_GETTER(onlyAccessesArgMemory());
@@ -450,7 +467,7 @@ public:
CALLSITE_DELEGATE_SETTER(setOnlyAccessesArgMemory());
}
- /// @brief Determine if the call cannot return.
+ /// Determine if the call cannot return.
bool doesNotReturn() const {
CALLSITE_DELEGATE_GETTER(doesNotReturn());
}
@@ -458,7 +475,7 @@ public:
CALLSITE_DELEGATE_SETTER(setDoesNotReturn());
}
- /// @brief Determine if the call cannot unwind.
+ /// Determine if the call cannot unwind.
bool doesNotThrow() const {
CALLSITE_DELEGATE_GETTER(doesNotThrow());
}
@@ -466,7 +483,7 @@ public:
CALLSITE_DELEGATE_SETTER(setDoesNotThrow());
}
- /// @brief Determine if the call can be duplicated.
+ /// Determine if the call can be duplicated.
bool cannotDuplicate() const {
CALLSITE_DELEGATE_GETTER(cannotDuplicate());
}
@@ -474,7 +491,7 @@ public:
CALLSITE_DELEGATE_GETTER(setCannotDuplicate());
}
- /// @brief Determine if the call is convergent.
+ /// Determine if the call is convergent.
bool isConvergent() const {
CALLSITE_DELEGATE_GETTER(isConvergent());
}
@@ -546,31 +563,31 @@ public:
cast<InvokeInst>(II)->getOperandBundlesAsDefs(Defs);
}
- /// @brief Determine whether this data operand is not captured.
+ /// Determine whether this data operand is not captured.
bool doesNotCapture(unsigned OpNo) const {
return dataOperandHasImpliedAttr(OpNo + 1, Attribute::NoCapture);
}
- /// @brief Determine whether this argument is passed by value.
+ /// Determine whether this argument is passed by value.
bool isByValArgument(unsigned ArgNo) const {
- return paramHasAttr(ArgNo + 1, Attribute::ByVal);
+ return paramHasAttr(ArgNo, Attribute::ByVal);
}
- /// @brief Determine whether this argument is passed in an alloca.
+ /// Determine whether this argument is passed in an alloca.
bool isInAllocaArgument(unsigned ArgNo) const {
- return paramHasAttr(ArgNo + 1, Attribute::InAlloca);
+ return paramHasAttr(ArgNo, Attribute::InAlloca);
}
- /// @brief Determine whether this argument is passed by value or in an alloca.
+ /// Determine whether this argument is passed by value or in an alloca.
bool isByValOrInAllocaArgument(unsigned ArgNo) const {
- return paramHasAttr(ArgNo + 1, Attribute::ByVal) ||
- paramHasAttr(ArgNo + 1, Attribute::InAlloca);
+ return paramHasAttr(ArgNo, Attribute::ByVal) ||
+ paramHasAttr(ArgNo, Attribute::InAlloca);
}
- /// @brief Determine if there are is an inalloca argument. Only the last
- /// argument can have the inalloca attribute.
+ /// Determine if there are is an inalloca argument. Only the last argument can
+ /// have the inalloca attribute.
bool hasInAllocaArgument() const {
- return paramHasAttr(arg_size(), Attribute::InAlloca);
+ return !arg_empty() && paramHasAttr(arg_size() - 1, Attribute::InAlloca);
}
bool doesNotAccessMemory(unsigned OpNo) const {
@@ -582,21 +599,26 @@ public:
dataOperandHasImpliedAttr(OpNo + 1, Attribute::ReadNone);
}
- /// @brief Return true if the return value is known to be not null.
+ 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 (paramHasAttr(0, Attribute::NonNull))
+ if (hasRetAttr(Attribute::NonNull))
return true;
- else if (getDereferenceableBytes(0) > 0 &&
+ else if (getDereferenceableBytes(AttributeList::ReturnIndex) > 0 &&
getType()->getPointerAddressSpace() == 0)
return true;
return false;
}
- /// hasArgument - Returns true if this CallSite passes the given Value* as an
- /// argument to the called function.
+ /// 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)
@@ -661,7 +683,7 @@ template <> struct DenseMapInfo<CallSite> {
}
};
-/// ImmutableCallSite - establish a view to a call site for examination
+/// Establish a view to a call site for examination.
class ImmutableCallSite : public CallSiteBase<> {
public:
ImmutableCallSite() = default;
diff --git a/contrib/llvm/include/llvm/IR/CallingConv.h b/contrib/llvm/include/llvm/IR/CallingConv.h
index 9cfbda1..850964a 100644
--- a/contrib/llvm/include/llvm/IR/CallingConv.h
+++ b/contrib/llvm/include/llvm/IR/CallingConv.h
@@ -1,4 +1,4 @@
-//===-- llvm/CallingConv.h - LLVM Calling Conventions -----------*- C++ -*-===//
+//===- llvm/CallingConv.h - LLVM Calling Conventions ------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -20,8 +20,9 @@ namespace llvm {
/// the well-known calling conventions.
///
namespace CallingConv {
+
/// LLVM IR allows to use arbitrary numbers as calling convention identifiers.
- typedef unsigned ID;
+ using ID = unsigned;
/// A set of enums which specify the assigned numeric values for known llvm
/// calling conventions.
@@ -142,11 +143,15 @@ namespace CallingConv {
/// System V ABI, used on most non-Windows systems.
X86_64_SysV = 78,
- /// \brief The C convention as implemented on Windows/x86-64. This
- /// convention differs from the more common \c X86_64_SysV convention
- /// in a number of ways, most notably in that XMM registers used to pass
- /// arguments are shadowed by GPRs, and vice versa.
- X86_64_Win64 = 79,
+ /// \brief The C convention as implemented on Windows/x86-64 and
+ /// AArch64. This convention differs from the more common
+ /// \c X86_64_SysV convention in a number of ways, most notably in
+ /// that XMM registers used to pass arguments are shadowed by GPRs,
+ /// and vice versa.
+ /// On AArch64, this is identical to the normal C (AAPCS) calling
+ /// convention for normal functions, but floats are passed in integer
+ /// registers to variadic functions.
+ Win64 = 79,
/// \brief MSVC calling convention that passes vectors and vector aggregates
/// in SSE registers.
@@ -196,11 +201,20 @@ namespace CallingConv {
/// Register calling convention used for parameters transfer optimization
X86_RegCall = 92,
+ /// Calling convention used for Mesa hull shaders. (= tessellation control
+ /// shaders)
+ AMDGPU_HS = 93,
+
+ /// Calling convention used for special MSP430 rtlib functions
+ /// which have an "optimized" convention using additional registers.
+ MSP430_BUILTIN = 94,
+
/// The highest possible calling convention ID. Must be some 2^k - 1.
MaxID = 1023
};
-} // End CallingConv namespace
-} // End llvm namespace
+} // end namespace CallingConv
+
+} // end namespace llvm
-#endif
+#endif // LLVM_IR_CALLINGCONV_H
diff --git a/contrib/llvm/include/llvm/IR/Comdat.h b/contrib/llvm/include/llvm/IR/Comdat.h
index f4a391c..fa87093 100644
--- a/contrib/llvm/include/llvm/IR/Comdat.h
+++ b/contrib/llvm/include/llvm/IR/Comdat.h
@@ -1,4 +1,4 @@
-//===-- llvm/IR/Comdat.h - Comdat definitions -------------------*- C++ -*-===//
+//===- llvm/IR/Comdat.h - Comdat definitions --------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -51,8 +51,8 @@ private:
Comdat();
// Points to the map in Module.
- StringMapEntry<Comdat> *Name;
- SelectionKind SK;
+ StringMapEntry<Comdat> *Name = nullptr;
+ SelectionKind SK = Any;
};
inline raw_ostream &operator<<(raw_ostream &OS, const Comdat &C) {
diff --git a/contrib/llvm/include/llvm/IR/Constant.h b/contrib/llvm/include/llvm/IR/Constant.h
index 99c970e..9daeac6 100644
--- a/contrib/llvm/include/llvm/IR/Constant.h
+++ b/contrib/llvm/include/llvm/IR/Constant.h
@@ -40,8 +40,6 @@ class APInt;
/// don't have to worry about the lifetime of the objects.
/// @brief LLVM Constant Representation
class Constant : public User {
- void anchor() override;
-
protected:
Constant(Type *ty, ValueTy vty, Use *Ops, unsigned NumOps)
: User(ty, vty, Ops, NumOps) {}
@@ -118,7 +116,7 @@ public:
void destroyConstant();
//// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return V->getValueID() >= ConstantFirstVal &&
V->getValueID() <= ConstantLastVal;
}
@@ -152,12 +150,13 @@ public:
/// hanging off of the globals.
void removeDeadConstantUsers() const;
- Constant *stripPointerCasts() {
+ const Constant *stripPointerCasts() const {
return cast<Constant>(Value::stripPointerCasts());
}
- const Constant *stripPointerCasts() const {
- return const_cast<Constant*>(this)->stripPointerCasts();
+ Constant *stripPointerCasts() {
+ return const_cast<Constant*>(
+ static_cast<const Constant *>(this)->stripPointerCasts());
}
};
diff --git a/contrib/llvm/include/llvm/IR/ConstantRange.h b/contrib/llvm/include/llvm/IR/ConstantRange.h
index 27a9b13..ff6495e 100644
--- a/contrib/llvm/include/llvm/IR/ConstantRange.h
+++ b/contrib/llvm/include/llvm/IR/ConstantRange.h
@@ -34,33 +34,30 @@
#include "llvm/ADT/APInt.h"
#include "llvm/IR/InstrTypes.h"
-#include "llvm/Support/DataTypes.h"
+#include "llvm/IR/Instruction.h"
+#include "llvm/Support/Compiler.h"
+#include <cstdint>
namespace llvm {
class MDNode;
+class raw_ostream;
/// This class represents a range of values.
-///
-class ConstantRange {
+class LLVM_NODISCARD ConstantRange {
APInt Lower, Upper;
- // If we have move semantics, pass APInts by value and move them into place.
- typedef APInt APIntMoveTy;
-
public:
/// Initialize a full (the default) or empty set for the specified bit width.
- ///
explicit ConstantRange(uint32_t BitWidth, bool isFullSet = true);
/// Initialize a range to hold the single specified value.
- ///
- ConstantRange(APIntMoveTy Value);
+ ConstantRange(APInt Value);
/// @brief Initialize a range of values explicitly. This will assert out if
/// Lower==Upper and Lower != Min or Max value for its type. It will also
/// assert out if the two APInt's are not the same bit width.
- ConstantRange(APIntMoveTy Lower, APIntMoveTy Upper);
+ ConstantRange(APInt Lower, APInt Upper);
/// Produce the smallest range such that all values that may satisfy the given
/// predicate with any value contained within Other is contained in the
@@ -99,7 +96,7 @@ public:
///
/// NB! The returned set does *not* contain **all** possible values of X for
/// which "X BinOpC Y" does not wrap -- some viable values of X may be
- /// missing, so you cannot use this to contrain X's range. E.g. in the last
+ /// missing, so you cannot use this to constrain X's range. E.g. in the last
/// example, "(-2) + 1" is both nsw and nuw (so the "X" could be -2), but (-2)
/// is not in the set returned.
///
@@ -122,46 +119,36 @@ public:
bool getEquivalentICmp(CmpInst::Predicate &Pred, APInt &RHS) const;
/// Return the lower value for this range.
- ///
const APInt &getLower() const { return Lower; }
/// Return the upper value for this range.
- ///
const APInt &getUpper() const { return Upper; }
/// Get the bit width of this ConstantRange.
- ///
uint32_t getBitWidth() const { return Lower.getBitWidth(); }
/// Return true if this set contains all of the elements possible
/// for this data-type.
- ///
bool isFullSet() const;
/// Return true if this set contains no members.
- ///
bool isEmptySet() const;
/// Return true if this set wraps around the top of the range.
/// For example: [100, 8).
- ///
bool isWrappedSet() const;
/// Return true if this set wraps around the INT_MIN of
/// its bitwidth. For example: i8 [120, 140).
- ///
bool isSignWrappedSet() const;
/// Return true if the specified value is in the set.
- ///
bool contains(const APInt &Val) const;
/// Return true if the other range is a subset of this one.
- ///
bool contains(const ConstantRange &CR) const;
/// If this set contains a single element, return it, otherwise return null.
- ///
const APInt *getSingleElement() const {
if (Upper == Lower + 1)
return &Lower;
@@ -177,31 +164,30 @@ public:
}
/// Return true if this set contains exactly one member.
- ///
bool isSingleElement() const { return getSingleElement() != nullptr; }
/// Return the number of elements in this set.
- ///
APInt getSetSize() const;
+ /// Compare set size of this range with the range CR.
+ bool isSizeStrictlySmallerThan(const ConstantRange &CR) const;
+
+ // Compare set size of this range with Value.
+ bool isSizeLargerThan(uint64_t MaxSize) const;
+
/// Return the largest unsigned value contained in the ConstantRange.
- ///
APInt getUnsignedMax() const;
/// Return the smallest unsigned value contained in the ConstantRange.
- ///
APInt getUnsignedMin() const;
/// Return the largest signed value contained in the ConstantRange.
- ///
APInt getSignedMax() const;
/// Return the smallest signed value contained in the ConstantRange.
- ///
APInt getSignedMin() const;
/// Return true if this range is equal to another range.
- ///
bool operator==(const ConstantRange &CR) const {
return Lower == CR.Lower && Upper == CR.Upper;
}
@@ -212,8 +198,8 @@ public:
/// Subtract the specified constant from the endpoints of this constant range.
ConstantRange subtract(const APInt &CI) const;
- /// \brief Subtract the specified range from this range (aka relative
- /// complement of the sets).
+ /// Subtract the specified range from this range (aka relative complement of
+ /// the sets).
ConstantRange difference(const ConstantRange &CR) const;
/// Return the range that results from the intersection of
@@ -222,7 +208,6 @@ public:
/// smallest possible set size that does so. Because there may be two
/// intersections with the same set size, A.intersectWith(B) might not
/// be equal to B.intersectWith(A).
- ///
ConstantRange intersectWith(const ConstantRange &CR) const;
/// Return the range that results from the union of this range
@@ -230,7 +215,6 @@ public:
/// elements of both sets, but may contain more. For example, [3, 9) union
/// [12,15) is [3, 15), which includes 9, 10, and 11, which were not included
/// in either set before.
- ///
ConstantRange unionWith(const ConstantRange &CR) const;
/// Return a new range representing the possible values resulting
@@ -330,15 +314,12 @@ public:
ConstantRange lshr(const ConstantRange &Other) const;
/// Return a new range that is the logical not of the current set.
- ///
ConstantRange inverse() const;
/// Print out the bounds to a stream.
- ///
void print(raw_ostream &OS) const;
/// Allow printing from a debugger easily.
- ///
void dump() const;
};
@@ -352,6 +333,6 @@ inline raw_ostream &operator<<(raw_ostream &OS, const ConstantRange &CR) {
/// E.g. if RangeMD is !{i32 0, i32 10, i32 15, i32 20} then return [0, 20).
ConstantRange getConstantRangeFromMetadata(const MDNode &RangeMD);
-} // End llvm namespace
+} // end namespace llvm
-#endif
+#endif // LLVM_IR_CONSTANTRANGE_H
diff --git a/contrib/llvm/include/llvm/IR/Constants.h b/contrib/llvm/include/llvm/IR/Constants.h
index cbefa3f..0094fd5 100644
--- a/contrib/llvm/include/llvm/IR/Constants.h
+++ b/contrib/llvm/include/llvm/IR/Constants.h
@@ -26,6 +26,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/None.h"
#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/IR/Constant.h"
#include "llvm/IR/DerivedTypes.h"
@@ -57,8 +58,6 @@ template <class ConstantClass> struct ConstantAggrKeyType;
class ConstantData : public Constant {
friend class Constant;
- void anchor() override;
-
Value *handleOperandChangeImpl(Value *From, Value *To) {
llvm_unreachable("Constant data does not have operands!");
}
@@ -69,11 +68,8 @@ protected:
void *operator new(size_t s) { return User::operator new(s, 0); }
public:
- ConstantData() = delete;
ConstantData(const ConstantData &) = delete;
- void *operator new(size_t, unsigned) = delete;
-
/// Methods to support type inquiry through isa, cast, and dyn_cast.
static bool classof(const Value *V) {
return V->getValueID() >= ConstantDataFirstVal &&
@@ -92,7 +88,6 @@ class ConstantInt final : public ConstantData {
ConstantInt(IntegerType *Ty, const APInt& V);
- void anchor() override;
void destroyConstantImpl();
public:
@@ -138,7 +133,7 @@ public:
static Constant *get(Type* Ty, const APInt& V);
/// Return the constant as an APInt value reference. This allows clients to
- /// obtain a copy of the value, with all its precision in tact.
+ /// obtain a full-precision copy of the value.
/// @brief Return the constant's value.
inline const APInt &getValue() const {
return Val;
@@ -196,7 +191,7 @@ public:
/// common code. It also correctly performs the comparison without the
/// potential for an assertion from getZExtValue().
bool isZero() const {
- return Val == 0;
+ return Val.isNullValue();
}
/// This is just a convenience method to make client code smaller for a
@@ -204,7 +199,7 @@ public:
/// potential for an assertion from getZExtValue().
/// @brief Determine if the value is one.
bool isOne() const {
- return Val == 1;
+ return Val.isOneValue();
}
/// This function will return true iff every bit in this constant is set
@@ -245,7 +240,7 @@ public:
/// @returns true iff this constant is greater or equal to the given number.
/// @brief Determine if the value is greater or equal to the given number.
bool uge(uint64_t Num) const {
- return Val.getActiveBits() > 64 || Val.getZExtValue() >= Num;
+ return Val.uge(Num);
}
/// getLimitedValue - If the value is smaller than the specified limit,
@@ -273,7 +268,6 @@ class ConstantFP final : public ConstantData {
ConstantFP(Type *Ty, const APFloat& V);
- void anchor() override;
void destroyConstantImpl();
public:
@@ -452,7 +446,14 @@ class ConstantStruct final : public ConstantAggregate {
public:
// ConstantStruct accessors
static Constant *get(StructType *T, ArrayRef<Constant*> V);
- static Constant *get(StructType *T, ...) LLVM_END_WITH_NULL;
+
+ template <typename... Csts>
+ static typename std::enable_if<are_base_of<Constant, Csts...>::value,
+ Constant *>::type
+ get(StructType *T, Csts *... Vs) {
+ SmallVector<Constant *, 8> Values({Vs...});
+ return get(T, Values);
+ }
/// Return an anonymous struct that has the specified elements.
/// If the struct is possibly empty, then you must specify a context.
@@ -580,7 +581,7 @@ class ConstantDataSequential : public ConstantData {
protected:
explicit ConstantDataSequential(Type *ty, ValueTy VT, const char *Data)
: ConstantData(ty, VT), DataElements(Data), Next(nullptr) {}
- ~ConstantDataSequential() override { delete Next; }
+ ~ConstantDataSequential() { delete Next; }
static Constant *getImpl(StringRef Bytes, Type *Ty);
@@ -597,6 +598,10 @@ public:
/// specified element in the low bits of a uint64_t.
uint64_t getElementAsInteger(unsigned i) const;
+ /// If this is a sequential container of integers (of any size), return the
+ /// specified element as an APInt.
+ APInt getElementAsAPInt(unsigned i) const;
+
/// If this is a sequential container of floating point type, return the
/// specified element as an APFloat.
APFloat getElementAsAPFloat(unsigned i) const;
@@ -630,8 +635,8 @@ public:
/// The size of the elements is known to be a multiple of one byte.
uint64_t getElementByteSize() const;
- /// This method returns true if this is an array of i8.
- bool isString() const;
+ /// This method returns true if this is an array of \p CharSize integers.
+ bool isString(unsigned CharSize = 8) const;
/// This method returns true if the array "isString", ends with a null byte,
/// and does not contains any other null bytes.
@@ -679,18 +684,9 @@ class ConstantDataArray final : public ConstantDataSequential {
explicit ConstantDataArray(Type *ty, const char *Data)
: ConstantDataSequential(ty, ConstantDataArrayVal, Data) {}
- /// Allocate space for exactly zero operands.
- void *operator new(size_t s) {
- return User::operator new(s, 0);
- }
-
- void anchor() override;
-
public:
ConstantDataArray(const ConstantDataArray &) = delete;
- void *operator new(size_t, unsigned) = delete;
-
/// get() constructors - Return a constant with array type with an element
/// count and element type matching the ArrayRef passed in. Note that this
/// can return a ConstantAggregateZero object.
@@ -742,18 +738,9 @@ class ConstantDataVector final : public ConstantDataSequential {
explicit ConstantDataVector(Type *ty, const char *Data)
: ConstantDataSequential(ty, ConstantDataVectorVal, Data) {}
- // allocate space for exactly zero operands.
- void *operator new(size_t s) {
- return User::operator new(s, 0);
- }
-
- void anchor() override;
-
public:
ConstantDataVector(const ConstantDataVector &) = delete;
- void *operator new(size_t, unsigned) = delete;
-
/// get() constructors - Return a constant with vector type with an element
/// count and element type matching the ArrayRef passed in. Note that this
/// can return a ConstantAggregateZero object.
@@ -778,6 +765,10 @@ public:
/// i32/i64/float/double) and must be a ConstantFP or ConstantInt.
static Constant *getSplat(unsigned NumElts, Constant *Elt);
+ /// Returns true if this is a splat constant, meaning that all elements have
+ /// the same value.
+ bool isSplat() const;
+
/// If this is a splat constant, meaning that all of the elements have the
/// same value, return that value. Otherwise return NULL.
Constant *getSplatValue() const;
@@ -830,8 +821,6 @@ class BlockAddress final : public Constant {
Value *handleOperandChangeImpl(Value *From, Value *To);
public:
- void *operator new(size_t, unsigned) = delete;
-
/// Return a BlockAddress for the specified function and basic block.
static BlockAddress *get(Function *F, BasicBlock *BB);
@@ -851,7 +840,7 @@ public:
BasicBlock *getBasicBlock() const { return (BasicBlock*)Op<1>().get(); }
/// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return V->getValueID() == BlockAddressVal;
}
};
@@ -1226,7 +1215,7 @@ public:
Instruction *getAsInstruction();
/// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return V->getValueID() == ConstantExprVal;
}
diff --git a/contrib/llvm/include/llvm/IR/DIBuilder.h b/contrib/llvm/include/llvm/IR/DIBuilder.h
index 48cb7fe..6a14f78 100644
--- a/contrib/llvm/include/llvm/IR/DIBuilder.h
+++ b/contrib/llvm/include/llvm/IR/DIBuilder.h
@@ -86,6 +86,10 @@ namespace llvm {
/// Construct any deferred debug info descriptors.
void finalize();
+ /// Finalize a specific subprogram - no new variables may be added to this
+ /// subprogram afterwards.
+ void finalizeSubprogram(DISubprogram *SP);
+
/// A CompileUnit provides an anchor for all debugging
/// information generated during this instance of compilation.
/// \param Lang Source programming language, eg. dwarf::DW_LANG_C99
@@ -105,13 +109,17 @@ namespace llvm {
/// out into.
/// \param Kind The kind of debug information to generate.
/// \param DWOId The DWOId if this is a split skeleton compile unit.
+ /// \param SplitDebugInlining Whether to emit inline debug info.
+ /// \param DebugInfoForProfiling Whether to emit extra debug info for
+ /// profile collection.
DICompileUnit *
createCompileUnit(unsigned Lang, DIFile *File, StringRef Producer,
bool isOptimized, StringRef Flags, unsigned RV,
StringRef SplitName = StringRef(),
DICompileUnit::DebugEmissionKind Kind =
DICompileUnit::DebugEmissionKind::FullDebug,
- uint64_t DWOId = 0, bool SplitDebugInlining = true);
+ uint64_t DWOId = 0, bool SplitDebugInlining = true,
+ bool DebugInfoForProfiling = false);
/// Create a file descriptor to hold debugging information for a file.
/// \param Filename File name.
@@ -164,12 +172,15 @@ namespace llvm {
DIDerivedType *createQualifiedType(unsigned Tag, DIType *FromTy);
/// Create debugging information entry for a pointer.
- /// \param PointeeTy Type pointed by this pointer.
- /// \param SizeInBits Size.
- /// \param AlignInBits Alignment. (optional)
- /// \param Name Pointer type name. (optional)
+ /// \param PointeeTy Type pointed by this pointer.
+ /// \param SizeInBits Size.
+ /// \param AlignInBits Alignment. (optional)
+ /// \param DWARFAddressSpace DWARF address space. (optional)
+ /// \param Name Pointer type name. (optional)
DIDerivedType *createPointerType(DIType *PointeeTy, uint64_t SizeInBits,
uint32_t AlignInBits = 0,
+ Optional<unsigned> DWARFAddressSpace =
+ None,
StringRef Name = "");
/// Create debugging information entry for a pointer to member.
@@ -186,7 +197,9 @@ namespace llvm {
/// style reference or rvalue reference type.
DIDerivedType *createReferenceType(unsigned Tag, DIType *RTy,
uint64_t SizeInBits = 0,
- uint32_t AlignInBits = 0);
+ uint32_t AlignInBits = 0,
+ Optional<unsigned> DWARFAddressSpace =
+ None);
/// Create debugging information entry for a typedef.
/// \param Ty Original type.
@@ -431,13 +444,6 @@ namespace llvm {
DINode::DIFlags Flags = DINode::FlagZero,
unsigned CC = 0);
- /// Create an external type reference.
- /// \param Tag Dwarf TAG.
- /// \param File File in which the type is defined.
- /// \param UniqueIdentifier A unique identifier for the type.
- DICompositeType *createExternalTypeRef(unsigned Tag, DIFile *File,
- StringRef UniqueIdentifier);
-
/// Create a new DIType* with "artificial" flag set.
DIType *createArtificialType(DIType *Ty);
@@ -575,15 +581,14 @@ namespace llvm {
/// These flags are used to emit dwarf attributes.
/// \param isOptimized True if optimization is ON.
/// \param TParams Function template parameters.
- DISubprogram *createFunction(DIScope *Scope, StringRef Name,
- StringRef LinkageName, DIFile *File,
- unsigned LineNo, DISubroutineType *Ty,
- bool isLocalToUnit, bool isDefinition,
- unsigned ScopeLine,
- DINode::DIFlags Flags = DINode::FlagZero,
- bool isOptimized = false,
- DITemplateParameterArray TParams = nullptr,
- DISubprogram *Decl = nullptr);
+ /// \param ThrownTypes Exception types this function may throw.
+ DISubprogram *createFunction(
+ DIScope *Scope, StringRef Name, StringRef LinkageName, DIFile *File,
+ unsigned LineNo, DISubroutineType *Ty, bool isLocalToUnit,
+ bool isDefinition, unsigned ScopeLine,
+ DINode::DIFlags Flags = DINode::FlagZero, bool isOptimized = false,
+ DITemplateParameterArray TParams = nullptr,
+ DISubprogram *Decl = nullptr, DITypeArray ThrownTypes = nullptr);
/// Identical to createFunction,
/// except that the resulting DbgNode is meant to be RAUWed.
@@ -593,7 +598,7 @@ namespace llvm {
bool isDefinition, unsigned ScopeLine,
DINode::DIFlags Flags = DINode::FlagZero, bool isOptimized = false,
DITemplateParameterArray TParams = nullptr,
- DISubprogram *Decl = nullptr);
+ DISubprogram *Decl = nullptr, DITypeArray ThrownTypes = nullptr);
/// Create a new descriptor for the specified C++ method.
/// See comments in \a DISubprogram* for descriptions of these fields.
@@ -617,23 +622,23 @@ namespace llvm {
/// This flags are used to emit dwarf attributes.
/// \param isOptimized True if optimization is ON.
/// \param TParams Function template parameters.
+ /// \param ThrownTypes Exception types this function may throw.
DISubprogram *createMethod(
DIScope *Scope, StringRef Name, StringRef LinkageName, DIFile *File,
unsigned LineNo, DISubroutineType *Ty, bool isLocalToUnit,
bool isDefinition, unsigned Virtuality = 0, unsigned VTableIndex = 0,
int ThisAdjustment = 0, DIType *VTableHolder = nullptr,
DINode::DIFlags Flags = DINode::FlagZero, bool isOptimized = false,
- DITemplateParameterArray TParams = nullptr);
+ DITemplateParameterArray TParams = nullptr,
+ DITypeArray ThrownTypes = nullptr);
/// This creates new descriptor for a namespace with the specified
/// parent scope.
/// \param Scope Namespace scope
/// \param Name Name of this namespace
- /// \param File Source file
- /// \param LineNo Line number
/// \param ExportSymbols True for C++ inline namespaces.
- DINamespace *createNameSpace(DIScope *Scope, StringRef Name, DIFile *File,
- unsigned LineNo, bool ExportSymbols);
+ DINamespace *createNameSpace(DIScope *Scope, StringRef Name,
+ bool ExportSymbols);
/// This creates new descriptor for a module with the specified
/// parent scope.
@@ -669,32 +674,37 @@ namespace llvm {
/// Create a descriptor for an imported module.
/// \param Context The scope this module is imported into
- /// \param NS The namespace being imported here
- /// \param Line Line number
+ /// \param NS The namespace being imported here.
+ /// \param File File where the declaration is located.
+ /// \param Line Line number of the declaration.
DIImportedEntity *createImportedModule(DIScope *Context, DINamespace *NS,
- unsigned Line);
+ DIFile *File, unsigned Line);
/// Create a descriptor for an imported module.
- /// \param Context The scope this module is imported into
- /// \param NS An aliased namespace
- /// \param Line Line number
+ /// \param Context The scope this module is imported into.
+ /// \param NS An aliased namespace.
+ /// \param File File where the declaration is located.
+ /// \param Line Line number of the declaration.
DIImportedEntity *createImportedModule(DIScope *Context,
- DIImportedEntity *NS, unsigned Line);
+ DIImportedEntity *NS, DIFile *File,
+ unsigned Line);
/// Create a descriptor for an imported module.
- /// \param Context The scope this module is imported into
- /// \param M The module being imported here
- /// \param Line Line number
+ /// \param Context The scope this module is imported into.
+ /// \param M The module being imported here
+ /// \param File File where the declaration is located.
+ /// \param Line Line number of the declaration.
DIImportedEntity *createImportedModule(DIScope *Context, DIModule *M,
- unsigned Line);
+ DIFile *File, unsigned Line);
/// Create a descriptor for an imported function.
- /// \param Context The scope this module is imported into
- /// \param Decl The declaration (or definition) of a function, type, or
- /// variable
- /// \param Line Line number
+ /// \param Context The scope this module is imported into.
+ /// \param Decl The declaration (or definition) of a function, type, or
+ /// variable.
+ /// \param File File where the declaration is located.
+ /// \param Line Line number of the declaration.
DIImportedEntity *createImportedDeclaration(DIScope *Context, DINode *Decl,
- unsigned Line,
+ DIFile *File, unsigned Line,
StringRef Name = "");
/// Insert a new llvm.dbg.declare intrinsic call.
@@ -776,6 +786,9 @@ namespace llvm {
}
};
+ // Create wrappers for C Binding types (see CBindingWrapping.h).
+ DEFINE_ISA_CONVERSION_FUNCTIONS(DIBuilder, LLVMDIBuilderRef)
+
} // end namespace llvm
#endif // LLVM_IR_DIBUILDER_H
diff --git a/contrib/llvm/include/llvm/IR/DataLayout.h b/contrib/llvm/include/llvm/IR/DataLayout.h
index 6f37669..daf8f8d 100644
--- a/contrib/llvm/include/llvm/IR/DataLayout.h
+++ b/contrib/llvm/include/llvm/IR/DataLayout.h
@@ -1,4 +1,4 @@
-//===--------- llvm/DataLayout.h - Data size & alignment info ---*- C++ -*-===//
+//===- llvm/DataLayout.h - Data size & alignment info -----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -20,27 +20,32 @@
#ifndef LLVM_IR_DATALAYOUT_H
#define LLVM_IR_DATALAYOUT_H
-#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Type.h"
#include "llvm/Pass.h"
-#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/MathExtras.h"
+#include <cassert>
+#include <cstdint>
+#include <string>
// This needs to be outside of the namespace, to avoid conflict with llvm-c
// decl.
-typedef struct LLVMOpaqueTargetData *LLVMTargetDataRef;
+using LLVMTargetDataRef = struct LLVMOpaqueTargetData *;
namespace llvm {
-class Value;
-class StructType;
-class StructLayout;
-class Triple;
class GlobalVariable;
class LLVMContext;
-template<typename T>
-class ArrayRef;
+class Module;
+class StructLayout;
+class Triple;
+class Value;
/// Enum used to categorize the alignment types stored by LayoutAlignElem
enum AlignTypeEnum {
@@ -72,6 +77,7 @@ struct LayoutAlignElem {
static LayoutAlignElem get(AlignTypeEnum align_type, unsigned abi_align,
unsigned pref_align, uint32_t bit_width);
+
bool operator==(const LayoutAlignElem &rhs) const;
};
@@ -90,6 +96,7 @@ struct PointerAlignElem {
/// Initializer
static PointerAlignElem get(uint32_t AddressSpace, unsigned ABIAlign,
unsigned PrefAlign, uint32_t TypeByteWidth);
+
bool operator==(const PointerAlignElem &rhs) const;
};
@@ -104,6 +111,7 @@ private:
/// Defaults to false.
bool BigEndian;
+ unsigned AllocaAddrSpace;
unsigned StackNaturalAlign;
enum ManglingModeT {
@@ -118,13 +126,24 @@ private:
SmallVector<unsigned char, 8> LegalIntWidths;
- /// \brief Primitive type alignment data.
- SmallVector<LayoutAlignElem, 16> Alignments;
+ /// \brief Primitive type alignment data. This is sorted by type and bit
+ /// width during construction.
+ using AlignmentsTy = SmallVector<LayoutAlignElem, 16>;
+ AlignmentsTy Alignments;
+
+ AlignmentsTy::const_iterator
+ findAlignmentLowerBound(AlignTypeEnum AlignType, uint32_t BitWidth) const {
+ return const_cast<DataLayout *>(this)->findAlignmentLowerBound(AlignType,
+ BitWidth);
+ }
+
+ AlignmentsTy::iterator
+ findAlignmentLowerBound(AlignTypeEnum AlignType, uint32_t BitWidth);
/// \brief The string representation used to create this DataLayout
std::string StringRepresentation;
- typedef SmallVector<PointerAlignElem, 8> PointersTy;
+ using PointersTy = SmallVector<PointerAlignElem, 8>;
PointersTy Pointers;
PointersTy::const_iterator
@@ -134,16 +153,8 @@ private:
PointersTy::iterator findPointerLowerBound(uint32_t AddressSpace);
- /// This member is a signal that a requested alignment type and bit width were
- /// not found in the SmallVector.
- static const LayoutAlignElem InvalidAlignmentElem;
-
- /// This member is a signal that a requested pointer type and bit width were
- /// not found in the DenseSet.
- static const PointerAlignElem InvalidPointerElem;
-
// The StructType -> StructLayout map.
- mutable void *LayoutMap;
+ mutable void *LayoutMap = nullptr;
/// Pointers in these address spaces are non-integral, and don't have a
/// well-defined bitwise representation.
@@ -159,22 +170,6 @@ private:
/// Internal helper method that returns requested alignment for type.
unsigned getAlignment(Type *Ty, bool abi_or_pref) const;
- /// \brief Valid alignment predicate.
- ///
- /// Predicate that tests a LayoutAlignElem reference returned by get() against
- /// InvalidAlignmentElem.
- bool validAlignment(const LayoutAlignElem &align) const {
- return &align != &InvalidAlignmentElem;
- }
-
- /// \brief Valid pointer predicate.
- ///
- /// Predicate that tests a PointerAlignElem reference returned by get()
- /// against \c InvalidPointerElem.
- bool validPointer(const PointerAlignElem &align) const {
- return &align != &InvalidPointerElem;
- }
-
/// Parses a target data specification string. Assert if the string is
/// malformed.
void parseSpecifier(StringRef LayoutDescription);
@@ -184,21 +179,22 @@ private:
public:
/// Constructs a DataLayout from a specification string. See reset().
- explicit DataLayout(StringRef LayoutDescription) : LayoutMap(nullptr) {
+ explicit DataLayout(StringRef LayoutDescription) {
reset(LayoutDescription);
}
/// Initialize target data from properties stored in the module.
explicit DataLayout(const Module *M);
- void init(const Module *M);
+ DataLayout(const DataLayout &DL) { *this = DL; }
- DataLayout(const DataLayout &DL) : LayoutMap(nullptr) { *this = DL; }
+ ~DataLayout(); // Not virtual, do not subclass this class
DataLayout &operator=(const DataLayout &DL) {
clear();
StringRepresentation = DL.StringRepresentation;
BigEndian = DL.isBigEndian();
+ AllocaAddrSpace = DL.AllocaAddrSpace;
StackNaturalAlign = DL.StackNaturalAlign;
ManglingMode = DL.ManglingMode;
LegalIntWidths = DL.LegalIntWidths;
@@ -211,7 +207,7 @@ public:
bool operator==(const DataLayout &Other) const;
bool operator!=(const DataLayout &Other) const { return !(*this == Other); }
- ~DataLayout(); // Not virtual, do not subclass this class
+ void init(const Module *M);
/// Parse a data layout string (with fallback to default values).
void reset(StringRef LayoutDescription);
@@ -254,6 +250,7 @@ public:
}
unsigned getStackAlignment() const { return StackNaturalAlign; }
+ unsigned getAllocaAddrSpace() const { return AllocaAddrSpace; }
bool hasMicrosoftFastStdCallMangling() const {
return ManglingMode == MM_WinCOFFX86;
@@ -499,6 +496,7 @@ class StructLayout {
unsigned IsPadded : 1;
unsigned NumElements : 31;
uint64_t MemberOffsets[1]; // variable sized array!
+
public:
uint64_t getSizeInBytes() const { return StructSize; }
@@ -525,6 +523,7 @@ public:
private:
friend class DataLayout; // Only DataLayout can create this class
+
StructLayout(StructType *ST, const DataLayout &DL);
};
@@ -570,6 +569,6 @@ inline uint64_t DataLayout::getTypeSizeInBits(Type *Ty) const {
}
}
-} // End llvm namespace
+} // end namespace llvm
-#endif
+#endif // LLVM_IR_DATALAYOUT_H
diff --git a/contrib/llvm/include/llvm/IR/DebugInfo.h b/contrib/llvm/include/llvm/IR/DebugInfo.h
index 04f4619..1d8e7e2 100644
--- a/contrib/llvm/include/llvm/IR/DebugInfo.h
+++ b/contrib/llvm/include/llvm/IR/DebugInfo.h
@@ -21,17 +21,12 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/IR/DebugInfoMetadata.h"
-#include "llvm/Support/Casting.h"
-#include "llvm/Support/Dwarf.h"
-#include "llvm/Support/ErrorHandling.h"
-#include <iterator>
namespace llvm {
-class Module;
+
class DbgDeclareInst;
class DbgValueInst;
-template <typename K, typename V, typename KeyInfoT, typename BucketT>
-class DenseMap;
+class Module;
/// \brief Find subprogram that is enclosing this scope.
DISubprogram *getDISubprogram(const MDNode *Scope);
@@ -95,13 +90,13 @@ private:
bool addScope(DIScope *Scope);
public:
- typedef SmallVectorImpl<DICompileUnit *>::const_iterator
- compile_unit_iterator;
- typedef SmallVectorImpl<DISubprogram *>::const_iterator subprogram_iterator;
- typedef SmallVectorImpl<DIGlobalVariableExpression *>::const_iterator
- global_variable_expression_iterator;
- typedef SmallVectorImpl<DIType *>::const_iterator type_iterator;
- typedef SmallVectorImpl<DIScope *>::const_iterator scope_iterator;
+ using compile_unit_iterator =
+ SmallVectorImpl<DICompileUnit *>::const_iterator;
+ using subprogram_iterator = SmallVectorImpl<DISubprogram *>::const_iterator;
+ using global_variable_expression_iterator =
+ SmallVectorImpl<DIGlobalVariableExpression *>::const_iterator;
+ using type_iterator = SmallVectorImpl<DIType *>::const_iterator;
+ using scope_iterator = SmallVectorImpl<DIScope *>::const_iterator;
iterator_range<compile_unit_iterator> compile_units() const {
return make_range(CUs.begin(), CUs.end());
@@ -140,4 +135,4 @@ private:
} // end namespace llvm
-#endif
+#endif // LLVM_IR_DEBUGINFO_H
diff --git a/contrib/llvm/include/llvm/IR/DebugInfoFlags.def b/contrib/llvm/include/llvm/IR/DebugInfoFlags.def
index 87f3dc9..7ea6346 100644
--- a/contrib/llvm/include/llvm/IR/DebugInfoFlags.def
+++ b/contrib/llvm/include/llvm/IR/DebugInfoFlags.def
@@ -34,7 +34,8 @@ HANDLE_DI_FLAG((1 << 11), Vector)
HANDLE_DI_FLAG((1 << 12), StaticMember)
HANDLE_DI_FLAG((1 << 13), LValueReference)
HANDLE_DI_FLAG((1 << 14), RValueReference)
-HANDLE_DI_FLAG((1 << 15), ExternalTypeRef)
+// 15 was formerly ExternalTypeRef, but this was never used.
+HANDLE_DI_FLAG((1 << 15), Reserved)
HANDLE_DI_FLAG((1 << 16), SingleInheritance)
HANDLE_DI_FLAG((2 << 16), MultipleInheritance)
HANDLE_DI_FLAG((3 << 16), VirtualInheritance)
diff --git a/contrib/llvm/include/llvm/IR/DebugInfoMetadata.h b/contrib/llvm/include/llvm/IR/DebugInfoMetadata.h
index 1878552..678a43a 100644
--- a/contrib/llvm/include/llvm/IR/DebugInfoMetadata.h
+++ b/contrib/llvm/include/llvm/IR/DebugInfoMetadata.h
@@ -17,11 +17,14 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/BitmaskEnum.h"
#include "llvm/ADT/None.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/IR/Metadata.h"
#include "llvm/Support/Casting.h"
-#include "llvm/Support/Dwarf.h"
#include <cassert>
#include <climits>
#include <cstddef>
@@ -56,8 +59,6 @@
namespace llvm {
-template <typename T> class Optional;
-
/// Holds a subclass of DINode.
///
/// FIXME: This class doesn't currently make much sense. Previously it was a
@@ -92,9 +93,9 @@ public:
bool operator!=(const TypedDINodeRef<T> &X) const { return MD != X.MD; }
};
-typedef TypedDINodeRef<DINode> DINodeRef;
-typedef TypedDINodeRef<DIScope> DIScopeRef;
-typedef TypedDINodeRef<DIType> DITypeRef;
+using DINodeRef = TypedDINodeRef<DINode>;
+using DIScopeRef = TypedDINodeRef<DIScope>;
+using DITypeRef = TypedDINodeRef<DIType>;
class DITypeRefArray {
const MDTuple *N = nullptr;
@@ -147,7 +148,7 @@ public:
/// Tagged DWARF-like metadata node.
///
/// A metadata node with a DWARF tag (i.e., a constant named \c DW_TAG_*,
-/// defined in llvm/Support/Dwarf.h). Called \a DINode because it's
+/// defined in llvm/BinaryFormat/Dwarf.h). Called \a DINode because it's
/// potentially used for non-DWARF output.
class DINode : public MDNode {
friend class LLVMContextImpl;
@@ -238,7 +239,8 @@ public:
};
template <class T> struct simplify_type<const TypedDINodeRef<T>> {
- typedef Metadata *SimpleType;
+ using SimpleType = Metadata *;
+
static SimpleType getSimplifiedValue(const TypedDINodeRef<T> &MD) {
return MD;
}
@@ -433,10 +435,10 @@ public:
/// Return the raw underlying file.
///
- /// An \a DIFile is an \a DIScope, but it doesn't point at a separate file
- /// (it\em is the file). If \c this is an \a DIFile, we need to return \c
- /// this. Otherwise, return the first operand, which is where all other
- /// subclasses store their file pointer.
+ /// A \a DIFile is a \a DIScope, but it doesn't point at a separate file (it
+ /// \em is the file). If \c this is an \a DIFile, we need to return \c this.
+ /// Otherwise, return the first operand, which is where all other subclasses
+ /// store their file pointer.
Metadata *getRawFile() const {
return isa<DIFile>(this) ? const_cast<DIScope *>(this)
: static_cast<Metadata *>(getOperand(0));
@@ -629,7 +631,6 @@ public:
bool isStaticMember() const { return getFlags() & FlagStaticMember; }
bool isLValueReference() const { return getFlags() & FlagLValueReference; }
bool isRValueReference() const { return getFlags() & FlagRValueReference; }
- bool isExternalTypeRef() const { return getFlags() & FlagExternalTypeRef; }
static bool classof(const Metadata *MD) {
switch (MD->getMetadataID()) {
@@ -710,37 +711,45 @@ class DIDerivedType : public DIType {
friend class LLVMContextImpl;
friend class MDNode;
+ /// \brief The DWARF address space of the memory pointed to or referenced by a
+ /// pointer or reference type respectively.
+ Optional<unsigned> DWARFAddressSpace;
+
DIDerivedType(LLVMContext &C, StorageType Storage, unsigned Tag,
unsigned Line, uint64_t SizeInBits, uint32_t AlignInBits,
- uint64_t OffsetInBits, DIFlags Flags, ArrayRef<Metadata *> Ops)
+ uint64_t OffsetInBits, Optional<unsigned> DWARFAddressSpace,
+ DIFlags Flags, ArrayRef<Metadata *> Ops)
: DIType(C, DIDerivedTypeKind, Storage, Tag, Line, SizeInBits,
- AlignInBits, OffsetInBits, Flags, Ops) {}
+ AlignInBits, OffsetInBits, Flags, Ops),
+ DWARFAddressSpace(DWARFAddressSpace) {}
~DIDerivedType() = default;
static DIDerivedType *getImpl(LLVMContext &Context, unsigned Tag,
StringRef Name, DIFile *File, unsigned Line,
DIScopeRef Scope, DITypeRef BaseType,
uint64_t SizeInBits, uint32_t AlignInBits,
- uint64_t OffsetInBits, DIFlags Flags,
- Metadata *ExtraData, StorageType Storage,
- bool ShouldCreate = true) {
+ uint64_t OffsetInBits,
+ Optional<unsigned> DWARFAddressSpace,
+ DIFlags Flags, Metadata *ExtraData,
+ StorageType Storage, bool ShouldCreate = true) {
return getImpl(Context, Tag, getCanonicalMDString(Context, Name), File,
Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits,
- Flags, ExtraData, Storage, ShouldCreate);
+ DWARFAddressSpace, Flags, ExtraData, Storage, ShouldCreate);
}
static DIDerivedType *getImpl(LLVMContext &Context, unsigned Tag,
MDString *Name, Metadata *File, unsigned Line,
Metadata *Scope, Metadata *BaseType,
uint64_t SizeInBits, uint32_t AlignInBits,
- uint64_t OffsetInBits, DIFlags Flags,
- Metadata *ExtraData, StorageType Storage,
- bool ShouldCreate = true);
+ uint64_t OffsetInBits,
+ Optional<unsigned> DWARFAddressSpace,
+ DIFlags Flags, Metadata *ExtraData,
+ StorageType Storage, bool ShouldCreate = true);
TempDIDerivedType cloneImpl() const {
return getTemporary(getContext(), getTag(), getName(), getFile(), getLine(),
getScope(), getBaseType(), getSizeInBits(),
- getAlignInBits(), getOffsetInBits(), getFlags(),
- getExtraData());
+ getAlignInBits(), getOffsetInBits(),
+ getDWARFAddressSpace(), getFlags(), getExtraData());
}
public:
@@ -748,24 +757,32 @@ public:
(unsigned Tag, MDString *Name, Metadata *File,
unsigned Line, Metadata *Scope, Metadata *BaseType,
uint64_t SizeInBits, uint32_t AlignInBits,
- uint64_t OffsetInBits, DIFlags Flags,
+ uint64_t OffsetInBits,
+ Optional<unsigned> DWARFAddressSpace, DIFlags Flags,
Metadata *ExtraData = nullptr),
(Tag, Name, File, Line, Scope, BaseType, SizeInBits,
- AlignInBits, OffsetInBits, Flags, ExtraData))
+ AlignInBits, OffsetInBits, DWARFAddressSpace, Flags,
+ ExtraData))
DEFINE_MDNODE_GET(DIDerivedType,
(unsigned Tag, StringRef Name, DIFile *File, unsigned Line,
DIScopeRef Scope, DITypeRef BaseType, uint64_t SizeInBits,
uint32_t AlignInBits, uint64_t OffsetInBits,
- DIFlags Flags, Metadata *ExtraData = nullptr),
+ Optional<unsigned> DWARFAddressSpace, DIFlags Flags,
+ Metadata *ExtraData = nullptr),
(Tag, Name, File, Line, Scope, BaseType, SizeInBits,
- AlignInBits, OffsetInBits, Flags, ExtraData))
+ AlignInBits, OffsetInBits, DWARFAddressSpace, Flags,
+ ExtraData))
TempDIDerivedType clone() const { return cloneImpl(); }
- //// Get the base type this is derived from.
+ /// Get the base type this is derived from.
DITypeRef getBaseType() const { return DITypeRef(getRawBaseType()); }
Metadata *getRawBaseType() const { return getOperand(3); }
+ /// \returns The DWARF address space of the memory pointed to or referenced by
+ /// a pointer or reference type respectively.
+ Optional<unsigned> getDWARFAddressSpace() const { return DWARFAddressSpace; }
+
/// Get extra data associated with this derived type.
///
/// Class type for pointer-to-members, objective-c property node for ivars,
@@ -782,15 +799,18 @@ public:
assert(getTag() == dwarf::DW_TAG_ptr_to_member_type);
return DITypeRef(getExtraData());
}
+
DIObjCProperty *getObjCProperty() const {
return dyn_cast_or_null<DIObjCProperty>(getExtraData());
}
+
Constant *getStorageOffsetInBits() const {
assert(getTag() == dwarf::DW_TAG_member && isBitField());
if (auto *C = cast_or_null<ConstantAsMetadata>(getExtraData()))
return C->getValue();
return nullptr;
}
+
Constant *getConstant() const {
assert(getTag() == dwarf::DW_TAG_member && isStaticMember());
if (auto *C = cast_or_null<ConstantAsMetadata>(getExtraData()))
@@ -953,9 +973,11 @@ public:
#endif
replaceOperandWith(4, Elements.get());
}
+
void replaceVTableHolder(DITypeRef VTableHolder) {
replaceOperandWith(5, VTableHolder);
}
+
void replaceTemplateParams(DITemplateParameterArray TemplateParams) {
replaceOperandWith(6, TemplateParams.get());
}
@@ -1014,6 +1036,7 @@ public:
DITypeRefArray getTypeArray() const {
return cast_or_null<MDTuple>(getRawTypeArray());
}
+
Metadata *getRawTypeArray() const { return getOperand(3); }
static bool classof(const Metadata *MD) {
@@ -1044,15 +1067,17 @@ private:
unsigned EmissionKind;
uint64_t DWOId;
bool SplitDebugInlining;
+ bool DebugInfoForProfiling;
DICompileUnit(LLVMContext &C, StorageType Storage, unsigned SourceLanguage,
bool IsOptimized, unsigned RuntimeVersion,
unsigned EmissionKind, uint64_t DWOId, bool SplitDebugInlining,
- ArrayRef<Metadata *> Ops)
+ bool DebugInfoForProfiling, ArrayRef<Metadata *> Ops)
: DIScope(C, DICompileUnitKind, Storage, dwarf::DW_TAG_compile_unit, Ops),
SourceLanguage(SourceLanguage), IsOptimized(IsOptimized),
RuntimeVersion(RuntimeVersion), EmissionKind(EmissionKind),
- DWOId(DWOId), SplitDebugInlining(SplitDebugInlining) {
+ DWOId(DWOId), SplitDebugInlining(SplitDebugInlining),
+ DebugInfoForProfiling(DebugInfoForProfiling) {
assert(Storage != Uniqued);
}
~DICompileUnit() = default;
@@ -1065,15 +1090,16 @@ private:
DIScopeArray RetainedTypes,
DIGlobalVariableExpressionArray GlobalVariables,
DIImportedEntityArray ImportedEntities, DIMacroNodeArray Macros,
- uint64_t DWOId, bool SplitDebugInlining, StorageType Storage,
- bool ShouldCreate = true) {
+ uint64_t DWOId, bool SplitDebugInlining, bool DebugInfoForProfiling,
+ 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, Storage, ShouldCreate);
+ DWOId, SplitDebugInlining, DebugInfoForProfiling, Storage,
+ ShouldCreate);
}
static DICompileUnit *
getImpl(LLVMContext &Context, unsigned SourceLanguage, Metadata *File,
@@ -1082,7 +1108,8 @@ private:
unsigned EmissionKind, Metadata *EnumTypes, Metadata *RetainedTypes,
Metadata *GlobalVariables, Metadata *ImportedEntities,
Metadata *Macros, uint64_t DWOId, bool SplitDebugInlining,
- StorageType Storage, bool ShouldCreate = true);
+ bool DebugInfoForProfiling, StorageType Storage,
+ bool ShouldCreate = true);
TempDICompileUnit cloneImpl() const {
return getTemporary(getContext(), getSourceLanguage(), getFile(),
@@ -1090,7 +1117,8 @@ private:
getRuntimeVersion(), getSplitDebugFilename(),
getEmissionKind(), getEnumTypes(), getRetainedTypes(),
getGlobalVariables(), getImportedEntities(),
- getMacros(), DWOId, getSplitDebugInlining());
+ getMacros(), DWOId, getSplitDebugInlining(),
+ getDebugInfoForProfiling());
}
public:
@@ -1105,10 +1133,11 @@ public:
DICompositeTypeArray EnumTypes, DIScopeArray RetainedTypes,
DIGlobalVariableExpressionArray GlobalVariables,
DIImportedEntityArray ImportedEntities, DIMacroNodeArray Macros,
- uint64_t DWOId, bool SplitDebugInlining),
+ uint64_t DWOId, bool SplitDebugInlining, bool DebugInfoForProfiling),
(SourceLanguage, File, Producer, IsOptimized, Flags, RuntimeVersion,
SplitDebugFilename, EmissionKind, EnumTypes, RetainedTypes,
- GlobalVariables, ImportedEntities, Macros, DWOId, SplitDebugInlining))
+ GlobalVariables, ImportedEntities, Macros, DWOId, SplitDebugInlining,
+ DebugInfoForProfiling))
DEFINE_MDNODE_GET_DISTINCT_TEMPORARY(
DICompileUnit,
(unsigned SourceLanguage, Metadata *File, MDString *Producer,
@@ -1116,10 +1145,11 @@ public:
MDString *SplitDebugFilename, unsigned EmissionKind, Metadata *EnumTypes,
Metadata *RetainedTypes, Metadata *GlobalVariables,
Metadata *ImportedEntities, Metadata *Macros, uint64_t DWOId,
- bool SplitDebugInlining),
+ bool SplitDebugInlining, bool DebugInfoForProfiling),
(SourceLanguage, File, Producer, IsOptimized, Flags, RuntimeVersion,
SplitDebugFilename, EmissionKind, EnumTypes, RetainedTypes,
- GlobalVariables, ImportedEntities, Macros, DWOId, SplitDebugInlining))
+ GlobalVariables, ImportedEntities, Macros, DWOId, SplitDebugInlining,
+ DebugInfoForProfiling))
TempDICompileUnit clone() const { return cloneImpl(); }
@@ -1129,6 +1159,7 @@ public:
DebugEmissionKind getEmissionKind() const {
return (DebugEmissionKind)EmissionKind;
}
+ bool getDebugInfoForProfiling() const { return DebugInfoForProfiling; }
StringRef getProducer() const { return getStringOperand(1); }
StringRef getFlags() const { return getStringOperand(2); }
StringRef getSplitDebugFilename() const { return getStringOperand(3); }
@@ -1246,6 +1277,28 @@ class DILocation : public MDNode {
static_cast<Metadata *>(InlinedAt), Storage, ShouldCreate);
}
+ /// With a given unsigned int \p U, use up to 13 bits to represent it.
+ /// old_bit 1~5 --> new_bit 1~5
+ /// old_bit 6~12 --> new_bit 7~13
+ /// new_bit_6 is 0 if higher bits (7~13) are all 0
+ static unsigned getPrefixEncodingFromUnsigned(unsigned U) {
+ U &= 0xfff;
+ return U > 0x1f ? (((U & 0xfe0) << 1) | (U & 0x1f) | 0x20) : U;
+ }
+
+ /// Reverse transformation as getPrefixEncodingFromUnsigned.
+ static unsigned getUnsignedFromPrefixEncoding(unsigned U) {
+ return (U & 0x20) ? (((U >> 1) & 0xfe0) | (U & 0x1f)) : (U & 0x1f);
+ }
+
+ /// Returns the next component stored in discriminator.
+ static unsigned getNextComponentInDiscriminator(unsigned D) {
+ if ((D & 1) == 0)
+ return D >> ((D & 0x40) ? 14 : 7);
+ else
+ return D >> 1;
+ }
+
TempDILocation cloneImpl() const {
// Get the raw scope/inlinedAt since it is possible to invoke this on
// a DILocation containing temporary metadata.
@@ -1272,6 +1325,7 @@ public:
unsigned getLine() const { return SubclassData32; }
unsigned getColumn() const { return SubclassData16; }
DILocalScope *getScope() const { return cast<DILocalScope>(getRawScope()); }
+
DILocation *getInlinedAt() const {
return cast_or_null<DILocation>(getRawInlinedAt());
}
@@ -1307,10 +1361,48 @@ public:
///
/// DWARF discriminators distinguish identical file locations between
/// instructions that are on different basic blocks.
+ ///
+ /// There are 3 components stored in discriminator, from lower bits:
+ ///
+ /// Base discriminator: assigned by AddDiscriminators pass to identify IRs
+ /// that are defined by the same source line, but
+ /// different basic blocks.
+ /// Duplication factor: assigned by optimizations that will scale down
+ /// the execution frequency of the original IR.
+ /// Copy Identifier: assigned by optimizations that clones the IR.
+ /// Each copy of the IR will be assigned an identifier.
+ ///
+ /// Encoding:
+ ///
+ /// The above 3 components are encoded into a 32bit unsigned integer in
+ /// order. If the lowest bit is 1, the current component is empty, and the
+ /// next component will start in the next bit. Otherwise, the the current
+ /// component is non-empty, and its content starts in the next bit. The
+ /// length of each components is either 5 bit or 12 bit: if the 7th bit
+ /// is 0, the bit 2~6 (5 bits) are used to represent the component; if the
+ /// 7th bit is 1, the bit 2~6 (5 bits) and 8~14 (7 bits) are combined to
+ /// represent the component.
+
inline unsigned getDiscriminator() const;
/// Returns a new DILocation with updated \p Discriminator.
- inline DILocation *cloneWithDiscriminator(unsigned Discriminator) const;
+ inline const DILocation *cloneWithDiscriminator(unsigned Discriminator) const;
+
+ /// Returns a new DILocation with updated base discriminator \p BD.
+ inline const DILocation *setBaseDiscriminator(unsigned BD) const;
+
+ /// Returns the duplication factor stored in the discriminator.
+ inline unsigned getDuplicationFactor() const;
+
+ /// Returns the copy identifier stored in the discriminator.
+ inline unsigned getCopyIdentifier() const;
+
+ /// Returns the base discriminator stored in the discriminator.
+ inline unsigned getBaseDiscriminator() const;
+
+ /// Returns a new DILocation with duplication factor \p DF encoded in the
+ /// discriminator.
+ inline const DILocation *cloneWithDuplicationFactor(unsigned DF) const;
/// When two instructions are combined into a single instruction we also
/// need to combine the original locations into a single location.
@@ -1333,6 +1425,30 @@ public:
return nullptr;
}
+ /// Returns the base discriminator for a given encoded discriminator \p D.
+ static unsigned getBaseDiscriminatorFromDiscriminator(unsigned D) {
+ if ((D & 1) == 0)
+ return getUnsignedFromPrefixEncoding(D >> 1);
+ else
+ return 0;
+ }
+
+ /// Returns the duplication factor for a given encoded discriminator \p D.
+ static unsigned getDuplicationFactorFromDiscriminator(unsigned D) {
+ D = getNextComponentInDiscriminator(D);
+ if (D == 0 || (D & 1))
+ return 1;
+ else
+ return getUnsignedFromPrefixEncoding(D >> 1);
+ }
+
+ /// Returns the copy identifier for a given encoded discriminator \p D.
+ static unsigned getCopyIdentifierFromDiscriminator(unsigned D) {
+ return getUnsignedFromPrefixEncoding(getNextComponentInDiscriminator(
+ getNextComponentInDiscriminator(D)));
+ }
+
+
Metadata *getRawScope() const { return getOperand(0); }
Metadata *getRawInlinedAt() const {
if (getNumOperands() == 2)
@@ -1401,14 +1517,14 @@ class DISubprogram : public DILocalScope {
unsigned VirtualIndex, int ThisAdjustment, DIFlags Flags,
bool IsOptimized, DICompileUnit *Unit,
DITemplateParameterArray TemplateParams, DISubprogram *Declaration,
- DILocalVariableArray Variables, StorageType Storage,
- bool ShouldCreate = true) {
+ DILocalVariableArray Variables, DITypeArray ThrownTypes,
+ StorageType Storage, bool ShouldCreate = true) {
return getImpl(Context, Scope, getCanonicalMDString(Context, Name),
getCanonicalMDString(Context, LinkageName), File, Line, Type,
IsLocalToUnit, IsDefinition, ScopeLine, ContainingType,
Virtuality, VirtualIndex, ThisAdjustment, Flags, IsOptimized,
Unit, TemplateParams.get(), Declaration, Variables.get(),
- Storage, ShouldCreate);
+ ThrownTypes.get(), Storage, ShouldCreate);
}
static DISubprogram *
getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name,
@@ -1417,15 +1533,16 @@ class DISubprogram : public DILocalScope {
Metadata *ContainingType, unsigned Virtuality, unsigned VirtualIndex,
int ThisAdjustment, DIFlags Flags, bool IsOptimized, Metadata *Unit,
Metadata *TemplateParams, Metadata *Declaration, Metadata *Variables,
- StorageType Storage, bool ShouldCreate = true);
+ Metadata *ThrownTypes, StorageType Storage, bool ShouldCreate = true);
TempDISubprogram cloneImpl() const {
- return getTemporary(
- getContext(), getScope(), getName(), getLinkageName(), getFile(),
- getLine(), getType(), isLocalToUnit(), isDefinition(), getScopeLine(),
- getContainingType(), getVirtuality(), getVirtualIndex(),
- getThisAdjustment(), getFlags(), isOptimized(), getUnit(),
- getTemplateParams(), getDeclaration(), getVariables());
+ return getTemporary(getContext(), getScope(), getName(), getLinkageName(),
+ getFile(), getLine(), getType(), isLocalToUnit(),
+ isDefinition(), getScopeLine(), getContainingType(),
+ getVirtuality(), getVirtualIndex(), getThisAdjustment(),
+ getFlags(), isOptimized(), getUnit(),
+ getTemplateParams(), getDeclaration(), getVariables(),
+ getThrownTypes());
}
public:
@@ -1438,11 +1555,12 @@ public:
bool IsOptimized, DICompileUnit *Unit,
DITemplateParameterArray TemplateParams = nullptr,
DISubprogram *Declaration = nullptr,
- DILocalVariableArray Variables = nullptr),
+ DILocalVariableArray Variables = nullptr,
+ DITypeArray ThrownTypes = nullptr),
(Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit,
IsDefinition, ScopeLine, ContainingType, Virtuality,
VirtualIndex, ThisAdjustment, Flags, IsOptimized, Unit,
- TemplateParams, Declaration, Variables))
+ TemplateParams, Declaration, Variables, ThrownTypes))
DEFINE_MDNODE_GET(
DISubprogram,
(Metadata * Scope, MDString *Name, MDString *LinkageName, Metadata *File,
@@ -1450,10 +1568,12 @@ public:
unsigned ScopeLine, Metadata *ContainingType, unsigned Virtuality,
unsigned VirtualIndex, int ThisAdjustment, DIFlags Flags,
bool IsOptimized, Metadata *Unit, Metadata *TemplateParams = nullptr,
- Metadata *Declaration = nullptr, Metadata *Variables = nullptr),
+ Metadata *Declaration = nullptr, Metadata *Variables = nullptr,
+ Metadata *ThrownTypes = nullptr),
(Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition,
ScopeLine, ContainingType, Virtuality, VirtualIndex, ThisAdjustment,
- Flags, IsOptimized, Unit, TemplateParams, Declaration, Variables))
+ Flags, IsOptimized, Unit, TemplateParams, Declaration, Variables,
+ ThrownTypes))
TempDISubprogram clone() const { return cloneImpl(); }
@@ -1502,11 +1622,7 @@ public:
DIScopeRef getScope() const { return DIScopeRef(getRawScope()); }
StringRef getName() const { return getStringOperand(2); }
- StringRef getDisplayName() const { return getStringOperand(3); }
- StringRef getLinkageName() const { return getStringOperand(4); }
-
- MDString *getRawName() const { return getOperandAs<MDString>(2); }
- MDString *getRawLinkageName() const { return getOperandAs<MDString>(4); }
+ StringRef getLinkageName() const { return getStringOperand(3); }
DISubroutineType *getType() const {
return cast_or_null<DISubroutineType>(getRawType());
@@ -1518,9 +1634,7 @@ public:
DICompileUnit *getUnit() const {
return cast_or_null<DICompileUnit>(getRawUnit());
}
- void replaceUnit(DICompileUnit *CU) {
- replaceOperandWith(7, CU);
- }
+ void replaceUnit(DICompileUnit *CU) { replaceOperandWith(5, CU); }
DITemplateParameterArray getTemplateParams() const {
return cast_or_null<MDTuple>(getRawTemplateParams());
}
@@ -1530,14 +1644,26 @@ public:
DILocalVariableArray getVariables() const {
return cast_or_null<MDTuple>(getRawVariables());
}
+ DITypeArray getThrownTypes() const {
+ return cast_or_null<MDTuple>(getRawThrownTypes());
+ }
Metadata *getRawScope() const { return getOperand(1); }
- Metadata *getRawType() const { return getOperand(5); }
- Metadata *getRawContainingType() const { return getOperand(6); }
- Metadata *getRawUnit() const { return getOperand(7); }
- Metadata *getRawTemplateParams() const { return getOperand(8); }
- Metadata *getRawDeclaration() const { return getOperand(9); }
- Metadata *getRawVariables() const { return getOperand(10); }
+ MDString *getRawName() const { return getOperandAs<MDString>(2); }
+ MDString *getRawLinkageName() const { return getOperandAs<MDString>(3); }
+ Metadata *getRawType() const { return getOperand(4); }
+ Metadata *getRawUnit() const { return getOperand(5); }
+ Metadata *getRawDeclaration() const { return getOperand(6); }
+ Metadata *getRawVariables() const { return getOperand(7); }
+ Metadata *getRawContainingType() const {
+ return getNumOperands() > 8 ? getOperandAs<Metadata>(8) : nullptr;
+ }
+ Metadata *getRawTemplateParams() const {
+ return getNumOperands() > 9 ? getOperandAs<Metadata>(9) : nullptr;
+ }
+ Metadata *getRawThrownTypes() const {
+ return getNumOperands() > 10 ? getOperandAs<Metadata>(10) : nullptr;
+ }
/// Check if this subprogram describes the given function.
///
@@ -1676,7 +1802,8 @@ unsigned DILocation::getDiscriminator() const {
return 0;
}
-DILocation *DILocation::cloneWithDiscriminator(unsigned Discriminator) const {
+const DILocation *
+DILocation::cloneWithDiscriminator(unsigned Discriminator) const {
DIScope *Scope = getScope();
// Skip all parent DILexicalBlockFile that already have a discriminator
// assigned. We do not want to have nested DILexicalBlockFiles that have
@@ -1692,49 +1819,80 @@ DILocation *DILocation::cloneWithDiscriminator(unsigned Discriminator) const {
getInlinedAt());
}
+unsigned DILocation::getBaseDiscriminator() const {
+ return getBaseDiscriminatorFromDiscriminator(getDiscriminator());
+}
+
+unsigned DILocation::getDuplicationFactor() const {
+ return getDuplicationFactorFromDiscriminator(getDiscriminator());
+}
+
+unsigned DILocation::getCopyIdentifier() const {
+ return getCopyIdentifierFromDiscriminator(getDiscriminator());
+}
+
+const DILocation *DILocation::setBaseDiscriminator(unsigned D) const {
+ if (D == 0)
+ return this;
+ else
+ return cloneWithDiscriminator(getPrefixEncodingFromUnsigned(D) << 1);
+}
+
+const DILocation *DILocation::cloneWithDuplicationFactor(unsigned DF) const {
+ DF *= getDuplicationFactor();
+ if (DF <= 1)
+ return this;
+
+ unsigned BD = getBaseDiscriminator();
+ unsigned CI = getCopyIdentifier() << (DF > 0x1f ? 14 : 7);
+ unsigned D = CI | (getPrefixEncodingFromUnsigned(DF) << 1);
+
+ if (BD == 0)
+ D = (D << 1) | 1;
+ else
+ D = (D << (BD > 0x1f ? 14 : 7)) | (getPrefixEncodingFromUnsigned(BD) << 1);
+
+ return cloneWithDiscriminator(D);
+}
+
class DINamespace : public DIScope {
friend class LLVMContextImpl;
friend class MDNode;
- unsigned Line;
unsigned ExportSymbols : 1;
- DINamespace(LLVMContext &Context, StorageType Storage, unsigned Line,
- bool ExportSymbols, ArrayRef<Metadata *> Ops)
+ DINamespace(LLVMContext &Context, StorageType Storage, bool ExportSymbols,
+ ArrayRef<Metadata *> Ops)
: DIScope(Context, DINamespaceKind, Storage, dwarf::DW_TAG_namespace,
Ops),
- Line(Line), ExportSymbols(ExportSymbols) {}
+ ExportSymbols(ExportSymbols) {}
~DINamespace() = default;
static DINamespace *getImpl(LLVMContext &Context, DIScope *Scope,
- DIFile *File, StringRef Name, unsigned Line,
- bool ExportSymbols, StorageType Storage,
- bool ShouldCreate = true) {
- return getImpl(Context, Scope, File, getCanonicalMDString(Context, Name),
- Line, ExportSymbols, Storage, ShouldCreate);
+ StringRef Name, bool ExportSymbols,
+ StorageType Storage, bool ShouldCreate = true) {
+ return getImpl(Context, Scope, getCanonicalMDString(Context, Name),
+ ExportSymbols, Storage, ShouldCreate);
}
static DINamespace *getImpl(LLVMContext &Context, Metadata *Scope,
- Metadata *File, MDString *Name, unsigned Line,
- bool ExportSymbols, StorageType Storage,
- bool ShouldCreate = true);
+ MDString *Name, bool ExportSymbols,
+ StorageType Storage, bool ShouldCreate = true);
TempDINamespace cloneImpl() const {
- return getTemporary(getContext(), getScope(), getFile(), getName(),
- getLine(), getExportSymbols());
+ return getTemporary(getContext(), getScope(), getName(),
+ getExportSymbols());
}
public:
- DEFINE_MDNODE_GET(DINamespace, (DIScope * Scope, DIFile *File, StringRef Name,
- unsigned Line, bool ExportSymbols),
- (Scope, File, Name, Line, ExportSymbols))
DEFINE_MDNODE_GET(DINamespace,
- (Metadata * Scope, Metadata *File, MDString *Name,
- unsigned Line, bool ExportSymbols),
- (Scope, File, Name, Line, ExportSymbols))
+ (DIScope *Scope, StringRef Name, bool ExportSymbols),
+ (Scope, Name, ExportSymbols))
+ DEFINE_MDNODE_GET(DINamespace,
+ (Metadata *Scope, MDString *Name, bool ExportSymbols),
+ (Scope, Name, ExportSymbols))
TempDINamespace clone() const { return cloneImpl(); }
- unsigned getLine() const { return Line; }
bool getExportSymbols() const { return ExportSymbols; }
DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); }
StringRef getName() const { return getStringOperand(2); }
@@ -1918,7 +2076,7 @@ protected:
DIVariable(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Line,
ArrayRef<Metadata *> Ops, uint32_t AlignInBits = 0)
: DINode(C, ID, Storage, dwarf::DW_TAG_variable, Ops), Line(Line),
- AlignInBits(AlignInBits) {}
+ AlignInBits(AlignInBits) {}
~DIVariable() = default;
public:
@@ -1935,6 +2093,7 @@ public:
return F->getFilename();
return "";
}
+
StringRef getDirectory() const {
if (auto *F = getFile())
return F->getDirectory();
@@ -1958,9 +2117,6 @@ public:
/// variable, or the location of a single piece of a variable, or (when using
/// DW_OP_stack_value) is the constant variable value.
///
-/// FIXME: Instead of DW_OP_plus taking an argument, this should use DW_OP_const
-/// and have DW_OP_plus consume the topmost elements on the stack.
-///
/// TODO: Co-allocate the expression elements.
/// TODO: Separate from MDNode, or otherwise drop Distinct and Temporary
/// storage types.
@@ -1991,6 +2147,7 @@ public:
ArrayRef<uint64_t> getElements() const { return Elements; }
unsigned getNumElements() const { return Elements.size(); }
+
uint64_t getElement(unsigned I) const {
assert(I < Elements.size() && "Index out of range");
return Elements[I];
@@ -1999,7 +2156,8 @@ public:
/// Determine whether this represents a standalone constant value.
bool isConstant() const;
- typedef ArrayRef<uint64_t>::iterator element_iterator;
+ using element_iterator = ArrayRef<uint64_t>::iterator;
+
element_iterator elements_begin() const { return getElements().begin(); }
element_iterator elements_end() const { return getElements().end(); }
@@ -2087,6 +2245,9 @@ public:
expr_op_iterator expr_op_end() const {
return expr_op_iterator(elements_end());
}
+ iterator_range<expr_op_iterator> expr_ops() const {
+ return {expr_op_begin(), expr_op_end()};
+ }
/// @}
bool isValid() const;
@@ -2095,7 +2256,7 @@ public:
return MD->getMetadataID() == DIExpressionKind;
}
- /// Is the first element a DW_OP_deref?.
+ /// Return whether the first element a DW_OP_deref.
bool startsWithDeref() const {
return getNumElements() > 0 && getElement(0) == dwarf::DW_OP_deref;
}
@@ -2108,7 +2269,7 @@ public:
/// Retrieve the details of this fragment expression.
static Optional<FragmentInfo> getFragmentInfo(expr_op_iterator Start,
- expr_op_iterator End);
+ expr_op_iterator End);
/// Retrieve the details of this fragment expression.
Optional<FragmentInfo> getFragmentInfo() const {
@@ -2117,6 +2278,21 @@ public:
/// Return whether this is a piece of an aggregate variable.
bool isFragment() const { return getFragmentInfo().hasValue(); }
+
+ /// Append \p Ops with operations to apply the \p Offset.
+ static void appendOffset(SmallVectorImpl<uint64_t> &Ops, int64_t Offset);
+
+ /// If this is a constant offset, extract it. If there is no expression,
+ /// return true with an offset of zero.
+ bool extractIfOffset(int64_t &Offset) const;
+
+ /// Constants for DIExpression::prepend.
+ enum { NoDeref = false, WithDeref = true, WithStackValue = true };
+
+ /// Prepend \p DIExpr with a deref and offset operation and optionally turn it
+ /// into a stack value.
+ static DIExpression *prepend(const DIExpression *DIExpr, bool Deref,
+ int64_t Offset = 0, bool StackValue = false);
};
/// Global variables.
@@ -2343,6 +2519,7 @@ public:
return F->getFilename();
return "";
}
+
StringRef getDirectory() const {
if (auto *F = getFile())
return F->getDirectory();
@@ -2374,32 +2551,32 @@ class DIImportedEntity : public DINode {
static DIImportedEntity *getImpl(LLVMContext &Context, unsigned Tag,
DIScope *Scope, DINodeRef Entity,
- unsigned Line, StringRef Name,
+ DIFile *File, unsigned Line, StringRef Name,
StorageType Storage,
bool ShouldCreate = true) {
- return getImpl(Context, Tag, Scope, Entity, Line,
+ return getImpl(Context, Tag, Scope, Entity, File, Line,
getCanonicalMDString(Context, Name), Storage, ShouldCreate);
}
static DIImportedEntity *getImpl(LLVMContext &Context, unsigned Tag,
Metadata *Scope, Metadata *Entity,
- unsigned Line, MDString *Name,
- StorageType Storage,
+ Metadata *File, unsigned Line,
+ MDString *Name, StorageType Storage,
bool ShouldCreate = true);
TempDIImportedEntity cloneImpl() const {
return getTemporary(getContext(), getTag(), getScope(), getEntity(),
- getLine(), getName());
+ getFile(), getLine(), getName());
}
public:
DEFINE_MDNODE_GET(DIImportedEntity,
(unsigned Tag, DIScope *Scope, DINodeRef Entity,
- unsigned Line, StringRef Name = ""),
- (Tag, Scope, Entity, Line, Name))
+ DIFile *File, unsigned Line, StringRef Name = ""),
+ (Tag, Scope, Entity, File, Line, Name))
DEFINE_MDNODE_GET(DIImportedEntity,
(unsigned Tag, Metadata *Scope, Metadata *Entity,
- unsigned Line, MDString *Name),
- (Tag, Scope, Entity, Line, Name))
+ Metadata *File, unsigned Line, MDString *Name),
+ (Tag, Scope, Entity, File, Line, Name))
TempDIImportedEntity clone() const { return cloneImpl(); }
@@ -2407,10 +2584,12 @@ public:
DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); }
DINodeRef getEntity() const { return DINodeRef(getRawEntity()); }
StringRef getName() const { return getStringOperand(2); }
+ DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
Metadata *getRawScope() const { return getOperand(0); }
Metadata *getRawEntity() const { return getOperand(1); }
MDString *getRawName() const { return getOperandAs<MDString>(2); }
+ Metadata *getRawFile() const { return getOperand(3); }
static bool classof(const Metadata *MD) {
return MD->getMetadataID() == DIImportedEntityKind;
@@ -2443,10 +2622,13 @@ public:
TempDIGlobalVariableExpression clone() const { return cloneImpl(); }
Metadata *getRawVariable() const { return getOperand(0); }
+
DIGlobalVariable *getVariable() const {
return cast_or_null<DIGlobalVariable>(getRawVariable());
}
+
Metadata *getRawExpression() const { return getOperand(1); }
+
DIExpression *getExpression() const {
return cast_or_null<DIExpression>(getRawExpression());
}
@@ -2459,7 +2641,8 @@ public:
/// Macro Info DWARF-like metadata node.
///
/// A metadata node with a DWARF macro info (i.e., a constant named
-/// \c DW_MACINFO_*, defined in llvm/Support/Dwarf.h). Called \a DIMacroNode
+/// \c DW_MACINFO_*, defined in llvm/BinaryFormat/Dwarf.h). Called \a
+/// DIMacroNode
/// because it's potentially used for non-DWARF output.
class DIMacroNode : public MDNode {
friend class LLVMContextImpl;
diff --git a/contrib/llvm/include/llvm/IR/DebugLoc.h b/contrib/llvm/include/llvm/IR/DebugLoc.h
index 202be3d..eef1212 100644
--- a/contrib/llvm/include/llvm/IR/DebugLoc.h
+++ b/contrib/llvm/include/llvm/IR/DebugLoc.h
@@ -80,6 +80,16 @@ namespace llvm {
static DebugLoc get(unsigned Line, unsigned Col, const MDNode *Scope,
const MDNode *InlinedAt = nullptr);
+ enum { ReplaceLastInlinedAt = true };
+ /// Rebuild the entire inlined-at chain for this instruction so that the top of
+ /// 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,
+ LLVMContext &Ctx,
+ DenseMap<const MDNode *, MDNode *> &Cache,
+ bool ReplaceLast = false);
+
unsigned getLine() const;
unsigned getCol() const;
MDNode *getScope() const;
diff --git a/contrib/llvm/include/llvm/IR/DerivedTypes.h b/contrib/llvm/include/llvm/IR/DerivedTypes.h
index 05e9915..6e5e085 100644
--- a/contrib/llvm/include/llvm/IR/DerivedTypes.h
+++ b/contrib/llvm/include/llvm/IR/DerivedTypes.h
@@ -1,4 +1,4 @@
-//===-- llvm/DerivedTypes.h - Classes for handling data types ---*- C++ -*-===//
+//===- llvm/DerivedTypes.h - Classes for handling data types ----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -19,6 +19,7 @@
#define LLVM_IR_DERIVEDTYPES_H
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/IR/Type.h"
#include "llvm/Support/Casting.h"
@@ -88,7 +89,7 @@ public:
bool isPowerOf2ByteWidth() const;
/// Methods for support type inquiry through isa, cast, and dyn_cast.
- static inline bool classof(const Type *T) {
+ static bool classof(const Type *T) {
return T->getTypeID() == IntegerTyID;
}
};
@@ -122,7 +123,8 @@ public:
bool isVarArg() const { return getSubclassData()!=0; }
Type *getReturnType() const { return ContainedTys[0]; }
- typedef Type::subtype_iterator param_iterator;
+ using param_iterator = Type::subtype_iterator;
+
param_iterator param_begin() const { return ContainedTys + 1; }
param_iterator param_end() const { return &ContainedTys[NumContainedTys]; }
ArrayRef<Type *> params() const {
@@ -137,7 +139,7 @@ public:
unsigned getNumParams() const { return NumContainedTys - 1; }
/// Methods for support type inquiry through isa, cast, and dyn_cast.
- static inline bool classof(const Type *T) {
+ static bool classof(const Type *T) {
return T->getTypeID() == FunctionTyID;
}
};
@@ -169,7 +171,7 @@ public:
bool indexValid(unsigned Idx) const;
/// Methods for support type inquiry through isa, cast, and dyn_cast.
- static inline bool classof(const Type *T) {
+ static bool classof(const Type *T) {
return T->getTypeID() == ArrayTyID ||
T->getTypeID() == StructTyID ||
T->getTypeID() == VectorTyID;
@@ -197,8 +199,7 @@ public:
/// generator for a target expects).
///
class StructType : public CompositeType {
- StructType(LLVMContext &C)
- : CompositeType(C, StructTyID), SymbolTableEntry(nullptr) {}
+ StructType(LLVMContext &C) : CompositeType(C, StructTyID) {}
enum {
/// This is the contents of the SubClassData field.
@@ -212,7 +213,7 @@ class StructType : public CompositeType {
/// symbol table entry (maintained by LLVMContext) for the struct.
/// This is null if the type is an literal struct or if it is a identified
/// type that has an empty name.
- void *SymbolTableEntry;
+ void *SymbolTableEntry = nullptr;
public:
StructType(const StructType &) = delete;
@@ -228,7 +229,14 @@ public:
static StructType *create(LLVMContext &Context, ArrayRef<Type *> Elements,
StringRef Name, bool isPacked = false);
static StructType *create(LLVMContext &Context, ArrayRef<Type *> Elements);
- static StructType *create(StringRef Name, Type *elt1, ...) LLVM_END_WITH_NULL;
+ template <class... Tys>
+ static typename std::enable_if<are_base_of<Type, Tys...>::value,
+ StructType *>::type
+ 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...});
+ return create(StructFields, Name);
+ }
/// This static method is the primary way to create a literal StructType.
static StructType *get(LLVMContext &Context, ArrayRef<Type*> Elements,
@@ -240,7 +248,15 @@ public:
/// This static method is a convenience method for creating structure types by
/// specifying the elements as arguments. Note that this method always returns
/// a non-packed struct, and requires at least one element type.
- static StructType *get(Type *elt1, ...) LLVM_END_WITH_NULL;
+ template <class... Tys>
+ static typename std::enable_if<are_base_of<Type, Tys...>::value,
+ StructType *>::type
+ get(Type *elt1, Tys *... elts) {
+ assert(elt1 && "Cannot create a struct type with no elements with this");
+ LLVMContext &Ctx = elt1->getContext();
+ SmallVector<llvm::Type *, 8> StructFields({elt1, elts...});
+ return llvm::StructType::get(Ctx, StructFields);
+ }
bool isPacked() const { return (getSubclassData() & SCDB_Packed) != 0; }
@@ -269,13 +285,21 @@ public:
/// Specify a body for an opaque identified type.
void setBody(ArrayRef<Type*> Elements, bool isPacked = false);
- void setBody(Type *elt1, ...) LLVM_END_WITH_NULL;
+
+ template <typename... Tys>
+ typename std::enable_if<are_base_of<Type, Tys...>::value, void>::type
+ setBody(Type *elt1, Tys *... elts) {
+ assert(elt1 && "Cannot create a struct type with no elements with this");
+ SmallVector<llvm::Type *, 8> StructFields({elt1, elts...});
+ setBody(StructFields);
+ }
/// Return true if the specified type is valid as a element type.
static bool isValidElementType(Type *ElemTy);
// Iterator access to the elements.
- typedef Type::subtype_iterator element_iterator;
+ using element_iterator = Type::subtype_iterator;
+
element_iterator element_begin() const { return ContainedTys; }
element_iterator element_end() const { return &ContainedTys[NumContainedTys];}
ArrayRef<Type *> const elements() const {
@@ -293,7 +317,7 @@ public:
}
/// Methods for support type inquiry through isa, cast, and dyn_cast.
- static inline bool classof(const Type *T) {
+ static bool classof(const Type *T) {
return T->getTypeID() == StructTyID;
}
};
@@ -336,7 +360,7 @@ public:
Type *getElementType() const { return ContainedType; }
/// Methods for support type inquiry through isa, cast, and dyn_cast.
- static inline bool classof(const Type *T) {
+ static bool classof(const Type *T) {
return T->getTypeID() == ArrayTyID || T->getTypeID() == VectorTyID;
}
};
@@ -356,7 +380,7 @@ public:
static bool isValidElementType(Type *ElemTy);
/// Methods for support type inquiry through isa, cast, and dyn_cast.
- static inline bool classof(const Type *T) {
+ static bool classof(const Type *T) {
return T->getTypeID() == ArrayTyID;
}
};
@@ -430,7 +454,7 @@ public:
}
/// Methods for support type inquiry through isa, cast, and dyn_cast.
- static inline bool classof(const Type *T) {
+ static bool classof(const Type *T) {
return T->getTypeID() == VectorTyID;
}
};
@@ -471,7 +495,7 @@ public:
inline unsigned getAddressSpace() const { return getSubclassData(); }
/// Implement support type inquiry through isa, cast, and dyn_cast.
- static inline bool classof(const Type *T) {
+ static bool classof(const Type *T) {
return T->getTypeID() == PointerTyID;
}
};
diff --git a/contrib/llvm/include/llvm/IR/DerivedUser.h b/contrib/llvm/include/llvm/IR/DerivedUser.h
new file mode 100644
index 0000000..67c483d
--- /dev/null
+++ b/contrib/llvm/include/llvm/IR/DerivedUser.h
@@ -0,0 +1,45 @@
+//===- DerivedUser.h - Base for non-IR Users --------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_DERIVEDUSER_H
+#define LLVM_IR_DERIVEDUSER_H
+
+#include "llvm/IR/User.h"
+
+namespace llvm {
+
+class Type;
+class Use;
+
+/// Extension point for the Value hierarchy. All classes outside of lib/IR
+/// that wish to inherit from User should instead inherit from DerivedUser
+/// instead. Inheriting from this class is discouraged.
+///
+/// Generally speaking, Value is the base of a closed class hierarchy
+/// that can't be extended by code outside of lib/IR. This class creates a
+/// loophole that allows classes outside of lib/IR to extend User to leverage
+/// its use/def list machinery.
+class DerivedUser : public User {
+protected:
+ using DeleteValueTy = void (*)(DerivedUser *);
+
+private:
+ friend class Value;
+
+ DeleteValueTy DeleteValue;
+
+public:
+ DerivedUser(Type *Ty, unsigned VK, Use *U, unsigned NumOps,
+ DeleteValueTy DeleteValue)
+ : User(Ty, VK, U, NumOps), DeleteValue(DeleteValue) {}
+};
+
+} // end namespace llvm
+
+#endif // LLVM_IR_DERIVEDUSER_H
diff --git a/contrib/llvm/include/llvm/IR/DiagnosticInfo.h b/contrib/llvm/include/llvm/IR/DiagnosticInfo.h
index a93c180..15d3325 100644
--- a/contrib/llvm/include/llvm/IR/DiagnosticInfo.h
+++ b/contrib/llvm/include/llvm/IR/DiagnosticInfo.h
@@ -15,7 +15,7 @@
#ifndef LLVM_IR_DIAGNOSTICINFO_H
#define LLVM_IR_DIAGNOSTICINFO_H
-#include "llvm/ADT/None.h"
+#include "llvm-c/Types.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
@@ -23,10 +23,9 @@
#include "llvm/IR/DebugLoc.h"
#include "llvm/Support/CBindingWrapping.h"
#include "llvm/Support/YAMLTraits.h"
-#include "llvm-c/Types.h"
-#include <functional>
#include <algorithm>
#include <cstdint>
+#include <functional>
#include <iterator>
#include <string>
@@ -69,6 +68,11 @@ enum DiagnosticKind {
DK_OptimizationFailure,
DK_FirstRemark = DK_OptimizationRemark,
DK_LastRemark = DK_OptimizationFailure,
+ DK_MachineOptimizationRemark,
+ DK_MachineOptimizationRemarkMissed,
+ DK_MachineOptimizationRemarkAnalysis,
+ DK_FirstMachineRemark = DK_MachineOptimizationRemark,
+ DK_LastMachineRemark = DK_MachineOptimizationRemarkAnalysis,
DK_MIRParser,
DK_PGOProfile,
DK_Unsupported,
@@ -115,18 +119,18 @@ public:
virtual void print(DiagnosticPrinter &DP) const = 0;
};
-typedef std::function<void(const DiagnosticInfo &)> DiagnosticHandlerFunction;
+using DiagnosticHandlerFunction = std::function<void(const DiagnosticInfo &)>;
/// Diagnostic information for inline asm reporting.
/// This is basically a message and an optional location.
class DiagnosticInfoInlineAsm : public DiagnosticInfo {
private:
/// Optional line information. 0 if not set.
- unsigned LocCookie;
+ unsigned LocCookie = 0;
/// Message to be reported.
const Twine &MsgStr;
/// Optional origin of the problem.
- const Instruction *Instr;
+ const Instruction *Instr = nullptr;
public:
/// \p MsgStr is the message to be reported to the frontend.
@@ -134,8 +138,7 @@ public:
/// for the whole life time of the Diagnostic.
DiagnosticInfoInlineAsm(const Twine &MsgStr,
DiagnosticSeverity Severity = DS_Error)
- : DiagnosticInfo(DK_InlineAsm, Severity), LocCookie(0), MsgStr(MsgStr),
- Instr(nullptr) {}
+ : DiagnosticInfo(DK_InlineAsm, Severity), MsgStr(MsgStr) {}
/// \p LocCookie if non-zero gives the line number for this report.
/// \p MsgStr gives the message.
@@ -144,7 +147,7 @@ public:
DiagnosticInfoInlineAsm(unsigned LocCookie, const Twine &MsgStr,
DiagnosticSeverity Severity = DS_Error)
: DiagnosticInfo(DK_InlineAsm, Severity), LocCookie(LocCookie),
- MsgStr(MsgStr), Instr(nullptr) {}
+ MsgStr(MsgStr) {}
/// \p Instr gives the original instruction that triggered the diagnostic.
/// \p MsgStr gives the message.
@@ -289,10 +292,10 @@ public:
DiagnosticInfoSampleProfile(StringRef FileName, const Twine &Msg,
DiagnosticSeverity Severity = DS_Error)
: DiagnosticInfo(DK_SampleProfile, Severity), FileName(FileName),
- LineNum(0), Msg(Msg) {}
+ Msg(Msg) {}
DiagnosticInfoSampleProfile(const Twine &Msg,
DiagnosticSeverity Severity = DS_Error)
- : DiagnosticInfo(DK_SampleProfile, Severity), LineNum(0), Msg(Msg) {}
+ : DiagnosticInfo(DK_SampleProfile, Severity), Msg(Msg) {}
/// \see DiagnosticInfo::print.
void print(DiagnosticPrinter &DP) const override;
@@ -311,7 +314,7 @@ private:
/// Line number where the diagnostic occurred. If 0, no line number will
/// be emitted in the message.
- unsigned LineNum;
+ unsigned LineNum = 0;
/// Message to report.
const Twine &Msg;
@@ -342,19 +345,35 @@ private:
const Twine &Msg;
};
-/// Common features for diagnostics with an associated DebugLoc
-class DiagnosticInfoWithDebugLocBase : public DiagnosticInfo {
+class DiagnosticLocation {
+ StringRef Filename;
+ unsigned Line = 0;
+ unsigned Column = 0;
+
+public:
+ DiagnosticLocation() = default;
+ DiagnosticLocation(const DebugLoc &DL);
+ DiagnosticLocation(const DISubprogram *SP);
+
+ bool isValid() const { return !Filename.empty(); }
+ StringRef getFilename() const { return Filename; }
+ unsigned getLine() const { return Line; }
+ unsigned getColumn() const { return Column; }
+};
+
+/// Common features for diagnostics with an associated location.
+class DiagnosticInfoWithLocationBase : public DiagnosticInfo {
public:
- /// \p Fn is the function where the diagnostic is being emitted. \p DLoc is
+ /// \p Fn is the function where the diagnostic is being emitted. \p Loc is
/// the location information to use in the diagnostic.
- DiagnosticInfoWithDebugLocBase(enum DiagnosticKind Kind,
+ DiagnosticInfoWithLocationBase(enum DiagnosticKind Kind,
enum DiagnosticSeverity Severity,
const Function &Fn,
- const DebugLoc &DLoc)
- : DiagnosticInfo(Kind, Severity), Fn(Fn), DLoc(DLoc) {}
+ const DiagnosticLocation &Loc)
+ : DiagnosticInfo(Kind, Severity), Fn(Fn), Loc(Loc) {}
/// Return true if location information is available for this diagnostic.
- bool isLocationAvailable() const;
+ bool isLocationAvailable() const { return Loc.isValid(); }
/// Return a string with the location information for this diagnostic
/// in the format "file:line:col". If location information is not available,
@@ -366,18 +385,19 @@ public:
void getLocation(StringRef *Filename, unsigned *Line, unsigned *Column) const;
const Function &getFunction() const { return Fn; }
- const DebugLoc &getDebugLoc() const { return DLoc; }
+ DiagnosticLocation getLocation() const { return Loc; }
private:
/// Function where this diagnostic is triggered.
const Function &Fn;
/// Debug location where this diagnostic is triggered.
- DebugLoc DLoc;
+ DiagnosticLocation Loc;
};
-/// Common features for diagnostics dealing with optimization remarks.
-class DiagnosticInfoOptimizationBase : public DiagnosticInfoWithDebugLocBase {
+/// \brief Common features for diagnostics dealing with optimization remarks
+/// that are used by both IR and MIR passes.
+class DiagnosticInfoOptimizationBase : public DiagnosticInfoWithLocationBase {
public:
/// \brief Used to set IsVerbose via the stream interface.
struct setIsVerbose {};
@@ -394,66 +414,29 @@ public:
StringRef Key;
std::string Val;
// If set, the debug location corresponding to the value.
- DebugLoc DLoc;
+ DiagnosticLocation Loc;
explicit Argument(StringRef Str = "") : Key("String"), Val(Str) {}
- Argument(StringRef Key, Value *V);
- Argument(StringRef Key, Type *T);
+ Argument(StringRef Key, const Value *V);
+ Argument(StringRef Key, const Type *T);
Argument(StringRef Key, int N);
Argument(StringRef Key, unsigned N);
Argument(StringRef Key, bool B) : Key(Key), Val(B ? "true" : "false") {}
};
/// \p PassName is the name of the pass emitting this diagnostic. \p
- /// RemarkName is a textual identifier for the remark. \p Fn is the function
- /// where the diagnostic is being emitted. \p DLoc is the location information
- /// to use in the diagnostic. If line table information is available, the
- /// diagnostic will include the source code location. \p CodeRegion is IR
- /// value (currently basic block) that the optimization operates on. This is
- /// currently used to provide run-time hotness information with PGO.
- DiagnosticInfoOptimizationBase(enum DiagnosticKind Kind,
- enum DiagnosticSeverity Severity,
- const char *PassName, StringRef RemarkName,
- const Function &Fn, const DebugLoc &DLoc,
- Value *CodeRegion = nullptr)
- : DiagnosticInfoWithDebugLocBase(Kind, Severity, Fn, DLoc),
- PassName(PassName), RemarkName(RemarkName), CodeRegion(CodeRegion) {}
-
- /// \brief This is ctor variant allows a pass to build an optimization remark
- /// from an existing remark.
- ///
- /// This is useful when a transformation pass (e.g LV) wants to emit a remark
- /// (\p Orig) generated by one of its analyses (e.g. LAA) as its own analysis
- /// remark. The string \p Prepend will be emitted before the original
- /// message.
- DiagnosticInfoOptimizationBase(const char *PassName, StringRef Prepend,
- const DiagnosticInfoOptimizationBase &Orig)
- : DiagnosticInfoWithDebugLocBase((DiagnosticKind)Orig.getKind(),
- Orig.getSeverity(), Orig.getFunction(),
- Orig.getDebugLoc()),
- PassName(PassName), RemarkName(Orig.RemarkName),
- CodeRegion(Orig.getCodeRegion()) {
- *this << Prepend;
- std::copy(Orig.Args.begin(), Orig.Args.end(), std::back_inserter(Args));
- }
-
- /// Legacy interface.
- /// \p PassName is the name of the pass emitting this diagnostic.
- /// \p Fn is the function where the diagnostic is being emitted. \p DLoc is
- /// the location information to use in the diagnostic. If line table
+ /// RemarkName is a textual identifier for the remark (single-word,
+ /// camel-case). \p Fn is the function where the diagnostic is being emitted.
+ /// \p Loc is the location information to use in the diagnostic. If line table
/// information is available, the diagnostic will include the source code
- /// location. \p Msg is the message to show. Note that this class does not
- /// copy this message, so this reference must be valid for the whole life time
- /// of the diagnostic.
+ /// location.
DiagnosticInfoOptimizationBase(enum DiagnosticKind Kind,
enum DiagnosticSeverity Severity,
- const char *PassName, const Function &Fn,
- const DebugLoc &DLoc, const Twine &Msg,
- Optional<uint64_t> Hotness = None)
- : DiagnosticInfoWithDebugLocBase(Kind, Severity, Fn, DLoc),
- PassName(PassName), Hotness(Hotness) {
- Args.push_back(Argument(Msg.str()));
- }
+ const char *PassName, StringRef RemarkName,
+ const Function &Fn,
+ const DiagnosticLocation &Loc)
+ : DiagnosticInfoWithLocationBase(Kind, Severity, Fn, Loc),
+ PassName(PassName), RemarkName(RemarkName) {}
DiagnosticInfoOptimizationBase &operator<<(StringRef S);
DiagnosticInfoOptimizationBase &operator<<(Argument A);
@@ -475,33 +458,45 @@ public:
Optional<uint64_t> getHotness() const { return Hotness; }
void setHotness(Optional<uint64_t> H) { Hotness = H; }
- Value *getCodeRegion() const { return CodeRegion; }
-
bool isVerbose() const { return IsVerbose; }
static bool classof(const DiagnosticInfo *DI) {
- return DI->getKind() >= DK_FirstRemark &&
- DI->getKind() <= DK_LastRemark;
+ return (DI->getKind() >= DK_FirstRemark &&
+ DI->getKind() <= DK_LastRemark) ||
+ (DI->getKind() >= DK_FirstMachineRemark &&
+ DI->getKind() <= DK_LastMachineRemark);
}
-private:
+ bool isPassed() const {
+ return (getKind() == DK_OptimizationRemark ||
+ getKind() == DK_MachineOptimizationRemark);
+ }
+
+ bool isMissed() const {
+ return (getKind() == DK_OptimizationRemarkMissed ||
+ getKind() == DK_MachineOptimizationRemarkMissed);
+ }
+
+ bool isAnalysis() const {
+ return (getKind() == DK_OptimizationRemarkAnalysis ||
+ getKind() == DK_MachineOptimizationRemarkAnalysis);
+ }
+
+protected:
/// Name of the pass that triggers this report. If this matches the
/// regular expression given in -Rpass=regexp, then the remark will
/// be emitted.
const char *PassName;
- /// Textual identifier for the remark. Can be used by external tools reading
- /// the YAML output file for optimization remarks to identify the remark.
+ /// Textual identifier for the remark (single-word, camel-case). Can be used
+ /// by external tools reading the YAML output file for optimization remarks to
+ /// identify the remark.
StringRef RemarkName;
/// If profile information is available, this is the number of times the
/// corresponding code was executed in a profile instrumentation run.
Optional<uint64_t> Hotness;
- /// The IR value (currently basic block) that the optimization operates on.
- /// This is currently used to provide run-time hotness information with PGO.
- Value *CodeRegion;
-
/// Arguments collected via the streaming interface.
SmallVector<Argument, 4> Args;
@@ -516,106 +511,186 @@ private:
friend struct yaml::MappingTraits<DiagnosticInfoOptimizationBase *>;
};
-/// Diagnostic information for applied optimization remarks.
-class OptimizationRemark : public DiagnosticInfoOptimizationBase {
+/// \brief Common features for diagnostics dealing with optimization remarks
+/// that are used by IR passes.
+class DiagnosticInfoIROptimization : public DiagnosticInfoOptimizationBase {
public:
- /// \p PassName is the name of the pass emitting this diagnostic. If
- /// this name matches the regular expression given in -Rpass=, then the
- /// diagnostic will be emitted. \p Fn is the function where the diagnostic
- /// is being emitted. \p DLoc is the location information to use in the
- /// diagnostic. If line table information is available, the diagnostic
- /// will include the source code location. \p Msg is the message to show.
- /// Note that this class does not copy this message, so this reference
- /// must be valid for the whole life time of the diagnostic.
- OptimizationRemark(const char *PassName, const Function &Fn,
- const DebugLoc &DLoc, const Twine &Msg,
- Optional<uint64_t> Hotness = None)
- : DiagnosticInfoOptimizationBase(DK_OptimizationRemark, DS_Remark,
- PassName, Fn, DLoc, Msg, Hotness) {}
+ /// \p PassName is the name of the pass emitting this diagnostic. \p
+ /// RemarkName is a textual identifier for the remark (single-word,
+ /// camel-case). \p Fn is the function where the diagnostic is being emitted.
+ /// \p Loc is the location information to use in the diagnostic. If line table
+ /// information is available, the diagnostic will include the source code
+ /// location. \p CodeRegion is IR value (currently basic block) that the
+ /// optimization operates on. This is currently used to provide run-time
+ /// hotness information with PGO.
+ DiagnosticInfoIROptimization(enum DiagnosticKind Kind,
+ enum DiagnosticSeverity Severity,
+ const char *PassName, StringRef RemarkName,
+ const Function &Fn,
+ const DiagnosticLocation &Loc,
+ const Value *CodeRegion = nullptr)
+ : DiagnosticInfoOptimizationBase(Kind, Severity, PassName, RemarkName, Fn,
+ Loc),
+ CodeRegion(CodeRegion) {}
+
+ /// \brief This is ctor variant allows a pass to build an optimization remark
+ /// from an existing remark.
+ ///
+ /// This is useful when a transformation pass (e.g LV) wants to emit a remark
+ /// (\p Orig) generated by one of its analyses (e.g. LAA) as its own analysis
+ /// remark. The string \p Prepend will be emitted before the original
+ /// message.
+ DiagnosticInfoIROptimization(const char *PassName, StringRef Prepend,
+ const DiagnosticInfoIROptimization &Orig)
+ : DiagnosticInfoOptimizationBase(
+ (DiagnosticKind)Orig.getKind(), Orig.getSeverity(), PassName,
+ Orig.RemarkName, Orig.getFunction(), Orig.getLocation()),
+ CodeRegion(Orig.getCodeRegion()) {
+ *this << Prepend;
+ std::copy(Orig.Args.begin(), Orig.Args.end(), std::back_inserter(Args));
+ }
+ /// Legacy interface.
+ /// \p PassName is the name of the pass emitting this diagnostic.
+ /// \p Fn is the function where the diagnostic is being emitted. \p Loc is
+ /// the location information to use in the diagnostic. If line table
+ /// information is available, the diagnostic will include the source code
+ /// location. \p Msg is the message to show. Note that this class does not
+ /// copy this message, so this reference must be valid for the whole life time
+ /// of the diagnostic.
+ DiagnosticInfoIROptimization(enum DiagnosticKind Kind,
+ enum DiagnosticSeverity Severity,
+ const char *PassName, const Function &Fn,
+ const DiagnosticLocation &Loc, const Twine &Msg)
+ : DiagnosticInfoOptimizationBase(Kind, Severity, PassName, "", Fn, Loc) {
+ *this << Msg.str();
+ }
+
+ const Value *getCodeRegion() const { return CodeRegion; }
+
+ static bool classof(const DiagnosticInfo *DI) {
+ return DI->getKind() >= DK_FirstRemark && DI->getKind() <= DK_LastRemark;
+ }
+
+private:
+ /// The IR value (currently basic block) that the optimization operates on.
+ /// This is currently used to provide run-time hotness information with PGO.
+ const Value *CodeRegion;
+};
+
+/// Diagnostic information for applied optimization remarks.
+class OptimizationRemark : public DiagnosticInfoIROptimization {
+public:
/// \p PassName is the name of the pass emitting this diagnostic. If this name
/// matches the regular expression given in -Rpass=, then the diagnostic will
- /// be emitted. \p RemarkName is a textual identifier for the remark. \p
- /// DLoc is the debug location and \p CodeRegion is the region that the
- /// optimization operates on (currently on block is supported).
+ /// be emitted. \p RemarkName is a textual identifier for the remark (single-
+ /// word, camel-case). \p Loc is the debug location and \p CodeRegion is the
+ /// region that the optimization operates on (currently only block is
+ /// supported).
OptimizationRemark(const char *PassName, StringRef RemarkName,
- const DebugLoc &DLoc, Value *CodeRegion);
+ const DiagnosticLocation &Loc, const Value *CodeRegion);
- /// Same as above but the debug location and code region is derived from \p
+ /// Same as above, but the debug location and code region are derived from \p
/// Instr.
OptimizationRemark(const char *PassName, StringRef RemarkName,
- Instruction *Inst);
+ const Instruction *Inst);
+
+ /// Same as above, but the debug location and code region are derived from \p
+ /// Func.
+ OptimizationRemark(const char *PassName, StringRef RemarkName,
+ const Function *Func);
static bool classof(const DiagnosticInfo *DI) {
return DI->getKind() == DK_OptimizationRemark;
}
+ static bool isEnabled(StringRef PassName);
+
/// \see DiagnosticInfoOptimizationBase::isEnabled.
- bool isEnabled() const override;
-};
+ bool isEnabled() const override { return isEnabled(getPassName()); }
-/// Diagnostic information for missed-optimization remarks.
-class OptimizationRemarkMissed : public DiagnosticInfoOptimizationBase {
-public:
+private:
+ /// This is deprecated now and only used by the function API below.
/// \p PassName is the name of the pass emitting this diagnostic. If
- /// this name matches the regular expression given in -Rpass-missed=, then the
+ /// this name matches the regular expression given in -Rpass=, then the
/// diagnostic will be emitted. \p Fn is the function where the diagnostic
- /// is being emitted. \p DLoc is the location information to use in the
+ /// is being emitted. \p Loc is the location information to use in the
/// diagnostic. If line table information is available, the diagnostic
/// will include the source code location. \p Msg is the message to show.
/// Note that this class does not copy this message, so this reference
/// must be valid for the whole life time of the diagnostic.
- OptimizationRemarkMissed(const char *PassName, const Function &Fn,
- const DebugLoc &DLoc, const Twine &Msg,
- Optional<uint64_t> Hotness = None)
- : DiagnosticInfoOptimizationBase(DK_OptimizationRemarkMissed, DS_Remark,
- PassName, Fn, DLoc, Msg, Hotness) {}
+ OptimizationRemark(const char *PassName, const Function &Fn,
+ const DiagnosticLocation &Loc, const Twine &Msg)
+ : DiagnosticInfoIROptimization(DK_OptimizationRemark, DS_Remark, PassName,
+ Fn, Loc, Msg) {}
+
+ friend void emitOptimizationRemark(LLVMContext &Ctx, const char *PassName,
+ const Function &Fn,
+ const DiagnosticLocation &Loc,
+ const Twine &Msg);
+};
+/// Diagnostic information for missed-optimization remarks.
+class OptimizationRemarkMissed : public DiagnosticInfoIROptimization {
+public:
/// \p PassName is the name of the pass emitting this diagnostic. If this name
/// matches the regular expression given in -Rpass-missed=, then the
- /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
- /// remark. \p DLoc is the debug location and \p CodeRegion is the region
- /// that the optimization operates on (currently on block is supported).
+ /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
+ /// remark (single-word, camel-case). \p Loc is the debug location and \p
+ /// CodeRegion is the region that the optimization operates on (currently only
+ /// block is supported).
OptimizationRemarkMissed(const char *PassName, StringRef RemarkName,
- const DebugLoc &DLoc, Value *CodeRegion);
+ const DiagnosticLocation &Loc,
+ const Value *CodeRegion);
/// \brief Same as above but \p Inst is used to derive code region and debug
/// location.
OptimizationRemarkMissed(const char *PassName, StringRef RemarkName,
- Instruction *Inst);
+ const Instruction *Inst);
static bool classof(const DiagnosticInfo *DI) {
return DI->getKind() == DK_OptimizationRemarkMissed;
}
+ static bool isEnabled(StringRef PassName);
+
/// \see DiagnosticInfoOptimizationBase::isEnabled.
- bool isEnabled() const override;
+ bool isEnabled() const override { return isEnabled(getPassName()); }
+
+private:
+ /// This is deprecated now and only used by the function API below.
+ /// \p PassName is the name of the pass emitting this diagnostic. If
+ /// this name matches the regular expression given in -Rpass-missed=, then the
+ /// diagnostic will be emitted. \p Fn is the function where the diagnostic
+ /// is being emitted. \p Loc is the location information to use in the
+ /// diagnostic. If line table information is available, the diagnostic
+ /// will include the source code location. \p Msg is the message to show.
+ /// Note that this class does not copy this message, so this reference
+ /// must be valid for the whole life time of the diagnostic.
+ OptimizationRemarkMissed(const char *PassName, const Function &Fn,
+ const DiagnosticLocation &Loc, const Twine &Msg)
+ : DiagnosticInfoIROptimization(DK_OptimizationRemarkMissed, DS_Remark,
+ PassName, Fn, Loc, Msg) {}
+
+ friend void emitOptimizationRemarkMissed(LLVMContext &Ctx,
+ const char *PassName,
+ const Function &Fn,
+ const DiagnosticLocation &Loc,
+ const Twine &Msg);
};
/// Diagnostic information for optimization analysis remarks.
-class OptimizationRemarkAnalysis : public DiagnosticInfoOptimizationBase {
+class OptimizationRemarkAnalysis : public DiagnosticInfoIROptimization {
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 diagnostic will be emitted. \p Fn is the function where the diagnostic
- /// is being emitted. \p DLoc is the location information to use in the
- /// diagnostic. If line table information is available, the diagnostic will
- /// include the source code location. \p Msg is the message to show. Note that
- /// this class does not copy this message, so this reference must be valid for
- /// the whole life time of the diagnostic.
- OptimizationRemarkAnalysis(const char *PassName, const Function &Fn,
- const DebugLoc &DLoc, const Twine &Msg,
- Optional<uint64_t> Hotness = None)
- : DiagnosticInfoOptimizationBase(DK_OptimizationRemarkAnalysis, DS_Remark,
- PassName, Fn, DLoc, Msg, Hotness) {}
-
/// \p PassName is the name of the pass emitting this diagnostic. If this name
/// matches the regular expression given in -Rpass-analysis=, then the
- /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
- /// remark. \p DLoc is the debug location and \p CodeRegion is the region
- /// that the optimization operates on (currently on block is supported).
+ /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
+ /// remark (single-word, camel-case). \p Loc is the debug location and \p
+ /// CodeRegion is the region that the optimization operates on (currently only
+ /// block is supported).
OptimizationRemarkAnalysis(const char *PassName, StringRef RemarkName,
- const DebugLoc &DLoc, Value *CodeRegion);
+ const DiagnosticLocation &Loc,
+ const Value *CodeRegion);
/// \brief This is ctor variant allows a pass to build an optimization remark
/// from an existing remark.
@@ -626,19 +701,23 @@ public:
/// message.
OptimizationRemarkAnalysis(const char *PassName, StringRef Prepend,
const OptimizationRemarkAnalysis &Orig)
- : DiagnosticInfoOptimizationBase(PassName, Prepend, Orig) {}
+ : DiagnosticInfoIROptimization(PassName, Prepend, Orig) {}
/// \brief Same as above but \p Inst is used to derive code region and debug
/// location.
OptimizationRemarkAnalysis(const char *PassName, StringRef RemarkName,
- Instruction *Inst);
+ const Instruction *Inst);
static bool classof(const DiagnosticInfo *DI) {
return DI->getKind() == DK_OptimizationRemarkAnalysis;
}
+ static bool isEnabled(StringRef PassName);
+
/// \see DiagnosticInfoOptimizationBase::isEnabled.
- bool isEnabled() const override;
+ bool isEnabled() const override {
+ return shouldAlwaysPrint() || isEnabled(getPassName());
+ }
static const char *AlwaysPrint;
@@ -646,24 +725,65 @@ public:
protected:
OptimizationRemarkAnalysis(enum DiagnosticKind Kind, const char *PassName,
- const Function &Fn, const DebugLoc &DLoc,
- const Twine &Msg, Optional<uint64_t> Hotness)
- : DiagnosticInfoOptimizationBase(Kind, DS_Remark, PassName, Fn, DLoc, Msg,
- Hotness) {}
+ const Function &Fn, const DiagnosticLocation &Loc,
+ const Twine &Msg)
+ : DiagnosticInfoIROptimization(Kind, DS_Remark, PassName, Fn, Loc, Msg) {}
OptimizationRemarkAnalysis(enum DiagnosticKind Kind, const char *PassName,
- StringRef RemarkName, const DebugLoc &DLoc,
- Value *CodeRegion);
+ StringRef RemarkName,
+ const DiagnosticLocation &Loc,
+ const Value *CodeRegion);
+
+private:
+ /// This is deprecated now and only used by the function API below.
+ /// \p PassName is the name of the pass emitting this diagnostic. If
+ /// this name matches the regular expression given in -Rpass-analysis=, then
+ /// the diagnostic will be emitted. \p Fn is the function where the diagnostic
+ /// is being emitted. \p Loc is the location information to use in the
+ /// diagnostic. If line table information is available, the diagnostic will
+ /// include the source code location. \p Msg is the message to show. Note that
+ /// this class does not copy this message, so this reference must be valid for
+ /// the whole life time of the diagnostic.
+ OptimizationRemarkAnalysis(const char *PassName, const Function &Fn,
+ const DiagnosticLocation &Loc, const Twine &Msg)
+ : DiagnosticInfoIROptimization(DK_OptimizationRemarkAnalysis, DS_Remark,
+ PassName, Fn, Loc, Msg) {}
+
+ friend void emitOptimizationRemarkAnalysis(LLVMContext &Ctx,
+ const char *PassName,
+ const Function &Fn,
+ const DiagnosticLocation &Loc,
+ const Twine &Msg);
};
/// Diagnostic information for optimization analysis remarks related to
/// floating-point non-commutativity.
class OptimizationRemarkAnalysisFPCommute : public OptimizationRemarkAnalysis {
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
+ /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
+ /// remark (single-word, camel-case). \p Loc is the debug location and \p
+ /// CodeRegion is the region that the optimization operates on (currently only
+ /// block is supported). The front-end will append its own message related to
+ /// options that address floating-point non-commutativity.
+ OptimizationRemarkAnalysisFPCommute(const char *PassName,
+ StringRef RemarkName,
+ const DiagnosticLocation &Loc,
+ const Value *CodeRegion)
+ : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisFPCommute,
+ PassName, RemarkName, Loc, CodeRegion) {}
+
+ static bool classof(const DiagnosticInfo *DI) {
+ return DI->getKind() == DK_OptimizationRemarkAnalysisFPCommute;
+ }
+
+private:
+ /// This is deprecated now and only used by the function API below.
/// \p PassName is the name of the pass emitting this diagnostic. If
/// this name matches the regular expression given in -Rpass-analysis=, then
/// the diagnostic will be emitted. \p Fn is the function where the diagnostic
- /// is being emitted. \p DLoc is the location information to use in the
+ /// is being emitted. \p Loc is the location information to use in the
/// diagnostic. If line table information is available, the diagnostic will
/// include the source code location. \p Msg is the message to show. The
/// front-end will append its own message related to options that address
@@ -671,37 +791,43 @@ public:
/// message, so this reference must be valid for the whole life time of the
/// diagnostic.
OptimizationRemarkAnalysisFPCommute(const char *PassName, const Function &Fn,
- const DebugLoc &DLoc, const Twine &Msg,
- Optional<uint64_t> Hotness = None)
+ const DiagnosticLocation &Loc,
+ const Twine &Msg)
: OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisFPCommute,
- PassName, Fn, DLoc, Msg, Hotness) {}
+ PassName, Fn, Loc, Msg) {}
- /// \p PassName is the name of the pass emitting this diagnostic. If this name
- /// matches the regular expression given in -Rpass-analysis=, then the
- /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
- /// remark. \p DLoc is the debug location and \p CodeRegion is the region
- /// that the optimization operates on (currently on block is supported). The
- /// front-end will append its own message related to options that address
- /// floating-point non-commutativity.
- OptimizationRemarkAnalysisFPCommute(const char *PassName,
- StringRef RemarkName,
- const DebugLoc &DLoc, Value *CodeRegion)
- : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisFPCommute,
- PassName, RemarkName, DLoc, CodeRegion) {}
-
- static bool classof(const DiagnosticInfo *DI) {
- return DI->getKind() == DK_OptimizationRemarkAnalysisFPCommute;
- }
+ friend void emitOptimizationRemarkAnalysisFPCommute(
+ LLVMContext &Ctx, const char *PassName, const Function &Fn,
+ const DiagnosticLocation &Loc, const Twine &Msg);
};
/// Diagnostic information for optimization analysis remarks related to
/// pointer aliasing.
class OptimizationRemarkAnalysisAliasing : public OptimizationRemarkAnalysis {
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
+ /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
+ /// remark (single-word, camel-case). \p Loc is the debug location and \p
+ /// CodeRegion is the region that the optimization operates on (currently only
+ /// block is supported). The front-end will append its own message related to
+ /// options that address pointer aliasing legality.
+ OptimizationRemarkAnalysisAliasing(const char *PassName, StringRef RemarkName,
+ const DiagnosticLocation &Loc,
+ const Value *CodeRegion)
+ : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisAliasing,
+ PassName, RemarkName, Loc, CodeRegion) {}
+
+ static bool classof(const DiagnosticInfo *DI) {
+ return DI->getKind() == DK_OptimizationRemarkAnalysisAliasing;
+ }
+
+private:
+ /// This is deprecated now and only used by the function API below.
/// \p PassName is the name of the pass emitting this diagnostic. If
/// this name matches the regular expression given in -Rpass-analysis=, then
/// the diagnostic will be emitted. \p Fn is the function where the diagnostic
- /// is being emitted. \p DLoc is the location information to use in the
+ /// is being emitted. \p Loc is the location information to use in the
/// diagnostic. If line table information is available, the diagnostic will
/// include the source code location. \p Msg is the message to show. The
/// front-end will append its own message related to options that address
@@ -709,26 +835,14 @@ public:
/// message, so this reference must be valid for the whole life time of the
/// diagnostic.
OptimizationRemarkAnalysisAliasing(const char *PassName, const Function &Fn,
- const DebugLoc &DLoc, const Twine &Msg,
- Optional<uint64_t> Hotness = None)
+ const DiagnosticLocation &Loc,
+ const Twine &Msg)
: OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisAliasing,
- PassName, Fn, DLoc, Msg, Hotness) {}
+ PassName, Fn, Loc, Msg) {}
- /// \p PassName is the name of the pass emitting this diagnostic. If this name
- /// matches the regular expression given in -Rpass-analysis=, then the
- /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
- /// remark. \p DLoc is the debug location and \p CodeRegion is the region
- /// that the optimization operates on (currently on block is supported). The
- /// front-end will append its own message related to options that address
- /// pointer aliasing legality.
- OptimizationRemarkAnalysisAliasing(const char *PassName, StringRef RemarkName,
- const DebugLoc &DLoc, Value *CodeRegion)
- : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisAliasing,
- PassName, RemarkName, DLoc, CodeRegion) {}
-
- static bool classof(const DiagnosticInfo *DI) {
- return DI->getKind() == DK_OptimizationRemarkAnalysisAliasing;
- }
+ friend void emitOptimizationRemarkAnalysisAliasing(
+ LLVMContext &Ctx, const char *PassName, const Function &Fn,
+ const DiagnosticLocation &Loc, const Twine &Msg);
};
/// Diagnostic information for machine IR parser.
@@ -771,73 +885,97 @@ public:
// Create wrappers for C Binding types (see CBindingWrapping.h).
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DiagnosticInfo, LLVMDiagnosticInfoRef)
-/// Emit an optimization-applied message. \p PassName is the name of the pass
-/// emitting the message. If -Rpass= is given and \p PassName matches the
-/// regular expression in -Rpass, then the remark will be emitted. \p Fn is
-/// the function triggering the remark, \p DLoc is the debug location where
-/// the diagnostic is generated. \p Msg is the message string to use.
+/// \brief Legacy interface to emit an optimization-applied message. Use
+/// (Machine)OptimizationRemarkEmitter instead.
+///
+/// \p PassName is the name of the pass emitting the message. If -Rpass= is
+/// given and \p PassName matches the regular expression in -Rpass, then the
+/// remark will be emitted. \p Fn is the function triggering the remark, \p Loc
+/// is the debug location where the diagnostic is generated. \p Msg is the
+/// message string to use.
void emitOptimizationRemark(LLVMContext &Ctx, const char *PassName,
- const Function &Fn, const DebugLoc &DLoc,
+ const Function &Fn, const DiagnosticLocation &Loc,
const Twine &Msg);
-/// Emit an optimization-missed message. \p PassName is the name of the
-/// pass emitting the message. If -Rpass-missed= is given and \p PassName
-/// matches the regular expression in -Rpass, then the remark will be
-/// emitted. \p Fn is the function triggering the remark, \p DLoc is the
-/// debug location where the diagnostic is generated. \p Msg is the
+/// \brief Legacy interface to emit an optimization-missed message. Use
+/// (Machine)OptimizationRemarkEmitter instead.
+///
+/// \p PassName is the name of the pass emitting the message. If -Rpass-missed=
+/// is given and \p PassName matches the regular expression in -Rpass, then the
+/// remark will be emitted. \p Fn is the function triggering the remark, \p Loc
+/// is the debug location where the diagnostic is generated. \p Msg is the
/// message string to use.
void emitOptimizationRemarkMissed(LLVMContext &Ctx, const char *PassName,
- const Function &Fn, const DebugLoc &DLoc,
+ const Function &Fn,
+ const DiagnosticLocation &Loc,
const Twine &Msg);
-/// Emit an optimization analysis remark message. \p PassName is the name of
-/// the pass emitting the message. If -Rpass-analysis= is given and \p
-/// PassName matches the regular expression in -Rpass, then the remark will be
-/// emitted. \p Fn is the function triggering the remark, \p DLoc is the debug
-/// location where the diagnostic is generated. \p Msg is the message string
-/// to use.
+/// \brief Legacy interface to emit an optimization analysis remark message.
+/// Use (Machine)OptimizationRemarkEmitter instead.
+///
+/// \p PassName is the name of the pass emitting the message. If
+/// -Rpass-analysis= is given and \p PassName matches the regular expression in
+/// -Rpass, then the remark will be emitted. \p Fn is the function triggering
+/// the remark, \p Loc is the debug location where the diagnostic is
+/// generated. \p Msg is the message string to use.
void emitOptimizationRemarkAnalysis(LLVMContext &Ctx, const char *PassName,
- const Function &Fn, const DebugLoc &DLoc,
+ const Function &Fn,
+ const DiagnosticLocation &Loc,
const Twine &Msg);
-/// Emit an optimization analysis remark related to messages about
-/// floating-point non-commutativity. \p PassName is the name of the pass
-/// emitting the message. If -Rpass-analysis= is given and \p PassName matches
-/// the regular expression in -Rpass, then the remark will be emitted. \p Fn is
-/// the function triggering the remark, \p DLoc is the debug location where the
-/// diagnostic is generated. \p Msg is the message string to use.
+/// \brief Legacy interface to emit an optimization analysis remark related to
+/// messages about floating-point non-commutativity. Use
+/// (Machine)OptimizationRemarkEmitter instead.
+///
+/// \p PassName is the name of the pass emitting the message. If
+/// -Rpass-analysis= is given and \p PassName matches the regular expression in
+/// -Rpass, then the remark will be emitted. \p Fn is the function triggering
+/// the remark, \p Loc is the debug location where the diagnostic is
+/// generated. \p Msg is the message string to use.
void emitOptimizationRemarkAnalysisFPCommute(LLVMContext &Ctx,
const char *PassName,
const Function &Fn,
- const DebugLoc &DLoc,
+ const DiagnosticLocation &Loc,
const Twine &Msg);
-/// Emit an optimization analysis remark related to messages about
-/// pointer aliasing. \p PassName is the name of the pass emitting the message.
+/// \brief Legacy interface to emit an optimization analysis remark related to
+/// messages about pointer aliasing. Use (Machine)OptimizationRemarkEmitter
+/// instead.
+///
+/// \p PassName is the name of the pass emitting the message.
/// If -Rpass-analysis= is given and \p PassName matches the regular expression
/// in -Rpass, then the remark will be emitted. \p Fn is the function triggering
-/// the remark, \p DLoc is the debug location where the diagnostic is generated.
+/// the remark, \p Loc is the debug location where the diagnostic is generated.
/// \p Msg is the message string to use.
void emitOptimizationRemarkAnalysisAliasing(LLVMContext &Ctx,
const char *PassName,
const Function &Fn,
- const DebugLoc &DLoc,
+ const DiagnosticLocation &Loc,
const Twine &Msg);
/// Diagnostic information for optimization failures.
-class DiagnosticInfoOptimizationFailure
- : public DiagnosticInfoOptimizationBase {
+class DiagnosticInfoOptimizationFailure : public DiagnosticInfoIROptimization {
public:
- /// \p Fn is the function where the diagnostic is being emitted. \p DLoc is
+ /// \p Fn is the function where the diagnostic is being emitted. \p Loc is
/// the location information to use in the diagnostic. If line table
/// information is available, the diagnostic will include the source code
/// location. \p Msg is the message to show. Note that this class does not
/// copy this message, so this reference must be valid for the whole life time
/// of the diagnostic.
- DiagnosticInfoOptimizationFailure(const Function &Fn, const DebugLoc &DLoc,
+ DiagnosticInfoOptimizationFailure(const Function &Fn,
+ const DiagnosticLocation &Loc,
const Twine &Msg)
- : DiagnosticInfoOptimizationBase(DK_OptimizationFailure, DS_Warning,
- nullptr, Fn, DLoc, Msg) {}
+ : DiagnosticInfoIROptimization(DK_OptimizationFailure, DS_Warning,
+ nullptr, Fn, Loc, Msg) {}
+
+ /// \p PassName is the name of the pass emitting this diagnostic. \p
+ /// RemarkName is a textual identifier for the remark (single-word,
+ /// camel-case). \p Loc is the debug location and \p CodeRegion is the
+ /// region that the optimization operates on (currently basic block is
+ /// supported).
+ DiagnosticInfoOptimizationFailure(const char *PassName, StringRef RemarkName,
+ const DiagnosticLocation &Loc,
+ const Value *CodeRegion);
static bool classof(const DiagnosticInfo *DI) {
return DI->getKind() == DK_OptimizationFailure;
@@ -848,22 +986,22 @@ public:
};
/// Diagnostic information for unsupported feature in backend.
-class DiagnosticInfoUnsupported
- : public DiagnosticInfoWithDebugLocBase {
+class DiagnosticInfoUnsupported : public DiagnosticInfoWithLocationBase {
private:
Twine Msg;
public:
- /// \p Fn is the function where the diagnostic is being emitted. \p DLoc is
+ /// \p Fn is the function where the diagnostic is being emitted. \p Loc is
/// the location information to use in the diagnostic. If line table
/// information is available, the diagnostic will include the source code
/// location. \p Msg is the message to show. Note that this class does not
/// copy this message, so this reference must be valid for the whole life time
/// of the diagnostic.
- DiagnosticInfoUnsupported(const Function &Fn, const Twine &Msg,
- DebugLoc DLoc = DebugLoc(),
- DiagnosticSeverity Severity = DS_Error)
- : DiagnosticInfoWithDebugLocBase(DK_Unsupported, Severity, Fn, DLoc),
+ DiagnosticInfoUnsupported(
+ const Function &Fn, const Twine &Msg,
+ const DiagnosticLocation &Loc = DiagnosticLocation(),
+ DiagnosticSeverity Severity = DS_Error)
+ : DiagnosticInfoWithLocationBase(DK_Unsupported, Severity, Fn, Loc),
Msg(Msg) {}
static bool classof(const DiagnosticInfo *DI) {
@@ -875,18 +1013,6 @@ public:
void print(DiagnosticPrinter &DP) const override;
};
-/// Emit a warning when loop vectorization is specified but fails. \p Fn is the
-/// function triggering the warning, \p DLoc is the debug location where the
-/// diagnostic is generated. \p Msg is the message string to use.
-void emitLoopVectorizeWarning(LLVMContext &Ctx, const Function &Fn,
- const DebugLoc &DLoc, const Twine &Msg);
-
-/// Emit a warning when loop interleaving is specified but fails. \p Fn is the
-/// function triggering the warning, \p DLoc is the debug location where the
-/// diagnostic is generated. \p Msg is the message string to use.
-void emitLoopInterleaveWarning(LLVMContext &Ctx, const Function &Fn,
- const DebugLoc &DLoc, const Twine &Msg);
-
} // end namespace llvm
#endif // LLVM_IR_DIAGNOSTICINFO_H
diff --git a/contrib/llvm/include/llvm/IR/Dominators.h b/contrib/llvm/include/llvm/IR/Dominators.h
index 7c733ba..5b21a2c 100644
--- a/contrib/llvm/include/llvm/IR/Dominators.h
+++ b/contrib/llvm/include/llvm/IR/Dominators.h
@@ -16,51 +16,88 @@
#define LLVM_IR_DOMINATORS_H
#include "llvm/ADT/DenseMapInfo.h"
+#include "llvm/ADT/DepthFirstIterator.h"
#include "llvm/ADT/GraphTraits.h"
-#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/Hashing.h"
+#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/CFG.h"
#include "llvm/IR/PassManager.h"
#include "llvm/Pass.h"
#include "llvm/Support/GenericDomTree.h"
+#include <utility>
namespace llvm {
class Function;
-class BasicBlock;
+class Instruction;
+class Module;
class raw_ostream;
extern template class DomTreeNodeBase<BasicBlock>;
-extern template class DominatorTreeBase<BasicBlock>;
+extern template class DominatorTreeBase<BasicBlock, false>; // DomTree
+extern template class DominatorTreeBase<BasicBlock, true>; // PostDomTree
-extern template void Calculate<Function, BasicBlock *>(
- DominatorTreeBaseByGraphTraits<GraphTraits<BasicBlock *>> &DT, Function &F);
-extern template void Calculate<Function, Inverse<BasicBlock *>>(
- DominatorTreeBaseByGraphTraits<GraphTraits<Inverse<BasicBlock *>>> &DT,
- Function &F);
+namespace DomTreeBuilder {
+using BBDomTree = DomTreeBase<BasicBlock>;
+using BBPostDomTree = PostDomTreeBase<BasicBlock>;
-typedef DomTreeNodeBase<BasicBlock> DomTreeNode;
+extern template void Calculate<BBDomTree, Function>(BBDomTree &DT, Function &F);
+extern template void Calculate<BBPostDomTree, Function>(BBPostDomTree &DT,
+ Function &F);
+
+extern template void InsertEdge<BBDomTree>(BBDomTree &DT, BasicBlock *From,
+ BasicBlock *To);
+extern template void InsertEdge<BBPostDomTree>(BBPostDomTree &DT,
+ BasicBlock *From,
+ BasicBlock *To);
+
+extern template void DeleteEdge<BBDomTree>(BBDomTree &DT, BasicBlock *From,
+ BasicBlock *To);
+extern template void DeleteEdge<BBPostDomTree>(BBPostDomTree &DT,
+ BasicBlock *From,
+ BasicBlock *To);
+
+extern template bool Verify<BBDomTree>(const BBDomTree &DT);
+extern template bool Verify<BBPostDomTree>(const BBPostDomTree &DT);
+} // namespace DomTreeBuilder
+
+using DomTreeNode = DomTreeNodeBase<BasicBlock>;
class BasicBlockEdge {
const BasicBlock *Start;
const BasicBlock *End;
+
public:
BasicBlockEdge(const BasicBlock *Start_, const BasicBlock *End_) :
- Start(Start_), End(End_) { }
+ Start(Start_), End(End_) {}
+
+ BasicBlockEdge(const std::pair<BasicBlock *, BasicBlock *> &Pair)
+ : Start(Pair.first), End(Pair.second) {}
+
+ BasicBlockEdge(const std::pair<const BasicBlock *, const BasicBlock *> &Pair)
+ : Start(Pair.first), End(Pair.second) {}
+
const BasicBlock *getStart() const {
return Start;
}
+
const BasicBlock *getEnd() const {
return End;
}
+
+ /// Check if this is the only edge between Start and End.
bool isSingleEdge() const;
};
template <> struct DenseMapInfo<BasicBlockEdge> {
+ using BBInfo = DenseMapInfo<const BasicBlock *>;
+
static unsigned getHashValue(const BasicBlockEdge *V);
- typedef DenseMapInfo<const BasicBlock *> BBInfo;
+
static inline BasicBlockEdge getEmptyKey() {
return BasicBlockEdge(BBInfo::getEmptyKey(), BBInfo::getEmptyKey());
}
+
static inline BasicBlockEdge getTombstoneKey() {
return BasicBlockEdge(BBInfo::getTombstoneKey(), BBInfo::getTombstoneKey());
}
@@ -69,6 +106,7 @@ template <> struct DenseMapInfo<BasicBlockEdge> {
return hash_combine(BBInfo::getHashValue(Edge.getStart()),
BBInfo::getHashValue(Edge.getEnd()));
}
+
static bool isEqual(const BasicBlockEdge &LHS, const BasicBlockEdge &RHS) {
return BBInfo::isEqual(LHS.getStart(), RHS.getStart()) &&
BBInfo::isEqual(LHS.getEnd(), RHS.getEnd());
@@ -93,28 +131,24 @@ template <> struct DenseMapInfo<BasicBlockEdge> {
/// the dominator tree is initially constructed may still exist in the tree,
/// even if the tree is properly updated. Calling code should not rely on the
/// preceding statements; this is stated only to assist human understanding.
-class DominatorTree : public DominatorTreeBase<BasicBlock> {
-public:
- typedef DominatorTreeBase<BasicBlock> Base;
+class DominatorTree : public DominatorTreeBase<BasicBlock, false> {
+ public:
+ using Base = DominatorTreeBase<BasicBlock, false>;
- DominatorTree() : DominatorTreeBase<BasicBlock>(false) {}
- explicit DominatorTree(Function &F) : DominatorTreeBase<BasicBlock>(false) {
- recalculate(F);
- }
+ DominatorTree() = default;
+ explicit DominatorTree(Function &F) { recalculate(F); }
+
+ /// Handle invalidation explicitly.
+ bool invalidate(Function &F, const PreservedAnalyses &PA,
+ FunctionAnalysisManager::Invalidator &);
/// \brief Returns *false* if the other dominator tree matches this dominator
/// tree.
inline bool compare(const DominatorTree &Other) const {
const DomTreeNode *R = getRootNode();
const DomTreeNode *OtherR = Other.getRootNode();
-
- if (!R || !OtherR || R->getBlock() != OtherR->getBlock())
- return true;
-
- if (Base::compare(Other))
- return true;
-
- return false;
+ return !R || !OtherR || R->getBlock() != OtherR->getBlock() ||
+ Base::compare(Other);
}
// Ensure base-class overloads are visible.
@@ -127,6 +161,11 @@ public:
bool dominates(const Instruction *Def, const Use &U) const;
bool dominates(const Instruction *Def, const Instruction *User) const;
bool dominates(const Instruction *Def, const BasicBlock *BB) const;
+
+ /// Return true if an edge dominates a use.
+ ///
+ /// If BBE is not a unique edge between start and end of the edge, it can
+ /// never dominate the use.
bool dominates(const BasicBlockEdge &BBE, const Use &U) const;
bool dominates(const BasicBlockEdge &BBE, const BasicBlock *BB) const;
@@ -141,6 +180,10 @@ public:
/// This should only be used for debugging as it aborts the program if the
/// verification fails.
void verifyDomTree() const;
+
+ // Pop up a GraphViz/gv window with the Dominator Tree rendered using `dot`.
+ void viewGraph(const Twine &Name, const Twine &Title);
+ void viewGraph();
};
//===-------------------------------------
@@ -148,9 +191,9 @@ public:
// iterable by generic graph iterators.
template <class Node, class ChildIterator> struct DomTreeGraphTraitsBase {
- typedef Node *NodeRef;
- typedef ChildIterator ChildIteratorType;
- typedef df_iterator<Node *, df_iterator_default_set<Node*>> nodes_iterator;
+ using NodeRef = Node *;
+ using ChildIteratorType = ChildIterator;
+ using nodes_iterator = df_iterator<Node *, df_iterator_default_set<Node*>>;
static NodeRef getEntryNode(NodeRef N) { return N; }
static ChildIteratorType child_begin(NodeRef N) { return N->begin(); }
@@ -192,7 +235,7 @@ class DominatorTreeAnalysis : public AnalysisInfoMixin<DominatorTreeAnalysis> {
public:
/// \brief Provide the result typedef for this analysis pass.
- typedef DominatorTree Result;
+ using Result = DominatorTree;
/// \brief Run the analysis pass over a function and produce a dominator tree.
DominatorTree run(Function &F, FunctionAnalysisManager &);
@@ -205,6 +248,7 @@ class DominatorTreePrinterPass
public:
explicit DominatorTreePrinterPass(raw_ostream &OS);
+
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
};
@@ -240,6 +284,6 @@ public:
void print(raw_ostream &OS, const Module *M = nullptr) const override;
};
-} // End llvm namespace
+} // end namespace llvm
-#endif
+#endif // LLVM_IR_DOMINATORS_H
diff --git a/contrib/llvm/include/llvm/IR/Function.h b/contrib/llvm/include/llvm/IR/Function.h
index 1854d41..75fccc1 100644
--- a/contrib/llvm/include/llvm/IR/Function.h
+++ b/contrib/llvm/include/llvm/IR/Function.h
@@ -1,4 +1,4 @@
-//===-- llvm/Function.h - Class to represent a single function --*- C++ -*-===//
+//===- llvm/Function.h - Class to represent a single function ---*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -18,18 +18,23 @@
#ifndef LLVM_IR_FUNCTION_H
#define LLVM_IR_FUNCTION_H
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Twine.h"
#include "llvm/ADT/ilist_node.h"
#include "llvm/ADT/iterator_range.h"
-#include "llvm/ADT/StringRef.h"
#include "llvm/IR/Argument.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/CallingConv.h"
+#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/GlobalObject.h"
+#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/OperandTraits.h"
#include "llvm/IR/SymbolTableListTraits.h"
#include "llvm/IR/Value.h"
+#include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h"
#include <cassert>
#include <cstddef>
@@ -39,31 +44,35 @@
namespace llvm {
-template <typename T> class Optional;
class AssemblyAnnotationWriter;
-class FunctionType;
-class LLVMContext;
+class Constant;
class DISubprogram;
+class LLVMContext;
+class Module;
+template <typename T> class Optional;
+class raw_ostream;
+class Type;
+class User;
class Function : public GlobalObject, public ilist_node<Function> {
public:
- typedef SymbolTableList<Argument> ArgumentListType;
- typedef SymbolTableList<BasicBlock> BasicBlockListType;
+ using BasicBlockListType = SymbolTableList<BasicBlock>;
// BasicBlock iterators...
- typedef BasicBlockListType::iterator iterator;
- typedef BasicBlockListType::const_iterator const_iterator;
+ using iterator = BasicBlockListType::iterator;
+ using const_iterator = BasicBlockListType::const_iterator;
- typedef ArgumentListType::iterator arg_iterator;
- typedef ArgumentListType::const_iterator const_arg_iterator;
+ using arg_iterator = Argument *;
+ using const_arg_iterator = const Argument *;
private:
// Important things that make up a function!
- BasicBlockListType BasicBlocks; ///< The basic blocks
- mutable ArgumentListType ArgumentList; ///< The formal arguments
+ BasicBlockListType BasicBlocks; ///< The basic blocks
+ mutable Argument *Arguments = nullptr; ///< The formal arguments
+ size_t NumArgs;
std::unique_ptr<ValueSymbolTable>
SymTab; ///< Symbol table of args/instructions
- AttributeSet AttributeSets; ///< Parameter attributes
+ AttributeList AttributeSets; ///< Parameter attributes
/*
* Value::SubclassData
@@ -102,6 +111,8 @@ private:
void BuildLazyArguments() const;
+ void clearArguments();
+
/// Function ctor - If the (optional) Module argument is specified, the
/// function is automatically inserted into the end of the function list for
/// the module.
@@ -112,7 +123,7 @@ private:
public:
Function(const Function&) = delete;
void operator=(const Function&) = delete;
- ~Function() override;
+ ~Function();
static Function *Create(FunctionType *Ty, LinkageTypes Linkage,
const Twine &N = "", Module *M = nullptr) {
@@ -121,10 +132,14 @@ public:
// Provide fast operand accessors.
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
- /// Returns the type of the ret val.
- Type *getReturnType() const;
+
/// Returns the FunctionType for me.
- FunctionType *getFunctionType() const;
+ FunctionType *getFunctionType() const {
+ return cast<FunctionType>(getValueType());
+ }
+
+ /// Returns the type of the ret val.
+ Type *getReturnType() const { return getFunctionType()->getReturnType(); }
/// getContext - Return a reference to the LLVMContext associated with this
/// function.
@@ -132,10 +147,16 @@ public:
/// isVarArg - Return true if this function takes a variable number of
/// arguments.
- bool isVarArg() const;
+ bool isVarArg() const { return getFunctionType()->isVarArg(); }
- bool isMaterializable() const;
- void setIsMaterializable(bool V);
+ bool isMaterializable() const {
+ return getGlobalObjectSubClassData() & (1 << IsMaterializableBit);
+ }
+ void setIsMaterializable(bool V) {
+ unsigned Mask = 1 << IsMaterializableBit;
+ setGlobalObjectSubClassData((~Mask & getGlobalObjectSubClassData()) |
+ (V ? Mask : 0u));
+ }
/// getIntrinsicID - This method returns the ID number of the specified
/// function, or Intrinsic::not_intrinsic if the function is not an
@@ -173,42 +194,45 @@ public:
}
/// @brief Return the attribute list for this Function.
- AttributeSet getAttributes() const { return AttributeSets; }
+ AttributeList getAttributes() const { return AttributeSets; }
/// @brief Set the attribute list for this Function.
- void setAttributes(AttributeSet Attrs) { AttributeSets = Attrs; }
+ void setAttributes(AttributeList Attrs) { AttributeSets = Attrs; }
/// @brief Add function attributes to this function.
void addFnAttr(Attribute::AttrKind Kind) {
- addAttribute(AttributeSet::FunctionIndex, Kind);
+ addAttribute(AttributeList::FunctionIndex, Kind);
}
/// @brief Add function attributes to this function.
void addFnAttr(StringRef Kind, StringRef Val = StringRef()) {
- addAttribute(AttributeSet::FunctionIndex,
+ addAttribute(AttributeList::FunctionIndex,
Attribute::get(getContext(), Kind, Val));
}
void addFnAttr(Attribute Attr) {
- addAttribute(AttributeSet::FunctionIndex, Attr);
+ addAttribute(AttributeList::FunctionIndex, Attr);
}
/// @brief Remove function attributes from this function.
void removeFnAttr(Attribute::AttrKind Kind) {
- removeAttribute(AttributeSet::FunctionIndex, Kind);
+ removeAttribute(AttributeList::FunctionIndex, Kind);
}
/// @brief Remove function attribute from this function.
void removeFnAttr(StringRef Kind) {
- setAttributes(AttributeSets.removeAttribute(
- getContext(), AttributeSet::FunctionIndex, Kind));
+ setAttributes(getAttributes().removeAttribute(
+ getContext(), AttributeList::FunctionIndex, Kind));
}
/// \brief Set the entry count for this function.
///
/// Entry count is the number of times this function was executed based on
- /// pgo data.
- void setEntryCount(uint64_t Count);
+ /// pgo data. \p Imports points to a set of GUIDs that needs to be imported
+ /// by the function for sample PGO, to enable the same inlines as the
+ /// profiled optimized binary.
+ void setEntryCount(uint64_t Count,
+ const DenseSet<GlobalValue::GUID> *Imports = nullptr);
/// \brief Get the entry count for this function.
///
@@ -216,6 +240,10 @@ public:
/// pgo data.
Optional<uint64_t> getEntryCount() const;
+ /// Returns the set of GUIDs that needs to be imported to the function for
+ /// sample PGO, to enable the same inlines as the profiled optimized binary.
+ DenseSet<GlobalValue::GUID> getImportGUIDs() const;
+
/// Set the section prefix for this function.
void setSectionPrefix(StringRef Prefix);
@@ -232,17 +260,17 @@ public:
/// @brief Return the attribute for the given attribute kind.
Attribute getFnAttribute(Attribute::AttrKind Kind) const {
- return getAttribute(AttributeSet::FunctionIndex, Kind);
+ return getAttribute(AttributeList::FunctionIndex, Kind);
}
Attribute getFnAttribute(StringRef Kind) const {
- return getAttribute(AttributeSet::FunctionIndex, Kind);
+ return getAttribute(AttributeList::FunctionIndex, Kind);
}
/// \brief Return the stack alignment for the function.
unsigned getFnStackAlignment() const {
if (!hasFnAttribute(Attribute::StackAlignment))
return 0;
- return AttributeSets.getStackAlignment(AttributeSet::FunctionIndex);
+ return AttributeSets.getStackAlignment(AttributeList::FunctionIndex);
}
/// hasGC/getGC/setGC/clearGC - The name of the garbage collection algorithm
@@ -261,7 +289,16 @@ public:
void addAttribute(unsigned i, Attribute Attr);
/// @brief adds the attributes to the list of attributes.
- void addAttributes(unsigned i, AttributeSet Attrs);
+ void addAttributes(unsigned i, const AttrBuilder &Attrs);
+
+ /// @brief adds the attribute to the list of attributes for the given arg.
+ void addParamAttr(unsigned ArgNo, Attribute::AttrKind Kind);
+
+ /// @brief adds the attribute to the list of attributes for the given arg.
+ void addParamAttr(unsigned ArgNo, Attribute Attr);
+
+ /// @brief adds the attributes to the list of attributes for the given arg.
+ void addParamAttrs(unsigned ArgNo, const AttrBuilder &Attrs);
/// @brief removes the attribute from the list of attributes.
void removeAttribute(unsigned i, Attribute::AttrKind Kind);
@@ -270,13 +307,27 @@ public:
void removeAttribute(unsigned i, StringRef Kind);
/// @brief removes the attributes from the list of attributes.
- void removeAttributes(unsigned i, AttributeSet Attrs);
+ void removeAttributes(unsigned i, const AttrBuilder &Attrs);
+
+ /// @brief removes the attribute from the list of attributes.
+ void removeParamAttr(unsigned ArgNo, Attribute::AttrKind Kind);
+
+ /// @brief removes the attribute from the list of attributes.
+ void removeParamAttr(unsigned ArgNo, StringRef Kind);
+
+ /// @brief removes the attribute from the list of attributes.
+ void removeParamAttrs(unsigned ArgNo, const AttrBuilder &Attrs);
/// @brief check if an attributes is in the list of attributes.
bool hasAttribute(unsigned i, Attribute::AttrKind Kind) const {
return getAttributes().hasAttribute(i, Kind);
}
+ /// @brief check if an attributes is in the list of attributes.
+ bool hasParamAttribute(unsigned ArgNo, Attribute::AttrKind Kind) const {
+ return getAttributes().hasParamAttribute(ArgNo, Kind);
+ }
+
Attribute getAttribute(unsigned i, Attribute::AttrKind Kind) const {
return AttributeSets.getAttribute(i, Kind);
}
@@ -288,27 +339,50 @@ public:
/// @brief adds the dereferenceable attribute to the list of attributes.
void addDereferenceableAttr(unsigned i, uint64_t Bytes);
+ /// @brief adds the dereferenceable attribute to the list of attributes for
+ /// the given arg.
+ void addDereferenceableParamAttr(unsigned ArgNo, uint64_t Bytes);
+
/// @brief adds the dereferenceable_or_null attribute to the list of
/// attributes.
void addDereferenceableOrNullAttr(unsigned i, uint64_t Bytes);
+ /// @brief adds the dereferenceable_or_null attribute to the list of
+ /// attributes for the given arg.
+ void addDereferenceableOrNullParamAttr(unsigned ArgNo, uint64_t Bytes);
+
/// @brief Extract the alignment for a call or parameter (0=unknown).
- unsigned getParamAlignment(unsigned i) const {
- return AttributeSets.getParamAlignment(i);
+ unsigned getParamAlignment(unsigned ArgNo) const {
+ return AttributeSets.getParamAlignment(ArgNo);
}
/// @brief Extract the number of dereferenceable bytes for a call or
/// parameter (0=unknown).
+ /// @param i AttributeList index, referring to a return value or argument.
uint64_t getDereferenceableBytes(unsigned i) const {
return AttributeSets.getDereferenceableBytes(i);
}
+ /// @brief Extract the number of dereferenceable bytes for a parameter.
+ /// @param ArgNo Index of an argument, with 0 being the first function arg.
+ uint64_t getParamDereferenceableBytes(unsigned ArgNo) const {
+ return AttributeSets.getParamDereferenceableBytes(ArgNo);
+ }
+
/// @brief Extract the number of dereferenceable_or_null bytes for a call or
/// parameter (0=unknown).
+ /// @param i AttributeList index, referring to a return value or argument.
uint64_t getDereferenceableOrNullBytes(unsigned i) const {
return AttributeSets.getDereferenceableOrNullBytes(i);
}
+ /// @brief Extract the number of dereferenceable_or_null bytes for a
+ /// parameter.
+ /// @param ArgNo AttributeList ArgNo, referring to an argument.
+ uint64_t getParamDereferenceableOrNullBytes(unsigned ArgNo) const {
+ return AttributeSets.getParamDereferenceableOrNullBytes(ArgNo);
+ }
+
/// @brief Determine if the function does not access memory.
bool doesNotAccessMemory() const {
return hasFnAttribute(Attribute::ReadNone);
@@ -393,6 +467,14 @@ public:
removeFnAttr(Attribute::Convergent);
}
+ /// @brief Determine if the call has sideeffects.
+ bool isSpeculatable() const {
+ return hasFnAttribute(Attribute::Speculatable);
+ }
+ void setSpeculatable() {
+ addFnAttr(Attribute::Speculatable);
+ }
+
/// Determine if the function is known not to recurse, directly or
/// indirectly.
bool doesNotRecurse() const {
@@ -417,44 +499,20 @@ public:
}
/// @brief Determine if the function returns a structure through first
- /// pointer argument.
+ /// or second pointer argument.
bool hasStructRetAttr() const {
- return AttributeSets.hasAttribute(1, Attribute::StructRet) ||
- AttributeSets.hasAttribute(2, Attribute::StructRet);
+ return AttributeSets.hasParamAttribute(0, Attribute::StructRet) ||
+ AttributeSets.hasParamAttribute(1, Attribute::StructRet);
}
/// @brief Determine if the parameter or return value is marked with NoAlias
/// attribute.
- /// @param n The parameter to check. 1 is the first parameter, 0 is the return
- bool doesNotAlias(unsigned n) const {
- return AttributeSets.hasAttribute(n, Attribute::NoAlias);
+ bool returnDoesNotAlias() const {
+ return AttributeSets.hasAttribute(AttributeList::ReturnIndex,
+ Attribute::NoAlias);
}
- void setDoesNotAlias(unsigned n) {
- addAttribute(n, Attribute::NoAlias);
- }
-
- /// @brief Determine if the parameter can be captured.
- /// @param n The parameter to check. 1 is the first parameter, 0 is the return
- bool doesNotCapture(unsigned n) const {
- return AttributeSets.hasAttribute(n, Attribute::NoCapture);
- }
- void setDoesNotCapture(unsigned n) {
- addAttribute(n, Attribute::NoCapture);
- }
-
- bool doesNotAccessMemory(unsigned n) const {
- return AttributeSets.hasAttribute(n, Attribute::ReadNone);
- }
- void setDoesNotAccessMemory(unsigned n) {
- addAttribute(n, Attribute::ReadNone);
- }
-
- bool onlyReadsMemory(unsigned n) const {
- return doesNotAccessMemory(n) ||
- AttributeSets.hasAttribute(n, Attribute::ReadOnly);
- }
- void setOnlyReadsMemory(unsigned n) {
- addAttribute(n, Attribute::ReadOnly);
+ void setReturnDoesNotAlias() {
+ addAttribute(AttributeList::ReturnIndex, Attribute::NoAlias);
}
/// Optimize this function for minimum size (-Oz).
@@ -467,7 +525,7 @@ public:
/// copyAttributesFrom - copy all additional attributes (those not needed to
/// create a Function) from the Function Src to this one.
- void copyAttributesFrom(const GlobalValue *Src) override;
+ void copyAttributesFrom(const Function *Src);
/// deleteBody - This method deletes the body of the function, and converts
/// the linkage to external.
@@ -480,12 +538,12 @@ public:
/// removeFromParent - This method unlinks 'this' from the containing module,
/// but does not delete it.
///
- void removeFromParent() override;
+ void removeFromParent();
/// eraseFromParent - This method unlinks 'this' from the containing module
/// and deletes it.
///
- void eraseFromParent() override;
+ void eraseFromParent();
/// Steal arguments from another function.
///
@@ -496,19 +554,6 @@ public:
/// Get the underlying elements of the Function... the basic block list is
/// empty for external functions.
///
- const ArgumentListType &getArgumentList() const {
- CheckLazyArguments();
- return ArgumentList;
- }
- ArgumentListType &getArgumentList() {
- CheckLazyArguments();
- return ArgumentList;
- }
-
- static ArgumentListType Function::*getSublistAccess(Argument*) {
- return &Function::ArgumentList;
- }
-
const BasicBlockListType &getBasicBlockList() const { return BasicBlocks; }
BasicBlockListType &getBasicBlockList() { return BasicBlocks; }
@@ -549,20 +594,20 @@ public:
arg_iterator arg_begin() {
CheckLazyArguments();
- return ArgumentList.begin();
+ return Arguments;
}
const_arg_iterator arg_begin() const {
CheckLazyArguments();
- return ArgumentList.begin();
+ return Arguments;
}
arg_iterator arg_end() {
CheckLazyArguments();
- return ArgumentList.end();
+ return Arguments + NumArgs;
}
const_arg_iterator arg_end() const {
CheckLazyArguments();
- return ArgumentList.end();
+ return Arguments + NumArgs;
}
iterator_range<arg_iterator> args() {
@@ -574,8 +619,8 @@ public:
/// @}
- size_t arg_size() const;
- bool arg_empty() const;
+ size_t arg_size() const { return NumArgs; }
+ bool arg_empty() const { return arg_size() == 0; }
/// \brief Check whether this function has a personality function.
bool hasPersonalityFn() const {
@@ -626,7 +671,7 @@ public:
void viewCFGOnly() const;
/// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return V->getValueID() == Value::FunctionVal;
}
@@ -671,6 +716,9 @@ public:
/// to \a DISubprogram.
DISubprogram *getSubprogram() const;
+ /// Returns true if we should emit debug info for profiling.
+ bool isDebugInfoForProfiling() const;
+
private:
void allocHungoffUselist();
template<int Idx> void setHungoffOperand(Constant *C);
diff --git a/contrib/llvm/include/llvm/IR/GetElementPtrTypeIterator.h b/contrib/llvm/include/llvm/IR/GetElementPtrTypeIterator.h
index 490bff2..3c143ea 100644
--- a/contrib/llvm/include/llvm/IR/GetElementPtrTypeIterator.h
+++ b/contrib/llvm/include/llvm/IR/GetElementPtrTypeIterator.h
@@ -21,7 +21,9 @@
#include "llvm/IR/Operator.h"
#include "llvm/IR/User.h"
#include "llvm/Support/Casting.h"
+#include <cassert>
#include <cstddef>
+#include <cstdint>
#include <iterator>
namespace llvm {
@@ -29,13 +31,13 @@ namespace llvm {
template<typename ItTy = User::const_op_iterator>
class generic_gep_type_iterator
: public std::iterator<std::forward_iterator_tag, Type *, ptrdiff_t> {
- typedef std::iterator<std::forward_iterator_tag,
- Type *, ptrdiff_t> super;
+ using super = std::iterator<std::forward_iterator_tag, Type *, ptrdiff_t>;
ItTy OpIt;
PointerUnion<StructType *, Type *> CurTy;
enum : uint64_t { Unbounded = -1ull };
uint64_t NumElements = Unbounded;
+
generic_gep_type_iterator() = default;
public:
@@ -121,7 +123,7 @@ namespace llvm {
}
};
- typedef generic_gep_type_iterator<> gep_type_iterator;
+ using gep_type_iterator = generic_gep_type_iterator<>;
inline gep_type_iterator gep_type_begin(const User *GEP) {
auto *GEPOp = cast<GEPOperator>(GEP);
diff --git a/contrib/llvm/include/llvm/IR/GlobalAlias.h b/contrib/llvm/include/llvm/IR/GlobalAlias.h
index 37a291d..450583b 100644
--- a/contrib/llvm/include/llvm/IR/GlobalAlias.h
+++ b/contrib/llvm/include/llvm/IR/GlobalAlias.h
@@ -59,15 +59,19 @@ public:
// Linkage, Type, Parent and AddressSpace taken from the Aliasee.
static GlobalAlias *create(const Twine &Name, GlobalValue *Aliasee);
+ void copyAttributesFrom(const GlobalValue *Src) {
+ GlobalValue::copyAttributesFrom(Src);
+ }
+
/// removeFromParent - This method unlinks 'this' from the containing module,
/// but does not delete it.
///
- void removeFromParent() override;
+ void removeFromParent();
/// eraseFromParent - This method unlinks 'this' from the containing module
/// and deletes it.
///
- void eraseFromParent() override;
+ void eraseFromParent();
/// These methods retrieve and set alias target.
void setAliasee(Constant *Aliasee);
@@ -84,7 +88,7 @@ public:
}
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return V->getValueID() == Value::GlobalAliasVal;
}
};
diff --git a/contrib/llvm/include/llvm/IR/GlobalIFunc.h b/contrib/llvm/include/llvm/IR/GlobalIFunc.h
index bfaa996..ef51315 100644
--- a/contrib/llvm/include/llvm/IR/GlobalIFunc.h
+++ b/contrib/llvm/include/llvm/IR/GlobalIFunc.h
@@ -47,12 +47,16 @@ public:
LinkageTypes Linkage, const Twine &Name,
Constant *Resolver, Module *Parent);
+ void copyAttributesFrom(const GlobalIFunc *Src) {
+ GlobalValue::copyAttributesFrom(Src);
+ }
+
/// This method unlinks 'this' from the containing module, but does not
/// delete it.
- void removeFromParent() final;
+ void removeFromParent();
/// This method unlinks 'this' from the containing module and deletes it.
- void eraseFromParent() final;
+ void eraseFromParent();
/// These methods retrieve and set ifunc resolver function.
void setResolver(Constant *Resolver) {
@@ -66,7 +70,7 @@ public:
}
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return V->getValueID() == Value::GlobalIFuncVal;
}
};
diff --git a/contrib/llvm/include/llvm/IR/GlobalIndirectSymbol.h b/contrib/llvm/include/llvm/IR/GlobalIndirectSymbol.h
index 671309e..22c0068 100644
--- a/contrib/llvm/include/llvm/IR/GlobalIndirectSymbol.h
+++ b/contrib/llvm/include/llvm/IR/GlobalIndirectSymbol.h
@@ -48,30 +48,34 @@ public:
setOperand(0, Symbol);
}
const Constant *getIndirectSymbol() const {
- return const_cast<GlobalIndirectSymbol *>(this)->getIndirectSymbol();
+ return getOperand(0);
}
Constant *getIndirectSymbol() {
- return getOperand(0);
+ return const_cast<Constant *>(
+ static_cast<const GlobalIndirectSymbol *>(this)->getIndirectSymbol());
}
const GlobalObject *getBaseObject() const {
- return const_cast<GlobalIndirectSymbol *>(this)->getBaseObject();
+ return dyn_cast<GlobalObject>(getIndirectSymbol()->stripInBoundsOffsets());
}
GlobalObject *getBaseObject() {
- return dyn_cast<GlobalObject>(getIndirectSymbol()->stripInBoundsOffsets());
+ return const_cast<GlobalObject *>(
+ static_cast<const GlobalIndirectSymbol *>(this)->getBaseObject());
}
const GlobalObject *getBaseObject(const DataLayout &DL, APInt &Offset) const {
- return const_cast<GlobalIndirectSymbol *>(this)->getBaseObject(DL, Offset);
- }
- GlobalObject *getBaseObject(const DataLayout &DL, APInt &Offset) {
return dyn_cast<GlobalObject>(
getIndirectSymbol()->stripAndAccumulateInBoundsConstantOffsets(DL,
Offset));
}
+ GlobalObject *getBaseObject(const DataLayout &DL, APInt &Offset) {
+ return const_cast<GlobalObject *>(
+ static_cast<const GlobalIndirectSymbol *>(this)
+ ->getBaseObject(DL, Offset));
+ }
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return V->getValueID() == Value::GlobalAliasVal ||
V->getValueID() == Value::GlobalIFuncVal;
}
diff --git a/contrib/llvm/include/llvm/IR/GlobalObject.h b/contrib/llvm/include/llvm/IR/GlobalObject.h
index 1057f56..278b193 100644
--- a/contrib/llvm/include/llvm/IR/GlobalObject.h
+++ b/contrib/llvm/include/llvm/IR/GlobalObject.h
@@ -63,8 +63,17 @@ public:
}
void setAlignment(unsigned Align);
- unsigned getGlobalObjectSubClassData() const;
- void setGlobalObjectSubClassData(unsigned Val);
+ unsigned getGlobalObjectSubClassData() const {
+ unsigned ValueData = getGlobalValueSubClassData();
+ return ValueData >> GlobalObjectBits;
+ }
+
+ void setGlobalObjectSubClassData(unsigned Val) {
+ unsigned OldData = getGlobalValueSubClassData();
+ setGlobalValueSubClassData((OldData & GlobalObjectMask) |
+ (Val << GlobalObjectBits));
+ assert(getGlobalObjectSubClassData() == Val && "representation error");
+ }
/// Check if this global has a custom object file section.
///
@@ -141,10 +150,12 @@ public:
void addTypeMetadata(unsigned Offset, Metadata *TypeID);
- void copyAttributesFrom(const GlobalValue *Src) override;
+protected:
+ void copyAttributesFrom(const GlobalObject *Src);
+public:
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return V->getValueID() == Value::FunctionVal ||
V->getValueID() == Value::GlobalVariableVal;
}
diff --git a/contrib/llvm/include/llvm/IR/GlobalValue.h b/contrib/llvm/include/llvm/IR/GlobalValue.h
index c6398aa..d65d43c 100644
--- a/contrib/llvm/include/llvm/IR/GlobalValue.h
+++ b/contrib/llvm/include/llvm/IR/GlobalValue.h
@@ -23,9 +23,9 @@
#include "llvm/IR/Constant.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Value.h"
-#include "llvm/Support/MD5.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/MD5.h"
#include <cassert>
#include <cstdint>
#include <string>
@@ -161,6 +161,10 @@ protected:
Parent = parent;
}
+ ~GlobalValue() {
+ removeDeadConstantUsers(); // remove any dead constants using this.
+ }
+
public:
enum ThreadLocalMode {
NotThreadLocal = 0,
@@ -172,10 +176,6 @@ public:
GlobalValue(const GlobalValue &) = delete;
- ~GlobalValue() override {
- removeDeadConstantUsers(); // remove any dead constants using this.
- }
-
unsigned getAlignment() const;
enum class UnnamedAddr {
@@ -211,9 +211,10 @@ public:
}
bool hasComdat() const { return getComdat() != nullptr; }
- Comdat *getComdat();
- const Comdat *getComdat() const {
- return const_cast<GlobalValue *>(this)->getComdat();
+ const Comdat *getComdat() const;
+ Comdat *getComdat() {
+ return const_cast<Comdat *>(
+ static_cast<const GlobalValue *>(this)->getComdat());
}
VisibilityTypes getVisibility() const { return VisibilityTypes(Visibility); }
@@ -434,14 +435,20 @@ public:
bool isWeakForLinker() const { return isWeakForLinker(getLinkage()); }
+protected:
/// Copy all additional attributes (those not needed to create a GlobalValue)
/// from the GlobalValue Src to this one.
- virtual void copyAttributesFrom(const GlobalValue *Src);
+ void copyAttributesFrom(const GlobalValue *Src);
- /// If special LLVM prefix that is used to inform the asm printer to not emit
- /// usual symbol prefix before the symbol name is used then return linkage
- /// name after skipping this special LLVM prefix.
- static StringRef getRealLinkageName(StringRef Name) {
+public:
+ /// If the given string begins with the GlobalValue name mangling escape
+ /// character '\1', drop it.
+ ///
+ /// This function applies a specific mangling that is used in PGO profiles,
+ /// among other things. If you're trying to get a symbol name for an
+ /// arbitrary GlobalValue, this is not the function you're looking for; see
+ /// Mangler.h.
+ static StringRef dropLLVMManglingEscape(StringRef Name) {
if (!Name.empty() && Name[0] == '\1')
return Name.substr(1);
return Name;
@@ -514,10 +521,11 @@ public:
// increased.
bool canIncreaseAlignment() const;
- const GlobalObject *getBaseObject() const {
- return const_cast<GlobalValue *>(this)->getBaseObject();
+ const GlobalObject *getBaseObject() const;
+ GlobalObject *getBaseObject() {
+ return const_cast<GlobalObject *>(
+ static_cast<const GlobalValue *>(this)->getBaseObject());
}
- GlobalObject *getBaseObject();
/// Returns whether this is a reference to an absolute symbol.
bool isAbsoluteSymbolRef() const;
@@ -528,10 +536,10 @@ public:
/// This method unlinks 'this' from the containing module, but does not delete
/// it.
- virtual void removeFromParent() = 0;
+ void removeFromParent();
/// This method unlinks 'this' from the containing module and deletes it.
- virtual void eraseFromParent() = 0;
+ void eraseFromParent();
/// Get the module that this global value is contained inside of...
Module *getParent() { return Parent; }
diff --git a/contrib/llvm/include/llvm/IR/GlobalVariable.h b/contrib/llvm/include/llvm/IR/GlobalVariable.h
index 3b545d8..34ace6f 100644
--- a/contrib/llvm/include/llvm/IR/GlobalVariable.h
+++ b/contrib/llvm/include/llvm/IR/GlobalVariable.h
@@ -23,6 +23,7 @@
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/Twine.h"
#include "llvm/ADT/ilist_node.h"
+#include "llvm/IR/Attributes.h"
#include "llvm/IR/GlobalObject.h"
#include "llvm/IR/OperandTraits.h"
#include "llvm/IR/Value.h"
@@ -41,6 +42,7 @@ class DIGlobalVariableExpression;
class GlobalVariable : public GlobalObject, public ilist_node<GlobalVariable> {
friend class SymbolTableListTraits<GlobalVariable>;
+ AttributeSet Attrs;
bool isConstantGlobal : 1; // Is this a global constant?
bool isExternallyInitializedConstant : 1; // Is this a global whose value
// can change from its initial
@@ -64,7 +66,7 @@ public:
GlobalVariable(const GlobalVariable &) = delete;
GlobalVariable &operator=(const GlobalVariable &) = delete;
- ~GlobalVariable() override {
+ ~GlobalVariable() {
dropAllReferences();
// FIXME: needed by operator delete
@@ -76,8 +78,6 @@ public:
return User::operator new(s, 1);
}
- void *operator new(size_t, unsigned) = delete;
-
/// Provide fast operand accessors
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
@@ -156,17 +156,17 @@ public:
/// copyAttributesFrom - copy all additional attributes (those not needed to
/// create a GlobalVariable) from the GlobalVariable Src to this one.
- void copyAttributesFrom(const GlobalValue *Src) override;
+ void copyAttributesFrom(const GlobalVariable *Src);
/// removeFromParent - This method unlinks 'this' from the containing module,
/// but does not delete it.
///
- void removeFromParent() override;
+ void removeFromParent();
/// eraseFromParent - This method unlinks 'this' from the containing module
/// and deletes it.
///
- void eraseFromParent() override;
+ void eraseFromParent();
/// Drop all references in preparation to destroy the GlobalVariable. This
/// drops not only the reference to the initializer but also to any metadata.
@@ -178,8 +178,70 @@ public:
/// Fill the vector with all debug info attachements.
void getDebugInfo(SmallVectorImpl<DIGlobalVariableExpression *> &GVs) const;
+ /// Add attribute to this global.
+ void addAttribute(Attribute::AttrKind Kind) {
+ Attrs = Attrs.addAttribute(getContext(), Kind);
+ }
+
+ /// Add attribute to this global.
+ void addAttribute(StringRef Kind, StringRef Val = StringRef()) {
+ Attrs = Attrs.addAttribute(getContext(), Kind, Val);
+ }
+
+ /// Return true if the attribute exists.
+ bool hasAttribute(Attribute::AttrKind Kind) const {
+ return Attrs.hasAttribute(Kind);
+ }
+
+ /// Return true if the attribute exists.
+ bool hasAttribute(StringRef Kind) const {
+ return Attrs.hasAttribute(Kind);
+ }
+
+ /// Return true if any attributes exist.
+ bool hasAttributes() const {
+ return Attrs.hasAttributes();
+ }
+
+ /// Return the attribute object.
+ Attribute getAttribute(Attribute::AttrKind Kind) const {
+ return Attrs.getAttribute(Kind);
+ }
+
+ /// Return the attribute object.
+ Attribute getAttribute(StringRef Kind) const {
+ return Attrs.getAttribute(Kind);
+ }
+
+ /// Return the attribute set for this global
+ AttributeSet getAttributes() const {
+ return Attrs;
+ }
+
+ /// Return attribute set as list with index.
+ /// FIXME: This may not be required once ValueEnumerators
+ /// in bitcode-writer can enumerate attribute-set.
+ AttributeList getAttributesAsList(unsigned index) const {
+ if (!hasAttributes())
+ return AttributeList();
+ std::pair<unsigned, AttributeSet> AS[1] = {{index, Attrs}};
+ return AttributeList::get(getContext(), AS);
+ }
+
+ /// Set attribute list for this global
+ void setAttributes(AttributeSet A) {
+ Attrs = A;
+ }
+
+ /// Check if section name is present
+ bool hasImplicitSection() const {
+ return getAttributes().hasAttribute("bss-section") ||
+ getAttributes().hasAttribute("data-section") ||
+ getAttributes().hasAttribute("rodata-section");
+ }
+
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return V->getValueID() == Value::GlobalVariableVal;
}
};
diff --git a/contrib/llvm/include/llvm/IR/IRBuilder.h b/contrib/llvm/include/llvm/IR/IRBuilder.h
index 1d9c169..5344a93 100644
--- a/contrib/llvm/include/llvm/IR/IRBuilder.h
+++ b/contrib/llvm/include/llvm/IR/IRBuilder.h
@@ -15,6 +15,7 @@
#ifndef LLVM_IR_IRBUILDER_H
#define LLVM_IR_IRBUILDER_H
+#include "llvm-c/Types.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/None.h"
#include "llvm/ADT/StringRef.h"
@@ -33,6 +34,7 @@
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Module.h"
#include "llvm/IR/Operator.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Value.h"
@@ -40,11 +42,10 @@
#include "llvm/Support/AtomicOrdering.h"
#include "llvm/Support/CBindingWrapping.h"
#include "llvm/Support/Casting.h"
-#include "llvm-c/Types.h"
+#include <algorithm>
#include <cassert>
#include <cstddef>
#include <cstdint>
-#include <algorithm>
#include <functional>
namespace llvm {
@@ -75,7 +76,7 @@ class IRBuilderCallbackInserter : IRBuilderDefaultInserter {
public:
IRBuilderCallbackInserter(std::function<void(Instruction *)> Callback)
- : Callback(Callback) {}
+ : Callback(std::move(Callback)) {}
protected:
void InsertHelper(Instruction *I, const Twine &Name,
@@ -434,6 +435,26 @@ public:
MDNode *ScopeTag = nullptr,
MDNode *NoAliasTag = nullptr);
+ /// \brief Create and insert an element unordered-atomic memcpy 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.
+ CallInst *CreateElementUnorderedAtomicMemCpy(
+ Value *Dst, Value *Src, uint64_t Size, uint32_t ElementSize,
+ MDNode *TBAATag = nullptr, MDNode *TBAAStructTag = nullptr,
+ MDNode *ScopeTag = nullptr, MDNode *NoAliasTag = nullptr) {
+ return CreateElementUnorderedAtomicMemCpy(
+ Dst, Src, getInt64(Size), ElementSize, TBAATag, TBAAStructTag, ScopeTag,
+ NoAliasTag);
+ }
+
+ CallInst *CreateElementUnorderedAtomicMemCpy(
+ Value *Dst, Value *Src, Value *Size, uint32_t ElementSize,
+ MDNode *TBAATag = nullptr, MDNode *TBAAStructTag = nullptr,
+ MDNode *ScopeTag = nullptr, MDNode *NoAliasTag = nullptr);
+
/// \brief Create and insert a memmove between the specified
/// pointers.
///
@@ -453,6 +474,45 @@ public:
MDNode *ScopeTag = nullptr,
MDNode *NoAliasTag = nullptr);
+ /// \brief 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);
+
+ /// \brief Create a vector fmul reduction intrinsic of the source vector.
+ /// The first parameter is a scalar accumulator value for ordered reductions.
+ CallInst *CreateFMulReduce(Value *Acc, Value *Src);
+
+ /// \brief Create a vector int add reduction intrinsic of the source vector.
+ CallInst *CreateAddReduce(Value *Src);
+
+ /// \brief Create a vector int mul reduction intrinsic of the source vector.
+ CallInst *CreateMulReduce(Value *Src);
+
+ /// \brief Create a vector int AND reduction intrinsic of the source vector.
+ CallInst *CreateAndReduce(Value *Src);
+
+ /// \brief Create a vector int OR reduction intrinsic of the source vector.
+ CallInst *CreateOrReduce(Value *Src);
+
+ /// \brief Create a vector int XOR reduction intrinsic of the source vector.
+ CallInst *CreateXorReduce(Value *Src);
+
+ /// \brief Create a vector integer max reduction intrinsic of the source
+ /// vector.
+ CallInst *CreateIntMaxReduce(Value *Src, bool IsSigned = false);
+
+ /// \brief Create a vector integer min reduction intrinsic of the source
+ /// vector.
+ CallInst *CreateIntMinReduce(Value *Src, bool IsSigned = false);
+
+ /// \brief Create a vector float max reduction intrinsic of the source
+ /// vector.
+ CallInst *CreateFPMaxReduce(Value *Src, bool NoNaN = false);
+
+ /// \brief Create a vector float min reduction intrinsic of the source
+ /// vector.
+ CallInst *CreateFPMinReduce(Value *Src, bool NoNaN = false);
+
/// \brief Create a lifetime.start intrinsic.
///
/// If the pointer isn't i8* it will be converted.
@@ -560,6 +620,22 @@ public:
Type *ResultType,
const Twine &Name = "");
+ /// Create a call to intrinsic \p ID with 2 operands which is mangled on the
+ /// first type.
+ CallInst *CreateBinaryIntrinsic(Intrinsic::ID ID,
+ Value *LHS, Value *RHS,
+ const Twine &Name = "");
+
+ /// Create call to the minnum intrinsic.
+ CallInst *CreateMinNum(Value *LHS, Value *RHS, const Twine &Name = "") {
+ return CreateBinaryIntrinsic(Intrinsic::minnum, LHS, RHS, Name);
+ }
+
+ /// Create call to the maxnum intrinsic.
+ CallInst *CreateMaxNum(Value *LHS, Value *RHS, const Twine &Name = "") {
+ return CreateBinaryIntrinsic(Intrinsic::minnum, LHS, RHS, Name);
+ }
+
private:
/// \brief Create a call to a masked intrinsic with given Id.
CallInst *CreateMaskedIntrinsic(Intrinsic::ID Id, ArrayRef<Value *> Ops,
@@ -986,7 +1062,7 @@ public:
Value *CreateAnd(Value *LHS, Value *RHS, const Twine &Name = "") {
if (Constant *RC = dyn_cast<Constant>(RHS)) {
- if (isa<ConstantInt>(RC) && cast<ConstantInt>(RC)->isAllOnesValue())
+ if (isa<ConstantInt>(RC) && cast<ConstantInt>(RC)->isMinusOne())
return LHS; // LHS & -1 -> LHS
if (Constant *LC = dyn_cast<Constant>(LHS))
return Insert(Folder.CreateAnd(LC, RC), Name);
@@ -1073,9 +1149,15 @@ public:
// Instruction creation methods: Memory Instructions
//===--------------------------------------------------------------------===//
+ AllocaInst *CreateAlloca(Type *Ty, unsigned AddrSpace,
+ Value *ArraySize = nullptr, const Twine &Name = "") {
+ return Insert(new AllocaInst(Ty, AddrSpace, ArraySize), Name);
+ }
+
AllocaInst *CreateAlloca(Type *Ty, Value *ArraySize = nullptr,
const Twine &Name = "") {
- return Insert(new AllocaInst(Ty, ArraySize), Name);
+ const DataLayout &DL = BB->getParent()->getParent()->getDataLayout();
+ return Insert(new AllocaInst(Ty, DL.getAllocaAddrSpace(), ArraySize), Name);
}
// \brief Provided to resolve 'CreateLoad(Ptr, "...")' correctly, instead of
// converting the string to 'bool' for the isVolatile parameter.
@@ -1121,22 +1203,22 @@ public:
return SI;
}
FenceInst *CreateFence(AtomicOrdering Ordering,
- SynchronizationScope SynchScope = CrossThread,
+ SyncScope::ID SSID = SyncScope::System,
const Twine &Name = "") {
- return Insert(new FenceInst(Context, Ordering, SynchScope), Name);
+ return Insert(new FenceInst(Context, Ordering, SSID), Name);
}
AtomicCmpXchgInst *
CreateAtomicCmpXchg(Value *Ptr, Value *Cmp, Value *New,
AtomicOrdering SuccessOrdering,
AtomicOrdering FailureOrdering,
- SynchronizationScope SynchScope = CrossThread) {
+ SyncScope::ID SSID = SyncScope::System) {
return Insert(new AtomicCmpXchgInst(Ptr, Cmp, New, SuccessOrdering,
- FailureOrdering, SynchScope));
+ FailureOrdering, SSID));
}
AtomicRMWInst *CreateAtomicRMW(AtomicRMWInst::BinOp Op, Value *Ptr, Value *Val,
AtomicOrdering Ordering,
- SynchronizationScope SynchScope = CrossThread) {
- return Insert(new AtomicRMWInst(Op, Ptr, Val, Ordering, SynchScope));
+ SyncScope::ID SSID = SyncScope::System) {
+ return Insert(new AtomicRMWInst(Op, Ptr, Val, Ordering, SSID));
}
Value *CreateGEP(Value *Ptr, ArrayRef<Value *> IdxList,
const Twine &Name = "") {
@@ -1435,11 +1517,9 @@ public:
const Twine &Name = "") {
if (V->getType() == DestTy)
return V;
- if (V->getType()->getScalarType()->isPointerTy() &&
- DestTy->getScalarType()->isIntegerTy())
+ if (V->getType()->isPtrOrPtrVectorTy() && DestTy->isIntOrIntVectorTy())
return CreatePtrToInt(V, DestTy, Name);
- if (V->getType()->getScalarType()->isIntegerTy() &&
- DestTy->getScalarType()->isPointerTy())
+ if (V->getType()->isIntOrIntVectorTy() && DestTy->isPtrOrPtrVectorTy())
return CreateIntToPtr(V, DestTy, Name);
return CreateBitCast(V, DestTy, Name);
@@ -1790,24 +1870,16 @@ public:
return V;
}
- /// \brief Create an assume intrinsic call that represents an alignment
- /// assumption on the provided pointer.
- ///
- /// 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.
- CallInst *CreateAlignmentAssumption(const DataLayout &DL, Value *PtrValue,
- unsigned Alignment,
- Value *OffsetValue = nullptr) {
- assert(isa<PointerType>(PtrValue->getType()) &&
- "trying to create an alignment assumption on a non-pointer?");
-
- PointerType *PtrTy = cast<PointerType>(PtrValue->getType());
- Type *IntPtrTy = getIntPtrTy(DL, PtrTy->getAddressSpace());
+private:
+ /// \brief Helper function that creates an assume intrinsic call that
+ /// represents an alignment assumption on the provided Ptr, Mask, Type
+ /// and Offset.
+ CallInst *CreateAlignmentAssumptionHelper(const DataLayout &DL,
+ Value *PtrValue, Value *Mask,
+ Type *IntPtrTy,
+ Value *OffsetValue) {
Value *PtrIntValue = CreatePtrToInt(PtrValue, IntPtrTy, "ptrint");
- Value *Mask = ConstantInt::get(IntPtrTy,
- Alignment > 0 ? Alignment - 1 : 0);
if (OffsetValue) {
bool IsOffsetZero = false;
if (ConstantInt *CI = dyn_cast<ConstantInt>(OffsetValue))
@@ -1824,9 +1896,60 @@ public:
Value *Zero = ConstantInt::get(IntPtrTy, 0);
Value *MaskedPtr = CreateAnd(PtrIntValue, Mask, "maskedptr");
Value *InvCond = CreateICmpEQ(MaskedPtr, Zero, "maskcond");
-
return CreateAssumption(InvCond);
}
+
+public:
+ /// \brief Create an assume intrinsic call that represents an alignment
+ /// assumption on the provided pointer.
+ ///
+ /// 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.
+ CallInst *CreateAlignmentAssumption(const DataLayout &DL, Value *PtrValue,
+ unsigned Alignment,
+ Value *OffsetValue = nullptr) {
+ assert(isa<PointerType>(PtrValue->getType()) &&
+ "trying to create an alignment assumption on a non-pointer?");
+ PointerType *PtrTy = cast<PointerType>(PtrValue->getType());
+ Type *IntPtrTy = getIntPtrTy(DL, PtrTy->getAddressSpace());
+
+ Value *Mask = ConstantInt::get(IntPtrTy, Alignment > 0 ? Alignment - 1 : 0);
+ return CreateAlignmentAssumptionHelper(DL, PtrValue, Mask, IntPtrTy,
+ OffsetValue);
+ }
+ //
+ /// \brief Create an assume intrinsic call that represents an alignment
+ /// assumption on the provided pointer.
+ ///
+ /// 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.
+ ///
+ /// 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) {
+ assert(isa<PointerType>(PtrValue->getType()) &&
+ "trying to create an alignment assumption on a non-pointer?");
+ PointerType *PtrTy = cast<PointerType>(PtrValue->getType());
+ Type *IntPtrTy = getIntPtrTy(DL, PtrTy->getAddressSpace());
+
+ if (Alignment->getType() != IntPtrTy)
+ Alignment = CreateIntCast(Alignment, IntPtrTy, /*isSigned*/ true,
+ "alignmentcast");
+ Value *IsPositive =
+ CreateICmp(CmpInst::ICMP_SGT, Alignment,
+ ConstantInt::get(Alignment->getType(), 0), "ispositive");
+ Value *PositiveMask =
+ CreateSub(Alignment, ConstantInt::get(IntPtrTy, 1), "positivemask");
+ Value *Mask = CreateSelect(IsPositive, PositiveMask,
+ ConstantInt::get(IntPtrTy, 0), "mask");
+
+ return CreateAlignmentAssumptionHelper(DL, PtrValue, Mask, IntPtrTy,
+ OffsetValue);
+ }
};
// Create wrappers for C Binding types (see CBindingWrapping.h).
diff --git a/contrib/llvm/include/llvm/IR/InlineAsm.h b/contrib/llvm/include/llvm/IR/InlineAsm.h
index f95509b..59874b0 100644
--- a/contrib/llvm/include/llvm/IR/InlineAsm.h
+++ b/contrib/llvm/include/llvm/IR/InlineAsm.h
@@ -1,4 +1,4 @@
-//===-- llvm/InlineAsm.h - Class to represent inline asm strings-*- C++ -*-===//
+//===- llvm/InlineAsm.h - Class to represent inline asm strings -*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -28,7 +28,7 @@ class FunctionType;
class PointerType;
template <class ConstantClass> class ConstantUniqueMap;
-class InlineAsm : public Value {
+class InlineAsm final : public Value {
public:
enum AsmDialect {
AD_ATT,
@@ -48,7 +48,6 @@ private:
InlineAsm(FunctionType *Ty, const std::string &AsmString,
const std::string &Constraints, bool hasSideEffects,
bool isAlignStack, AsmDialect asmDialect);
- ~InlineAsm() override;
/// When the ConstantUniqueMap merges two types and makes two InlineAsms
/// identical, it destroys one of them with this method.
@@ -95,39 +94,41 @@ public:
isClobber // '~x'
};
- typedef std::vector<std::string> ConstraintCodeVector;
+ using ConstraintCodeVector = std::vector<std::string>;
struct SubConstraintInfo {
/// MatchingInput - If this is not -1, this is an output constraint where an
/// input constraint is required to match it (e.g. "0"). The value is the
/// constraint number that matches this one (for example, if this is
/// constraint #0 and constraint #4 has the value "0", this will be 4).
- signed char MatchingInput;
+ signed char MatchingInput = -1;
+
/// Code - The constraint code, either the register name (in braces) or the
/// constraint letter/number.
ConstraintCodeVector Codes;
+
/// Default constructor.
- SubConstraintInfo() : MatchingInput(-1) {}
+ SubConstraintInfo() = default;
};
- typedef std::vector<SubConstraintInfo> SubConstraintInfoVector;
+ using SubConstraintInfoVector = std::vector<SubConstraintInfo>;
struct ConstraintInfo;
- typedef std::vector<ConstraintInfo> ConstraintInfoVector;
+ using ConstraintInfoVector = std::vector<ConstraintInfo>;
struct ConstraintInfo {
/// Type - The basic type of the constraint: input/output/clobber
///
- ConstraintPrefix Type;
+ ConstraintPrefix Type = isInput;
/// isEarlyClobber - "&": output operand writes result before inputs are all
/// read. This is only ever set for an output operand.
- bool isEarlyClobber;
+ bool isEarlyClobber = false;
/// MatchingInput - If this is not -1, this is an output constraint where an
/// input constraint is required to match it (e.g. "0"). The value is the
/// constraint number that matches this one (for example, if this is
/// constraint #0 and constraint #4 has the value "0", this will be 4).
- signed char MatchingInput;
+ signed char MatchingInput = -1;
/// hasMatchingInput - Return true if this is an output constraint that has
/// a matching input constraint.
@@ -135,30 +136,30 @@ public:
/// isCommutative - This is set to true for a constraint that is commutative
/// with the next operand.
- bool isCommutative;
+ bool isCommutative = false;
/// isIndirect - True if this operand is an indirect operand. This means
/// that the address of the source or destination is present in the call
/// instruction, instead of it being returned or passed in explicitly. This
/// is represented with a '*' in the asm string.
- bool isIndirect;
+ bool isIndirect = false;
/// Code - The constraint code, either the register name (in braces) or the
/// constraint letter/number.
ConstraintCodeVector Codes;
/// isMultipleAlternative - '|': has multiple-alternative constraints.
- bool isMultipleAlternative;
+ bool isMultipleAlternative = false;
/// multipleAlternatives - If there are multiple alternative constraints,
/// this array will contain them. Otherwise it will be empty.
SubConstraintInfoVector multipleAlternatives;
/// The currently selected alternative constraint index.
- unsigned currentAlternativeIndex;
+ unsigned currentAlternativeIndex = 0;
/// Default constructor.
- ConstraintInfo();
+ ConstraintInfo() = default;
/// Parse - Analyze the specified string (e.g. "=*&{eax}") and fill in the
/// fields in this structure. If the constraint string is not understood,
@@ -182,7 +183,7 @@ public:
}
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return V->getValueID() == Value::InlineAsmVal;
}
diff --git a/contrib/llvm/include/llvm/IR/InstIterator.h b/contrib/llvm/include/llvm/IR/InstIterator.h
index 28fc473..2988fc9 100644
--- a/contrib/llvm/include/llvm/IR/InstIterator.h
+++ b/contrib/llvm/include/llvm/IR/InstIterator.h
@@ -31,20 +31,20 @@ namespace llvm {
// inst_iterator and const_inst_iterator's.
//
template <class BB_t, class BB_i_t, class BI_t, class II_t> class InstIterator {
- typedef BB_t BBty;
- typedef BB_i_t BBIty;
- typedef BI_t BIty;
- typedef II_t IIty;
+ using BBty = BB_t;
+ using BBIty = BB_i_t;
+ using BIty = BI_t;
+ using IIty = II_t;
BB_t *BBs; // BasicBlocksType
BB_i_t BB; // BasicBlocksType::iterator
BI_t BI; // BasicBlock::iterator
public:
- typedef std::bidirectional_iterator_tag iterator_category;
- typedef IIty value_type;
- typedef signed difference_type;
- typedef IIty* pointer;
- typedef IIty& reference;
+ using iterator_category = std::bidirectional_iterator_tag;
+ using value_type = IIty;
+ using difference_type = signed;
+ using pointer = IIty *;
+ using reference = IIty &;
// Default constructor
InstIterator() = default;
@@ -119,13 +119,15 @@ private:
}
};
-typedef InstIterator<SymbolTableList<BasicBlock>, Function::iterator,
- BasicBlock::iterator, Instruction> inst_iterator;
-typedef InstIterator<const SymbolTableList<BasicBlock>,
- Function::const_iterator, BasicBlock::const_iterator,
- const Instruction> const_inst_iterator;
-typedef iterator_range<inst_iterator> inst_range;
-typedef iterator_range<const_inst_iterator> const_inst_range;
+using inst_iterator =
+ InstIterator<SymbolTableList<BasicBlock>, Function::iterator,
+ BasicBlock::iterator, Instruction>;
+using const_inst_iterator =
+ InstIterator<const SymbolTableList<BasicBlock>,
+ Function::const_iterator, BasicBlock::const_iterator,
+ const Instruction>;
+using inst_range = iterator_range<inst_iterator>;
+using const_inst_range = iterator_range<const_inst_iterator>;
inline inst_iterator inst_begin(Function *F) { return inst_iterator(*F); }
inline inst_iterator inst_end(Function *F) { return inst_iterator(*F, true); }
diff --git a/contrib/llvm/include/llvm/IR/InstVisitor.h b/contrib/llvm/include/llvm/IR/InstVisitor.h
index 088d3e0..5557981 100644
--- a/contrib/llvm/include/llvm/IR/InstVisitor.h
+++ b/contrib/llvm/include/llvm/IR/InstVisitor.h
@@ -116,6 +116,9 @@ public:
// visit - Finally, code to visit an instruction...
//
RetTy visit(Instruction &I) {
+ static_assert(std::is_base_of<InstVisitor, SubClass>::value,
+ "Must pass the derived type to this template!");
+
switch (I.getOpcode()) {
default: llvm_unreachable("Unknown instruction type encountered!");
// Build the switch statement using the Instruction.def file...
diff --git a/contrib/llvm/include/llvm/IR/InstrTypes.h b/contrib/llvm/include/llvm/IR/InstrTypes.h
index f2abbec..d749077 100644
--- a/contrib/llvm/include/llvm/IR/InstrTypes.h
+++ b/contrib/llvm/include/llvm/IR/InstrTypes.h
@@ -1,4 +1,4 @@
-//===-- llvm/InstrTypes.h - Important Instruction subclasses ----*- C++ -*-===//
+//===- llvm/InstrTypes.h - Important Instruction subclasses -----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -17,19 +17,21 @@
#define LLVM_IR_INSTRTYPES_H
#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/iterator_range.h"
#include "llvm/ADT/None.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
+#include "llvm/ADT/iterator_range.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/OperandTraits.h"
+#include "llvm/IR/Type.h"
#include "llvm/IR/User.h"
+#include "llvm/IR/Value.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/ErrorHandling.h"
#include <algorithm>
@@ -60,36 +62,21 @@ protected:
Use *Ops, unsigned NumOps, BasicBlock *InsertAtEnd)
: Instruction(Ty, iType, Ops, NumOps, InsertAtEnd) {}
- // Out of line virtual method, so the vtable, etc has a home.
- ~TerminatorInst() override;
-
- /// Virtual methods - Terminators should overload these and provide inline
- /// overrides of non-V methods.
- virtual BasicBlock *getSuccessorV(unsigned idx) const = 0;
- virtual unsigned getNumSuccessorsV() const = 0;
- virtual void setSuccessorV(unsigned idx, BasicBlock *B) = 0;
-
public:
/// Return the number of successors that this terminator has.
- unsigned getNumSuccessors() const {
- return getNumSuccessorsV();
- }
+ unsigned getNumSuccessors() const;
/// Return the specified successor.
- BasicBlock *getSuccessor(unsigned idx) const {
- return getSuccessorV(idx);
- }
+ BasicBlock *getSuccessor(unsigned idx) const;
/// Update the specified successor to point at the provided block.
- void setSuccessor(unsigned idx, BasicBlock *B) {
- setSuccessorV(idx, B);
- }
+ void setSuccessor(unsigned idx, BasicBlock *B);
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const Instruction *I) {
+ static bool classof(const Instruction *I) {
return I->isTerminator();
}
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return isa<Instruction>(V) && classof(cast<Instruction>(V));
}
@@ -114,17 +101,17 @@ public:
template <class Term, class BB> // Successor Iterator
class SuccIterator : public std::iterator<std::random_access_iterator_tag, BB,
int, BB *, BB *> {
- typedef std::iterator<std::random_access_iterator_tag, BB, int, BB *, BB *>
- super;
+ using super =
+ std::iterator<std::random_access_iterator_tag, BB, int, BB *, BB *>;
public:
- typedef typename super::pointer pointer;
- typedef typename super::reference reference;
+ using pointer = typename super::pointer;
+ using reference = typename super::reference;
private:
Term TermInst;
unsigned idx;
- typedef SuccIterator<Term, BB> Self;
+ using Self = SuccIterator<Term, BB>;
inline bool index_is_valid(unsigned idx) {
return idx < TermInst->getNumSuccessors();
@@ -260,11 +247,11 @@ public:
}
};
- typedef SuccIterator<TerminatorInst *, BasicBlock> succ_iterator;
- typedef SuccIterator<const TerminatorInst *, const BasicBlock>
- succ_const_iterator;
- typedef iterator_range<succ_iterator> succ_range;
- typedef iterator_range<succ_const_iterator> succ_const_range;
+ using succ_iterator = SuccIterator<TerminatorInst *, BasicBlock>;
+ using succ_const_iterator =
+ SuccIterator<const TerminatorInst *, const BasicBlock>;
+ using succ_range = iterator_range<succ_iterator>;
+ using succ_const_range = iterator_range<succ_const_iterator>;
private:
inline succ_iterator succ_begin() { return succ_iterator(this); }
@@ -307,23 +294,18 @@ public:
return User::operator new(s, 1);
}
- void *operator new(size_t, unsigned) = delete;
-
- // Out of line virtual method, so the vtable, etc has a home.
- ~UnaryInstruction() override;
-
/// Transparently provide more efficient getOperand methods.
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const Instruction *I) {
+ static bool classof(const Instruction *I) {
return I->getOpcode() == Instruction::Alloca ||
I->getOpcode() == Instruction::Load ||
I->getOpcode() == Instruction::VAArg ||
I->getOpcode() == Instruction::ExtractValue ||
(I->getOpcode() >= CastOpsBegin && I->getOpcode() < CastOpsEnd);
}
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return isa<Instruction>(V) && classof(cast<Instruction>(V));
}
};
@@ -340,8 +322,9 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(UnaryInstruction, Value)
//===----------------------------------------------------------------------===//
class BinaryOperator : public Instruction {
+ void AssertOK();
+
protected:
- void init(BinaryOps iType);
BinaryOperator(BinaryOps iType, Value *S1, Value *S2, Type *Ty,
const Twine &Name, Instruction *InsertBefore);
BinaryOperator(BinaryOps iType, Value *S1, Value *S2, Type *Ty,
@@ -349,6 +332,7 @@ protected:
// Note: Instruction needs to be a friend here to call cloneImpl.
friend class Instruction;
+
BinaryOperator *cloneImpl() const;
public:
@@ -357,8 +341,6 @@ public:
return User::operator new(s, 2);
}
- void *operator new(size_t, unsigned) = delete;
-
/// Transparently provide more efficient getOperand methods.
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
@@ -550,10 +532,10 @@ public:
bool swapOperands();
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const Instruction *I) {
+ static bool classof(const Instruction *I) {
return I->isBinaryOp();
}
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return isa<Instruction>(V) && classof(cast<Instruction>(V));
}
};
@@ -576,8 +558,6 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(BinaryOperator, Value)
/// if (isa<CastInst>(Instr)) { ... }
/// @brief Base class of casting instructions.
class CastInst : public UnaryInstruction {
- void anchor() override;
-
protected:
/// @brief Constructor with insert-before-instruction semantics for subclasses
CastInst(Type *Ty, unsigned iType, Value *S,
@@ -853,10 +833,10 @@ public:
static bool castIsValid(Instruction::CastOps op, Value *S, Type *DstTy);
/// @brief Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const Instruction *I) {
+ static bool classof(const Instruction *I) {
return I->isCast();
}
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return isa<Instruction>(V) && classof(cast<Instruction>(V));
}
};
@@ -922,18 +902,12 @@ protected:
Value *LHS, Value *RHS, const Twine &Name,
BasicBlock *InsertAtEnd);
- void anchor() override; // Out of line virtual method.
-
public:
- CmpInst() = delete;
-
// allocate space for exactly two operands
void *operator new(size_t s) {
return User::operator new(s, 2);
}
- void *operator new(size_t, unsigned) = delete;
-
/// Construct a compare instruction, given the opcode, the predicate and
/// the two operands. Optionally (if InstBefore is specified) insert the
/// instruction into a BasicBlock right before the specified instruction.
@@ -1059,18 +1033,6 @@ public:
return isFalseWhenEqual(getPredicate());
}
- /// @brief Determine if Pred1 implies Pred2 is true when two compares have
- /// matching operands.
- bool isImpliedTrueByMatchingCmp(Predicate Pred2) {
- return isImpliedTrueByMatchingCmp(getPredicate(), Pred2);
- }
-
- /// @brief Determine if Pred1 implies Pred2 is false when two compares have
- /// matching operands.
- bool isImpliedFalseByMatchingCmp(Predicate Pred2) {
- return isImpliedFalseByMatchingCmp(getPredicate(), Pred2);
- }
-
/// @returns true if the predicate is unsigned, false otherwise.
/// @brief Determine if the predicate is an unsigned operation.
static bool isUnsigned(Predicate predicate);
@@ -1100,11 +1062,11 @@ public:
static bool isImpliedFalseByMatchingCmp(Predicate Pred1, Predicate Pred2);
/// @brief Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const Instruction *I) {
+ static bool classof(const Instruction *I) {
return I->getOpcode() == Instruction::ICmp ||
I->getOpcode() == Instruction::FCmp;
}
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return isa<Instruction>(V) && classof(cast<Instruction>(V));
}
@@ -1137,8 +1099,6 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CmpInst, Value)
//===----------------------------------------------------------------------===//
class FuncletPadInst : public Instruction {
private:
- void init(Value *ParentPad, ArrayRef<Value *> Args, const Twine &NameStr);
-
FuncletPadInst(const FuncletPadInst &CPI);
explicit FuncletPadInst(Instruction::FuncletPadOps Op, Value *ParentPad,
@@ -1148,11 +1108,14 @@ private:
ArrayRef<Value *> Args, unsigned Values,
const Twine &NameStr, BasicBlock *InsertAtEnd);
+ void init(Value *ParentPad, ArrayRef<Value *> Args, const Twine &NameStr);
+
protected:
// Note: Instruction needs to be a friend here to call cloneImpl.
friend class Instruction;
friend class CatchPadInst;
friend class CleanupPadInst;
+
FuncletPadInst *cloneImpl() const;
public:
@@ -1189,8 +1152,8 @@ public:
}
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const Instruction *I) { return I->isFuncletPad(); }
- static inline bool classof(const Value *V) {
+ static bool classof(const Instruction *I) { return I->isFuncletPad(); }
+ static bool classof(const Value *V) {
return isa<Instruction>(V) && classof(cast<Instruction>(V));
}
};
@@ -1273,7 +1236,8 @@ public:
ArrayRef<InputTy> inputs() const { return Inputs; }
- typedef typename std::vector<InputTy>::const_iterator input_iterator;
+ using input_iterator = typename std::vector<InputTy>::const_iterator;
+
size_t input_size() const { return Inputs.size(); }
input_iterator input_begin() const { return Inputs.begin(); }
input_iterator input_end() const { return Inputs.end(); }
@@ -1281,8 +1245,8 @@ public:
StringRef getTag() const { return Tag; }
};
-typedef OperandBundleDefT<Value *> OperandBundleDef;
-typedef OperandBundleDefT<const Value *> ConstOperandBundleDef;
+using OperandBundleDef = OperandBundleDefT<Value *>;
+using ConstOperandBundleDef = OperandBundleDefT<const Value *>;
/// \brief A mixin to add operand bundle functionality to llvm instruction
/// classes.
@@ -1565,8 +1529,8 @@ protected:
return OperandBundleUse(BOI.Tag, Inputs);
}
- typedef BundleOpInfo *bundle_op_iterator;
- typedef const BundleOpInfo *const_bundle_op_iterator;
+ using bundle_op_iterator = BundleOpInfo *;
+ using const_bundle_op_iterator = const BundleOpInfo *;
/// \brief Return the start of the list of BundleOpInfo instances associated
/// with this OperandBundleUser.
@@ -1666,6 +1630,6 @@ protected:
}
};
-} // end llvm namespace
+} // end namespace llvm
#endif // LLVM_IR_INSTRTYPES_H
diff --git a/contrib/llvm/include/llvm/IR/Instruction.def b/contrib/llvm/include/llvm/IR/Instruction.def
index 18711ab..8661729 100644
--- a/contrib/llvm/include/llvm/IR/Instruction.def
+++ b/contrib/llvm/include/llvm/IR/Instruction.def
@@ -102,6 +102,10 @@
#define LAST_OTHER_INST(num)
#endif
+#ifndef HANDLE_USER_INST
+#define HANDLE_USER_INST(num, opc, Class) HANDLE_OTHER_INST(num, opc, Class)
+#endif
+
// Terminator Instructions - These instructions are used to terminate a basic
// block of the program. Every basic block must end with one of these
// instructions for it to be a well formed basic block.
@@ -185,8 +189,8 @@ HANDLE_OTHER_INST(52, FCmp , FCmpInst ) // Floating point comparison instr.
HANDLE_OTHER_INST(53, PHI , PHINode ) // PHI node instruction
HANDLE_OTHER_INST(54, Call , CallInst ) // Call a function
HANDLE_OTHER_INST(55, Select , SelectInst ) // select instruction
-HANDLE_OTHER_INST(56, UserOp1, Instruction) // May be used internally in a pass
-HANDLE_OTHER_INST(57, UserOp2, Instruction) // Internal to passes only
+HANDLE_USER_INST (56, UserOp1, Instruction) // May be used internally in a pass
+HANDLE_USER_INST (57, UserOp2, Instruction) // Internal to passes only
HANDLE_OTHER_INST(58, VAArg , VAArgInst ) // vaarg instruction
HANDLE_OTHER_INST(59, ExtractElement, ExtractElementInst)// extract from vector
HANDLE_OTHER_INST(60, InsertElement, InsertElementInst) // insert into vector
@@ -220,6 +224,8 @@ HANDLE_OTHER_INST(64, LandingPad, LandingPadInst) // Landing pad instruction.
#undef HANDLE_OTHER_INST
#undef LAST_OTHER_INST
+#undef HANDLE_USER_INST
+
#ifdef HANDLE_INST
#undef HANDLE_INST
#endif
diff --git a/contrib/llvm/include/llvm/IR/Instruction.h b/contrib/llvm/include/llvm/IR/Instruction.h
index fd7c54d..8dc0211 100644
--- a/contrib/llvm/include/llvm/IR/Instruction.h
+++ b/contrib/llvm/include/llvm/IR/Instruction.h
@@ -16,9 +16,9 @@
#define LLVM_IR_INSTRUCTION_H
#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/ilist_node.h"
#include "llvm/ADT/None.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/ilist_node.h"
#include "llvm/IR/DebugLoc.h"
#include "llvm/IR/SymbolTableListTraits.h"
#include "llvm/IR/User.h"
@@ -36,6 +36,10 @@ class FastMathFlags;
class MDNode;
struct AAMDNodes;
+template <> struct ilist_alloc_traits<Instruction> {
+ static inline void deleteNode(Instruction *V);
+};
+
class Instruction : public User,
public ilist_node_with_parent<Instruction, BasicBlock> {
BasicBlock *Parent;
@@ -47,13 +51,13 @@ class Instruction : public User,
HasMetadataBit = 1 << 15
};
+protected:
+ ~Instruction(); // Use deleteValue() to delete a generic Instruction.
+
public:
Instruction(const Instruction &) = delete;
Instruction &operator=(const Instruction &) = delete;
- // Out of line virtual method, so the vtable, etc has a home.
- ~Instruction() override;
-
/// Specialize the methods defined in Value, as we know that an instruction
/// can only be used by other instructions.
Instruction *user_back() { return cast<Instruction>(*user_begin());}
@@ -68,14 +72,20 @@ public:
/// Note: this is undefined behavior if the instruction does not have a
/// parent, or the parent basic block does not have a parent function.
const Module *getModule() const;
- Module *getModule();
+ Module *getModule() {
+ return const_cast<Module *>(
+ static_cast<const Instruction *>(this)->getModule());
+ }
/// Return the function this instruction belongs to.
///
/// Note: it is undefined behavior to call this on an instruction not
/// currently inserted into a function.
const Function *getFunction() const;
- Function *getFunction();
+ Function *getFunction() {
+ return const_cast<Function *>(
+ static_cast<const Instruction *>(this)->getFunction());
+ }
/// This method unlinks 'this' from the containing basic block, but does not
/// delete it.
@@ -142,9 +152,14 @@ public:
return getOpcode() == AShr;
}
+ /// Determine if the Opcode is and/or/xor.
+ static inline bool isBitwiseLogicOp(unsigned Opcode) {
+ return Opcode == And || Opcode == Or || Opcode == Xor;
+ }
+
/// Return true if this is and/or/xor.
inline bool isBitwiseLogicOp() const {
- return getOpcode() == And || getOpcode() == Or || getOpcode() == Xor;
+ return isBitwiseLogicOp(getOpcode());
}
/// Determine if the OpCode is one of the CastInst instructions.
@@ -252,6 +267,12 @@ public:
/// Returns false if no metadata was found.
bool extractProfTotalWeight(uint64_t &TotalVal) const;
+ /// Updates branch_weights metadata by scaling it by \p S / \p T.
+ void updateProfWeight(uint64_t S, uint64_t T);
+
+ /// 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); }
@@ -276,6 +297,10 @@ public:
/// Determine whether the no signed wrap flag is set.
bool hasNoSignedWrap() const;
+ /// Drops flags that may cause this instruction to evaluate to poison despite
+ /// having non-poison inputs.
+ void dropPoisonGeneratingFlags();
+
/// Determine whether the exact flag is set.
bool isExact() const;
@@ -329,6 +354,9 @@ public:
/// Determine whether the allow-reciprocal flag is set.
bool hasAllowReciprocal() const;
+ /// Determine whether the allow-contract flag is set.
+ bool hasAllowContract() const;
+
/// Convenience function for getting all the fast-math flags, which must be an
/// operator which supports these flags. See LangRef.html for the meaning of
/// these flags.
@@ -337,9 +365,9 @@ public:
/// Copy I's fast-math flags
void copyFastMathFlags(const Instruction *I);
- /// Convenience method to copy supported wrapping, exact, and fast-math flags
- /// from V to this instruction.
- void copyIRFlags(const Value *V);
+ /// Convenience method to copy supported exact, fast-math, and (optionally)
+ /// wrapping flags from V to this instruction.
+ void copyIRFlags(const Value *V, bool IncludeWrapFlags = true);
/// Logical 'and' of any supported wrapping, exact, and fast-math flags of
/// V and this instruction.
@@ -372,18 +400,30 @@ public:
///
/// In LLVM, the Add, Mul, And, Or, and Xor operators are associative.
///
- bool isAssociative() const;
- static bool isAssociative(unsigned op);
+ bool isAssociative() const LLVM_READONLY;
+ static bool isAssociative(unsigned Opcode) {
+ return Opcode == And || Opcode == Or || Opcode == Xor ||
+ Opcode == Add || Opcode == Mul;
+ }
/// Return true if the instruction is commutative:
///
/// Commutative operators satisfy: (x op y) === (y op x)
///
- /// In LLVM, these are the associative operators, plus SetEQ and SetNE, when
+ /// In LLVM, these are the commutative operators, plus SetEQ and SetNE, when
/// applied to any type.
///
bool isCommutative() const { return isCommutative(getOpcode()); }
- static bool isCommutative(unsigned op);
+ static bool isCommutative(unsigned Opcode) {
+ switch (Opcode) {
+ case Add: case FAdd:
+ case Mul: case FMul:
+ case And: case Or: case Xor:
+ return true;
+ default:
+ return false;
+ }
+ }
/// Return true if the instruction is idempotent:
///
@@ -392,7 +432,9 @@ public:
/// In LLVM, the And and Or operators are idempotent.
///
bool isIdempotent() const { return isIdempotent(getOpcode()); }
- static bool isIdempotent(unsigned op);
+ static bool isIdempotent(unsigned Opcode) {
+ return Opcode == And || Opcode == Or;
+ }
/// Return true if the instruction is nilpotent:
///
@@ -404,7 +446,9 @@ public:
/// In LLVM, the Xor operator is nilpotent.
///
bool isNilpotent() const { return isNilpotent(getOpcode()); }
- static bool isNilpotent(unsigned op);
+ static bool isNilpotent(unsigned Opcode) {
+ return Opcode == Xor;
+ }
/// Return true if this instruction may modify memory.
bool mayWriteToMemory() const;
@@ -421,6 +465,12 @@ public:
/// higher.
bool isAtomic() const;
+ /// Return true if this atomic instruction loads from memory.
+ bool hasAtomicLoad() const;
+
+ /// Return true if this atomic instruction stores to memory.
+ bool hasAtomicStore() const;
+
/// Return true if this instruction may throw an exception.
bool mayThrow() const;
@@ -506,7 +556,7 @@ public:
/// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return V->getValueID() >= Value::InstructionVal;
}
@@ -599,6 +649,10 @@ private:
Instruction *cloneImpl() const;
};
+inline void ilist_alloc_traits<Instruction>::deleteNode(Instruction *V) {
+ V->deleteValue();
+}
+
} // end namespace llvm
#endif // LLVM_IR_INSTRUCTION_H
diff --git a/contrib/llvm/include/llvm/IR/Instructions.h b/contrib/llvm/include/llvm/IR/Instructions.h
index a5d78a0..60ae988 100644
--- a/contrib/llvm/include/llvm/IR/Instructions.h
+++ b/contrib/llvm/include/llvm/IR/Instructions.h
@@ -1,4 +1,4 @@
-//===-- llvm/Instructions.h - Instruction subclass definitions --*- C++ -*-===//
+//===- llvm/Instructions.h - Instruction subclass definitions ---*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -17,28 +17,33 @@
#define LLVM_IR_INSTRUCTIONS_H
#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/iterator_range.h"
#include "llvm/ADT/None.h"
-#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
+#include "llvm/ADT/iterator.h"
+#include "llvm/ADT/iterator_range.h"
#include "llvm/IR/Attributes.h"
+#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/CallingConv.h"
#include "llvm/IR/Constant.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/InstrTypes.h"
+#include "llvm/IR/Instruction.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/Support/AtomicOrdering.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/ErrorHandling.h"
#include <cassert>
#include <cstddef>
#include <cstdint>
+#include <iterator>
namespace llvm {
@@ -47,11 +52,6 @@ class ConstantInt;
class DataLayout;
class LLVMContext;
-enum SynchronizationScope {
- SingleThread = 0,
- CrossThread = 1
-};
-
//===----------------------------------------------------------------------===//
// AllocaInst Class
//===----------------------------------------------------------------------===//
@@ -67,23 +67,23 @@ protected:
AllocaInst *cloneImpl() const;
public:
- explicit AllocaInst(Type *Ty, Value *ArraySize = nullptr,
+ explicit AllocaInst(Type *Ty, unsigned AddrSpace,
+ Value *ArraySize = nullptr,
const Twine &Name = "",
Instruction *InsertBefore = nullptr);
- AllocaInst(Type *Ty, Value *ArraySize,
+ AllocaInst(Type *Ty, unsigned AddrSpace, Value *ArraySize,
const Twine &Name, BasicBlock *InsertAtEnd);
- AllocaInst(Type *Ty, const Twine &Name, Instruction *InsertBefore = nullptr);
- AllocaInst(Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd);
+ AllocaInst(Type *Ty, unsigned AddrSpace,
+ const Twine &Name, Instruction *InsertBefore = nullptr);
+ AllocaInst(Type *Ty, unsigned AddrSpace,
+ const Twine &Name, BasicBlock *InsertAtEnd);
- AllocaInst(Type *Ty, Value *ArraySize, unsigned Align,
+ AllocaInst(Type *Ty, unsigned AddrSpace, Value *ArraySize, unsigned Align,
const Twine &Name = "", Instruction *InsertBefore = nullptr);
- AllocaInst(Type *Ty, Value *ArraySize, unsigned Align,
+ AllocaInst(Type *Ty, unsigned AddrSpace, Value *ArraySize, unsigned Align,
const Twine &Name, BasicBlock *InsertAtEnd);
- // Out of line virtual method, so the vtable, etc. has a home.
- ~AllocaInst() override;
-
/// Return true if there is an allocation size parameter to the allocation
/// instruction that is not 1.
bool isArrayAllocation() const;
@@ -140,10 +140,10 @@ public:
}
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const Instruction *I) {
+ static bool classof(const Instruction *I) {
return (I->getOpcode() == Instruction::Alloca);
}
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return isa<Instruction>(V) && classof(cast<Instruction>(V));
}
@@ -190,17 +190,16 @@ public:
LoadInst(Value *Ptr, const Twine &NameStr, bool isVolatile,
unsigned Align, BasicBlock *InsertAtEnd);
LoadInst(Value *Ptr, const Twine &NameStr, bool isVolatile, unsigned Align,
- AtomicOrdering Order, SynchronizationScope SynchScope = CrossThread,
+ AtomicOrdering Order, SyncScope::ID SSID = SyncScope::System,
Instruction *InsertBefore = nullptr)
: LoadInst(cast<PointerType>(Ptr->getType())->getElementType(), Ptr,
- NameStr, isVolatile, Align, Order, SynchScope, InsertBefore) {}
+ NameStr, isVolatile, Align, Order, SSID, InsertBefore) {}
LoadInst(Type *Ty, Value *Ptr, const Twine &NameStr, bool isVolatile,
unsigned Align, AtomicOrdering Order,
- SynchronizationScope SynchScope = CrossThread,
+ SyncScope::ID SSID = SyncScope::System,
Instruction *InsertBefore = nullptr);
LoadInst(Value *Ptr, const Twine &NameStr, bool isVolatile,
- unsigned Align, AtomicOrdering Order,
- SynchronizationScope SynchScope,
+ unsigned Align, AtomicOrdering Order, SyncScope::ID SSID,
BasicBlock *InsertAtEnd);
LoadInst(Value *Ptr, const char *NameStr, Instruction *InsertBefore);
LoadInst(Value *Ptr, const char *NameStr, BasicBlock *InsertAtEnd);
@@ -230,37 +229,38 @@ public:
void setAlignment(unsigned Align);
- /// Returns the ordering effect of this fence.
+ /// Returns the ordering constraint of this load instruction.
AtomicOrdering getOrdering() const {
return AtomicOrdering((getSubclassDataFromInstruction() >> 7) & 7);
}
- /// Set the ordering constraint on this load. May not be Release or
- /// AcquireRelease.
+ /// 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));
}
- SynchronizationScope getSynchScope() const {
- return SynchronizationScope((getSubclassDataFromInstruction() >> 6) & 1);
+ /// Returns the synchronization scope ID of this load instruction.
+ SyncScope::ID getSyncScopeID() const {
+ return SSID;
}
- /// Specify whether this load is ordered with respect to all
- /// concurrently executing threads, or only with respect to signal handlers
- /// executing in the same thread.
- void setSynchScope(SynchronizationScope xthread) {
- setInstructionSubclassData((getSubclassDataFromInstruction() & ~(1 << 6)) |
- (xthread << 6));
+ /// Sets the synchronization scope ID of this load instruction.
+ void setSyncScopeID(SyncScope::ID SSID) {
+ this->SSID = SSID;
}
+ /// Sets the ordering constraint and the synchronization scope ID of this load
+ /// instruction.
void setAtomic(AtomicOrdering Ordering,
- SynchronizationScope SynchScope = CrossThread) {
+ SyncScope::ID SSID = SyncScope::System) {
setOrdering(Ordering);
- setSynchScope(SynchScope);
+ setSyncScopeID(SSID);
}
bool isSimple() const { return !isAtomic() && !isVolatile(); }
+
bool isUnordered() const {
return (getOrdering() == AtomicOrdering::NotAtomic ||
getOrdering() == AtomicOrdering::Unordered) &&
@@ -270,17 +270,18 @@ public:
Value *getPointerOperand() { return getOperand(0); }
const Value *getPointerOperand() const { return getOperand(0); }
static unsigned getPointerOperandIndex() { return 0U; }
+ Type *getPointerOperandType() const { return getPointerOperand()->getType(); }
/// Returns the address space of the pointer operand.
unsigned getPointerAddressSpace() const {
- return getPointerOperand()->getType()->getPointerAddressSpace();
+ return getPointerOperandType()->getPointerAddressSpace();
}
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const Instruction *I) {
+ static bool classof(const Instruction *I) {
return I->getOpcode() == Instruction::Load;
}
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return isa<Instruction>(V) && classof(cast<Instruction>(V));
}
@@ -290,6 +291,11 @@ private:
void setInstructionSubclassData(unsigned short D) {
Instruction::setInstructionSubclassData(D);
}
+
+ /// The synchronization scope ID of this load instruction. Not quite enough
+ /// room in SubClassData for everything, so synchronization scope ID gets its
+ /// own field.
+ SyncScope::ID SSID;
};
//===----------------------------------------------------------------------===//
@@ -318,11 +324,10 @@ public:
unsigned Align, BasicBlock *InsertAtEnd);
StoreInst(Value *Val, Value *Ptr, bool isVolatile,
unsigned Align, AtomicOrdering Order,
- SynchronizationScope SynchScope = CrossThread,
+ SyncScope::ID SSID = SyncScope::System,
Instruction *InsertBefore = nullptr);
StoreInst(Value *Val, Value *Ptr, bool isVolatile,
- unsigned Align, AtomicOrdering Order,
- SynchronizationScope SynchScope,
+ unsigned Align, AtomicOrdering Order, SyncScope::ID SSID,
BasicBlock *InsertAtEnd);
// allocate space for exactly two operands
@@ -330,8 +335,6 @@ public:
return User::operator new(s, 2);
}
- void *operator new(size_t, unsigned) = delete;
-
/// Return true if this is a store to a volatile memory location.
bool isVolatile() const { return getSubclassDataFromInstruction() & 1; }
@@ -351,37 +354,38 @@ public:
void setAlignment(unsigned Align);
- /// Returns the ordering effect of this store.
+ /// Returns the ordering constraint of this store instruction.
AtomicOrdering getOrdering() const {
return AtomicOrdering((getSubclassDataFromInstruction() >> 7) & 7);
}
- /// Set the ordering constraint on this store. May not be Acquire or
- /// AcquireRelease.
+ /// 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));
}
- SynchronizationScope getSynchScope() const {
- return SynchronizationScope((getSubclassDataFromInstruction() >> 6) & 1);
+ /// Returns the synchronization scope ID of this store instruction.
+ SyncScope::ID getSyncScopeID() const {
+ return SSID;
}
- /// Specify whether this store instruction is ordered with respect to all
- /// concurrently executing threads, or only with respect to signal handlers
- /// executing in the same thread.
- void setSynchScope(SynchronizationScope xthread) {
- setInstructionSubclassData((getSubclassDataFromInstruction() & ~(1 << 6)) |
- (xthread << 6));
+ /// Sets the synchronization scope ID of this store instruction.
+ void setSyncScopeID(SyncScope::ID SSID) {
+ this->SSID = SSID;
}
+ /// Sets the ordering constraint and the synchronization scope ID of this
+ /// store instruction.
void setAtomic(AtomicOrdering Ordering,
- SynchronizationScope SynchScope = CrossThread) {
+ SyncScope::ID SSID = SyncScope::System) {
setOrdering(Ordering);
- setSynchScope(SynchScope);
+ setSyncScopeID(SSID);
}
bool isSimple() const { return !isAtomic() && !isVolatile(); }
+
bool isUnordered() const {
return (getOrdering() == AtomicOrdering::NotAtomic ||
getOrdering() == AtomicOrdering::Unordered) &&
@@ -394,17 +398,18 @@ public:
Value *getPointerOperand() { return getOperand(1); }
const Value *getPointerOperand() const { return getOperand(1); }
static unsigned getPointerOperandIndex() { return 1U; }
+ Type *getPointerOperandType() const { return getPointerOperand()->getType(); }
/// Returns the address space of the pointer operand.
unsigned getPointerAddressSpace() const {
- return getPointerOperand()->getType()->getPointerAddressSpace();
+ return getPointerOperandType()->getPointerAddressSpace();
}
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const Instruction *I) {
+ static bool classof(const Instruction *I) {
return I->getOpcode() == Instruction::Store;
}
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return isa<Instruction>(V) && classof(cast<Instruction>(V));
}
@@ -414,6 +419,11 @@ private:
void setInstructionSubclassData(unsigned short D) {
Instruction::setInstructionSubclassData(D);
}
+
+ /// The synchronization scope ID of this store instruction. Not quite enough
+ /// room in SubClassData for everything, so synchronization scope ID gets its
+ /// own field.
+ SyncScope::ID SSID;
};
template <>
@@ -428,7 +438,7 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(StoreInst, Value)
/// An instruction for ordering other memory operations.
class FenceInst : public Instruction {
- void Init(AtomicOrdering Ordering, SynchronizationScope SynchScope);
+ void Init(AtomicOrdering Ordering, SyncScope::ID SSID);
protected:
// Note: Instruction needs to be a friend here to call cloneImpl.
@@ -440,10 +450,9 @@ public:
// Ordering may only be Acquire, Release, AcquireRelease, or
// SequentiallyConsistent.
FenceInst(LLVMContext &C, AtomicOrdering Ordering,
- SynchronizationScope SynchScope = CrossThread,
+ SyncScope::ID SSID = SyncScope::System,
Instruction *InsertBefore = nullptr);
- FenceInst(LLVMContext &C, AtomicOrdering Ordering,
- SynchronizationScope SynchScope,
+ FenceInst(LLVMContext &C, AtomicOrdering Ordering, SyncScope::ID SSID,
BasicBlock *InsertAtEnd);
// allocate space for exactly zero operands
@@ -451,37 +460,33 @@ public:
return User::operator new(s, 0);
}
- void *operator new(size_t, unsigned) = delete;
-
- /// Returns the ordering effect of this fence.
+ /// Returns the ordering constraint of this fence instruction.
AtomicOrdering getOrdering() const {
return AtomicOrdering(getSubclassDataFromInstruction() >> 1);
}
- /// Set the ordering constraint on this fence. May only be Acquire, Release,
- /// AcquireRelease, or SequentiallyConsistent.
+ /// 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));
}
- SynchronizationScope getSynchScope() const {
- return SynchronizationScope(getSubclassDataFromInstruction() & 1);
+ /// Returns the synchronization scope ID of this fence instruction.
+ SyncScope::ID getSyncScopeID() const {
+ return SSID;
}
- /// Specify whether this fence orders other operations with respect to all
- /// concurrently executing threads, or only with respect to signal handlers
- /// executing in the same thread.
- void setSynchScope(SynchronizationScope xthread) {
- setInstructionSubclassData((getSubclassDataFromInstruction() & ~1) |
- xthread);
+ /// Sets the synchronization scope ID of this fence instruction.
+ void setSyncScopeID(SyncScope::ID SSID) {
+ this->SSID = SSID;
}
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const Instruction *I) {
+ static bool classof(const Instruction *I) {
return I->getOpcode() == Instruction::Fence;
}
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return isa<Instruction>(V) && classof(cast<Instruction>(V));
}
@@ -491,6 +496,11 @@ private:
void setInstructionSubclassData(unsigned short D) {
Instruction::setInstructionSubclassData(D);
}
+
+ /// The synchronization scope ID of this fence instruction. Not quite enough
+ /// room in SubClassData for everything, so synchronization scope ID gets its
+ /// own field.
+ SyncScope::ID SSID;
};
//===----------------------------------------------------------------------===//
@@ -504,7 +514,7 @@ private:
class AtomicCmpXchgInst : public Instruction {
void Init(Value *Ptr, Value *Cmp, Value *NewVal,
AtomicOrdering SuccessOrdering, AtomicOrdering FailureOrdering,
- SynchronizationScope SynchScope);
+ SyncScope::ID SSID);
protected:
// Note: Instruction needs to be a friend here to call cloneImpl.
@@ -516,21 +526,17 @@ public:
AtomicCmpXchgInst(Value *Ptr, Value *Cmp, Value *NewVal,
AtomicOrdering SuccessOrdering,
AtomicOrdering FailureOrdering,
- SynchronizationScope SynchScope,
- Instruction *InsertBefore = nullptr);
+ SyncScope::ID SSID, Instruction *InsertBefore = nullptr);
AtomicCmpXchgInst(Value *Ptr, Value *Cmp, Value *NewVal,
AtomicOrdering SuccessOrdering,
AtomicOrdering FailureOrdering,
- SynchronizationScope SynchScope,
- BasicBlock *InsertAtEnd);
+ SyncScope::ID SSID, 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, unsigned) = delete;
-
/// Return true if this is a cmpxchg from a volatile memory
/// location.
///
@@ -558,7 +564,12 @@ public:
/// Transparently provide more efficient getOperand methods.
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
- /// Set the ordering constraint on this cmpxchg.
+ /// Returns the success ordering constraint of this cmpxchg instruction.
+ AtomicOrdering getSuccessOrdering() const {
+ return AtomicOrdering((getSubclassDataFromInstruction() >> 2) & 7);
+ }
+
+ /// Sets the success ordering constraint of this cmpxchg instruction.
void setSuccessOrdering(AtomicOrdering Ordering) {
assert(Ordering != AtomicOrdering::NotAtomic &&
"CmpXchg instructions can only be atomic.");
@@ -566,6 +577,12 @@ public:
((unsigned)Ordering << 2));
}
+ /// Returns the failure ordering constraint of this cmpxchg instruction.
+ AtomicOrdering getFailureOrdering() const {
+ return AtomicOrdering((getSubclassDataFromInstruction() >> 5) & 7);
+ }
+
+ /// Sets the failure ordering constraint of this cmpxchg instruction.
void setFailureOrdering(AtomicOrdering Ordering) {
assert(Ordering != AtomicOrdering::NotAtomic &&
"CmpXchg instructions can only be atomic.");
@@ -573,28 +590,14 @@ public:
((unsigned)Ordering << 5));
}
- /// Specify whether this cmpxchg is atomic and orders other operations with
- /// respect to all concurrently executing threads, or only with respect to
- /// signal handlers executing in the same thread.
- void setSynchScope(SynchronizationScope SynchScope) {
- setInstructionSubclassData((getSubclassDataFromInstruction() & ~2) |
- (SynchScope << 1));
- }
-
- /// Returns the ordering constraint on this cmpxchg.
- AtomicOrdering getSuccessOrdering() const {
- return AtomicOrdering((getSubclassDataFromInstruction() >> 2) & 7);
- }
-
- /// Returns the ordering constraint on this cmpxchg.
- AtomicOrdering getFailureOrdering() const {
- return AtomicOrdering((getSubclassDataFromInstruction() >> 5) & 7);
+ /// Returns the synchronization scope ID of this cmpxchg instruction.
+ SyncScope::ID getSyncScopeID() const {
+ return SSID;
}
- /// Returns whether this cmpxchg is atomic between threads or only within a
- /// single thread.
- SynchronizationScope getSynchScope() const {
- return SynchronizationScope((getSubclassDataFromInstruction() & 2) >> 1);
+ /// Sets the synchronization scope ID of this cmpxchg instruction.
+ void setSyncScopeID(SyncScope::ID SSID) {
+ this->SSID = SSID;
}
Value *getPointerOperand() { return getOperand(0); }
@@ -636,10 +639,10 @@ public:
}
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const Instruction *I) {
+ static bool classof(const Instruction *I) {
return I->getOpcode() == Instruction::AtomicCmpXchg;
}
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return isa<Instruction>(V) && classof(cast<Instruction>(V));
}
@@ -649,6 +652,11 @@ private:
void setInstructionSubclassData(unsigned short D) {
Instruction::setInstructionSubclassData(D);
}
+
+ /// The synchronization scope ID of this cmpxchg instruction. Not quite
+ /// enough room in SubClassData for everything, so synchronization scope ID
+ /// gets its own field.
+ SyncScope::ID SSID;
};
template <>
@@ -708,10 +716,10 @@ public:
};
AtomicRMWInst(BinOp Operation, Value *Ptr, Value *Val,
- AtomicOrdering Ordering, SynchronizationScope SynchScope,
+ AtomicOrdering Ordering, SyncScope::ID SSID,
Instruction *InsertBefore = nullptr);
AtomicRMWInst(BinOp Operation, Value *Ptr, Value *Val,
- AtomicOrdering Ordering, SynchronizationScope SynchScope,
+ AtomicOrdering Ordering, SyncScope::ID SSID,
BasicBlock *InsertAtEnd);
// allocate space for exactly two operands
@@ -719,8 +727,6 @@ public:
return User::operator new(s, 2);
}
- void *operator new(size_t, unsigned) = delete;
-
BinOp getOperation() const {
return static_cast<BinOp>(getSubclassDataFromInstruction() >> 5);
}
@@ -747,7 +753,12 @@ public:
/// Transparently provide more efficient getOperand methods.
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
- /// Set the ordering constraint on this RMW.
+ /// Returns the ordering constraint of this rmw instruction.
+ AtomicOrdering getOrdering() const {
+ return AtomicOrdering((getSubclassDataFromInstruction() >> 2) & 7);
+ }
+
+ /// Sets the ordering constraint of this rmw instruction.
void setOrdering(AtomicOrdering Ordering) {
assert(Ordering != AtomicOrdering::NotAtomic &&
"atomicrmw instructions can only be atomic.");
@@ -755,23 +766,14 @@ public:
((unsigned)Ordering << 2));
}
- /// Specify whether this RMW orders other operations with respect to all
- /// concurrently executing threads, or only with respect to signal handlers
- /// executing in the same thread.
- void setSynchScope(SynchronizationScope SynchScope) {
- setInstructionSubclassData((getSubclassDataFromInstruction() & ~2) |
- (SynchScope << 1));
+ /// Returns the synchronization scope ID of this rmw instruction.
+ SyncScope::ID getSyncScopeID() const {
+ return SSID;
}
- /// Returns the ordering constraint on this RMW.
- AtomicOrdering getOrdering() const {
- return AtomicOrdering((getSubclassDataFromInstruction() >> 2) & 7);
- }
-
- /// Returns whether this RMW is atomic between threads or only within a
- /// single thread.
- SynchronizationScope getSynchScope() const {
- return SynchronizationScope((getSubclassDataFromInstruction() & 2) >> 1);
+ /// Sets the synchronization scope ID of this rmw instruction.
+ void setSyncScopeID(SyncScope::ID SSID) {
+ this->SSID = SSID;
}
Value *getPointerOperand() { return getOperand(0); }
@@ -787,22 +789,27 @@ public:
}
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const Instruction *I) {
+ static bool classof(const Instruction *I) {
return I->getOpcode() == Instruction::AtomicRMW;
}
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return isa<Instruction>(V) && classof(cast<Instruction>(V));
}
private:
void Init(BinOp Operation, Value *Ptr, Value *Val,
- AtomicOrdering Ordering, SynchronizationScope SynchScope);
+ 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);
}
+
+ /// The synchronization scope ID of this rmw instruction. Not quite enough
+ /// room in SubClassData for everything, so synchronization scope ID gets its
+ /// own field.
+ SyncScope::ID SSID;
};
template <>
@@ -831,10 +838,7 @@ class GetElementPtrInst : public Instruction {
Type *SourceElementType;
Type *ResultElementType;
- void anchor() override;
-
GetElementPtrInst(const GetElementPtrInst &GEPI);
- void init(Value *Ptr, ArrayRef<Value *> IdxList, const Twine &NameStr);
/// Constructors - Create a getelementptr instruction with a base pointer an
/// list of indices. The first ctor can optionally insert before an existing
@@ -847,6 +851,8 @@ class GetElementPtrInst : public Instruction {
ArrayRef<Value *> IdxList, unsigned Values,
const Twine &NameStr, BasicBlock *InsertAtEnd);
+ void init(Value *Ptr, ArrayRef<Value *> IdxList, const Twine &NameStr);
+
protected:
// Note: Instruction needs to be a friend here to call cloneImpl.
friend class Instruction;
@@ -958,6 +964,14 @@ public:
inline op_iterator idx_end() { return op_end(); }
inline const_op_iterator idx_end() const { return op_end(); }
+ inline iterator_range<op_iterator> indices() {
+ return make_range(idx_begin(), idx_end());
+ }
+
+ inline iterator_range<const_op_iterator> indices() const {
+ return make_range(idx_begin(), idx_end());
+ }
+
Value *getPointerOperand() {
return getOperand(0);
}
@@ -1040,10 +1054,10 @@ public:
bool accumulateConstantOffset(const DataLayout &DL, APInt &Offset) const;
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const Instruction *I) {
+ static bool classof(const Instruction *I) {
return (I->getOpcode() == Instruction::GetElementPtr);
}
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return isa<Instruction>(V) && classof(cast<Instruction>(V));
}
};
@@ -1092,11 +1106,8 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(GetElementPtrInst, Value)
/// must be identical types.
/// Represent an integer comparison operator.
class ICmpInst: public CmpInst {
- void anchor() override;
-
void AssertOK() {
- assert(getPredicate() >= CmpInst::FIRST_ICMP_PREDICATE &&
- getPredicate() <= CmpInst::LAST_ICMP_PREDICATE &&
+ assert(isIntPredicate() &&
"Invalid ICmp predicate value");
assert(getOperand(0)->getType() == getOperand(1)->getType() &&
"Both operands to ICmp instruction are not of the same type!");
@@ -1220,10 +1231,10 @@ public:
}
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const Instruction *I) {
+ static bool classof(const Instruction *I) {
return I->getOpcode() == Instruction::ICmp;
}
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return isa<Instruction>(V) && classof(cast<Instruction>(V));
}
};
@@ -1237,6 +1248,15 @@ public:
/// vectors of floating point values. The operands must be identical types.
/// Represents a floating point comparison operator.
class FCmpInst: public CmpInst {
+ void AssertOK() {
+ assert(isFPPredicate() && "Invalid FCmp predicate value");
+ assert(getOperand(0)->getType() == getOperand(1)->getType() &&
+ "Both operands to FCmp instruction are not of the same type!");
+ // Check that the operands are the right type
+ assert(getOperand(0)->getType()->isFPOrFPVectorTy() &&
+ "Invalid operand types for FCmp instruction");
+ }
+
protected:
// Note: Instruction needs to be a friend here to call cloneImpl.
friend class Instruction;
@@ -1255,13 +1275,7 @@ public:
) : CmpInst(makeCmpResultType(LHS->getType()),
Instruction::FCmp, pred, LHS, RHS, NameStr,
InsertBefore) {
- assert(pred <= FCmpInst::LAST_FCMP_PREDICATE &&
- "Invalid FCmp predicate value");
- assert(getOperand(0)->getType() == getOperand(1)->getType() &&
- "Both operands to FCmp instruction are not of the same type!");
- // Check that the operands are the right type
- assert(getOperand(0)->getType()->isFPOrFPVectorTy() &&
- "Invalid operand types for FCmp instruction");
+ AssertOK();
}
/// Constructor with insert-at-end semantics.
@@ -1274,13 +1288,7 @@ public:
) : CmpInst(makeCmpResultType(LHS->getType()),
Instruction::FCmp, pred, LHS, RHS, NameStr,
&InsertAtEnd) {
- assert(pred <= FCmpInst::LAST_FCMP_PREDICATE &&
- "Invalid FCmp predicate value");
- assert(getOperand(0)->getType() == getOperand(1)->getType() &&
- "Both operands to FCmp instruction are not of the same type!");
- // Check that the operands are the right type
- assert(getOperand(0)->getType()->isFPOrFPVectorTy() &&
- "Invalid operand types for FCmp instruction");
+ AssertOK();
}
/// Constructor with no-insertion semantics
@@ -1291,13 +1299,7 @@ public:
const Twine &NameStr = "" ///< Name of the instruction
) : CmpInst(makeCmpResultType(LHS->getType()),
Instruction::FCmp, pred, LHS, RHS, NameStr) {
- assert(pred <= FCmpInst::LAST_FCMP_PREDICATE &&
- "Invalid FCmp predicate value");
- assert(getOperand(0)->getType() == getOperand(1)->getType() &&
- "Both operands to FCmp instruction are not of the same type!");
- // Check that the operands are the right type
- assert(getOperand(0)->getType()->isFPOrFPVectorTy() &&
- "Invalid operand types for FCmp instruction");
+ AssertOK();
}
/// @returns true if the predicate of this instruction is EQ or NE.
@@ -1336,10 +1338,10 @@ public:
}
/// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const Instruction *I) {
+ static bool classof(const Instruction *I) {
return I->getOpcode() == Instruction::FCmp;
}
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return isa<Instruction>(V) && classof(cast<Instruction>(V));
}
};
@@ -1354,7 +1356,7 @@ class CallInst : public Instruction,
public OperandBundleUser<CallInst, User::op_iterator> {
friend class OperandBundleUser<CallInst, User::op_iterator>;
- AttributeSet AttributeList; ///< parameter attributes for call
+ AttributeList Attrs; ///< parameter attributes for call
FunctionType *FTy;
CallInst(const CallInst &CI);
@@ -1406,8 +1408,6 @@ protected:
CallInst *cloneImpl() const;
public:
- ~CallInst() override;
-
static CallInst *Create(Value *Func, ArrayRef<Value *> Args,
ArrayRef<OperandBundleDef> Bundles = None,
const Twine &NameStr = "",
@@ -1633,11 +1633,11 @@ public:
/// Return the parameter attributes for this call.
///
- AttributeSet getAttributes() const { return AttributeList; }
+ AttributeList getAttributes() const { return Attrs; }
/// Set the parameter attributes for this call.
///
- void setAttributes(AttributeSet Attrs) { AttributeList = Attrs; }
+ void setAttributes(AttributeList A) { Attrs = A; }
/// adds the attribute to the list of attributes.
void addAttribute(unsigned i, Attribute::AttrKind Kind);
@@ -1645,12 +1645,24 @@ public:
/// adds the attribute to the list of attributes.
void addAttribute(unsigned i, Attribute Attr);
+ /// Adds the attribute to the indicated argument
+ void addParamAttr(unsigned ArgNo, Attribute::AttrKind Kind);
+
+ /// Adds the attribute to the indicated argument
+ void addParamAttr(unsigned ArgNo, Attribute Attr);
+
/// removes the attribute from the list of attributes.
void removeAttribute(unsigned i, Attribute::AttrKind Kind);
/// removes the attribute from the list of attributes.
void removeAttribute(unsigned i, StringRef Kind);
+ /// Removes the attribute from the given argument
+ void removeParamAttr(unsigned ArgNo, Attribute::AttrKind Kind);
+
+ /// Removes the attribute from the given argument
+ void removeParamAttr(unsigned ArgNo, StringRef Kind);
+
/// adds the dereferenceable attribute to the list of attributes.
void addDereferenceableAttr(unsigned i, uint64_t Bytes);
@@ -1670,8 +1682,11 @@ public:
return hasFnAttrImpl(Kind);
}
- /// Determine whether the call or the callee has the given attributes.
- bool paramHasAttr(unsigned i, Attribute::AttrKind Kind) const;
+ /// Determine whether the return value has the given attribute.
+ bool hasRetAttr(Attribute::AttrKind Kind) const;
+
+ /// Determine whether the argument or parameter has the given attribute.
+ bool paramHasAttr(unsigned ArgNo, Attribute::AttrKind Kind) const;
/// Get the attribute of a given kind at a position.
Attribute getAttribute(unsigned i, Attribute::AttrKind Kind) const {
@@ -1683,6 +1698,18 @@ public:
return getAttributes().getAttribute(i, Kind);
}
+ /// Get the attribute of a given kind from a given arg
+ Attribute getParamAttr(unsigned ArgNo, Attribute::AttrKind Kind) const {
+ assert(ArgNo < getNumArgOperands() && "Out of bounds");
+ return getAttributes().getParamAttr(ArgNo, Kind);
+ }
+
+ /// Get the attribute of a given kind from a given arg
+ Attribute getParamAttr(unsigned ArgNo, StringRef Kind) const {
+ assert(ArgNo < getNumArgOperands() && "Out of bounds");
+ return getAttributes().getParamAttr(ArgNo, Kind);
+ }
+
/// Return true if the data operand at index \p i has the attribute \p
/// A.
///
@@ -1698,28 +1725,29 @@ public:
/// (\p i - 1) in the operand list.
bool dataOperandHasImpliedAttr(unsigned i, Attribute::AttrKind Kind) const;
+ /// Extract the alignment of the return value.
+ unsigned getRetAlignment() const { return Attrs.getRetAlignment(); }
+
/// Extract the alignment for a call or parameter (0=unknown).
- unsigned getParamAlignment(unsigned i) const {
- return AttributeList.getParamAlignment(i);
+ unsigned getParamAlignment(unsigned ArgNo) const {
+ return Attrs.getParamAlignment(ArgNo);
}
/// Extract the number of dereferenceable bytes for a call or
/// parameter (0=unknown).
uint64_t getDereferenceableBytes(unsigned i) const {
- return AttributeList.getDereferenceableBytes(i);
+ return Attrs.getDereferenceableBytes(i);
}
/// Extract the number of dereferenceable_or_null bytes for a call or
/// parameter (0=unknown).
uint64_t getDereferenceableOrNullBytes(unsigned i) const {
- return AttributeList.getDereferenceableOrNullBytes(i);
+ return Attrs.getDereferenceableOrNullBytes(i);
}
- /// @brief Determine if the parameter or return value is marked with NoAlias
- /// attribute.
- /// @param n The parameter to check. 1 is the first parameter, 0 is the return
- bool doesNotAlias(unsigned n) const {
- return AttributeList.hasAttribute(n, Attribute::NoAlias);
+ /// @brief Determine if the return value is marked with NoAlias attribute.
+ bool returnDoesNotAlias() const {
+ return Attrs.hasAttribute(AttributeList::ReturnIndex, Attribute::NoAlias);
}
/// Return true if the call should not be treated as a call to a
@@ -1732,7 +1760,7 @@ public:
/// Return true if the call should not be inlined.
bool isNoInline() const { return hasFnAttr(Attribute::NoInline); }
void setIsNoInline() {
- addAttribute(AttributeSet::FunctionIndex, Attribute::NoInline);
+ addAttribute(AttributeList::FunctionIndex, Attribute::NoInline);
}
/// Return true if the call can return twice
@@ -1740,7 +1768,7 @@ public:
return hasFnAttr(Attribute::ReturnsTwice);
}
void setCanReturnTwice() {
- addAttribute(AttributeSet::FunctionIndex, Attribute::ReturnsTwice);
+ addAttribute(AttributeList::FunctionIndex, Attribute::ReturnsTwice);
}
/// Determine if the call does not access memory.
@@ -1748,7 +1776,7 @@ public:
return hasFnAttr(Attribute::ReadNone);
}
void setDoesNotAccessMemory() {
- addAttribute(AttributeSet::FunctionIndex, Attribute::ReadNone);
+ addAttribute(AttributeList::FunctionIndex, Attribute::ReadNone);
}
/// Determine if the call does not access or only reads memory.
@@ -1756,7 +1784,7 @@ public:
return doesNotAccessMemory() || hasFnAttr(Attribute::ReadOnly);
}
void setOnlyReadsMemory() {
- addAttribute(AttributeSet::FunctionIndex, Attribute::ReadOnly);
+ addAttribute(AttributeList::FunctionIndex, Attribute::ReadOnly);
}
/// Determine if the call does not access or only writes memory.
@@ -1764,7 +1792,7 @@ public:
return doesNotAccessMemory() || hasFnAttr(Attribute::WriteOnly);
}
void setDoesNotReadMemory() {
- addAttribute(AttributeSet::FunctionIndex, Attribute::WriteOnly);
+ addAttribute(AttributeList::FunctionIndex, Attribute::WriteOnly);
}
/// @brief Determine if the call can access memmory only using pointers based
@@ -1773,34 +1801,34 @@ public:
return hasFnAttr(Attribute::ArgMemOnly);
}
void setOnlyAccessesArgMemory() {
- addAttribute(AttributeSet::FunctionIndex, Attribute::ArgMemOnly);
+ addAttribute(AttributeList::FunctionIndex, Attribute::ArgMemOnly);
}
/// Determine if the call cannot return.
bool doesNotReturn() const { return hasFnAttr(Attribute::NoReturn); }
void setDoesNotReturn() {
- addAttribute(AttributeSet::FunctionIndex, Attribute::NoReturn);
+ addAttribute(AttributeList::FunctionIndex, Attribute::NoReturn);
}
/// Determine if the call cannot unwind.
bool doesNotThrow() const { return hasFnAttr(Attribute::NoUnwind); }
void setDoesNotThrow() {
- addAttribute(AttributeSet::FunctionIndex, Attribute::NoUnwind);
+ addAttribute(AttributeList::FunctionIndex, Attribute::NoUnwind);
}
/// Determine if the call cannot be duplicated.
bool cannotDuplicate() const {return hasFnAttr(Attribute::NoDuplicate); }
void setCannotDuplicate() {
- addAttribute(AttributeSet::FunctionIndex, Attribute::NoDuplicate);
+ addAttribute(AttributeList::FunctionIndex, Attribute::NoDuplicate);
}
/// Determine if the call is convergent
bool isConvergent() const { return hasFnAttr(Attribute::Convergent); }
void setConvergent() {
- addAttribute(AttributeSet::FunctionIndex, Attribute::Convergent);
+ addAttribute(AttributeList::FunctionIndex, Attribute::Convergent);
}
void setNotConvergent() {
- removeAttribute(AttributeSet::FunctionIndex, Attribute::Convergent);
+ removeAttribute(AttributeList::FunctionIndex, Attribute::Convergent);
}
/// Determine if the call returns a structure through first
@@ -1810,12 +1838,12 @@ public:
return false;
// Be friendly and also check the callee.
- return paramHasAttr(1, Attribute::StructRet);
+ return paramHasAttr(0, Attribute::StructRet);
}
/// Determine if any call argument is an aggregate passed by value.
bool hasByValArgument() const {
- return AttributeList.hasAttrSomewhere(Attribute::ByVal);
+ return Attrs.hasAttrSomewhere(Attribute::ByVal);
}
/// Return the function called, or null if this is an
@@ -1849,16 +1877,16 @@ public:
}
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const Instruction *I) {
+ static bool classof(const Instruction *I) {
return I->getOpcode() == Instruction::Call;
}
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return isa<Instruction>(V) && classof(cast<Instruction>(V));
}
private:
template <typename AttrKind> bool hasFnAttrImpl(AttrKind Kind) const {
- if (AttributeList.hasAttribute(AttributeSet::FunctionIndex, Kind))
+ if (Attrs.hasAttribute(AttributeList::FunctionIndex, Kind))
return true;
// Operand bundles override attributes on the called function, but don't
@@ -1867,7 +1895,8 @@ private:
return false;
if (const Function *F = getCalledFunction())
- return F->getAttributes().hasAttribute(AttributeSet::FunctionIndex, Kind);
+ return F->getAttributes().hasAttribute(AttributeList::FunctionIndex,
+ Kind);
return false;
}
@@ -1986,10 +2015,10 @@ public:
}
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const Instruction *I) {
+ static bool classof(const Instruction *I) {
return I->getOpcode() == Instruction::Select;
}
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return isa<Instruction>(V) && classof(cast<Instruction>(V));
}
};
@@ -2032,10 +2061,10 @@ public:
static unsigned getPointerOperandIndex() { return 0U; }
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const Instruction *I) {
+ static bool classof(const Instruction *I) {
return I->getOpcode() == VAArg;
}
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return isa<Instruction>(V) && classof(cast<Instruction>(V));
}
};
@@ -2089,10 +2118,10 @@ public:
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const Instruction *I) {
+ static bool classof(const Instruction *I) {
return I->getOpcode() == Instruction::ExtractElement;
}
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return isa<Instruction>(V) && classof(cast<Instruction>(V));
}
};
@@ -2152,10 +2181,10 @@ public:
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const Instruction *I) {
+ static bool classof(const Instruction *I) {
return I->getOpcode() == Instruction::InsertElement;
}
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return isa<Instruction>(V) && classof(cast<Instruction>(V));
}
};
@@ -2237,11 +2266,24 @@ public:
return Mask;
}
+ /// Change values in a shuffle permute mask assuming the two vector operands
+ /// of length InVecNumElts have swapped position.
+ static void commuteShuffleMask(MutableArrayRef<int> Mask,
+ unsigned InVecNumElts) {
+ for (int &Idx : Mask) {
+ if (Idx == -1)
+ continue;
+ Idx = Idx < (int)InVecNumElts ? Idx + InVecNumElts : Idx - InVecNumElts;
+ assert(Idx >= 0 && Idx < (int)InVecNumElts * 2 &&
+ "shufflevector mask index out of range");
+ }
+ }
+
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const Instruction *I) {
+ static bool classof(const Instruction *I) {
return I->getOpcode() == Instruction::ShuffleVector;
}
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return isa<Instruction>(V) && classof(cast<Instruction>(V));
}
};
@@ -2264,6 +2306,7 @@ class ExtractValueInst : public UnaryInstruction {
SmallVector<unsigned, 4> Indices;
ExtractValueInst(const ExtractValueInst &EVI);
+
/// Constructors - Create a extractvalue instruction with a base aggregate
/// value and a list of indices. The first ctor can optionally insert before
/// an existing instruction, the second appends the new instruction to the
@@ -2276,9 +2319,6 @@ class ExtractValueInst : public UnaryInstruction {
ArrayRef<unsigned> Idxs,
const Twine &NameStr, BasicBlock *InsertAtEnd);
- // allocate space for exactly one operand
- void *operator new(size_t s) { return User::operator new(s, 1); }
-
void init(ArrayRef<unsigned> Idxs, const Twine &NameStr);
protected:
@@ -2309,7 +2349,8 @@ public:
/// Null is returned if the indices are invalid for the specified type.
static Type *getIndexedType(Type *Agg, ArrayRef<unsigned> Idxs);
- typedef const unsigned* idx_iterator;
+ using idx_iterator = const unsigned*;
+
inline idx_iterator idx_begin() const { return Indices.begin(); }
inline idx_iterator idx_end() const { return Indices.end(); }
inline iterator_range<idx_iterator> indices() const {
@@ -2339,10 +2380,10 @@ public:
}
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const Instruction *I) {
+ static bool classof(const Instruction *I) {
return I->getOpcode() == Instruction::ExtractValue;
}
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return isa<Instruction>(V) && classof(cast<Instruction>(V));
}
};
@@ -2412,8 +2453,6 @@ public:
return User::operator new(s, 2);
}
- void *operator new(size_t, unsigned) = delete;
-
static InsertValueInst *Create(Value *Agg, Value *Val,
ArrayRef<unsigned> Idxs,
const Twine &NameStr = "",
@@ -2431,7 +2470,8 @@ public:
/// Transparently provide more efficient getOperand methods.
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
- typedef const unsigned* idx_iterator;
+ using idx_iterator = const unsigned*;
+
inline idx_iterator idx_begin() const { return Indices.begin(); }
inline idx_iterator idx_end() const { return Indices.end(); }
inline iterator_range<idx_iterator> indices() const {
@@ -2471,10 +2511,10 @@ public:
}
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const Instruction *I) {
+ static bool classof(const Instruction *I) {
return I->getOpcode() == Instruction::InsertValue;
}
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return isa<Instruction>(V) && classof(cast<Instruction>(V));
}
};
@@ -2522,7 +2562,6 @@ class PHINode : public Instruction {
unsigned ReservedSpace;
PHINode(const PHINode &PN);
- // allocate space for exactly zero operands
explicit PHINode(Type *Ty, unsigned NumReservedValues,
const Twine &NameStr = "",
@@ -2541,12 +2580,6 @@ class PHINode : public Instruction {
allocHungoffUses(ReservedSpace);
}
- void *operator new(size_t s) {
- return User::operator new(s);
- }
-
- void anchor() override;
-
protected:
// Note: Instruction needs to be a friend here to call cloneImpl.
friend class Instruction;
@@ -2561,8 +2594,6 @@ protected:
}
public:
- void *operator new(size_t, unsigned) = delete;
-
/// Constructors - NumReservedValues is a hint for the number of incoming
/// edges that this phi node will have (use 0 if you really have no idea).
static PHINode *Create(Type *Ty, unsigned NumReservedValues,
@@ -2582,8 +2613,8 @@ public:
// Block iterator interface. This provides access to the list of incoming
// basic blocks, which parallels the list of incoming values.
- typedef BasicBlock **block_iterator;
- typedef BasicBlock * const *const_block_iterator;
+ using block_iterator = BasicBlock **;
+ using const_block_iterator = BasicBlock * const *;
block_iterator block_begin() {
Use::UserRef *ref =
@@ -2632,9 +2663,11 @@ public:
"All operands to PHI node must be the same type as the PHI node!");
setOperand(i, V);
}
+
static unsigned getOperandNumForIncomingValue(unsigned i) {
return i;
}
+
static unsigned getIncomingValueNumForOperand(unsigned i) {
return i;
}
@@ -2718,10 +2751,10 @@ public:
bool hasConstantOrUndefValue() const;
/// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const Instruction *I) {
+ static bool classof(const Instruction *I) {
return I->getOpcode() == Instruction::PHI;
}
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return isa<Instruction>(V) && classof(cast<Instruction>(V));
}
@@ -2778,8 +2811,6 @@ protected:
LandingPadInst *cloneImpl() const;
public:
- void *operator new(size_t, unsigned) = delete;
-
/// Constructors - NumReservedClauses is a hint for the number of incoming
/// clauses that this landingpad will have (use 0 if you really have no idea).
static LandingPadInst *Create(Type *RetTy, unsigned NumReservedClauses,
@@ -2829,10 +2860,10 @@ public:
void reserveClauses(unsigned Size) { growOperands(Size); }
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const Instruction *I) {
+ static bool classof(const Instruction *I) {
return I->getOpcode() == Instruction::LandingPad;
}
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return isa<Instruction>(V) && classof(cast<Instruction>(V));
}
};
@@ -2878,8 +2909,6 @@ protected:
ReturnInst *cloneImpl() const;
public:
- ~ReturnInst() override;
-
static ReturnInst* Create(LLVMContext &C, Value *retVal = nullptr,
Instruction *InsertBefore = nullptr) {
return new(!!retVal) ReturnInst(C, retVal, InsertBefore);
@@ -2905,17 +2934,23 @@ public:
unsigned getNumSuccessors() const { return 0; }
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const Instruction *I) {
+ static bool classof(const Instruction *I) {
return (I->getOpcode() == Instruction::Ret);
}
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return isa<Instruction>(V) && classof(cast<Instruction>(V));
}
private:
- BasicBlock *getSuccessorV(unsigned idx) const override;
- unsigned getNumSuccessorsV() const override;
- void setSuccessorV(unsigned idx, BasicBlock *B) override;
+ friend TerminatorInst;
+
+ BasicBlock *getSuccessor(unsigned idx) const {
+ llvm_unreachable("ReturnInst has no successors!");
+ }
+
+ void setSuccessor(unsigned idx, BasicBlock *B) {
+ llvm_unreachable("ReturnInst has no successors!");
+ }
};
template <>
@@ -3015,17 +3050,12 @@ public:
void swapSuccessors();
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const Instruction *I) {
+ static bool classof(const Instruction *I) {
return (I->getOpcode() == Instruction::Br);
}
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return isa<Instruction>(V) && classof(cast<Instruction>(V));
}
-
-private:
- BasicBlock *getSuccessorV(unsigned idx) const override;
- unsigned getNumSuccessorsV() const override;
- void setSuccessorV(unsigned idx, BasicBlock *B) override;
};
template <>
@@ -3079,47 +3109,44 @@ protected:
SwitchInst *cloneImpl() const;
public:
- void *operator new(size_t, unsigned) = delete;
-
// -2
static const unsigned DefaultPseudoIndex = static_cast<unsigned>(~0L-1);
- template <class SwitchInstTy, class ConstantIntTy, class BasicBlockTy>
- class CaseIteratorT {
- protected:
- SwitchInstTy *SI;
- unsigned Index;
+ template <typename CaseHandleT> class CaseIteratorImpl;
- public:
- typedef CaseIteratorT<SwitchInstTy, ConstantIntTy, BasicBlockTy> Self;
+ /// A handle to a particular switch case. It exposes a convenient interface
+ /// to both the case value and the successor block.
+ ///
+ /// We define this as a template and instantiate it to form both a const and
+ /// non-const handle.
+ template <typename SwitchInstT, typename ConstantIntT, typename BasicBlockT>
+ class CaseHandleImpl {
+ // Directly befriend both const and non-const iterators.
+ friend class SwitchInst::CaseIteratorImpl<
+ CaseHandleImpl<SwitchInstT, ConstantIntT, BasicBlockT>>;
- /// Initializes case iterator for given SwitchInst and for given
- /// case number.
- CaseIteratorT(SwitchInstTy *SI, unsigned CaseNum) {
- this->SI = SI;
- Index = CaseNum;
- }
+ protected:
+ // Expose the switch type we're parameterized with to the iterator.
+ using SwitchInstType = SwitchInstT;
- /// Initializes case iterator for given SwitchInst and for given
- /// TerminatorInst's successor index.
- static Self fromSuccessorIndex(SwitchInstTy *SI, unsigned SuccessorIndex) {
- assert(SuccessorIndex < SI->getNumSuccessors() &&
- "Successor index # out of range!");
- return SuccessorIndex != 0 ?
- Self(SI, SuccessorIndex - 1) :
- Self(SI, DefaultPseudoIndex);
- }
+ SwitchInstT *SI;
+ ptrdiff_t Index;
+
+ CaseHandleImpl() = default;
+ CaseHandleImpl(SwitchInstT *SI, ptrdiff_t Index) : SI(SI), Index(Index) {}
+ public:
/// Resolves case value for current case.
- ConstantIntTy *getCaseValue() {
- assert(Index < SI->getNumCases() && "Index out the number of cases.");
- return reinterpret_cast<ConstantIntTy*>(SI->getOperand(2 + Index*2));
+ ConstantIntT *getCaseValue() const {
+ assert((unsigned)Index < SI->getNumCases() &&
+ "Index out the number of cases.");
+ return reinterpret_cast<ConstantIntT *>(SI->getOperand(2 + Index * 2));
}
/// Resolves successor for current case.
- BasicBlockTy *getCaseSuccessor() {
- assert((Index < SI->getNumCases() ||
- Index == DefaultPseudoIndex) &&
+ BasicBlockT *getCaseSuccessor() const {
+ assert(((unsigned)Index < SI->getNumCases() ||
+ (unsigned)Index == DefaultPseudoIndex) &&
"Index out the number of cases.");
return SI->getSuccessor(getSuccessorIndex());
}
@@ -3129,63 +3156,32 @@ public:
/// Returns TerminatorInst's successor index for current case successor.
unsigned getSuccessorIndex() const {
- assert((Index == DefaultPseudoIndex || Index < SI->getNumCases()) &&
+ assert(((unsigned)Index == DefaultPseudoIndex ||
+ (unsigned)Index < SI->getNumCases()) &&
"Index out the number of cases.");
- return Index != DefaultPseudoIndex ? Index + 1 : 0;
+ return (unsigned)Index != DefaultPseudoIndex ? Index + 1 : 0;
}
- Self operator++() {
- // Check index correctness after increment.
- // Note: Index == getNumCases() means end().
- assert(Index+1 <= SI->getNumCases() && "Index out the number of cases.");
- ++Index;
- return *this;
- }
- Self operator++(int) {
- Self tmp = *this;
- ++(*this);
- return tmp;
- }
- Self operator--() {
- // Check index correctness after decrement.
- // Note: Index == getNumCases() means end().
- // Also allow "-1" iterator here. That will became valid after ++.
- assert((Index == 0 || Index-1 <= SI->getNumCases()) &&
- "Index out the number of cases.");
- --Index;
- return *this;
- }
- Self operator--(int) {
- Self tmp = *this;
- --(*this);
- return tmp;
- }
- bool operator==(const Self& RHS) const {
- assert(RHS.SI == SI && "Incompatible operators.");
- return RHS.Index == Index;
- }
- bool operator!=(const Self& RHS) const {
- assert(RHS.SI == SI && "Incompatible operators.");
- return RHS.Index != Index;
- }
- Self &operator*() {
- return *this;
+ bool operator==(const CaseHandleImpl &RHS) const {
+ assert(SI == RHS.SI && "Incompatible operators.");
+ return Index == RHS.Index;
}
};
- typedef CaseIteratorT<const SwitchInst, const ConstantInt, const BasicBlock>
- ConstCaseIt;
+ using ConstCaseHandle =
+ CaseHandleImpl<const SwitchInst, const ConstantInt, const BasicBlock>;
- class CaseIt : public CaseIteratorT<SwitchInst, ConstantInt, BasicBlock> {
- typedef CaseIteratorT<SwitchInst, ConstantInt, BasicBlock> ParentTy;
+ class CaseHandle
+ : public CaseHandleImpl<SwitchInst, ConstantInt, BasicBlock> {
+ friend class SwitchInst::CaseIteratorImpl<CaseHandle>;
public:
- CaseIt(const ParentTy &Src) : ParentTy(Src) {}
- CaseIt(SwitchInst *SI, unsigned CaseNum) : ParentTy(SI, CaseNum) {}
+ CaseHandle(SwitchInst *SI, ptrdiff_t Index) : CaseHandleImpl(SI, Index) {}
/// Sets the new value for current case.
void setValue(ConstantInt *V) {
- assert(Index < SI->getNumCases() && "Index out the number of cases.");
+ assert((unsigned)Index < SI->getNumCases() &&
+ "Index out the number of cases.");
SI->setOperand(2 + Index*2, reinterpret_cast<Value*>(V));
}
@@ -3195,6 +3191,76 @@ public:
}
};
+ template <typename CaseHandleT>
+ class CaseIteratorImpl
+ : public iterator_facade_base<CaseIteratorImpl<CaseHandleT>,
+ std::random_access_iterator_tag,
+ CaseHandleT> {
+ using SwitchInstT = typename CaseHandleT::SwitchInstType;
+
+ CaseHandleT Case;
+
+ public:
+ /// Default constructed iterator is in an invalid state until assigned to
+ /// a case for a particular switch.
+ CaseIteratorImpl() = default;
+
+ /// Initializes case iterator for given SwitchInst and for given
+ /// case number.
+ CaseIteratorImpl(SwitchInstT *SI, unsigned CaseNum) : Case(SI, CaseNum) {}
+
+ /// Initializes case iterator for given SwitchInst and for given
+ /// TerminatorInst's successor index.
+ static CaseIteratorImpl fromSuccessorIndex(SwitchInstT *SI,
+ unsigned SuccessorIndex) {
+ assert(SuccessorIndex < SI->getNumSuccessors() &&
+ "Successor index # out of range!");
+ return SuccessorIndex != 0 ? CaseIteratorImpl(SI, SuccessorIndex - 1)
+ : CaseIteratorImpl(SI, DefaultPseudoIndex);
+ }
+
+ /// Support converting to the const variant. This will be a no-op for const
+ /// variant.
+ operator CaseIteratorImpl<ConstCaseHandle>() const {
+ return CaseIteratorImpl<ConstCaseHandle>(Case.SI, Case.Index);
+ }
+
+ CaseIteratorImpl &operator+=(ptrdiff_t N) {
+ // Check index correctness after addition.
+ // Note: Index == getNumCases() means end().
+ assert(Case.Index + N >= 0 &&
+ (unsigned)(Case.Index + N) <= Case.SI->getNumCases() &&
+ "Case.Index out the number of cases.");
+ Case.Index += N;
+ return *this;
+ }
+ CaseIteratorImpl &operator-=(ptrdiff_t N) {
+ // Check index correctness after subtraction.
+ // Note: Case.Index == getNumCases() means end().
+ assert(Case.Index - N >= 0 &&
+ (unsigned)(Case.Index - N) <= Case.SI->getNumCases() &&
+ "Case.Index out the number of cases.");
+ Case.Index -= N;
+ return *this;
+ }
+ ptrdiff_t operator-(const CaseIteratorImpl &RHS) const {
+ assert(Case.SI == RHS.Case.SI && "Incompatible operators.");
+ return Case.Index - RHS.Case.Index;
+ }
+ bool operator==(const CaseIteratorImpl &RHS) const {
+ return Case == RHS.Case;
+ }
+ bool operator<(const CaseIteratorImpl &RHS) const {
+ assert(Case.SI == RHS.Case.SI && "Incompatible operators.");
+ return Case.Index < RHS.Case.Index;
+ }
+ CaseHandleT &operator*() { return Case; }
+ const CaseHandleT &operator*() const { return Case; }
+ };
+
+ using CaseIt = CaseIteratorImpl<CaseHandle>;
+ using ConstCaseIt = CaseIteratorImpl<ConstCaseHandle>;
+
static SwitchInst *Create(Value *Value, BasicBlock *Default,
unsigned NumCases,
Instruction *InsertBefore = nullptr) {
@@ -3278,30 +3344,40 @@ public:
/// default case iterator to indicate that it is handled by the default
/// handler.
CaseIt findCaseValue(const ConstantInt *C) {
- for (CaseIt i = case_begin(), e = case_end(); i != e; ++i)
- if (i.getCaseValue() == C)
- return i;
+ CaseIt I = llvm::find_if(
+ cases(), [C](CaseHandle &Case) { return Case.getCaseValue() == C; });
+ if (I != case_end())
+ return I;
+
return case_default();
}
ConstCaseIt findCaseValue(const ConstantInt *C) const {
- for (ConstCaseIt i = case_begin(), e = case_end(); i != e; ++i)
- if (i.getCaseValue() == C)
- return i;
+ ConstCaseIt I = llvm::find_if(cases(), [C](ConstCaseHandle &Case) {
+ return Case.getCaseValue() == C;
+ });
+ if (I != case_end())
+ return I;
+
return case_default();
}
/// Finds the unique case value for a given successor. Returns null if the
/// successor is not found, not unique, or is the default case.
ConstantInt *findCaseDest(BasicBlock *BB) {
- if (BB == getDefaultDest()) return nullptr;
+ if (BB == getDefaultDest())
+ return nullptr;
ConstantInt *CI = nullptr;
- for (CaseIt i = case_begin(), e = case_end(); i != e; ++i) {
- if (i.getCaseSuccessor() == BB) {
- if (CI) return nullptr; // Multiple cases lead to BB.
- else CI = i.getCaseValue();
- }
+ for (auto Case : cases()) {
+ if (Case.getCaseSuccessor() != BB)
+ continue;
+
+ if (CI)
+ return nullptr; // Multiple cases lead to BB.
+
+ CI = Case.getCaseValue();
}
+
return CI;
}
@@ -3316,8 +3392,9 @@ public:
/// index idx and above.
/// Note:
/// This action invalidates iterators for all cases following the one removed,
- /// including the case_end() iterator.
- void removeCase(CaseIt i);
+ /// including the case_end() iterator. It returns an iterator for the next
+ /// case.
+ CaseIt removeCase(CaseIt I);
unsigned getNumSuccessors() const { return getNumOperands()/2; }
BasicBlock *getSuccessor(unsigned idx) const {
@@ -3330,17 +3407,12 @@ public:
}
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const Instruction *I) {
+ static bool classof(const Instruction *I) {
return I->getOpcode() == Instruction::Switch;
}
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return isa<Instruction>(V) && classof(cast<Instruction>(V));
}
-
-private:
- BasicBlock *getSuccessorV(unsigned idx) const override;
- unsigned getNumSuccessorsV() const override;
- void setSuccessorV(unsigned idx, BasicBlock *B) override;
};
template <>
@@ -3390,8 +3462,6 @@ protected:
IndirectBrInst *cloneImpl() const;
public:
- void *operator new(size_t, unsigned) = delete;
-
static IndirectBrInst *Create(Value *Address, unsigned NumDests,
Instruction *InsertBefore = nullptr) {
return new IndirectBrInst(Address, NumDests, InsertBefore);
@@ -3435,17 +3505,12 @@ public:
}
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const Instruction *I) {
+ static bool classof(const Instruction *I) {
return I->getOpcode() == Instruction::IndirectBr;
}
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return isa<Instruction>(V) && classof(cast<Instruction>(V));
}
-
-private:
- BasicBlock *getSuccessorV(unsigned idx) const override;
- unsigned getNumSuccessorsV() const override;
- void setSuccessorV(unsigned idx, BasicBlock *B) override;
};
template <>
@@ -3465,7 +3530,7 @@ class InvokeInst : public TerminatorInst,
public OperandBundleUser<InvokeInst, User::op_iterator> {
friend class OperandBundleUser<InvokeInst, User::op_iterator>;
- AttributeSet AttributeList;
+ AttributeList Attrs;
FunctionType *FTy;
InvokeInst(const InvokeInst &BI);
@@ -3566,6 +3631,7 @@ public:
return new (Values) InvokeInst(Func, IfNormal, IfException, Args, None,
Values, NameStr, InsertAtEnd);
}
+
static InvokeInst *Create(Value *Func, BasicBlock *IfNormal,
BasicBlock *IfException, ArrayRef<Value *> Args,
ArrayRef<OperandBundleDef> Bundles,
@@ -3669,11 +3735,11 @@ public:
/// Return the parameter attributes for this invoke.
///
- AttributeSet getAttributes() const { return AttributeList; }
+ AttributeList getAttributes() const { return Attrs; }
/// Set the parameter attributes for this invoke.
///
- void setAttributes(AttributeSet Attrs) { AttributeList = Attrs; }
+ void setAttributes(AttributeList A) { Attrs = A; }
/// adds the attribute to the list of attributes.
void addAttribute(unsigned i, Attribute::AttrKind Kind);
@@ -3681,12 +3747,18 @@ public:
/// adds the attribute to the list of attributes.
void addAttribute(unsigned i, Attribute Attr);
+ /// Adds the attribute to the indicated argument
+ void addParamAttr(unsigned ArgNo, Attribute::AttrKind Kind);
+
/// removes the attribute from the list of attributes.
void removeAttribute(unsigned i, Attribute::AttrKind Kind);
/// removes the attribute from the list of attributes.
void removeAttribute(unsigned i, StringRef Kind);
+ /// Removes the attribute from the given argument
+ void removeParamAttr(unsigned ArgNo, Attribute::AttrKind Kind);
+
/// adds the dereferenceable attribute to the list of attributes.
void addDereferenceableAttr(unsigned i, uint64_t Bytes);
@@ -3706,8 +3778,11 @@ public:
return hasFnAttrImpl(Kind);
}
- /// Determine whether the call or the callee has the given attributes.
- bool paramHasAttr(unsigned i, Attribute::AttrKind Kind) const;
+ /// Determine whether the return value has the given attribute.
+ bool hasRetAttr(Attribute::AttrKind Kind) const;
+
+ /// Determine whether the argument or parameter has the given attribute.
+ bool paramHasAttr(unsigned ArgNo, Attribute::AttrKind Kind) const;
/// Get the attribute of a given kind at a position.
Attribute getAttribute(unsigned i, Attribute::AttrKind Kind) const {
@@ -3735,28 +3810,29 @@ public:
/// (\p i - 1) in the operand list.
bool dataOperandHasImpliedAttr(unsigned i, Attribute::AttrKind Kind) const;
+ /// Extract the alignment of the return value.
+ unsigned getRetAlignment() const { return Attrs.getRetAlignment(); }
+
/// Extract the alignment for a call or parameter (0=unknown).
- unsigned getParamAlignment(unsigned i) const {
- return AttributeList.getParamAlignment(i);
+ unsigned getParamAlignment(unsigned ArgNo) const {
+ return Attrs.getParamAlignment(ArgNo);
}
/// Extract the number of dereferenceable bytes for a call or
/// parameter (0=unknown).
uint64_t getDereferenceableBytes(unsigned i) const {
- return AttributeList.getDereferenceableBytes(i);
+ return Attrs.getDereferenceableBytes(i);
}
/// Extract the number of dereferenceable_or_null bytes for a call or
/// parameter (0=unknown).
uint64_t getDereferenceableOrNullBytes(unsigned i) const {
- return AttributeList.getDereferenceableOrNullBytes(i);
+ return Attrs.getDereferenceableOrNullBytes(i);
}
- /// @brief Determine if the parameter or return value is marked with NoAlias
- /// attribute.
- /// @param n The parameter to check. 1 is the first parameter, 0 is the return
- bool doesNotAlias(unsigned n) const {
- return AttributeList.hasAttribute(n, Attribute::NoAlias);
+ /// @brief Determine if the return value is marked with NoAlias attribute.
+ bool returnDoesNotAlias() const {
+ return Attrs.hasAttribute(AttributeList::ReturnIndex, Attribute::NoAlias);
}
/// Return true if the call should not be treated as a call to a
@@ -3771,7 +3847,7 @@ public:
/// Return true if the call should not be inlined.
bool isNoInline() const { return hasFnAttr(Attribute::NoInline); }
void setIsNoInline() {
- addAttribute(AttributeSet::FunctionIndex, Attribute::NoInline);
+ addAttribute(AttributeList::FunctionIndex, Attribute::NoInline);
}
/// Determine if the call does not access memory.
@@ -3779,7 +3855,7 @@ public:
return hasFnAttr(Attribute::ReadNone);
}
void setDoesNotAccessMemory() {
- addAttribute(AttributeSet::FunctionIndex, Attribute::ReadNone);
+ addAttribute(AttributeList::FunctionIndex, Attribute::ReadNone);
}
/// Determine if the call does not access or only reads memory.
@@ -3787,7 +3863,7 @@ public:
return doesNotAccessMemory() || hasFnAttr(Attribute::ReadOnly);
}
void setOnlyReadsMemory() {
- addAttribute(AttributeSet::FunctionIndex, Attribute::ReadOnly);
+ addAttribute(AttributeList::FunctionIndex, Attribute::ReadOnly);
}
/// Determine if the call does not access or only writes memory.
@@ -3795,7 +3871,7 @@ public:
return doesNotAccessMemory() || hasFnAttr(Attribute::WriteOnly);
}
void setDoesNotReadMemory() {
- addAttribute(AttributeSet::FunctionIndex, Attribute::WriteOnly);
+ addAttribute(AttributeList::FunctionIndex, Attribute::WriteOnly);
}
/// @brief Determine if the call access memmory only using it's pointer
@@ -3804,34 +3880,34 @@ public:
return hasFnAttr(Attribute::ArgMemOnly);
}
void setOnlyAccessesArgMemory() {
- addAttribute(AttributeSet::FunctionIndex, Attribute::ArgMemOnly);
+ addAttribute(AttributeList::FunctionIndex, Attribute::ArgMemOnly);
}
/// Determine if the call cannot return.
bool doesNotReturn() const { return hasFnAttr(Attribute::NoReturn); }
void setDoesNotReturn() {
- addAttribute(AttributeSet::FunctionIndex, Attribute::NoReturn);
+ addAttribute(AttributeList::FunctionIndex, Attribute::NoReturn);
}
/// Determine if the call cannot unwind.
bool doesNotThrow() const { return hasFnAttr(Attribute::NoUnwind); }
void setDoesNotThrow() {
- addAttribute(AttributeSet::FunctionIndex, Attribute::NoUnwind);
+ addAttribute(AttributeList::FunctionIndex, Attribute::NoUnwind);
}
/// Determine if the invoke cannot be duplicated.
bool cannotDuplicate() const {return hasFnAttr(Attribute::NoDuplicate); }
void setCannotDuplicate() {
- addAttribute(AttributeSet::FunctionIndex, Attribute::NoDuplicate);
+ addAttribute(AttributeList::FunctionIndex, Attribute::NoDuplicate);
}
/// Determine if the invoke is convergent
bool isConvergent() const { return hasFnAttr(Attribute::Convergent); }
void setConvergent() {
- addAttribute(AttributeSet::FunctionIndex, Attribute::Convergent);
+ addAttribute(AttributeList::FunctionIndex, Attribute::Convergent);
}
void setNotConvergent() {
- removeAttribute(AttributeSet::FunctionIndex, Attribute::Convergent);
+ removeAttribute(AttributeList::FunctionIndex, Attribute::Convergent);
}
/// Determine if the call returns a structure through first
@@ -3841,12 +3917,12 @@ public:
return false;
// Be friendly and also check the callee.
- return paramHasAttr(1, Attribute::StructRet);
+ return paramHasAttr(0, Attribute::StructRet);
}
/// Determine if any call argument is an aggregate passed by value.
bool hasByValArgument() const {
- return AttributeList.hasAttrSomewhere(Attribute::ByVal);
+ return Attrs.hasAttrSomewhere(Attribute::ByVal);
}
/// Return the function called, or null if this is an
@@ -3905,20 +3981,16 @@ public:
unsigned getNumSuccessors() const { return 2; }
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const Instruction *I) {
+ static bool classof(const Instruction *I) {
return (I->getOpcode() == Instruction::Invoke);
}
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return isa<Instruction>(V) && classof(cast<Instruction>(V));
}
private:
- BasicBlock *getSuccessorV(unsigned idx) const override;
- unsigned getNumSuccessorsV() const override;
- void setSuccessorV(unsigned idx, BasicBlock *B) override;
-
template <typename AttrKind> bool hasFnAttrImpl(AttrKind Kind) const {
- if (AttributeList.hasAttribute(AttributeSet::FunctionIndex, Kind))
+ if (Attrs.hasAttribute(AttributeList::FunctionIndex, Kind))
return true;
// Operand bundles override attributes on the called function, but don't
@@ -3927,7 +3999,8 @@ private:
return false;
if (const Function *F = getCalledFunction())
- return F->getAttributes().hasAttribute(AttributeSet::FunctionIndex, Kind);
+ return F->getAttributes().hasAttribute(AttributeList::FunctionIndex,
+ Kind);
return false;
}
@@ -4003,17 +4076,23 @@ public:
unsigned getNumSuccessors() const { return 0; }
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const Instruction *I) {
+ static bool classof(const Instruction *I) {
return I->getOpcode() == Instruction::Resume;
}
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return isa<Instruction>(V) && classof(cast<Instruction>(V));
}
private:
- BasicBlock *getSuccessorV(unsigned idx) const override;
- unsigned getNumSuccessorsV() const override;
- void setSuccessorV(unsigned idx, BasicBlock *B) override;
+ friend TerminatorInst;
+
+ BasicBlock *getSuccessor(unsigned idx) const {
+ llvm_unreachable("ResumeInst has no successors!");
+ }
+
+ void setSuccessor(unsigned idx, BasicBlock *NewSucc) {
+ llvm_unreachable("ResumeInst has no successors!");
+ }
};
template <>
@@ -4065,8 +4144,6 @@ protected:
CatchSwitchInst *cloneImpl() const;
public:
- void *operator new(size_t, unsigned) = delete;
-
static CatchSwitchInst *Create(Value *ParentPad, BasicBlock *UnwindDest,
unsigned NumHandlers,
const Twine &NameStr = "",
@@ -4118,13 +4195,14 @@ private:
}
public:
- typedef std::pointer_to_unary_function<Value *, BasicBlock *> DerefFnTy;
- typedef mapped_iterator<op_iterator, DerefFnTy> handler_iterator;
- typedef iterator_range<handler_iterator> handler_range;
- typedef std::pointer_to_unary_function<const Value *, const BasicBlock *>
- ConstDerefFnTy;
- typedef mapped_iterator<const_op_iterator, ConstDerefFnTy> const_handler_iterator;
- typedef iterator_range<const_handler_iterator> const_handler_range;
+ using DerefFnTy = std::pointer_to_unary_function<Value *, BasicBlock *>;
+ using handler_iterator = mapped_iterator<op_iterator, DerefFnTy>;
+ using handler_range = iterator_range<handler_iterator>;
+ using ConstDerefFnTy =
+ std::pointer_to_unary_function<const Value *, const BasicBlock *>;
+ using const_handler_iterator =
+ mapped_iterator<const_op_iterator, ConstDerefFnTy>;
+ using const_handler_range = iterator_range<const_handler_iterator>;
/// Returns an iterator that points to the first handler in CatchSwitchInst.
handler_iterator handler_begin() {
@@ -4186,17 +4264,12 @@ public:
}
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const Instruction *I) {
+ static bool classof(const Instruction *I) {
return I->getOpcode() == Instruction::CatchSwitch;
}
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return isa<Instruction>(V) && classof(cast<Instruction>(V));
}
-
-private:
- BasicBlock *getSuccessorV(unsigned Idx) const override;
- unsigned getNumSuccessorsV() const override;
- void setSuccessorV(unsigned Idx, BasicBlock *B) override;
};
template <>
@@ -4237,10 +4310,10 @@ public:
}
/// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const Instruction *I) {
+ static bool classof(const Instruction *I) {
return I->getOpcode() == Instruction::CleanupPad;
}
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return isa<Instruction>(V) && classof(cast<Instruction>(V));
}
};
@@ -4287,10 +4360,10 @@ public:
}
/// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const Instruction *I) {
+ static bool classof(const Instruction *I) {
return I->getOpcode() == Instruction::CatchPad;
}
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return isa<Instruction>(V) && classof(cast<Instruction>(V));
}
};
@@ -4351,17 +4424,25 @@ public:
}
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const Instruction *I) {
+ static bool classof(const Instruction *I) {
return (I->getOpcode() == Instruction::CatchRet);
}
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return isa<Instruction>(V) && classof(cast<Instruction>(V));
}
private:
- BasicBlock *getSuccessorV(unsigned Idx) const override;
- unsigned getNumSuccessorsV() const override;
- void setSuccessorV(unsigned Idx, BasicBlock *B) override;
+ friend TerminatorInst;
+
+ BasicBlock *getSuccessor(unsigned Idx) const {
+ assert(Idx < getNumSuccessors() && "Successor # out of range for catchret!");
+ return getSuccessor();
+ }
+
+ void setSuccessor(unsigned Idx, BasicBlock *B) {
+ assert(Idx < getNumSuccessors() && "Successor # out of range for catchret!");
+ setSuccessor(B);
+ }
};
template <>
@@ -4439,17 +4520,25 @@ public:
}
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const Instruction *I) {
+ static bool classof(const Instruction *I) {
return (I->getOpcode() == Instruction::CleanupRet);
}
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return isa<Instruction>(V) && classof(cast<Instruction>(V));
}
private:
- BasicBlock *getSuccessorV(unsigned Idx) const override;
- unsigned getNumSuccessorsV() const override;
- void setSuccessorV(unsigned Idx, BasicBlock *B) override;
+ friend TerminatorInst;
+
+ BasicBlock *getSuccessor(unsigned Idx) const {
+ assert(Idx == 0);
+ return getUnwindDest();
+ }
+
+ void setSuccessor(unsigned Idx, BasicBlock *B) {
+ assert(Idx == 0);
+ setUnwindDest(B);
+ }
// Shadow Instruction::setInstructionSubclassData with a private forwarding
// method so that subclasses cannot accidentally use it.
@@ -4489,22 +4578,26 @@ public:
return User::operator new(s, 0);
}
- void *operator new(size_t, unsigned) = delete;
-
unsigned getNumSuccessors() const { return 0; }
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const Instruction *I) {
+ static bool classof(const Instruction *I) {
return I->getOpcode() == Instruction::Unreachable;
}
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return isa<Instruction>(V) && classof(cast<Instruction>(V));
}
private:
- BasicBlock *getSuccessorV(unsigned idx) const override;
- unsigned getNumSuccessorsV() const override;
- void setSuccessorV(unsigned idx, BasicBlock *B) override;
+ friend TerminatorInst;
+
+ BasicBlock *getSuccessor(unsigned idx) const {
+ llvm_unreachable("UnreachableInst has no successors!");
+ }
+
+ void setSuccessor(unsigned idx, BasicBlock *B) {
+ llvm_unreachable("UnreachableInst has no successors!");
+ }
};
//===----------------------------------------------------------------------===//
@@ -4538,10 +4631,10 @@ public:
);
/// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const Instruction *I) {
+ static bool classof(const Instruction *I) {
return I->getOpcode() == Trunc;
}
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return isa<Instruction>(V) && classof(cast<Instruction>(V));
}
};
@@ -4577,10 +4670,10 @@ public:
);
/// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const Instruction *I) {
+ static bool classof(const Instruction *I) {
return I->getOpcode() == ZExt;
}
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return isa<Instruction>(V) && classof(cast<Instruction>(V));
}
};
@@ -4616,10 +4709,10 @@ public:
);
/// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const Instruction *I) {
+ static bool classof(const Instruction *I) {
return I->getOpcode() == SExt;
}
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return isa<Instruction>(V) && classof(cast<Instruction>(V));
}
};
@@ -4655,10 +4748,10 @@ public:
);
/// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const Instruction *I) {
+ static bool classof(const Instruction *I) {
return I->getOpcode() == FPTrunc;
}
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return isa<Instruction>(V) && classof(cast<Instruction>(V));
}
};
@@ -4694,10 +4787,10 @@ public:
);
/// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const Instruction *I) {
+ static bool classof(const Instruction *I) {
return I->getOpcode() == FPExt;
}
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return isa<Instruction>(V) && classof(cast<Instruction>(V));
}
};
@@ -4733,10 +4826,10 @@ public:
);
/// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const Instruction *I) {
+ static bool classof(const Instruction *I) {
return I->getOpcode() == UIToFP;
}
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return isa<Instruction>(V) && classof(cast<Instruction>(V));
}
};
@@ -4772,10 +4865,10 @@ public:
);
/// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const Instruction *I) {
+ static bool classof(const Instruction *I) {
return I->getOpcode() == SIToFP;
}
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return isa<Instruction>(V) && classof(cast<Instruction>(V));
}
};
@@ -4811,10 +4904,10 @@ public:
);
/// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const Instruction *I) {
+ static bool classof(const Instruction *I) {
return I->getOpcode() == FPToUI;
}
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return isa<Instruction>(V) && classof(cast<Instruction>(V));
}
};
@@ -4850,10 +4943,10 @@ public:
);
/// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const Instruction *I) {
+ static bool classof(const Instruction *I) {
return I->getOpcode() == FPToSI;
}
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return isa<Instruction>(V) && classof(cast<Instruction>(V));
}
};
@@ -4893,10 +4986,10 @@ public:
}
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const Instruction *I) {
+ static bool classof(const Instruction *I) {
return I->getOpcode() == IntToPtr;
}
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return isa<Instruction>(V) && classof(cast<Instruction>(V));
}
};
@@ -4944,10 +5037,10 @@ public:
}
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const Instruction *I) {
+ static bool classof(const Instruction *I) {
return I->getOpcode() == PtrToInt;
}
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return isa<Instruction>(V) && classof(cast<Instruction>(V));
}
};
@@ -4983,10 +5076,10 @@ public:
);
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const Instruction *I) {
+ static bool classof(const Instruction *I) {
return I->getOpcode() == BitCast;
}
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return isa<Instruction>(V) && classof(cast<Instruction>(V));
}
};
@@ -5023,10 +5116,10 @@ public:
);
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const Instruction *I) {
+ static bool classof(const Instruction *I) {
return I->getOpcode() == AddrSpaceCast;
}
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return isa<Instruction>(V) && classof(cast<Instruction>(V));
}
diff --git a/contrib/llvm/include/llvm/IR/IntrinsicInst.h b/contrib/llvm/include/llvm/IR/IntrinsicInst.h
index b14a545..f55d17e 100644
--- a/contrib/llvm/include/llvm/IR/IntrinsicInst.h
+++ b/contrib/llvm/include/llvm/IR/IntrinsicInst.h
@@ -53,12 +53,12 @@ namespace llvm {
}
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const CallInst *I) {
+ static bool classof(const CallInst *I) {
if (const Function *CF = I->getCalledFunction())
return CF->isIntrinsic();
return false;
}
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return isa<CallInst>(V) && classof(cast<CallInst>(V));
}
};
@@ -72,7 +72,7 @@ namespace llvm {
Value *getVariableLocation(bool AllowNullOp = true) const;
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const IntrinsicInst *I) {
+ static bool classof(const IntrinsicInst *I) {
switch (I->getIntrinsicID()) {
case Intrinsic::dbg_declare:
case Intrinsic::dbg_value:
@@ -80,7 +80,7 @@ namespace llvm {
default: return false;
}
}
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
}
};
@@ -107,10 +107,10 @@ namespace llvm {
}
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const IntrinsicInst *I) {
+ static bool classof(const IntrinsicInst *I) {
return I->getIntrinsicID() == Intrinsic::dbg_declare;
}
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
}
};
@@ -144,9 +144,322 @@ namespace llvm {
}
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const IntrinsicInst *I) {
+ 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 is the common base class for constrained floating point intrinsics.
+ class ConstrainedFPIntrinsic : public IntrinsicInst {
+ public:
+ enum RoundingMode {
+ rmInvalid,
+ rmDynamic,
+ rmToNearest,
+ rmDownward,
+ rmUpward,
+ rmTowardZero
+ };
+
+ enum ExceptionBehavior {
+ ebInvalid,
+ ebIgnore,
+ ebMayTrap,
+ ebStrict
+ };
+
+ bool isUnaryOp() const;
+ RoundingMode getRoundingMode() const;
+ ExceptionBehavior getExceptionBehavior() 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_fadd:
+ case Intrinsic::experimental_constrained_fsub:
+ case Intrinsic::experimental_constrained_fmul:
+ case Intrinsic::experimental_constrained_fdiv:
+ case Intrinsic::experimental_constrained_frem:
+ case Intrinsic::experimental_constrained_sqrt:
+ case Intrinsic::experimental_constrained_pow:
+ case Intrinsic::experimental_constrained_powi:
+ case Intrinsic::experimental_constrained_sin:
+ case Intrinsic::experimental_constrained_cos:
+ case Intrinsic::experimental_constrained_exp:
+ case Intrinsic::experimental_constrained_exp2:
+ case Intrinsic::experimental_constrained_log:
+ case Intrinsic::experimental_constrained_log10:
+ case Intrinsic::experimental_constrained_log2:
+ case Intrinsic::experimental_constrained_rint:
+ case Intrinsic::experimental_constrained_nearbyint:
+ return true;
+ default: return false;
+ }
+ }
+ static bool classof(const Value *V) {
+ return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+ }
+ };
+
+ /// This class represents atomic memcpy intrinsic
+ /// TODO: Integrate this class into MemIntrinsic hierarchy; for now this is
+ /// C&P of all methods from that hierarchy
+ class ElementUnorderedAtomicMemCpyInst : public IntrinsicInst {
+ private:
+ enum { ARG_DEST = 0, ARG_SOURCE = 1, ARG_LENGTH = 2, ARG_ELEMENTSIZE = 3 };
+
+ 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); }
+
+ /// Return the arguments to the instruction.
+ Value *getRawSource() const {
+ return const_cast<Value *>(getArgOperand(ARG_SOURCE));
+ }
+ const Use &getRawSourceUse() const { return getArgOperandUse(ARG_SOURCE); }
+ Use &getRawSourceUse() { return getArgOperandUse(ARG_SOURCE); }
+
+ Value *getLength() const {
+ return const_cast<Value *>(getArgOperand(ARG_LENGTH));
+ }
+ const Use &getLengthUse() const { return getArgOperandUse(ARG_LENGTH); }
+ Use &getLengthUse() { return getArgOperandUse(ARG_LENGTH); }
+
+ bool isVolatile() const { return false; }
+
+ Value *getRawElementSizeInBytes() const {
+ return const_cast<Value *>(getArgOperand(ARG_ELEMENTSIZE));
+ }
+
+ ConstantInt *getElementSizeInBytesCst() const {
+ return cast<ConstantInt>(getRawElementSizeInBytes());
+ }
+
+ uint32_t getElementSizeInBytes() const {
+ return getElementSizeInBytesCst()->getZExtValue();
+ }
+
+ /// This is just like getRawDest, but it strips off any cast
+ /// instructions that feed it, giving the original input. The returned
+ /// value is guaranteed to be a pointer.
+ Value *getDest() const { return getRawDest()->stripPointerCasts(); }
+
+ /// 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 getDestAddressSpace() const {
+ return cast<PointerType>(getRawDest()->getType())->getAddressSpace();
+ }
+
+ unsigned getSourceAddressSpace() const {
+ return cast<PointerType>(getRawSource()->getType())->getAddressSpace();
+ }
+
+ /// 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);
+ }
+
+ void setSource(Value *Ptr) {
+ assert(getRawSource()->getType() == Ptr->getType() &&
+ "setSource called with pointer of wrong type!");
+ setArgOperand(ARG_SOURCE, Ptr);
+ }
+
+ void setLength(Value *L) {
+ assert(getLength()->getType() == L->getType() &&
+ "setLength called with value of wrong type!");
+ setArgOperand(ARG_LENGTH, L);
+ }
+
+ 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) {
+ return I->getIntrinsicID() == Intrinsic::memcpy_element_unordered_atomic;
+ }
+ static bool classof(const Value *V) {
+ return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+ }
+ };
+
+ class ElementUnorderedAtomicMemMoveInst : public IntrinsicInst {
+ private:
+ enum { ARG_DEST = 0, ARG_SOURCE = 1, ARG_LENGTH = 2, ARG_ELEMENTSIZE = 3 };
+
+ 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); }
+
+ /// Return the arguments to the instruction.
+ Value *getRawSource() const {
+ return const_cast<Value *>(getArgOperand(ARG_SOURCE));
+ }
+ const Use &getRawSourceUse() const { return getArgOperandUse(ARG_SOURCE); }
+ Use &getRawSourceUse() { return getArgOperandUse(ARG_SOURCE); }
+
+ Value *getLength() const {
+ return const_cast<Value *>(getArgOperand(ARG_LENGTH));
+ }
+ const Use &getLengthUse() const { return getArgOperandUse(ARG_LENGTH); }
+ Use &getLengthUse() { return getArgOperandUse(ARG_LENGTH); }
+
+ bool isVolatile() const { return false; }
+
+ Value *getRawElementSizeInBytes() const {
+ return const_cast<Value *>(getArgOperand(ARG_ELEMENTSIZE));
+ }
+
+ ConstantInt *getElementSizeInBytesCst() const {
+ return cast<ConstantInt>(getRawElementSizeInBytes());
+ }
+
+ uint32_t getElementSizeInBytes() const {
+ return getElementSizeInBytesCst()->getZExtValue();
+ }
+
+ /// This is just like getRawDest, but it strips off any cast
+ /// instructions that feed it, giving the original input. The returned
+ /// value is guaranteed to be a pointer.
+ Value *getDest() const { return getRawDest()->stripPointerCasts(); }
+
+ /// 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 getDestAddressSpace() const {
+ return cast<PointerType>(getRawDest()->getType())->getAddressSpace();
+ }
+
+ unsigned getSourceAddressSpace() const {
+ return cast<PointerType>(getRawSource()->getType())->getAddressSpace();
+ }
+
+ /// 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);
+ }
+
+ void setSource(Value *Ptr) {
+ assert(getRawSource()->getType() == Ptr->getType() &&
+ "setSource called with pointer of wrong type!");
+ setArgOperand(ARG_SOURCE, Ptr);
+ }
+
+ void setLength(Value *L) {
+ assert(getLength()->getType() == L->getType() &&
+ "setLength called with value of wrong type!");
+ setArgOperand(ARG_LENGTH, L);
+ }
+
+ void setElementSizeInBytes(Constant *V) {
+ assert(V->getType() == Type::getInt8Ty(getContext()) &&
+ "setElementSizeInBytes called with value of wrong type!");
+ setArgOperand(ARG_ELEMENTSIZE, V);
+ }
+
+ static inline bool classof(const IntrinsicInst *I) {
+ return I->getIntrinsicID() == Intrinsic::memmove_element_unordered_atomic;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+ }
+ };
+
+ /// This class represents atomic memset intrinsic
+ /// TODO: Integrate this class into MemIntrinsic hierarchy; for now this is
+ /// C&P of all methods from that hierarchy
+ class ElementUnorderedAtomicMemSetInst : public IntrinsicInst {
+ private:
+ enum { ARG_DEST = 0, ARG_VALUE = 1, ARG_LENGTH = 2, ARG_ELEMENTSIZE = 3 };
+
+ 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 *getValue() const { return const_cast<Value*>(getArgOperand(ARG_VALUE)); }
+ const Use &getValueUse() const { return getArgOperandUse(ARG_VALUE); }
+ Use &getValueUse() { return getArgOperandUse(ARG_VALUE); }
+
+ Value *getLength() const {
+ return const_cast<Value *>(getArgOperand(ARG_LENGTH));
+ }
+ const Use &getLengthUse() const { return getArgOperandUse(ARG_LENGTH); }
+ Use &getLengthUse() { return getArgOperandUse(ARG_LENGTH); }
+
+ bool isVolatile() const { return false; }
+
+ Value *getRawElementSizeInBytes() const {
+ return const_cast<Value *>(getArgOperand(ARG_ELEMENTSIZE));
+ }
+
+ ConstantInt *getElementSizeInBytesCst() const {
+ return cast<ConstantInt>(getRawElementSizeInBytes());
+ }
+
+ uint32_t getElementSizeInBytes() const {
+ return getElementSizeInBytesCst()->getZExtValue();
+ }
+
+ /// This is just like getRawDest, but it strips off any cast
+ /// instructions 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();
+ }
+
+ /// 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);
+ }
+
+ void setValue(Value *Val) {
+ assert(getValue()->getType() == Val->getType() &&
+ "setValue called with value of wrong type!");
+ setArgOperand(ARG_VALUE, Val);
+ }
+
+ void setLength(Value *L) {
+ assert(getLength()->getType() == L->getType() &&
+ "setLength called with value of wrong type!");
+ setArgOperand(ARG_LENGTH, L);
+ }
+
+ void setElementSizeInBytes(Constant *V) {
+ assert(V->getType() == Type::getInt8Ty(getContext()) &&
+ "setElementSizeInBytes called with value of wrong type!");
+ setArgOperand(ARG_ELEMENTSIZE, V);
+ }
+
+ static inline bool classof(const IntrinsicInst *I) {
+ return I->getIntrinsicID() == Intrinsic::memset_element_unordered_atomic;
+ }
static inline bool classof(const Value *V) {
return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
}
@@ -214,7 +527,7 @@ namespace llvm {
}
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const IntrinsicInst *I) {
+ static bool classof(const IntrinsicInst *I) {
switch (I->getIntrinsicID()) {
case Intrinsic::memcpy:
case Intrinsic::memmove:
@@ -223,7 +536,7 @@ namespace llvm {
default: return false;
}
}
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
}
};
@@ -243,10 +556,10 @@ namespace llvm {
}
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const IntrinsicInst *I) {
+ static bool classof(const IntrinsicInst *I) {
return I->getIntrinsicID() == Intrinsic::memset;
}
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
}
};
@@ -275,11 +588,11 @@ namespace llvm {
}
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const IntrinsicInst *I) {
+ static bool classof(const IntrinsicInst *I) {
return I->getIntrinsicID() == Intrinsic::memcpy ||
I->getIntrinsicID() == Intrinsic::memmove;
}
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
}
};
@@ -288,10 +601,10 @@ namespace llvm {
class MemCpyInst : public MemTransferInst {
public:
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const IntrinsicInst *I) {
+ static bool classof(const IntrinsicInst *I) {
return I->getIntrinsicID() == Intrinsic::memcpy;
}
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
}
};
@@ -300,10 +613,10 @@ namespace llvm {
class MemMoveInst : public MemTransferInst {
public:
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const IntrinsicInst *I) {
+ static bool classof(const IntrinsicInst *I) {
return I->getIntrinsicID() == Intrinsic::memmove;
}
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
}
};
@@ -311,10 +624,10 @@ namespace llvm {
/// This represents the llvm.va_start intrinsic.
class VAStartInst : public IntrinsicInst {
public:
- static inline bool classof(const IntrinsicInst *I) {
+ static bool classof(const IntrinsicInst *I) {
return I->getIntrinsicID() == Intrinsic::vastart;
}
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
}
@@ -324,10 +637,10 @@ namespace llvm {
/// This represents the llvm.va_end intrinsic.
class VAEndInst : public IntrinsicInst {
public:
- static inline bool classof(const IntrinsicInst *I) {
+ static bool classof(const IntrinsicInst *I) {
return I->getIntrinsicID() == Intrinsic::vaend;
}
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
}
@@ -337,10 +650,10 @@ namespace llvm {
/// This represents the llvm.va_copy intrinsic.
class VACopyInst : public IntrinsicInst {
public:
- static inline bool classof(const IntrinsicInst *I) {
+ static bool classof(const IntrinsicInst *I) {
return I->getIntrinsicID() == Intrinsic::vacopy;
}
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
}
@@ -351,10 +664,10 @@ namespace llvm {
/// This represents the llvm.instrprof_increment intrinsic.
class InstrProfIncrementInst : public IntrinsicInst {
public:
- static inline bool classof(const IntrinsicInst *I) {
+ static bool classof(const IntrinsicInst *I) {
return I->getIntrinsicID() == Intrinsic::instrprof_increment;
}
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
}
@@ -380,10 +693,10 @@ namespace llvm {
class InstrProfIncrementInstStep : public InstrProfIncrementInst {
public:
- static inline bool classof(const IntrinsicInst *I) {
+ static bool classof(const IntrinsicInst *I) {
return I->getIntrinsicID() == Intrinsic::instrprof_increment_step;
}
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
}
};
@@ -391,10 +704,10 @@ namespace llvm {
/// This represents the llvm.instrprof_value_profile intrinsic.
class InstrProfValueProfileInst : public IntrinsicInst {
public:
- static inline bool classof(const IntrinsicInst *I) {
+ static bool classof(const IntrinsicInst *I) {
return I->getIntrinsicID() == Intrinsic::instrprof_value_profile;
}
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
}
diff --git a/contrib/llvm/include/llvm/IR/Intrinsics.h b/contrib/llvm/include/llvm/IR/Intrinsics.h
index d073584..fc79da7 100644
--- a/contrib/llvm/include/llvm/IR/Intrinsics.h
+++ b/contrib/llvm/include/llvm/IR/Intrinsics.h
@@ -28,7 +28,7 @@ class FunctionType;
class Function;
class LLVMContext;
class Module;
-class AttributeSet;
+class AttributeList;
/// This namespace contains an enum with a value for every intrinsic/builtin
/// function known by LLVM. The enum values are returned by
@@ -69,7 +69,7 @@ namespace Intrinsic {
bool isLeaf(ID id);
/// Return the attributes for an intrinsic.
- AttributeSet getAttributes(LLVMContext &C, ID id);
+ AttributeList getAttributes(LLVMContext &C, ID id);
/// Create or insert an LLVM Function declaration for an intrinsic, and return
/// it.
@@ -100,7 +100,7 @@ namespace Intrinsic {
Void, VarArg, MMX, Token, Metadata, Half, Float, Double,
Integer, Vector, Pointer, Struct,
Argument, ExtendArgument, TruncArgument, HalfVecArgument,
- SameVecWidthArgument, PtrToArgument, PtrToElt, VecOfPtrsToElt
+ SameVecWidthArgument, PtrToArgument, PtrToElt, VecOfAnyPtrsToElt
} Kind;
union {
@@ -119,25 +119,43 @@ namespace Intrinsic {
AK_AnyVector,
AK_AnyPointer
};
+
unsigned getArgumentNumber() const {
assert(Kind == Argument || Kind == ExtendArgument ||
Kind == TruncArgument || Kind == HalfVecArgument ||
Kind == SameVecWidthArgument || Kind == PtrToArgument ||
- Kind == PtrToElt || Kind == VecOfPtrsToElt);
+ Kind == PtrToElt);
return Argument_Info >> 3;
}
ArgKind getArgumentKind() const {
assert(Kind == Argument || Kind == ExtendArgument ||
Kind == TruncArgument || Kind == HalfVecArgument ||
- Kind == SameVecWidthArgument || Kind == PtrToArgument ||
- Kind == VecOfPtrsToElt);
+ Kind == SameVecWidthArgument || Kind == PtrToArgument);
return (ArgKind)(Argument_Info & 7);
}
+ // VecOfAnyPtrsToElt uses both an overloaded argument (for address space)
+ // and a reference argument (for matching vector width and element types)
+ unsigned getOverloadArgNumber() const {
+ assert(Kind == VecOfAnyPtrsToElt);
+ return Argument_Info >> 16;
+ }
+ unsigned getRefArgNumber() const {
+ assert(Kind == VecOfAnyPtrsToElt);
+ return Argument_Info & 0xFFFF;
+ }
+
static IITDescriptor get(IITDescriptorKind K, unsigned Field) {
IITDescriptor Result = { K, { Field } };
return Result;
}
+
+ static IITDescriptor get(IITDescriptorKind K, unsigned short Hi,
+ unsigned short Lo) {
+ unsigned Field = Hi << 16 | Lo;
+ IITDescriptor Result = {K, {Field}};
+ return Result;
+ }
};
/// Return the IIT table descriptor for the specified intrinsic into an array
diff --git a/contrib/llvm/include/llvm/IR/Intrinsics.td b/contrib/llvm/include/llvm/IR/Intrinsics.td
index 89ae942..14c88e5 100644
--- a/contrib/llvm/include/llvm/IR/Intrinsics.td
+++ b/contrib/llvm/include/llvm/IR/Intrinsics.td
@@ -98,6 +98,18 @@ def IntrNoDuplicate : IntrinsicProperty;
// Parallels the convergent attribute on LLVM IR functions.
def IntrConvergent : IntrinsicProperty;
+// This property indicates that the intrinsic is safe to speculate.
+def IntrSpeculatable : IntrinsicProperty;
+
+// This property can be used to override the 'has no other side effects'
+// language of the IntrNoMem, IntrReadMem, IntrWriteMem, and IntrArgMemOnly
+// intrinsic properties. By default, intrinsics are assumed to have side
+// effects, so this property is only necessary if you have defined one of
+// the memory properties listed above.
+// For this property, 'side effects' has the same meaning as 'side effects'
+// defined by the hasSideEffects property of the TableGen Instruction class.
+def IntrHasSideEffects : IntrinsicProperty;
+
//===----------------------------------------------------------------------===//
// Types used by intrinsics.
//===----------------------------------------------------------------------===//
@@ -143,7 +155,7 @@ class LLVMVectorSameWidth<int num, LLVMType elty>
}
class LLVMPointerTo<int num> : LLVMMatchType<num>;
class LLVMPointerToElt<int num> : LLVMMatchType<num>;
-class LLVMVectorOfPointersToElt<int num> : LLVMMatchType<num>;
+class LLVMVectorOfAnyPointersToElt<int num> : LLVMMatchType<num>;
// Match the type of another intrinsic parameter that is expected to be a
// vector type, but change the element count to be half as many
@@ -331,13 +343,13 @@ def int_get_dynamic_area_offset : Intrinsic<[llvm_anyint_ty]>;
def int_thread_pointer : Intrinsic<[llvm_ptr_ty], [], [IntrNoMem]>,
GCCBuiltin<"__builtin_thread_pointer">;
-// IntrArgMemOnly is more pessimistic than strictly necessary for prefetch,
-// however it does conveniently prevent the prefetch from being reordered
-// with respect to nearby accesses to the same memory.
-def int_prefetch : Intrinsic<[],
- [llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty,
- llvm_i32_ty],
- [IntrArgMemOnly, NoCapture<0>]>;
+// IntrInaccessibleMemOrArgMemOnly is a little more pessimistic than strictly
+// necessary for prefetch, however it does conveniently prevent the prefetch
+// from being reordered overly much with respect to nearby access to the same
+// memory while not impeding optimization.
+def int_prefetch
+ : Intrinsic<[], [ llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty ],
+ [ IntrInaccessibleMemOrArgMemOnly, ReadOnly<0>, NoCapture<0> ]>;
def int_pcmarker : Intrinsic<[], [llvm_i32_ty]>;
def int_readcyclecounter : Intrinsic<[llvm_i64_ty]>;
@@ -389,7 +401,10 @@ def int_memset : Intrinsic<[],
llvm_i32_ty, llvm_i1_ty],
[IntrArgMemOnly, NoCapture<0>, WriteOnly<0>]>;
-let IntrProperties = [IntrNoMem] in {
+// FIXME: Add version of these floating point intrinsics which allow non-default
+// rounding modes and FP exception handling.
+
+let IntrProperties = [IntrNoMem, IntrSpeculatable] in {
def int_fma : Intrinsic<[llvm_anyfloat_ty],
[LLVMMatchType<0>, LLVMMatchType<0>,
LLVMMatchType<0>]>;
@@ -425,10 +440,12 @@ let IntrProperties = [IntrNoMem] in {
}
def int_minnum : Intrinsic<[llvm_anyfloat_ty],
- [LLVMMatchType<0>, LLVMMatchType<0>], [IntrNoMem, Commutative]
+ [LLVMMatchType<0>, LLVMMatchType<0>],
+ [IntrNoMem, IntrSpeculatable, Commutative]
>;
def int_maxnum : Intrinsic<[llvm_anyfloat_ty],
- [LLVMMatchType<0>, LLVMMatchType<0>], [IntrNoMem, Commutative]
+ [LLVMMatchType<0>, LLVMMatchType<0>],
+ [IntrNoMem, IntrSpeculatable, Commutative]
>;
// NOTE: these are internal interfaces.
@@ -438,10 +455,100 @@ def int_sigsetjmp : Intrinsic<[llvm_i32_ty] , [llvm_ptr_ty, llvm_i32_ty]>;
def int_siglongjmp : Intrinsic<[], [llvm_ptr_ty, llvm_i32_ty], [IntrNoReturn]>;
// Internal interface for object size checking
-def int_objectsize : Intrinsic<[llvm_anyint_ty], [llvm_anyptr_ty, llvm_i1_ty],
- [IntrNoMem]>,
+def int_objectsize : Intrinsic<[llvm_anyint_ty],
+ [llvm_anyptr_ty, llvm_i1_ty, llvm_i1_ty],
+ [IntrNoMem, IntrSpeculatable]>,
GCCBuiltin<"__builtin_object_size">;
+//===--------------- Constrained Floating Point Intrinsics ----------------===//
+//
+
+let IntrProperties = [IntrInaccessibleMemOnly] in {
+ def int_experimental_constrained_fadd : Intrinsic<[ llvm_anyfloat_ty ],
+ [ LLVMMatchType<0>,
+ LLVMMatchType<0>,
+ llvm_metadata_ty,
+ llvm_metadata_ty ]>;
+ def int_experimental_constrained_fsub : Intrinsic<[ llvm_anyfloat_ty ],
+ [ LLVMMatchType<0>,
+ LLVMMatchType<0>,
+ llvm_metadata_ty,
+ llvm_metadata_ty ]>;
+ def int_experimental_constrained_fmul : Intrinsic<[ llvm_anyfloat_ty ],
+ [ LLVMMatchType<0>,
+ LLVMMatchType<0>,
+ llvm_metadata_ty,
+ llvm_metadata_ty ]>;
+ def int_experimental_constrained_fdiv : Intrinsic<[ llvm_anyfloat_ty ],
+ [ LLVMMatchType<0>,
+ LLVMMatchType<0>,
+ llvm_metadata_ty,
+ llvm_metadata_ty ]>;
+ def int_experimental_constrained_frem : Intrinsic<[ llvm_anyfloat_ty ],
+ [ LLVMMatchType<0>,
+ LLVMMatchType<0>,
+ llvm_metadata_ty,
+ llvm_metadata_ty ]>;
+
+ // These intrinsics are sensitive to the rounding mode so we need constrained
+ // versions of each of them. When strict rounding and exception control are
+ // not required the non-constrained versions of these intrinsics should be
+ // used.
+ def int_experimental_constrained_sqrt : Intrinsic<[ llvm_anyfloat_ty ],
+ [ LLVMMatchType<0>,
+ llvm_metadata_ty,
+ llvm_metadata_ty ]>;
+ def int_experimental_constrained_powi : Intrinsic<[ llvm_anyfloat_ty ],
+ [ LLVMMatchType<0>,
+ llvm_i32_ty,
+ llvm_metadata_ty,
+ llvm_metadata_ty ]>;
+ def int_experimental_constrained_sin : Intrinsic<[ llvm_anyfloat_ty ],
+ [ LLVMMatchType<0>,
+ llvm_metadata_ty,
+ llvm_metadata_ty ]>;
+ def int_experimental_constrained_cos : Intrinsic<[ llvm_anyfloat_ty ],
+ [ LLVMMatchType<0>,
+ llvm_metadata_ty,
+ llvm_metadata_ty ]>;
+ def int_experimental_constrained_pow : Intrinsic<[ llvm_anyfloat_ty ],
+ [ LLVMMatchType<0>,
+ LLVMMatchType<0>,
+ llvm_metadata_ty,
+ llvm_metadata_ty ]>;
+ def int_experimental_constrained_log : Intrinsic<[ llvm_anyfloat_ty ],
+ [ LLVMMatchType<0>,
+ llvm_metadata_ty,
+ llvm_metadata_ty ]>;
+ def int_experimental_constrained_log10: Intrinsic<[ llvm_anyfloat_ty ],
+ [ LLVMMatchType<0>,
+ llvm_metadata_ty,
+ llvm_metadata_ty ]>;
+ def int_experimental_constrained_log2 : Intrinsic<[ llvm_anyfloat_ty ],
+ [ LLVMMatchType<0>,
+ llvm_metadata_ty,
+ llvm_metadata_ty ]>;
+ def int_experimental_constrained_exp : Intrinsic<[ llvm_anyfloat_ty ],
+ [ LLVMMatchType<0>,
+ llvm_metadata_ty,
+ llvm_metadata_ty ]>;
+ def int_experimental_constrained_exp2 : Intrinsic<[ llvm_anyfloat_ty ],
+ [ LLVMMatchType<0>,
+ llvm_metadata_ty,
+ llvm_metadata_ty ]>;
+ def int_experimental_constrained_rint : Intrinsic<[ llvm_anyfloat_ty ],
+ [ LLVMMatchType<0>,
+ llvm_metadata_ty,
+ llvm_metadata_ty ]>;
+ def int_experimental_constrained_nearbyint : Intrinsic<[ llvm_anyfloat_ty ],
+ [ LLVMMatchType<0>,
+ llvm_metadata_ty,
+ llvm_metadata_ty ]>;
+}
+// FIXME: Add intrinsics for fcmp, fptrunc, fpext, fptoui and fptosi.
+// FIXME: Add intrinsics for fabs, copysign, floor, ceil, trunc and round?
+
+
//===------------------------- Expect Intrinsics --------------------------===//
//
def int_expect : Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>,
@@ -451,7 +558,7 @@ def int_expect : Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>,
//
// None of these intrinsics accesses memory at all.
-let IntrProperties = [IntrNoMem] in {
+let IntrProperties = [IntrNoMem, IntrSpeculatable] in {
def int_bswap: Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>]>;
def int_ctpop: Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>]>;
def int_ctlz : Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>, llvm_i1_ty]>;
@@ -462,10 +569,11 @@ let IntrProperties = [IntrNoMem] in {
//===------------------------ Debugger Intrinsics -------------------------===//
//
-// None of these intrinsics accesses memory at all...but that doesn't mean the
-// optimizers can change them aggressively. Special handling needed in a few
-// places.
-let IntrProperties = [IntrNoMem] in {
+// None of these intrinsics accesses memory at all...but that doesn't
+// mean the optimizers can change them aggressively. Special handling
+// needed in a few places. These synthetic intrinsics have no
+// side-effects and just mark information about their operands.
+let IntrProperties = [IntrNoMem, IntrSpeculatable] in {
def int_dbg_declare : Intrinsic<[],
[llvm_metadata_ty,
llvm_metadata_ty,
@@ -543,32 +651,32 @@ def int_adjust_trampoline : Intrinsic<[llvm_ptr_ty], [llvm_ptr_ty],
// Expose the carry flag from add operations on two integrals.
def int_sadd_with_overflow : Intrinsic<[llvm_anyint_ty, llvm_i1_ty],
[LLVMMatchType<0>, LLVMMatchType<0>],
- [IntrNoMem]>;
+ [IntrNoMem, IntrSpeculatable]>;
def int_uadd_with_overflow : Intrinsic<[llvm_anyint_ty, llvm_i1_ty],
[LLVMMatchType<0>, LLVMMatchType<0>],
- [IntrNoMem]>;
+ [IntrNoMem, IntrSpeculatable]>;
def int_ssub_with_overflow : Intrinsic<[llvm_anyint_ty, llvm_i1_ty],
[LLVMMatchType<0>, LLVMMatchType<0>],
- [IntrNoMem]>;
+ [IntrNoMem, IntrSpeculatable]>;
def int_usub_with_overflow : Intrinsic<[llvm_anyint_ty, llvm_i1_ty],
[LLVMMatchType<0>, LLVMMatchType<0>],
- [IntrNoMem]>;
+ [IntrNoMem, IntrSpeculatable]>;
def int_smul_with_overflow : Intrinsic<[llvm_anyint_ty, llvm_i1_ty],
[LLVMMatchType<0>, LLVMMatchType<0>],
- [IntrNoMem]>;
+ [IntrNoMem, IntrSpeculatable]>;
def int_umul_with_overflow : Intrinsic<[llvm_anyint_ty, llvm_i1_ty],
[LLVMMatchType<0>, LLVMMatchType<0>],
- [IntrNoMem]>;
+ [IntrNoMem, IntrSpeculatable]>;
//===------------------------- Memory Use Markers -------------------------===//
//
def int_lifetime_start : Intrinsic<[],
- [llvm_i64_ty, llvm_ptr_ty],
+ [llvm_i64_ty, llvm_anyptr_ty],
[IntrArgMemOnly, NoCapture<1>]>;
def int_lifetime_end : Intrinsic<[],
- [llvm_i64_ty, llvm_ptr_ty],
+ [llvm_i64_ty, llvm_anyptr_ty],
[IntrArgMemOnly, NoCapture<1>]>;
def int_invariant_start : Intrinsic<[llvm_descriptor_ty],
[llvm_i64_ty, llvm_anyptr_ty],
@@ -578,9 +686,16 @@ def int_invariant_end : Intrinsic<[],
llvm_anyptr_ty],
[IntrArgMemOnly, NoCapture<2>]>;
+// invariant.group.barrier can't be marked with 'readnone' (IntrNoMem),
+// because it would cause CSE of two barriers with the same argument.
+// Readonly and argmemonly says that barrier only reads its argument and
+// it can be CSE only if memory didn't change between 2 barriers call,
+// which is valid.
+// The argument also can't be marked with 'returned' attribute, because
+// it would remove barrier.
def int_invariant_group_barrier : Intrinsic<[llvm_ptr_ty],
[llvm_ptr_ty],
- [IntrNoMem]>;
+ [IntrReadMem, IntrArgMemOnly]>;
//===------------------------ Stackmap Intrinsics -------------------------===//
//
@@ -619,18 +734,18 @@ def int_experimental_gc_relocate : Intrinsic<[llvm_any_ty],
// Coroutine Structure Intrinsics.
-def int_coro_id : Intrinsic<[llvm_token_ty], [llvm_i32_ty, llvm_ptr_ty,
- llvm_ptr_ty, llvm_ptr_ty],
- [IntrArgMemOnly, IntrReadMem,
+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>]>;
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>]>;
-def int_coro_free : Intrinsic<[llvm_ptr_ty], [llvm_token_ty, llvm_ptr_ty],
- [IntrReadMem, IntrArgMemOnly, ReadOnly<1>,
+def int_coro_free : Intrinsic<[llvm_ptr_ty], [llvm_token_ty, llvm_ptr_ty],
+ [IntrReadMem, IntrArgMemOnly, ReadOnly<1>,
NoCapture<1>]>;
-def int_coro_end : Intrinsic<[], [llvm_ptr_ty, llvm_i1_ty], []>;
+def int_coro_end : Intrinsic<[llvm_i1_ty], [llvm_ptr_ty, llvm_i1_ty], []>;
def int_coro_frame : Intrinsic<[llvm_ptr_ty], [], [IntrNoMem]>;
def int_coro_size : Intrinsic<[llvm_anyint_ty], [], [IntrNoMem]>;
@@ -702,14 +817,14 @@ def int_masked_load : Intrinsic<[llvm_anyvector_ty],
[IntrReadMem, IntrArgMemOnly]>;
def int_masked_gather: Intrinsic<[llvm_anyvector_ty],
- [LLVMVectorOfPointersToElt<0>, llvm_i32_ty,
+ [LLVMVectorOfAnyPointersToElt<0>, llvm_i32_ty,
LLVMVectorSameWidth<0, llvm_i1_ty>,
LLVMMatchType<0>],
[IntrReadMem]>;
def int_masked_scatter: Intrinsic<[],
[llvm_anyvector_ty,
- LLVMVectorOfPointersToElt<0>, llvm_i32_ty,
+ LLVMVectorOfAnyPointersToElt<0>, llvm_i32_ty,
LLVMVectorSameWidth<0, llvm_i1_ty>]>;
def int_masked_expandload: Intrinsic<[llvm_anyvector_ty],
@@ -736,15 +851,92 @@ def int_type_checked_load : Intrinsic<[llvm_ptr_ty, llvm_i1_ty],
def int_load_relative: Intrinsic<[llvm_ptr_ty], [llvm_ptr_ty, llvm_anyint_ty],
[IntrReadMem, IntrArgMemOnly]>;
+// 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]>;
+//===----------------------------------------------------------------------===//
+
//===------ Memory intrinsics with element-wise atomicity guarantees ------===//
//
-def int_memcpy_element_atomic : Intrinsic<[],
- [llvm_anyptr_ty, llvm_anyptr_ty,
- llvm_i64_ty, llvm_i32_ty],
- [IntrArgMemOnly, NoCapture<0>, NoCapture<1>,
- WriteOnly<0>, ReadOnly<1>]>;
-
+// @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, NoCapture<0>, NoCapture<1>, WriteOnly<0>,
+ ReadOnly<1>
+ ]>;
+
+// @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, NoCapture<0>, NoCapture<1>, WriteOnly<0>,
+ ReadOnly<1>
+ ]>;
+
+// @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, NoCapture<0>, WriteOnly<0> ]>;
+
+//===------------------------ Reduction Intrinsics ------------------------===//
+//
+def int_experimental_vector_reduce_fadd : Intrinsic<[llvm_anyfloat_ty],
+ [llvm_anyfloat_ty,
+ llvm_anyvector_ty],
+ [IntrNoMem]>;
+def int_experimental_vector_reduce_fmul : Intrinsic<[llvm_anyfloat_ty],
+ [llvm_anyfloat_ty,
+ llvm_anyvector_ty],
+ [IntrNoMem]>;
+def int_experimental_vector_reduce_add : Intrinsic<[llvm_anyint_ty],
+ [llvm_anyvector_ty],
+ [IntrNoMem]>;
+def int_experimental_vector_reduce_mul : Intrinsic<[llvm_anyint_ty],
+ [llvm_anyvector_ty],
+ [IntrNoMem]>;
+def int_experimental_vector_reduce_and : Intrinsic<[llvm_anyint_ty],
+ [llvm_anyvector_ty],
+ [IntrNoMem]>;
+def int_experimental_vector_reduce_or : Intrinsic<[llvm_anyint_ty],
+ [llvm_anyvector_ty],
+ [IntrNoMem]>;
+def int_experimental_vector_reduce_xor : Intrinsic<[llvm_anyint_ty],
+ [llvm_anyvector_ty],
+ [IntrNoMem]>;
+def int_experimental_vector_reduce_smax : Intrinsic<[llvm_anyint_ty],
+ [llvm_anyvector_ty],
+ [IntrNoMem]>;
+def int_experimental_vector_reduce_smin : Intrinsic<[llvm_anyint_ty],
+ [llvm_anyvector_ty],
+ [IntrNoMem]>;
+def int_experimental_vector_reduce_umax : Intrinsic<[llvm_anyint_ty],
+ [llvm_anyvector_ty],
+ [IntrNoMem]>;
+def int_experimental_vector_reduce_umin : Intrinsic<[llvm_anyint_ty],
+ [llvm_anyvector_ty],
+ [IntrNoMem]>;
+def int_experimental_vector_reduce_fmax : Intrinsic<[llvm_anyfloat_ty],
+ [llvm_anyvector_ty],
+ [IntrNoMem]>;
+def int_experimental_vector_reduce_fmin : Intrinsic<[llvm_anyfloat_ty],
+ [llvm_anyvector_ty],
+ [IntrNoMem]>;
+
+//===----- Intrinsics that are used to provide predicate information -----===//
+
+def int_ssa_copy : Intrinsic<[llvm_any_ty], [LLVMMatchType<0>],
+ [IntrNoMem, Returned<0>]>;
//===----------------------------------------------------------------------===//
// Target-specific intrinsics
//===----------------------------------------------------------------------===//
diff --git a/contrib/llvm/include/llvm/IR/IntrinsicsAMDGPU.td b/contrib/llvm/include/llvm/IR/IntrinsicsAMDGPU.td
index dcec386..4e0529a 100644
--- a/contrib/llvm/include/llvm/IR/IntrinsicsAMDGPU.td
+++ b/contrib/llvm/include/llvm/IR/IntrinsicsAMDGPU.td
@@ -12,10 +12,10 @@
//===----------------------------------------------------------------------===//
class AMDGPUReadPreloadRegisterIntrinsic
- : Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>;
+ : Intrinsic<[llvm_i32_ty], [], [IntrNoMem, IntrSpeculatable]>;
class AMDGPUReadPreloadRegisterIntrinsicNamed<string name>
- : Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>, GCCBuiltin<name>;
+ : Intrinsic<[llvm_i32_ty], [], [IntrNoMem, IntrSpeculatable]>, GCCBuiltin<name>;
let TargetPrefix = "r600" in {
@@ -47,7 +47,8 @@ def int_r600_group_barrier : GCCBuiltin<"__builtin_r600_group_barrier">,
// 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]>;
+ Intrinsic<[LLVMQualPointerType<llvm_i8_ty, 7>], [],
+ [IntrNoMem, IntrSpeculatable]>;
def int_r600_rat_store_typed :
// 1st parameter: Data
@@ -57,11 +58,15 @@ def int_r600_rat_store_typed :
GCCBuiltin<"__builtin_r600_rat_store_typed">;
def int_r600_recipsqrt_ieee : Intrinsic<
- [llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem]
+ [llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem, IntrSpeculatable]
>;
def int_r600_recipsqrt_clamped : Intrinsic<
- [llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem]
+ [llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem, IntrSpeculatable]
+>;
+
+def int_r600_cube : Intrinsic<
+ [llvm_v4f32_ty], [llvm_v4f32_ty], [IntrNoMem, IntrSpeculatable]
>;
} // End TargetPrefix = "r600"
@@ -78,31 +83,51 @@ defm int_amdgcn_workgroup_id : AMDGPUReadPreloadRegisterIntrinsic_xyz_named
def int_amdgcn_dispatch_ptr :
GCCBuiltin<"__builtin_amdgcn_dispatch_ptr">,
- Intrinsic<[LLVMQualPointerType<llvm_i8_ty, 2>], [], [IntrNoMem]>;
+ Intrinsic<[LLVMQualPointerType<llvm_i8_ty, 2>], [],
+ [IntrNoMem, IntrSpeculatable]>;
def int_amdgcn_queue_ptr :
GCCBuiltin<"__builtin_amdgcn_queue_ptr">,
- Intrinsic<[LLVMQualPointerType<llvm_i8_ty, 2>], [], [IntrNoMem]>;
+ Intrinsic<[LLVMQualPointerType<llvm_i8_ty, 2>], [],
+ [IntrNoMem, IntrSpeculatable]>;
def int_amdgcn_kernarg_segment_ptr :
GCCBuiltin<"__builtin_amdgcn_kernarg_segment_ptr">,
- Intrinsic<[LLVMQualPointerType<llvm_i8_ty, 2>], [], [IntrNoMem]>;
+ Intrinsic<[LLVMQualPointerType<llvm_i8_ty, 2>], [],
+ [IntrNoMem, IntrSpeculatable]>;
def int_amdgcn_implicitarg_ptr :
GCCBuiltin<"__builtin_amdgcn_implicitarg_ptr">,
- Intrinsic<[LLVMQualPointerType<llvm_i8_ty, 2>], [], [IntrNoMem]>;
+ Intrinsic<[LLVMQualPointerType<llvm_i8_ty, 2>], [],
+ [IntrNoMem, IntrSpeculatable]>;
def int_amdgcn_groupstaticsize :
GCCBuiltin<"__builtin_amdgcn_groupstaticsize">,
- Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>;
+ Intrinsic<[llvm_i32_ty], [], [IntrNoMem, IntrSpeculatable]>;
def int_amdgcn_dispatch_id :
GCCBuiltin<"__builtin_amdgcn_dispatch_id">,
- Intrinsic<[llvm_i64_ty], [], [IntrNoMem]>;
+ Intrinsic<[llvm_i64_ty], [], [IntrNoMem, IntrSpeculatable]>;
def int_amdgcn_implicit_buffer_ptr :
GCCBuiltin<"__builtin_amdgcn_implicit_buffer_ptr">,
- Intrinsic<[LLVMQualPointerType<llvm_i8_ty, 2>], [], [IntrNoMem]>;
+ Intrinsic<[LLVMQualPointerType<llvm_i8_ty, 2>], [],
+ [IntrNoMem, IntrSpeculatable]>;
+
+// Set EXEC to the 64-bit value given.
+// This is always moved to the beginning of the basic block.
+def int_amdgcn_init_exec : Intrinsic<[],
+ [llvm_i64_ty], // 64-bit literal constant
+ [IntrConvergent]>;
+
+// Set EXEC according to a thread count packed in an SGPR input:
+// thread_count = (input >> bitoffset) & 0x7f;
+// This is always moved to the beginning of the basic block.
+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]>;
+
//===----------------------------------------------------------------------===//
// Instruction Intrinsics
@@ -121,7 +146,8 @@ def int_amdgcn_s_barrier : GCCBuiltin<"__builtin_amdgcn_s_barrier">,
def int_amdgcn_wave_barrier : GCCBuiltin<"__builtin_amdgcn_wave_barrier">,
Intrinsic<[], [], [IntrConvergent]>;
-def int_amdgcn_s_waitcnt : Intrinsic<[], [llvm_i32_ty], []>;
+def int_amdgcn_s_waitcnt : GCCBuiltin<"__builtin_amdgcn_s_waitcnt">,
+ Intrinsic<[], [llvm_i32_ty], []>;
def int_amdgcn_div_scale : Intrinsic<
// 1st parameter: Numerator
@@ -130,118 +156,144 @@ def int_amdgcn_div_scale : Intrinsic<
// second. (0 = first, 1 = second).
[llvm_anyfloat_ty, llvm_i1_ty],
[LLVMMatchType<0>, LLVMMatchType<0>, llvm_i1_ty],
- [IntrNoMem]
+ [IntrNoMem, IntrSpeculatable]
>;
def int_amdgcn_div_fmas : Intrinsic<[llvm_anyfloat_ty],
[LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>, llvm_i1_ty],
- [IntrNoMem]
+ [IntrNoMem, IntrSpeculatable]
>;
def int_amdgcn_div_fixup : Intrinsic<[llvm_anyfloat_ty],
[LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>],
- [IntrNoMem]
+ [IntrNoMem, IntrSpeculatable]
>;
def int_amdgcn_trig_preop : Intrinsic<
- [llvm_anyfloat_ty], [LLVMMatchType<0>, llvm_i32_ty], [IntrNoMem]
+ [llvm_anyfloat_ty], [LLVMMatchType<0>, llvm_i32_ty],
+ [IntrNoMem, IntrSpeculatable]
>;
def int_amdgcn_sin : Intrinsic<
- [llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem]
+ [llvm_anyfloat_ty], [LLVMMatchType<0>],
+ [IntrNoMem, IntrSpeculatable]
>;
def int_amdgcn_cos : Intrinsic<
- [llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem]
+ [llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem, IntrSpeculatable]
>;
def int_amdgcn_log_clamp : Intrinsic<
- [llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem]
+ [llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem, IntrSpeculatable]
>;
def int_amdgcn_fmul_legacy : GCCBuiltin<"__builtin_amdgcn_fmul_legacy">,
- Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty], [IntrNoMem]
+ Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty],
+ [IntrNoMem, IntrSpeculatable]
>;
def int_amdgcn_rcp : Intrinsic<
- [llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem]
+ [llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem, IntrSpeculatable]
>;
def int_amdgcn_rcp_legacy : GCCBuiltin<"__builtin_amdgcn_rcp_legacy">,
- Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]
+ Intrinsic<[llvm_float_ty], [llvm_float_ty],
+ [IntrNoMem, IntrSpeculatable]
>;
def int_amdgcn_rsq : Intrinsic<
- [llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem]
+ [llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem, IntrSpeculatable]
>;
def int_amdgcn_rsq_legacy : GCCBuiltin<"__builtin_amdgcn_rsq_legacy">,
Intrinsic<
- [llvm_float_ty], [llvm_float_ty], [IntrNoMem]
+ [llvm_float_ty], [llvm_float_ty], [IntrNoMem, IntrSpeculatable]
>;
def int_amdgcn_rsq_clamp : Intrinsic<
- [llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem]>;
+ [llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem, IntrSpeculatable]>;
def int_amdgcn_ldexp : Intrinsic<
- [llvm_anyfloat_ty], [LLVMMatchType<0>, llvm_i32_ty], [IntrNoMem]
+ [llvm_anyfloat_ty], [LLVMMatchType<0>, llvm_i32_ty],
+ [IntrNoMem, IntrSpeculatable]
>;
def int_amdgcn_frexp_mant : Intrinsic<
- [llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem]
+ [llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem, IntrSpeculatable]
>;
def int_amdgcn_frexp_exp : Intrinsic<
- [llvm_anyint_ty], [llvm_anyfloat_ty], [IntrNoMem]
+ [llvm_anyint_ty], [llvm_anyfloat_ty], [IntrNoMem, IntrSpeculatable]
>;
// 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]
+ [llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem, IntrSpeculatable]
+>;
+
+def int_amdgcn_cvt_pkrtz : Intrinsic<
+ [llvm_v2f16_ty], [llvm_float_ty, llvm_float_ty],
+ [IntrNoMem, IntrSpeculatable]
>;
def int_amdgcn_class : Intrinsic<
- [llvm_i1_ty], [llvm_anyfloat_ty, llvm_i32_ty], [IntrNoMem]
+ [llvm_i1_ty], [llvm_anyfloat_ty, llvm_i32_ty],
+ [IntrNoMem, IntrSpeculatable]
+>;
+
+def int_amdgcn_fmed3 : GCCBuiltin<"__builtin_amdgcn_fmed3">,
+ Intrinsic<[llvm_anyfloat_ty],
+ [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>],
+ [IntrNoMem, IntrSpeculatable]
>;
def int_amdgcn_cubeid : GCCBuiltin<"__builtin_amdgcn_cubeid">,
Intrinsic<[llvm_float_ty],
- [llvm_float_ty, llvm_float_ty, llvm_float_ty], [IntrNoMem]
+ [llvm_float_ty, llvm_float_ty, llvm_float_ty],
+ [IntrNoMem, IntrSpeculatable]
>;
def int_amdgcn_cubema : GCCBuiltin<"__builtin_amdgcn_cubema">,
Intrinsic<[llvm_float_ty],
- [llvm_float_ty, llvm_float_ty, llvm_float_ty], [IntrNoMem]
+ [llvm_float_ty, llvm_float_ty, llvm_float_ty],
+ [IntrNoMem, IntrSpeculatable]
>;
def int_amdgcn_cubesc : GCCBuiltin<"__builtin_amdgcn_cubesc">,
Intrinsic<[llvm_float_ty],
- [llvm_float_ty, llvm_float_ty, llvm_float_ty], [IntrNoMem]
+ [llvm_float_ty, llvm_float_ty, llvm_float_ty],
+ [IntrNoMem, IntrSpeculatable]
>;
def int_amdgcn_cubetc : GCCBuiltin<"__builtin_amdgcn_cubetc">,
Intrinsic<[llvm_float_ty],
- [llvm_float_ty, llvm_float_ty, llvm_float_ty], [IntrNoMem]
+ [llvm_float_ty, llvm_float_ty, llvm_float_ty],
+ [IntrNoMem, IntrSpeculatable]
>;
// 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]>;
-
-// TODO: Do we want an ordering for these?
-def int_amdgcn_atomic_inc : Intrinsic<[llvm_anyint_ty],
- [llvm_anyptr_ty, LLVMMatchType<0>],
- [IntrArgMemOnly, NoCapture<0>]
+ Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>],
+ [IntrNoMem, IntrSpeculatable]
>;
-def int_amdgcn_atomic_dec : Intrinsic<[llvm_anyint_ty],
- [llvm_anyptr_ty, LLVMMatchType<0>],
+
+// Fields should mirror atomicrmw
+class AMDGPUAtomicIncIntrin : Intrinsic<[llvm_anyint_ty],
+ [llvm_anyptr_ty,
+ LLVMMatchType<0>,
+ llvm_i32_ty, // ordering
+ llvm_i32_ty, // scope
+ llvm_i1_ty], // isVolatile
[IntrArgMemOnly, NoCapture<0>]
>;
+def int_amdgcn_atomic_inc : AMDGPUAtomicIncIntrin;
+def int_amdgcn_atomic_dec : AMDGPUAtomicIncIntrin;
+
class AMDGPUImageLoad : Intrinsic <
[llvm_anyfloat_ty], // vdata(VGPR)
[llvm_anyint_ty, // vaddr(VGPR)
@@ -423,6 +475,33 @@ class AMDGPUBufferStore : Intrinsic <
def int_amdgcn_buffer_store_format : AMDGPUBufferStore;
def int_amdgcn_buffer_store : AMDGPUBufferStore;
+def int_amdgcn_tbuffer_load : Intrinsic <
+ [llvm_any_ty], // overloaded for types f32/i32, v2f32/v2i32, v4f32/v4i32
+ [llvm_v4i32_ty, // rsrc(SGPR)
+ llvm_i32_ty, // vindex(VGPR)
+ llvm_i32_ty, // voffset(VGPR)
+ llvm_i32_ty, // soffset(SGPR)
+ llvm_i32_ty, // offset(imm)
+ llvm_i32_ty, // dfmt(imm)
+ llvm_i32_ty, // nfmt(imm)
+ llvm_i1_ty, // glc(imm)
+ llvm_i1_ty], // slc(imm)
+ []>;
+
+def int_amdgcn_tbuffer_store : Intrinsic <
+ [],
+ [llvm_any_ty, // vdata(VGPR), overloaded for types f32/i32, v2f32/v2i32, v4f32/v4i32
+ llvm_v4i32_ty, // rsrc(SGPR)
+ llvm_i32_ty, // vindex(VGPR)
+ llvm_i32_ty, // voffset(VGPR)
+ llvm_i32_ty, // soffset(SGPR)
+ llvm_i32_ty, // offset(imm)
+ llvm_i32_ty, // dfmt(imm)
+ llvm_i32_ty, // nfmt(imm)
+ llvm_i1_ty, // glc(imm)
+ llvm_i1_ty], // slc(imm)
+ []>;
+
class AMDGPUBufferAtomic : Intrinsic <
[llvm_i32_ty],
[llvm_i32_ty, // vdata(VGPR)
@@ -451,6 +530,32 @@ def int_amdgcn_buffer_atomic_cmpswap : Intrinsic<
llvm_i1_ty], // slc(imm)
[]>;
+// Uses that do not set the done bit should set IntrWriteMem on the
+// call site.
+def int_amdgcn_exp : Intrinsic <[], [
+ llvm_i32_ty, // tgt,
+ llvm_i32_ty, // en
+ llvm_any_ty, // src0 (f32 or i32)
+ LLVMMatchType<0>, // src1
+ LLVMMatchType<0>, // src2
+ LLVMMatchType<0>, // src3
+ llvm_i1_ty, // done
+ llvm_i1_ty // vm
+ ],
+ []
+>;
+
+// exp with compr bit set.
+def int_amdgcn_exp_compr : Intrinsic <[], [
+ llvm_i32_ty, // tgt,
+ llvm_i32_ty, // en
+ llvm_anyvector_ty, // src0 (v2f16 or v2i16)
+ LLVMMatchType<0>, // src1
+ llvm_i1_ty, // done
+ llvm_i1_ty], // vm
+ []
+>;
+
def int_amdgcn_buffer_wbinvl1_sc :
GCCBuiltin<"__builtin_amdgcn_buffer_wbinvl1_sc">,
Intrinsic<[], [], []>;
@@ -484,7 +589,19 @@ def int_amdgcn_s_decperflevel :
def int_amdgcn_s_getreg :
GCCBuiltin<"__builtin_amdgcn_s_getreg">,
- Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrReadMem]>;
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty],
+ [IntrReadMem, IntrSpeculatable]
+>;
+
+// int_amdgcn_s_getpc is provided to allow a specific style of position
+// independent code to determine the high part of its address when it is
+// known (through convention) that the code and any data of interest does
+// not cross a 4Gb address boundary. Use for any other purpose may not
+// produce the desired results as optimizations may cause code movement,
+// 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]>;
// __builtin_amdgcn_interp_mov <param>, <attr_chan>, <attr>, <m0>
// param values: 0 = P10, 1 = P20, 2 = P0
@@ -492,23 +609,24 @@ 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]>;
+ [IntrNoMem, IntrSpeculatable]>;
// __builtin_amdgcn_interp_p1 <i>, <attr_chan>, <attr>, <m0>
+// This intrinsic reads from lds, but the memory values are constant,
+// so it behaves like IntrNoMem.
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]>; // This intrinsic reads from lds, but the memory
- // values are constant, so it behaves like IntrNoMem.
+ [IntrNoMem, IntrSpeculatable]>;
// __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]>; // See int_amdgcn_v_interp_p1 for why this is
- // IntrNoMem.
+ [IntrNoMem, IntrSpeculatable]>;
+ // See int_amdgcn_v_interp_p1 for why this is IntrNoMem.
// Pixel shaders only: whether the current pixel is live (i.e. not a helper
// invocation for derivative computation).
@@ -530,42 +648,69 @@ def int_amdgcn_ds_swizzle :
GCCBuiltin<"__builtin_amdgcn_ds_swizzle">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem, IntrConvergent]>;
-// llvm.amdgcn.lerp
+def int_amdgcn_ubfe : Intrinsic<[llvm_anyint_ty],
+ [LLVMMatchType<0>, llvm_i32_ty, llvm_i32_ty],
+ [IntrNoMem, IntrSpeculatable]
+>;
+
+def int_amdgcn_sbfe : Intrinsic<[llvm_anyint_ty],
+ [LLVMMatchType<0>, llvm_i32_ty, llvm_i32_ty],
+ [IntrNoMem, IntrSpeculatable]
+>;
+
def int_amdgcn_lerp :
GCCBuiltin<"__builtin_amdgcn_lerp">,
- Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+ [IntrNoMem, IntrSpeculatable]
+>;
def int_amdgcn_sad_u8 :
GCCBuiltin<"__builtin_amdgcn_sad_u8">,
- Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+ [IntrNoMem, IntrSpeculatable]
+>;
def int_amdgcn_msad_u8 :
GCCBuiltin<"__builtin_amdgcn_msad_u8">,
- Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+ [IntrNoMem, IntrSpeculatable]
+>;
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]>;
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+ [IntrNoMem, IntrSpeculatable]
+>;
def int_amdgcn_sad_u16 :
GCCBuiltin<"__builtin_amdgcn_sad_u16">,
- Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+ [IntrNoMem, IntrSpeculatable]
+>;
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]>;
+ Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i32_ty, llvm_i64_ty],
+ [IntrNoMem, IntrSpeculatable]
+>;
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]>;
+ Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i32_ty, llvm_i64_ty],
+ [IntrNoMem, IntrSpeculatable]
+>;
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]>;
+ Intrinsic<[llvm_v4i32_ty], [llvm_i64_ty, llvm_i32_ty, llvm_v4i32_ty],
+ [IntrNoMem, IntrSpeculatable]
+>;
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]>;
+ Intrinsic<[llvm_i32_ty], [llvm_float_ty, llvm_i32_ty, llvm_i32_ty],
+ [IntrNoMem, IntrSpeculatable]
+>;
def int_amdgcn_icmp :
Intrinsic<[llvm_i64_ty], [llvm_anyint_ty, LLVMMatchType<0>, llvm_i32_ty],
@@ -579,10 +724,22 @@ def int_amdgcn_readfirstlane :
GCCBuiltin<"__builtin_amdgcn_readfirstlane">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrNoMem, IntrConvergent]>;
+// 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]>;
+def int_amdgcn_alignbit : Intrinsic<[llvm_i32_ty],
+ [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+ [IntrNoMem, IntrSpeculatable]
+>;
+
+def int_amdgcn_alignbyte : Intrinsic<[llvm_i32_ty],
+ [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+ [IntrNoMem, IntrSpeculatable]
+>;
+
//===----------------------------------------------------------------------===//
// CI+ Intrinsics
//===----------------------------------------------------------------------===//
@@ -619,10 +776,52 @@ def int_amdgcn_s_memrealtime :
// 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]>;
// 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]>;
+
+//===----------------------------------------------------------------------===//
+// Special Intrinsics for backend internal use only. No frontend
+// should emit calls to these.
+// ===----------------------------------------------------------------------===//
+def int_amdgcn_if : Intrinsic<[llvm_i1_ty, llvm_i64_ty],
+ [llvm_i1_ty], [IntrConvergent]
+>;
+
+def int_amdgcn_else : Intrinsic<[llvm_i1_ty, llvm_i64_ty],
+ [llvm_i64_ty], [IntrConvergent]
+>;
+
+def int_amdgcn_break : Intrinsic<[llvm_i64_ty],
+ [llvm_i64_ty], [IntrNoMem, IntrConvergent]
+>;
+
+def int_amdgcn_if_break : Intrinsic<[llvm_i64_ty],
+ [llvm_i1_ty, llvm_i64_ty], [IntrNoMem, IntrConvergent]
+>;
+
+def int_amdgcn_else_break : Intrinsic<[llvm_i64_ty],
+ [llvm_i64_ty, llvm_i64_ty], [IntrNoMem, IntrConvergent]
+>;
+
+def int_amdgcn_loop : Intrinsic<[llvm_i1_ty],
+ [llvm_i64_ty], [IntrConvergent]
+>;
+
+def int_amdgcn_end_cf : Intrinsic<[], [llvm_i64_ty], [IntrConvergent]>;
+
+// Represent unreachable in a divergent region.
+def int_amdgcn_unreachable : Intrinsic<[], [], [IntrConvergent]>;
+
+// Emit 2.5 ulp, no denormal division. Should only be inserted by
+// pass based on !fpmath metadata.
+def int_amdgcn_fdiv_fast : Intrinsic<
+ [llvm_float_ty], [llvm_float_ty, llvm_float_ty],
+ [IntrNoMem, IntrSpeculatable]
+>;
}
diff --git a/contrib/llvm/include/llvm/IR/IntrinsicsARM.td b/contrib/llvm/include/llvm/IR/IntrinsicsARM.td
index 2423968..fe38613 100644
--- a/contrib/llvm/include/llvm/IR/IntrinsicsARM.td
+++ b/contrib/llvm/include/llvm/IR/IntrinsicsARM.td
@@ -22,12 +22,26 @@ let TargetPrefix = "arm" in { // All intrinsics start with "llvm.arm.".
// 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], []>;
+// 16-bit multiplications
+def int_arm_smulbb : GCCBuiltin<"__builtin_arm_smulbb">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_arm_smulbt : GCCBuiltin<"__builtin_arm_smulbt">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_arm_smultb : GCCBuiltin<"__builtin_arm_smultb">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_arm_smultt : GCCBuiltin<"__builtin_arm_smultt">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_arm_smulwb : GCCBuiltin<"__builtin_arm_smulwb">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_arm_smulwt : GCCBuiltin<"__builtin_arm_smulwt">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
+
//===----------------------------------------------------------------------===//
// Saturating Arithmetic
def int_arm_qadd : GCCBuiltin<"__builtin_arm_qadd">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
- [IntrNoMem, Commutative]>;
+ [Commutative, IntrNoMem]>;
def int_arm_qsub : GCCBuiltin<"__builtin_arm_qsub">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
def int_arm_ssat : GCCBuiltin<"__builtin_arm_ssat">,
@@ -35,6 +49,176 @@ def int_arm_ssat : GCCBuiltin<"__builtin_arm_ssat">,
def int_arm_usat : GCCBuiltin<"__builtin_arm_usat">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
+// Accumulating multiplications
+def int_arm_smlabb : GCCBuiltin<"__builtin_arm_smlabb">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+def int_arm_smlabt : GCCBuiltin<"__builtin_arm_smlabt">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+def int_arm_smlatb : GCCBuiltin<"__builtin_arm_smlatb">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+def int_arm_smlatt : GCCBuiltin<"__builtin_arm_smlatt">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+def int_arm_smlawb : GCCBuiltin<"__builtin_arm_smlawb">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+def int_arm_smlawt : GCCBuiltin<"__builtin_arm_smlawt">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+
+// Parallel 16-bit saturation
+def int_arm_ssat16 : GCCBuiltin<"__builtin_arm_ssat16">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_arm_usat16 : GCCBuiltin<"__builtin_arm_usat16">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
+
+// Packing and unpacking
+def int_arm_sxtab16 : GCCBuiltin<"__builtin_arm_sxtab16">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_arm_sxtb16 : GCCBuiltin<"__builtin_arm_sxtb16">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrNoMem]>;
+def int_arm_uxtab16 : GCCBuiltin<"__builtin_arm_uxtab16">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_arm_uxtb16 : GCCBuiltin<"__builtin_arm_uxtb16">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrNoMem]>;
+
+// Parallel selection, reads the GE flags.
+def int_arm_sel : GCCBuiltin<"__builtin_arm_sel">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrReadMem]>;
+
+// Parallel 8-bit addition and subtraction
+def int_arm_qadd8 : GCCBuiltin<"__builtin_arm_qadd8">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_arm_qsub8 : GCCBuiltin<"__builtin_arm_qsub8">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
+// Writes to the GE bits.
+def int_arm_sadd8 : GCCBuiltin<"__builtin_arm_sadd8">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], []>;
+def int_arm_shadd8 : GCCBuiltin<"__builtin_arm_shadd8">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_arm_shsub8 : GCCBuiltin<"__builtin_arm_shsub8">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
+// Writes to the GE bits.
+def int_arm_ssub8 : GCCBuiltin<"__builtin_arm_ssub8">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], []>;
+// Writes to the GE bits.
+def int_arm_uadd8 : GCCBuiltin<"__builtin_arm_uadd8">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], []>;
+def int_arm_uhadd8 : GCCBuiltin<"__builtin_arm_uhadd8">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_arm_uhsub8 : GCCBuiltin<"__builtin_arm_uhsub8">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_arm_uqadd8 : GCCBuiltin<"__builtin_arm_uqadd8">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_arm_uqsub8 : GCCBuiltin<"__builtin_arm_uqsub8">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
+// Writes to the GE bits.
+def int_arm_usub8 : GCCBuiltin<"__builtin_arm_usub8">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], []>;
+
+// Sum of 8-bit absolute differences
+def int_arm_usad8 : GCCBuiltin<"__builtin_arm_usad8">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_arm_usada8 : GCCBuiltin<"__builtin_arm_usada8">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+
+// Parallel 16-bit addition and subtraction
+def int_arm_qadd16 : GCCBuiltin<"__builtin_arm_qadd16">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_arm_qasx : GCCBuiltin<"__builtin_arm_qasx">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_arm_qsax : GCCBuiltin<"__builtin_arm_qsax">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_arm_qsub16 : GCCBuiltin<"__builtin_arm_qsub16">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
+// Writes to the GE bits.
+def int_arm_sadd16 : GCCBuiltin<"__builtin_arm_sadd16">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], []>;
+// Writes to the GE bits.
+def int_arm_sasx : GCCBuiltin<"__builtin_arm_sasx">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], []>;
+def int_arm_shadd16 : GCCBuiltin<"__builtin_arm_shadd16">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_arm_shasx : GCCBuiltin<"__builtin_arm_shasx">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_arm_shsax : GCCBuiltin<"__builtin_arm_shsax">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_arm_shsub16 : GCCBuiltin<"__builtin_arm_shsub16">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
+// Writes to the GE bits.
+def int_arm_ssax : GCCBuiltin<"__builtin_arm_ssax">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], []>;
+// Writes to the GE bits.
+def int_arm_ssub16 : GCCBuiltin<"__builtin_arm_ssub16">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], []>;
+// Writes to the GE bits.
+def int_arm_uadd16 : GCCBuiltin<"__builtin_arm_uadd16">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], []>;
+// Writes to the GE bits.
+def int_arm_uasx : GCCBuiltin<"__builtin_arm_uasx">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], []>;
+def int_arm_uhadd16 : GCCBuiltin<"__builtin_arm_uhadd16">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_arm_uhasx : GCCBuiltin<"__builtin_arm_uhasx">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_arm_uhsax : GCCBuiltin<"__builtin_arm_uhsax">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_arm_uhsub16 : GCCBuiltin<"__builtin_arm_uhsub16">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_arm_uqadd16 : GCCBuiltin<"__builtin_arm_uqadd16">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_arm_uqasx : GCCBuiltin<"__builtin_arm_uqasx">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_arm_uqsax : GCCBuiltin<"__builtin_arm_uqsax">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_arm_uqsub16 : GCCBuiltin<"__builtin_arm_uqsub16">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
+// Writes to the GE bits.
+def int_arm_usax : GCCBuiltin<"__builtin_arm_usax">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], []>;
+// Writes to the GE bits.
+def int_arm_usub16 : GCCBuiltin<"__builtin_arm_usub16">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], []>;
+
+// Parallel 16-bit multiplication
+def int_arm_smlad : GCCBuiltin<"__builtin_arm_smlad">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+def int_arm_smladx : GCCBuiltin<"__builtin_arm_smladx">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+def int_arm_smlald : GCCBuiltin<"__builtin_arm_smlald">,
+ Intrinsic<[llvm_i64_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i64_ty],
+ [IntrNoMem]>;
+def int_arm_smlaldx : GCCBuiltin<"__builtin_arm_smlaldx">,
+ Intrinsic<[llvm_i64_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i64_ty],
+ [IntrNoMem]>;
+def int_arm_smlsd : GCCBuiltin<"__builtin_arm_smlsd">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+def int_arm_smlsdx : GCCBuiltin<"__builtin_arm_smlsdx">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+def int_arm_smlsld : GCCBuiltin<"__builtin_arm_smlsld">,
+ Intrinsic<[llvm_i64_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i64_ty],
+ [IntrNoMem]>;
+def int_arm_smlsldx : GCCBuiltin<"__builtin_arm_smlsldx">,
+ Intrinsic<[llvm_i64_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i64_ty],
+ [IntrNoMem]>;
+def int_arm_smuad : GCCBuiltin<"__builtin_arm_smuad">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_arm_smuadx : GCCBuiltin<"__builtin_arm_smuadx">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_arm_smusd : GCCBuiltin<"__builtin_arm_smusd">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_arm_smusdx : GCCBuiltin<"__builtin_arm_smusdx">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
+
+
//===----------------------------------------------------------------------===//
// Load, Store and Clear exclusive
@@ -67,7 +251,7 @@ def int_arm_isb : GCCBuiltin<"__builtin_arm_isb">, MSBuiltin<"__isb">,
// VFP
def int_arm_get_fpscr : GCCBuiltin<"__builtin_arm_get_fpscr">,
- Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>;
+ Intrinsic<[llvm_i32_ty], [], []>;
def int_arm_set_fpscr : GCCBuiltin<"__builtin_arm_set_fpscr">,
Intrinsic<[], [llvm_i32_ty], []>;
def int_arm_vcvtr : Intrinsic<[llvm_float_ty], [llvm_anyfloat_ty],
diff --git a/contrib/llvm/include/llvm/IR/IntrinsicsHexagon.td b/contrib/llvm/include/llvm/IR/IntrinsicsHexagon.td
index 6519f05..0982453 100644
--- a/contrib/llvm/include/llvm/IR/IntrinsicsHexagon.td
+++ b/contrib/llvm/include/llvm/IR/IntrinsicsHexagon.td
@@ -32,16 +32,6 @@ class Hexagon_qi_mem_Intrinsic<string GCCIntSuffix>
: Hexagon_Intrinsic<GCCIntSuffix,
[llvm_i1_ty], [llvm_ptr_ty],
[IntrNoMem]>;
-
-//
-// DEF_FUNCTION_TYPE_1(void_ftype_SI,BT_VOID,BT_INT) ->
-// Hexagon_void_si_Intrinsic<string GCCIntSuffix>
-//
-class Hexagon_void_si_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [], [llvm_ptr_ty],
- []>;
-
//
// DEF_FUNCTION_TYPE_1(HI_ftype_SI,BT_I16,BT_INT) ->
// Hexagon_hi_si_Intrinsic<string GCCIntSuffix>
@@ -4959,11 +4949,25 @@ Hexagon_di_di_Intrinsic<"HEXAGON_S2_interleave">;
//
def int_hexagon_S2_deinterleave :
Hexagon_di_di_Intrinsic<"HEXAGON_S2_deinterleave">;
+
//
// BUILTIN_INFO(HEXAGON.dcfetch_A,v_ftype_DI*,1)
//
def int_hexagon_prefetch :
-Hexagon_void_si_Intrinsic<"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>;
@@ -5659,20 +5663,20 @@ class Hexagon_v2048v2048v1024v1024i_Intrinsic<string GCCIntSuffix>
[IntrNoMem]>;
//
-// Hexagon_LLiLLiLLi_Intrinsic<string GCCIntSuffix>
-// tag : M6_vabsdiffb
-class Hexagon_LLiLLiLLi_Intrinsic<string GCCIntSuffix>
+// Hexagon_vv64ivmemv512_Intrinsic<string GCCIntSuffix>
+// tag: V6_vS32b_qpred_ai
+class Hexagon_vv64ivmemv512_Intrinsic<string GCCIntSuffix>
: Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_i64_ty], [llvm_i64_ty,llvm_i64_ty],
- [IntrNoMem]>;
+ [], [llvm_v512i1_ty,llvm_ptr_ty,llvm_v16i32_ty],
+ [IntrArgMemOnly]>;
//
-// Hexagon_LLii_Intrinsic<string GCCIntSuffix>
-// tag : S6_vsplatrbp
-class Hexagon_LLii_Intrinsic<string GCCIntSuffix>
+// Hexagon_vv128ivmemv1024_Intrinsic<string GCCIntSuffix>
+// tag: V6_vS32b_qpred_ai_128B
+class Hexagon_vv128ivmemv1024_Intrinsic<string GCCIntSuffix>
: Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_i64_ty], [llvm_i32_ty],
- [IntrNoMem]>;
+ [], [llvm_v1024i1_ty,llvm_ptr_ty,llvm_v32i32_ty],
+ [IntrArgMemOnly]>;
//
// BUILTIN_INFO(HEXAGON.S6_rol_i_r,SI_ftype_SISI,2)
@@ -9343,6 +9347,303 @@ def int_hexagon_V6_vlutvwh_oracc_128B :
Hexagon_v2048v2048v1024v1024i_Intrinsic<"HEXAGON_V6_vlutvwh_oracc_128B">;
//
+// Masked vector stores
+//
+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">;
+
+
+///
+/// HexagonV62 intrinsics
+///
+
+//
+// Hexagon_LLiLLiLLi_Intrinsic<string GCCIntSuffix>
+// tag : M6_vabsdiffb
+class Hexagon_LLiLLiLLi_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i64_ty], [llvm_i64_ty,llvm_i64_ty],
+ [IntrNoMem]>;
+
+//
+// Hexagon_LLii_Intrinsic<string GCCIntSuffix>
+// tag : S6_vsplatrbp
+class Hexagon_LLii_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i64_ty], [llvm_i32_ty],
+ [IntrNoMem]>;
+
+//
+// Hexagon_V62_v512v512i_Intrinsic<string GCCIntSuffix>
+// tag : V6_vlsrb
+class Hexagon_V62_v512v512i_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v16i32_ty], [llvm_v16i32_ty,llvm_i32_ty],
+ [IntrNoMem]>;
+
+//
+// Hexagon_V62_v1024v1024i_Intrinsic<string GCCIntSuffix>
+// tag : V6_vlsrb_128B
+class Hexagon_V62_v1024v1024i_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v32i32_ty], [llvm_v32i32_ty,llvm_i32_ty],
+ [IntrNoMem]>;
+
+//
+// Hexagon_V62_v512v512v512i_Intrinsic<string GCCIntSuffix>
+// tag : V6_vasrwuhrndsat
+class Hexagon_V62_v512v512v512i_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v16i32_ty], [llvm_v16i32_ty,llvm_v16i32_ty,llvm_i32_ty],
+ [IntrNoMem]>;
+
+//
+// Hexagon_V62_v1024v1024v1024i_Intrinsic<string GCCIntSuffix>
+// tag : V6_vasrwuhrndsat_128B
+class Hexagon_V62_v1024v1024v1024i_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v32i32_ty], [llvm_v32i32_ty,llvm_v32i32_ty,llvm_i32_ty],
+ [IntrNoMem]>;
+
+//
+// Hexagon_V62_v512v512v512_Intrinsic<string GCCIntSuffix>
+// tag : V6_vrounduwuh
+class Hexagon_V62_v512v512v512_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v16i32_ty], [llvm_v16i32_ty,llvm_v16i32_ty],
+ [IntrNoMem]>;
+
+//
+// Hexagon_V62_v1024v1024v1024_Intrinsic<string GCCIntSuffix>
+// tag : V6_vrounduwuh_128B
+class Hexagon_V62_v1024v1024v1024_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v32i32_ty], [llvm_v32i32_ty,llvm_v32i32_ty],
+ [IntrNoMem]>;
+
+//
+// Hexagon_V62_v2048v2048v2048_Intrinsic<string GCCIntSuffix>
+// tag : V6_vadduwsat_dv_128B
+class Hexagon_V62_v2048v2048v2048_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v64i32_ty], [llvm_v64i32_ty,llvm_v64i32_ty],
+ [IntrNoMem]>;
+
+//
+// Hexagon_V62_v1024v1024v512v512_Intrinsic<string GCCIntSuffix>
+// tag : V6_vaddhw_acc
+class Hexagon_V62_v1024v1024v512v512_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v32i32_ty], [llvm_v32i32_ty,llvm_v16i32_ty,llvm_v16i32_ty],
+ [IntrNoMem]>;
+
+//
+// Hexagon_V62_v2048v2048v1024v1024_Intrinsic<string GCCIntSuffix>
+// tag : V6_vaddhw_acc_128B
+class Hexagon_V62_v2048v2048v1024v1024_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v64i32_ty], [llvm_v64i32_ty,llvm_v32i32_ty,llvm_v32i32_ty],
+ [IntrNoMem]>;
+
+//
+// Hexagon_V62_v1024v512v512_Intrinsic<string GCCIntSuffix>
+// tag : V6_vmpyewuh_64
+class Hexagon_V62_v1024v512v512_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v32i32_ty], [llvm_v16i32_ty,llvm_v16i32_ty],
+ [IntrNoMem]>;
+
+//
+// Hexagon_V62_v2048v1024v1024_Intrinsic<string GCCIntSuffix>
+// tag : V6_vmpyewuh_64_128B
+class Hexagon_V62_v2048v1024v1024_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v64i32_ty], [llvm_v32i32_ty,llvm_v32i32_ty],
+ [IntrNoMem]>;
+
+//
+// Hexagon_V62_v2048v2048i_Intrinsic<string GCCIntSuffix>
+// tag : V6_vmpauhb_128B
+class Hexagon_V62_v2048v2048i_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v64i32_ty], [llvm_v64i32_ty,llvm_i32_ty],
+ [IntrNoMem]>;
+
+//
+// Hexagon_V62_v2048v2048v2048i_Intrinsic<string GCCIntSuffix>
+// tag : V6_vmpauhb_acc_128B
+class Hexagon_V62_v2048v2048v2048i_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v64i32_ty], [llvm_v64i32_ty,llvm_v64i32_ty,llvm_i32_ty],
+ [IntrNoMem]>;
+
+//
+// Hexagon_V62_v512v64ii_Intrinsic<string GCCIntSuffix>
+// tag : V6_vandnqrt
+class Hexagon_V62_v512v64ii_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v16i32_ty], [llvm_v512i1_ty,llvm_i32_ty],
+ [IntrNoMem]>;
+
+//
+// Hexagon_V62_v1024v128ii_Intrinsic<string GCCIntSuffix>
+// tag : V6_vandnqrt_128B
+class Hexagon_V62_v1024v128ii_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v32i32_ty], [llvm_v1024i1_ty,llvm_i32_ty],
+ [IntrNoMem]>;
+
+//
+// Hexagon_V62_v512v512v64ii_Intrinsic<string GCCIntSuffix>
+// tag : V6_vandnqrt_acc
+class Hexagon_V62_v512v512v64ii_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v16i32_ty], [llvm_v16i32_ty,llvm_v512i1_ty,llvm_i32_ty],
+ [IntrNoMem]>;
+
+//
+// Hexagon_V62_v1024v1024v128ii_Intrinsic<string GCCIntSuffix>
+// tag : V6_vandnqrt_acc_128B
+class Hexagon_V62_v1024v1024v128ii_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v32i32_ty], [llvm_v32i32_ty,llvm_v1024i1_ty,llvm_i32_ty],
+ [IntrNoMem]>;
+
+//
+// Hexagon_V62_v512v64iv512_Intrinsic<string GCCIntSuffix>
+// tag : V6_vandvqv
+class Hexagon_V62_v512v64iv512_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v16i32_ty], [llvm_v512i1_ty,llvm_v16i32_ty],
+ [IntrNoMem]>;
+
+//
+// Hexagon_V62_v1024v128iv1024_Intrinsic<string GCCIntSuffix>
+// tag : V6_vandvqv_128B
+class Hexagon_V62_v1024v128iv1024_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v32i32_ty], [llvm_v1024i1_ty,llvm_v32i32_ty],
+ [IntrNoMem]>;
+
+//
+// Hexagon_V62_v64ii_Intrinsic<string GCCIntSuffix>
+// tag : V6_pred_scalar2v2
+class Hexagon_V62_v64ii_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v512i1_ty], [llvm_i32_ty],
+ [IntrNoMem]>;
+
+//
+// Hexagon_V62_v128ii_Intrinsic<string GCCIntSuffix>
+// tag : V6_pred_scalar2v2_128B
+class Hexagon_V62_v128ii_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v1024i1_ty], [llvm_i32_ty],
+ [IntrNoMem]>;
+
+//
+// Hexagon_V62_v64iv64iv64i_Intrinsic<string GCCIntSuffix>
+// tag : V6_shuffeqw
+class Hexagon_V62_v64iv64iv64i_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v512i1_ty], [llvm_v512i1_ty,llvm_v512i1_ty],
+ [IntrNoMem]>;
+
+//
+// Hexagon_V62_v128iv128iv128i_Intrinsic<string GCCIntSuffix>
+// tag : V6_shuffeqw_128B
+class Hexagon_V62_v128iv128iv128i_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v1024i1_ty], [llvm_v1024i1_ty,llvm_v1024i1_ty],
+ [IntrNoMem]>;
+
+//
+// Hexagon_V62_v512i_Intrinsic<string GCCIntSuffix>
+// tag : V6_lvsplath
+class Hexagon_V62_v512i_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v16i32_ty], [llvm_i32_ty],
+ [IntrNoMem]>;
+
+//
+// Hexagon_V62_v1024i_Intrinsic<string GCCIntSuffix>
+// tag : V6_lvsplath_128B
+class Hexagon_V62_v1024i_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v32i32_ty], [llvm_i32_ty],
+ [IntrNoMem]>;
+
+//
+// Hexagon_V62_v512v512v512v512i_Intrinsic<string GCCIntSuffix>
+// tag : V6_vlutvvb_oracci
+class Hexagon_V62_v512v512v512v512i_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v16i32_ty], [llvm_v16i32_ty,llvm_v16i32_ty,llvm_v16i32_ty,llvm_i32_ty],
+ [IntrNoMem]>;
+
+//
+// Hexagon_V62_v1024v1024v1024v1024i_Intrinsic<string GCCIntSuffix>
+// tag : V6_vlutvvb_oracci_128B
+class Hexagon_V62_v1024v1024v1024v1024i_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v32i32_ty], [llvm_v32i32_ty,llvm_v32i32_ty,llvm_v32i32_ty,llvm_i32_ty],
+ [IntrNoMem]>;
+
+//
+// Hexagon_V62_v1024v512v512i_Intrinsic<string GCCIntSuffix>
+// tag : V6_vlutvwhi
+class Hexagon_V62_v1024v512v512i_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v32i32_ty], [llvm_v16i32_ty,llvm_v16i32_ty,llvm_i32_ty],
+ [IntrNoMem]>;
+
+//
+// Hexagon_V62_v2048v1024v1024i_Intrinsic<string GCCIntSuffix>
+// tag : V6_vlutvwhi_128B
+class Hexagon_V62_v2048v1024v1024i_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v64i32_ty], [llvm_v32i32_ty,llvm_v32i32_ty,llvm_i32_ty],
+ [IntrNoMem]>;
+
+//
+// Hexagon_V62_v1024v1024v512v512i_Intrinsic<string GCCIntSuffix>
+// tag : V6_vlutvwh_oracci
+class Hexagon_V62_v1024v1024v512v512i_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v32i32_ty], [llvm_v32i32_ty,llvm_v16i32_ty,llvm_v16i32_ty,llvm_i32_ty],
+ [IntrNoMem]>;
+
+//
+// Hexagon_V62_v2048v2048v1024v1024i_Intrinsic<string GCCIntSuffix>
+// tag : V6_vlutvwh_oracci_128B
+class Hexagon_V62_v2048v2048v1024v1024i_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v64i32_ty], [llvm_v64i32_ty,llvm_v32i32_ty,llvm_v32i32_ty,llvm_i32_ty],
+ [IntrNoMem]>;
+
+
+//
// BUILTIN_INFO(HEXAGON.M6_vabsdiffb,DI_ftype_DIDI,2)
// tag : M6_vabsdiffb
def int_hexagon_M6_vabsdiffb :
@@ -9355,12 +9656,6 @@ def int_hexagon_M6_vabsdiffub :
Hexagon_LLiLLiLLi_Intrinsic<"HEXAGON_M6_vabsdiffub">;
//
-// BUILTIN_INFO(HEXAGON.S6_vsplatrbp,DI_ftype_SI,1)
-// tag : S6_vsplatrbp
-def int_hexagon_S6_vsplatrbp :
-Hexagon_LLii_Intrinsic<"HEXAGON_S6_vsplatrbp">;
-
-//
// BUILTIN_INFO(HEXAGON.S6_vtrunehb_ppp,DI_ftype_DIDI,2)
// tag : S6_vtrunehb_ppp
def int_hexagon_S6_vtrunehb_ppp :
@@ -9371,3 +9666,550 @@ Hexagon_LLiLLiLLi_Intrinsic<"HEXAGON_S6_vtrunehb_ppp">;
// tag : S6_vtrunohb_ppp
def int_hexagon_S6_vtrunohb_ppp :
Hexagon_LLiLLiLLi_Intrinsic<"HEXAGON_S6_vtrunohb_ppp">;
+
+//
+// BUILTIN_INFO(HEXAGON.S6_vsplatrbp,DI_ftype_SI,1)
+// tag : S6_vsplatrbp
+def int_hexagon_S6_vsplatrbp :
+Hexagon_LLii_Intrinsic<"HEXAGON_S6_vsplatrbp">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vlsrb,VI_ftype_VISI,2)
+// tag : V6_vlsrb
+def int_hexagon_V6_vlsrb :
+Hexagon_V62_v512v512i_Intrinsic<"HEXAGON_V6_vlsrb">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vlsrb_128B,VI_ftype_VISI,2)
+// tag : V6_vlsrb_128B
+def int_hexagon_V6_vlsrb_128B :
+Hexagon_V62_v1024v1024i_Intrinsic<"HEXAGON_V6_vlsrb_128B">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vasrwuhrndsat,VI_ftype_VIVISI,3)
+// tag : V6_vasrwuhrndsat
+def int_hexagon_V6_vasrwuhrndsat :
+Hexagon_V62_v512v512v512i_Intrinsic<"HEXAGON_V6_vasrwuhrndsat">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vasrwuhrndsat_128B,VI_ftype_VIVISI,3)
+// tag : V6_vasrwuhrndsat_128B
+def int_hexagon_V6_vasrwuhrndsat_128B :
+Hexagon_V62_v1024v1024v1024i_Intrinsic<"HEXAGON_V6_vasrwuhrndsat_128B">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vasruwuhrndsat,VI_ftype_VIVISI,3)
+// tag : V6_vasruwuhrndsat
+def int_hexagon_V6_vasruwuhrndsat :
+Hexagon_V62_v512v512v512i_Intrinsic<"HEXAGON_V6_vasruwuhrndsat">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vasruwuhrndsat_128B,VI_ftype_VIVISI,3)
+// tag : V6_vasruwuhrndsat_128B
+def int_hexagon_V6_vasruwuhrndsat_128B :
+Hexagon_V62_v1024v1024v1024i_Intrinsic<"HEXAGON_V6_vasruwuhrndsat_128B">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vasrhbsat,VI_ftype_VIVISI,3)
+// tag : V6_vasrhbsat
+def int_hexagon_V6_vasrhbsat :
+Hexagon_V62_v512v512v512i_Intrinsic<"HEXAGON_V6_vasrhbsat">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vasrhbsat_128B,VI_ftype_VIVISI,3)
+// tag : V6_vasrhbsat_128B
+def int_hexagon_V6_vasrhbsat_128B :
+Hexagon_V62_v1024v1024v1024i_Intrinsic<"HEXAGON_V6_vasrhbsat_128B">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vrounduwuh,VI_ftype_VIVI,2)
+// tag : V6_vrounduwuh
+def int_hexagon_V6_vrounduwuh :
+Hexagon_V62_v512v512v512_Intrinsic<"HEXAGON_V6_vrounduwuh">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vrounduwuh_128B,VI_ftype_VIVI,2)
+// tag : V6_vrounduwuh_128B
+def int_hexagon_V6_vrounduwuh_128B :
+Hexagon_V62_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vrounduwuh_128B">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vrounduhub,VI_ftype_VIVI,2)
+// tag : V6_vrounduhub
+def int_hexagon_V6_vrounduhub :
+Hexagon_V62_v512v512v512_Intrinsic<"HEXAGON_V6_vrounduhub">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vrounduhub_128B,VI_ftype_VIVI,2)
+// tag : V6_vrounduhub_128B
+def int_hexagon_V6_vrounduhub_128B :
+Hexagon_V62_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vrounduhub_128B">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vadduwsat,VI_ftype_VIVI,2)
+// tag : V6_vadduwsat
+def int_hexagon_V6_vadduwsat :
+Hexagon_V62_v512v512v512_Intrinsic<"HEXAGON_V6_vadduwsat">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vadduwsat_128B,VI_ftype_VIVI,2)
+// tag : V6_vadduwsat_128B
+def int_hexagon_V6_vadduwsat_128B :
+Hexagon_V62_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vadduwsat_128B">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vadduwsat_dv,VD_ftype_VDVD,2)
+// tag : V6_vadduwsat_dv
+def int_hexagon_V6_vadduwsat_dv :
+Hexagon_V62_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vadduwsat_dv">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vadduwsat_dv_128B,VD_ftype_VDVD,2)
+// tag : V6_vadduwsat_dv_128B
+def int_hexagon_V6_vadduwsat_dv_128B :
+Hexagon_V62_v2048v2048v2048_Intrinsic<"HEXAGON_V6_vadduwsat_dv_128B">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vsubuwsat,VI_ftype_VIVI,2)
+// tag : V6_vsubuwsat
+def int_hexagon_V6_vsubuwsat :
+Hexagon_V62_v512v512v512_Intrinsic<"HEXAGON_V6_vsubuwsat">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vsubuwsat_128B,VI_ftype_VIVI,2)
+// tag : V6_vsubuwsat_128B
+def int_hexagon_V6_vsubuwsat_128B :
+Hexagon_V62_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vsubuwsat_128B">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vsubuwsat_dv,VD_ftype_VDVD,2)
+// tag : V6_vsubuwsat_dv
+def int_hexagon_V6_vsubuwsat_dv :
+Hexagon_V62_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vsubuwsat_dv">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vsubuwsat_dv_128B,VD_ftype_VDVD,2)
+// tag : V6_vsubuwsat_dv_128B
+def int_hexagon_V6_vsubuwsat_dv_128B :
+Hexagon_V62_v2048v2048v2048_Intrinsic<"HEXAGON_V6_vsubuwsat_dv_128B">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vaddbsat,VI_ftype_VIVI,2)
+// tag : V6_vaddbsat
+def int_hexagon_V6_vaddbsat :
+Hexagon_V62_v512v512v512_Intrinsic<"HEXAGON_V6_vaddbsat">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vaddbsat_128B,VI_ftype_VIVI,2)
+// tag : V6_vaddbsat_128B
+def int_hexagon_V6_vaddbsat_128B :
+Hexagon_V62_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vaddbsat_128B">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vaddbsat_dv,VD_ftype_VDVD,2)
+// tag : V6_vaddbsat_dv
+def int_hexagon_V6_vaddbsat_dv :
+Hexagon_V62_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vaddbsat_dv">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vaddbsat_dv_128B,VD_ftype_VDVD,2)
+// tag : V6_vaddbsat_dv_128B
+def int_hexagon_V6_vaddbsat_dv_128B :
+Hexagon_V62_v2048v2048v2048_Intrinsic<"HEXAGON_V6_vaddbsat_dv_128B">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vsubbsat,VI_ftype_VIVI,2)
+// tag : V6_vsubbsat
+def int_hexagon_V6_vsubbsat :
+Hexagon_V62_v512v512v512_Intrinsic<"HEXAGON_V6_vsubbsat">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vsubbsat_128B,VI_ftype_VIVI,2)
+// tag : V6_vsubbsat_128B
+def int_hexagon_V6_vsubbsat_128B :
+Hexagon_V62_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vsubbsat_128B">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vsubbsat_dv,VD_ftype_VDVD,2)
+// tag : V6_vsubbsat_dv
+def int_hexagon_V6_vsubbsat_dv :
+Hexagon_V62_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vsubbsat_dv">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vsubbsat_dv_128B,VD_ftype_VDVD,2)
+// tag : V6_vsubbsat_dv_128B
+def int_hexagon_V6_vsubbsat_dv_128B :
+Hexagon_V62_v2048v2048v2048_Intrinsic<"HEXAGON_V6_vsubbsat_dv_128B">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vaddububb_sat,VI_ftype_VIVI,2)
+// tag : V6_vaddububb_sat
+def int_hexagon_V6_vaddububb_sat :
+Hexagon_V62_v512v512v512_Intrinsic<"HEXAGON_V6_vaddububb_sat">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vaddububb_sat_128B,VI_ftype_VIVI,2)
+// tag : V6_vaddububb_sat_128B
+def int_hexagon_V6_vaddububb_sat_128B :
+Hexagon_V62_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vaddububb_sat_128B">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vsubububb_sat,VI_ftype_VIVI,2)
+// tag : V6_vsubububb_sat
+def int_hexagon_V6_vsubububb_sat :
+Hexagon_V62_v512v512v512_Intrinsic<"HEXAGON_V6_vsubububb_sat">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vsubububb_sat_128B,VI_ftype_VIVI,2)
+// tag : V6_vsubububb_sat_128B
+def int_hexagon_V6_vsubububb_sat_128B :
+Hexagon_V62_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vsubububb_sat_128B">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vaddhw_acc,VD_ftype_VDVIVI,3)
+// tag : V6_vaddhw_acc
+def int_hexagon_V6_vaddhw_acc :
+Hexagon_V62_v1024v1024v512v512_Intrinsic<"HEXAGON_V6_vaddhw_acc">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vaddhw_acc_128B,VD_ftype_VDVIVI,3)
+// tag : V6_vaddhw_acc_128B
+def int_hexagon_V6_vaddhw_acc_128B :
+Hexagon_V62_v2048v2048v1024v1024_Intrinsic<"HEXAGON_V6_vaddhw_acc_128B">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vadduhw_acc,VD_ftype_VDVIVI,3)
+// tag : V6_vadduhw_acc
+def int_hexagon_V6_vadduhw_acc :
+Hexagon_V62_v1024v1024v512v512_Intrinsic<"HEXAGON_V6_vadduhw_acc">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vadduhw_acc_128B,VD_ftype_VDVIVI,3)
+// tag : V6_vadduhw_acc_128B
+def int_hexagon_V6_vadduhw_acc_128B :
+Hexagon_V62_v2048v2048v1024v1024_Intrinsic<"HEXAGON_V6_vadduhw_acc_128B">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vaddubh_acc,VD_ftype_VDVIVI,3)
+// tag : V6_vaddubh_acc
+def int_hexagon_V6_vaddubh_acc :
+Hexagon_V62_v1024v1024v512v512_Intrinsic<"HEXAGON_V6_vaddubh_acc">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vaddubh_acc_128B,VD_ftype_VDVIVI,3)
+// tag : V6_vaddubh_acc_128B
+def int_hexagon_V6_vaddubh_acc_128B :
+Hexagon_V62_v2048v2048v1024v1024_Intrinsic<"HEXAGON_V6_vaddubh_acc_128B">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vmpyewuh_64,VD_ftype_VIVI,2)
+// tag : V6_vmpyewuh_64
+def int_hexagon_V6_vmpyewuh_64 :
+Hexagon_V62_v1024v512v512_Intrinsic<"HEXAGON_V6_vmpyewuh_64">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vmpyewuh_64_128B,VD_ftype_VIVI,2)
+// tag : V6_vmpyewuh_64_128B
+def int_hexagon_V6_vmpyewuh_64_128B :
+Hexagon_V62_v2048v1024v1024_Intrinsic<"HEXAGON_V6_vmpyewuh_64_128B">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vmpyowh_64_acc,VD_ftype_VDVIVI,3)
+// tag : V6_vmpyowh_64_acc
+def int_hexagon_V6_vmpyowh_64_acc :
+Hexagon_V62_v1024v1024v512v512_Intrinsic<"HEXAGON_V6_vmpyowh_64_acc">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vmpyowh_64_acc_128B,VD_ftype_VDVIVI,3)
+// tag : V6_vmpyowh_64_acc_128B
+def int_hexagon_V6_vmpyowh_64_acc_128B :
+Hexagon_V62_v2048v2048v1024v1024_Intrinsic<"HEXAGON_V6_vmpyowh_64_acc_128B">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vmpauhb,VD_ftype_VDSI,2)
+// tag : V6_vmpauhb
+def int_hexagon_V6_vmpauhb :
+Hexagon_V62_v1024v1024i_Intrinsic<"HEXAGON_V6_vmpauhb">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vmpauhb_128B,VD_ftype_VDSI,2)
+// tag : V6_vmpauhb_128B
+def int_hexagon_V6_vmpauhb_128B :
+Hexagon_V62_v2048v2048i_Intrinsic<"HEXAGON_V6_vmpauhb_128B">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vmpauhb_acc,VD_ftype_VDVDSI,3)
+// tag : V6_vmpauhb_acc
+def int_hexagon_V6_vmpauhb_acc :
+Hexagon_V62_v1024v1024v1024i_Intrinsic<"HEXAGON_V6_vmpauhb_acc">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vmpauhb_acc_128B,VD_ftype_VDVDSI,3)
+// tag : V6_vmpauhb_acc_128B
+def int_hexagon_V6_vmpauhb_acc_128B :
+Hexagon_V62_v2048v2048v2048i_Intrinsic<"HEXAGON_V6_vmpauhb_acc_128B">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vmpyiwub,VI_ftype_VISI,2)
+// tag : V6_vmpyiwub
+def int_hexagon_V6_vmpyiwub :
+Hexagon_V62_v512v512i_Intrinsic<"HEXAGON_V6_vmpyiwub">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vmpyiwub_128B,VI_ftype_VISI,2)
+// tag : V6_vmpyiwub_128B
+def int_hexagon_V6_vmpyiwub_128B :
+Hexagon_V62_v1024v1024i_Intrinsic<"HEXAGON_V6_vmpyiwub_128B">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vmpyiwub_acc,VI_ftype_VIVISI,3)
+// tag : V6_vmpyiwub_acc
+def int_hexagon_V6_vmpyiwub_acc :
+Hexagon_V62_v512v512v512i_Intrinsic<"HEXAGON_V6_vmpyiwub_acc">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vmpyiwub_acc_128B,VI_ftype_VIVISI,3)
+// tag : V6_vmpyiwub_acc_128B
+def int_hexagon_V6_vmpyiwub_acc_128B :
+Hexagon_V62_v1024v1024v1024i_Intrinsic<"HEXAGON_V6_vmpyiwub_acc_128B">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vandnqrt,VI_ftype_QVSI,2)
+// tag : V6_vandnqrt
+def int_hexagon_V6_vandnqrt :
+Hexagon_V62_v512v64ii_Intrinsic<"HEXAGON_V6_vandnqrt">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vandnqrt_128B,VI_ftype_QVSI,2)
+// tag : V6_vandnqrt_128B
+def int_hexagon_V6_vandnqrt_128B :
+Hexagon_V62_v1024v128ii_Intrinsic<"HEXAGON_V6_vandnqrt_128B">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vandnqrt_acc,VI_ftype_VIQVSI,3)
+// tag : V6_vandnqrt_acc
+def int_hexagon_V6_vandnqrt_acc :
+Hexagon_V62_v512v512v64ii_Intrinsic<"HEXAGON_V6_vandnqrt_acc">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vandnqrt_acc_128B,VI_ftype_VIQVSI,3)
+// tag : V6_vandnqrt_acc_128B
+def int_hexagon_V6_vandnqrt_acc_128B :
+Hexagon_V62_v1024v1024v128ii_Intrinsic<"HEXAGON_V6_vandnqrt_acc_128B">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vandvqv,VI_ftype_QVVI,2)
+// tag : V6_vandvqv
+def int_hexagon_V6_vandvqv :
+Hexagon_V62_v512v64iv512_Intrinsic<"HEXAGON_V6_vandvqv">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vandvqv_128B,VI_ftype_QVVI,2)
+// tag : V6_vandvqv_128B
+def int_hexagon_V6_vandvqv_128B :
+Hexagon_V62_v1024v128iv1024_Intrinsic<"HEXAGON_V6_vandvqv_128B">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vandvnqv,VI_ftype_QVVI,2)
+// tag : V6_vandvnqv
+def int_hexagon_V6_vandvnqv :
+Hexagon_V62_v512v64iv512_Intrinsic<"HEXAGON_V6_vandvnqv">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vandvnqv_128B,VI_ftype_QVVI,2)
+// tag : V6_vandvnqv_128B
+def int_hexagon_V6_vandvnqv_128B :
+Hexagon_V62_v1024v128iv1024_Intrinsic<"HEXAGON_V6_vandvnqv_128B">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_pred_scalar2v2,QV_ftype_SI,1)
+// tag : V6_pred_scalar2v2
+def int_hexagon_V6_pred_scalar2v2 :
+Hexagon_V62_v64ii_Intrinsic<"HEXAGON_V6_pred_scalar2v2">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_pred_scalar2v2_128B,QV_ftype_SI,1)
+// tag : V6_pred_scalar2v2_128B
+def int_hexagon_V6_pred_scalar2v2_128B :
+Hexagon_V62_v128ii_Intrinsic<"HEXAGON_V6_pred_scalar2v2_128B">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_shuffeqw,QV_ftype_QVQV,2)
+// tag : V6_shuffeqw
+def int_hexagon_V6_shuffeqw :
+Hexagon_V62_v64iv64iv64i_Intrinsic<"HEXAGON_V6_shuffeqw">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_shuffeqw_128B,QV_ftype_QVQV,2)
+// tag : V6_shuffeqw_128B
+def int_hexagon_V6_shuffeqw_128B :
+Hexagon_V62_v128iv128iv128i_Intrinsic<"HEXAGON_V6_shuffeqw_128B">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_shuffeqh,QV_ftype_QVQV,2)
+// tag : V6_shuffeqh
+def int_hexagon_V6_shuffeqh :
+Hexagon_V62_v64iv64iv64i_Intrinsic<"HEXAGON_V6_shuffeqh">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_shuffeqh_128B,QV_ftype_QVQV,2)
+// tag : V6_shuffeqh_128B
+def int_hexagon_V6_shuffeqh_128B :
+Hexagon_V62_v128iv128iv128i_Intrinsic<"HEXAGON_V6_shuffeqh_128B">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vmaxb,VI_ftype_VIVI,2)
+// tag : V6_vmaxb
+def int_hexagon_V6_vmaxb :
+Hexagon_V62_v512v512v512_Intrinsic<"HEXAGON_V6_vmaxb">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vmaxb_128B,VI_ftype_VIVI,2)
+// tag : V6_vmaxb_128B
+def int_hexagon_V6_vmaxb_128B :
+Hexagon_V62_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vmaxb_128B">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vminb,VI_ftype_VIVI,2)
+// tag : V6_vminb
+def int_hexagon_V6_vminb :
+Hexagon_V62_v512v512v512_Intrinsic<"HEXAGON_V6_vminb">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vminb_128B,VI_ftype_VIVI,2)
+// tag : V6_vminb_128B
+def int_hexagon_V6_vminb_128B :
+Hexagon_V62_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vminb_128B">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vsatuwuh,VI_ftype_VIVI,2)
+// tag : V6_vsatuwuh
+def int_hexagon_V6_vsatuwuh :
+Hexagon_V62_v512v512v512_Intrinsic<"HEXAGON_V6_vsatuwuh">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vsatuwuh_128B,VI_ftype_VIVI,2)
+// tag : V6_vsatuwuh_128B
+def int_hexagon_V6_vsatuwuh_128B :
+Hexagon_V62_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vsatuwuh_128B">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_lvsplath,VI_ftype_SI,1)
+// tag : V6_lvsplath
+def int_hexagon_V6_lvsplath :
+Hexagon_V62_v512i_Intrinsic<"HEXAGON_V6_lvsplath">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_lvsplath_128B,VI_ftype_SI,1)
+// tag : V6_lvsplath_128B
+def int_hexagon_V6_lvsplath_128B :
+Hexagon_V62_v1024i_Intrinsic<"HEXAGON_V6_lvsplath_128B">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_lvsplatb,VI_ftype_SI,1)
+// tag : V6_lvsplatb
+def int_hexagon_V6_lvsplatb :
+Hexagon_V62_v512i_Intrinsic<"HEXAGON_V6_lvsplatb">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_lvsplatb_128B,VI_ftype_SI,1)
+// tag : V6_lvsplatb_128B
+def int_hexagon_V6_lvsplatb_128B :
+Hexagon_V62_v1024i_Intrinsic<"HEXAGON_V6_lvsplatb_128B">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vaddclbw,VI_ftype_VIVI,2)
+// tag : V6_vaddclbw
+def int_hexagon_V6_vaddclbw :
+Hexagon_V62_v512v512v512_Intrinsic<"HEXAGON_V6_vaddclbw">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vaddclbw_128B,VI_ftype_VIVI,2)
+// tag : V6_vaddclbw_128B
+def int_hexagon_V6_vaddclbw_128B :
+Hexagon_V62_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vaddclbw_128B">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vaddclbh,VI_ftype_VIVI,2)
+// tag : V6_vaddclbh
+def int_hexagon_V6_vaddclbh :
+Hexagon_V62_v512v512v512_Intrinsic<"HEXAGON_V6_vaddclbh">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vaddclbh_128B,VI_ftype_VIVI,2)
+// tag : V6_vaddclbh_128B
+def int_hexagon_V6_vaddclbh_128B :
+Hexagon_V62_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vaddclbh_128B">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vlutvvbi,VI_ftype_VIVISI,3)
+// tag : V6_vlutvvbi
+def int_hexagon_V6_vlutvvbi :
+Hexagon_V62_v512v512v512i_Intrinsic<"HEXAGON_V6_vlutvvbi">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vlutvvbi_128B,VI_ftype_VIVISI,3)
+// tag : V6_vlutvvbi_128B
+def int_hexagon_V6_vlutvvbi_128B :
+Hexagon_V62_v1024v1024v1024i_Intrinsic<"HEXAGON_V6_vlutvvbi_128B">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vlutvvb_oracci,VI_ftype_VIVIVISI,4)
+// tag : V6_vlutvvb_oracci
+def int_hexagon_V6_vlutvvb_oracci :
+Hexagon_V62_v512v512v512v512i_Intrinsic<"HEXAGON_V6_vlutvvb_oracci">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vlutvvb_oracci_128B,VI_ftype_VIVIVISI,4)
+// tag : V6_vlutvvb_oracci_128B
+def int_hexagon_V6_vlutvvb_oracci_128B :
+Hexagon_V62_v1024v1024v1024v1024i_Intrinsic<"HEXAGON_V6_vlutvvb_oracci_128B">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vlutvwhi,VD_ftype_VIVISI,3)
+// tag : V6_vlutvwhi
+def int_hexagon_V6_vlutvwhi :
+Hexagon_V62_v1024v512v512i_Intrinsic<"HEXAGON_V6_vlutvwhi">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vlutvwhi_128B,VD_ftype_VIVISI,3)
+// tag : V6_vlutvwhi_128B
+def int_hexagon_V6_vlutvwhi_128B :
+Hexagon_V62_v2048v1024v1024i_Intrinsic<"HEXAGON_V6_vlutvwhi_128B">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vlutvwh_oracci,VD_ftype_VDVIVISI,4)
+// tag : V6_vlutvwh_oracci
+def int_hexagon_V6_vlutvwh_oracci :
+Hexagon_V62_v1024v1024v512v512i_Intrinsic<"HEXAGON_V6_vlutvwh_oracci">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vlutvwh_oracci_128B,VD_ftype_VDVIVISI,4)
+// tag : V6_vlutvwh_oracci_128B
+def int_hexagon_V6_vlutvwh_oracci_128B :
+Hexagon_V62_v2048v2048v1024v1024i_Intrinsic<"HEXAGON_V6_vlutvwh_oracci_128B">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vlutvvb_nm,VI_ftype_VIVISI,3)
+// tag : V6_vlutvvb_nm
+def int_hexagon_V6_vlutvvb_nm :
+Hexagon_V62_v512v512v512i_Intrinsic<"HEXAGON_V6_vlutvvb_nm">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vlutvvb_nm_128B,VI_ftype_VIVISI,3)
+// tag : V6_vlutvvb_nm_128B
+def int_hexagon_V6_vlutvvb_nm_128B :
+Hexagon_V62_v1024v1024v1024i_Intrinsic<"HEXAGON_V6_vlutvvb_nm_128B">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vlutvwh_nm,VD_ftype_VIVISI,3)
+// tag : V6_vlutvwh_nm
+def int_hexagon_V6_vlutvwh_nm :
+Hexagon_V62_v1024v512v512i_Intrinsic<"HEXAGON_V6_vlutvwh_nm">;
+
+//
+// BUILTIN_INFO(HEXAGON.V6_vlutvwh_nm_128B,VD_ftype_VIVISI,3)
+// tag : V6_vlutvwh_nm_128B
+def int_hexagon_V6_vlutvwh_nm_128B :
+Hexagon_V62_v2048v1024v1024i_Intrinsic<"HEXAGON_V6_vlutvwh_nm_128B">;
+
diff --git a/contrib/llvm/include/llvm/IR/IntrinsicsNVVM.td b/contrib/llvm/include/llvm/IR/IntrinsicsNVVM.td
index f035ac3..68f123d 100644
--- a/contrib/llvm/include/llvm/IR/IntrinsicsNVVM.td
+++ b/contrib/llvm/include/llvm/IR/IntrinsicsNVVM.td
@@ -11,6 +11,27 @@
//
//===----------------------------------------------------------------------===//
+// The following intrinsics were once defined here, but are now auto-upgraded
+// to target-generic LLVM intrinsics.
+//
+// * llvm.nvvm.brev32 --> llvm.bitreverse.i32
+// * llvm.nvvm.brev64 --> llvm.bitreverse.i64
+// * llvm.nvvm.clz.i --> llvm.ctlz.i32
+// * llvm.nvvm.clz.ll --> trunc i64 llvm.ctlz.i64(x) to i32
+// * llvm.nvvm.popc.i --> llvm.ctpop.i32
+// * llvm.nvvm.popc.ll --> trunc i64 llvm.ctpop.i64 to i32
+// * llvm.nvvm.abs.i --> select(x >= -x, x, -x)
+// * llvm.nvvm.abs.ll --> ibid.
+// * llvm.nvvm.max.i --> select(x sge y, x, y)
+// * llvm.nvvm.max.ll --> ibid.
+// * llvm.nvvm.max.ui --> select(x uge y, x, y)
+// * llvm.nvvm.max.ull --> ibid.
+// * llvm.nvvm.max.i --> select(x sle y, x, y)
+// * llvm.nvvm.max.ll --> ibid.
+// * llvm.nvvm.max.ui --> select(x ule y, x, y)
+// * llvm.nvvm.max.ull --> ibid.
+// * llvm.nvvm.h2f --> llvm.convert.to.fp16.f32
+
def llvm_anyi64ptr_ty : LLVMAnyPointerType<llvm_i64_ty>; // (space)i64*
//
@@ -18,16 +39,6 @@ def llvm_anyi64ptr_ty : LLVMAnyPointerType<llvm_i64_ty>; // (space)i64*
//
let TargetPrefix = "nvvm" in {
- def int_nvvm_clz_i : GCCBuiltin<"__nvvm_clz_i">,
- Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrNoMem]>;
- def int_nvvm_clz_ll : GCCBuiltin<"__nvvm_clz_ll">,
- Intrinsic<[llvm_i32_ty], [llvm_i64_ty], [IntrNoMem]>;
-
- def int_nvvm_popc_i : GCCBuiltin<"__nvvm_popc_i">,
- Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrNoMem]>;
- def int_nvvm_popc_ll : GCCBuiltin<"__nvvm_popc_ll">,
- Intrinsic<[llvm_i32_ty], [llvm_i64_ty], [IntrNoMem]>;
-
def int_nvvm_prmt : GCCBuiltin<"__nvvm_prmt">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
[IntrNoMem, Commutative]>;
@@ -36,34 +47,6 @@ let TargetPrefix = "nvvm" in {
// Min Max
//
- def int_nvvm_min_i : GCCBuiltin<"__nvvm_min_i">,
- Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
- [IntrNoMem, Commutative]>;
- def int_nvvm_min_ui : GCCBuiltin<"__nvvm_min_ui">,
- Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
- [IntrNoMem, Commutative]>;
-
- def int_nvvm_min_ll : GCCBuiltin<"__nvvm_min_ll">,
- Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty],
- [IntrNoMem, Commutative]>;
- def int_nvvm_min_ull : GCCBuiltin<"__nvvm_min_ull">,
- Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty],
- [IntrNoMem, Commutative]>;
-
- def int_nvvm_max_i : GCCBuiltin<"__nvvm_max_i">,
- Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
- [IntrNoMem, Commutative]>;
- def int_nvvm_max_ui : GCCBuiltin<"__nvvm_max_ui">,
- Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
- [IntrNoMem, Commutative]>;
-
- def int_nvvm_max_ll : GCCBuiltin<"__nvvm_max_ll">,
- Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty],
- [IntrNoMem, Commutative]>;
- def int_nvvm_max_ull : GCCBuiltin<"__nvvm_max_ull">,
- Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty],
- [IntrNoMem, Commutative]>;
-
def int_nvvm_fmin_f : GCCBuiltin<"__nvvm_fmin_f">,
Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty],
[IntrNoMem, Commutative]>;
@@ -201,15 +184,6 @@ let TargetPrefix = "nvvm" in {
[IntrNoMem, Commutative]>;
//
-// Brev
-//
-
- def int_nvvm_brev32 : GCCBuiltin<"__nvvm_brev32">,
- Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrNoMem]>;
- def int_nvvm_brev64 : GCCBuiltin<"__nvvm_brev64">,
- Intrinsic<[llvm_i64_ty], [llvm_i64_ty], [IntrNoMem]>;
-
-//
// Sad
//
@@ -242,16 +216,10 @@ let TargetPrefix = "nvvm" in {
// Abs
//
- def int_nvvm_abs_i : GCCBuiltin<"__nvvm_abs_i">,
- Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrNoMem]>;
- def int_nvvm_abs_ll : GCCBuiltin<"__nvvm_abs_ll">,
- Intrinsic<[llvm_i64_ty], [llvm_i64_ty], [IntrNoMem]>;
-
def int_nvvm_fabs_ftz_f : GCCBuiltin<"__nvvm_fabs_ftz_f">,
Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
def int_nvvm_fabs_f : GCCBuiltin<"__nvvm_fabs_f">,
Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
-
def int_nvvm_fabs_d : GCCBuiltin<"__nvvm_fabs_d">,
Intrinsic<[llvm_double_ty], [llvm_double_ty], [IntrNoMem]>;
@@ -700,9 +668,6 @@ let TargetPrefix = "nvvm" in {
def int_nvvm_f2h_rn : GCCBuiltin<"__nvvm_f2h_rn">,
Intrinsic<[llvm_i16_ty], [llvm_float_ty], [IntrNoMem]>;
- def int_nvvm_h2f : GCCBuiltin<"__nvvm_h2f">,
- Intrinsic<[llvm_float_ty], [llvm_i16_ty], [IntrNoMem]>;
-
//
// Bitcast
//
@@ -768,6 +733,13 @@ let TargetPrefix = "nvvm" in {
// intrinsics in this file, this one is a user-facing API.
def int_nvvm_barrier0 : GCCBuiltin<"__syncthreads">,
Intrinsic<[], [], [IntrConvergent]>;
+ // Synchronize all threads in the CTA at barrier 'n'.
+ def int_nvvm_barrier_n : GCCBuiltin<"__nvvm_bar_n">,
+ Intrinsic<[], [llvm_i32_ty], [IntrConvergent]>;
+ // Synchronize 'm', a multiple of warp size, (arg 2) threads in
+ // the CTA at barrier 'n' (arg 1).
+ def int_nvvm_barrier : GCCBuiltin<"__nvvm_bar">,
+ Intrinsic<[], [llvm_i32_ty, llvm_i32_ty], [IntrConvergent]>;
def int_nvvm_barrier0_popc : GCCBuiltin<"__nvvm_bar0_popc">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrConvergent]>;
def int_nvvm_barrier0_and : GCCBuiltin<"__nvvm_bar0_and">,
diff --git a/contrib/llvm/include/llvm/IR/IntrinsicsPowerPC.td b/contrib/llvm/include/llvm/IR/IntrinsicsPowerPC.td
index 12e23b6..6321bb8 100644
--- a/contrib/llvm/include/llvm/IR/IntrinsicsPowerPC.td
+++ b/contrib/llvm/include/llvm/IR/IntrinsicsPowerPC.td
@@ -203,19 +203,19 @@ let TargetPrefix = "ppc" in { // All intrinsics start with "llvm.ppc.".
// source address with a single pointer.
def int_ppc_altivec_stvx :
Intrinsic<[], [llvm_v4i32_ty, llvm_ptr_ty],
- [IntrArgMemOnly]>;
+ [IntrWriteMem, IntrArgMemOnly]>;
def int_ppc_altivec_stvxl :
Intrinsic<[], [llvm_v4i32_ty, llvm_ptr_ty],
- [IntrArgMemOnly]>;
+ [IntrWriteMem, IntrArgMemOnly]>;
def int_ppc_altivec_stvebx :
Intrinsic<[], [llvm_v16i8_ty, llvm_ptr_ty],
- [IntrArgMemOnly]>;
+ [IntrWriteMem, IntrArgMemOnly]>;
def int_ppc_altivec_stvehx :
Intrinsic<[], [llvm_v8i16_ty, llvm_ptr_ty],
- [IntrArgMemOnly]>;
+ [IntrWriteMem, IntrArgMemOnly]>;
def int_ppc_altivec_stvewx :
Intrinsic<[], [llvm_v4i32_ty, llvm_ptr_ty],
- [IntrArgMemOnly]>;
+ [IntrWriteMem, IntrArgMemOnly]>;
// Comparisons setting a vector.
def int_ppc_altivec_vcmpbfp : GCCBuiltin<"__builtin_altivec_vcmpbfp">,
@@ -749,20 +749,20 @@ def int_ppc_vsx_lxvll :
IntrArgMemOnly]>;
def int_ppc_vsx_stxvl :
Intrinsic<[], [llvm_v4i32_ty, llvm_ptr_ty, llvm_i64_ty],
- [IntrArgMemOnly]>;
+ [IntrWriteMem, IntrArgMemOnly]>;
def int_ppc_vsx_stxvll :
Intrinsic<[], [llvm_v4i32_ty, llvm_ptr_ty, llvm_i64_ty],
- [IntrArgMemOnly]>;
+ [IntrWriteMem, IntrArgMemOnly]>;
// Vector store.
-def int_ppc_vsx_stxvw4x :
- Intrinsic<[], [llvm_v4i32_ty, llvm_ptr_ty], [IntrArgMemOnly]>;
-def int_ppc_vsx_stxvd2x :
- Intrinsic<[], [llvm_v2f64_ty, llvm_ptr_ty], [IntrArgMemOnly]>;
-def int_ppc_vsx_stxvw4x_be :
- Intrinsic<[], [llvm_v4i32_ty, llvm_ptr_ty], [IntrArgMemOnly]>;
-def int_ppc_vsx_stxvd2x_be :
- Intrinsic<[], [llvm_v2f64_ty, llvm_ptr_ty], [IntrArgMemOnly]>;
+def int_ppc_vsx_stxvw4x : Intrinsic<[], [llvm_v4i32_ty, llvm_ptr_ty],
+ [IntrWriteMem, IntrArgMemOnly]>;
+def int_ppc_vsx_stxvd2x : Intrinsic<[], [llvm_v2f64_ty, llvm_ptr_ty],
+ [IntrWriteMem, IntrArgMemOnly]>;
+def int_ppc_vsx_stxvw4x_be : Intrinsic<[], [llvm_v4i32_ty, llvm_ptr_ty],
+ [IntrWriteMem, IntrArgMemOnly]>;
+def int_ppc_vsx_stxvd2x_be : Intrinsic<[], [llvm_v2f64_ty, llvm_ptr_ty],
+ [IntrWriteMem, IntrArgMemOnly]>;
// Vector and scalar maximum.
def int_ppc_vsx_xvmaxdp : PowerPC_VSX_Vec_DDD_Intrinsic<"xvmaxdp">;
def int_ppc_vsx_xvmaxsp : PowerPC_VSX_Vec_FFF_Intrinsic<"xvmaxsp">;
@@ -953,7 +953,7 @@ class PowerPC_QPX_LoadPerm_Intrinsic<string GCCIntSuffix>
class PowerPC_QPX_Store_Intrinsic<string GCCIntSuffix>
: PowerPC_QPX_Intrinsic<GCCIntSuffix,
[], [llvm_v4f64_ty, llvm_ptr_ty],
- [IntrArgMemOnly]>;
+ [IntrWriteMem, IntrArgMemOnly]>;
//===----------------------------------------------------------------------===//
// PowerPC QPX Intrinsic Definitions.
@@ -1132,4 +1132,6 @@ def int_ppc_tsuspend : GCCBuiltin<"__builtin_tsuspend">,
def int_ppc_ttest : GCCBuiltin<"__builtin_ttest">,
Intrinsic<[llvm_i64_ty], [], []>;
+
+def int_ppc_cfence : Intrinsic<[], [llvm_anyint_ty], []>;
}
diff --git a/contrib/llvm/include/llvm/IR/IntrinsicsSystemZ.td b/contrib/llvm/include/llvm/IR/IntrinsicsSystemZ.td
index 9be37d3..98065bc 100644
--- a/contrib/llvm/include/llvm/IR/IntrinsicsSystemZ.td
+++ b/contrib/llvm/include/llvm/IR/IntrinsicsSystemZ.td
@@ -373,6 +373,49 @@ let TargetPrefix = "s390" in {
def int_s390_vfidb : Intrinsic<[llvm_v2f64_ty],
[llvm_v2f64_ty, llvm_i32_ty, llvm_i32_ty],
[IntrNoMem]>;
+
+ // Instructions from the Vector Enhancements Facility 1
+ def int_s390_vbperm : SystemZBinaryConv<"vbperm", llvm_v2i64_ty,
+ llvm_v16i8_ty>;
+
+ 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]>;
+
+ def int_s390_vfmaxdb : Intrinsic<[llvm_v2f64_ty],
+ [llvm_v2f64_ty, llvm_v2f64_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+ def int_s390_vfmindb : Intrinsic<[llvm_v2f64_ty],
+ [llvm_v2f64_ty, llvm_v2f64_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+ def int_s390_vfmaxsb : Intrinsic<[llvm_v4f32_ty],
+ [llvm_v4f32_ty, llvm_v4f32_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+ def int_s390_vfminsb : Intrinsic<[llvm_v4f32_ty],
+ [llvm_v4f32_ty, llvm_v4f32_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+
+ def int_s390_vfcesbs : SystemZBinaryConvCC<llvm_v4i32_ty, llvm_v4f32_ty>;
+ def int_s390_vfchsbs : SystemZBinaryConvCC<llvm_v4i32_ty, llvm_v4f32_ty>;
+ def int_s390_vfchesbs : SystemZBinaryConvCC<llvm_v4i32_ty, llvm_v4f32_ty>;
+
+ def int_s390_vftcisb : SystemZBinaryConvIntCC<llvm_v4i32_ty, llvm_v4f32_ty>;
+
+ def int_s390_vfisb : Intrinsic<[llvm_v4f32_ty],
+ [llvm_v4f32_ty, llvm_i32_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+
+ // Instructions from the Vector Packed Decimal Facility
+ def int_s390_vlrl : GCCBuiltin<"__builtin_s390_vlrl">,
+ Intrinsic<[llvm_v16i8_ty], [llvm_i32_ty, llvm_ptr_ty],
+ [IntrReadMem, IntrArgMemOnly]>;
+
+ def int_s390_vstrl : GCCBuiltin<"__builtin_s390_vstrl">,
+ Intrinsic<[], [llvm_v16i8_ty, llvm_i32_ty, llvm_ptr_ty],
+ // In fact write-only but there's no property
+ // for that.
+ [IntrArgMemOnly]>;
}
//===----------------------------------------------------------------------===//
diff --git a/contrib/llvm/include/llvm/IR/IntrinsicsWebAssembly.td b/contrib/llvm/include/llvm/IR/IntrinsicsWebAssembly.td
index 4234c46..640ef62 100644
--- a/contrib/llvm/include/llvm/IR/IntrinsicsWebAssembly.td
+++ b/contrib/llvm/include/llvm/IR/IntrinsicsWebAssembly.td
@@ -17,6 +17,10 @@ let TargetPrefix = "wasm" in { // All intrinsics start with "llvm.wasm.".
// Note that current_memory is not IntrNoMem because it must be sequenced with
// respect to grow_memory calls.
def int_wasm_current_memory : Intrinsic<[llvm_anyint_ty], [], [IntrReadMem]>;
-def int_wasm_grow_memory : Intrinsic<[], [llvm_anyint_ty], []>;
+def int_wasm_grow_memory : Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>], []>;
+
+// Exception handling intrinsics
+def int_wasm_throw: Intrinsic<[], [llvm_i32_ty, llvm_ptr_ty], [Throws]>;
+def int_wasm_rethrow: Intrinsic<[], [], [Throws]>;
}
diff --git a/contrib/llvm/include/llvm/IR/IntrinsicsX86.td b/contrib/llvm/include/llvm/IR/IntrinsicsX86.td
index 85966af..80c5287 100644
--- a/contrib/llvm/include/llvm/IR/IntrinsicsX86.td
+++ b/contrib/llvm/include/llvm/IR/IntrinsicsX86.td
@@ -785,12 +785,6 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
[IntrNoMem, Commutative]>;
}
-// Cacheability support ops
-let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
- def int_x86_sse41_movntdqa : GCCBuiltin<"__builtin_ia32_movntdqa">,
- Intrinsic<[llvm_v2i64_ty], [llvm_ptr_ty], [IntrReadMem]>;
-}
-
// Test instruction with bitwise comparison.
let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
def int_x86_sse41_ptestz : GCCBuiltin<"__builtin_ia32_ptestz128">,
@@ -2346,8 +2340,6 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
def int_x86_avx2_mpsadbw : GCCBuiltin<"__builtin_ia32_mpsadbw256">,
Intrinsic<[llvm_v16i16_ty], [llvm_v32i8_ty, llvm_v32i8_ty,
llvm_i8_ty], [IntrNoMem, Commutative]>;
- def int_x86_avx2_movntdqa : GCCBuiltin<"__builtin_ia32_movntdqa256">,
- Intrinsic<[llvm_v4i64_ty], [llvm_ptr_ty], [IntrReadMem]>;
}
//===----------------------------------------------------------------------===//
@@ -3033,17 +3025,6 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
def int_x86_xop_vfrcz_ps_256 : GCCBuiltin<"__builtin_ia32_vfrczps256">,
Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty], [IntrNoMem]>;
- def int_x86_xop_vpcmov :
- GCCBuiltin<"__builtin_ia32_vpcmov">,
- Intrinsic<[llvm_v2i64_ty],
- [llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty],
- [IntrNoMem]>;
- def int_x86_xop_vpcmov_256 :
- GCCBuiltin<"__builtin_ia32_vpcmov_256">,
- Intrinsic<[llvm_v4i64_ty],
- [llvm_v4i64_ty, llvm_v4i64_ty, llvm_v4i64_ty],
- [IntrNoMem]>;
-
def int_x86_xop_vpcomb : GCCBuiltin<"__builtin_ia32_vpcomb">,
Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty,
llvm_i8_ty], [IntrNoMem]>;
@@ -3240,6 +3221,29 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
}
//===----------------------------------------------------------------------===//
+// LWP
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_llwpcb :
+ GCCBuiltin<"__builtin_ia32_llwpcb">,
+ Intrinsic<[], [llvm_ptr_ty], []>;
+ def int_x86_slwpcb :
+ GCCBuiltin<"__builtin_ia32_slwpcb">,
+ Intrinsic<[llvm_ptr_ty], [], []>;
+ def int_x86_lwpins32 :
+ GCCBuiltin<"__builtin_ia32_lwpins32">,
+ Intrinsic<[llvm_i8_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], []>;
+ def int_x86_lwpins64 :
+ GCCBuiltin<"__builtin_ia32_lwpins64">,
+ Intrinsic<[llvm_i8_ty], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], []>;
+ def int_x86_lwpval32 :
+ GCCBuiltin<"__builtin_ia32_lwpval32">,
+ Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], []>;
+ def int_x86_lwpval64 :
+ GCCBuiltin<"__builtin_ia32_lwpval64">,
+ Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], []>;
+}
+
+//===----------------------------------------------------------------------===//
// MMX
// Empty MMX state op.
@@ -3881,74 +3885,22 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
def int_x86_avx512_cvtq2mask_512 : GCCBuiltin<"__builtin_ia32_cvtq2mask512">,
Intrinsic<[llvm_i8_ty], [llvm_v8i64_ty], [IntrNoMem]>;
- def int_x86_avx512_cvtmask2b_128 : GCCBuiltin<"__builtin_ia32_cvtmask2b128">,
- Intrinsic<[llvm_v16i8_ty], [llvm_i16_ty], [IntrNoMem]>;
- def int_x86_avx512_cvtmask2b_256 : GCCBuiltin<"__builtin_ia32_cvtmask2b256">,
- Intrinsic<[llvm_v32i8_ty], [llvm_i32_ty], [IntrNoMem]>;
- def int_x86_avx512_cvtmask2b_512 : GCCBuiltin<"__builtin_ia32_cvtmask2b512">,
- Intrinsic<[llvm_v64i8_ty], [llvm_i64_ty], [IntrNoMem]>;
-
- def int_x86_avx512_cvtmask2w_128 : GCCBuiltin<"__builtin_ia32_cvtmask2w128">,
- Intrinsic<[llvm_v8i16_ty], [llvm_i8_ty], [IntrNoMem]>;
- def int_x86_avx512_cvtmask2w_256 : GCCBuiltin<"__builtin_ia32_cvtmask2w256">,
- Intrinsic<[llvm_v16i16_ty], [llvm_i16_ty], [IntrNoMem]>;
- def int_x86_avx512_cvtmask2w_512 : GCCBuiltin<"__builtin_ia32_cvtmask2w512">,
- Intrinsic<[llvm_v32i16_ty], [llvm_i32_ty], [IntrNoMem]>;
-
- def int_x86_avx512_cvtmask2d_128 : GCCBuiltin<"__builtin_ia32_cvtmask2d128">,
- Intrinsic<[llvm_v4i32_ty], [llvm_i8_ty], [IntrNoMem]>;
- def int_x86_avx512_cvtmask2d_256 : GCCBuiltin<"__builtin_ia32_cvtmask2d256">,
- Intrinsic<[llvm_v8i32_ty], [llvm_i8_ty], [IntrNoMem]>;
- def int_x86_avx512_cvtmask2d_512 : GCCBuiltin<"__builtin_ia32_cvtmask2d512">,
- Intrinsic<[llvm_v16i32_ty], [llvm_i16_ty], [IntrNoMem]>;
-
- def int_x86_avx512_cvtmask2q_128 : GCCBuiltin<"__builtin_ia32_cvtmask2q128">,
- Intrinsic<[llvm_v2i64_ty], [llvm_i8_ty], [IntrNoMem]>;
- def int_x86_avx512_cvtmask2q_256 : GCCBuiltin<"__builtin_ia32_cvtmask2q256">,
- Intrinsic<[llvm_v4i64_ty], [llvm_i8_ty], [IntrNoMem]>;
- def int_x86_avx512_cvtmask2q_512 : GCCBuiltin<"__builtin_ia32_cvtmask2q512">,
- Intrinsic<[llvm_v8i64_ty], [llvm_i8_ty], [IntrNoMem]>;
-
}
// Pack ops.
let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
- def int_x86_avx512_mask_packsswb_128 : GCCBuiltin<"__builtin_ia32_packsswb128_mask">,
- Intrinsic<[llvm_v16i8_ty], [llvm_v8i16_ty, llvm_v8i16_ty,
- llvm_v16i8_ty, llvm_i16_ty], [IntrNoMem]>;
- def int_x86_avx512_mask_packsswb_256 : GCCBuiltin<"__builtin_ia32_packsswb256_mask">,
- Intrinsic<[llvm_v32i8_ty], [llvm_v16i16_ty,llvm_v16i16_ty,
- llvm_v32i8_ty, llvm_i32_ty], [IntrNoMem]>;
- def int_x86_avx512_mask_packsswb_512 : GCCBuiltin<"__builtin_ia32_packsswb512_mask">,
- Intrinsic<[llvm_v64i8_ty], [llvm_v32i16_ty,llvm_v32i16_ty,
- llvm_v64i8_ty, llvm_i64_ty], [IntrNoMem]>;
- def int_x86_avx512_mask_packssdw_128 : GCCBuiltin<"__builtin_ia32_packssdw128_mask">,
- Intrinsic<[llvm_v8i16_ty], [llvm_v4i32_ty, llvm_v4i32_ty,
- llvm_v8i16_ty, llvm_i8_ty], [IntrNoMem]>;
- def int_x86_avx512_mask_packssdw_256 : GCCBuiltin<"__builtin_ia32_packssdw256_mask">,
- Intrinsic<[llvm_v16i16_ty], [llvm_v8i32_ty, llvm_v8i32_ty,
- llvm_v16i16_ty, llvm_i16_ty], [IntrNoMem]>;
- def int_x86_avx512_mask_packssdw_512 : GCCBuiltin<"__builtin_ia32_packssdw512_mask">,
- Intrinsic<[llvm_v32i16_ty], [llvm_v16i32_ty, llvm_v16i32_ty,
- llvm_v32i16_ty, llvm_i32_ty], [IntrNoMem]>;
- def int_x86_avx512_mask_packuswb_128 : GCCBuiltin<"__builtin_ia32_packuswb128_mask">,
- Intrinsic<[llvm_v16i8_ty], [llvm_v8i16_ty, llvm_v8i16_ty,
- llvm_v16i8_ty, llvm_i16_ty], [IntrNoMem]>;
- def int_x86_avx512_mask_packuswb_256 : GCCBuiltin<"__builtin_ia32_packuswb256_mask">,
- Intrinsic<[llvm_v32i8_ty], [llvm_v16i16_ty,llvm_v16i16_ty,
- llvm_v32i8_ty, llvm_i32_ty], [IntrNoMem]>;
- def int_x86_avx512_mask_packuswb_512 : GCCBuiltin<"__builtin_ia32_packuswb512_mask">,
- Intrinsic<[llvm_v64i8_ty], [llvm_v32i16_ty,llvm_v32i16_ty,
- llvm_v64i8_ty, llvm_i64_ty], [IntrNoMem]>;
- def int_x86_avx512_mask_packusdw_128 : GCCBuiltin<"__builtin_ia32_packusdw128_mask">,
- Intrinsic<[llvm_v8i16_ty], [llvm_v4i32_ty, llvm_v4i32_ty,
- llvm_v8i16_ty, llvm_i8_ty], [IntrNoMem]>;
- def int_x86_avx512_mask_packusdw_256 : GCCBuiltin<"__builtin_ia32_packusdw256_mask">,
- Intrinsic<[llvm_v16i16_ty], [llvm_v8i32_ty, llvm_v8i32_ty,
- llvm_v16i16_ty, llvm_i16_ty], [IntrNoMem]>;
- def int_x86_avx512_mask_packusdw_512 : GCCBuiltin<"__builtin_ia32_packusdw512_mask">,
- Intrinsic<[llvm_v32i16_ty], [llvm_v16i32_ty, llvm_v16i32_ty,
- llvm_v32i16_ty, llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx512_packsswb_512 : GCCBuiltin<"__builtin_ia32_packsswb512">,
+ Intrinsic<[llvm_v64i8_ty], [llvm_v32i16_ty,llvm_v32i16_ty],
+ [IntrNoMem]>;
+ def int_x86_avx512_packssdw_512 : GCCBuiltin<"__builtin_ia32_packssdw512">,
+ Intrinsic<[llvm_v32i16_ty], [llvm_v16i32_ty, llvm_v16i32_ty],
+ [IntrNoMem]>;
+ def int_x86_avx512_packuswb_512 : GCCBuiltin<"__builtin_ia32_packuswb512">,
+ Intrinsic<[llvm_v64i8_ty], [llvm_v32i16_ty,llvm_v32i16_ty],
+ [IntrNoMem]>;
+ def int_x86_avx512_packusdw_512 : GCCBuiltin<"__builtin_ia32_packusdw512">,
+ Intrinsic<[llvm_v32i16_ty], [llvm_v16i32_ty, llvm_v16i32_ty],
+ [IntrNoMem]>;
}
// Vector convert
@@ -4595,39 +4547,15 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
def int_x86_avx512_mask_div_pd_512 : GCCBuiltin<"__builtin_ia32_divpd512_mask">,
Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_v8f64_ty,
llvm_v8f64_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>;
- def int_x86_avx512_mask_max_ps_128 : GCCBuiltin<"__builtin_ia32_maxps_mask">,
- Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty,
- llvm_v4f32_ty, llvm_i8_ty], [IntrNoMem]>;
- def int_x86_avx512_mask_max_ps_256 : GCCBuiltin<"__builtin_ia32_maxps256_mask">,
- Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_v8f32_ty,
- llvm_v8f32_ty, llvm_i8_ty], [IntrNoMem]>;
def int_x86_avx512_mask_max_ps_512 : GCCBuiltin<"__builtin_ia32_maxps512_mask">,
Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_v16f32_ty,
llvm_v16f32_ty, llvm_i16_ty, llvm_i32_ty], [IntrNoMem]>;
- def int_x86_avx512_mask_max_pd_128 : GCCBuiltin<"__builtin_ia32_maxpd_mask">,
- Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty,
- llvm_v2f64_ty, llvm_i8_ty], [IntrNoMem]>;
- def int_x86_avx512_mask_max_pd_256 : GCCBuiltin<"__builtin_ia32_maxpd256_mask">,
- Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_v4f64_ty,
- llvm_v4f64_ty, llvm_i8_ty], [IntrNoMem]>;
def int_x86_avx512_mask_max_pd_512 : GCCBuiltin<"__builtin_ia32_maxpd512_mask">,
Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_v8f64_ty,
llvm_v8f64_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>;
- def int_x86_avx512_mask_min_ps_128 : GCCBuiltin<"__builtin_ia32_minps_mask">,
- Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty,
- llvm_v4f32_ty, llvm_i8_ty], [IntrNoMem]>;
- def int_x86_avx512_mask_min_ps_256 : GCCBuiltin<"__builtin_ia32_minps256_mask">,
- Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_v8f32_ty,
- llvm_v8f32_ty, llvm_i8_ty], [IntrNoMem]>;
def int_x86_avx512_mask_min_ps_512 : GCCBuiltin<"__builtin_ia32_minps512_mask">,
Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_v16f32_ty,
llvm_v16f32_ty, llvm_i16_ty, llvm_i32_ty], [IntrNoMem]>;
- def int_x86_avx512_mask_min_pd_128 : GCCBuiltin<"__builtin_ia32_minpd_mask">,
- Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty,
- llvm_v2f64_ty, llvm_i8_ty], [IntrNoMem]>;
- def int_x86_avx512_mask_min_pd_256 : GCCBuiltin<"__builtin_ia32_minpd256_mask">,
- Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_v4f64_ty,
- llvm_v4f64_ty, llvm_i8_ty], [IntrNoMem]>;
def int_x86_avx512_mask_min_pd_512 : GCCBuiltin<"__builtin_ia32_minpd512_mask">,
Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_v8f64_ty,
llvm_v8f64_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>;
@@ -5481,32 +5409,6 @@ let TargetPrefix = "x86" in {
Intrinsic<[llvm_v8i64_ty],
[llvm_v8i64_ty, llvm_v8i64_ty, llvm_i8_ty],
[IntrNoMem]>;
-
- def int_x86_avx512_mask_lzcnt_d_128 :
- Intrinsic<[llvm_v4i32_ty],
- [llvm_v4i32_ty, llvm_v4i32_ty, llvm_i8_ty],
- [IntrNoMem]>;
- def int_x86_avx512_mask_lzcnt_d_256 :
- Intrinsic<[llvm_v8i32_ty],
- [llvm_v8i32_ty, llvm_v8i32_ty, llvm_i8_ty],
- [IntrNoMem]>;
- def int_x86_avx512_mask_lzcnt_d_512 :
- Intrinsic<[llvm_v16i32_ty],
- [llvm_v16i32_ty, llvm_v16i32_ty, llvm_i16_ty],
- [IntrNoMem]>;
-
- def int_x86_avx512_mask_lzcnt_q_128 :
- Intrinsic<[llvm_v2i64_ty],
- [llvm_v2i64_ty, llvm_v2i64_ty, llvm_i8_ty],
- [IntrNoMem]>;
- def int_x86_avx512_mask_lzcnt_q_256 :
- Intrinsic<[llvm_v4i64_ty],
- [llvm_v4i64_ty, llvm_v4i64_ty, llvm_i8_ty],
- [IntrNoMem]>;
- def int_x86_avx512_mask_lzcnt_q_512 :
- Intrinsic<[llvm_v8i64_ty],
- [llvm_v8i64_ty, llvm_v8i64_ty, llvm_i8_ty],
- [IntrNoMem]>;
}
// Compares
@@ -5518,86 +5420,6 @@ let TargetPrefix = "x86" in {
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]>;
-
- def int_x86_avx512_mask_cmp_b_512:
- Intrinsic<[llvm_i64_ty], [llvm_v64i8_ty, llvm_v64i8_ty, llvm_i32_ty,
- llvm_i64_ty], [IntrNoMem]>;
- def int_x86_avx512_mask_cmp_w_512:
- Intrinsic<[llvm_i32_ty], [llvm_v32i16_ty, llvm_v32i16_ty, llvm_i32_ty,
- llvm_i32_ty], [IntrNoMem]>;
- def int_x86_avx512_mask_cmp_d_512:
- Intrinsic<[llvm_i16_ty], [llvm_v16i32_ty, llvm_v16i32_ty, llvm_i32_ty,
- llvm_i16_ty], [IntrNoMem ]>;
- def int_x86_avx512_mask_cmp_q_512:
- Intrinsic<[llvm_i8_ty], [llvm_v8i64_ty, llvm_v8i64_ty, llvm_i32_ty,
- llvm_i8_ty], [IntrNoMem]>;
-
- def int_x86_avx512_mask_ucmp_b_512:
- Intrinsic<[llvm_i64_ty], [llvm_v64i8_ty, llvm_v64i8_ty, llvm_i32_ty,
- llvm_i64_ty], [IntrNoMem]>;
- def int_x86_avx512_mask_ucmp_w_512:
- Intrinsic<[llvm_i32_ty], [llvm_v32i16_ty, llvm_v32i16_ty, llvm_i32_ty,
- llvm_i32_ty], [IntrNoMem]>;
- def int_x86_avx512_mask_ucmp_d_512:
- Intrinsic<[llvm_i16_ty], [llvm_v16i32_ty, llvm_v16i32_ty, llvm_i32_ty,
- llvm_i16_ty], [IntrNoMem]>;
- def int_x86_avx512_mask_ucmp_q_512:
- Intrinsic<[llvm_i8_ty], [llvm_v8i64_ty, llvm_v8i64_ty, llvm_i32_ty,
- llvm_i8_ty], [IntrNoMem]>;
-
- // 256-bit
- def int_x86_avx512_mask_cmp_b_256:
- Intrinsic<[llvm_i32_ty], [llvm_v32i8_ty, llvm_v32i8_ty, llvm_i32_ty,
- llvm_i32_ty], [IntrNoMem]>;
- def int_x86_avx512_mask_cmp_w_256:
- Intrinsic<[llvm_i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty, llvm_i32_ty,
- llvm_i16_ty], [IntrNoMem]>;
- def int_x86_avx512_mask_cmp_d_256:
- Intrinsic<[llvm_i8_ty], [llvm_v8i32_ty, llvm_v8i32_ty, llvm_i32_ty,
- llvm_i8_ty], [IntrNoMem]>;
- def int_x86_avx512_mask_cmp_q_256:
- Intrinsic<[llvm_i8_ty], [llvm_v4i64_ty, llvm_v4i64_ty, llvm_i32_ty,
- llvm_i8_ty], [IntrNoMem]>;
-
- def int_x86_avx512_mask_ucmp_b_256:
- Intrinsic<[llvm_i32_ty], [llvm_v32i8_ty, llvm_v32i8_ty, llvm_i32_ty,
- llvm_i32_ty], [IntrNoMem]>;
- def int_x86_avx512_mask_ucmp_w_256:
- Intrinsic<[llvm_i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty, llvm_i32_ty,
- llvm_i16_ty], [IntrNoMem]>;
- def int_x86_avx512_mask_ucmp_d_256:
- Intrinsic<[llvm_i8_ty], [llvm_v8i32_ty, llvm_v8i32_ty, llvm_i32_ty,
- llvm_i8_ty], [IntrNoMem]>;
- def int_x86_avx512_mask_ucmp_q_256:
- Intrinsic<[llvm_i8_ty], [llvm_v4i64_ty, llvm_v4i64_ty, llvm_i32_ty,
- llvm_i8_ty], [IntrNoMem]>;
-
- // 128-bit
- def int_x86_avx512_mask_cmp_b_128:
- Intrinsic<[llvm_i16_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty,
- llvm_i16_ty], [IntrNoMem]>;
- def int_x86_avx512_mask_cmp_w_128:
- Intrinsic<[llvm_i8_ty], [llvm_v8i16_ty, llvm_v8i16_ty, llvm_i32_ty,
- llvm_i8_ty], [IntrNoMem]>;
- def int_x86_avx512_mask_cmp_d_128:
- Intrinsic<[llvm_i8_ty], [llvm_v4i32_ty, llvm_v4i32_ty, llvm_i32_ty,
- llvm_i8_ty], [IntrNoMem]>;
- def int_x86_avx512_mask_cmp_q_128:
- Intrinsic<[llvm_i8_ty], [llvm_v2i64_ty, llvm_v2i64_ty, llvm_i32_ty,
- llvm_i8_ty], [IntrNoMem]>;
-
- def int_x86_avx512_mask_ucmp_b_128:
- Intrinsic<[llvm_i16_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty,
- llvm_i16_ty], [IntrNoMem]>;
- def int_x86_avx512_mask_ucmp_w_128:
- Intrinsic<[llvm_i8_ty], [llvm_v8i16_ty, llvm_v8i16_ty, llvm_i32_ty,
- llvm_i8_ty], [IntrNoMem]>;
- def int_x86_avx512_mask_ucmp_d_128:
- Intrinsic<[llvm_i8_ty], [llvm_v4i32_ty, llvm_v4i32_ty, llvm_i32_ty,
- llvm_i8_ty], [IntrNoMem]>;
- def int_x86_avx512_mask_ucmp_q_128:
- Intrinsic<[llvm_i8_ty], [llvm_v2i64_ty, llvm_v2i64_ty, llvm_i32_ty,
- llvm_i8_ty], [IntrNoMem]>;
}
// Compress, Expand
@@ -6458,10 +6280,6 @@ let TargetPrefix = "x86" in {
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]>;
-
- def int_x86_avx512_movntdqa :
- GCCBuiltin<"__builtin_ia32_movntdqa512">,
- Intrinsic<[llvm_v8i64_ty], [llvm_ptr_ty], [IntrReadMem]>;
}
//===----------------------------------------------------------------------===//
@@ -6495,3 +6313,10 @@ let TargetPrefix = "x86" in {
: GCCBuiltin<"__builtin_ia32_mwaitx">,
Intrinsic<[], [ llvm_i32_ty, llvm_i32_ty, llvm_i32_ty ], []>;
}
+
+//===----------------------------------------------------------------------===//
+// Cache-line zero
+let TargetPrefix = "x86" in {
+ def int_x86_clzero : GCCBuiltin<"__builtin_ia32_clzero">,
+ Intrinsic<[], [llvm_ptr_ty], []>;
+}
diff --git a/contrib/llvm/include/llvm/IR/LLVMContext.h b/contrib/llvm/include/llvm/IR/LLVMContext.h
index 7f43d5d..4cb7770 100644
--- a/contrib/llvm/include/llvm/IR/LLVMContext.h
+++ b/contrib/llvm/include/llvm/IR/LLVMContext.h
@@ -1,4 +1,4 @@
-//===-- llvm/LLVMContext.h - Class for managing "global" state --*- C++ -*-===//
+//===- llvm/LLVMContext.h - Class for managing "global" state ---*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -37,9 +37,29 @@ class StringRef;
class Twine;
namespace yaml {
+
class Output;
+
} // end namespace yaml
+namespace SyncScope {
+
+typedef uint8_t ID;
+
+/// Known synchronization scope IDs, which always have the same value. All
+/// synchronization scope IDs that LLVM has special knowledge of are listed
+/// here. Additionally, this scheme allows LLVM to efficiently check for
+/// specific synchronization scope ID without comparing strings.
+enum {
+ /// Synchronized with respect to signal handlers executing in the same thread.
+ SingleThread = 0,
+
+ /// Synchronized with respect to all concurrently executing threads.
+ System = 1
+};
+
+} // end namespace SyncScope
+
/// This is an important class for using LLVM in a threaded context. It
/// (opaquely) owns and manages the core "global" data of LLVM's core
/// infrastructure, including the type and constant uniquing tables.
@@ -78,6 +98,7 @@ public:
MD_type = 19, // "type"
MD_section_prefix = 20, // "section_prefix"
MD_absolute_symbol = 21, // "absolute_symbol"
+ MD_associated = 22, // "associated"
};
/// Known operand bundle tag IDs, which always have the same value. All
@@ -108,6 +129,16 @@ public:
/// tag registered with an LLVMContext has an unique ID.
uint32_t getOperandBundleTagID(StringRef Tag) const;
+ /// getOrInsertSyncScopeID - Maps synchronization scope name to
+ /// synchronization scope ID. Every synchronization scope registered with
+ /// LLVMContext has unique ID except pre-defined ones.
+ SyncScope::ID getOrInsertSyncScopeID(StringRef SSN);
+
+ /// getSyncScopeNames - Populates client supplied SmallVector with
+ /// synchronization scope names registered with LLVMContext. Synchronization
+ /// scope names are ordered by increasing synchronization scope IDs.
+ void getSyncScopeNames(SmallVectorImpl<StringRef> &SSNs) const;
+
/// Define the GC for a function
void setGC(const Function &Fn, std::string GCName);
@@ -133,17 +164,17 @@ public:
void enableDebugTypeODRUniquing();
void disableDebugTypeODRUniquing();
- typedef void (*InlineAsmDiagHandlerTy)(const SMDiagnostic&, void *Context,
- unsigned LocCookie);
+ using InlineAsmDiagHandlerTy = void (*)(const SMDiagnostic&, void *Context,
+ unsigned LocCookie);
/// Defines the type of a diagnostic handler.
/// \see LLVMContext::setDiagnosticHandler.
/// \see LLVMContext::diagnose.
- typedef void (*DiagnosticHandlerTy)(const DiagnosticInfo &DI, void *Context);
+ using DiagnosticHandlerTy = void (*)(const DiagnosticInfo &DI, void *Context);
/// Defines the type of a yield callback.
/// \see LLVMContext::setYieldCallback.
- typedef void (*YieldCallbackTy)(LLVMContext *Context, void *OpaqueHandle);
+ using YieldCallbackTy = void (*)(LLVMContext *Context, void *OpaqueHandle);
/// setInlineAsmDiagnosticHandler - This method sets a handler that is invoked
/// when problems with inline asm are detected by the backend. The first
@@ -185,10 +216,19 @@ public:
/// \brief Return if a code hotness metric should be included in optimization
/// diagnostics.
- bool getDiagnosticHotnessRequested() const;
+ bool getDiagnosticsHotnessRequested() const;
/// \brief Set if a code hotness metric should be included in optimization
/// diagnostics.
- void setDiagnosticHotnessRequested(bool Requested);
+ void setDiagnosticsHotnessRequested(bool Requested);
+
+ /// \brief Return the minimum hotness value a diagnostic would need in order
+ /// to be included in optimization diagnostics. If there is no minimum, this
+ /// returns None.
+ uint64_t getDiagnosticsHotnessThreshold() const;
+
+ /// \brief Set the minimum hotness value a diagnostic needs in order to be
+ /// included in optimization diagnostics.
+ void setDiagnosticsHotnessThreshold(uint64_t Threshold);
/// \brief Return the YAML file used by the backend to save optimization
/// diagnostics. If null, diagnostics are not saved in a file but only
diff --git a/contrib/llvm/include/llvm/IR/LegacyPassManager.h b/contrib/llvm/include/llvm/IR/LegacyPassManager.h
index 5257a0e..9a376a1 100644
--- a/contrib/llvm/include/llvm/IR/LegacyPassManager.h
+++ b/contrib/llvm/include/llvm/IR/LegacyPassManager.h
@@ -98,6 +98,9 @@ private:
// Create wrappers for C Binding types (see CBindingWrapping.h).
DEFINE_STDCXX_CONVERSION_FUNCTIONS(legacy::PassManagerBase, LLVMPassManagerRef)
+/// If -time-passes has been specified, report the timings immediately and then
+/// reset the timers to zero.
+void reportAndResetTimings();
} // End llvm namespace
#endif
diff --git a/contrib/llvm/include/llvm/IR/LegacyPassNameParser.h b/contrib/llvm/include/llvm/IR/LegacyPassNameParser.h
index fd9d468..4cec081 100644
--- a/contrib/llvm/include/llvm/IR/LegacyPassNameParser.h
+++ b/contrib/llvm/include/llvm/IR/LegacyPassNameParser.h
@@ -81,15 +81,15 @@ public:
// default implementation to sort the table before we print...
void printOptionInfo(const cl::Option &O, size_t GlobalWidth) const override {
PassNameParser *PNP = const_cast<PassNameParser*>(this);
- array_pod_sort(PNP->Values.begin(), PNP->Values.end(), ValLessThan);
+ array_pod_sort(PNP->Values.begin(), PNP->Values.end(), ValCompare);
cl::parser<const PassInfo*>::printOptionInfo(O, GlobalWidth);
}
private:
- // ValLessThan - Provide a sorting comparator for Values elements...
- static int ValLessThan(const PassNameParser::OptionInfo *VT1,
- const PassNameParser::OptionInfo *VT2) {
- return VT1->Name < VT2->Name;
+ // ValCompare - Provide a sorting comparator for Values elements...
+ static int ValCompare(const PassNameParser::OptionInfo *VT1,
+ const PassNameParser::OptionInfo *VT2) {
+ return VT1->Name.compare(VT2->Name);
}
};
diff --git a/contrib/llvm/include/llvm/IR/MDBuilder.h b/contrib/llvm/include/llvm/IR/MDBuilder.h
index bab8728..899976a 100644
--- a/contrib/llvm/include/llvm/IR/MDBuilder.h
+++ b/contrib/llvm/include/llvm/IR/MDBuilder.h
@@ -15,7 +15,9 @@
#ifndef LLVM_IR_MDBUILDER_H
#define LLVM_IR_MDBUILDER_H
+#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/IR/GlobalValue.h"
#include "llvm/Support/DataTypes.h"
#include <utility>
@@ -63,8 +65,11 @@ public:
/// Return metadata specifying that a branch or switch is unpredictable.
MDNode *createUnpredictable();
- /// Return metadata containing the entry count for a function.
- MDNode *createFunctionEntryCount(uint64_t Count);
+ /// Return metadata containing the entry \p Count for a function, and the
+ /// GUIDs stored in \p Imports that need to be imported for sample PGO, to
+ /// enable the same inlines as the profiled optimized binary
+ MDNode *createFunctionEntryCount(uint64_t Count,
+ const DenseSet<GlobalValue::GUID> *Imports);
/// Return metadata containing the section prefix for a function.
MDNode *createFunctionSectionPrefix(StringRef Prefix);
diff --git a/contrib/llvm/include/llvm/IR/Mangler.h b/contrib/llvm/include/llvm/IR/Mangler.h
index 0eb91a3..56ee213 100644
--- a/contrib/llvm/include/llvm/IR/Mangler.h
+++ b/contrib/llvm/include/llvm/IR/Mangler.h
@@ -21,6 +21,7 @@ namespace llvm {
class DataLayout;
template <typename T> class SmallVectorImpl;
+class Triple;
class Twine;
class raw_ostream;
@@ -46,6 +47,9 @@ public:
const Twine &GVName, const DataLayout &DL);
};
+void emitLinkerFlagsForGlobalCOFF(raw_ostream &OS, const GlobalValue *GV,
+ const Triple &TT, Mangler &Mangler);
+
} // End llvm namespace
#endif
diff --git a/contrib/llvm/include/llvm/IR/Metadata.h b/contrib/llvm/include/llvm/IR/Metadata.h
index 46c785a..3462cc0 100644
--- a/contrib/llvm/include/llvm/IR/Metadata.h
+++ b/contrib/llvm/include/llvm/IR/Metadata.h
@@ -19,16 +19,17 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseMapInfo.h"
-#include "llvm/ADT/ilist_node.h"
-#include "llvm/ADT/iterator_range.h"
#include "llvm/ADT/None.h"
#include "llvm/ADT/PointerUnion.h"
-#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/ilist_node.h"
+#include "llvm/ADT/iterator_range.h"
#include "llvm/IR/Constant.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Value.h"
+#include "llvm/Support/CBindingWrapping.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/ErrorHandling.h"
#include <cassert>
@@ -44,6 +45,8 @@ namespace llvm {
class Module;
class ModuleSlotTracker;
+class raw_ostream;
+class Type;
enum LLVMConstants : uint32_t {
DEBUG_METADATA_VERSION = 3 // Current debug info version number.
@@ -66,8 +69,8 @@ protected:
unsigned char Storage;
// TODO: expose remaining bits to subclasses.
- unsigned short SubclassData16;
- unsigned SubclassData32;
+ unsigned short SubclassData16 = 0;
+ unsigned SubclassData32 = 0;
public:
enum MetadataKind {
@@ -77,8 +80,8 @@ public:
protected:
Metadata(unsigned ID, StorageType Storage)
- : SubclassID(ID), Storage(Storage), SubclassData16(0), SubclassData32(0) {
- static_assert(sizeof(*this) == 8, "Metdata fields poorly packed");
+ : SubclassID(ID), Storage(Storage) {
+ static_assert(sizeof(*this) == 8, "Metadata fields poorly packed");
}
~Metadata() = default;
@@ -133,6 +136,14 @@ public:
/// @}
};
+// Create wrappers for C Binding types (see CBindingWrapping.h).
+DEFINE_ISA_CONVERSION_FUNCTIONS(Metadata, LLVMMetadataRef)
+
+// Specialized opaque metadata conversions.
+inline Metadata **unwrap(LLVMMetadataRef *MDs) {
+ return reinterpret_cast<Metadata**>(MDs);
+}
+
#define HANDLE_METADATA(CLASS) class CLASS;
#include "llvm/IR/Metadata.def"
@@ -165,14 +176,16 @@ class MetadataAsValue : public Value {
Metadata *MD;
MetadataAsValue(Type *Ty, Metadata *MD);
- ~MetadataAsValue() override;
/// \brief Drop use of metadata (during teardown).
void dropUse() { MD = nullptr; }
public:
+ ~MetadataAsValue();
+
static MetadataAsValue *get(LLVMContext &Context, Metadata *MD);
static MetadataAsValue *getIfExists(LLVMContext &Context, Metadata *MD);
+
Metadata *getMetadata() const { return MD; }
static bool classof(const Value *V) {
@@ -247,7 +260,7 @@ public:
/// \brief Check whether metadata is replaceable.
static bool isReplaceable(const Metadata &MD);
- typedef PointerUnion<MetadataAsValue *, Metadata *> OwnerTy;
+ using OwnerTy = PointerUnion<MetadataAsValue *, Metadata *>;
private:
/// \brief Track a reference to metadata for an owner.
@@ -265,16 +278,15 @@ class ReplaceableMetadataImpl {
friend class MetadataTracking;
public:
- typedef MetadataTracking::OwnerTy OwnerTy;
+ using OwnerTy = MetadataTracking::OwnerTy;
private:
LLVMContext &Context;
- uint64_t NextIndex;
+ uint64_t NextIndex = 0;
SmallDenseMap<void *, std::pair<OwnerTy, uint64_t>, 4> UseMap;
public:
- ReplaceableMetadataImpl(LLVMContext &Context)
- : Context(Context), NextIndex(0) {}
+ ReplaceableMetadataImpl(LLVMContext &Context) : Context(Context) {}
~ReplaceableMetadataImpl() {
assert(UseMap.empty() && "Cannot destroy in-use replaceable metadata");
@@ -343,17 +355,21 @@ protected:
public:
static ValueAsMetadata *get(Value *V);
+
static ConstantAsMetadata *getConstant(Value *C) {
return cast<ConstantAsMetadata>(get(C));
}
+
static LocalAsMetadata *getLocal(Value *Local) {
return cast<LocalAsMetadata>(get(Local));
}
static ValueAsMetadata *getIfExists(Value *V);
+
static ConstantAsMetadata *getConstantIfExists(Value *C) {
return cast_or_null<ConstantAsMetadata>(getIfExists(C));
}
+
static LocalAsMetadata *getLocalIfExists(Value *Local) {
return cast_or_null<LocalAsMetadata>(getIfExists(Local));
}
@@ -482,8 +498,8 @@ namespace detail {
template <class T> T &make();
template <class T, class Result> struct HasDereference {
- typedef char Yes[1];
- typedef char No[2];
+ using Yes = char[1];
+ using No = char[2];
template <size_t N> struct SFINAE {};
template <class U, class V>
@@ -586,8 +602,9 @@ dyn_extract_or_null(Y &&MD) {
class MDString : public Metadata {
friend class StringMapEntry<MDString>;
- StringMapEntry<MDString> *Entry;
- MDString() : Metadata(MDStringKind, Uniqued), Entry(nullptr) {}
+ StringMapEntry<MDString> *Entry = nullptr;
+
+ MDString() : Metadata(MDStringKind, Uniqued) {}
public:
MDString(const MDString &) = delete;
@@ -603,7 +620,7 @@ public:
unsigned getLength() const { return (unsigned)getString().size(); }
- typedef StringRef::iterator iterator;
+ using iterator = StringRef::iterator;
/// \brief Pointer to the first byte of the string.
iterator begin() const { return getString().begin(); }
@@ -643,6 +660,19 @@ struct AAMDNodes {
/// \brief The tag specifying the noalias scope.
MDNode *NoAlias;
+
+ /// \brief Given two sets of AAMDNodes that apply to the same pointer,
+ /// give the best AAMDNodes that are compatible with both (i.e. a set of
+ /// nodes whose allowable aliasing conclusions are a subset of those
+ /// allowable by both of the inputs). However, for efficiency
+ /// reasons, do not create any new MDNodes.
+ AAMDNodes intersect(const AAMDNodes &Other) {
+ AAMDNodes Result;
+ Result.TBAA = Other.TBAA == TBAA ? TBAA : nullptr;
+ Result.Scope = Other.Scope == Scope ? Scope : nullptr;
+ Result.NoAlias = Other.NoAlias == NoAlias ? NoAlias : nullptr;
+ return Result;
+ }
};
// Specialize DenseMapInfo for AAMDNodes.
@@ -720,12 +750,14 @@ private:
};
template <> struct simplify_type<MDOperand> {
- typedef Metadata *SimpleType;
+ using SimpleType = Metadata *;
+
static SimpleType getSimplifiedValue(MDOperand &MD) { return MD.get(); }
};
template <> struct simplify_type<const MDOperand> {
- typedef Metadata *SimpleType;
+ using SimpleType = Metadata *;
+
static SimpleType getSimplifiedValue(const MDOperand &MD) { return MD.get(); }
};
@@ -807,7 +839,7 @@ struct TempMDNodeDeleter {
};
#define HANDLE_MDNODE_LEAF(CLASS) \
- typedef std::unique_ptr<CLASS, TempMDNodeDeleter> Temp##CLASS;
+ using Temp##CLASS = std::unique_ptr<CLASS, TempMDNodeDeleter>;
#define HANDLE_MDNODE_BRANCH(CLASS) HANDLE_MDNODE_LEAF(CLASS)
#include "llvm/IR/Metadata.def"
@@ -837,6 +869,10 @@ class MDNode : public Metadata {
ContextAndReplaceableUses Context;
protected:
+ MDNode(LLVMContext &Context, unsigned ID, StorageType Storage,
+ ArrayRef<Metadata *> Ops1, ArrayRef<Metadata *> Ops2 = None);
+ ~MDNode() = default;
+
void *operator new(size_t Size, unsigned NumOps);
void operator delete(void *Mem);
@@ -850,16 +886,13 @@ protected:
llvm_unreachable("Constructor throws?");
}
- MDNode(LLVMContext &Context, unsigned ID, StorageType Storage,
- ArrayRef<Metadata *> Ops1, ArrayRef<Metadata *> Ops2 = None);
- ~MDNode() = default;
-
void dropAllReferences();
MDOperand *mutable_begin() { return mutable_end() - NumOperands; }
MDOperand *mutable_end() { return reinterpret_cast<MDOperand *>(this); }
- typedef iterator_range<MDOperand *> mutable_op_range;
+ using mutable_op_range = iterator_range<MDOperand *>;
+
mutable_op_range mutable_operands() {
return mutable_op_range(mutable_begin(), mutable_end());
}
@@ -1018,8 +1051,8 @@ private:
static void dispatchResetHash(NodeTy *, std::false_type) {}
public:
- typedef const MDOperand *op_iterator;
- typedef iterator_range<op_iterator> op_range;
+ using op_iterator = const MDOperand *;
+ using op_range = iterator_range<op_iterator>;
op_iterator op_begin() const {
return const_cast<MDNode *>(this)->mutable_begin();
@@ -1062,7 +1095,6 @@ public:
static MDNode *getMostGenericRange(MDNode *A, MDNode *B);
static MDNode *getMostGenericAliasScope(MDNode *A, MDNode *B);
static MDNode *getMostGenericAlignmentOrDereferenceable(MDNode *A, MDNode *B);
-
};
/// \brief Tuple of metadata.
@@ -1214,16 +1246,18 @@ public:
// FIXME: Fix callers and remove condition on N.
unsigned size() const { return N ? N->getNumOperands() : 0u; }
+ bool empty() const { return N ? N->getNumOperands() == 0 : true; }
T *operator[](unsigned I) const { return cast_or_null<T>(N->getOperand(I)); }
// FIXME: Fix callers and remove condition on N.
- typedef TypedMDOperandIterator<T> iterator;
+ using iterator = TypedMDOperandIterator<T>;
+
iterator begin() const { return N ? iterator(N->op_begin()) : iterator(); }
iterator end() const { return N ? iterator(N->op_end()) : iterator(); }
};
#define HANDLE_METADATA(CLASS) \
- typedef MDTupleTypedArrayWrapper<CLASS> CLASS##Array;
+ using CLASS##Array = MDTupleTypedArrayWrapper<CLASS>;
#include "llvm/IR/Metadata.def"
/// Placeholder metadata for operands of distinct MDNodes.
@@ -1284,7 +1318,7 @@ class NamedMDNode : public ilist_node<NamedMDNode> {
friend class Module;
std::string Name;
- Module *Parent;
+ Module *Parent = nullptr;
void *Operands; // SmallVector<TrackingMDRef, 4>
void setParent(Module *M) { Parent = M; }
@@ -1294,12 +1328,12 @@ class NamedMDNode : public ilist_node<NamedMDNode> {
template<class T1, class T2>
class op_iterator_impl :
public std::iterator<std::bidirectional_iterator_tag, T2> {
+ friend class NamedMDNode;
+
const NamedMDNode *Node = nullptr;
unsigned Idx = 0;
- op_iterator_impl(const NamedMDNode *N, unsigned i) : Node(N), Idx(i) { }
-
- friend class NamedMDNode;
+ op_iterator_impl(const NamedMDNode *N, unsigned i) : Node(N), Idx(i) {}
public:
op_iterator_impl() = default;
@@ -1361,11 +1395,13 @@ public:
// ---------------------------------------------------------------------------
// Operand Iterator interface...
//
- typedef op_iterator_impl<MDNode *, MDNode> op_iterator;
+ using op_iterator = op_iterator_impl<MDNode *, MDNode>;
+
op_iterator op_begin() { return op_iterator(this, 0); }
op_iterator op_end() { return op_iterator(this, getNumOperands()); }
- typedef op_iterator_impl<const MDNode *, MDNode> const_op_iterator;
+ using const_op_iterator = op_iterator_impl<const MDNode *, MDNode>;
+
const_op_iterator op_begin() const { return const_op_iterator(this, 0); }
const_op_iterator op_end() const { return const_op_iterator(this, getNumOperands()); }
diff --git a/contrib/llvm/include/llvm/IR/Module.h b/contrib/llvm/include/llvm/IR/Module.h
index 79870b9..196e32e 100644
--- a/contrib/llvm/include/llvm/IR/Module.h
+++ b/contrib/llvm/include/llvm/IR/Module.h
@@ -1,4 +1,4 @@
-//===-- llvm/Module.h - C++ class to represent a VM module ------*- C++ -*-===//
+//===- llvm/Module.h - C++ class to represent a VM module -------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -15,7 +15,12 @@
#ifndef LLVM_IR_MODULE_H
#define LLVM_IR_MODULE_H
+#include "llvm-c/Types.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/iterator_range.h"
+#include "llvm/IR/Attributes.h"
#include "llvm/IR/Comdat.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Function.h"
@@ -23,20 +28,26 @@
#include "llvm/IR/GlobalIFunc.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/Metadata.h"
+#include "llvm/IR/SymbolTableListTraits.h"
#include "llvm/Support/CBindingWrapping.h"
#include "llvm/Support/CodeGen.h"
-#include "llvm/Support/DataTypes.h"
+#include <cstddef>
+#include <cstdint>
+#include <iterator>
+#include <memory>
+#include <string>
+#include <vector>
namespace llvm {
-template <typename T> class Optional;
+
class Error;
class FunctionType;
class GVMaterializer;
class LLVMContext;
class MemoryBuffer;
class RandomNumberGenerator;
-class StructType;
template <class PtrType> class SmallPtrSetImpl;
+class StructType;
/// A Module instance is used to store all the information related to an
/// LLVM module. Modules are the top level container of all other LLVM
@@ -54,47 +65,47 @@ class Module {
/// @{
public:
/// The type for the list of global variables.
- typedef SymbolTableList<GlobalVariable> GlobalListType;
+ using GlobalListType = SymbolTableList<GlobalVariable>;
/// The type for the list of functions.
- typedef SymbolTableList<Function> FunctionListType;
+ using FunctionListType = SymbolTableList<Function>;
/// The type for the list of aliases.
- typedef SymbolTableList<GlobalAlias> AliasListType;
+ using AliasListType = SymbolTableList<GlobalAlias>;
/// The type for the list of ifuncs.
- typedef SymbolTableList<GlobalIFunc> IFuncListType;
+ using IFuncListType = SymbolTableList<GlobalIFunc>;
/// The type for the list of named metadata.
- typedef ilist<NamedMDNode> NamedMDListType;
+ using NamedMDListType = ilist<NamedMDNode>;
/// The type of the comdat "symbol" table.
- typedef StringMap<Comdat> ComdatSymTabType;
+ using ComdatSymTabType = StringMap<Comdat>;
/// The Global Variable iterator.
- typedef GlobalListType::iterator global_iterator;
+ using global_iterator = GlobalListType::iterator;
/// The Global Variable constant iterator.
- typedef GlobalListType::const_iterator const_global_iterator;
+ using const_global_iterator = GlobalListType::const_iterator;
/// The Function iterators.
- typedef FunctionListType::iterator iterator;
+ using iterator = FunctionListType::iterator;
/// The Function constant iterator
- typedef FunctionListType::const_iterator const_iterator;
+ using const_iterator = FunctionListType::const_iterator;
/// The Function reverse iterator.
- typedef FunctionListType::reverse_iterator reverse_iterator;
+ using reverse_iterator = FunctionListType::reverse_iterator;
/// The Function constant reverse iterator.
- typedef FunctionListType::const_reverse_iterator const_reverse_iterator;
+ using const_reverse_iterator = FunctionListType::const_reverse_iterator;
/// The Global Alias iterators.
- typedef AliasListType::iterator alias_iterator;
+ using alias_iterator = AliasListType::iterator;
/// The Global Alias constant iterator
- typedef AliasListType::const_iterator const_alias_iterator;
+ using const_alias_iterator = AliasListType::const_iterator;
/// The Global IFunc iterators.
- typedef IFuncListType::iterator ifunc_iterator;
+ using ifunc_iterator = IFuncListType::iterator;
/// The Global IFunc constant iterator
- typedef IFuncListType::const_iterator const_ifunc_iterator;
+ using const_ifunc_iterator = IFuncListType::const_iterator;
/// The named metadata iterators.
- typedef NamedMDListType::iterator named_metadata_iterator;
+ using named_metadata_iterator = NamedMDListType::iterator;
/// The named metadata constant iterators.
- typedef NamedMDListType::const_iterator const_named_metadata_iterator;
+ using const_named_metadata_iterator = NamedMDListType::const_iterator;
/// This enumeration defines the supported behaviors of module flags.
enum ModFlagBehavior {
@@ -128,9 +139,12 @@ public:
/// during the append operation.
AppendUnique = 6,
+ /// Takes the max of the two values, which are required to be integers.
+ Max = 7,
+
// Markers:
ModFlagBehaviorFirstVal = Error,
- ModFlagBehaviorLastVal = AppendUnique
+ ModFlagBehaviorLastVal = Max
};
/// Checks if Metadata represents a valid ModFlagBehavior, and stores the
@@ -141,6 +155,7 @@ public:
ModFlagBehavior Behavior;
MDString *Key;
Metadata *Val;
+
ModuleFlagEntry(ModFlagBehavior B, MDString *K, Metadata *V)
: Behavior(B), Key(K), Val(V) {}
};
@@ -234,7 +249,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.
- RandomNumberGenerator *createRNG(const Pass* P) const;
+ std::unique_ptr<RandomNumberGenerator> createRNG(const Pass* P) const;
/// @}
/// @name Module Level Mutators
@@ -311,7 +326,7 @@ public:
/// 4. Finally, the function exists but has the wrong prototype: return the
/// function with a constantexpr cast to the right prototype.
Constant *getOrInsertFunction(StringRef Name, FunctionType *T,
- AttributeSet AttributeList);
+ AttributeList AttributeList);
Constant *getOrInsertFunction(StringRef Name, FunctionType *T);
@@ -319,15 +334,24 @@ public:
/// exist, add a prototype for the function and return it. This function
/// guarantees to return a constant of pointer to the specified function type
/// or a ConstantExpr BitCast of that type if the named function has a
- /// different type. This version of the method takes a null terminated list of
+ /// different type. This version of the method takes a list of
/// function arguments, which makes it easier for clients to use.
+ template<typename... ArgsTy>
Constant *getOrInsertFunction(StringRef Name,
- AttributeSet AttributeList,
- Type *RetTy, ...) LLVM_END_WITH_NULL;
+ AttributeList AttributeList,
+ Type *RetTy, ArgsTy... Args)
+ {
+ SmallVector<Type*, sizeof...(ArgsTy)> ArgTys{Args...};
+ return getOrInsertFunction(Name,
+ FunctionType::get(RetTy, ArgTys, false),
+ AttributeList);
+ }
/// Same as above, but without the attributes.
- Constant *getOrInsertFunction(StringRef Name, Type *RetTy, ...)
- LLVM_END_WITH_NULL;
+ template<typename... ArgsTy>
+ Constant *getOrInsertFunction(StringRef Name, Type *RetTy, ArgsTy... Args) {
+ return getOrInsertFunction(Name, AttributeList{}, RetTy, Args...);
+ }
/// Look up the specified function in the module symbol table. If it does not
/// exist, return null.
@@ -345,20 +369,23 @@ public:
return getGlobalVariable(Name, false);
}
- GlobalVariable *getGlobalVariable(StringRef Name, bool AllowInternal) const {
- return const_cast<Module *>(this)->getGlobalVariable(Name, AllowInternal);
- }
+ GlobalVariable *getGlobalVariable(StringRef Name, bool AllowInternal) const;
- GlobalVariable *getGlobalVariable(StringRef Name, bool AllowInternal = false);
+ GlobalVariable *getGlobalVariable(StringRef Name,
+ bool AllowInternal = false) {
+ return static_cast<const Module *>(this)->getGlobalVariable(Name,
+ AllowInternal);
+ }
/// Return the global variable in the module with the specified name, of
/// arbitrary type. This method returns null if a global with the specified
/// name is not found.
- GlobalVariable *getNamedGlobal(StringRef Name) {
+ const GlobalVariable *getNamedGlobal(StringRef Name) const {
return getGlobalVariable(Name, true);
}
- const GlobalVariable *getNamedGlobal(StringRef Name) const {
- return const_cast<Module *>(this)->getNamedGlobal(Name);
+ GlobalVariable *getNamedGlobal(StringRef Name) {
+ return const_cast<GlobalVariable *>(
+ static_cast<const Module *>(this)->getNamedGlobal(Name));
}
/// Look up the specified global in the module symbol table.
@@ -471,9 +498,11 @@ public:
const GlobalListType &getGlobalList() const { return GlobalList; }
/// Get the Module's list of global variables.
GlobalListType &getGlobalList() { return GlobalList; }
+
static GlobalListType Module::*getSublistAccess(GlobalVariable*) {
return &Module::GlobalList;
}
+
/// Get the Module's list of functions (constant).
const FunctionListType &getFunctionList() const { return FunctionList; }
/// Get the Module's list of functions.
@@ -481,31 +510,39 @@ public:
static FunctionListType Module::*getSublistAccess(Function*) {
return &Module::FunctionList;
}
+
/// Get the Module's list of aliases (constant).
const AliasListType &getAliasList() const { return AliasList; }
/// Get the Module's list of aliases.
AliasListType &getAliasList() { return AliasList; }
+
static AliasListType Module::*getSublistAccess(GlobalAlias*) {
return &Module::AliasList;
}
+
/// Get the Module's list of ifuncs (constant).
const IFuncListType &getIFuncList() const { return IFuncList; }
/// Get the Module's list of ifuncs.
IFuncListType &getIFuncList() { return IFuncList; }
+
static IFuncListType Module::*getSublistAccess(GlobalIFunc*) {
return &Module::IFuncList;
}
+
/// Get the Module's list of named metadata (constant).
const NamedMDListType &getNamedMDList() const { return NamedMDList; }
/// Get the Module's list of named metadata.
NamedMDListType &getNamedMDList() { return NamedMDList; }
+
static NamedMDListType Module::*getSublistAccess(NamedMDNode*) {
return &Module::NamedMDList;
}
+
/// Get the symbol table of global variable and function identifiers
const ValueSymbolTable &getValueSymbolTable() const { return *ValSymTab; }
/// Get the Module's symbol table of global variable and function identifiers.
ValueSymbolTable &getValueSymbolTable() { return *ValSymTab; }
+
/// Get the Module's symbol table for COMDATs (constant).
const ComdatSymTabType &getComdatSymbolTable() const { return ComdatSymTab; }
/// Get the Module's symbol table for COMDATs.
@@ -590,11 +627,11 @@ public:
/// @name Convenience iterators
/// @{
- typedef concat_iterator<GlobalObject, iterator, global_iterator>
- global_object_iterator;
- typedef concat_iterator<const GlobalObject, const_iterator,
- const_global_iterator>
- const_global_object_iterator;
+ using global_object_iterator =
+ concat_iterator<GlobalObject, iterator, global_iterator>;
+ using const_global_object_iterator =
+ concat_iterator<const GlobalObject, const_iterator,
+ const_global_iterator>;
iterator_range<global_object_iterator> global_objects() {
return concat<GlobalObject>(functions(), globals());
@@ -615,6 +652,31 @@ public:
return global_objects().end();
}
+ using global_value_iterator =
+ concat_iterator<GlobalValue, iterator, global_iterator, alias_iterator,
+ ifunc_iterator>;
+ using const_global_value_iterator =
+ concat_iterator<const GlobalValue, const_iterator, const_global_iterator,
+ const_alias_iterator, const_ifunc_iterator>;
+
+ iterator_range<global_value_iterator> global_values() {
+ return concat<GlobalValue>(functions(), globals(), aliases(), ifuncs());
+ }
+ iterator_range<const_global_value_iterator> global_values() const {
+ return concat<const GlobalValue>(functions(), globals(), aliases(),
+ ifuncs());
+ }
+
+ global_value_iterator global_value_begin() { return global_values().begin(); }
+ global_value_iterator global_value_end() { return global_values().end(); }
+
+ const_global_value_iterator global_value_begin() const {
+ return global_values().begin();
+ }
+ const_global_value_iterator global_value_end() const {
+ return global_values().end();
+ }
+
/// @}
/// @name Named Metadata Iteration
/// @{
@@ -644,28 +706,35 @@ public:
: public std::iterator<std::input_iterator_tag, DICompileUnit *> {
NamedMDNode *CUs;
unsigned Idx;
+
void SkipNoDebugCUs();
+
public:
explicit debug_compile_units_iterator(NamedMDNode *CUs, unsigned Idx)
: CUs(CUs), Idx(Idx) {
SkipNoDebugCUs();
}
+
debug_compile_units_iterator &operator++() {
++Idx;
SkipNoDebugCUs();
return *this;
}
+
debug_compile_units_iterator operator++(int) {
debug_compile_units_iterator T(*this);
++Idx;
return T;
}
+
bool operator==(const debug_compile_units_iterator &I) const {
return Idx == I.Idx;
}
+
bool operator!=(const debug_compile_units_iterator &I) const {
return Idx != I.Idx;
}
+
DICompileUnit *operator*() const;
DICompileUnit *operator->() const;
};
@@ -726,6 +795,10 @@ public:
/// @name Utility functions for querying Debug information.
/// @{
+ /// \brief Returns the Number of Register ParametersDwarf Version by checking
+ /// module flags.
+ unsigned getNumberRegisterParameters() const;
+
/// \brief Returns the Dwarf Version by checking module flags.
unsigned getDwarfVersion() const;
@@ -791,6 +864,6 @@ inline Module *unwrap(LLVMModuleProviderRef MP) {
return reinterpret_cast<Module*>(MP);
}
-} // End llvm namespace
+} // end namespace llvm
-#endif
+#endif // LLVM_IR_MODULE_H
diff --git a/contrib/llvm/include/llvm/IR/ModuleSummaryIndex.h b/contrib/llvm/include/llvm/IR/ModuleSummaryIndex.h
index 83c4ae0..4aa8a01 100644
--- a/contrib/llvm/include/llvm/IR/ModuleSummaryIndex.h
+++ b/contrib/llvm/include/llvm/IR/ModuleSummaryIndex.h
@@ -1,4 +1,4 @@
-//===-- llvm/ModuleSummaryIndex.h - Module Summary Index --------*- C++ -*-===//
+//===- llvm/ModuleSummaryIndex.h - Module Summary Index ---------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -16,25 +16,44 @@
#ifndef LLVM_IR_MODULESUMMARYINDEX_H
#define LLVM_IR_MODULESUMMARYINDEX_H
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/Module.h"
-
+#include <algorithm>
#include <array>
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
+#include <map>
+#include <memory>
+#include <set>
+#include <string>
+#include <utility>
+#include <vector>
namespace llvm {
namespace yaml {
+
template <typename T> struct MappingTraits;
-}
+
+} // end namespace yaml
/// \brief Class to accumulate and hold information about a callee.
struct CalleeInfo {
- enum class HotnessType : uint8_t { Unknown = 0, Cold = 1, None = 2, Hot = 3 };
+ enum class HotnessType : uint8_t {
+ Unknown = 0,
+ Cold = 1,
+ None = 2,
+ Hot = 3,
+ Critical = 4
+ };
HotnessType Hotness = HotnessType::Unknown;
CalleeInfo() = default;
@@ -45,58 +64,59 @@ struct CalleeInfo {
}
};
-/// Struct to hold value either by GUID or GlobalValue*. Values in combined
-/// indexes as well as indirect calls are GUIDs, all others are GlobalValues.
+class GlobalValueSummary;
+
+using GlobalValueSummaryList = std::vector<std::unique_ptr<GlobalValueSummary>>;
+
+struct GlobalValueSummaryInfo {
+ /// The GlobalValue corresponding to this summary. This is only used in
+ /// per-module summaries.
+ const GlobalValue *GV = nullptr;
+
+ /// List of global value summary structures for a particular value held
+ /// in the GlobalValueMap. Requires a vector in the case of multiple
+ /// COMDAT values of the same name.
+ GlobalValueSummaryList SummaryList;
+};
+
+/// Map from global value GUID to corresponding summary structures. Use a
+/// std::map rather than a DenseMap so that pointers to the map's value_type
+/// (which are used by ValueInfo) are not invalidated by insertion. Also it will
+/// likely incur less overhead, as the value type is not very small and the size
+/// of the map is unknown, resulting in inefficiencies due to repeated
+/// insertions and resizing.
+using GlobalValueSummaryMapTy =
+ std::map<GlobalValue::GUID, GlobalValueSummaryInfo>;
+
+/// Struct that holds a reference to a particular GUID in a global value
+/// summary.
struct ValueInfo {
- /// The value representation used in this instance.
- enum ValueInfoKind {
- VI_GUID,
- VI_Value,
- };
+ const GlobalValueSummaryMapTy::value_type *Ref = nullptr;
- /// Union of the two possible value types.
- union ValueUnion {
- GlobalValue::GUID Id;
- const GlobalValue *GV;
- ValueUnion(GlobalValue::GUID Id) : Id(Id) {}
- ValueUnion(const GlobalValue *GV) : GV(GV) {}
- };
+ ValueInfo() = default;
+ ValueInfo(const GlobalValueSummaryMapTy::value_type *Ref) : Ref(Ref) {}
+
+ operator bool() const { return Ref; }
+
+ GlobalValue::GUID getGUID() const { return Ref->first; }
+ const GlobalValue *getValue() const { return Ref->second.GV; }
- /// The value being represented.
- ValueUnion TheValue;
- /// The value representation.
- ValueInfoKind Kind;
- /// Constructor for a GUID value
- ValueInfo(GlobalValue::GUID Id = 0) : TheValue(Id), Kind(VI_GUID) {}
- /// Constructor for a GlobalValue* value
- ValueInfo(const GlobalValue *V) : TheValue(V), Kind(VI_Value) {}
- /// Accessor for GUID value
- GlobalValue::GUID getGUID() const {
- assert(Kind == VI_GUID && "Not a GUID type");
- return TheValue.Id;
- }
- /// Accessor for GlobalValue* value
- const GlobalValue *getValue() const {
- assert(Kind == VI_Value && "Not a Value type");
- return TheValue.GV;
- }
- bool isGUID() const { return Kind == VI_GUID; }
+ ArrayRef<std::unique_ptr<GlobalValueSummary>> getSummaryList() const {
+ return Ref->second.SummaryList;
+ }
};
template <> struct DenseMapInfo<ValueInfo> {
- static inline ValueInfo getEmptyKey() { return ValueInfo((GlobalValue *)-1); }
- static inline ValueInfo getTombstoneKey() {
- return ValueInfo((GlobalValue *)-2);
- }
- static bool isEqual(ValueInfo L, ValueInfo R) {
- if (L.isGUID() != R.isGUID())
- return false;
- return L.isGUID() ? (L.getGUID() == R.getGUID())
- : (L.getValue() == R.getValue());
+ static inline ValueInfo getEmptyKey() {
+ return ValueInfo((GlobalValueSummaryMapTy::value_type *)-1);
}
- static unsigned getHashValue(ValueInfo I) {
- return I.isGUID() ? I.getGUID() : (uintptr_t)I.getValue();
+
+ static inline ValueInfo getTombstoneKey() {
+ return ValueInfo((GlobalValueSummaryMapTy::value_type *)-2);
}
+
+ static bool isEqual(ValueInfo L, ValueInfo R) { return L.Ref == R.Ref; }
+ static unsigned getHashValue(ValueInfo I) { return (uintptr_t)I.Ref; }
};
/// \brief Function and variable summary information to aid decisions and
@@ -121,16 +141,18 @@ public:
/// be renamed or references something that can't be renamed).
unsigned NotEligibleToImport : 1;
- /// Indicate that the global value must be considered a live root for
- /// index-based liveness analysis. Used for special LLVM values such as
- /// llvm.global_ctors that the linker does not know about.
- unsigned LiveRoot : 1;
+ /// In per-module summary, indicate that the global value must be considered
+ /// a live root for index-based liveness analysis. Used for special LLVM
+ /// values such as llvm.global_ctors that the linker does not know about.
+ ///
+ /// In combined summary, indicate that the global value is live.
+ unsigned Live : 1;
/// Convenience Constructors
explicit GVFlags(GlobalValue::LinkageTypes Linkage,
- bool NotEligibleToImport, bool LiveRoot)
+ bool NotEligibleToImport, bool Live)
: Linkage(Linkage), NotEligibleToImport(NotEligibleToImport),
- LiveRoot(LiveRoot) {}
+ Live(Live) {}
};
private:
@@ -142,7 +164,7 @@ private:
/// This is the hash of the name of the symbol in the original file. It is
/// identical to the GUID for global symbols, but differs for local since the
/// GUID includes the module level id in the hash.
- GlobalValue::GUID OriginalName;
+ GlobalValue::GUID OriginalName = 0;
/// \brief Path of module IR containing value's definition, used to locate
/// module during importing.
@@ -159,8 +181,9 @@ private:
/// are listed in the derived FunctionSummary object.
std::vector<ValueInfo> RefEdgeList;
+ bool isLive() const { return Flags.Live; }
+
protected:
- /// GlobalValueSummary constructor.
GlobalValueSummary(SummaryKind K, GVFlags Flags, std::vector<ValueInfo> Refs)
: Kind(K), Flags(Flags), RefEdgeList(std::move(Refs)) {}
@@ -201,19 +224,17 @@ public:
/// Return true if this global value can't be imported.
bool notEligibleToImport() const { return Flags.NotEligibleToImport; }
- /// Return true if this global value must be considered a root for live
- /// value analysis on the index.
- bool liveRoot() const { return Flags.LiveRoot; }
-
- /// Flag that this global value must be considered a root for live
- /// value analysis on the index.
- void setLiveRoot() { Flags.LiveRoot = true; }
+ void setLive(bool Live) { Flags.Live = Live; }
/// Flag that this global value cannot be imported.
void setNotEligibleToImport() { Flags.NotEligibleToImport = true; }
/// Return the list of values referenced by this global value definition.
ArrayRef<ValueInfo> refs() const { return RefEdgeList; }
+
+ friend class ModuleSummaryIndex;
+ friend void computeDeadSymbols(class ModuleSummaryIndex &,
+ const DenseSet<GlobalValue::GUID> &);
};
/// \brief Alias summary information.
@@ -221,7 +242,6 @@ class AliasSummary : public GlobalValueSummary {
GlobalValueSummary *AliaseeSummary;
public:
- /// Summary constructors.
AliasSummary(GVFlags Flags, std::vector<ValueInfo> Refs)
: GlobalValueSummary(AliasKind, Flags, std::move(Refs)) {}
@@ -233,12 +253,13 @@ public:
void setAliasee(GlobalValueSummary *Aliasee) { AliaseeSummary = Aliasee; }
const GlobalValueSummary &getAliasee() const {
- return const_cast<AliasSummary *>(this)->getAliasee();
+ assert(AliaseeSummary && "Unexpected missing aliasee summary");
+ return *AliaseeSummary;
}
GlobalValueSummary &getAliasee() {
- assert(AliaseeSummary && "Unexpected missing aliasee summary");
- return *AliaseeSummary;
+ return const_cast<GlobalValueSummary &>(
+ static_cast<const AliasSummary *>(this)->getAliasee());
}
};
@@ -247,7 +268,24 @@ public:
class FunctionSummary : public GlobalValueSummary {
public:
/// <CalleeValueInfo, CalleeInfo> call edge pair.
- typedef std::pair<ValueInfo, CalleeInfo> EdgeTy;
+ using EdgeTy = std::pair<ValueInfo, CalleeInfo>;
+
+ /// An "identifier" for a virtual function. This contains the type identifier
+ /// represented as a GUID and the offset from the address point to the virtual
+ /// function pointer, where "address point" is as defined in the Itanium ABI:
+ /// https://mentorembedded.github.io/cxx-abi/abi.html#vtable-general
+ struct VFuncId {
+ GlobalValue::GUID GUID;
+ uint64_t Offset;
+ };
+
+ /// A specification for a virtual function call with all constant integer
+ /// arguments. This is used to perform virtual constant propagation on the
+ /// summary.
+ struct ConstVCall {
+ VFuncId VFunc;
+ std::vector<uint64_t> Args;
+ };
private:
/// Number of instructions (ignoring debug instructions, e.g.) computed
@@ -257,17 +295,46 @@ private:
/// List of <CalleeValueInfo, CalleeInfo> call edge pairs from this function.
std::vector<EdgeTy> CallGraphEdgeList;
- /// List of type identifiers used by this function, represented as GUIDs.
- std::vector<GlobalValue::GUID> TypeIdList;
+ /// All type identifier related information. Because these fields are
+ /// relatively uncommon we only allocate space for them if necessary.
+ struct TypeIdInfo {
+ /// List of type identifiers used by this function in llvm.type.test
+ /// intrinsics other than by an llvm.assume intrinsic, represented as GUIDs.
+ std::vector<GlobalValue::GUID> TypeTests;
+
+ /// List of virtual calls made by this function using (respectively)
+ /// llvm.assume(llvm.type.test) or llvm.type.checked.load intrinsics that do
+ /// not have all constant integer arguments.
+ std::vector<VFuncId> TypeTestAssumeVCalls, TypeCheckedLoadVCalls;
+
+ /// List of virtual calls made by this function using (respectively)
+ /// llvm.assume(llvm.type.test) or llvm.type.checked.load intrinsics with
+ /// all constant integer arguments.
+ std::vector<ConstVCall> TypeTestAssumeConstVCalls,
+ TypeCheckedLoadConstVCalls;
+ };
+
+ std::unique_ptr<TypeIdInfo> TIdInfo;
public:
- /// Summary constructors.
FunctionSummary(GVFlags Flags, unsigned NumInsts, std::vector<ValueInfo> Refs,
std::vector<EdgeTy> CGEdges,
- std::vector<GlobalValue::GUID> TypeIds)
+ std::vector<GlobalValue::GUID> TypeTests,
+ std::vector<VFuncId> TypeTestAssumeVCalls,
+ std::vector<VFuncId> TypeCheckedLoadVCalls,
+ std::vector<ConstVCall> TypeTestAssumeConstVCalls,
+ std::vector<ConstVCall> TypeCheckedLoadConstVCalls)
: GlobalValueSummary(FunctionKind, Flags, std::move(Refs)),
- InstCount(NumInsts), CallGraphEdgeList(std::move(CGEdges)),
- TypeIdList(std::move(TypeIds)) {}
+ InstCount(NumInsts), CallGraphEdgeList(std::move(CGEdges)) {
+ if (!TypeTests.empty() || !TypeTestAssumeVCalls.empty() ||
+ !TypeCheckedLoadVCalls.empty() || !TypeTestAssumeConstVCalls.empty() ||
+ !TypeCheckedLoadConstVCalls.empty())
+ TIdInfo = llvm::make_unique<TypeIdInfo>(TypeIdInfo{
+ std::move(TypeTests), std::move(TypeTestAssumeVCalls),
+ std::move(TypeCheckedLoadVCalls),
+ std::move(TypeTestAssumeConstVCalls),
+ std::move(TypeCheckedLoadConstVCalls)});
+ }
/// Check if this is a function summary.
static bool classof(const GlobalValueSummary *GVS) {
@@ -280,8 +347,91 @@ public:
/// Return the list of <CalleeValueInfo, CalleeInfo> pairs.
ArrayRef<EdgeTy> calls() const { return CallGraphEdgeList; }
- /// Returns the list of type identifiers used by this function.
- ArrayRef<GlobalValue::GUID> type_tests() const { return TypeIdList; }
+ /// Returns the list of type identifiers used by this function in
+ /// llvm.type.test intrinsics other than by an llvm.assume intrinsic,
+ /// represented as GUIDs.
+ ArrayRef<GlobalValue::GUID> type_tests() const {
+ if (TIdInfo)
+ return TIdInfo->TypeTests;
+ return {};
+ }
+
+ /// Returns the list of virtual calls made by this function using
+ /// llvm.assume(llvm.type.test) intrinsics that do not have all constant
+ /// integer arguments.
+ ArrayRef<VFuncId> type_test_assume_vcalls() const {
+ if (TIdInfo)
+ return TIdInfo->TypeTestAssumeVCalls;
+ return {};
+ }
+
+ /// Returns the list of virtual calls made by this function using
+ /// llvm.type.checked.load intrinsics that do not have all constant integer
+ /// arguments.
+ ArrayRef<VFuncId> type_checked_load_vcalls() const {
+ if (TIdInfo)
+ return TIdInfo->TypeCheckedLoadVCalls;
+ return {};
+ }
+
+ /// Returns the list of virtual calls made by this function using
+ /// llvm.assume(llvm.type.test) intrinsics with all constant integer
+ /// arguments.
+ ArrayRef<ConstVCall> type_test_assume_const_vcalls() const {
+ if (TIdInfo)
+ return TIdInfo->TypeTestAssumeConstVCalls;
+ return {};
+ }
+
+ /// Returns the list of virtual calls made by this function using
+ /// llvm.type.checked.load intrinsics with all constant integer arguments.
+ ArrayRef<ConstVCall> type_checked_load_const_vcalls() const {
+ if (TIdInfo)
+ return TIdInfo->TypeCheckedLoadConstVCalls;
+ return {};
+ }
+
+ /// 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) {
+ if (!TIdInfo)
+ TIdInfo = llvm::make_unique<TypeIdInfo>();
+ TIdInfo->TypeTests.push_back(Guid);
+ }
+};
+
+template <> struct DenseMapInfo<FunctionSummary::VFuncId> {
+ static FunctionSummary::VFuncId getEmptyKey() { return {0, uint64_t(-1)}; }
+
+ static FunctionSummary::VFuncId getTombstoneKey() {
+ return {0, uint64_t(-2)};
+ }
+
+ static bool isEqual(FunctionSummary::VFuncId L, FunctionSummary::VFuncId R) {
+ return L.GUID == R.GUID && L.Offset == R.Offset;
+ }
+
+ static unsigned getHashValue(FunctionSummary::VFuncId I) { return I.GUID; }
+};
+
+template <> struct DenseMapInfo<FunctionSummary::ConstVCall> {
+ static FunctionSummary::ConstVCall getEmptyKey() {
+ return {{0, uint64_t(-1)}, {}};
+ }
+
+ static FunctionSummary::ConstVCall getTombstoneKey() {
+ return {{0, uint64_t(-2)}, {}};
+ }
+
+ static bool isEqual(FunctionSummary::ConstVCall L,
+ FunctionSummary::ConstVCall R) {
+ return DenseMapInfo<FunctionSummary::VFuncId>::isEqual(L.VFunc, R.VFunc) &&
+ L.Args == R.Args;
+ }
+
+ static unsigned getHashValue(FunctionSummary::ConstVCall I) {
+ return I.VFunc.GUID;
+ }
};
/// \brief Global variable summary information to aid decisions and
@@ -293,7 +443,6 @@ public:
class GlobalVarSummary : public GlobalValueSummary {
public:
- /// Summary constructors.
GlobalVarSummary(GVFlags Flags, std::vector<ValueInfo> Refs)
: GlobalValueSummary(GlobalVarKind, Flags, std::move(Refs)) {}
@@ -323,38 +472,57 @@ struct TypeTestResolution {
unsigned SizeM1BitWidth = 0;
};
+struct WholeProgramDevirtResolution {
+ enum Kind {
+ Indir, ///< Just do a regular virtual call
+ SingleImpl, ///< Single implementation devirtualization
+ } TheKind = Indir;
+
+ std::string SingleImplName;
+
+ struct ByArg {
+ enum Kind {
+ Indir, ///< Just do a regular virtual call
+ UniformRetVal, ///< Uniform return value optimization
+ UniqueRetVal, ///< Unique return value optimization
+ VirtualConstProp, ///< Virtual constant propagation
+ } TheKind = Indir;
+
+ /// Additional information for the resolution:
+ /// - UniformRetVal: the uniform return value.
+ /// - UniqueRetVal: the return value associated with the unique vtable (0 or
+ /// 1).
+ uint64_t Info = 0;
+ };
+
+ /// Resolutions for calls with all constant integer arguments (excluding the
+ /// first argument, "this"), where the key is the argument vector.
+ std::map<std::vector<uint64_t>, ByArg> ResByArg;
+};
+
struct TypeIdSummary {
TypeTestResolution TTRes;
+
+ /// Mapping from byte offset to whole-program devirt resolution for that
+ /// (typeid, byte offset) pair.
+ std::map<uint64_t, WholeProgramDevirtResolution> WPDRes;
};
/// 160 bits SHA1
-typedef std::array<uint32_t, 5> ModuleHash;
-
-/// List of global value summary structures for a particular value held
-/// in the GlobalValueMap. Requires a vector in the case of multiple
-/// COMDAT values of the same name.
-typedef std::vector<std::unique_ptr<GlobalValueSummary>> GlobalValueSummaryList;
-
-/// Map from global value GUID to corresponding summary structures.
-/// Use a std::map rather than a DenseMap since it will likely incur
-/// less overhead, as the value type is not very small and the size
-/// of the map is unknown, resulting in inefficiencies due to repeated
-/// insertions and resizing.
-typedef std::map<GlobalValue::GUID, GlobalValueSummaryList>
- GlobalValueSummaryMapTy;
+using ModuleHash = std::array<uint32_t, 5>;
/// Type used for iterating through the global value summary map.
-typedef GlobalValueSummaryMapTy::const_iterator const_gvsummary_iterator;
-typedef GlobalValueSummaryMapTy::iterator gvsummary_iterator;
+using const_gvsummary_iterator = GlobalValueSummaryMapTy::const_iterator;
+using gvsummary_iterator = GlobalValueSummaryMapTy::iterator;
/// String table to hold/own module path strings, which additionally holds the
/// module ID assigned to each module during the plugin step, as well as a hash
/// of the module. The StringMap makes a copy of and owns inserted strings.
-typedef StringMap<std::pair<uint64_t, ModuleHash>> ModulePathStringTableTy;
+using ModulePathStringTableTy = StringMap<std::pair<uint64_t, ModuleHash>>;
/// Map of global value GUID to its summary, used to identify values defined in
/// a particular module, and provide efficient access to their summary.
-typedef std::map<GlobalValue::GUID, GlobalValueSummary *> GVSummaryMapTy;
+using GVSummaryMapTy = DenseMap<GlobalValue::GUID, GlobalValueSummary *>;
/// Class to hold module path string table and global value map,
/// and encapsulate methods for operating on them.
@@ -372,9 +540,26 @@ private:
// FIXME: Add bitcode read/write support for this field.
std::map<std::string, TypeIdSummary> TypeIdMap;
+ /// Mapping from original ID to GUID. If original ID can map to multiple
+ /// GUIDs, it will be mapped to 0.
+ std::map<GlobalValue::GUID, GlobalValue::GUID> OidGuidMap;
+
+ /// Indicates that summary-based GlobalValue GC has run, and values with
+ /// GVFlags::Live==false are really dead. Otherwise, all values must be
+ /// considered live.
+ bool WithGlobalValueDeadStripping = false;
+
+ std::set<std::string> CfiFunctionDefs;
+ std::set<std::string> CfiFunctionDecls;
+
// YAML I/O support.
friend yaml::MappingTraits<ModuleSummaryIndex>;
+ GlobalValueSummaryMapTy::value_type *
+ getOrInsertValuePtr(GlobalValue::GUID GUID) {
+ return &*GlobalValueMap.emplace(GUID, GlobalValueSummaryInfo{}).first;
+ }
+
public:
gvsummary_iterator begin() { return GlobalValueMap.begin(); }
const_gvsummary_iterator begin() const { return GlobalValueMap.begin(); }
@@ -382,50 +567,90 @@ public:
const_gvsummary_iterator end() const { return GlobalValueMap.end(); }
size_t size() const { return GlobalValueMap.size(); }
- /// Get the list of global value summary objects for a given value name.
- const GlobalValueSummaryList &getGlobalValueSummaryList(StringRef ValueName) {
- return GlobalValueMap[GlobalValue::getGUID(ValueName)];
+ bool withGlobalValueDeadStripping() const {
+ return WithGlobalValueDeadStripping;
+ }
+ void setWithGlobalValueDeadStripping() {
+ WithGlobalValueDeadStripping = true;
+ }
+
+ bool isGlobalValueLive(const GlobalValueSummary *GVS) const {
+ return !WithGlobalValueDeadStripping || GVS->isLive();
+ }
+ bool isGUIDLive(GlobalValue::GUID GUID) const;
+
+ /// Return a ValueInfo for GUID if it exists, otherwise return ValueInfo().
+ ValueInfo getValueInfo(GlobalValue::GUID GUID) const {
+ auto I = GlobalValueMap.find(GUID);
+ return ValueInfo(I == GlobalValueMap.end() ? nullptr : &*I);
+ }
+
+ /// Return a ValueInfo for \p GUID.
+ ValueInfo getOrInsertValueInfo(GlobalValue::GUID GUID) {
+ return ValueInfo(getOrInsertValuePtr(GUID));
}
- /// Get the list of global value summary objects for a given value name.
- const const_gvsummary_iterator
- findGlobalValueSummaryList(StringRef ValueName) const {
- return GlobalValueMap.find(GlobalValue::getGUID(ValueName));
+ /// Return a ValueInfo for \p GV and mark it as belonging to GV.
+ ValueInfo getOrInsertValueInfo(const GlobalValue *GV) {
+ auto VP = getOrInsertValuePtr(GV->getGUID());
+ VP->second.GV = GV;
+ return ValueInfo(VP);
}
- /// Get the list of global value summary objects for a given value GUID.
- const const_gvsummary_iterator
- findGlobalValueSummaryList(GlobalValue::GUID ValueGUID) const {
- return GlobalValueMap.find(ValueGUID);
+ /// Return the GUID for \p OriginalId in the OidGuidMap.
+ GlobalValue::GUID getGUIDFromOriginalID(GlobalValue::GUID OriginalID) const {
+ const auto I = OidGuidMap.find(OriginalID);
+ return I == OidGuidMap.end() ? 0 : I->second;
}
+ std::set<std::string> &cfiFunctionDefs() { return CfiFunctionDefs; }
+ const std::set<std::string> &cfiFunctionDefs() const { return CfiFunctionDefs; }
+
+ std::set<std::string> &cfiFunctionDecls() { return CfiFunctionDecls; }
+ const std::set<std::string> &cfiFunctionDecls() const { return CfiFunctionDecls; }
+
/// Add a global value summary for a value of the given name.
void addGlobalValueSummary(StringRef ValueName,
std::unique_ptr<GlobalValueSummary> Summary) {
- GlobalValueMap[GlobalValue::getGUID(ValueName)].push_back(
- std::move(Summary));
+ addGlobalValueSummary(getOrInsertValueInfo(GlobalValue::getGUID(ValueName)),
+ std::move(Summary));
}
- /// Add a global value summary for a value of the given GUID.
- void addGlobalValueSummary(GlobalValue::GUID ValueGUID,
+ /// Add a global value summary for the given ValueInfo.
+ void addGlobalValueSummary(ValueInfo VI,
std::unique_ptr<GlobalValueSummary> Summary) {
- GlobalValueMap[ValueGUID].push_back(std::move(Summary));
+ addOriginalName(VI.getGUID(), Summary->getOriginalName());
+ // Here we have a notionally const VI, but the value it points to is owned
+ // by the non-const *this.
+ const_cast<GlobalValueSummaryMapTy::value_type *>(VI.Ref)
+ ->second.SummaryList.push_back(std::move(Summary));
+ }
+
+ /// Add an original name for the value of the given GUID.
+ void addOriginalName(GlobalValue::GUID ValueGUID,
+ GlobalValue::GUID OrigGUID) {
+ if (OrigGUID == 0 || ValueGUID == OrigGUID)
+ return;
+ if (OidGuidMap.count(OrigGUID) && OidGuidMap[OrigGUID] != ValueGUID)
+ OidGuidMap[OrigGUID] = 0;
+ else
+ OidGuidMap[OrigGUID] = ValueGUID;
}
/// Find the summary for global \p GUID in module \p ModuleId, or nullptr if
/// not found.
GlobalValueSummary *findSummaryInModule(GlobalValue::GUID ValueGUID,
StringRef ModuleId) const {
- auto CalleeInfoList = findGlobalValueSummaryList(ValueGUID);
- if (CalleeInfoList == end()) {
+ auto CalleeInfo = getValueInfo(ValueGUID);
+ if (!CalleeInfo) {
return nullptr; // This function does not have a summary
}
auto Summary =
- llvm::find_if(CalleeInfoList->second,
+ llvm::find_if(CalleeInfo.getSummaryList(),
[&](const std::unique_ptr<GlobalValueSummary> &Summary) {
return Summary->modulePath() == ModuleId;
});
- if (Summary == CalleeInfoList->second.end())
+ if (Summary == CalleeInfo.getSummaryList().end())
return nullptr;
return Summary->get();
}
@@ -467,13 +692,6 @@ public:
return It->second.second;
}
- /// Add the given per-module index into this module index/summary,
- /// assigning it the given module ID. Each module merged in should have
- /// a unique ID, necessary for consistent renaming of promoted
- /// static (local) variables.
- void mergeFrom(std::unique_ptr<ModuleSummaryIndex> Other,
- uint64_t NextModuleId);
-
/// Convenience method for creating a promoted global name
/// for the given value name of a local, and its original module's ID.
static std::string getGlobalNameForLocal(StringRef Name, ModuleHash ModHash) {
@@ -490,14 +708,13 @@ public:
return Pair.first;
}
- /// Add a new module path with the given \p Hash, mapped to the given \p
- /// ModID, and return an iterator to the entry in the index.
- ModulePathStringTableTy::iterator
- addModulePath(StringRef ModPath, uint64_t ModId,
- ModuleHash Hash = ModuleHash{{0}}) {
- return ModulePathStringTable.insert(std::make_pair(
- ModPath,
- std::make_pair(ModId, Hash))).first;
+ typedef ModulePathStringTableTy::value_type ModuleInfo;
+
+ /// Add a new module with the given \p Hash, mapped to the given \p
+ /// ModID, and return a reference to the module.
+ ModuleInfo *addModule(StringRef ModPath, uint64_t ModId,
+ ModuleHash Hash = ModuleHash{{0}}) {
+ return &*ModulePathStringTable.insert({ModPath, {ModId, Hash}}).first;
}
/// Check if the given Module has any functions available for exporting
@@ -507,12 +724,24 @@ public:
return ModulePathStringTable.count(M.getModuleIdentifier());
}
- /// Remove entries in the GlobalValueMap that have empty summaries due to the
- /// eager nature of map entry creation during VST parsing. These would
- /// also be suppressed during combined index generation in mergeFrom(),
- /// but if there was only one module or this was the first module we might
- /// not invoke mergeFrom.
- void removeEmptySummaryEntries();
+ const std::map<std::string, TypeIdSummary> &typeIds() const {
+ return TypeIdMap;
+ }
+
+ /// This accessor should only be used when exporting because it can mutate the
+ /// map.
+ TypeIdSummary &getOrInsertTypeIdSummary(StringRef TypeId) {
+ return TypeIdMap[TypeId];
+ }
+
+ /// This returns either a pointer to the type id summary (if present in the
+ /// summary map) or null (if not present). This may be used when importing.
+ const TypeIdSummary *getTypeIdSummary(StringRef TypeId) const {
+ auto I = TypeIdMap.find(TypeId);
+ if (I == TypeIdMap.end())
+ return nullptr;
+ return &I->second;
+ }
/// Collect for the given module the list of function it defines
/// (GUID -> Summary).
@@ -525,6 +754,6 @@ public:
StringMap<GVSummaryMapTy> &ModuleToDefinedGVSummaries) const;
};
-} // End llvm namespace
+} // end namespace llvm
-#endif
+#endif // LLVM_IR_MODULESUMMARYINDEX_H
diff --git a/contrib/llvm/include/llvm/IR/ModuleSummaryIndexYAML.h b/contrib/llvm/include/llvm/IR/ModuleSummaryIndexYAML.h
index e2880ec..7f6cb5b 100644
--- a/contrib/llvm/include/llvm/IR/ModuleSummaryIndexYAML.h
+++ b/contrib/llvm/include/llvm/IR/ModuleSummaryIndexYAML.h
@@ -33,27 +33,151 @@ template <> struct MappingTraits<TypeTestResolution> {
}
};
+template <>
+struct ScalarEnumerationTraits<WholeProgramDevirtResolution::ByArg::Kind> {
+ static void enumeration(IO &io,
+ WholeProgramDevirtResolution::ByArg::Kind &value) {
+ io.enumCase(value, "Indir", WholeProgramDevirtResolution::ByArg::Indir);
+ io.enumCase(value, "UniformRetVal",
+ WholeProgramDevirtResolution::ByArg::UniformRetVal);
+ io.enumCase(value, "UniqueRetVal",
+ WholeProgramDevirtResolution::ByArg::UniqueRetVal);
+ io.enumCase(value, "VirtualConstProp",
+ WholeProgramDevirtResolution::ByArg::VirtualConstProp);
+ }
+};
+
+template <> struct MappingTraits<WholeProgramDevirtResolution::ByArg> {
+ static void mapping(IO &io, WholeProgramDevirtResolution::ByArg &res) {
+ io.mapOptional("Kind", res.TheKind);
+ io.mapOptional("Info", res.Info);
+ }
+};
+
+template <>
+struct CustomMappingTraits<
+ std::map<std::vector<uint64_t>, WholeProgramDevirtResolution::ByArg>> {
+ static void inputOne(
+ IO &io, StringRef Key,
+ std::map<std::vector<uint64_t>, WholeProgramDevirtResolution::ByArg> &V) {
+ std::vector<uint64_t> Args;
+ std::pair<StringRef, StringRef> P = {"", Key};
+ while (!P.second.empty()) {
+ P = P.second.split(',');
+ uint64_t Arg;
+ if (P.first.getAsInteger(0, Arg)) {
+ io.setError("key not an integer");
+ return;
+ }
+ Args.push_back(Arg);
+ }
+ io.mapRequired(Key.str().c_str(), V[Args]);
+ }
+ static void output(
+ IO &io,
+ std::map<std::vector<uint64_t>, WholeProgramDevirtResolution::ByArg> &V) {
+ for (auto &P : V) {
+ std::string Key;
+ for (uint64_t Arg : P.first) {
+ if (!Key.empty())
+ Key += ',';
+ Key += llvm::utostr(Arg);
+ }
+ io.mapRequired(Key.c_str(), P.second);
+ }
+ }
+};
+
+template <> struct ScalarEnumerationTraits<WholeProgramDevirtResolution::Kind> {
+ static void enumeration(IO &io, WholeProgramDevirtResolution::Kind &value) {
+ io.enumCase(value, "Indir", WholeProgramDevirtResolution::Indir);
+ io.enumCase(value, "SingleImpl", WholeProgramDevirtResolution::SingleImpl);
+ }
+};
+
+template <> struct MappingTraits<WholeProgramDevirtResolution> {
+ static void mapping(IO &io, WholeProgramDevirtResolution &res) {
+ io.mapOptional("Kind", res.TheKind);
+ io.mapOptional("SingleImplName", res.SingleImplName);
+ io.mapOptional("ResByArg", res.ResByArg);
+ }
+};
+
+template <>
+struct CustomMappingTraits<std::map<uint64_t, WholeProgramDevirtResolution>> {
+ static void inputOne(IO &io, StringRef Key,
+ std::map<uint64_t, WholeProgramDevirtResolution> &V) {
+ uint64_t KeyInt;
+ if (Key.getAsInteger(0, KeyInt)) {
+ io.setError("key not an integer");
+ return;
+ }
+ io.mapRequired(Key.str().c_str(), V[KeyInt]);
+ }
+ static void output(IO &io, std::map<uint64_t, WholeProgramDevirtResolution> &V) {
+ for (auto &P : V)
+ io.mapRequired(llvm::utostr(P.first).c_str(), P.second);
+ }
+};
+
template <> struct MappingTraits<TypeIdSummary> {
static void mapping(IO &io, TypeIdSummary& summary) {
io.mapOptional("TTRes", summary.TTRes);
+ io.mapOptional("WPDRes", summary.WPDRes);
}
};
struct FunctionSummaryYaml {
+ unsigned Linkage;
+ bool NotEligibleToImport, Live;
std::vector<uint64_t> TypeTests;
+ std::vector<FunctionSummary::VFuncId> TypeTestAssumeVCalls,
+ TypeCheckedLoadVCalls;
+ std::vector<FunctionSummary::ConstVCall> TypeTestAssumeConstVCalls,
+ TypeCheckedLoadConstVCalls;
};
} // End yaml namespace
} // End llvm namespace
-LLVM_YAML_IS_SEQUENCE_VECTOR(uint64_t)
+namespace llvm {
+namespace yaml {
+
+template <> struct MappingTraits<FunctionSummary::VFuncId> {
+ static void mapping(IO &io, FunctionSummary::VFuncId& id) {
+ io.mapOptional("GUID", id.GUID);
+ io.mapOptional("Offset", id.Offset);
+ }
+};
+
+template <> struct MappingTraits<FunctionSummary::ConstVCall> {
+ static void mapping(IO &io, FunctionSummary::ConstVCall& id) {
+ io.mapOptional("VFunc", id.VFunc);
+ io.mapOptional("Args", id.Args);
+ }
+};
+
+} // End yaml namespace
+} // End llvm namespace
+
+LLVM_YAML_IS_SEQUENCE_VECTOR(FunctionSummary::VFuncId)
+LLVM_YAML_IS_SEQUENCE_VECTOR(FunctionSummary::ConstVCall)
namespace llvm {
namespace yaml {
template <> struct MappingTraits<FunctionSummaryYaml> {
static void mapping(IO &io, FunctionSummaryYaml& summary) {
+ io.mapOptional("Linkage", summary.Linkage);
+ io.mapOptional("NotEligibleToImport", summary.NotEligibleToImport);
+ io.mapOptional("Live", summary.Live);
io.mapOptional("TypeTests", summary.TypeTests);
+ io.mapOptional("TypeTestAssumeVCalls", summary.TypeTestAssumeVCalls);
+ io.mapOptional("TypeCheckedLoadVCalls", summary.TypeCheckedLoadVCalls);
+ io.mapOptional("TypeTestAssumeConstVCalls",
+ summary.TypeTestAssumeConstVCalls);
+ io.mapOptional("TypeCheckedLoadConstVCalls",
+ summary.TypeCheckedLoadConstVCalls);
}
};
@@ -78,19 +202,29 @@ template <> struct CustomMappingTraits<GlobalValueSummaryMapTy> {
}
auto &Elem = V[KeyInt];
for (auto &FSum : FSums) {
- GlobalValueSummary::GVFlags GVFlags(GlobalValue::ExternalLinkage, false,
- false);
- Elem.push_back(llvm::make_unique<FunctionSummary>(
- GVFlags, 0, ArrayRef<ValueInfo>{},
- ArrayRef<FunctionSummary::EdgeTy>{}, std::move(FSum.TypeTests)));
+ Elem.SummaryList.push_back(llvm::make_unique<FunctionSummary>(
+ GlobalValueSummary::GVFlags(
+ static_cast<GlobalValue::LinkageTypes>(FSum.Linkage),
+ FSum.NotEligibleToImport, FSum.Live),
+ 0, ArrayRef<ValueInfo>{}, ArrayRef<FunctionSummary::EdgeTy>{},
+ std::move(FSum.TypeTests), std::move(FSum.TypeTestAssumeVCalls),
+ std::move(FSum.TypeCheckedLoadVCalls),
+ std::move(FSum.TypeTestAssumeConstVCalls),
+ std::move(FSum.TypeCheckedLoadConstVCalls)));
}
}
static void output(IO &io, GlobalValueSummaryMapTy &V) {
for (auto &P : V) {
std::vector<FunctionSummaryYaml> FSums;
- for (auto &Sum : P.second) {
+ for (auto &Sum : P.second.SummaryList) {
if (auto *FSum = dyn_cast<FunctionSummary>(Sum.get()))
- FSums.push_back(FunctionSummaryYaml{FSum->type_tests()});
+ FSums.push_back(FunctionSummaryYaml{
+ FSum->flags().Linkage,
+ static_cast<bool>(FSum->flags().NotEligibleToImport),
+ static_cast<bool>(FSum->flags().Live), FSum->type_tests(),
+ FSum->type_test_assume_vcalls(), FSum->type_checked_load_vcalls(),
+ FSum->type_test_assume_const_vcalls(),
+ FSum->type_checked_load_const_vcalls()});
}
if (!FSums.empty())
io.mapRequired(llvm::utostr(P.first).c_str(), FSums);
@@ -102,6 +236,25 @@ template <> struct MappingTraits<ModuleSummaryIndex> {
static void mapping(IO &io, ModuleSummaryIndex& index) {
io.mapOptional("GlobalValueMap", index.GlobalValueMap);
io.mapOptional("TypeIdMap", index.TypeIdMap);
+ io.mapOptional("WithGlobalValueDeadStripping",
+ index.WithGlobalValueDeadStripping);
+
+ if (io.outputting()) {
+ std::vector<std::string> CfiFunctionDefs(index.CfiFunctionDefs.begin(),
+ index.CfiFunctionDefs.end());
+ io.mapOptional("CfiFunctionDefs", CfiFunctionDefs);
+ std::vector<std::string> CfiFunctionDecls(index.CfiFunctionDecls.begin(),
+ index.CfiFunctionDecls.end());
+ io.mapOptional("CfiFunctionDecls", CfiFunctionDecls);
+ } else {
+ std::vector<std::string> CfiFunctionDefs;
+ io.mapOptional("CfiFunctionDefs", CfiFunctionDefs);
+ index.CfiFunctionDefs = {CfiFunctionDefs.begin(), CfiFunctionDefs.end()};
+ std::vector<std::string> CfiFunctionDecls;
+ io.mapOptional("CfiFunctionDecls", CfiFunctionDecls);
+ index.CfiFunctionDecls = {CfiFunctionDecls.begin(),
+ CfiFunctionDecls.end()};
+ }
}
};
diff --git a/contrib/llvm/include/llvm/IR/OperandTraits.h b/contrib/llvm/include/llvm/IR/OperandTraits.h
index e97a800..c618aff 100644
--- a/contrib/llvm/include/llvm/IR/OperandTraits.h
+++ b/contrib/llvm/include/llvm/IR/OperandTraits.h
@@ -30,6 +30,9 @@ namespace llvm {
template <typename SubClass, unsigned ARITY>
struct FixedNumOperandTraits {
static Use *op_begin(SubClass* U) {
+ static_assert(
+ !std::is_polymorphic<SubClass>::value,
+ "adding virtual methods to subclasses of User breaks use lists");
return reinterpret_cast<Use*>(U) - ARITY;
}
static Use *op_end(SubClass* U) {
@@ -65,6 +68,9 @@ struct OptionalOperandTraits : public FixedNumOperandTraits<SubClass, ARITY> {
template <typename SubClass, unsigned MINARITY = 0>
struct VariadicOperandTraits {
static Use *op_begin(SubClass* U) {
+ static_assert(
+ !std::is_polymorphic<SubClass>::value,
+ "adding virtual methods to subclasses of User breaks use lists");
return reinterpret_cast<Use*>(U) - static_cast<User*>(U)->getNumOperands();
}
static Use *op_end(SubClass* U) {
@@ -82,9 +88,6 @@ struct VariadicOperandTraits {
/// HungoffOperandTraits - determine the allocation regime of the Use array
/// when it is not a prefix to the User object, but allocated at an unrelated
/// heap address.
-/// Assumes that the User subclass that is determined by this traits class
-/// has an OperandList member of type User::op_iterator. [Note: this is now
-/// trivially satisfied, because User has that member for historic reasons.]
///
/// This is the traits class that is needed when the Use array must be
/// resizable.
diff --git a/contrib/llvm/include/llvm/IR/Operator.h b/contrib/llvm/include/llvm/IR/Operator.h
index 444ce93..9df6bfc 100644
--- a/contrib/llvm/include/llvm/IR/Operator.h
+++ b/contrib/llvm/include/llvm/IR/Operator.h
@@ -18,8 +18,6 @@
#include "llvm/ADT/None.h"
#include "llvm/ADT/Optional.h"
#include "llvm/IR/Constants.h"
-#include "llvm/IR/DataLayout.h"
-#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Value.h"
@@ -31,18 +29,12 @@ namespace llvm {
/// This is a utility class that provides an abstraction for the common
/// functionality between Instructions and ConstantExprs.
class Operator : public User {
-protected:
- // NOTE: Cannot use = delete because it's not legal to delete
- // an overridden method that's not deleted in the base class. Cannot leave
- // this unimplemented because that leads to an ODR-violation.
- ~Operator() override;
-
public:
// The Operator class is intended to be used as a utility, and is never itself
// instantiated.
Operator() = delete;
+ ~Operator() = delete;
- void *operator new(size_t, unsigned) = delete;
void *operator new(size_t s) = delete;
/// Return the opcode for this Instruction or ConstantExpr.
@@ -62,9 +54,9 @@ public:
return Instruction::UserOp1;
}
- static inline bool classof(const Instruction *) { return true; }
- static inline bool classof(const ConstantExpr *) { return true; }
- static inline bool classof(const Value *V) {
+ static bool classof(const Instruction *) { return true; }
+ static bool classof(const ConstantExpr *) { return true; }
+ static bool classof(const Value *V) {
return isa<Instruction>(V) || isa<ConstantExpr>(V);
}
};
@@ -105,19 +97,19 @@ public:
return (SubclassOptionalData & NoSignedWrap) != 0;
}
- static inline bool classof(const Instruction *I) {
+ static bool classof(const Instruction *I) {
return I->getOpcode() == Instruction::Add ||
I->getOpcode() == Instruction::Sub ||
I->getOpcode() == Instruction::Mul ||
I->getOpcode() == Instruction::Shl;
}
- static inline bool classof(const ConstantExpr *CE) {
+ static bool classof(const ConstantExpr *CE) {
return CE->getOpcode() == Instruction::Add ||
CE->getOpcode() == Instruction::Sub ||
CE->getOpcode() == Instruction::Mul ||
CE->getOpcode() == Instruction::Shl;
}
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return (isa<Instruction>(V) && classof(cast<Instruction>(V))) ||
(isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V)));
}
@@ -152,13 +144,13 @@ public:
OpC == Instruction::LShr;
}
- static inline bool classof(const ConstantExpr *CE) {
+ static bool classof(const ConstantExpr *CE) {
return isPossiblyExactOpcode(CE->getOpcode());
}
- static inline bool classof(const Instruction *I) {
+ static bool classof(const Instruction *I) {
return isPossiblyExactOpcode(I->getOpcode());
}
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return (isa<Instruction>(V) && classof(cast<Instruction>(V))) ||
(isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V)));
}
@@ -174,12 +166,15 @@ private:
FastMathFlags(unsigned F) : Flags(F) { }
public:
+ /// This is how the bits are used in Value::SubclassOptionalData so they
+ /// should fit there too.
enum {
UnsafeAlgebra = (1 << 0),
NoNaNs = (1 << 1),
NoInfs = (1 << 2),
NoSignedZeros = (1 << 3),
- AllowReciprocal = (1 << 4)
+ AllowReciprocal = (1 << 4),
+ AllowContract = (1 << 5)
};
FastMathFlags() = default;
@@ -195,6 +190,7 @@ public:
bool noInfs() const { return 0 != (Flags & NoInfs); }
bool noSignedZeros() const { return 0 != (Flags & NoSignedZeros); }
bool allowReciprocal() const { return 0 != (Flags & AllowReciprocal); }
+ bool allowContract() const { return 0 != (Flags & AllowContract); }
bool unsafeAlgebra() const { return 0 != (Flags & UnsafeAlgebra); }
/// Flag setters
@@ -202,12 +198,16 @@ public:
void setNoInfs() { Flags |= NoInfs; }
void setNoSignedZeros() { Flags |= NoSignedZeros; }
void setAllowReciprocal() { Flags |= AllowReciprocal; }
+ void setAllowContract(bool B) {
+ Flags = (Flags & ~AllowContract) | B * AllowContract;
+ }
void setUnsafeAlgebra() {
Flags |= UnsafeAlgebra;
setNoNaNs();
setNoInfs();
setNoSignedZeros();
setAllowReciprocal();
+ setAllowContract(true);
}
void operator&=(const FastMathFlags &OtherFlags) {
@@ -259,6 +259,12 @@ private:
(B * FastMathFlags::AllowReciprocal);
}
+ void setHasAllowContract(bool B) {
+ SubclassOptionalData =
+ (SubclassOptionalData & ~FastMathFlags::AllowContract) |
+ (B * FastMathFlags::AllowContract);
+ }
+
/// Convenience function for setting multiple fast-math flags.
/// FMF is a mask of the bits to set.
void setFastMathFlags(FastMathFlags FMF) {
@@ -302,6 +308,12 @@ public:
return (SubclassOptionalData & FastMathFlags::AllowReciprocal) != 0;
}
+ /// Test whether this operation is permitted to
+ /// be floating-point contracted.
+ bool hasAllowContract() const {
+ return (SubclassOptionalData & FastMathFlags::AllowContract) != 0;
+ }
+
/// Convenience function for getting all the fast-math flags
FastMathFlags getFastMathFlags() const {
return FastMathFlags(SubclassOptionalData);
@@ -312,12 +324,19 @@ public:
/// precision.
float getFPAccuracy() const;
- static inline bool classof(const Instruction *I) {
+ static bool classof(const Instruction *I) {
return I->getType()->isFPOrFPVectorTy() ||
I->getOpcode() == Instruction::FCmp;
}
- static inline bool classof(const Value *V) {
- return isa<Instruction>(V) && classof(cast<Instruction>(V));
+
+ static bool classof(const ConstantExpr *CE) {
+ return CE->getType()->isFPOrFPVectorTy() ||
+ CE->getOpcode() == Instruction::FCmp;
+ }
+
+ static bool classof(const Value *V) {
+ return (isa<Instruction>(V) && classof(cast<Instruction>(V))) ||
+ (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V)));
}
};
@@ -325,13 +344,13 @@ public:
template<typename SuperClass, unsigned Opc>
class ConcreteOperator : public SuperClass {
public:
- static inline bool classof(const Instruction *I) {
+ static bool classof(const Instruction *I) {
return I->getOpcode() == Opc;
}
- static inline bool classof(const ConstantExpr *CE) {
+ static bool classof(const ConstantExpr *CE) {
return CE->getOpcode() == Opc;
}
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return (isa<Instruction>(V) && classof(cast<Instruction>(V))) ||
(isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V)));
}
diff --git a/contrib/llvm/include/llvm/IR/OptBisect.h b/contrib/llvm/include/llvm/IR/OptBisect.h
index 9eee65e..185a5ac 100644
--- a/contrib/llvm/include/llvm/IR/OptBisect.h
+++ b/contrib/llvm/include/llvm/IR/OptBisect.h
@@ -51,24 +51,6 @@ public:
template <class UnitT>
bool shouldRunPass(const Pass *P, const UnitT &U);
- /// Checks the bisect limit to determine if the optimization described by the
- /// /p Desc argument should run.
- ///
- /// This function will immediate return true if bisection is disabled. If the
- /// bisect limit is set to -1, the function will print a message with the
- /// bisect number assigned to the optimization along with the /p Desc
- /// description and return true. Otherwise, the function will print a message
- /// with the bisect number assigned to the optimization and indicating whether
- /// or not the pass will be run and return true if the bisect limit has not
- /// yet been exceded or false if it has.
- ///
- /// Passes may call this function to provide more fine grained control over
- /// individual optimizations performed by the pass. Passes which cannot be
- /// skipped entirely (such as non-optional code generation passes) may still
- /// call this function to control whether or not individual optional
- /// transformations are performed.
- bool shouldRunCase(const Twine &Desc);
-
private:
bool checkPass(const StringRef PassName, const StringRef TargetDesc);
diff --git a/contrib/llvm/include/llvm/IR/PassManager.h b/contrib/llvm/include/llvm/IR/PassManager.h
index b7811fd..3931756 100644
--- a/contrib/llvm/include/llvm/IR/PassManager.h
+++ b/contrib/llvm/include/llvm/IR/PassManager.h
@@ -39,8 +39,8 @@
#define LLVM_IR_PASSMANAGER_H
#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/TinyPtrVector.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Module.h"
@@ -48,9 +48,15 @@
#include "llvm/Support/Debug.h"
#include "llvm/Support/TypeName.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/Support/type_traits.h"
+#include <algorithm>
+#include <cassert>
+#include <cstring>
+#include <iterator>
#include <list>
#include <memory>
+#include <tuple>
+#include <type_traits>
+#include <utility>
#include <vector>
namespace llvm {
@@ -73,6 +79,46 @@ struct alignas(8) AnalysisKey {};
/// if it is, the analysis knows that it itself is preserved.
struct alignas(8) AnalysisSetKey {};
+/// This templated class represents "all analyses that operate over \<a
+/// particular IR unit\>" (e.g. a Function or a Module) in instances of
+/// PreservedAnalysis.
+///
+/// This lets a transformation say e.g. "I preserved all function analyses".
+///
+/// Note that you must provide an explicit instantiation declaration and
+/// definition for this template in order to get the correct behavior on
+/// Windows. Otherwise, the address of SetKey will not be stable.
+template <typename IRUnitT> class AllAnalysesOn {
+public:
+ static AnalysisSetKey *ID() { return &SetKey; }
+
+private:
+ static AnalysisSetKey SetKey;
+};
+
+template <typename IRUnitT> AnalysisSetKey AllAnalysesOn<IRUnitT>::SetKey;
+
+extern template class AllAnalysesOn<Module>;
+extern template class AllAnalysesOn<Function>;
+
+/// Represents analyses that only rely on functions' control flow.
+///
+/// This can be used with \c PreservedAnalyses to mark the CFG as preserved and
+/// to query whether it has been preserved.
+///
+/// The CFG of a function is defined as the set of basic blocks and the edges
+/// between them. Changing the set of basic blocks in a function is enough to
+/// mutate the CFG. Mutating the condition of a branch or argument of an
+/// invoked function does not mutate the CFG, but changing the successor labels
+/// of those instructions does.
+class CFGAnalyses {
+public:
+ static AnalysisSetKey *ID() { return &SetKey; }
+
+private:
+ static AnalysisSetKey SetKey;
+};
+
/// A set of analyses that are preserved following a run of a transformation
/// pass.
///
@@ -116,6 +162,14 @@ public:
return PA;
}
+ /// \brief Construct a preserved analyses object with a single preserved set.
+ template <typename AnalysisSetT>
+ static PreservedAnalyses allInSet() {
+ PreservedAnalyses PA;
+ PA.preserveSet<AnalysisSetT>();
+ return PA;
+ }
+
/// Mark an analysis as preserved.
template <typename AnalysisT> void preserve() { preserve(AnalysisT::ID()); }
@@ -348,29 +402,6 @@ struct AnalysisInfoMixin : PassInfoMixin<DerivedT> {
}
};
-/// This templated class represents "all analyses that operate over \<a
-/// particular IR unit\>" (e.g. a Function or a Module) in instances of
-/// PreservedAnalysis.
-///
-/// This lets a transformation say e.g. "I preserved all function analyses".
-///
-/// Note that you must provide an explicit instantiation declaration and
-/// definition for this template in order to get the correct behavior on
-/// Windows. Otherwise, the address of SetKey will not be stable.
-template <typename IRUnitT>
-class AllAnalysesOn {
-public:
- static AnalysisSetKey *ID() { return &SetKey; }
-
-private:
- static AnalysisSetKey SetKey;
-};
-
-template <typename IRUnitT> AnalysisSetKey AllAnalysesOn<IRUnitT>::SetKey;
-
-extern template class AllAnalysesOn<Module>;
-extern template class AllAnalysesOn<Function>;
-
/// \brief Manages a sequence of passes over a particular unit of IR.
///
/// A pass manager contains a sequence of passes to run over a particular unit
@@ -452,15 +483,16 @@ public:
}
template <typename PassT> void addPass(PassT Pass) {
- typedef detail::PassModel<IRUnitT, PassT, PreservedAnalyses,
- AnalysisManagerT, ExtraArgTs...>
- PassModelT;
+ using PassModelT =
+ detail::PassModel<IRUnitT, PassT, PreservedAnalyses, AnalysisManagerT,
+ ExtraArgTs...>;
+
Passes.emplace_back(new PassModelT(std::move(Pass)));
}
private:
- typedef detail::PassConcept<IRUnitT, AnalysisManagerT, ExtraArgTs...>
- PassConceptT;
+ using PassConceptT =
+ detail::PassConcept<IRUnitT, AnalysisManagerT, ExtraArgTs...>;
std::vector<std::unique_ptr<PassConceptT>> Passes;
@@ -469,12 +501,14 @@ private:
};
extern template class PassManager<Module>;
+
/// \brief Convenience typedef for a pass manager over modules.
-typedef PassManager<Module> ModulePassManager;
+using ModulePassManager = PassManager<Module>;
extern template class PassManager<Function>;
+
/// \brief Convenience typedef for a pass manager over functions.
-typedef PassManager<Function> FunctionPassManager;
+using FunctionPassManager = PassManager<Function>;
/// \brief A container for analyses that lazily runs them and caches their
/// results.
@@ -487,11 +521,11 @@ public:
private:
// Now that we've defined our invalidator, we can define the concept types.
- typedef detail::AnalysisResultConcept<IRUnitT, PreservedAnalyses, Invalidator>
- ResultConceptT;
- typedef detail::AnalysisPassConcept<IRUnitT, PreservedAnalyses, Invalidator,
- ExtraArgTs...>
- PassConceptT;
+ using ResultConceptT =
+ detail::AnalysisResultConcept<IRUnitT, PreservedAnalyses, Invalidator>;
+ using PassConceptT =
+ detail::AnalysisPassConcept<IRUnitT, PreservedAnalyses, Invalidator,
+ ExtraArgTs...>;
/// \brief List of analysis pass IDs and associated concept pointers.
///
@@ -499,18 +533,18 @@ private:
/// erases. Provides the analysis ID to enable finding iterators to a given
/// entry in maps below, and provides the storage for the actual result
/// concept.
- typedef std::list<std::pair<AnalysisKey *, std::unique_ptr<ResultConceptT>>>
- AnalysisResultListT;
+ using AnalysisResultListT =
+ std::list<std::pair<AnalysisKey *, std::unique_ptr<ResultConceptT>>>;
/// \brief Map type from IRUnitT pointer to our custom list type.
- typedef DenseMap<IRUnitT *, AnalysisResultListT> AnalysisResultListMapT;
+ using AnalysisResultListMapT = DenseMap<IRUnitT *, AnalysisResultListT>;
/// \brief Map type from a pair of analysis ID and IRUnitT pointer to an
/// iterator into a particular result list (which is where the actual analysis
/// result is stored).
- typedef DenseMap<std::pair<AnalysisKey *, IRUnitT *>,
- typename AnalysisResultListT::iterator>
- AnalysisResultMapT;
+ using AnalysisResultMapT =
+ DenseMap<std::pair<AnalysisKey *, IRUnitT *>,
+ typename AnalysisResultListT::iterator>;
public:
/// API to communicate dependencies between analyses during invalidation.
@@ -541,10 +575,10 @@ public:
/// dependecies on it will become invalid as a result.
template <typename PassT>
bool invalidate(IRUnitT &IR, const PreservedAnalyses &PA) {
- typedef detail::AnalysisResultModel<IRUnitT, PassT,
- typename PassT::Result,
- PreservedAnalyses, Invalidator>
- ResultModelT;
+ using ResultModelT =
+ detail::AnalysisResultModel<IRUnitT, PassT, typename PassT::Result,
+ PreservedAnalyses, Invalidator>;
+
return invalidateImpl<ResultModelT>(PassT::ID(), IR, PA);
}
@@ -655,9 +689,11 @@ public:
"This analysis pass was not registered prior to being queried");
ResultConceptT &ResultConcept =
getResultImpl(PassT::ID(), IR, ExtraArgs...);
- typedef detail::AnalysisResultModel<IRUnitT, PassT, typename PassT::Result,
- PreservedAnalyses, Invalidator>
- ResultModelT;
+
+ using ResultModelT =
+ detail::AnalysisResultModel<IRUnitT, PassT, typename PassT::Result,
+ PreservedAnalyses, Invalidator>;
+
return static_cast<ResultModelT &>(ResultConcept).Result;
}
@@ -675,9 +711,10 @@ public:
if (!ResultConcept)
return nullptr;
- typedef detail::AnalysisResultModel<IRUnitT, PassT, typename PassT::Result,
- PreservedAnalyses, Invalidator>
- ResultModelT;
+ using ResultModelT =
+ detail::AnalysisResultModel<IRUnitT, PassT, typename PassT::Result,
+ PreservedAnalyses, Invalidator>;
+
return &static_cast<ResultModelT *>(ResultConcept)->Result;
}
@@ -700,10 +737,10 @@ public:
/// hashtable.)
template <typename PassBuilderT>
bool registerPass(PassBuilderT &&PassBuilder) {
- typedef decltype(PassBuilder()) PassT;
- typedef detail::AnalysisPassModel<IRUnitT, PassT, PreservedAnalyses,
- Invalidator, ExtraArgTs...>
- PassModelT;
+ using PassT = decltype(PassBuilder());
+ using PassModelT =
+ detail::AnalysisPassModel<IRUnitT, PassT, PreservedAnalyses,
+ Invalidator, ExtraArgTs...>;
auto &PassPtr = AnalysisPasses[PassT::ID()];
if (PassPtr)
@@ -780,7 +817,7 @@ public:
if (DebugLogging)
dbgs() << "Invalidating analysis: " << this->lookUpPass(ID).name()
- << "\n";
+ << " on " << IR.getName() << "\n";
I = ResultsList.erase(I);
AnalysisResults.erase({ID, &IR});
@@ -821,7 +858,8 @@ private:
if (Inserted) {
auto &P = this->lookUpPass(ID);
if (DebugLogging)
- dbgs() << "Running analysis: " << P.name() << "\n";
+ dbgs() << "Running analysis: " << P.name() << " on " << IR.getName()
+ << "\n";
AnalysisResultListT &ResultList = AnalysisResultLists[&IR];
ResultList.emplace_back(ID, P.run(IR, *this, ExtraArgs...));
@@ -852,13 +890,14 @@ private:
if (DebugLogging)
dbgs() << "Invalidating analysis: " << this->lookUpPass(ID).name()
- << "\n";
+ << " on " << IR.getName() << "\n";
AnalysisResultLists[&IR].erase(RI->second);
AnalysisResults.erase(RI);
}
/// \brief Map type from module analysis pass ID to pass concept pointer.
- typedef DenseMap<AnalysisKey *, std::unique_ptr<PassConceptT>> AnalysisPassMapT;
+ using AnalysisPassMapT =
+ DenseMap<AnalysisKey *, std::unique_ptr<PassConceptT>>;
/// \brief Collection of module analysis passes, indexed by ID.
AnalysisPassMapT AnalysisPasses;
@@ -878,12 +917,14 @@ private:
};
extern template class AnalysisManager<Module>;
+
/// \brief Convenience typedef for the Module analysis manager.
-typedef AnalysisManager<Module> ModuleAnalysisManager;
+using ModuleAnalysisManager = AnalysisManager<Module>;
extern template class AnalysisManager<Function>;
+
/// \brief Convenience typedef for the Function analysis manager.
-typedef AnalysisManager<Function> FunctionAnalysisManager;
+using FunctionAnalysisManager = AnalysisManager<Function>;
/// \brief An analysis over an "outer" IR unit that provides access to an
/// analysis manager over an "inner" IR unit. The inner unit must be contained
@@ -909,20 +950,14 @@ public:
class Result {
public:
explicit Result(AnalysisManagerT &InnerAM) : InnerAM(&InnerAM) {}
+
Result(Result &&Arg) : InnerAM(std::move(Arg.InnerAM)) {
// We have to null out the analysis manager in the moved-from state
// because we are taking ownership of the responsibilty to clear the
// analysis state.
Arg.InnerAM = nullptr;
}
- Result &operator=(Result &&RHS) {
- InnerAM = RHS.InnerAM;
- // We have to null out the analysis manager in the moved-from state
- // because we are taking ownership of the responsibilty to clear the
- // analysis state.
- RHS.InnerAM = nullptr;
- return *this;
- }
+
~Result() {
// InnerAM is cleared in a moved from state where there is nothing to do.
if (!InnerAM)
@@ -933,6 +968,15 @@ public:
InnerAM->clear();
}
+ Result &operator=(Result &&RHS) {
+ InnerAM = RHS.InnerAM;
+ // We have to null out the analysis manager in the moved-from state
+ // because we are taking ownership of the responsibilty to clear the
+ // analysis state.
+ RHS.InnerAM = nullptr;
+ return *this;
+ }
+
/// \brief Accessor for the analysis manager.
AnalysisManagerT &getManager() { return *InnerAM; }
@@ -970,6 +1014,7 @@ public:
private:
friend AnalysisInfoMixin<
InnerAnalysisManagerProxy<AnalysisManagerT, IRUnitT>>;
+
static AnalysisKey Key;
AnalysisManagerT *InnerAM;
@@ -980,8 +1025,8 @@ AnalysisKey
InnerAnalysisManagerProxy<AnalysisManagerT, IRUnitT, ExtraArgTs...>::Key;
/// Provide the \c FunctionAnalysisManager to \c Module proxy.
-typedef InnerAnalysisManagerProxy<FunctionAnalysisManager, Module>
- FunctionAnalysisManagerModuleProxy;
+using FunctionAnalysisManagerModuleProxy =
+ InnerAnalysisManagerProxy<FunctionAnalysisManager, Module>;
/// Specialization of the invalidate method for the \c
/// FunctionAnalysisManagerModuleProxy's result.
@@ -1025,10 +1070,27 @@ public:
const AnalysisManagerT &getManager() const { return *AM; }
- /// \brief Handle invalidation by ignoring it; this pass is immutable.
+ /// When invalidation occurs, remove any registered invalidation events.
bool invalidate(
- IRUnitT &, const PreservedAnalyses &,
- typename AnalysisManager<IRUnitT, ExtraArgTs...>::Invalidator &) {
+ IRUnitT &IRUnit, const PreservedAnalyses &PA,
+ typename AnalysisManager<IRUnitT, ExtraArgTs...>::Invalidator &Inv) {
+ // Loop over the set of registered outer invalidation mappings and if any
+ // of them map to an analysis that is now invalid, clear it out.
+ SmallVector<AnalysisKey *, 4> DeadKeys;
+ for (auto &KeyValuePair : OuterAnalysisInvalidationMap) {
+ AnalysisKey *OuterID = KeyValuePair.first;
+ auto &InnerIDs = KeyValuePair.second;
+ InnerIDs.erase(llvm::remove_if(InnerIDs, [&](AnalysisKey *InnerID) {
+ return Inv.invalidate(InnerID, IRUnit, PA); }),
+ InnerIDs.end());
+ if (InnerIDs.empty())
+ DeadKeys.push_back(OuterID);
+ }
+
+ for (auto OuterID : DeadKeys)
+ OuterAnalysisInvalidationMap.erase(OuterID);
+
+ // The proxy itself remains valid regardless of anything else.
return false;
}
@@ -1079,6 +1141,7 @@ public:
private:
friend AnalysisInfoMixin<
OuterAnalysisManagerProxy<AnalysisManagerT, IRUnitT, ExtraArgTs...>>;
+
static AnalysisKey Key;
const AnalysisManagerT *AM;
@@ -1091,8 +1154,8 @@ AnalysisKey
extern template class OuterAnalysisManagerProxy<ModuleAnalysisManager,
Function>;
/// Provide the \c ModuleAnalysisManager to \c Function proxy.
-typedef OuterAnalysisManagerProxy<ModuleAnalysisManager, Function>
- ModuleAnalysisManagerFunctionProxy;
+using ModuleAnalysisManagerFunctionProxy =
+ OuterAnalysisManagerProxy<ModuleAnalysisManager, Function>;
/// \brief Trivial adaptor that maps from a module to its functions.
///
@@ -1256,6 +1319,6 @@ RepeatedPass<PassT> createRepeatedPass(int Count, PassT P) {
return RepeatedPass<PassT>(Count, std::move(P));
}
-}
+} // end namespace llvm
-#endif
+#endif // LLVM_IR_PASSMANAGER_H
diff --git a/contrib/llvm/include/llvm/IR/PassManagerInternal.h b/contrib/llvm/include/llvm/IR/PassManagerInternal.h
index 02f2167..9195d4d 100644
--- a/contrib/llvm/include/llvm/IR/PassManagerInternal.h
+++ b/contrib/llvm/include/llvm/IR/PassManagerInternal.h
@@ -27,7 +27,6 @@ namespace llvm {
template <typename IRUnitT> class AllAnalysesOn;
template <typename IRUnitT, typename... ExtraArgTs> class AnalysisManager;
-class Invalidator;
class PreservedAnalyses;
/// \brief Implementation details of the pass manager interfaces.
@@ -116,7 +115,7 @@ struct AnalysisResultConcept {
/// \brief SFINAE metafunction for computing whether \c ResultT provides an
/// \c invalidate member function.
template <typename IRUnitT, typename ResultT> class ResultHasInvalidateMethod {
- typedef char EnabledType;
+ using EnabledType = char;
struct DisabledType {
char a, b;
};
@@ -124,7 +123,7 @@ template <typename IRUnitT, typename ResultT> class ResultHasInvalidateMethod {
// Purely to help out MSVC which fails to disable the below specialization,
// explicitly enable using the result type's invalidate routine if we can
// successfully call that routine.
- template <typename T> struct Nonce { typedef EnabledType Type; };
+ template <typename T> struct Nonce { using Type = EnabledType; };
template <typename T>
static typename Nonce<decltype(std::declval<T>().invalidate(
std::declval<IRUnitT &>(), std::declval<PreservedAnalyses>()))>::Type
@@ -280,9 +279,9 @@ struct AnalysisPassModel : AnalysisPassConcept<IRUnitT, PreservedAnalysesT,
}
// FIXME: Replace PassT::Result with type traits when we use C++11.
- typedef AnalysisResultModel<IRUnitT, PassT, typename PassT::Result,
- PreservedAnalysesT, InvalidatorT>
- ResultModelT;
+ using ResultModelT =
+ AnalysisResultModel<IRUnitT, PassT, typename PassT::Result,
+ PreservedAnalysesT, InvalidatorT>;
/// \brief The model delegates to the \c PassT::run method.
///
@@ -291,7 +290,7 @@ struct AnalysisPassModel : AnalysisPassConcept<IRUnitT, PreservedAnalysesT,
AnalysisResultConcept<IRUnitT, PreservedAnalysesT, InvalidatorT>>
run(IRUnitT &IR, AnalysisManager<IRUnitT, ExtraArgTs...> &AM,
ExtraArgTs... ExtraArgs) override {
- return make_unique<ResultModelT>(Pass.run(IR, AM, ExtraArgs...));
+ return llvm::make_unique<ResultModelT>(Pass.run(IR, AM, ExtraArgs...));
}
/// \brief The model delegates to a static \c PassT::name method.
diff --git a/contrib/llvm/include/llvm/IR/PatternMatch.h b/contrib/llvm/include/llvm/IR/PatternMatch.h
index a30fc97..acb8952 100644
--- a/contrib/llvm/include/llvm/IR/PatternMatch.h
+++ b/contrib/llvm/include/llvm/IR/PatternMatch.h
@@ -29,11 +29,19 @@
#ifndef LLVM_IR_PATTERNMATCH_H
#define LLVM_IR_PATTERNMATCH_H
+#include "llvm/ADT/APFloat.h"
+#include "llvm/ADT/APInt.h"
#include "llvm/IR/CallSite.h"
+#include "llvm/IR/Constant.h"
#include "llvm/IR/Constants.h"
+#include "llvm/IR/InstrTypes.h"
+#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/Operator.h"
+#include "llvm/IR/Value.h"
+#include "llvm/Support/Casting.h"
+#include <cstdint>
namespace llvm {
namespace PatternMatch {
@@ -150,16 +158,68 @@ struct match_neg_zero {
/// zero
inline match_neg_zero m_NegZero() { return match_neg_zero(); }
+struct match_any_zero {
+ template <typename ITy> bool match(ITy *V) {
+ if (const auto *C = dyn_cast<Constant>(V))
+ return C->isZeroValue();
+ return false;
+ }
+};
+
/// \brief - Match an arbitrary zero/null constant. This includes
/// zero_initializer for vectors and ConstantPointerNull for pointers. For
/// floating point constants, this will match negative zero and positive zero
-inline match_combine_or<match_zero, match_neg_zero> m_AnyZero() {
- return m_CombineOr(m_Zero(), m_NegZero());
-}
+inline match_any_zero m_AnyZero() { return match_any_zero(); }
+
+struct match_nan {
+ template <typename ITy> bool match(ITy *V) {
+ if (const auto *C = dyn_cast<ConstantFP>(V))
+ return C->isNaN();
+ return false;
+ }
+};
+
+/// Match an arbitrary NaN constant. This includes quiet and signalling nans.
+inline match_nan m_NaN() { return match_nan(); }
+
+struct match_one {
+ template <typename ITy> bool match(ITy *V) {
+ if (const auto *C = dyn_cast<Constant>(V))
+ return C->isOneValue();
+ return false;
+ }
+};
+
+/// \brief Match an integer 1 or a vector with all elements equal to 1.
+inline match_one m_One() { return match_one(); }
+
+struct match_all_ones {
+ template <typename ITy> bool match(ITy *V) {
+ if (const auto *C = dyn_cast<Constant>(V))
+ return C->isAllOnesValue();
+ return false;
+ }
+};
+
+/// \brief Match an integer or vector with all bits set to true.
+inline match_all_ones m_AllOnes() { return match_all_ones(); }
+
+struct match_sign_mask {
+ template <typename ITy> bool match(ITy *V) {
+ if (const auto *C = dyn_cast<Constant>(V))
+ return C->isMinSignedValue();
+ return false;
+ }
+};
+
+/// \brief Match an integer or vector with only the sign bit(s) set.
+inline match_sign_mask m_SignMask() { return match_sign_mask(); }
struct apint_match {
const APInt *&Res;
+
apint_match(const APInt *&R) : Res(R) {}
+
template <typename ITy> bool match(ITy *V) {
if (auto *CI = dyn_cast<ConstantInt>(V)) {
Res = &CI->getValue();
@@ -217,7 +277,9 @@ template <typename Predicate> struct cst_pred_ty : public Predicate {
/// satisfy a specified predicate, and bind them to an APInt.
template <typename Predicate> struct api_pred_ty : public Predicate {
const APInt *&Res;
+
api_pred_ty(const APInt *&R) : Res(R) {}
+
template <typename ITy> bool match(ITy *V) {
if (const auto *CI = dyn_cast<ConstantInt>(V))
if (this->isValue(CI->getValue())) {
@@ -236,34 +298,6 @@ template <typename Predicate> struct api_pred_ty : public Predicate {
}
};
-struct is_one {
- bool isValue(const APInt &C) { return C == 1; }
-};
-
-/// \brief Match an integer 1 or a vector with all elements equal to 1.
-inline cst_pred_ty<is_one> m_One() { return cst_pred_ty<is_one>(); }
-inline api_pred_ty<is_one> m_One(const APInt *&V) { return V; }
-
-struct is_all_ones {
- bool isValue(const APInt &C) { return C.isAllOnesValue(); }
-};
-
-/// \brief Match an integer or vector with all bits set to true.
-inline cst_pred_ty<is_all_ones> m_AllOnes() {
- return cst_pred_ty<is_all_ones>();
-}
-inline api_pred_ty<is_all_ones> m_AllOnes(const APInt *&V) { return V; }
-
-struct is_sign_bit {
- bool isValue(const APInt &C) { return C.isSignBit(); }
-};
-
-/// \brief Match an integer or vector with only the sign bit(s) set.
-inline cst_pred_ty<is_sign_bit> m_SignBit() {
- return cst_pred_ty<is_sign_bit>();
-}
-inline api_pred_ty<is_sign_bit> m_SignBit(const APInt *&V) { return V; }
-
struct is_power2 {
bool isValue(const APInt &C) { return C.isPowerOf2(); }
};
@@ -281,6 +315,7 @@ inline api_pred_ty<is_maxsignedvalue> m_MaxSignedValue(const APInt *&V) { return
template <typename Class> struct bind_ty {
Class *&VR;
+
bind_ty(Class *&V) : VR(V) {}
template <typename ITy> bool match(ITy *V) {
@@ -313,6 +348,7 @@ inline bind_ty<ConstantFP> m_ConstantFP(ConstantFP *&C) { return C; }
/// \brief Match a specified Value*.
struct specificval_ty {
const Value *Val;
+
specificval_ty(const Value *V) : Val(V) {}
template <typename ITy> bool match(ITy *V) { return V == Val; }
@@ -325,6 +361,7 @@ inline specificval_ty m_Specific(const Value *V) { return V; }
/// that value.
struct specific_fpval {
double Val;
+
specific_fpval(double V) : Val(V) {}
template <typename ITy> bool match(ITy *V) {
@@ -347,11 +384,12 @@ inline specific_fpval m_FPOne() { return m_SpecificFP(1.0); }
struct bind_const_intval_ty {
uint64_t &VR;
+
bind_const_intval_ty(uint64_t &V) : VR(V) {}
template <typename ITy> bool match(ITy *V) {
if (const auto *CV = dyn_cast<ConstantInt>(V))
- if (CV->getBitWidth() <= 64) {
+ if (CV->getValue().ule(UINT64_MAX)) {
VR = CV->getZExtValue();
return true;
}
@@ -363,6 +401,7 @@ struct bind_const_intval_ty {
// value.
struct specific_intval {
uint64_t Val;
+
specific_intval(uint64_t V) : Val(V) {}
template <typename ITy> bool match(ITy *V) {
@@ -371,10 +410,7 @@ struct specific_intval {
if (const auto *C = dyn_cast<Constant>(V))
CI = dyn_cast_or_null<ConstantInt>(C->getSplatValue());
- if (CI && CI->getBitWidth() <= 64)
- return CI->getZExtValue() == Val;
-
- return false;
+ return CI && CI->getValue() == Val;
}
};
@@ -389,7 +425,8 @@ inline bind_const_intval_ty m_ConstantInt(uint64_t &V) { return V; }
//===----------------------------------------------------------------------===//
// Matcher for any binary operator.
//
-template <typename LHS_t, typename RHS_t> struct AnyBinaryOp_match {
+template <typename LHS_t, typename RHS_t, bool Commutable = false>
+struct AnyBinaryOp_match {
LHS_t L;
RHS_t R;
@@ -397,7 +434,9 @@ template <typename LHS_t, typename RHS_t> struct AnyBinaryOp_match {
template <typename OpTy> bool match(OpTy *V) {
if (auto *I = dyn_cast<BinaryOperator>(V))
- return L.match(I->getOperand(0)) && R.match(I->getOperand(1));
+ return (L.match(I->getOperand(0)) && R.match(I->getOperand(1))) ||
+ (Commutable && R.match(I->getOperand(0)) &&
+ L.match(I->getOperand(1)));
return false;
}
};
@@ -411,7 +450,8 @@ inline AnyBinaryOp_match<LHS, RHS> m_BinOp(const LHS &L, const RHS &R) {
// Matchers for specific binary operators.
//
-template <typename LHS_t, typename RHS_t, unsigned Opcode>
+template <typename LHS_t, typename RHS_t, unsigned Opcode,
+ bool Commutable = false>
struct BinaryOp_match {
LHS_t L;
RHS_t R;
@@ -421,11 +461,15 @@ struct BinaryOp_match {
template <typename OpTy> bool match(OpTy *V) {
if (V->getValueID() == Value::InstructionVal + Opcode) {
auto *I = cast<BinaryOperator>(V);
- return L.match(I->getOperand(0)) && R.match(I->getOperand(1));
+ return (L.match(I->getOperand(0)) && R.match(I->getOperand(1))) ||
+ (Commutable && R.match(I->getOperand(0)) &&
+ L.match(I->getOperand(1)));
}
if (auto *CE = dyn_cast<ConstantExpr>(V))
- return CE->getOpcode() == Opcode && L.match(CE->getOperand(0)) &&
- R.match(CE->getOperand(1));
+ return CE->getOpcode() == Opcode &&
+ ((L.match(CE->getOperand(0)) && R.match(CE->getOperand(1))) ||
+ (Commutable && R.match(CE->getOperand(0)) &&
+ L.match(CE->getOperand(1))));
return false;
}
};
@@ -630,47 +674,87 @@ m_NUWShl(const LHS &L, const RHS &R) {
}
//===----------------------------------------------------------------------===//
-// Class that matches two different binary ops.
+// Class that matches a group of binary opcodes.
//
-template <typename LHS_t, typename RHS_t, unsigned Opc1, unsigned Opc2>
-struct BinOp2_match {
+template <typename LHS_t, typename RHS_t, typename Predicate>
+struct BinOpPred_match : Predicate {
LHS_t L;
RHS_t R;
- BinOp2_match(const LHS_t &LHS, const RHS_t &RHS) : L(LHS), R(RHS) {}
+ BinOpPred_match(const LHS_t &LHS, const RHS_t &RHS) : L(LHS), R(RHS) {}
template <typename OpTy> bool match(OpTy *V) {
- if (V->getValueID() == Value::InstructionVal + Opc1 ||
- V->getValueID() == Value::InstructionVal + Opc2) {
- auto *I = cast<BinaryOperator>(V);
- return L.match(I->getOperand(0)) && R.match(I->getOperand(1));
- }
+ if (auto *I = dyn_cast<Instruction>(V))
+ return this->isOpType(I->getOpcode()) && L.match(I->getOperand(0)) &&
+ R.match(I->getOperand(1));
if (auto *CE = dyn_cast<ConstantExpr>(V))
- return (CE->getOpcode() == Opc1 || CE->getOpcode() == Opc2) &&
- L.match(CE->getOperand(0)) && R.match(CE->getOperand(1));
+ return this->isOpType(CE->getOpcode()) && L.match(CE->getOperand(0)) &&
+ R.match(CE->getOperand(1));
return false;
}
};
-/// \brief Matches LShr or AShr.
+struct is_shift_op {
+ bool isOpType(unsigned Opcode) { return Instruction::isShift(Opcode); }
+};
+
+struct is_right_shift_op {
+ bool isOpType(unsigned Opcode) {
+ return Opcode == Instruction::LShr || Opcode == Instruction::AShr;
+ }
+};
+
+struct is_logical_shift_op {
+ bool isOpType(unsigned Opcode) {
+ return Opcode == Instruction::LShr || Opcode == Instruction::Shl;
+ }
+};
+
+struct is_bitwiselogic_op {
+ bool isOpType(unsigned Opcode) {
+ return Instruction::isBitwiseLogicOp(Opcode);
+ }
+};
+
+struct is_idiv_op {
+ bool isOpType(unsigned Opcode) {
+ return Opcode == Instruction::SDiv || Opcode == Instruction::UDiv;
+ }
+};
+
+/// \brief Matches shift operations.
template <typename LHS, typename RHS>
-inline BinOp2_match<LHS, RHS, Instruction::LShr, Instruction::AShr>
-m_Shr(const LHS &L, const RHS &R) {
- return BinOp2_match<LHS, RHS, Instruction::LShr, Instruction::AShr>(L, R);
+inline BinOpPred_match<LHS, RHS, is_shift_op> m_Shift(const LHS &L,
+ const RHS &R) {
+ return BinOpPred_match<LHS, RHS, is_shift_op>(L, R);
}
-/// \brief Matches LShr or Shl.
+/// \brief Matches logical shift operations.
template <typename LHS, typename RHS>
-inline BinOp2_match<LHS, RHS, Instruction::LShr, Instruction::Shl>
+inline BinOpPred_match<LHS, RHS, is_right_shift_op> m_Shr(const LHS &L,
+ const RHS &R) {
+ return BinOpPred_match<LHS, RHS, is_right_shift_op>(L, R);
+}
+
+/// \brief Matches logical shift operations.
+template <typename LHS, typename RHS>
+inline BinOpPred_match<LHS, RHS, is_logical_shift_op>
m_LogicalShift(const LHS &L, const RHS &R) {
- return BinOp2_match<LHS, RHS, Instruction::LShr, Instruction::Shl>(L, R);
+ return BinOpPred_match<LHS, RHS, is_logical_shift_op>(L, R);
+}
+
+/// \brief Matches bitwise logic operations.
+template <typename LHS, typename RHS>
+inline BinOpPred_match<LHS, RHS, is_bitwiselogic_op>
+m_BitwiseLogic(const LHS &L, const RHS &R) {
+ return BinOpPred_match<LHS, RHS, is_bitwiselogic_op>(L, R);
}
-/// \brief Matches UDiv and SDiv.
+/// \brief Matches integer division operations.
template <typename LHS, typename RHS>
-inline BinOp2_match<LHS, RHS, Instruction::SDiv, Instruction::UDiv>
-m_IDiv(const LHS &L, const RHS &R) {
- return BinOp2_match<LHS, RHS, Instruction::SDiv, Instruction::UDiv>(L, R);
+inline BinOpPred_match<LHS, RHS, is_idiv_op> m_IDiv(const LHS &L,
+ const RHS &R) {
+ return BinOpPred_match<LHS, RHS, is_idiv_op>(L, R);
}
//===----------------------------------------------------------------------===//
@@ -696,7 +780,8 @@ template <typename T> inline Exact_match<T> m_Exact(const T &SubPattern) {
// Matchers for CmpInst classes
//
-template <typename LHS_t, typename RHS_t, typename Class, typename PredicateTy>
+template <typename LHS_t, typename RHS_t, typename Class, typename PredicateTy,
+ bool Commutable = false>
struct CmpClass_match {
PredicateTy &Predicate;
LHS_t L;
@@ -707,7 +792,9 @@ struct CmpClass_match {
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))) {
+ if ((L.match(I->getOperand(0)) && R.match(I->getOperand(1))) ||
+ (Commutable && R.match(I->getOperand(0)) &&
+ L.match(I->getOperand(1)))) {
Predicate = I->getPredicate();
return true;
}
@@ -814,6 +901,13 @@ inline CastClass_match<OpTy, Instruction::ZExt> m_ZExt(const OpTy &Op) {
return CastClass_match<OpTy, Instruction::ZExt>(Op);
}
+template <typename OpTy>
+inline match_combine_or<CastClass_match<OpTy, Instruction::ZExt>,
+ CastClass_match<OpTy, Instruction::SExt>>
+m_ZExtOrSExt(const OpTy &Op) {
+ return m_CombineOr(m_ZExt(Op), m_SExt(Op));
+}
+
/// \brief Matches UIToFP.
template <typename OpTy>
inline CastClass_match<OpTy, Instruction::UIToFP> m_UIToFP(const OpTy &Op) {
@@ -826,6 +920,18 @@ inline CastClass_match<OpTy, Instruction::SIToFP> m_SIToFP(const OpTy &Op) {
return CastClass_match<OpTy, Instruction::SIToFP>(Op);
}
+/// \brief Matches FPTrunc
+template <typename OpTy>
+inline CastClass_match<OpTy, Instruction::FPTrunc> m_FPTrunc(const OpTy &Op) {
+ return CastClass_match<OpTy, Instruction::FPTrunc>(Op);
+}
+
+/// \brief Matches FPExt
+template <typename OpTy>
+inline CastClass_match<OpTy, Instruction::FPExt> m_FPExt(const OpTy &Op) {
+ return CastClass_match<OpTy, Instruction::FPExt>(Op);
+}
+
//===----------------------------------------------------------------------===//
// Matchers for unary operators
//
@@ -837,17 +943,18 @@ template <typename LHS_t> struct not_match {
template <typename OpTy> bool match(OpTy *V) {
if (auto *O = dyn_cast<Operator>(V))
- if (O->getOpcode() == Instruction::Xor)
- return matchIfNot(O->getOperand(0), O->getOperand(1));
+ if (O->getOpcode() == Instruction::Xor) {
+ if (isAllOnes(O->getOperand(1)))
+ return L.match(O->getOperand(0));
+ if (isAllOnes(O->getOperand(0)))
+ return L.match(O->getOperand(1));
+ }
return false;
}
private:
- bool matchIfNot(Value *LHS, Value *RHS) {
- return (isa<ConstantInt>(RHS) || isa<ConstantDataVector>(RHS) ||
- // FIXME: Remove CV.
- isa<ConstantVector>(RHS)) &&
- cast<Constant>(RHS)->isAllOnesValue() && L.match(LHS);
+ bool isAllOnes(Value *V) {
+ return isa<Constant>(V) && cast<Constant>(V)->isAllOnesValue();
}
};
@@ -907,6 +1014,7 @@ template <typename LHS> inline fneg_match<LHS> m_FNeg(const LHS &L) {
struct br_match {
BasicBlock *&Succ;
+
br_match(BasicBlock *&Succ) : Succ(Succ) {}
template <typename OpTy> bool match(OpTy *V) {
@@ -924,6 +1032,7 @@ inline br_match m_UnconditionalBr(BasicBlock *&Succ) { return br_match(Succ); }
template <typename Cond_t> struct brc_match {
Cond_t Cond;
BasicBlock *&T, *&F;
+
brc_match(const Cond_t &C, BasicBlock *&t, BasicBlock *&f)
: Cond(C), T(t), F(f) {}
@@ -947,7 +1056,8 @@ inline brc_match<Cond_t> m_Br(const Cond_t &C, BasicBlock *&T, BasicBlock *&F) {
// Matchers for max/min idioms, eg: "select (sgt x, y), x, y" -> smax(x,y).
//
-template <typename CmpInst_t, typename LHS_t, typename RHS_t, typename Pred_t>
+template <typename CmpInst_t, typename LHS_t, typename RHS_t, typename Pred_t,
+ bool Commutable = false>
struct MaxMin_match {
LHS_t L;
RHS_t R;
@@ -972,12 +1082,13 @@ struct MaxMin_match {
(TrueVal != RHS || FalseVal != LHS))
return false;
typename CmpInst_t::Predicate Pred =
- LHS == TrueVal ? Cmp->getPredicate() : Cmp->getSwappedPredicate();
+ LHS == TrueVal ? Cmp->getPredicate() : Cmp->getInversePredicate();
// Does "(x pred y) ? x : y" represent the desired max/min operation?
if (!Pred_t::match(Pred))
return false;
// It does! Bind the operands.
- return L.match(LHS) && R.match(RHS);
+ return (L.match(LHS) && R.match(RHS)) ||
+ (Commutable && R.match(LHS) && L.match(RHS));
}
};
@@ -1083,7 +1194,7 @@ inline MaxMin_match<FCmpInst, LHS, RHS, ofmax_pred_ty> m_OrdFMax(const LHS &L,
/// semantics. In the presence of 'NaN' we have to preserve the original
/// select(fcmp(olt/le, L, R), L, R) semantics matched by this predicate.
///
-/// max(L, R) iff L and R are not NaN
+/// min(L, R) iff L and R are not NaN
/// m_OrdFMin(L, R) = R iff L or R are NaN
template <typename LHS, typename RHS>
inline MaxMin_match<FCmpInst, LHS, RHS, ofmin_pred_ty> m_OrdFMin(const LHS &L,
@@ -1099,13 +1210,28 @@ inline MaxMin_match<FCmpInst, LHS, RHS, ofmin_pred_ty> m_OrdFMin(const LHS &L,
/// select(fcmp(ugt/ge, L, R), L, R) semantics matched by this predicate.
///
/// max(L, R) iff L and R are not NaN
-/// m_UnordFMin(L, R) = L iff L or R are NaN
+/// m_UnordFMax(L, R) = L iff L or R are NaN
template <typename LHS, typename RHS>
inline MaxMin_match<FCmpInst, LHS, RHS, ufmax_pred_ty>
m_UnordFMax(const LHS &L, const RHS &R) {
return MaxMin_match<FCmpInst, LHS, RHS, ufmax_pred_ty>(L, R);
}
+/// \brief Match an 'unordered' floating point minimum function.
+/// Floating point has one special value 'NaN'. Therefore, there is no total
+/// order. However, if we can ignore the 'NaN' value (for example, because of a
+/// 'no-nans-float-math' flag) a combination of a fcmp and select has 'minimum'
+/// semantics. In the presence of 'NaN' we have to preserve the original
+/// select(fcmp(ult/le, L, R), L, R) semantics matched by this predicate.
+///
+/// min(L, R) iff L and R are not NaN
+/// m_UnordFMin(L, R) = L iff L or R are NaN
+template <typename LHS, typename RHS>
+inline MaxMin_match<FCmpInst, LHS, RHS, ufmin_pred_ty>
+m_UnordFMin(const LHS &L, const RHS &R) {
+ return MaxMin_match<FCmpInst, LHS, RHS, ufmin_pred_ty>(L, R);
+}
+
//===----------------------------------------------------------------------===//
// Matchers for overflow check patterns: e.g. (a + b) u< a
//
@@ -1152,24 +1278,10 @@ m_UAddWithOverflow(const LHS_t &L, const RHS_t &R, const Sum_t &S) {
return UAddWithOverflow_match<LHS_t, RHS_t, Sum_t>(L, R, S);
}
-/// \brief Match an 'unordered' floating point minimum function.
-/// Floating point has one special value 'NaN'. Therefore, there is no total
-/// order. However, if we can ignore the 'NaN' value (for example, because of a
-/// 'no-nans-float-math' flag) a combination of a fcmp and select has 'minimum'
-/// semantics. In the presence of 'NaN' we have to preserve the original
-/// select(fcmp(ult/le, L, R), L, R) semantics matched by this predicate.
-///
-/// max(L, R) iff L and R are not NaN
-/// m_UnordFMin(L, R) = L iff L or R are NaN
-template <typename LHS, typename RHS>
-inline MaxMin_match<FCmpInst, LHS, RHS, ufmin_pred_ty>
-m_UnordFMin(const LHS &L, const RHS &R) {
- return MaxMin_match<FCmpInst, LHS, RHS, ufmin_pred_ty>(L, R);
-}
-
template <typename Opnd_t> struct Argument_match {
unsigned OpI;
Opnd_t Val;
+
Argument_match(unsigned OpIdx, const Opnd_t &V) : OpI(OpIdx), Val(V) {}
template <typename OpTy> bool match(OpTy *V) {
@@ -1187,6 +1299,7 @@ inline Argument_match<Opnd_t> m_Argument(const Opnd_t &Op) {
/// \brief Intrinsic matchers.
struct IntrinsicID_match {
unsigned ID;
+
IntrinsicID_match(Intrinsic::ID IntrID) : ID(IntrID) {}
template <typename OpTy> bool match(OpTy *V) {
@@ -1207,21 +1320,23 @@ template <typename T0 = void, typename T1 = void, typename T2 = void,
typename T9 = void, typename T10 = void>
struct m_Intrinsic_Ty;
template <typename T0> struct m_Intrinsic_Ty<T0> {
- typedef match_combine_and<IntrinsicID_match, Argument_match<T0>> Ty;
+ using Ty = match_combine_and<IntrinsicID_match, Argument_match<T0>>;
};
template <typename T0, typename T1> struct m_Intrinsic_Ty<T0, T1> {
- typedef match_combine_and<typename m_Intrinsic_Ty<T0>::Ty, Argument_match<T1>>
- Ty;
+ using Ty =
+ match_combine_and<typename m_Intrinsic_Ty<T0>::Ty, Argument_match<T1>>;
};
template <typename T0, typename T1, typename T2>
struct m_Intrinsic_Ty<T0, T1, T2> {
- typedef match_combine_and<typename m_Intrinsic_Ty<T0, T1>::Ty,
- Argument_match<T2>> Ty;
+ using Ty =
+ match_combine_and<typename m_Intrinsic_Ty<T0, T1>::Ty,
+ Argument_match<T2>>;
};
template <typename T0, typename T1, typename T2, typename T3>
struct m_Intrinsic_Ty<T0, T1, T2, T3> {
- typedef match_combine_and<typename m_Intrinsic_Ty<T0, T1, T2>::Ty,
- Argument_match<T3>> Ty;
+ using Ty =
+ match_combine_and<typename m_Intrinsic_Ty<T0, T1, T2>::Ty,
+ Argument_match<T3>>;
};
/// \brief Match intrinsic calls like this:
@@ -1256,6 +1371,11 @@ m_Intrinsic(const T0 &Op0, const T1 &Op1, const T2 &Op2, const T3 &Op3) {
// Helper intrinsic matching specializations.
template <typename Opnd0>
+inline typename m_Intrinsic_Ty<Opnd0>::Ty m_BitReverse(const Opnd0 &Op0) {
+ return m_Intrinsic<Intrinsic::bitreverse>(Op0);
+}
+
+template <typename Opnd0>
inline typename m_Intrinsic_Ty<Opnd0>::Ty m_BSwap(const Opnd0 &Op0) {
return m_Intrinsic<Intrinsic::bswap>(Op0);
}
@@ -1316,69 +1436,82 @@ template <typename Val_t> inline Signum_match<Val_t> m_Signum(const Val_t &V) {
// Matchers for two-operands operators with the operators in either order
//
+/// \brief Matches a BinaryOperator with LHS and RHS in either order.
+template <typename LHS, typename RHS>
+inline AnyBinaryOp_match<LHS, RHS, true> m_c_BinOp(const LHS &L, const RHS &R) {
+ return AnyBinaryOp_match<LHS, RHS, true>(L, R);
+}
+
/// \brief Matches an ICmp with a predicate over LHS and RHS in either order.
/// Does not swap the predicate.
-template<typename LHS, typename RHS>
-inline match_combine_or<CmpClass_match<LHS, RHS, ICmpInst, ICmpInst::Predicate>,
- CmpClass_match<RHS, LHS, ICmpInst, ICmpInst::Predicate>>
+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) {
- return m_CombineOr(m_ICmp(Pred, L, R), m_ICmp(Pred, R, L));
+ return CmpClass_match<LHS, RHS, ICmpInst, ICmpInst::Predicate, true>(Pred, L,
+ R);
+}
+
+/// \brief Matches a Add with LHS and RHS in either order.
+template <typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::Add, true> m_c_Add(const LHS &L,
+ const RHS &R) {
+ return BinaryOp_match<LHS, RHS, Instruction::Add, true>(L, R);
+}
+
+/// \brief Matches a Mul with LHS and RHS in either order.
+template <typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::Mul, true> m_c_Mul(const LHS &L,
+ const RHS &R) {
+ return BinaryOp_match<LHS, RHS, Instruction::Mul, true>(L, R);
}
/// \brief Matches an And with LHS and RHS in either order.
-template<typename LHS, typename RHS>
-inline match_combine_or<BinaryOp_match<LHS, RHS, Instruction::And>,
- BinaryOp_match<RHS, LHS, Instruction::And>>
-m_c_And(const LHS &L, const RHS &R) {
- return m_CombineOr(m_And(L, R), m_And(R, L));
+template <typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::And, true> m_c_And(const LHS &L,
+ const RHS &R) {
+ return BinaryOp_match<LHS, RHS, Instruction::And, true>(L, R);
}
/// \brief Matches an Or with LHS and RHS in either order.
-template<typename LHS, typename RHS>
-inline match_combine_or<BinaryOp_match<LHS, RHS, Instruction::Or>,
- BinaryOp_match<RHS, LHS, Instruction::Or>>
-m_c_Or(const LHS &L, const RHS &R) {
- return m_CombineOr(m_Or(L, R), m_Or(R, L));
+template <typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::Or, true> m_c_Or(const LHS &L,
+ const RHS &R) {
+ return BinaryOp_match<LHS, RHS, Instruction::Or, true>(L, R);
}
/// \brief Matches an Xor with LHS and RHS in either order.
-template<typename LHS, typename RHS>
-inline match_combine_or<BinaryOp_match<LHS, RHS, Instruction::Xor>,
- BinaryOp_match<RHS, LHS, Instruction::Xor>>
-m_c_Xor(const LHS &L, const RHS &R) {
- return m_CombineOr(m_Xor(L, R), m_Xor(R, L));
+template <typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::Xor, true> m_c_Xor(const LHS &L,
+ const RHS &R) {
+ return BinaryOp_match<LHS, RHS, Instruction::Xor, true>(L, R);
}
/// Matches an SMin with LHS and RHS in either order.
template <typename LHS, typename RHS>
-inline match_combine_or<MaxMin_match<ICmpInst, LHS, RHS, smin_pred_ty>,
- MaxMin_match<ICmpInst, RHS, LHS, smin_pred_ty>>
+inline MaxMin_match<ICmpInst, LHS, RHS, smin_pred_ty, true>
m_c_SMin(const LHS &L, const RHS &R) {
- return m_CombineOr(m_SMin(L, R), m_SMin(R, L));
+ return MaxMin_match<ICmpInst, LHS, RHS, smin_pred_ty, true>(L, R);
}
/// Matches an SMax with LHS and RHS in either order.
template <typename LHS, typename RHS>
-inline match_combine_or<MaxMin_match<ICmpInst, LHS, RHS, smax_pred_ty>,
- MaxMin_match<ICmpInst, RHS, LHS, smax_pred_ty>>
+inline MaxMin_match<ICmpInst, LHS, RHS, smax_pred_ty, true>
m_c_SMax(const LHS &L, const RHS &R) {
- return m_CombineOr(m_SMax(L, R), m_SMax(R, L));
+ return MaxMin_match<ICmpInst, LHS, RHS, smax_pred_ty, true>(L, R);
}
/// Matches a UMin with LHS and RHS in either order.
template <typename LHS, typename RHS>
-inline match_combine_or<MaxMin_match<ICmpInst, LHS, RHS, umin_pred_ty>,
- MaxMin_match<ICmpInst, RHS, LHS, umin_pred_ty>>
+inline MaxMin_match<ICmpInst, LHS, RHS, umin_pred_ty, true>
m_c_UMin(const LHS &L, const RHS &R) {
- return m_CombineOr(m_UMin(L, R), m_UMin(R, L));
+ return MaxMin_match<ICmpInst, LHS, RHS, umin_pred_ty, true>(L, R);
}
/// Matches a UMax with LHS and RHS in either order.
template <typename LHS, typename RHS>
-inline match_combine_or<MaxMin_match<ICmpInst, LHS, RHS, umax_pred_ty>,
- MaxMin_match<ICmpInst, RHS, LHS, umax_pred_ty>>
+inline MaxMin_match<ICmpInst, LHS, RHS, umax_pred_ty, true>
m_c_UMax(const LHS &L, const RHS &R) {
- return m_CombineOr(m_UMax(L, R), m_UMax(R, L));
+ return MaxMin_match<ICmpInst, LHS, RHS, umax_pred_ty, true>(L, R);
}
} // end namespace PatternMatch
} // end namespace llvm
-#endif
+#endif // LLVM_IR_PATTERNMATCH_H
diff --git a/contrib/llvm/include/llvm/IR/PredIteratorCache.h b/contrib/llvm/include/llvm/IR/PredIteratorCache.h
index 118310a..81f5353 100644
--- a/contrib/llvm/include/llvm/IR/PredIteratorCache.h
+++ b/contrib/llvm/include/llvm/IR/PredIteratorCache.h
@@ -27,8 +27,8 @@ namespace llvm {
/// wants the predecessor list for the same blocks.
class PredIteratorCache {
/// BlockToPredsMap - Pointer to null-terminated list.
- DenseMap<BasicBlock *, BasicBlock **> BlockToPredsMap;
- DenseMap<BasicBlock *, unsigned> BlockToPredCountMap;
+ mutable DenseMap<BasicBlock *, BasicBlock **> BlockToPredsMap;
+ mutable DenseMap<BasicBlock *, unsigned> BlockToPredCountMap;
/// Memory - This is the space that holds cached preds.
BumpPtrAllocator Memory;
@@ -55,13 +55,15 @@ private:
return Entry;
}
- unsigned GetNumPreds(BasicBlock *BB) {
- GetPreds(BB);
- return BlockToPredCountMap[BB];
+ unsigned GetNumPreds(BasicBlock *BB) const {
+ auto Result = BlockToPredCountMap.find(BB);
+ if (Result != BlockToPredCountMap.end())
+ return Result->second;
+ return BlockToPredCountMap[BB] = std::distance(pred_begin(BB), pred_end(BB));
}
public:
- size_t size(BasicBlock *BB) { return GetNumPreds(BB); }
+ size_t size(BasicBlock *BB) const { return GetNumPreds(BB); }
ArrayRef<BasicBlock *> get(BasicBlock *BB) {
return makeArrayRef(GetPreds(BB), GetNumPreds(BB));
}
diff --git a/contrib/llvm/include/llvm/IR/ProfileSummary.h b/contrib/llvm/include/llvm/IR/ProfileSummary.h
index f424801..d85ce8c 100644
--- a/contrib/llvm/include/llvm/IR/ProfileSummary.h
+++ b/contrib/llvm/include/llvm/IR/ProfileSummary.h
@@ -1,4 +1,4 @@
-//===-- ProfileSummary.h - Profile summary data structure. ------*- C++ -*-===//
+//===- ProfileSummary.h - Profile summary data structure. -------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -11,21 +11,17 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SUPPORT_PROFILE_SUMMARY_H
-#define LLVM_SUPPORT_PROFILE_SUMMARY_H
+#ifndef LLVM_IR_PROFILESUMMARY_H
+#define LLVM_IR_PROFILESUMMARY_H
+#include <algorithm>
#include <cstdint>
-#include <utility>
#include <vector>
-#include "llvm/Support/Casting.h"
-
namespace llvm {
class LLVMContext;
class Metadata;
-class MDTuple;
-class MDNode;
// The profile summary is one or more (Cutoff, MinCount, NumCounts) triplets.
// The semantics of counts depend on the type of profile. For instrumentation
@@ -37,12 +33,13 @@ struct ProfileSummaryEntry {
uint32_t Cutoff; ///< The required percentile of counts.
uint64_t MinCount; ///< The minimum count for this percentile.
uint64_t NumCounts; ///< Number of counts >= the minimum count.
+
ProfileSummaryEntry(uint32_t TheCutoff, uint64_t TheMinCount,
uint64_t TheNumCounts)
: Cutoff(TheCutoff), MinCount(TheMinCount), NumCounts(TheNumCounts) {}
};
-typedef std::vector<ProfileSummaryEntry> SummaryEntryVector;
+using SummaryEntryVector = std::vector<ProfileSummaryEntry>;
class ProfileSummary {
public:
@@ -59,6 +56,7 @@ private:
public:
static const int Scale = 1000000;
+
ProfileSummary(Kind K, SummaryEntryVector DetailedSummary,
uint64_t TotalCount, uint64_t MaxCount,
uint64_t MaxInternalCount, uint64_t MaxFunctionCount,
@@ -67,6 +65,7 @@ public:
TotalCount(TotalCount), MaxCount(MaxCount),
MaxInternalCount(MaxInternalCount), MaxFunctionCount(MaxFunctionCount),
NumCounts(NumCounts), NumFunctions(NumFunctions) {}
+
Kind getKind() const { return PSK; }
/// \brief Return summary information as metadata.
Metadata *getMD(LLVMContext &Context);
@@ -82,4 +81,5 @@ public:
};
} // end namespace llvm
-#endif
+
+#endif // LLVM_IR_PROFILESUMMARY_H
diff --git a/contrib/llvm/include/llvm/IR/SafepointIRVerifier.h b/contrib/llvm/include/llvm/IR/SafepointIRVerifier.h
new file mode 100644
index 0000000..092050d
--- /dev/null
+++ b/contrib/llvm/include/llvm/IR/SafepointIRVerifier.h
@@ -0,0 +1,35 @@
+//===- SafepointIRVerifier.h - Checks for GC relocation problems *- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines a verifier which is useful for enforcing the relocation
+// properties required by a relocating GC. Specifically, it looks for uses of
+// the unrelocated value of pointer SSA values after a possible safepoint. It
+// attempts to report no false negatives, but may end up reporting false
+// positives in rare cases (see the note at the top of the corresponding cpp
+// file.)
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_SAFEPOINT_IR_VERIFIER
+#define LLVM_IR_SAFEPOINT_IR_VERIFIER
+
+namespace llvm {
+
+class Function;
+class FunctionPass;
+
+/// Run the safepoint verifier over a single function. Crashes on failure.
+void verifySafepointIR(Function &F);
+
+/// Create an instance of the safepoint verifier pass which can be added to
+/// a pass pipeline to check for relocation bugs.
+FunctionPass *createSafepointIRVerifierPass();
+}
+
+#endif // LLVM_IR_SAFEPOINT_IR_VERIFIER
diff --git a/contrib/llvm/include/llvm/IR/Statepoint.h b/contrib/llvm/include/llvm/IR/Statepoint.h
index 916faa4..ad9537e 100644
--- a/contrib/llvm/include/llvm/IR/Statepoint.h
+++ b/contrib/llvm/include/llvm/IR/Statepoint.h
@@ -1,4 +1,4 @@
-//===-- llvm/IR/Statepoint.h - gc.statepoint utilities ----------*- C++ -*-===//
+//===- llvm/IR/Statepoint.h - gc.statepoint utilities -----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -17,17 +17,19 @@
#ifndef LLVM_IR_STATEPOINT_H
#define LLVM_IR_STATEPOINT_H
-#include "llvm/ADT/iterator_range.h"
#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/iterator_range.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/CallSite.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Function.h"
+#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/Support/Casting.h"
+#include "llvm/Support/MathExtras.h"
#include <cassert>
#include <cstddef>
#include <cstdint>
@@ -60,7 +62,10 @@ bool isStatepoint(const Value *V);
bool isStatepoint(const Value &V);
bool isGCRelocate(ImmutableCallSite CS);
+bool isGCRelocate(const Value *V);
+
bool isGCResult(ImmutableCallSite CS);
+bool isGCResult(const Value *V);
/// Analogous to CallSiteBase, this provides most of the actual
/// functionality for Statepoint and ImmutableStatepoint. It is
@@ -87,7 +92,7 @@ protected:
}
public:
- typedef typename CallSiteTy::arg_iterator arg_iterator;
+ using arg_iterator = typename CallSiteTy::arg_iterator;
enum {
IDPos = 0,
@@ -226,24 +231,24 @@ public:
return cast<ConstantInt>(NumVMSArgs)->getZExtValue();
}
- typename CallSiteTy::arg_iterator vm_state_begin() const {
+ typename CallSiteTy::arg_iterator deopt_begin() const {
auto I = gc_transition_args_end() + 1;
assert((getCallSite().arg_end() - I) >= 0);
return I;
}
- typename CallSiteTy::arg_iterator vm_state_end() const {
- auto I = vm_state_begin() + getNumTotalVMSArgs();
+ typename CallSiteTy::arg_iterator deopt_end() const {
+ auto I = deopt_begin() + getNumTotalVMSArgs();
assert((getCallSite().arg_end() - I) >= 0);
return I;
}
/// range adapter for vm state arguments
- iterator_range<arg_iterator> vm_state_args() const {
- return make_range(vm_state_begin(), vm_state_end());
+ iterator_range<arg_iterator> deopt_operands() const {
+ return make_range(deopt_begin(), deopt_end());
}
typename CallSiteTy::arg_iterator gc_args_begin() const {
- return vm_state_end();
+ return deopt_end();
}
typename CallSiteTy::arg_iterator gc_args_end() const {
return getCallSite().arg_end();
@@ -287,8 +292,8 @@ public:
(void)arg_end();
(void)gc_transition_args_begin();
(void)gc_transition_args_end();
- (void)vm_state_begin();
- (void)vm_state_end();
+ (void)deopt_begin();
+ (void)deopt_end();
(void)gc_args_begin();
(void)gc_args_end();
}
@@ -300,8 +305,9 @@ public:
class ImmutableStatepoint
: public StatepointBase<const Function, const Instruction, const Value,
ImmutableCallSite> {
- typedef StatepointBase<const Function, const Instruction, const Value,
- ImmutableCallSite> Base;
+ using Base =
+ StatepointBase<const Function, const Instruction, const Value,
+ ImmutableCallSite>;
public:
explicit ImmutableStatepoint(const Instruction *I) : Base(I) {}
@@ -312,7 +318,7 @@ public:
/// to a gc.statepoint.
class Statepoint
: public StatepointBase<Function, Instruction, Value, CallSite> {
- typedef StatepointBase<Function, Instruction, Value, CallSite> Base;
+ using Base = StatepointBase<Function, Instruction, Value, CallSite>;
public:
explicit Statepoint(Instruction *I) : Base(I) {}
@@ -323,11 +329,12 @@ public:
/// Currently, the only projections available are gc.result and gc.relocate.
class GCProjectionInst : public IntrinsicInst {
public:
- static inline bool classof(const IntrinsicInst *I) {
+ static bool classof(const IntrinsicInst *I) {
return I->getIntrinsicID() == Intrinsic::experimental_gc_relocate ||
I->getIntrinsicID() == Intrinsic::experimental_gc_result;
}
- static inline bool classof(const Value *V) {
+
+ static bool classof(const Value *V) {
return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
}
@@ -366,10 +373,11 @@ public:
/// Represents calls to the gc.relocate intrinsic.
class GCRelocateInst : public GCProjectionInst {
public:
- static inline bool classof(const IntrinsicInst *I) {
+ static bool classof(const IntrinsicInst *I) {
return I->getIntrinsicID() == Intrinsic::experimental_gc_relocate;
}
- static inline bool classof(const Value *V) {
+
+ static bool classof(const Value *V) {
return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
}
@@ -400,10 +408,11 @@ public:
/// Represents calls to the gc.result intrinsic.
class GCResultInst : public GCProjectionInst {
public:
- static inline bool classof(const IntrinsicInst *I) {
+ static bool classof(const IntrinsicInst *I) {
return I->getIntrinsicID() == Intrinsic::experimental_gc_result;
}
- static inline bool classof(const Value *V) {
+
+ static bool classof(const Value *V) {
return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
}
};
@@ -454,7 +463,7 @@ struct StatepointDirectives {
/// Parse out statepoint directives from the function attributes present in \p
/// AS.
-StatepointDirectives parseStatepointDirectivesFromAttrs(AttributeSet AS);
+StatepointDirectives parseStatepointDirectivesFromAttrs(AttributeList AS);
/// Return \c true if the the \p Attr is an attribute that is a statepoint
/// directive.
diff --git a/contrib/llvm/include/llvm/IR/SymbolTableListTraits.h b/contrib/llvm/include/llvm/IR/SymbolTableListTraits.h
index 5c6d58a..87ce902 100644
--- a/contrib/llvm/include/llvm/IR/SymbolTableListTraits.h
+++ b/contrib/llvm/include/llvm/IR/SymbolTableListTraits.h
@@ -1,4 +1,4 @@
-//===-- llvm/SymbolTableListTraits.h - Traits for iplist --------*- C++ -*-===//
+//===- llvm/SymbolTableListTraits.h - Traits for iplist ---------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -26,25 +26,29 @@
#define LLVM_IR_SYMBOLTABLELISTTRAITS_H
#include "llvm/ADT/ilist.h"
+#include "llvm/ADT/simple_ilist.h"
+#include <cstddef>
namespace llvm {
-class ValueSymbolTable;
-/// Template metafunction to get the parent type for a symbol table list.
-///
-/// Implementations create a typedef called \c type so that we only need a
-/// single template parameter for the list and traits.
-template <typename NodeTy> struct SymbolTableListParentType {};
class Argument;
class BasicBlock;
class Function;
-class Instruction;
-class GlobalVariable;
class GlobalAlias;
class GlobalIFunc;
+class GlobalVariable;
+class Instruction;
class Module;
+class ValueSymbolTable;
+
+/// Template metafunction to get the parent type for a symbol table list.
+///
+/// Implementations create a typedef called \c type so that we only need a
+/// single template parameter for the list and traits.
+template <typename NodeTy> struct SymbolTableListParentType {};
+
#define DEFINE_SYMBOL_TABLE_PARENT_TYPE(NODE, PARENT) \
- template <> struct SymbolTableListParentType<NODE> { typedef PARENT type; };
+ template <> struct SymbolTableListParentType<NODE> { using type = PARENT; };
DEFINE_SYMBOL_TABLE_PARENT_TYPE(Instruction, BasicBlock)
DEFINE_SYMBOL_TABLE_PARENT_TYPE(BasicBlock, Function)
DEFINE_SYMBOL_TABLE_PARENT_TYPE(Argument, Function)
@@ -61,13 +65,13 @@ template <typename NodeTy> class SymbolTableList;
//
template <typename ValueSubClass>
class SymbolTableListTraits : public ilist_alloc_traits<ValueSubClass> {
- typedef SymbolTableList<ValueSubClass> ListTy;
- typedef typename simple_ilist<ValueSubClass>::iterator iterator;
- typedef
- typename SymbolTableListParentType<ValueSubClass>::type ItemParentClass;
+ using ListTy = SymbolTableList<ValueSubClass>;
+ using iterator = typename simple_ilist<ValueSubClass>::iterator;
+ using ItemParentClass =
+ typename SymbolTableListParentType<ValueSubClass>::type;
public:
- SymbolTableListTraits() {}
+ SymbolTableListTraits() = default;
private:
/// getListOwner - Return the object that owns this list. If this is a list
@@ -109,6 +113,6 @@ template <class T>
class SymbolTableList
: public iplist_impl<simple_ilist<T>, SymbolTableListTraits<T>> {};
-} // End llvm namespace
+} // end namespace llvm
-#endif
+#endif // LLVM_IR_SYMBOLTABLELISTTRAITS_H
diff --git a/contrib/llvm/include/llvm/IR/TrackingMDRef.h b/contrib/llvm/include/llvm/IR/TrackingMDRef.h
index fe513a8..bdec904 100644
--- a/contrib/llvm/include/llvm/IR/TrackingMDRef.h
+++ b/contrib/llvm/include/llvm/IR/TrackingMDRef.h
@@ -15,6 +15,8 @@
#define LLVM_IR_TRACKINGMDREF_H
#include "llvm/IR/Metadata.h"
+#include <algorithm>
+#include <cassert>
namespace llvm {
@@ -22,14 +24,15 @@ namespace llvm {
///
/// This class behaves like \a TrackingVH, but for metadata.
class TrackingMDRef {
- Metadata *MD;
+ Metadata *MD = nullptr;
public:
- TrackingMDRef() : MD(nullptr) {}
+ TrackingMDRef() = default;
explicit TrackingMDRef(Metadata *MD) : MD(MD) { track(); }
TrackingMDRef(TrackingMDRef &&X) : MD(X.MD) { retrack(X); }
TrackingMDRef(const TrackingMDRef &X) : MD(X.MD) { track(); }
+
TrackingMDRef &operator=(TrackingMDRef &&X) {
if (&X == this)
return *this;
@@ -39,6 +42,7 @@ public:
retrack(X);
return *this;
}
+
TrackingMDRef &operator=(const TrackingMDRef &X) {
if (&X == this)
return *this;
@@ -48,6 +52,7 @@ public:
track();
return *this;
}
+
~TrackingMDRef() { untrack(); }
Metadata *get() const { return MD; }
@@ -80,10 +85,12 @@ private:
if (MD)
MetadataTracking::track(MD);
}
+
void untrack() {
if (MD)
MetadataTracking::untrack(MD);
}
+
void retrack(TrackingMDRef &X) {
assert(MD == X.MD && "Expected values to match");
if (X.MD) {
@@ -101,15 +108,17 @@ template <class T> class TypedTrackingMDRef {
TrackingMDRef Ref;
public:
- TypedTrackingMDRef() {}
+ TypedTrackingMDRef() = default;
explicit TypedTrackingMDRef(T *MD) : Ref(static_cast<Metadata *>(MD)) {}
TypedTrackingMDRef(TypedTrackingMDRef &&X) : Ref(std::move(X.Ref)) {}
TypedTrackingMDRef(const TypedTrackingMDRef &X) : Ref(X.Ref) {}
+
TypedTrackingMDRef &operator=(TypedTrackingMDRef &&X) {
Ref = std::move(X.Ref);
return *this;
}
+
TypedTrackingMDRef &operator=(const TypedTrackingMDRef &X) {
Ref = X.Ref;
return *this;
@@ -130,31 +139,35 @@ public:
bool hasTrivialDestructor() const { return Ref.hasTrivialDestructor(); }
};
-typedef TypedTrackingMDRef<MDNode> TrackingMDNodeRef;
-typedef TypedTrackingMDRef<ValueAsMetadata> TrackingValueAsMetadataRef;
+using TrackingMDNodeRef = TypedTrackingMDRef<MDNode>;
+using TrackingValueAsMetadataRef = TypedTrackingMDRef<ValueAsMetadata>;
// Expose the underlying metadata to casting.
template <> struct simplify_type<TrackingMDRef> {
- typedef Metadata *SimpleType;
+ using SimpleType = Metadata *;
+
static SimpleType getSimplifiedValue(TrackingMDRef &MD) { return MD.get(); }
};
template <> struct simplify_type<const TrackingMDRef> {
- typedef Metadata *SimpleType;
+ using SimpleType = Metadata *;
+
static SimpleType getSimplifiedValue(const TrackingMDRef &MD) {
return MD.get();
}
};
template <class T> struct simplify_type<TypedTrackingMDRef<T>> {
- typedef T *SimpleType;
+ using SimpleType = T *;
+
static SimpleType getSimplifiedValue(TypedTrackingMDRef<T> &MD) {
return MD.get();
}
};
template <class T> struct simplify_type<const TypedTrackingMDRef<T>> {
- typedef T *SimpleType;
+ using SimpleType = T *;
+
static SimpleType getSimplifiedValue(const TypedTrackingMDRef<T> &MD) {
return MD.get();
}
@@ -162,4 +175,4 @@ template <class T> struct simplify_type<const TypedTrackingMDRef<T>> {
} // end namespace llvm
-#endif
+#endif // LLVM_IR_TRACKINGMDREF_H
diff --git a/contrib/llvm/include/llvm/IR/Type.h b/contrib/llvm/include/llvm/IR/Type.h
index 778ee06..ef78012 100644
--- a/contrib/llvm/include/llvm/IR/Type.h
+++ b/contrib/llvm/include/llvm/IR/Type.h
@@ -1,4 +1,4 @@
-//===-- llvm/Type.h - Classes for handling data types -----------*- C++ -*-===//
+//===- llvm/Type.h - Classes for handling data types ------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -20,19 +20,20 @@
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Support/CBindingWrapping.h"
#include "llvm/Support/Casting.h"
-#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h"
+#include <cassert>
+#include <cstdint>
+#include <iterator>
namespace llvm {
-class PointerType;
+template<class GraphType> struct GraphTraits;
class IntegerType;
-class raw_ostream;
-class Module;
class LLVMContext;
-class LLVMContextImpl;
+class PointerType;
+class raw_ostream;
class StringRef;
-template<class GraphType> struct GraphTraits;
/// The instances of the Type class are immutable: once they are created,
/// they are never changed. Also note that only one instance of a particular
@@ -86,9 +87,9 @@ private:
protected:
friend class LLVMContextImpl;
+
explicit Type(LLVMContext &C, TypeID tid)
- : Context(C), ID(tid), SubclassData(0),
- NumContainedTys(0), ContainedTys(nullptr) {}
+ : Context(C), ID(tid), SubclassData(0) {}
~Type() = default;
unsigned getSubclassData() const { return SubclassData; }
@@ -100,14 +101,14 @@ protected:
}
/// Keeps track of how many Type*'s there are in the ContainedTys list.
- unsigned NumContainedTys;
+ unsigned NumContainedTys = 0;
/// A pointer to the array of Types contained by this Type. For example, this
/// includes the arguments of a function type, the elements of a structure,
/// the pointee of a pointer, the element type of an array, etc. This pointer
/// may be 0 for types that don't contain other types (Integer, Double,
/// Float).
- Type * const *ContainedTys;
+ Type * const *ContainedTys = nullptr;
static bool isSequentialType(TypeID TyID) {
return TyID == ArrayTyID || TyID == VectorTyID;
@@ -122,6 +123,7 @@ public:
/// inlined with the operands when printing an instruction.
void print(raw_ostream &O, bool IsForDebug = false,
bool NoDetails = false) const;
+
void dump() const;
/// Return the LLVMContext in which this type was uniqued.
@@ -200,6 +202,12 @@ public:
/// Return true if this is an integer type or a vector of integer types.
bool isIntOrIntVectorTy() const { return getScalarType()->isIntegerTy(); }
+ /// Return true if this is an integer type or a vector of integer types of
+ /// the given width.
+ bool isIntOrIntVectorTy(unsigned BitWidth) const {
+ return getScalarType()->isIntegerTy(BitWidth);
+ }
+
/// True if this is an instance of FunctionType.
bool isFunctionTy() const { return getTypeID() == FunctionTyID; }
@@ -290,19 +298,25 @@ public:
/// If this is a vector type, return the element type, otherwise return
/// 'this'.
- Type *getScalarType() const LLVM_READONLY;
+ Type *getScalarType() const {
+ if (isVectorTy())
+ return getVectorElementType();
+ return const_cast<Type*>(this);
+ }
//===--------------------------------------------------------------------===//
// Type Iteration support.
//
- typedef Type * const *subtype_iterator;
+ using subtype_iterator = Type * const *;
+
subtype_iterator subtype_begin() const { return ContainedTys; }
subtype_iterator subtype_end() const { return &ContainedTys[NumContainedTys];}
ArrayRef<Type*> subtypes() const {
return makeArrayRef(subtype_begin(), subtype_end());
}
- typedef std::reverse_iterator<subtype_iterator> subtype_reverse_iterator;
+ using subtype_reverse_iterator = std::reverse_iterator<subtype_iterator>;
+
subtype_reverse_iterator subtype_rbegin() const {
return subtype_reverse_iterator(subtype_end());
}
@@ -344,6 +358,7 @@ public:
}
inline uint64_t getArrayNumElements() const;
+
Type *getArrayElementType() const {
assert(getTypeID() == ArrayTyID);
return ContainedTys[0];
@@ -423,7 +438,7 @@ private:
};
// Printing of types.
-static inline raw_ostream &operator<<(raw_ostream &OS, Type &T) {
+static inline raw_ostream &operator<<(raw_ostream &OS, const Type &T) {
T.print(OS);
return OS;
}
@@ -440,8 +455,8 @@ template <> struct isa_impl<PointerType, Type> {
// graph of sub types.
template <> struct GraphTraits<Type *> {
- typedef Type *NodeRef;
- typedef Type::subtype_iterator ChildIteratorType;
+ using NodeRef = Type *;
+ using ChildIteratorType = Type::subtype_iterator;
static NodeRef getEntryNode(Type *T) { return T; }
static ChildIteratorType child_begin(NodeRef N) { return N->subtype_begin(); }
@@ -449,8 +464,8 @@ template <> struct GraphTraits<Type *> {
};
template <> struct GraphTraits<const Type*> {
- typedef const Type *NodeRef;
- typedef Type::subtype_iterator ChildIteratorType;
+ using NodeRef = const Type *;
+ using ChildIteratorType = Type::subtype_iterator;
static NodeRef getEntryNode(NodeRef T) { return T; }
static ChildIteratorType child_begin(NodeRef N) { return N->subtype_begin(); }
@@ -470,6 +485,6 @@ inline LLVMTypeRef *wrap(Type **Tys) {
return reinterpret_cast<LLVMTypeRef*>(const_cast<Type**>(Tys));
}
-} // End llvm namespace
+} // end namespace llvm
-#endif
+#endif // LLVM_IR_TYPE_H
diff --git a/contrib/llvm/include/llvm/IR/TypeFinder.h b/contrib/llvm/include/llvm/IR/TypeFinder.h
index 046f85c..c050c38 100644
--- a/contrib/llvm/include/llvm/IR/TypeFinder.h
+++ b/contrib/llvm/include/llvm/IR/TypeFinder.h
@@ -1,4 +1,4 @@
-//===-- llvm/IR/TypeFinder.h - Class to find used struct types --*- C++ -*-===//
+//===- llvm/IR/TypeFinder.h - Class to find used struct types ---*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -15,8 +15,7 @@
#define LLVM_IR_TYPEFINDER_H
#include "llvm/ADT/DenseSet.h"
-#include "llvm/IR/Metadata.h"
-#include "llvm/IR/Type.h"
+#include <cstddef>
#include <vector>
namespace llvm {
@@ -24,6 +23,7 @@ namespace llvm {
class MDNode;
class Module;
class StructType;
+class Type;
class Value;
/// TypeFinder - Walk over a module, identifying all of the types that are
@@ -36,16 +36,16 @@ class TypeFinder {
DenseSet<Type*> VisitedTypes;
std::vector<StructType*> StructTypes;
- bool OnlyNamed;
+ bool OnlyNamed = false;
public:
- TypeFinder() : OnlyNamed(false) {}
+ TypeFinder() = default;
void run(const Module &M, bool onlyNamed);
void clear();
- typedef std::vector<StructType*>::iterator iterator;
- typedef std::vector<StructType*>::const_iterator const_iterator;
+ using iterator = std::vector<StructType*>::iterator;
+ using const_iterator = std::vector<StructType*>::const_iterator;
iterator begin() { return StructTypes.begin(); }
iterator end() { return StructTypes.end(); }
@@ -77,6 +77,6 @@ private:
void incorporateMDNode(const MDNode *V);
};
-} // end llvm namespace
+} // end namespace llvm
-#endif
+#endif // LLVM_IR_TYPEFINDER_H
diff --git a/contrib/llvm/include/llvm/IR/Use.h b/contrib/llvm/include/llvm/IR/Use.h
index ff6b2e1..0ac1393 100644
--- a/contrib/llvm/include/llvm/IR/Use.h
+++ b/contrib/llvm/include/llvm/IR/Use.h
@@ -1,4 +1,4 @@
-//===-- llvm/Use.h - Definition of the Use class ----------------*- C++ -*-===//
+//===- llvm/Use.h - Definition of the Use class -----------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -25,16 +25,16 @@
#ifndef LLVM_IR_USE_H
#define LLVM_IR_USE_H
+#include "llvm-c/Types.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/Support/CBindingWrapping.h"
-#include "llvm-c/Types.h"
+#include "llvm/Support/Compiler.h"
namespace llvm {
-class Value;
-class User;
-class Use;
template <typename> struct simplify_type;
+class User;
+class Value;
/// \brief A Use represents the edge between a Value definition and its users.
///
@@ -61,9 +61,33 @@ 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.
- typedef PointerIntPair<User *, 1, unsigned> UserRef;
+ 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()
@@ -75,9 +99,11 @@ private:
enum PrevPtrTag { zeroDigitTag, oneDigitTag, stopTag, fullStopTag };
/// Constructor
- Use(PrevPtrTag tag) : Val(nullptr) { Prev.setInt(tag); }
+ Use(PrevPtrTag tag) { Prev.setInt(tag); }
public:
+ friend class Value;
+
operator Value *() const { return Val; }
Value *get() const { return Val; }
@@ -85,7 +111,7 @@ public:
///
/// For an instruction operand, for example, this will return the
/// instruction.
- User *getUser() const;
+ User *getUser() const LLVM_READONLY;
inline void set(Value *Val);
@@ -111,11 +137,11 @@ public:
static void zap(Use *Start, const Use *Stop, bool del = false);
private:
- const Use *getImpliedUser() const;
+ const Use *getImpliedUser() const LLVM_READONLY;
- Value *Val;
+ Value *Val = nullptr;
Use *Next;
- PointerIntPair<Use **, 2, PrevPtrTag> Prev;
+ PointerIntPair<Use **, 2, PrevPtrTag, PrevPointerTraits> Prev;
void setPrev(Use **NewPrev) { Prev.setPointer(NewPrev); }
@@ -133,18 +159,18 @@ private:
if (Next)
Next->setPrev(StrippedPrev);
}
-
- friend class Value;
};
/// \brief Allow clients to treat uses just like values when using
/// casting operators.
template <> struct simplify_type<Use> {
- typedef Value *SimpleType;
+ using SimpleType = Value *;
+
static SimpleType getSimplifiedValue(Use &Val) { return Val.get(); }
};
template <> struct simplify_type<const Use> {
- typedef /*const*/ Value *SimpleType;
+ using SimpleType = /*const*/ Value *;
+
static SimpleType getSimplifiedValue(const Use &Val) { return Val.get(); }
};
diff --git a/contrib/llvm/include/llvm/IR/UseListOrder.h b/contrib/llvm/include/llvm/IR/UseListOrder.h
index efff208..a8b394f 100644
--- a/contrib/llvm/include/llvm/IR/UseListOrder.h
+++ b/contrib/llvm/include/llvm/IR/UseListOrder.h
@@ -20,25 +20,24 @@
namespace llvm {
-class Module;
class Function;
class Value;
/// \brief Structure to hold a use-list order.
struct UseListOrder {
- const Value *V;
- const Function *F;
+ const Value *V = nullptr;
+ const Function *F = nullptr;
std::vector<unsigned> Shuffle;
UseListOrder(const Value *V, const Function *F, size_t ShuffleSize)
: V(V), F(F), Shuffle(ShuffleSize) {}
- UseListOrder() : V(nullptr), F(nullptr) {}
+ UseListOrder() = default;
UseListOrder(UseListOrder &&) = default;
UseListOrder &operator=(UseListOrder &&) = default;
};
-typedef std::vector<UseListOrder> UseListOrderStack;
+using UseListOrderStack = std::vector<UseListOrder>;
} // end namespace llvm
diff --git a/contrib/llvm/include/llvm/IR/User.h b/contrib/llvm/include/llvm/IR/User.h
index c907d6b..4dfa19c 100644
--- a/contrib/llvm/include/llvm/IR/User.h
+++ b/contrib/llvm/include/llvm/IR/User.h
@@ -1,4 +1,4 @@
-//===-- llvm/User.h - User class definition ---------------------*- C++ -*-===//
+//===- llvm/User.h - User class definition ----------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -46,8 +46,6 @@ class User : public Value {
template <unsigned>
friend struct HungoffOperandTraits;
- virtual void anchor();
-
LLVM_ATTRIBUTE_ALWAYS_INLINE inline static void *
allocateFixedOperandUser(size_t, unsigned, unsigned);
@@ -93,9 +91,11 @@ protected:
/// should be called if there are no uses.
void growHungoffUses(unsigned N, bool IsPhi = false);
+protected:
+ ~User() = default; // Use deleteValue() to delete a generic Instruction.
+
public:
User(const User &) = delete;
- ~User() override = default;
/// \brief Free memory allocated for User and Use objects.
void operator delete(void *Usr);
@@ -114,6 +114,7 @@ protected:
? OperandTraits<U>::op_end(const_cast<U*>(that))[Idx]
: OperandTraits<U>::op_begin(const_cast<U*>(that))[Idx];
}
+
template <int Idx> Use &Op() {
return OpFrom<Idx>(this);
}
@@ -122,8 +123,16 @@ protected:
}
private:
+ const Use *getHungOffOperands() const {
+ return *(reinterpret_cast<const Use *const *>(this) - 1);
+ }
+
Use *&getHungOffOperands() { return *(reinterpret_cast<Use **>(this) - 1); }
+ const Use *getIntrusiveOperands() const {
+ return reinterpret_cast<const Use *>(this) - NumUserOperands;
+ }
+
Use *getIntrusiveOperands() {
return reinterpret_cast<Use *>(this) - NumUserOperands;
}
@@ -135,11 +144,11 @@ private:
}
public:
- Use *getOperandList() {
+ const Use *getOperandList() const {
return HasHungOffUses ? getHungOffOperands() : getIntrusiveOperands();
}
- const Use *getOperandList() const {
- return const_cast<User *>(this)->getOperandList();
+ Use *getOperandList() {
+ return const_cast<Use *>(static_cast<const User *>(this)->getOperandList());
}
Value *getOperand(unsigned i) const {
@@ -197,10 +206,10 @@ public:
// ---------------------------------------------------------------------------
// Operand Iterator interface...
//
- typedef Use* op_iterator;
- typedef const Use* const_op_iterator;
- typedef iterator_range<op_iterator> op_range;
- typedef iterator_range<const_op_iterator> const_op_range;
+ using op_iterator = Use*;
+ using const_op_iterator = const Use*;
+ using op_range = iterator_range<op_iterator>;
+ using const_op_range = iterator_range<const_op_iterator>;
op_iterator op_begin() { return getOperandList(); }
const_op_iterator op_begin() const { return getOperandList(); }
@@ -244,6 +253,7 @@ public:
ptrdiff_t, const Value *, const Value *> {
explicit const_value_op_iterator(const Use *U = nullptr) :
iterator_adaptor_base(U) {}
+
const Value *operator*() const { return *I; }
const Value *operator->() const { return operator*(); }
};
@@ -278,10 +288,11 @@ public:
void replaceUsesOfWith(Value *From, Value *To);
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return isa<Instruction>(V) || isa<Constant>(V);
}
};
+
// Either Use objects, or a Use pointer can be prepended to User.
static_assert(alignof(Use) >= alignof(User),
"Alignment is insufficient after objects prepended to User");
@@ -289,13 +300,15 @@ static_assert(alignof(Use *) >= alignof(User),
"Alignment is insufficient after objects prepended to User");
template<> struct simplify_type<User::op_iterator> {
- typedef Value* SimpleType;
+ using SimpleType = Value*;
+
static SimpleType getSimplifiedValue(User::op_iterator &Val) {
return Val->get();
}
};
template<> struct simplify_type<User::const_op_iterator> {
- typedef /*const*/ Value* SimpleType;
+ using SimpleType = /*const*/ Value*;
+
static SimpleType getSimplifiedValue(User::const_op_iterator &Val) {
return Val->get();
}
diff --git a/contrib/llvm/include/llvm/IR/Value.def b/contrib/llvm/include/llvm/IR/Value.def
index 48842d7..cebd7f7 100644
--- a/contrib/llvm/include/llvm/IR/Value.def
+++ b/contrib/llvm/include/llvm/IR/Value.def
@@ -20,10 +20,14 @@
#if !(defined HANDLE_GLOBAL_VALUE || defined HANDLE_CONSTANT || \
defined HANDLE_INSTRUCTION || defined HANDLE_INLINE_ASM_VALUE || \
defined HANDLE_METADATA_VALUE || defined HANDLE_VALUE || \
- defined HANDLE_CONSTANT_MARKER)
+ defined HANDLE_CONSTANT_MARKER || defined HANDLE_MEMORY_VALUE)
#error "Missing macro definition of HANDLE_VALUE*"
#endif
+#ifndef HANDLE_MEMORY_VALUE
+#define HANDLE_MEMORY_VALUE(ValueName) HANDLE_VALUE(ValueName)
+#endif
+
#ifndef HANDLE_GLOBAL_VALUE
#define HANDLE_GLOBAL_VALUE(ValueName) HANDLE_CONSTANT(ValueName)
#endif
@@ -54,9 +58,13 @@
HANDLE_VALUE(Argument)
HANDLE_VALUE(BasicBlock)
-HANDLE_VALUE(MemoryUse)
-HANDLE_VALUE(MemoryDef)
-HANDLE_VALUE(MemoryPhi)
+
+// FIXME: It's awkward that Value.def knows about classes in Analysis. While
+// this doesn't introduce a strict link or include dependency, we should remove
+// the circular dependency eventually.
+HANDLE_MEMORY_VALUE(MemoryUse)
+HANDLE_MEMORY_VALUE(MemoryDef)
+HANDLE_MEMORY_VALUE(MemoryPhi)
HANDLE_GLOBAL_VALUE(Function)
HANDLE_GLOBAL_VALUE(GlobalAlias)
@@ -94,6 +102,7 @@ HANDLE_CONSTANT_MARKER(ConstantDataLastVal, ConstantTokenNone)
HANDLE_CONSTANT_MARKER(ConstantAggregateFirstVal, ConstantArray)
HANDLE_CONSTANT_MARKER(ConstantAggregateLastVal, ConstantVector)
+#undef HANDLE_MEMORY_VALUE
#undef HANDLE_GLOBAL_VALUE
#undef HANDLE_CONSTANT
#undef HANDLE_INSTRUCTION
diff --git a/contrib/llvm/include/llvm/IR/Value.h b/contrib/llvm/include/llvm/IR/Value.h
index bdafbbf..9e49149 100644
--- a/contrib/llvm/include/llvm/IR/Value.h
+++ b/contrib/llvm/include/llvm/IR/Value.h
@@ -1,4 +1,4 @@
-//===-- llvm/Value.h - Definition of the Value class ------------*- C++ -*-===//
+//===- llvm/Value.h - Definition of the Value class -------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,13 +14,14 @@
#ifndef LLVM_IR_VALUE_H
#define LLVM_IR_VALUE_H
+#include "llvm-c/Types.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/IR/Use.h"
#include "llvm/Support/CBindingWrapping.h"
#include "llvm/Support/Casting.h"
-#include "llvm-c/Types.h"
#include <cassert>
#include <iterator>
+#include <memory>
namespace llvm {
@@ -44,12 +45,13 @@ class LLVMContext;
class Module;
class ModuleSlotTracker;
class raw_ostream;
+template<typename ValueTy> class StringMapEntry;
class StringRef;
class Twine;
class Type;
+class User;
-template<typename ValueTy> class StringMapEntry;
-typedef StringMapEntry<Value*> ValueName;
+using ValueName = StringMapEntry<Value *>;
//===----------------------------------------------------------------------===//
// Value Class
@@ -69,6 +71,8 @@ typedef StringMapEntry<Value*> ValueName;
/// 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;
@@ -120,9 +124,11 @@ private:
template <typename UseT> // UseT == 'Use' or 'const Use'
class use_iterator_impl
: public std::iterator<std::forward_iterator_tag, UseT *> {
+ friend class Value;
+
UseT *U;
+
explicit use_iterator_impl(UseT *u) : U(u) {}
- friend class Value;
public:
use_iterator_impl() : U() {}
@@ -198,10 +204,19 @@ private:
protected:
Value(Type *Ty, unsigned scid);
+ /// Value's destructor should be virtual by design, but that would require
+ /// that Value and all of its subclasses have a vtable that effectively
+ /// duplicates the information in the value ID. As a size optimization, the
+ /// destructor has been protected, and the caller should manually call
+ /// deleteValue.
+ ~Value(); // Use deleteValue() to delete a generic Value.
+
public:
Value(const Value &) = delete;
- void operator=(const Value &) = delete;
- virtual ~Value();
+ Value &operator=(const Value &) = delete;
+
+ /// Delete a pointer to a generic Value.
+ void deleteValue();
/// \brief Support for debugging, callable in GDB: V->dump()
void dump() const;
@@ -294,15 +309,24 @@ public:
// when using them since you might not get all uses.
// The methods that don't start with materialized_ assert that modules is
// fully materialized.
- void assertModuleIsMaterialized() const;
+ void assertModuleIsMaterializedImpl() const;
+ // This indirection exists so we can keep assertModuleIsMaterializedImpl()
+ // around in release builds of Value.cpp to be linked with other code built
+ // in debug mode. But this avoids calling it in any of the release built code.
+ void assertModuleIsMaterialized() const {
+#ifndef NDEBUG
+ assertModuleIsMaterializedImpl();
+#endif
+ }
bool use_empty() const {
assertModuleIsMaterialized();
return UseList == nullptr;
}
- typedef use_iterator_impl<Use> use_iterator;
- typedef use_iterator_impl<const Use> const_use_iterator;
+ using use_iterator = use_iterator_impl<Use>;
+ using const_use_iterator = use_iterator_impl<const Use>;
+
use_iterator materialized_use_begin() { return use_iterator(UseList); }
const_use_iterator materialized_use_begin() const {
return const_use_iterator(UseList);
@@ -337,8 +361,9 @@ public:
return UseList == nullptr;
}
- typedef user_iterator_impl<User> user_iterator;
- typedef user_iterator_impl<const User> const_user_iterator;
+ using user_iterator = user_iterator_impl<User>;
+ using const_user_iterator = user_iterator_impl<const User>;
+
user_iterator materialized_user_begin() { return user_iterator(UseList); }
const_user_iterator materialized_user_begin() const {
return const_user_iterator(UseList);
@@ -468,27 +493,41 @@ public:
///
/// Returns the original uncasted value. If this is called on a non-pointer
/// value, it returns 'this'.
- Value *stripPointerCasts();
- const Value *stripPointerCasts() const {
- return const_cast<Value*>(this)->stripPointerCasts();
+ const Value *stripPointerCasts() const;
+ Value *stripPointerCasts() {
+ return const_cast<Value *>(
+ static_cast<const Value *>(this)->stripPointerCasts());
+ }
+
+ /// \brief Strip off pointer casts, all-zero GEPs, aliases and barriers.
+ ///
+ /// Returns the original uncasted value. If this is called on a non-pointer
+ /// value, it returns 'this'. This function should be used only in
+ /// Alias analysis.
+ const Value *stripPointerCastsAndBarriers() const;
+ Value *stripPointerCastsAndBarriers() {
+ return const_cast<Value *>(
+ static_cast<const Value *>(this)->stripPointerCastsAndBarriers());
}
/// \brief Strip off pointer casts and all-zero GEPs.
///
/// Returns the original uncasted value. If this is called on a non-pointer
/// value, it returns 'this'.
- Value *stripPointerCastsNoFollowAliases();
- const Value *stripPointerCastsNoFollowAliases() const {
- return const_cast<Value*>(this)->stripPointerCastsNoFollowAliases();
+ const Value *stripPointerCastsNoFollowAliases() const;
+ Value *stripPointerCastsNoFollowAliases() {
+ return const_cast<Value *>(
+ static_cast<const Value *>(this)->stripPointerCastsNoFollowAliases());
}
/// \brief Strip off pointer casts and all-constant inbounds GEPs.
///
/// Returns the original pointer value. If this is called on a non-pointer
/// value, it returns 'this'.
- Value *stripInBoundsConstantOffsets();
- const Value *stripInBoundsConstantOffsets() const {
- return const_cast<Value*>(this)->stripInBoundsConstantOffsets();
+ const Value *stripInBoundsConstantOffsets() const;
+ Value *stripInBoundsConstantOffsets() {
+ return const_cast<Value *>(
+ static_cast<const Value *>(this)->stripInBoundsConstantOffsets());
}
/// \brief Accumulate offsets from \a stripInBoundsConstantOffsets().
@@ -498,21 +537,22 @@ public:
/// correct bitwidth for an offset of this pointer type.
///
/// If this is called on a non-pointer value, it returns 'this'.
- Value *stripAndAccumulateInBoundsConstantOffsets(const DataLayout &DL,
- APInt &Offset);
const Value *stripAndAccumulateInBoundsConstantOffsets(const DataLayout &DL,
- APInt &Offset) const {
- return const_cast<Value *>(this)
- ->stripAndAccumulateInBoundsConstantOffsets(DL, Offset);
+ APInt &Offset) const;
+ Value *stripAndAccumulateInBoundsConstantOffsets(const DataLayout &DL,
+ APInt &Offset) {
+ return const_cast<Value *>(static_cast<const Value *>(this)
+ ->stripAndAccumulateInBoundsConstantOffsets(DL, Offset));
}
/// \brief Strip off pointer casts and inbounds GEPs.
///
/// Returns the original pointer value. If this is called on a non-pointer
/// value, it returns 'this'.
- Value *stripInBoundsOffsets();
- const Value *stripInBoundsOffsets() const {
- return const_cast<Value*>(this)->stripInBoundsOffsets();
+ const Value *stripInBoundsOffsets() const;
+ Value *stripInBoundsOffsets() {
+ return const_cast<Value *>(
+ static_cast<const Value *>(this)->stripInBoundsOffsets());
}
/// \brief Returns the number of bytes known to be dereferenceable for the
@@ -535,11 +575,11 @@ public:
/// the PHI node corresponding to PredBB. If not, return ourself. This is
/// useful if you want to know the value something has in a predecessor
/// block.
- Value *DoPHITranslation(const BasicBlock *CurBB, const BasicBlock *PredBB);
-
const Value *DoPHITranslation(const BasicBlock *CurBB,
- const BasicBlock *PredBB) const{
- return const_cast<Value*>(this)->DoPHITranslation(CurBB, PredBB);
+ const BasicBlock *PredBB) const;
+ Value *DoPHITranslation(const BasicBlock *CurBB, const BasicBlock *PredBB) {
+ return const_cast<Value *>(
+ static_cast<const Value *>(this)->DoPHITranslation(CurBB, PredBB));
}
/// \brief The maximum alignment for instructions.
@@ -582,7 +622,7 @@ private:
Use *Merged;
Use **Next = &Merged;
- for (;;) {
+ while (true) {
if (!L) {
*Next = R;
break;
@@ -616,6 +656,13 @@ protected:
void setValueSubclassData(unsigned short D) { SubclassData = D; }
};
+struct ValueDeleter { void operator()(Value *V) { V->deleteValue(); } };
+
+/// Use this instead of std::unique_ptr<Value> or std::unique_ptr<Instruction>.
+/// Those don't work because Value and Instruction's destructors are protected,
+/// aren't virtual, and won't destroy the complete object.
+using unique_value = std::unique_ptr<Value, ValueDeleter>;
+
inline raw_ostream &operator<<(raw_ostream &OS, const Value &V) {
V.print(OS);
return OS;
diff --git a/contrib/llvm/include/llvm/IR/ValueHandle.h b/contrib/llvm/include/llvm/IR/ValueHandle.h
index a4d4893..b45cc7b 100644
--- a/contrib/llvm/include/llvm/IR/ValueHandle.h
+++ b/contrib/llvm/include/llvm/IR/ValueHandle.h
@@ -17,10 +17,10 @@
#include "llvm/ADT/DenseMapInfo.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/IR/Value.h"
+#include "llvm/Support/Casting.h"
+#include <cassert>
namespace llvm {
-class ValueHandleBase;
-template<typename From> struct simplify_type;
/// \brief This is the common base class of value handles.
///
@@ -29,68 +29,71 @@ template<typename From> struct simplify_type;
/// below for details.
class ValueHandleBase {
friend class Value;
+
protected:
/// \brief This indicates what sub class the handle actually is.
///
/// This is to avoid having a vtable for the light-weight handle pointers. The
/// fully general Callback version does have a vtable.
- enum HandleBaseKind {
- Assert,
- Callback,
- Tracking,
- Weak
- };
+ enum HandleBaseKind { Assert, Callback, Weak, WeakTracking };
ValueHandleBase(const ValueHandleBase &RHS)
: ValueHandleBase(RHS.PrevPair.getInt(), RHS) {}
ValueHandleBase(HandleBaseKind Kind, const ValueHandleBase &RHS)
- : PrevPair(nullptr, Kind), Next(nullptr), V(RHS.V) {
- if (isValid(V))
+ : PrevPair(nullptr, Kind), Val(RHS.getValPtr()) {
+ if (isValid(getValPtr()))
AddToExistingUseList(RHS.getPrevPtr());
}
private:
PointerIntPair<ValueHandleBase**, 2, HandleBaseKind> PrevPair;
- ValueHandleBase *Next;
+ ValueHandleBase *Next = nullptr;
+ Value *Val = nullptr;
- Value* V;
+ void setValPtr(Value *V) { Val = V; }
public:
explicit ValueHandleBase(HandleBaseKind Kind)
- : PrevPair(nullptr, Kind), Next(nullptr), V(nullptr) {}
+ : PrevPair(nullptr, Kind) {}
ValueHandleBase(HandleBaseKind Kind, Value *V)
- : PrevPair(nullptr, Kind), Next(nullptr), V(V) {
- if (isValid(V))
+ : PrevPair(nullptr, Kind), Val(V) {
+ if (isValid(getValPtr()))
AddToUseList();
}
~ValueHandleBase() {
- if (isValid(V))
+ if (isValid(getValPtr()))
RemoveFromUseList();
}
Value *operator=(Value *RHS) {
- if (V == RHS) return RHS;
- if (isValid(V)) RemoveFromUseList();
- V = RHS;
- if (isValid(V)) AddToUseList();
+ if (getValPtr() == RHS)
+ return RHS;
+ if (isValid(getValPtr()))
+ RemoveFromUseList();
+ setValPtr(RHS);
+ if (isValid(getValPtr()))
+ AddToUseList();
return RHS;
}
Value *operator=(const ValueHandleBase &RHS) {
- if (V == RHS.V) return RHS.V;
- if (isValid(V)) RemoveFromUseList();
- V = RHS.V;
- if (isValid(V)) AddToExistingUseList(RHS.getPrevPtr());
- return V;
+ if (getValPtr() == RHS.getValPtr())
+ return RHS.getValPtr();
+ if (isValid(getValPtr()))
+ RemoveFromUseList();
+ setValPtr(RHS.getValPtr());
+ if (isValid(getValPtr()))
+ AddToExistingUseList(RHS.getPrevPtr());
+ return getValPtr();
}
- Value *operator->() const { return V; }
- Value &operator*() const { return *V; }
+ Value *operator->() const { return getValPtr(); }
+ Value &operator*() const { return *getValPtr(); }
protected:
- Value *getValPtr() const { return V; }
+ Value *getValPtr() const { return Val; }
static bool isValid(Value *V) {
return V &&
@@ -98,6 +101,15 @@ protected:
V != DenseMapInfo<Value *>::getTombstoneKey();
}
+ /// \brief Remove this ValueHandle from its current use list.
+ void RemoveFromUseList();
+
+ /// \brief Clear the underlying pointer without clearing the use list.
+ ///
+ /// This should only be used if a derived class has manually removed the
+ /// handle from the use list.
+ void clearValPtr() { setValPtr(nullptr); }
+
public:
// Callbacks made from Value.
static void ValueIsDeleted(Value *V);
@@ -120,23 +132,18 @@ private:
/// \brief Add this ValueHandle to the use list for V.
void AddToUseList();
- /// \brief Remove this ValueHandle from its current use list.
- void RemoveFromUseList();
};
-/// \brief Value handle that is nullable, but tries to track the Value.
+/// \brief A nullable Value handle that is nullable.
///
-/// This is a value handle that tries hard to point to a Value, even across
-/// RAUW operations, but will null itself out if the value is destroyed. this
-/// is useful for advisory sorts of information, but should not be used as the
-/// key of a map (since the map would have to rearrange itself when the pointer
-/// changes).
+/// This is a value handle that points to a value, and nulls itself
+/// out if that value is deleted.
class WeakVH : public ValueHandleBase {
public:
WeakVH() : ValueHandleBase(Weak) {}
WeakVH(Value *P) : ValueHandleBase(Weak, P) {}
WeakVH(const WeakVH &RHS)
- : ValueHandleBase(Weak, RHS) {}
+ : ValueHandleBase(Weak, RHS) {}
WeakVH &operator=(const WeakVH &RHS) = default;
@@ -155,14 +162,63 @@ public:
// Specialize simplify_type to allow WeakVH to participate in
// dyn_cast, isa, etc.
template <> struct simplify_type<WeakVH> {
- typedef Value *SimpleType;
+ using SimpleType = Value *;
+
static SimpleType getSimplifiedValue(WeakVH &WVH) { return WVH; }
};
template <> struct simplify_type<const WeakVH> {
- typedef Value *SimpleType;
+ using SimpleType = Value *;
+
static SimpleType getSimplifiedValue(const WeakVH &WVH) { return WVH; }
};
+/// \brief Value handle that is nullable, but tries to track the Value.
+///
+/// This is a value handle that tries hard to point to a Value, even across
+/// RAUW operations, but will null itself out if the value is destroyed. this
+/// is useful for advisory sorts of information, but should not be used as the
+/// key of a map (since the map would have to rearrange itself when the pointer
+/// changes).
+class WeakTrackingVH : public ValueHandleBase {
+public:
+ WeakTrackingVH() : ValueHandleBase(WeakTracking) {}
+ WeakTrackingVH(Value *P) : ValueHandleBase(WeakTracking, P) {}
+ WeakTrackingVH(const WeakTrackingVH &RHS)
+ : ValueHandleBase(WeakTracking, RHS) {}
+
+ WeakTrackingVH &operator=(const WeakTrackingVH &RHS) = default;
+
+ Value *operator=(Value *RHS) {
+ return ValueHandleBase::operator=(RHS);
+ }
+ Value *operator=(const ValueHandleBase &RHS) {
+ return ValueHandleBase::operator=(RHS);
+ }
+
+ operator Value*() const {
+ return getValPtr();
+ }
+
+ bool pointsToAliveValue() const {
+ return ValueHandleBase::isValid(getValPtr());
+ }
+};
+
+// Specialize simplify_type to allow WeakTrackingVH to participate in
+// dyn_cast, isa, etc.
+template <> struct simplify_type<WeakTrackingVH> {
+ using SimpleType = Value *;
+
+ static SimpleType getSimplifiedValue(WeakTrackingVH &WVH) { return WVH; }
+};
+template <> struct simplify_type<const WeakTrackingVH> {
+ using SimpleType = Value *;
+
+ static SimpleType getSimplifiedValue(const WeakTrackingVH &WVH) {
+ return WVH;
+ }
+};
+
/// \brief Value handle that asserts if the Value is deleted.
///
/// This is a Value Handle that points to a value and asserts out if the value
@@ -184,7 +240,7 @@ class AssertingVH
: public ValueHandleBase
#endif
{
- friend struct DenseMapInfo<AssertingVH<ValueTy> >;
+ friend struct DenseMapInfo<AssertingVH<ValueTy>>;
#ifndef NDEBUG
Value *getRawValPtr() const { return ValueHandleBase::getValPtr(); }
@@ -230,20 +286,23 @@ public:
// Specialize DenseMapInfo to allow AssertingVH to participate in DenseMap.
template<typename T>
-struct DenseMapInfo<AssertingVH<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());
@@ -251,7 +310,7 @@ struct DenseMapInfo<AssertingVH<T> > {
};
template <typename T>
-struct isPodLike<AssertingVH<T> > {
+struct isPodLike<AssertingVH<T>> {
#ifdef NDEBUG
static const bool value = true;
#else
@@ -259,46 +318,43 @@ struct isPodLike<AssertingVH<T> > {
#endif
};
-
/// \brief Value handle that tracks a Value across RAUW.
///
/// TrackingVH is designed for situations where a client needs to hold a handle
/// to a Value (or subclass) across some operations which may move that value,
/// but should never destroy it or replace it with some unacceptable type.
///
-/// It is an error to do anything with a TrackingVH whose value has been
-/// destroyed, except to destruct it.
-///
/// It is an error to attempt to replace a value with one of a type which is
/// incompatible with any of its outstanding TrackingVHs.
-template<typename ValueTy>
-class TrackingVH : public ValueHandleBase {
- void CheckValidity() const {
- Value *VP = ValueHandleBase::getValPtr();
-
- // Null is always ok.
- if (!VP) return;
+///
+/// It is an error to read from a TrackingVH that does not point to a valid
+/// value. A TrackingVH is said to not point to a valid value if either it
+/// hasn't yet been assigned a value yet or because the value it was tracking
+/// has since been deleted.
+///
+/// Assigning a value to a TrackingVH is always allowed, even if said TrackingVH
+/// no longer points to a valid value.
+template <typename ValueTy> class TrackingVH {
+ WeakTrackingVH InnerHandle;
- // Check that this value is valid (i.e., it hasn't been deleted). We
- // explicitly delay this check until access to avoid requiring clients to be
- // unnecessarily careful w.r.t. destruction.
- assert(ValueHandleBase::isValid(VP) && "Tracked Value was deleted!");
+public:
+ ValueTy *getValPtr() const {
+ assert(InnerHandle.pointsToAliveValue() &&
+ "TrackingVH must be non-null and valid on dereference!");
// Check that the value is a member of the correct subclass. We would like
// to check this property on assignment for better debugging, but we don't
// want to require a virtual interface on this VH. Instead we allow RAUW to
// replace this value with a value of an invalid type, and check it here.
- assert(isa<ValueTy>(VP) &&
+ assert(isa<ValueTy>(InnerHandle) &&
"Tracked Value was replaced by one with an invalid type!");
+ return cast<ValueTy>(InnerHandle);
}
- ValueTy *getValPtr() const {
- CheckValidity();
- return (ValueTy*)ValueHandleBase::getValPtr();
- }
void setValPtr(ValueTy *P) {
- CheckValidity();
- ValueHandleBase::operator=(GetAsValue(P));
+ // Assigning to non-valid TrackingVH's are fine so we just unconditionally
+ // assign here.
+ InnerHandle = GetAsValue(P);
}
// Convert a ValueTy*, which may be const, to the type the base
@@ -307,8 +363,8 @@ class TrackingVH : public ValueHandleBase {
static Value *GetAsValue(const Value *V) { return const_cast<Value*>(V); }
public:
- TrackingVH() : ValueHandleBase(Tracking) {}
- TrackingVH(ValueTy *P) : ValueHandleBase(Tracking, GetAsValue(P)) {}
+ TrackingVH() = default;
+ TrackingVH(ValueTy *P) { setValPtr(P); }
operator ValueTy*() const {
return getValPtr();
@@ -353,7 +409,8 @@ public:
///
/// Called when this->getValPtr() is destroyed, inside ~Value(), so you
/// may call any non-virtual Value method on getValPtr(), but no subclass
- /// methods. If WeakVH were implemented as a CallbackVH, it would use this
+ /// methods. If WeakTrackingVH were implemented as a CallbackVH, it would use
+ /// this
/// method to call setValPtr(NULL). AssertingVH would use this method to
/// cause an assertion failure.
///
@@ -364,12 +421,142 @@ public:
/// \brief Callback for Value RAUW.
///
/// Called when this->getValPtr()->replaceAllUsesWith(new_value) is called,
- /// _before_ any of the uses have actually been replaced. If WeakVH were
+ /// _before_ any of the uses have actually been replaced. If WeakTrackingVH
+ /// were
/// implemented as a CallbackVH, it would use this method to call
/// setValPtr(new_value). AssertingVH would do nothing in this method.
virtual void allUsesReplacedWith(Value *) {}
};
-} // End llvm namespace
+/// Value handle that poisons itself if the Value is deleted.
+///
+/// This is a Value Handle that points to a value and poisons itself if the
+/// value is destroyed while the handle is still live. This is very useful for
+/// catching dangling pointer bugs where an \c AssertingVH cannot be used
+/// because the dangling handle needs to outlive the value without ever being
+/// used.
+///
+/// One particularly useful place to use this is as the Key of a map. Dangling
+/// pointer bugs often lead to really subtle bugs that only occur if another
+/// object happens to get allocated to the same address as the old one. Using
+/// a PoisoningVH ensures that an assert is triggered if looking up a new value
+/// in the map finds a handle from the old value.
+///
+/// Note that a PoisoningVH handle does *not* follow values across RAUW
+/// operations. This means that RAUW's need to explicitly update the
+/// PoisoningVH's as it moves. This is required because in non-assert mode this
+/// class turns into a trivial wrapper around a pointer.
+template <typename ValueTy>
+class PoisoningVH
+#ifndef NDEBUG
+ final : public CallbackVH
+#endif
+{
+ friend struct DenseMapInfo<PoisoningVH<ValueTy>>;
+
+ // Convert a ValueTy*, which may be const, to the raw Value*.
+ static Value *GetAsValue(Value *V) { return V; }
+ static Value *GetAsValue(const Value *V) { return const_cast<Value *>(V); }
+
+#ifndef NDEBUG
+ /// A flag tracking whether this value has been poisoned.
+ ///
+ /// On delete and RAUW, we leave the value pointer alone so that as a raw
+ /// pointer it produces the same value (and we fit into the same key of
+ /// a hash table, etc), but we poison the handle so that any top-level usage
+ /// will fail.
+ bool Poisoned = false;
+
+ Value *getRawValPtr() const { return ValueHandleBase::getValPtr(); }
+ void setRawValPtr(Value *P) { ValueHandleBase::operator=(P); }
+
+ /// Handle deletion by poisoning the handle.
+ void deleted() override {
+ assert(!Poisoned && "Tried to delete an already poisoned handle!");
+ Poisoned = true;
+ RemoveFromUseList();
+ }
+
+ /// Handle RAUW by poisoning the handle.
+ void allUsesReplacedWith(Value *) override {
+ assert(!Poisoned && "Tried to RAUW an already poisoned handle!");
+ Poisoned = true;
+ RemoveFromUseList();
+ }
+#else // NDEBUG
+ Value *ThePtr = nullptr;
+
+ Value *getRawValPtr() const { return ThePtr; }
+ void setRawValPtr(Value *P) { ThePtr = P; }
+#endif
+
+ ValueTy *getValPtr() const {
+ assert(!Poisoned && "Accessed a poisoned value handle!");
+ return static_cast<ValueTy *>(getRawValPtr());
+ }
+ void setValPtr(ValueTy *P) { setRawValPtr(GetAsValue(P)); }
+
+public:
+ PoisoningVH() = default;
+#ifndef NDEBUG
+ PoisoningVH(ValueTy *P) : CallbackVH(GetAsValue(P)) {}
+ PoisoningVH(const PoisoningVH &RHS)
+ : CallbackVH(RHS), Poisoned(RHS.Poisoned) {}
+
+ ~PoisoningVH() {
+ if (Poisoned)
+ clearValPtr();
+ }
+ PoisoningVH &operator=(const PoisoningVH &RHS) {
+ if (Poisoned)
+ clearValPtr();
+ CallbackVH::operator=(RHS);
+ Poisoned = RHS.Poisoned;
+ return *this;
+ }
+#else
+ PoisoningVH(ValueTy *P) : ThePtr(GetAsValue(P)) {}
#endif
+
+ operator ValueTy *() const { return getValPtr(); }
+
+ ValueTy *operator->() const { return getValPtr(); }
+ ValueTy &operator*() const { return *getValPtr(); }
+};
+
+// Specialize DenseMapInfo to allow PoisoningVH to participate in DenseMap.
+template <typename T> struct DenseMapInfo<PoisoningVH<T>> {
+ static inline PoisoningVH<T> getEmptyKey() {
+ PoisoningVH<T> Res;
+ Res.setRawValPtr(DenseMapInfo<Value *>::getEmptyKey());
+ return Res;
+ }
+
+ static inline PoisoningVH<T> getTombstoneKey() {
+ PoisoningVH<T> Res;
+ Res.setRawValPtr(DenseMapInfo<Value *>::getTombstoneKey());
+ return Res;
+ }
+
+ static unsigned getHashValue(const PoisoningVH<T> &Val) {
+ return DenseMapInfo<Value *>::getHashValue(Val.getRawValPtr());
+ }
+
+ static bool isEqual(const PoisoningVH<T> &LHS, const PoisoningVH<T> &RHS) {
+ return DenseMapInfo<Value *>::isEqual(LHS.getRawValPtr(),
+ RHS.getRawValPtr());
+ }
+};
+
+template <typename T> struct isPodLike<PoisoningVH<T>> {
+#ifdef NDEBUG
+ static const bool value = true;
+#else
+ static const bool value = false;
+#endif
+};
+
+} // end namespace llvm
+
+#endif // LLVM_IR_VALUEHANDLE_H
diff --git a/contrib/llvm/include/llvm/IR/ValueMap.h b/contrib/llvm/include/llvm/IR/ValueMap.h
index 9648e19..11d5823 100644
--- a/contrib/llvm/include/llvm/IR/ValueMap.h
+++ b/contrib/llvm/include/llvm/IR/ValueMap.h
@@ -46,7 +46,6 @@ namespace llvm {
template<typename KeyT, typename ValueT, typename Config>
class ValueMapCallbackVH;
-
template<typename DenseMapT, typename KeyT>
class ValueMapIterator;
template<typename DenseMapT, typename KeyT>
@@ -57,7 +56,7 @@ class ValueMapConstIterator;
/// as possible with future versions of ValueMap.
template<typename KeyT, typename MutexT = sys::Mutex>
struct ValueMapConfig {
- typedef MutexT mutex_type;
+ using mutex_type = MutexT;
/// If FollowRAUW is true, the ValueMap will update mappings on RAUW. If it's
/// false, the ValueMap will leave the original mapping in place.
@@ -87,21 +86,21 @@ template<typename KeyT, typename ValueT, typename Config =ValueMapConfig<KeyT>>
class ValueMap {
friend class ValueMapCallbackVH<KeyT, ValueT, Config>;
- typedef ValueMapCallbackVH<KeyT, ValueT, Config> ValueMapCVH;
- typedef DenseMap<ValueMapCVH, ValueT, DenseMapInfo<ValueMapCVH>> MapT;
- typedef DenseMap<const Metadata *, TrackingMDRef> MDMapT;
- typedef typename Config::ExtraData ExtraData;
+ using ValueMapCVH = ValueMapCallbackVH<KeyT, ValueT, Config>;
+ using MapT = DenseMap<ValueMapCVH, ValueT, DenseMapInfo<ValueMapCVH>>;
+ using MDMapT = DenseMap<const Metadata *, TrackingMDRef>;
+ using ExtraData = typename Config::ExtraData;
+
MapT Map;
Optional<MDMapT> MDMap;
ExtraData Data;
-
bool MayMapMetadata = true;
public:
- typedef KeyT key_type;
- typedef ValueT mapped_type;
- typedef std::pair<KeyT, ValueT> value_type;
- typedef unsigned size_type;
+ using key_type = KeyT;
+ using mapped_type = ValueT;
+ using value_type = std::pair<KeyT, ValueT>;
+ using size_type = unsigned;
explicit ValueMap(unsigned NumInitBuckets = 64)
: Map(NumInitBuckets), Data() {}
@@ -132,8 +131,9 @@ public:
return Where->second.get();
}
- typedef ValueMapIterator<MapT, KeyT> iterator;
- typedef ValueMapConstIterator<MapT, KeyT> const_iterator;
+ using iterator = ValueMapIterator<MapT, KeyT>;
+ using const_iterator = ValueMapConstIterator<MapT, KeyT>;
+
inline iterator begin() { return iterator(Map.begin()); }
inline iterator end() { return iterator(Map.end()); }
inline const_iterator begin() const { return const_iterator(Map.begin()); }
@@ -244,8 +244,8 @@ class ValueMapCallbackVH final : public CallbackVH {
friend class ValueMap<KeyT, ValueT, Config>;
friend struct DenseMapInfo<ValueMapCallbackVH>;
- typedef ValueMap<KeyT, ValueT, Config> ValueMapT;
- typedef typename std::remove_pointer<KeyT>::type KeySansPointerT;
+ using ValueMapT = ValueMap<KeyT, ValueT, Config>;
+ using KeySansPointerT = typename std::remove_pointer<KeyT>::type;
ValueMapT *Map;
@@ -298,7 +298,7 @@ public:
template<typename KeyT, typename ValueT, typename Config>
struct DenseMapInfo<ValueMapCallbackVH<KeyT, ValueT, Config>> {
- typedef ValueMapCallbackVH<KeyT, ValueT, Config> VH;
+ using VH = ValueMapCallbackVH<KeyT, ValueT, Config>;
static inline VH getEmptyKey() {
return VH(DenseMapInfo<Value *>::getEmptyKey());
@@ -330,8 +330,8 @@ class ValueMapIterator :
public std::iterator<std::forward_iterator_tag,
std::pair<KeyT, typename DenseMapT::mapped_type>,
ptrdiff_t> {
- typedef typename DenseMapT::iterator BaseT;
- typedef typename DenseMapT::mapped_type ValueT;
+ using BaseT = typename DenseMapT::iterator;
+ using ValueT = typename DenseMapT::mapped_type;
BaseT I;
@@ -344,7 +344,9 @@ public:
struct ValueTypeProxy {
const KeyT first;
ValueT& second;
+
ValueTypeProxy *operator->() { return this; }
+
operator std::pair<KeyT, ValueT>() const {
return std::make_pair(first, second);
}
@@ -380,8 +382,8 @@ class ValueMapConstIterator :
public std::iterator<std::forward_iterator_tag,
std::pair<KeyT, typename DenseMapT::mapped_type>,
ptrdiff_t> {
- typedef typename DenseMapT::const_iterator BaseT;
- typedef typename DenseMapT::mapped_type ValueT;
+ using BaseT = typename DenseMapT::const_iterator;
+ using ValueT = typename DenseMapT::mapped_type;
BaseT I;
diff --git a/contrib/llvm/include/llvm/IR/ValueSymbolTable.h b/contrib/llvm/include/llvm/IR/ValueSymbolTable.h
index 61a12db..26cbbfa 100644
--- a/contrib/llvm/include/llvm/IR/ValueSymbolTable.h
+++ b/contrib/llvm/include/llvm/IR/ValueSymbolTable.h
@@ -1,4 +1,4 @@
-//===-- llvm/ValueSymbolTable.h - Implement a Value Symtab ------*- C++ -*-===//
+//===- llvm/ValueSymbolTable.h - Implement a Value Symtab -------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -15,54 +15,59 @@
#define LLVM_IR_VALUESYMBOLTABLE_H
#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/IR/Value.h"
-#include "llvm/Support/DataTypes.h"
+#include <cstdint>
namespace llvm {
- template <typename ValueSubClass> class SymbolTableListTraits;
- template <unsigned InternalLen> class SmallString;
- class BasicBlock;
- class Function;
- class NamedMDNode;
- class Module;
- class StringRef;
+
+class Argument;
+class BasicBlock;
+class Function;
+class GlobalAlias;
+class GlobalIFunc;
+class GlobalVariable;
+class Instruction;
+template <unsigned InternalLen> class SmallString;
+template <typename ValueSubClass> class SymbolTableListTraits;
/// This class provides a symbol table of name/value pairs. It is essentially
/// a std::map<std::string,Value*> but has a controlled interface provided by
/// LLVM as well as ensuring uniqueness of names.
///
class ValueSymbolTable {
- friend class Value;
friend class SymbolTableListTraits<Argument>;
friend class SymbolTableListTraits<BasicBlock>;
- friend class SymbolTableListTraits<Instruction>;
friend class SymbolTableListTraits<Function>;
- friend class SymbolTableListTraits<GlobalVariable>;
friend class SymbolTableListTraits<GlobalAlias>;
friend class SymbolTableListTraits<GlobalIFunc>;
+ friend class SymbolTableListTraits<GlobalVariable>;
+ friend class SymbolTableListTraits<Instruction>;
+ friend class Value;
+
/// @name Types
/// @{
public:
/// @brief A mapping of names to values.
- typedef StringMap<Value*> ValueMap;
+ using ValueMap = StringMap<Value*>;
/// @brief An iterator over a ValueMap.
- typedef ValueMap::iterator iterator;
+ using iterator = ValueMap::iterator;
/// @brief A const_iterator over a ValueMap.
- typedef ValueMap::const_iterator const_iterator;
+ using const_iterator = ValueMap::const_iterator;
/// @}
/// @name Constructors
/// @{
-public:
- ValueSymbolTable() : vmap(0), LastUnique(0) {}
+
+ ValueSymbolTable() : vmap(0) {}
~ValueSymbolTable();
/// @}
/// @name Accessors
/// @{
-public:
+
/// This method finds the value with the given \p Name in the
/// the symbol table.
/// @returns the value associated with the \p Name
@@ -84,7 +89,7 @@ public:
/// @}
/// @name Iteration
/// @{
-public:
+
/// @brief Get an iterator that from the beginning of the symbol table.
inline iterator begin() { return vmap.begin(); }
@@ -122,13 +127,13 @@ private:
/// @}
/// @name Internal Data
/// @{
-private:
+
ValueMap vmap; ///< The map that holds the symbol table.
- mutable uint32_t LastUnique; ///< Counter for tracking unique names
+ mutable uint32_t LastUnique = 0; ///< Counter for tracking unique names
/// @}
};
-} // End llvm namespace
+} // end namespace llvm
-#endif
+#endif // LLVM_IR_VALUESYMBOLTABLE_H
diff --git a/contrib/llvm/include/llvm/IR/Verifier.h b/contrib/llvm/include/llvm/IR/Verifier.h
index 71f727c..15e52d9 100644
--- a/contrib/llvm/include/llvm/IR/Verifier.h
+++ b/contrib/llvm/include/llvm/IR/Verifier.h
@@ -21,13 +21,17 @@
#ifndef LLVM_IR_VERIFIER_H
#define LLVM_IR_VERIFIER_H
+#include "llvm/ADT/DenseMap.h"
#include "llvm/IR/PassManager.h"
+#include <utility>
namespace llvm {
+class APInt;
class Function;
class FunctionPass;
-class ModulePass;
+class Instruction;
+class MDNode;
class Module;
class raw_ostream;
struct VerifierSupport;
@@ -47,7 +51,7 @@ class TBAAVerifier {
/// the offset of the access. If zero, only a zero offset is allowed.
///
/// \c BitWidth has no meaning if \c IsInvalid is true.
- typedef std::pair<bool, unsigned> TBAABaseNodeSummary;
+ using TBAABaseNodeSummary = std::pair<bool, unsigned>;
DenseMap<const MDNode *, TBAABaseNodeSummary> TBAABaseNodes;
/// Maps an alleged scalar TBAA node to a boolean that is true if the said
@@ -101,12 +105,14 @@ FunctionPass *createVerifierPass(bool FatalErrors = true);
/// and debug info errors.
class VerifierAnalysis : public AnalysisInfoMixin<VerifierAnalysis> {
friend AnalysisInfoMixin<VerifierAnalysis>;
+
static AnalysisKey Key;
public:
struct Result {
bool IRBroken, DebugInfoBroken;
};
+
Result run(Module &M, ModuleAnalysisManager &);
Result run(Function &F, FunctionAnalysisManager &);
};
@@ -136,7 +142,6 @@ public:
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
};
+} // end namespace llvm
-} // End llvm namespace
-
-#endif
+#endif // LLVM_IR_VERIFIER_H
diff --git a/contrib/llvm/include/llvm/InitializePasses.h b/contrib/llvm/include/llvm/InitializePasses.h
index a34ebaf..39ac464 100644
--- a/contrib/llvm/include/llvm/InitializePasses.h
+++ b/contrib/llvm/include/llvm/InitializePasses.h
@@ -53,13 +53,13 @@ void initializeCoroutines(PassRegistry&);
void initializeCodeGen(PassRegistry&);
/// Initialize all passes linked into the GlobalISel library.
-void initializeGlobalISel(PassRegistry &Registry);
+void initializeGlobalISel(PassRegistry&);
/// Initialize all passes linked into the CodeGen library.
void initializeTarget(PassRegistry&);
void initializeAAEvalLegacyPassPass(PassRegistry&);
-void initializeAAResultsWrapperPassPass(PassRegistry &);
+void initializeAAResultsWrapperPassPass(PassRegistry&);
void initializeADCELegacyPassPass(PassRegistry&);
void initializeAddDiscriminatorsLegacyPassPass(PassRegistry&);
void initializeAddressSanitizerModulePass(PassRegistry&);
@@ -68,22 +68,22 @@ void initializeAliasSetPrinterPass(PassRegistry&);
void initializeAlignmentFromAssumptionsPass(PassRegistry&);
void initializeAlwaysInlinerLegacyPassPass(PassRegistry&);
void initializeArgPromotionPass(PassRegistry&);
-void initializeAssumptionCacheTrackerPass(PassRegistry &);
+void initializeAssumptionCacheTrackerPass(PassRegistry&);
void initializeAtomicExpandPass(PassRegistry&);
-void initializeBBVectorizePass(PassRegistry&);
-void initializeBDCELegacyPassPass(PassRegistry &);
+void initializeBDCELegacyPassPass(PassRegistry&);
void initializeBarrierNoopPass(PassRegistry&);
void initializeBasicAAWrapperPassPass(PassRegistry&);
void initializeBlockExtractorPassPass(PassRegistry&);
void initializeBlockFrequencyInfoWrapperPassPass(PassRegistry&);
void initializeBoundsCheckingPass(PassRegistry&);
+void initializeBranchCoalescingPass(PassRegistry&);
void initializeBranchFolderPassPass(PassRegistry&);
void initializeBranchProbabilityInfoWrapperPassPass(PassRegistry&);
void initializeBranchRelaxationPass(PassRegistry&);
void initializeBreakCriticalEdgesPass(PassRegistry&);
+void initializeCFGOnlyPrinterLegacyPassPass(PassRegistry&);
void initializeCFGOnlyViewerLegacyPassPass(PassRegistry&);
void initializeCFGPrinterLegacyPassPass(PassRegistry&);
-void initializeCFGOnlyPrinterLegacyPassPass(PassRegistry&);
void initializeCFGSimplifyPassPass(PassRegistry&);
void initializeCFGViewerLegacyPassPass(PassRegistry&);
void initializeCFLAndersAAWrapperPassPass(PassRegistry&);
@@ -91,14 +91,14 @@ void initializeCFLSteensAAWrapperPassPass(PassRegistry&);
void initializeCallGraphDOTPrinterPass(PassRegistry&);
void initializeCallGraphPrinterLegacyPassPass(PassRegistry&);
void initializeCallGraphViewerPass(PassRegistry&);
-void initializeCallGraphWrapperPassPass(PassRegistry &);
+void initializeCallGraphWrapperPassPass(PassRegistry&);
void initializeCodeGenPreparePass(PassRegistry&);
-void initializeCountingFunctionInserterPass(PassRegistry&);
void initializeConstantHoistingLegacyPassPass(PassRegistry&);
-void initializeConstantMergeLegacyPassPass(PassRegistry &);
+void initializeConstantMergeLegacyPassPass(PassRegistry&);
void initializeConstantPropagationPass(PassRegistry&);
void initializeCorrelatedValuePropagationPass(PassRegistry&);
void initializeCostModelAnalysisPass(PassRegistry&);
+void initializeCountingFunctionInserterPass(PassRegistry&);
void initializeCrossDSOCFIPass(PassRegistry&);
void initializeDAEPass(PassRegistry&);
void initializeDAHPass(PassRegistry&);
@@ -107,7 +107,7 @@ void initializeDSELegacyPassPass(PassRegistry&);
void initializeDataFlowSanitizerPass(PassRegistry&);
void initializeDeadInstEliminationPass(PassRegistry&);
void initializeDeadMachineInstructionElimPass(PassRegistry&);
-void initializeDelinearizationPass(PassRegistry &);
+void initializeDelinearizationPass(PassRegistry&);
void initializeDemandedBitsWrapperPassPass(PassRegistry&);
void initializeDependenceAnalysisPass(PassRegistry&);
void initializeDependenceAnalysisWrapperPassPass(PassRegistry&);
@@ -120,28 +120,30 @@ void initializeDomViewerPass(PassRegistry&);
void initializeDominanceFrontierWrapperPassPass(PassRegistry&);
void initializeDominatorTreeWrapperPassPass(PassRegistry&);
void initializeDwarfEHPreparePass(PassRegistry&);
-void initializeEarlyCSELegacyPassPass(PassRegistry &);
-void initializeEarlyCSEMemSSALegacyPassPass(PassRegistry &);
+void initializeEarlyCSELegacyPassPass(PassRegistry&);
+void initializeEarlyCSEMemSSALegacyPassPass(PassRegistry&);
void initializeEarlyIfConverterPass(PassRegistry&);
void initializeEdgeBundlesPass(PassRegistry&);
void initializeEfficiencySanitizerPass(PassRegistry&);
-void initializeEliminateAvailableExternallyLegacyPassPass(PassRegistry &);
-void initializeRAGreedyPass(PassRegistry&);
-void initializeGVNHoistLegacyPassPass(PassRegistry &);
+void initializeEliminateAvailableExternallyLegacyPassPass(PassRegistry&);
void initializeExpandISelPseudosPass(PassRegistry&);
void initializeExpandPostRAPass(PassRegistry&);
+void initializeExpandReductionsPass(PassRegistry&);
void initializeExternalAAWrapperPassPass(PassRegistry&);
+void initializeFEntryInserterPass(PassRegistry&);
void initializeFinalizeMachineBundlesPass(PassRegistry&);
void initializeFlattenCFGPassPass(PassRegistry&);
void initializeFloat2IntLegacyPassPass(PassRegistry&);
void initializeForceFunctionAttrsLegacyPassPass(PassRegistry&);
void initializeForwardControlFlowIntegrityPass(PassRegistry&);
-void initializeFuncletLayoutPass(PassRegistry &);
-void initializeFunctionImportLegacyPassPass(PassRegistry &);
+void initializeFuncletLayoutPass(PassRegistry&);
+void initializeFunctionImportLegacyPassPass(PassRegistry&);
void initializeGCMachineCodeAnalysisPass(PassRegistry&);
void initializeGCModuleInfoPass(PassRegistry&);
void initializeGCOVProfilerLegacyPassPass(PassRegistry&);
+void initializeGVNHoistLegacyPassPass(PassRegistry&);
void initializeGVNLegacyPassPass(PassRegistry&);
+void initializeGVNSinkLegacyPassPass(PassRegistry&);
void initializeGlobalDCELegacyPassPass(PassRegistry&);
void initializeGlobalMergePass(PassRegistry&);
void initializeGlobalOptLegacyPassPass(PassRegistry&);
@@ -149,56 +151,62 @@ void initializeGlobalSplitPass(PassRegistry&);
void initializeGlobalsAAWrapperPassPass(PassRegistry&);
void initializeGuardWideningLegacyPassPass(PassRegistry&);
void initializeIPCPPass(PassRegistry&);
-void initializeIPSCCPLegacyPassPass(PassRegistry &);
-void initializeIRTranslatorPass(PassRegistry &);
+void initializeIPSCCPLegacyPassPass(PassRegistry&);
+void initializeIRTranslatorPass(PassRegistry&);
void initializeIVUsersWrapperPassPass(PassRegistry&);
void initializeIfConverterPass(PassRegistry&);
void initializeImplicitNullChecksPass(PassRegistry&);
void initializeIndVarSimplifyLegacyPassPass(PassRegistry&);
void initializeInductiveRangeCheckEliminationPass(PassRegistry&);
+void initializeInferAddressSpacesPass(PassRegistry&);
void initializeInferFunctionAttrsLegacyPassPass(PassRegistry&);
void initializeInlineCostAnalysisPass(PassRegistry&);
void initializeInstCountPass(PassRegistry&);
void initializeInstNamerPass(PassRegistry&);
void initializeInstSimplifierPass(PassRegistry&);
-void initializeInstrProfilingLegacyPassPass(PassRegistry &);
+void initializeInstrProfilingLegacyPassPass(PassRegistry&);
void initializeInstructionCombiningPassPass(PassRegistry&);
-void initializeInstructionSelectPass(PassRegistry &);
-void initializeInterleavedAccessPass(PassRegistry &);
+void initializeInstructionSelectPass(PassRegistry&);
+void initializeInterleavedAccessPass(PassRegistry&);
void initializeInternalizeLegacyPassPass(PassRegistry&);
void initializeIntervalPartitionPass(PassRegistry&);
void initializeJumpThreadingPass(PassRegistry&);
-void initializeLCSSAWrapperPassPass(PassRegistry&);
void initializeLCSSAVerificationPassPass(PassRegistry&);
-void initializeLegacyLICMPassPass(PassRegistry&);
-void initializeLegacyLoopSinkPassPass(PassRegistry&);
-void initializeLazyBranchProbabilityInfoPassPass(PassRegistry&);
+void initializeLCSSAWrapperPassPass(PassRegistry&);
+void initializeLateCFGSimplifyPassPass(PassRegistry&);
void initializeLazyBlockFrequencyInfoPassPass(PassRegistry&);
+void initializeLazyBranchProbabilityInfoPassPass(PassRegistry&);
+void initializeLazyMachineBlockFrequencyInfoPassPass(PassRegistry&);
+void initializeLazyValueInfoPrinterPass(PassRegistry&);
void initializeLazyValueInfoWrapperPassPass(PassRegistry&);
+void initializeLegacyLICMPassPass(PassRegistry&);
+void initializeLegacyLoopSinkPassPass(PassRegistry&);
void initializeLegalizerPass(PassRegistry&);
void initializeLibCallsShrinkWrapLegacyPassPass(PassRegistry&);
void initializeLintPass(PassRegistry&);
void initializeLiveDebugValuesPass(PassRegistry&);
void initializeLiveDebugVariablesPass(PassRegistry&);
void initializeLiveIntervalsPass(PassRegistry&);
+void initializeLiveRangeShrinkPass(PassRegistry&);
void initializeLiveRegMatrixPass(PassRegistry&);
void initializeLiveStacksPass(PassRegistry&);
void initializeLiveVariablesPass(PassRegistry&);
-void initializeLoadCombinePass(PassRegistry&);
-void initializeLoaderPassPass(PassRegistry&);
void initializeLoadStoreVectorizerPass(PassRegistry&);
+void initializeLoaderPassPass(PassRegistry&);
void initializeLocalStackSlotPassPass(PassRegistry&);
+void initializeLocalizerPass(PassRegistry&);
void initializeLoopAccessLegacyAnalysisPass(PassRegistry&);
-void initializeLoopDataPrefetchLegacyPassPass(PassRegistry &);
+void initializeLoopDataPrefetchLegacyPassPass(PassRegistry&);
void initializeLoopDeletionLegacyPassPass(PassRegistry&);
void initializeLoopDistributeLegacyPass(PassRegistry&);
void initializeLoopExtractorPass(PassRegistry&);
void initializeLoopIdiomRecognizeLegacyPassPass(PassRegistry&);
void initializeLoopInfoWrapperPassPass(PassRegistry&);
void initializeLoopInstSimplifyLegacyPassPass(PassRegistry&);
-void initializeLoopInterchangePass(PassRegistry &);
+void initializeLoopInterchangePass(PassRegistry&);
void initializeLoopLoadEliminationPass(PassRegistry&);
void initializeLoopPassPass(PassRegistry&);
+void initializeLoopPredicationLegacyPassPass(PassRegistry&);
void initializeLoopRerollPass(PassRegistry&);
void initializeLoopRotateLegacyPassPass(PassRegistry&);
void initializeLoopSimplifyCFGLegacyPassPass(PassRegistry&);
@@ -208,8 +216,8 @@ void initializeLoopUnrollPass(PassRegistry&);
void initializeLoopUnswitchPass(PassRegistry&);
void initializeLoopVectorizePass(PassRegistry&);
void initializeLoopVersioningLICMPass(PassRegistry&);
-void initializeLoopVersioningPassPass(PassRegistry &);
-void initializeLowerAtomicLegacyPassPass(PassRegistry &);
+void initializeLoopVersioningPassPass(PassRegistry&);
+void initializeLowerAtomicLegacyPassPass(PassRegistry&);
void initializeLowerEmuTLSPass(PassRegistry&);
void initializeLowerExpectIntrinsicPass(PassRegistry&);
void initializeLowerGuardIntrinsicLegacyPassPass(PassRegistry&);
@@ -223,7 +231,7 @@ void initializeMachineBlockPlacementPass(PassRegistry&);
void initializeMachineBlockPlacementStatsPass(PassRegistry&);
void initializeMachineBranchProbabilityInfoPass(PassRegistry&);
void initializeMachineCSEPass(PassRegistry&);
-void initializeMachineCombinerPass(PassRegistry &);
+void initializeMachineCombinerPass(PassRegistry&);
void initializeMachineCopyPropagationPass(PassRegistry&);
void initializeMachineDominanceFrontierPass(PassRegistry&);
void initializeMachineDominatorTreePass(PassRegistry&);
@@ -231,6 +239,8 @@ void initializeMachineFunctionPrinterPassPass(PassRegistry&);
void initializeMachineLICMPass(PassRegistry&);
void initializeMachineLoopInfoPass(PassRegistry&);
void initializeMachineModuleInfoPass(PassRegistry&);
+void initializeMachineOptimizationRemarkEmitterPassPass(PassRegistry&);
+void initializeMachineOutlinerPass(PassRegistry&);
void initializeMachinePipelinerPass(PassRegistry&);
void initializeMachinePostDominatorTreePass(PassRegistry&);
void initializeMachineRegionInfoPassPass(PassRegistry&);
@@ -242,17 +252,17 @@ void initializeMemCpyOptLegacyPassPass(PassRegistry&);
void initializeMemDepPrinterPass(PassRegistry&);
void initializeMemDerefPrinterPass(PassRegistry&);
void initializeMemoryDependenceWrapperPassPass(PassRegistry&);
+void initializeMemorySSAPrinterLegacyPassPass(PassRegistry&);
void initializeMemorySSAWrapperPassPass(PassRegistry&);
-void initializeMemorySSAPrinterLegacyPassPass(PassRegistry &);
void initializeMemorySanitizerPass(PassRegistry&);
void initializeMergeFunctionsPass(PassRegistry&);
-void initializeMergedLoadStoreMotionLegacyPassPass(PassRegistry &);
+void initializeMergedLoadStoreMotionLegacyPassPass(PassRegistry&);
void initializeMetaRenamerPass(PassRegistry&);
void initializeModuleDebugInfoPrinterPass(PassRegistry&);
-void initializeModuleSummaryIndexWrapperPassPass(PassRegistry &);
-void initializeNameAnonGlobalLegacyPassPass(PassRegistry &);
-void initializeNaryReassociateLegacyPassPass(PassRegistry &);
-void initializeNewGVNPass(PassRegistry&);
+void initializeModuleSummaryIndexWrapperPassPass(PassRegistry&);
+void initializeNameAnonGlobalLegacyPassPass(PassRegistry&);
+void initializeNaryReassociateLegacyPassPass(PassRegistry&);
+void initializeNewGVNLegacyPassPass(PassRegistry&);
void initializeObjCARCAAWrapperPassPass(PassRegistry&);
void initializeObjCARCAPElimPass(PassRegistry&);
void initializeObjCARCContractPass(PassRegistry&);
@@ -260,17 +270,18 @@ void initializeObjCARCExpandPass(PassRegistry&);
void initializeObjCARCOptPass(PassRegistry&);
void initializeOptimizationRemarkEmitterWrapperPassPass(PassRegistry&);
void initializeOptimizePHIsPass(PassRegistry&);
-void initializePAEvalPass(PassRegistry &);
+void initializePAEvalPass(PassRegistry&);
void initializePEIPass(PassRegistry&);
void initializePGOIndirectCallPromotionLegacyPassPass(PassRegistry&);
void initializePGOInstrumentationGenLegacyPassPass(PassRegistry&);
void initializePGOInstrumentationUseLegacyPassPass(PassRegistry&);
+void initializePGOMemOPSizeOptLegacyPassPass(PassRegistry&);
void initializePHIEliminationPass(PassRegistry&);
-void initializePhysicalRegisterUsageInfoPass(PassRegistry &);
-void initializePartialInlinerLegacyPassPass(PassRegistry &);
-void initializePartiallyInlineLibCallsLegacyPassPass(PassRegistry &);
-void initializePatchableFunctionPass(PassRegistry &);
+void initializePartialInlinerLegacyPassPass(PassRegistry&);
+void initializePartiallyInlineLibCallsLegacyPassPass(PassRegistry&);
+void initializePatchableFunctionPass(PassRegistry&);
void initializePeepholeOptimizerPass(PassRegistry&);
+void initializePhysicalRegisterUsageInfoPass(PassRegistry&);
void initializePlaceBackedgeSafepointsImplPass(PassRegistry&);
void initializePlaceSafepointsPass(PassRegistry&);
void initializePostDomOnlyPrinterPass(PassRegistry&);
@@ -283,15 +294,19 @@ void initializePostOrderFunctionAttrsLegacyPassPass(PassRegistry&);
void initializePostRAHazardRecognizerPass(PassRegistry&);
void initializePostRASchedulerPass(PassRegistry&);
void initializePreISelIntrinsicLoweringLegacyPassPass(PassRegistry&);
+void initializePredicateInfoPrinterLegacyPassPass(PassRegistry&);
void initializePrintBasicBlockPassPass(PassRegistry&);
void initializePrintFunctionPassWrapperPass(PassRegistry&);
void initializePrintModulePassWrapperPass(PassRegistry&);
void initializeProcessImplicitDefsPass(PassRegistry&);
-void initializeProfileSummaryInfoWrapperPassPass(PassRegistry &);
-void initializePromoteLegacyPassPass(PassRegistry &);
+void initializeProfileSummaryInfoWrapperPassPass(PassRegistry&);
+void initializePromoteLegacyPassPass(PassRegistry&);
void initializePruneEHPass(PassRegistry&);
+void initializeRABasicPass(PassRegistry&);
+void initializeRAFastPass(PassRegistry&);
+void initializeRAGreedyPass(PassRegistry&);
void initializeReassociateLegacyPassPass(PassRegistry&);
-void initializeRegBankSelectPass(PassRegistry &);
+void initializeRegBankSelectPass(PassRegistry&);
void initializeRegToMemPass(PassRegistry&);
void initializeRegionInfoPassPass(PassRegistry&);
void initializeRegionOnlyPrinterPass(PassRegistry&);
@@ -299,26 +314,29 @@ void initializeRegionOnlyViewerPass(PassRegistry&);
void initializeRegionPrinterPass(PassRegistry&);
void initializeRegionViewerPass(PassRegistry&);
void initializeRegisterCoalescerPass(PassRegistry&);
-void initializeStripGCRelocatesPass(PassRegistry&);
void initializeRenameIndependentSubregsPass(PassRegistry&);
-void initializeResetMachineFunctionPass(PassRegistry &);
+void initializeResetMachineFunctionPass(PassRegistry&);
void initializeReversePostOrderFunctionAttrsLegacyPassPass(PassRegistry&);
void initializeRewriteStatepointsForGCPass(PassRegistry&);
void initializeRewriteSymbolsLegacyPassPass(PassRegistry&);
-void initializeSCCPLegacyPassPass(PassRegistry &);
+void initializeSafepointIRVerifierPass(PassRegistry&);
+void initializeSCCPLegacyPassPass(PassRegistry&);
void initializeSCEVAAWrapperPassPass(PassRegistry&);
void initializeSLPVectorizerPass(PassRegistry&);
void initializeSROALegacyPassPass(PassRegistry&);
-void initializeSafeStackPass(PassRegistry&);
+void initializeSafeStackLegacyPassPass(PassRegistry&);
void initializeSampleProfileLoaderLegacyPassPass(PassRegistry&);
void initializeSanitizerCoverageModulePass(PassRegistry&);
void initializeScalarEvolutionWrapperPassPass(PassRegistry&);
+void initializeScalarizeMaskedMemIntrinPass(PassRegistry&);
void initializeScalarizerPass(PassRegistry&);
+void initializeScavengerTestPass(PassRegistry&);
void initializeScopedNoAliasAAWrapperPassPass(PassRegistry&);
-void initializeSeparateConstOffsetFromGEPPass(PassRegistry &);
+void initializeSeparateConstOffsetFromGEPPass(PassRegistry&);
void initializeShadowStackGCLoweringPass(PassRegistry&);
-void initializeShrinkWrapPass(PassRegistry &);
+void initializeShrinkWrapPass(PassRegistry&);
void initializeSimpleInlinerPass(PassRegistry&);
+void initializeSimpleLoopUnswitchLegacyPassPass(PassRegistry&);
void initializeSingleLoopExtractorPass(PassRegistry&);
void initializeSinkingLegacyPassPass(PassRegistry&);
void initializeSjLjEHPreparePass(PassRegistry&);
@@ -329,19 +347,20 @@ void initializeStackColoringPass(PassRegistry&);
void initializeStackMapLivenessPass(PassRegistry&);
void initializeStackProtectorPass(PassRegistry&);
void initializeStackSlotColoringPass(PassRegistry&);
-void initializeStraightLineStrengthReducePass(PassRegistry &);
+void initializeStraightLineStrengthReducePass(PassRegistry&);
void initializeStripDeadDebugInfoPass(PassRegistry&);
void initializeStripDeadPrototypesLegacyPassPass(PassRegistry&);
void initializeStripDebugDeclarePass(PassRegistry&);
+void initializeStripGCRelocatesPass(PassRegistry&);
void initializeStripNonDebugSymbolsPass(PassRegistry&);
void initializeStripNonLineTableDebugInfoPass(PassRegistry&);
void initializeStripSymbolsPass(PassRegistry&);
void initializeStructurizeCFGPass(PassRegistry&);
void initializeTailCallElimPass(PassRegistry&);
void initializeTailDuplicatePassPass(PassRegistry&);
-void initializeTargetLibraryInfoWrapperPassPass(PassRegistry &);
+void initializeTargetLibraryInfoWrapperPassPass(PassRegistry&);
void initializeTargetPassConfigPass(PassRegistry&);
-void initializeTargetTransformInfoWrapperPassPass(PassRegistry &);
+void initializeTargetTransformInfoWrapperPassPass(PassRegistry&);
void initializeThreadSanitizerPass(PassRegistry&);
void initializeTwoAddressInstructionPassPass(PassRegistry&);
void initializeTypeBasedAAWrapperPassPass(PassRegistry&);
@@ -352,11 +371,11 @@ void initializeUnreachableMachineBlockElimPass(PassRegistry&);
void initializeVerifierLegacyPassPass(PassRegistry&);
void initializeVirtRegMapPass(PassRegistry&);
void initializeVirtRegRewriterPass(PassRegistry&);
-void initializeWholeProgramDevirtPass(PassRegistry &);
+void initializeWholeProgramDevirtPass(PassRegistry&);
void initializeWinEHPreparePass(PassRegistry&);
-void initializeWriteBitcodePassPass(PassRegistry &);
-void initializeWriteThinLTOBitcodePass(PassRegistry &);
-void initializeXRayInstrumentationPass(PassRegistry &);
+void initializeWriteBitcodePassPass(PassRegistry&);
+void initializeWriteThinLTOBitcodePass(PassRegistry&);
+void initializeXRayInstrumentationPass(PassRegistry&);
}
#endif
diff --git a/contrib/llvm/include/llvm/LTO/Caching.h b/contrib/llvm/include/llvm/LTO/Caching.h
index 3b96bd1..f5ec70e 100644
--- a/contrib/llvm/include/llvm/LTO/Caching.h
+++ b/contrib/llvm/include/llvm/LTO/Caching.h
@@ -24,12 +24,19 @@ namespace lto {
/// This type defines the callback to add a pre-existing native object file
/// (e.g. in a cache).
///
-/// File callbacks must be thread safe.
-typedef std::function<void(unsigned Task, StringRef Path)> AddFileFn;
+/// MB->getBufferIdentifier() is a valid path for the file at the time that it
+/// was opened, but clients should prefer to access MB directly in order to
+/// avoid a potential race condition.
+///
+/// Buffer callbacks must be thread safe.
+typedef std::function<void(unsigned Task, std::unique_ptr<MemoryBuffer> MB)>
+ AddBufferFn;
/// Create a local file system cache which uses the given cache directory and
-/// file callback.
-NativeObjectCache localCache(std::string CacheDirectoryPath, AddFileFn AddFile);
+/// file callback. This function also creates the cache directory if it does not
+/// already exist.
+Expected<NativeObjectCache> localCache(StringRef CacheDirectoryPath,
+ AddBufferFn AddBuffer);
} // namespace lto
} // namespace llvm
diff --git a/contrib/llvm/include/llvm/LTO/Config.h b/contrib/llvm/include/llvm/LTO/Config.h
index 3aa48c9..73106f7 100644
--- a/contrib/llvm/include/llvm/LTO/Config.h
+++ b/contrib/llvm/include/llvm/LTO/Config.h
@@ -17,6 +17,7 @@
#include "llvm/IR/DiagnosticInfo.h"
#include "llvm/Support/CodeGen.h"
+#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
#include <functional>
@@ -38,12 +39,16 @@ struct Config {
std::string CPU;
TargetOptions Options;
std::vector<std::string> MAttrs;
- Reloc::Model RelocModel = Reloc::PIC_;
+ Optional<Reloc::Model> RelocModel = Reloc::PIC_;
CodeModel::Model CodeModel = CodeModel::Default;
CodeGenOpt::Level CGOptLevel = CodeGenOpt::Default;
+ TargetMachine::CodeGenFileType CGFileType = TargetMachine::CGFT_ObjectFile;
unsigned OptLevel = 2;
bool DisableVerify = false;
+ /// Use the new pass manager
+ bool UseNewPM = false;
+
/// Disable entirely the optimizer, including importing for ThinLTO
bool CodeGenOnly = false;
@@ -68,6 +73,12 @@ struct Config {
/// Sample PGO profile path.
std::string SampleProfile;
+ /// Optimization remarks file path.
+ std::string RemarksFilename = "";
+
+ /// Whether to emit optimization remarks with hotness informations.
+ bool RemarksWithHotness = false;
+
bool ShouldDiscardValueNames = true;
DiagnosticHandlerFunction DiagHandler;
diff --git a/contrib/llvm/include/llvm/LTO/LTO.h b/contrib/llvm/include/llvm/LTO/LTO.h
index 78ac73a..d678a68 100644
--- a/contrib/llvm/include/llvm/LTO/LTO.h
+++ b/contrib/llvm/include/llvm/LTO/LTO.h
@@ -19,12 +19,14 @@
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringSet.h"
-#include "llvm/CodeGen/Analysis.h"
+#include "llvm/Analysis/ObjectUtils.h"
#include "llvm/IR/DiagnosticInfo.h"
#include "llvm/IR/ModuleSummaryIndex.h"
#include "llvm/LTO/Config.h"
#include "llvm/Linker/IRMover.h"
-#include "llvm/Object/IRObjectFile.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"
@@ -68,25 +70,35 @@ std::string getThinLTOOutputFile(const std::string &Path,
const std::string &OldPrefix,
const std::string &NewPrefix);
+/// Setup optimization remarks.
+Expected<std::unique_ptr<tool_output_file>>
+setupOptimizationRemarks(LLVMContext &Context, StringRef LTORemarksFilename,
+ bool LTOPassRemarksWithHotness, int Count = -1);
+
class LTO;
struct SymbolResolution;
class ThinBackendProc;
-/// An input file. This is a wrapper for ModuleSymbolTable that exposes only the
+/// An input file. This is a symbol table wrapper that only exposes the
/// information that an LTO client should need in order to do symbol resolution.
class InputFile {
+public:
+ class Symbol;
+
+private:
// FIXME: Remove LTO class friendship once we have bitcode symbol tables.
friend LTO;
InputFile() = default;
- // FIXME: Remove the LLVMContext once we have bitcode symbol tables.
- LLVMContext Ctx;
- struct InputModule;
- std::vector<InputModule> Mods;
- ModuleSymbolTable SymTab;
+ std::vector<BitcodeModule> Mods;
+ SmallVector<char, 0> Strtab;
+ std::vector<Symbol> Symbols;
+
+ // [begin, end) for each module
+ std::vector<std::pair<size_t, size_t>> ModuleSymIndices;
- std::vector<StringRef> Comdats;
- DenseMap<const Comdat *, unsigned> ComdatMap;
+ StringRef TargetTriple, SourceFileName, COFFLinkerOpts;
+ std::vector<StringRef> ComdatTable;
public:
~InputFile();
@@ -94,143 +106,52 @@ public:
/// Create an InputFile.
static Expected<std::unique_ptr<InputFile>> create(MemoryBufferRef Object);
- class symbol_iterator;
-
- /// This is a wrapper for ArrayRef<ModuleSymbolTable::Symbol>::iterator that
- /// exposes only the information that an LTO client should need in order to do
- /// symbol resolution.
- ///
- /// This object is ephemeral; it is only valid as long as an iterator obtained
- /// from symbols() refers to it.
- class Symbol {
- friend symbol_iterator;
+ /// The purpose of this class is to only expose the symbol information that an
+ /// LTO client should need in order to do symbol resolution.
+ class Symbol : irsymtab::Symbol {
friend LTO;
- ArrayRef<ModuleSymbolTable::Symbol>::iterator I;
- const ModuleSymbolTable &SymTab;
- const InputFile *File;
- uint32_t Flags;
- SmallString<64> Name;
-
- bool shouldSkip() {
- return !(Flags & object::BasicSymbolRef::SF_Global) ||
- (Flags & object::BasicSymbolRef::SF_FormatSpecific);
- }
-
- void skip() {
- ArrayRef<ModuleSymbolTable::Symbol>::iterator E = SymTab.symbols().end();
- while (I != E) {
- Flags = SymTab.getSymbolFlags(*I);
- if (!shouldSkip())
- break;
- ++I;
- }
- if (I == E)
- return;
-
- Name.clear();
- {
- raw_svector_ostream OS(Name);
- SymTab.printSymbolName(OS, *I);
- }
- }
-
- bool isGV() const { return I->is<GlobalValue *>(); }
- GlobalValue *getGV() const { return I->get<GlobalValue *>(); }
-
- public:
- Symbol(ArrayRef<ModuleSymbolTable::Symbol>::iterator I,
- const ModuleSymbolTable &SymTab, const InputFile *File)
- : I(I), SymTab(SymTab), File(File) {
- skip();
- }
-
- /// Returns the mangled name of the global.
- StringRef getName() const { return Name; }
-
- uint32_t getFlags() const { return Flags; }
- GlobalValue::VisibilityTypes getVisibility() const {
- if (isGV())
- return getGV()->getVisibility();
- return GlobalValue::DefaultVisibility;
- }
- bool canBeOmittedFromSymbolTable() const {
- return isGV() && llvm::canBeOmittedFromSymbolTable(getGV());
- }
- bool isTLS() const {
- // FIXME: Expose a thread-local flag for module asm symbols.
- return isGV() && getGV()->isThreadLocal();
- }
-
- // Returns the index of the comdat this symbol is in or -1 if the symbol
- // is not in a comdat.
- // FIXME: We have to return Expected<int> because aliases point to an
- // arbitrary ConstantExpr and that might not actually be a constant. That
- // means we might not be able to find what an alias is aliased to and
- // so find its comdat.
- Expected<int> getComdatIndex() const;
-
- uint64_t getCommonSize() const {
- assert(Flags & object::BasicSymbolRef::SF_Common);
- if (!isGV())
- return 0;
- return getGV()->getParent()->getDataLayout().getTypeAllocSize(
- getGV()->getType()->getElementType());
- }
- unsigned getCommonAlignment() const {
- assert(Flags & object::BasicSymbolRef::SF_Common);
- if (!isGV())
- return 0;
- return getGV()->getAlignment();
- }
- };
-
- class symbol_iterator {
- Symbol Sym;
-
public:
- symbol_iterator(ArrayRef<ModuleSymbolTable::Symbol>::iterator I,
- const ModuleSymbolTable &SymTab, const InputFile *File)
- : Sym(I, SymTab, File) {}
-
- symbol_iterator &operator++() {
- ++Sym.I;
- Sym.skip();
- return *this;
- }
-
- symbol_iterator operator++(int) {
- symbol_iterator I = *this;
- ++*this;
- return I;
- }
-
- const Symbol &operator*() const { return Sym; }
- const Symbol *operator->() const { return &Sym; }
-
- bool operator!=(const symbol_iterator &Other) const {
- return Sym.I != Other.Sym.I;
- }
+ Symbol(const irsymtab::Symbol &S) : irsymtab::Symbol(S) {}
+
+ using irsymtab::Symbol::isUndefined;
+ using irsymtab::Symbol::isCommon;
+ using irsymtab::Symbol::isWeak;
+ using irsymtab::Symbol::isIndirect;
+ using irsymtab::Symbol::getName;
+ using irsymtab::Symbol::getVisibility;
+ using irsymtab::Symbol::canBeOmittedFromSymbolTable;
+ using irsymtab::Symbol::isTLS;
+ using irsymtab::Symbol::getComdatIndex;
+ using irsymtab::Symbol::getCommonSize;
+ using irsymtab::Symbol::getCommonAlignment;
+ using irsymtab::Symbol::getCOFFWeakExternalFallback;
+ using irsymtab::Symbol::isExecutable;
};
/// A range over the symbols in this InputFile.
- iterator_range<symbol_iterator> symbols() {
- return llvm::make_range(
- symbol_iterator(SymTab.symbols().begin(), SymTab, this),
- symbol_iterator(SymTab.symbols().end(), SymTab, this));
- }
+ ArrayRef<Symbol> symbols() const { return Symbols; }
+
+ /// Returns linker options specified in the input file.
+ StringRef getCOFFLinkerOpts() const { return COFFLinkerOpts; }
/// Returns the path to the InputFile.
StringRef getName() const;
+ /// Returns the input file's target triple.
+ StringRef getTargetTriple() const { return TargetTriple; }
+
/// Returns the source file path specified at compile time.
- StringRef getSourceFileName() const;
+ StringRef getSourceFileName() const { return SourceFileName; }
// Returns a table with all the comdats used by this file.
- ArrayRef<StringRef> getComdatTable() const { return Comdats; }
+ ArrayRef<StringRef> getComdatTable() const { return ComdatTable; }
private:
- iterator_range<symbol_iterator> module_symbols(InputModule &IM);
+ ArrayRef<Symbol> module_symbols(unsigned I) const {
+ const auto &Indices = ModuleSymIndices[I];
+ return {Symbols.data() + Indices.first, Symbols.data() + Indices.second};
+ }
};
/// This class wraps an output stream for a native object. Most clients should
@@ -360,6 +281,16 @@ private:
bool HasModule = false;
std::unique_ptr<Module> CombinedModule;
std::unique_ptr<IRMover> Mover;
+
+ // This stores the information about a regular LTO module that we have added
+ // to the link. It will either be linked immediately (for modules without
+ // summaries) or after summary-based dead stripping (for modules with
+ // summaries).
+ struct AddedModule {
+ std::unique_ptr<Module> M;
+ std::vector<GlobalValue *> Keep;
+ };
+ std::vector<AddedModule> ModsWithSummaries;
} RegularLTO;
struct ThinLTOState {
@@ -382,9 +313,10 @@ private:
/// The unmangled name of the global.
std::string IRName;
- /// Keep track if the symbol is visible outside of ThinLTO (i.e. in
- /// either a regular object or the regular LTO partition).
- bool VisibleOutsideThinLTO = false;
+ /// Keep track if the symbol is visible outside of a module with a summary
+ /// (i.e. in either a regular object or a regular LTO module without a
+ /// summary).
+ bool VisibleOutsideSummary = false;
bool UnnamedAddr = true;
@@ -418,20 +350,24 @@ private:
// Global mapping from mangled symbol names to resolutions.
StringMap<GlobalResolution> GlobalResolutions;
- void addSymbolToGlobalRes(SmallPtrSet<GlobalValue *, 8> &Used,
- const InputFile::Symbol &Sym, SymbolResolution Res,
- unsigned Partition);
+ void addModuleToGlobalRes(ArrayRef<InputFile::Symbol> Syms,
+ ArrayRef<SymbolResolution> Res, unsigned Partition,
+ bool InSummary);
// These functions take a range of symbol resolutions [ResI, ResE) and consume
// the resolutions used by a single input module by incrementing ResI. After
// these functions return, [ResI, ResE) will refer to the resolution range for
// the remaining modules in the InputFile.
- Error addModule(InputFile &Input, InputFile::InputModule &IM,
+ Error addModule(InputFile &Input, unsigned ModI,
const SymbolResolution *&ResI, const SymbolResolution *ResE);
- Error addRegularLTO(BitcodeModule BM, const SymbolResolution *&ResI,
- const SymbolResolution *ResE);
- Error addThinLTO(BitcodeModule BM, Module &M,
- iterator_range<InputFile::symbol_iterator> Syms,
+
+ Expected<RegularLTOState::AddedModule>
+ addRegularLTO(BitcodeModule BM, ArrayRef<InputFile::Symbol> Syms,
+ const SymbolResolution *&ResI, const SymbolResolution *ResE);
+ Error linkRegularLTO(RegularLTOState::AddedModule Mod,
+ bool LivenessFromIndex);
+
+ Error addThinLTO(BitcodeModule BM, ArrayRef<InputFile::Symbol> Syms,
const SymbolResolution *&ResI, const SymbolResolution *ResE);
Error runRegularLTO(AddStreamFn AddStream);
@@ -445,8 +381,9 @@ private:
/// each global symbol based on its internal resolution of that symbol.
struct SymbolResolution {
SymbolResolution()
- : Prevailing(0), FinalDefinitionInLinkageUnit(0), VisibleToRegularObj(0) {
- }
+ : Prevailing(0), FinalDefinitionInLinkageUnit(0), VisibleToRegularObj(0),
+ LinkerRedefined(0) {}
+
/// The linker has chosen this definition of the symbol.
unsigned Prevailing : 1;
@@ -456,6 +393,10 @@ struct SymbolResolution {
/// The definition of this symbol is visible outside of the LTO unit.
unsigned VisibleToRegularObj : 1;
+
+ /// Linker redefined version of the symbol which appeared in -wrap or -defsym
+ /// linker option.
+ unsigned LinkerRedefined : 1;
};
} // namespace lto
diff --git a/contrib/llvm/include/llvm/LTO/LTOBackend.h b/contrib/llvm/include/llvm/LTO/LTOBackend.h
index 933503a..d4743f6 100644
--- a/contrib/llvm/include/llvm/LTO/LTOBackend.h
+++ b/contrib/llvm/include/llvm/LTO/LTOBackend.h
@@ -34,14 +34,15 @@ class Target;
namespace lto {
-/// Runs a regular LTO backend.
+/// Runs a regular LTO backend. The regular LTO backend can also act as the
+/// regular LTO phase of ThinLTO, which may need to access the combined index.
Error backend(Config &C, AddStreamFn AddStream,
unsigned ParallelCodeGenParallelismLevel,
- std::unique_ptr<Module> M);
+ std::unique_ptr<Module> M, ModuleSummaryIndex &CombinedIndex);
/// Runs a ThinLTO backend.
Error thinBackend(Config &C, unsigned Task, AddStreamFn AddStream, Module &M,
- ModuleSummaryIndex &CombinedIndex,
+ const ModuleSummaryIndex &CombinedIndex,
const FunctionImporter::ImportMapTy &ImportList,
const GVSummaryMapTy &DefinedGlobals,
MapVector<StringRef, BitcodeModule> &ModuleMap);
diff --git a/contrib/llvm/include/llvm/LTO/legacy/LTOCodeGenerator.h b/contrib/llvm/include/llvm/LTO/legacy/LTOCodeGenerator.h
index f146821..952875f 100644
--- a/contrib/llvm/include/llvm/LTO/legacy/LTOCodeGenerator.h
+++ b/contrib/llvm/include/llvm/LTO/legacy/LTOCodeGenerator.h
@@ -41,6 +41,7 @@
#include "llvm/ADT/StringSet.h"
#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/Module.h"
+#include "llvm/Support/Error.h"
#include "llvm/Support/ToolOutputFile.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
@@ -174,6 +175,10 @@ struct LTOCodeGenerator {
/// Calls \a verifyMergedModuleOnce().
bool compileOptimized(ArrayRef<raw_pwrite_stream *> Out);
+ /// Enable the Freestanding mode: indicate that the optimizer should not
+ /// assume builtins are present on the target.
+ void setFreestanding(bool Enabled) { Freestanding = Enabled; }
+
void setDiagnosticHandler(lto_diagnostic_handler_t, void *);
LLVMContext &getContext() { return Context; }
@@ -206,7 +211,6 @@ private:
void emitError(const std::string &ErrMsg);
void emitWarning(const std::string &ErrMsg);
- bool setupOptimizationRemarks();
void finishOptimizationRemarks();
LLVMContext &Context;
@@ -237,6 +241,7 @@ private:
bool ShouldRestoreGlobalsLinkage = false;
TargetMachine::CodeGenFileType FileType = TargetMachine::CGFT_ObjectFile;
std::unique_ptr<tool_output_file> DiagnosticOutputFile;
+ bool Freestanding = false;
};
}
#endif
diff --git a/contrib/llvm/include/llvm/LTO/legacy/LTOModule.h b/contrib/llvm/include/llvm/LTO/legacy/LTOModule.h
index 2a87585..017e223 100644
--- a/contrib/llvm/include/llvm/LTO/legacy/LTOModule.h
+++ b/contrib/llvm/include/llvm/LTO/legacy/LTOModule.h
@@ -158,7 +158,7 @@ public:
private:
/// Parse metadata from the module
- // FIXME: it only parses "Linker Options" metadata at the moment
+ // FIXME: it only parses "llvm.linker.options" metadata at the moment
void parseMetadata();
/// Parse the symbols from the module and model-level ASM and add them to
diff --git a/contrib/llvm/include/llvm/LTO/legacy/ThinLTOCodeGenerator.h b/contrib/llvm/include/llvm/LTO/legacy/ThinLTOCodeGenerator.h
index 0cc3b26..14f0c48 100644
--- a/contrib/llvm/include/llvm/LTO/legacy/ThinLTOCodeGenerator.h
+++ b/contrib/llvm/include/llvm/LTO/legacy/ThinLTOCodeGenerator.h
@@ -20,6 +20,7 @@
#include "llvm/ADT/StringSet.h"
#include "llvm/ADT/Triple.h"
#include "llvm/IR/ModuleSummaryIndex.h"
+#include "llvm/Support/CachePruning.h"
#include "llvm/Support/CodeGen.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Target/TargetOptions.h"
@@ -140,9 +141,7 @@ public:
struct CachingOptions {
std::string Path; // Path to the cache, empty to disable.
- int PruningInterval = 1200; // seconds, -1 to disable pruning.
- unsigned int Expiration = 7 * 24 * 3600; // seconds (1w default).
- unsigned MaxPercentageOfAvailableSpace = 75; // percentage.
+ CachePruningPolicy Policy;
};
/// Provide a path to a directory where to store the cached files for
@@ -153,14 +152,14 @@ public:
/// negative value (default) to disable pruning. A value of 0 will be ignored.
void setCachePruningInterval(int Interval) {
if (Interval)
- CacheOptions.PruningInterval = Interval;
+ CacheOptions.Policy.Interval = std::chrono::seconds(Interval);
}
/// Cache policy: expiration (in seconds) for an entry.
/// A value of 0 will be ignored.
void setCacheEntryExpiration(unsigned Expiration) {
if (Expiration)
- CacheOptions.Expiration = Expiration;
+ CacheOptions.Policy.Expiration = std::chrono::seconds(Expiration);
}
/**
@@ -178,7 +177,7 @@ public:
*/
void setMaxCacheSizeRelativeToAvailableSpace(unsigned Percentage) {
if (Percentage)
- CacheOptions.MaxPercentageOfAvailableSpace = Percentage;
+ CacheOptions.Policy.MaxSizePercentageOfAvailableSpace = Percentage;
}
/**@}*/
@@ -206,6 +205,10 @@ public:
TMBuilder.Options = std::move(Options);
}
+ /// Enable the Freestanding mode: indicate that the optimizer should not
+ /// assume builtins are present on the target.
+ void setFreestanding(bool Enabled) { Freestanding = Enabled; }
+
/// CodeModel
void setCodePICModel(Optional<Reloc::Model> Model) {
TMBuilder.RelocModel = Model;
@@ -323,6 +326,10 @@ private:
/// importing or optimization.
bool CodeGenOnly = false;
+ /// Flag to indicate that the optimizer should not assume builtins are present
+ /// on the target.
+ bool Freestanding = false;
+
/// IR Optimization Level [0-3].
unsigned OptLevel = 3;
};
diff --git a/contrib/llvm/include/llvm/LinkAllIR.h b/contrib/llvm/include/llvm/LinkAllIR.h
index f078c73..de1d305 100644
--- a/contrib/llvm/include/llvm/LinkAllIR.h
+++ b/contrib/llvm/include/llvm/LinkAllIR.h
@@ -16,13 +16,13 @@
#ifndef LLVM_LINKALLIR_H
#define LLVM_LINKALLIR_H
+#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/IR/InlineAsm.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Verifier.h"
-#include "llvm/Support/Dwarf.h"
#include "llvm/Support/DynamicLibrary.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/Memory.h"
diff --git a/contrib/llvm/include/llvm/LinkAllPasses.h b/contrib/llvm/include/llvm/LinkAllPasses.h
index e50137f..d07c15c 100644
--- a/contrib/llvm/include/llvm/LinkAllPasses.h
+++ b/contrib/llvm/include/llvm/LinkAllPasses.h
@@ -16,8 +16,8 @@
#define LLVM_LINKALLPASSES_H
#include "llvm/ADT/Statistic.h"
-#include "llvm/Analysis/AliasSetTracker.h"
#include "llvm/Analysis/AliasAnalysisEvaluator.h"
+#include "llvm/Analysis/AliasSetTracker.h"
#include "llvm/Analysis/BasicAliasAnalysis.h"
#include "llvm/Analysis/CFLAndersAliasAnalysis.h"
#include "llvm/Analysis/CFLSteensAliasAnalysis.h"
@@ -38,6 +38,7 @@
#include "llvm/CodeGen/Passes.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/IRPrintingPasses.h"
+#include "llvm/Support/Valgrind.h"
#include "llvm/Transforms/IPO.h"
#include "llvm/Transforms/IPO/AlwaysInliner.h"
#include "llvm/Transforms/IPO/FunctionAttrs.h"
@@ -48,7 +49,6 @@
#include "llvm/Transforms/Utils/SymbolRewriter.h"
#include "llvm/Transforms/Utils/UnifyFunctionExitNodes.h"
#include "llvm/Transforms/Vectorize.h"
-#include "llvm/Support/Valgrind.h"
#include <cstdlib>
namespace {
@@ -75,6 +75,7 @@ namespace {
(void) llvm::createCallGraphDOTPrinterPass();
(void) llvm::createCallGraphViewerPass();
(void) llvm::createCFGSimplificationPass();
+ (void) llvm::createLateCFGSimplificationPass();
(void) llvm::createCFLAndersAAWrapperPass();
(void) llvm::createCFLSteensAAWrapperPass();
(void) llvm::createStructurizeCFGPass();
@@ -96,6 +97,7 @@ namespace {
(void) llvm::createPGOInstrumentationGenLegacyPass();
(void) llvm::createPGOInstrumentationUseLegacyPass();
(void) llvm::createPGOIndirectCallPromotionLegacyPass();
+ (void) llvm::createPGOMemOPSizeOptLegacyPass();
(void) llvm::createInstrProfilingLegacyPass();
(void) llvm::createFunctionImportPass();
(void) llvm::createFunctionInliningPass();
@@ -116,6 +118,7 @@ namespace {
(void) llvm::createLazyValueInfoPass();
(void) llvm::createLoopExtractorPass();
(void) llvm::createLoopInterchangePass();
+ (void) llvm::createLoopPredicationPass();
(void) llvm::createLoopSimplifyPass();
(void) llvm::createLoopSimplifyCFGPass();
(void) llvm::createLoopStrengthReducePass();
@@ -192,7 +195,6 @@ namespace {
(void) llvm::createLoopVectorizePass();
(void) llvm::createSLPVectorizerPass();
(void) llvm::createLoadStoreVectorizerPass();
- (void) llvm::createBBVectorizePass();
(void) llvm::createPartiallyInlineLibCallsPass();
(void) llvm::createScalarizerPass();
(void) llvm::createSeparateConstOffsetFromGEPPass();
@@ -203,6 +205,7 @@ namespace {
(void) llvm::createMemDerefPrinter();
(void) llvm::createFloat2IntPass();
(void) llvm::createEliminateAvailableExternallyPass();
+ (void) llvm::createScalarizeMaskedMemIntrinPass();
(void)new llvm::IntervalPartition();
(void)new llvm::ScalarEvolutionWrapperPass();
diff --git a/contrib/llvm/include/llvm/Linker/IRMover.h b/contrib/llvm/include/llvm/Linker/IRMover.h
index 2a187cb..235ada4 100644
--- a/contrib/llvm/include/llvm/Linker/IRMover.h
+++ b/contrib/llvm/include/llvm/Linker/IRMover.h
@@ -71,15 +71,11 @@ public:
/// not present in ValuesToLink. The GlobalValue and a ValueAdder callback
/// are passed as an argument, and the callback is expected to be called
/// if the GlobalValue needs to be added to the \p ValuesToLink and linked.
- /// - \p LinkModuleInlineAsm is true if the ModuleInlineAsm string in Src
- /// should be linked with (concatenated into) the ModuleInlineAsm string
- /// for the destination module. It should be true for full LTO, but not
- /// when importing for ThinLTO, otherwise we can have duplicate symbols.
/// - \p IsPerformingImport is true when this IR link is to perform ThinLTO
/// function importing from Src.
Error move(std::unique_ptr<Module> Src, ArrayRef<GlobalValue *> ValuesToLink,
std::function<void(GlobalValue &GV, ValueAdder Add)> AddLazyFor,
- bool LinkModuleInlineAsm, bool IsPerformingImport);
+ bool IsPerformingImport);
Module &getModule() { return Composite; }
private:
diff --git a/contrib/llvm/include/llvm/Linker/Linker.h b/contrib/llvm/include/llvm/Linker/Linker.h
index b077c37..628e011 100644
--- a/contrib/llvm/include/llvm/Linker/Linker.h
+++ b/contrib/llvm/include/llvm/Linker/Linker.h
@@ -10,6 +10,7 @@
#ifndef LLVM_LINKER_LINKER_H
#define LLVM_LINKER_LINKER_H
+#include "llvm/ADT/StringSet.h"
#include "llvm/Linker/IRMover.h"
namespace llvm {
@@ -29,10 +30,6 @@ public:
None = 0,
OverrideFromSrc = (1 << 0),
LinkOnlyNeeded = (1 << 1),
- InternalizeLinkedSymbols = (1 << 2),
- /// Don't force link referenced linkonce definitions, import declaration.
- DontForceLinkLinkonceODR = (1 << 3)
-
};
Linker(Module &M);
@@ -41,16 +38,20 @@ public:
///
/// Passing OverrideSymbols as true will have symbols from Src
/// shadow those in the Dest.
- /// For ThinLTO function importing/exporting the \p ModuleSummaryIndex
- /// is passed. If \p GlobalsToImport is provided, only the globals that
- /// are part of the set will be imported from the source module.
+ ///
+ /// Passing InternalizeCallback will have the linker call the function with
+ /// the new module and a list of global value names to be internalized by the
+ /// callback.
///
/// Returns true on error.
bool linkInModule(std::unique_ptr<Module> Src, unsigned Flags = Flags::None,
- DenseSet<const GlobalValue *> *GlobalsToImport = nullptr);
+ std::function<void(Module &, const StringSet<> &)>
+ InternalizeCallback = {});
static bool linkModules(Module &Dest, std::unique_ptr<Module> Src,
- unsigned Flags = Flags::None);
+ unsigned Flags = Flags::None,
+ std::function<void(Module &, const StringSet<> &)>
+ InternalizeCallback = {});
};
} // End llvm namespace
diff --git a/contrib/llvm/include/llvm/MC/ConstantPools.h b/contrib/llvm/include/llvm/MC/ConstantPools.h
index 3925800..ef33250 100644
--- a/contrib/llvm/include/llvm/MC/ConstantPools.h
+++ b/contrib/llvm/include/llvm/MC/ConstantPools.h
@@ -11,15 +11,18 @@
//
//===----------------------------------------------------------------------===//
-
#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"
+#include <cstdint>
+#include <map>
namespace llvm {
+
class MCContext;
class MCExpr;
class MCSection;
@@ -30,6 +33,7 @@ class MCSymbolRefExpr;
struct ConstantPoolEntry {
ConstantPoolEntry(MCSymbol *L, const MCExpr *Val, unsigned Sz, SMLoc Loc_)
: Label(L), Value(Val), Size(Sz), Loc(Loc_) {}
+
MCSymbol *Label;
const MCExpr *Value;
unsigned Size;
@@ -39,13 +43,13 @@ struct ConstantPoolEntry {
// A class to keep track of assembler-generated constant pools that are use to
// implement the ldr-pseudo.
class ConstantPool {
- typedef SmallVector<ConstantPoolEntry, 4> EntryVecTy;
+ using EntryVecTy = SmallVector<ConstantPoolEntry, 4>;
EntryVecTy Entries;
- DenseMap<int64_t, const MCSymbolRefExpr *> CachedEntries;
+ std::map<int64_t, const MCSymbolRefExpr *> CachedEntries;
public:
// Initialize a new empty constant pool
- ConstantPool() {}
+ ConstantPool() = default;
// Add a new entry to the constant pool in the next slot.
// \param Value is the new entry to put in the constant pool.
@@ -79,7 +83,7 @@ class AssemblerConstantPools {
// sections in a stable order to ensure that we have print the
// constant pools in a deterministic order when printing an assembly
// file.
- typedef MapVector<MCSection *, ConstantPool> ConstantPoolMapTy;
+ using ConstantPoolMapTy = MapVector<MCSection *, ConstantPool>;
ConstantPoolMapTy ConstantPools;
public:
@@ -93,6 +97,7 @@ private:
ConstantPool *getConstantPool(MCSection *Section);
ConstantPool &getOrCreateConstantPool(MCSection *Section);
};
+
} // end namespace llvm
-#endif
+#endif // LLVM_MC_CONSTANTPOOLS_H
diff --git a/contrib/llvm/include/llvm/MC/LaneBitmask.h b/contrib/llvm/include/llvm/MC/LaneBitmask.h
index 89e6092..73b987b 100644
--- a/contrib/llvm/include/llvm/MC/LaneBitmask.h
+++ b/contrib/llvm/include/llvm/MC/LaneBitmask.h
@@ -1,4 +1,4 @@
-//===-- llvm/MC/LaneBitmask.h -----------------------------------*- C++ -*-===//
+//===- llvm/MC/LaneBitmask.h ------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -30,14 +30,16 @@
#ifndef LLVM_MC_LANEBITMASK_H
#define LLVM_MC_LANEBITMASK_H
+#include "llvm/Support/Compiler.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/Printable.h"
#include "llvm/Support/raw_ostream.h"
namespace llvm {
+
struct LaneBitmask {
// When changing the underlying type, change the format string as well.
- typedef unsigned Type;
+ using Type = unsigned;
enum : unsigned { BitWidth = 8*sizeof(Type) };
constexpr static const char *const FormatStr = "%08X";
@@ -73,6 +75,9 @@ namespace llvm {
static LaneBitmask getNone() { return LaneBitmask(0); }
static LaneBitmask getAll() { return ~LaneBitmask(0); }
+ static LaneBitmask getLane(unsigned Lane) {
+ return LaneBitmask(Type(1) << Lane);
+ }
private:
Type Mask = 0;
@@ -84,6 +89,7 @@ namespace llvm {
OS << format(LaneBitmask::FormatStr, LaneMask.getAsInteger());
});
}
-}
+
+} // end namespace llvm
#endif // LLVM_MC_LANEBITMASK_H
diff --git a/contrib/llvm/include/llvm/MC/MCAsmBackend.h b/contrib/llvm/include/llvm/MC/MCAsmBackend.h
index d4bdbcd..5a8e29d 100644
--- a/contrib/llvm/include/llvm/MC/MCAsmBackend.h
+++ b/contrib/llvm/include/llvm/MC/MCAsmBackend.h
@@ -1,4 +1,4 @@
-//===-- llvm/MC/MCAsmBackend.h - MC Asm Backend -----------------*- C++ -*-===//
+//===- llvm/MC/MCAsmBackend.h - MC Asm Backend ------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -12,35 +12,33 @@
#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/Support/DataTypes.h"
-#include "llvm/Support/ErrorHandling.h"
+#include <cstdint>
namespace llvm {
+
class MCAsmLayout;
class MCAssembler;
class MCCFIInstruction;
-class MCELFObjectTargetWriter;
struct MCFixupKindInfo;
class MCFragment;
class MCInst;
-class MCRelaxableFragment;
class MCObjectWriter;
-class MCSection;
+class MCRelaxableFragment;
class MCSubtargetInfo;
class MCValue;
class raw_pwrite_stream;
/// Generic interface to target specific assembler backends.
class MCAsmBackend {
- MCAsmBackend(const MCAsmBackend &) = delete;
- void operator=(const MCAsmBackend &) = delete;
-
protected: // Can only create subclasses.
MCAsmBackend();
public:
+ MCAsmBackend(const MCAsmBackend &) = delete;
+ MCAsmBackend &operator=(const MCAsmBackend &) = delete;
virtual ~MCAsmBackend();
/// lifetime management
@@ -62,20 +60,20 @@ public:
/// Get information on a fixup kind.
virtual const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const;
- /// Target hook to adjust the literal value of a fixup if necessary.
- /// IsResolved signals whether the caller believes a relocation is needed; the
- /// target can modify the value. The default does nothing.
- virtual void processFixupValue(const MCAssembler &Asm,
- const MCAsmLayout &Layout,
- const MCFixup &Fixup, const MCFragment *DF,
- const MCValue &Target, uint64_t &Value,
- bool &IsResolved) {}
+ /// Hook to check if a relocation is needed for some target specific reason.
+ virtual bool shouldForceRelocation(const MCAssembler &Asm,
+ const MCFixup &Fixup,
+ const MCValue &Target) {
+ return false;
+ }
/// Apply the \p Value for given \p Fixup into the provided data fragment, at
/// the offset specified by the fixup and following the fixup kind as
- /// appropriate.
- virtual void applyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize,
- uint64_t Value, bool IsPCRel) const = 0;
+ /// appropriate. Errors (such as an out of range fixup value) should be
+ /// reported via \p Ctx.
+ virtual void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
+ const MCValue &Target, MutableArrayRef<char> Data,
+ uint64_t Value, bool IsResolved) const = 0;
/// @}
@@ -136,6 +134,6 @@ public:
}
};
-} // End llvm namespace
+} // end namespace llvm
-#endif
+#endif // LLVM_MC_MCASMBACKEND_H
diff --git a/contrib/llvm/include/llvm/MC/MCAsmInfo.h b/contrib/llvm/include/llvm/MC/MCAsmInfo.h
index f898bf5..234762f 100644
--- a/contrib/llvm/include/llvm/MC/MCAsmInfo.h
+++ b/contrib/llvm/include/llvm/MC/MCAsmInfo.h
@@ -16,20 +16,22 @@
#ifndef LLVM_MC_MCASMINFO_H
#define LLVM_MC_MCASMINFO_H
+#include "llvm/ADT/StringRef.h"
#include "llvm/MC/MCDirectives.h"
#include "llvm/MC/MCDwarf.h"
#include "llvm/MC/MCTargetOptions.h"
-#include <cassert>
#include <vector>
namespace llvm {
+
+class MCContext;
class MCExpr;
class MCSection;
class MCStreamer;
class MCSymbol;
-class MCContext;
namespace WinEH {
+
enum class EncodingType {
Invalid, /// Invalid
Alpha, /// Windows Alpha
@@ -40,17 +42,14 @@ enum class EncodingType {
X86, /// Windows x86, uses no CFI, just EH tables
MIPS = Alpha,
};
-}
+
+} // end namespace WinEH
namespace LCOMM {
+
enum LCOMMType { NoAlignment, ByteAlignment, Log2Alignment };
-}
-enum class DebugCompressionType {
- DCT_None, // no compression
- DCT_Zlib, // zlib style complession
- DCT_ZlibGnu // zlib-gnu style compression
-};
+} // end namespace LCOMM
/// This class is intended to be used as a base class for asm
/// properties and features specific to the target.
@@ -60,42 +59,42 @@ protected:
// Properties to be set by the target writer, used to configure asm printer.
//
- /// Pointer size in bytes. Default is 4.
- unsigned PointerSize;
+ /// Code pointer size in bytes. Default is 4.
+ unsigned CodePointerSize = 4;
/// Size of the stack slot reserved for callee-saved registers, in bytes.
/// Default is same as pointer size.
- unsigned CalleeSaveStackSlotSize;
+ unsigned CalleeSaveStackSlotSize = 4;
/// True if target is little endian. Default is true.
- bool IsLittleEndian;
+ bool IsLittleEndian = true;
/// True if target stack grow up. Default is false.
- bool StackGrowsUp;
+ bool StackGrowsUp = false;
/// True if this target has the MachO .subsections_via_symbols directive.
/// Default is false.
- bool HasSubsectionsViaSymbols;
+ bool HasSubsectionsViaSymbols = false;
/// True if this is a MachO target that supports the macho-specific .zerofill
/// directive for emitting BSS Symbols. Default is false.
- bool HasMachoZeroFillDirective;
+ bool HasMachoZeroFillDirective = false;
/// True if this is a MachO target that supports the macho-specific .tbss
/// directive for emitting thread local BSS Symbols. Default is false.
- bool HasMachoTBSSDirective;
+ bool HasMachoTBSSDirective = 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;
+ unsigned MaxInstLength = 4;
/// Every possible instruction length is a multiple of this value. Factored
/// out in .debug_frame and .debug_line. Defaults to 1.
- unsigned MinInstAlignment;
+ unsigned MinInstAlignment = 1;
/// The '$' token, when not referencing an identifier or constant, refers to
/// the current PC. Defaults to false.
- bool DollarIsPC;
+ bool DollarIsPC = false;
/// This string, if specified, is used to separate instructions from each
/// other when on the same line. Defaults to ';'
@@ -109,10 +108,10 @@ protected:
const char *LabelSuffix;
// Print the EH begin symbol with an assignment. Defaults to false.
- bool UseAssignmentForEHBegin;
+ bool UseAssignmentForEHBegin = false;
// Do we need to create a local symbol for .size?
- bool NeedsLocalForSize;
+ bool NeedsLocalForSize = false;
/// This prefix is used for globals like constant pool entries that are
/// completely private to the .s file and should not have names in the .o
@@ -142,20 +141,20 @@ protected:
const char *Code64Directive;
/// Which dialect of an assembler variant to use. Defaults to 0
- unsigned AssemblerDialect;
+ unsigned AssemblerDialect = 0;
/// This is true if the assembler allows @ characters in symbol names.
/// Defaults to false.
- bool AllowAtInName;
+ bool AllowAtInName = false;
/// If this is true, symbol names with invalid characters will be printed in
/// quotes.
- bool SupportsQuotedNames;
+ bool SupportsQuotedNames = true;
/// This is true if data region markers should be printed as
/// ".data_region/.end_data_region" directives. If false, use "$d/$a" labels
/// instead.
- bool UseDataRegionDirectives;
+ bool UseDataRegionDirectives = false;
//===--- Data Emission Directives -------------------------------------===//
@@ -185,13 +184,13 @@ protected:
/// If non-null, a directive that is used to emit a word which should be
/// relocated as a 64-bit GP-relative offset, e.g. .gpdword on Mips. Defaults
- /// to NULL.
- const char *GPRel64Directive;
+ /// to nullptr.
+ const char *GPRel64Directive = nullptr;
/// If non-null, a directive that is used to emit a word which should be
/// relocated as a 32-bit GP-relative offset, e.g. .gpword on Mips or .gprel32
- /// on Alpha. Defaults to NULL.
- const char *GPRel32Directive;
+ /// on Alpha. Defaults to nullptr.
+ const char *GPRel32Directive = nullptr;
/// If non-null, directives that are used to emit a word/dword which should
/// be relocated as a 32/64-bit DTP/TP-relative offset, e.g. .dtprelword/
@@ -204,14 +203,14 @@ protected:
/// This is true if this target uses "Sun Style" syntax for section switching
/// ("#alloc,#write" etc) instead of the normal ELF syntax (,"a,w") in
/// .section directives. Defaults to false.
- bool SunStyleELFSectionSwitchSyntax;
+ bool SunStyleELFSectionSwitchSyntax = false;
/// This is true if this target uses ELF '.section' directive before the
/// '.bss' one. It's used for PPC/Linux which doesn't support the '.bss'
/// directive only. Defaults to false.
- bool UsesELFSectionDirectiveForBSS;
+ bool UsesELFSectionDirectiveForBSS = false;
- bool NeedsDwarfSectionOffsetDirective;
+ bool NeedsDwarfSectionOffsetDirective = false;
//===--- Alignment Information ----------------------------------------===//
@@ -219,11 +218,11 @@ protected:
/// directives, where N is the number of bytes to align to. Otherwise, it
/// emits ".align log2(N)", e.g. 3 to align to an 8 byte boundary. Defaults
/// to true.
- bool AlignmentIsInBytes;
+ bool AlignmentIsInBytes = true;
/// If non-zero, this is used to fill the executable space created as the
/// result of a alignment directive. Defaults to 0
- unsigned TextAlignFillValue;
+ unsigned TextAlignFillValue = 0;
//===--- Global Variable Emission Directives --------------------------===//
@@ -236,7 +235,7 @@ protected:
/// uses a relocation but it can be suppressed by writing
/// a = f - g
/// .long a
- bool SetDirectiveSuppressesReloc;
+ bool SetDirectiveSuppressesReloc = false;
/// False if the assembler requires that we use
/// \code
@@ -251,98 +250,98 @@ protected:
/// \endcode
///
/// Defaults to true.
- bool HasAggressiveSymbolFolding;
+ bool HasAggressiveSymbolFolding = true;
/// True is .comm's and .lcomms optional alignment is to be specified in bytes
/// instead of log2(n). Defaults to true.
- bool COMMDirectiveAlignmentIsInBytes;
+ bool COMMDirectiveAlignmentIsInBytes = true;
/// Describes if the .lcomm directive for the target supports an alignment
/// argument and how it is interpreted. Defaults to NoAlignment.
- LCOMM::LCOMMType LCOMMDirectiveAlignmentType;
+ LCOMM::LCOMMType LCOMMDirectiveAlignmentType = LCOMM::NoAlignment;
// True if the target allows .align directives on functions. This is true for
// most targets, so defaults to true.
- bool HasFunctionAlignment;
+ bool HasFunctionAlignment = true;
/// True if the target has .type and .size directives, this is true for most
/// ELF targets. Defaults to true.
- bool HasDotTypeDotSizeDirective;
+ bool HasDotTypeDotSizeDirective = true;
/// True if the target has a single parameter .file directive, this is true
/// for ELF targets. Defaults to true.
- bool HasSingleParameterDotFile;
+ bool HasSingleParameterDotFile = true;
/// True if the target has a .ident directive, this is true for ELF targets.
/// Defaults to false.
- bool HasIdentDirective;
+ bool HasIdentDirective = false;
/// True if this target supports the MachO .no_dead_strip directive. Defaults
/// to false.
- bool HasNoDeadStrip;
+ bool HasNoDeadStrip = false;
/// True if this target supports the MachO .alt_entry directive. Defaults to
/// false.
- bool HasAltEntry;
+ bool HasAltEntry = false;
/// Used to declare a global as being a weak symbol. Defaults to ".weak".
const char *WeakDirective;
/// This directive, if non-null, is used to declare a global as being a weak
- /// undefined symbol. Defaults to NULL.
- const char *WeakRefDirective;
+ /// undefined symbol. Defaults to nullptr.
+ const char *WeakRefDirective = nullptr;
/// True if we have a directive to declare a global as being a weak defined
/// symbol. Defaults to false.
- bool HasWeakDefDirective;
+ bool HasWeakDefDirective = false;
/// True if we have a directive to declare a global as being a weak defined
/// symbol that can be hidden (unexported). Defaults to false.
- bool HasWeakDefCanBeHiddenDirective;
+ bool HasWeakDefCanBeHiddenDirective = false;
/// True if we have a .linkonce directive. This is used on cygwin/mingw.
/// Defaults to false.
- bool HasLinkOnceDirective;
+ bool HasLinkOnceDirective = false;
/// This attribute, if not MCSA_Invalid, is used to declare a symbol as having
/// hidden visibility. Defaults to MCSA_Hidden.
- MCSymbolAttr HiddenVisibilityAttr;
+ MCSymbolAttr HiddenVisibilityAttr = MCSA_Hidden;
/// This attribute, if not MCSA_Invalid, is used to declare an undefined
/// symbol as having hidden visibility. Defaults to MCSA_Hidden.
- MCSymbolAttr HiddenDeclarationVisibilityAttr;
+ MCSymbolAttr HiddenDeclarationVisibilityAttr = MCSA_Hidden;
/// This attribute, if not MCSA_Invalid, is used to declare a symbol as having
/// protected visibility. Defaults to MCSA_Protected
- MCSymbolAttr ProtectedVisibilityAttr;
+ MCSymbolAttr ProtectedVisibilityAttr = MCSA_Protected;
//===--- Dwarf Emission Directives -----------------------------------===//
/// True if target supports emission of debugging information. Defaults to
/// false.
- bool SupportsDebugInformation;
+ bool SupportsDebugInformation = false;
/// Exception handling format for the target. Defaults to None.
- ExceptionHandling ExceptionsType;
+ ExceptionHandling ExceptionsType = ExceptionHandling::None;
/// Windows exception handling data (.pdata) encoding. Defaults to Invalid.
- WinEH::EncodingType WinEHEncodingType;
+ WinEH::EncodingType WinEHEncodingType = WinEH::EncodingType::Invalid;
/// True if Dwarf2 output generally uses relocations for references to other
/// .debug_* sections.
- bool DwarfUsesRelocationsAcrossSections;
+ bool DwarfUsesRelocationsAcrossSections = true;
/// True if DWARF FDE symbol reference relocations should be replaced by an
/// absolute difference.
- bool DwarfFDESymbolsUseAbsDiff;
+ bool DwarfFDESymbolsUseAbsDiff = false;
/// True if dwarf register numbers are printed instead of symbolic register
/// names in .cfi_* directives. Defaults to false.
- bool DwarfRegNumForCFI;
+ bool DwarfRegNumForCFI = false;
/// True if target uses parens to indicate the symbol variant instead of @.
/// For example, foo(plt) instead of foo@plt. Defaults to false.
- bool UseParensForSymbolVariant;
+ bool UseParensForSymbolVariant = false;
//===--- Prologue State ----------------------------------------------===//
@@ -361,11 +360,11 @@ protected:
bool PreserveAsmComments;
/// Compress DWARF debug sections. Defaults to no compression.
- DebugCompressionType CompressDebugSections;
+ DebugCompressionType CompressDebugSections = DebugCompressionType::None;
/// True if the integrated assembler should interpret 'a >> b' constant
/// expressions as logical rather than arithmetic.
- bool UseLogicalShr;
+ bool UseLogicalShr = true;
// If true, emit GOTPCRELX/REX_GOTPCRELX instead of GOTPCREL, on
// X86_64 ELF.
@@ -379,8 +378,8 @@ public:
explicit MCAsmInfo();
virtual ~MCAsmInfo();
- /// Get the pointer size in bytes.
- unsigned getPointerSize() const { return PointerSize; }
+ /// Get the code pointer size in bytes.
+ unsigned getCodePointerSize() const { return CodePointerSize; }
/// Get the callee-saved register stack slot
/// size in bytes.
@@ -475,14 +474,17 @@ public:
bool needsLocalForSize() const { return NeedsLocalForSize; }
StringRef getPrivateGlobalPrefix() const { return PrivateGlobalPrefix; }
StringRef getPrivateLabelPrefix() const { return PrivateLabelPrefix; }
+
bool hasLinkerPrivateGlobalPrefix() const {
return LinkerPrivateGlobalPrefix[0] != '\0';
}
+
StringRef getLinkerPrivateGlobalPrefix() const {
if (hasLinkerPrivateGlobalPrefix())
return LinkerPrivateGlobalPrefix;
return getPrivateGlobalPrefix();
}
+
const char *getInlineAsmStart() const { return InlineAsmStart; }
const char *getInlineAsmEnd() const { return InlineAsmEnd; }
const char *getCode16Directive() const { return Code16Directive; }
@@ -491,25 +493,32 @@ public:
unsigned getAssemblerDialect() const { return AssemblerDialect; }
bool doesAllowAtInName() const { return AllowAtInName; }
bool supportsNameQuoting() const { return SupportsQuotedNames; }
+
bool doesSupportDataRegionDirectives() const {
return UseDataRegionDirectives;
}
+
const char *getZeroDirective() const { return ZeroDirective; }
const char *getAsciiDirective() const { return AsciiDirective; }
const char *getAscizDirective() const { return AscizDirective; }
bool getAlignmentIsInBytes() const { return AlignmentIsInBytes; }
unsigned getTextAlignFillValue() const { return TextAlignFillValue; }
const char *getGlobalDirective() const { return GlobalDirective; }
+
bool doesSetDirectiveSuppressReloc() const {
return SetDirectiveSuppressesReloc;
}
+
bool hasAggressiveSymbolFolding() const { return HasAggressiveSymbolFolding; }
+
bool getCOMMDirectiveAlignmentIsInBytes() const {
return COMMDirectiveAlignmentIsInBytes;
}
+
LCOMM::LCOMMType getLCOMMDirectiveAlignmentType() const {
return LCOMMDirectiveAlignmentType;
}
+
bool hasFunctionAlignment() const { return HasFunctionAlignment; }
bool hasDotTypeDotSizeDirective() const { return HasDotTypeDotSizeDirective; }
bool hasSingleParameterDotFile() const { return HasSingleParameterDotFile; }
@@ -519,22 +528,29 @@ public:
const char *getWeakDirective() const { return WeakDirective; }
const char *getWeakRefDirective() const { return WeakRefDirective; }
bool hasWeakDefDirective() const { return HasWeakDefDirective; }
+
bool hasWeakDefCanBeHiddenDirective() const {
return HasWeakDefCanBeHiddenDirective;
}
+
bool hasLinkOnceDirective() const { return HasLinkOnceDirective; }
MCSymbolAttr getHiddenVisibilityAttr() const { return HiddenVisibilityAttr; }
+
MCSymbolAttr getHiddenDeclarationVisibilityAttr() const {
return HiddenDeclarationVisibilityAttr;
}
+
MCSymbolAttr getProtectedVisibilityAttr() const {
return ProtectedVisibilityAttr;
}
+
bool doesSupportDebugInformation() const { return SupportsDebugInformation; }
+
bool doesSupportExceptionHandling() const {
return ExceptionsType != ExceptionHandling::None;
}
+
ExceptionHandling getExceptionHandlingType() const { return ExceptionsType; }
WinEH::EncodingType getWinEHEncodingType() const { return WinEHEncodingType; }
@@ -558,6 +574,7 @@ public:
bool doesDwarfUseRelocationsAcrossSections() const {
return DwarfUsesRelocationsAcrossSections;
}
+
bool doDwarfFDESymbolsUseAbsDiff() const { return DwarfFDESymbolsUseAbsDiff; }
bool useDwarfRegNumForCFI() const { return DwarfRegNumForCFI; }
bool useParensForSymbolVariant() const { return UseParensForSymbolVariant; }
@@ -600,6 +617,7 @@ public:
void setRelaxELFRelocations(bool V) { RelaxELFRelocations = V; }
bool hasMipsExpressions() const { return HasMipsExpressions; }
};
-}
-#endif
+} // end namespace llvm
+
+#endif // LLVM_MC_MCASMINFO_H
diff --git a/contrib/llvm/include/llvm/MC/MCAsmInfoCOFF.h b/contrib/llvm/include/llvm/MC/MCAsmInfoCOFF.h
index 56444f3..01c8ae4 100644
--- a/contrib/llvm/include/llvm/MC/MCAsmInfoCOFF.h
+++ b/contrib/llvm/include/llvm/MC/MCAsmInfoCOFF.h
@@ -1,4 +1,4 @@
-//===-- MCAsmInfoCOFF.h - COFF asm properties -------------------*- C++ -*-===//
+//===- MCAsmInfoCOFF.h - COFF asm properties --------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -13,24 +13,28 @@
#include "llvm/MC/MCAsmInfo.h"
namespace llvm {
- class MCAsmInfoCOFF : public MCAsmInfo {
- virtual void anchor();
- protected:
- explicit MCAsmInfoCOFF();
- };
-
- class MCAsmInfoMicrosoft : public MCAsmInfoCOFF {
- void anchor() override;
- protected:
- explicit MCAsmInfoMicrosoft();
- };
-
- class MCAsmInfoGNUCOFF : public MCAsmInfoCOFF {
- void anchor() override;
- protected:
- explicit MCAsmInfoGNUCOFF();
- };
-}
+class MCAsmInfoCOFF : public MCAsmInfo {
+ virtual void anchor();
+
+protected:
+ explicit MCAsmInfoCOFF();
+};
+
+class MCAsmInfoMicrosoft : public MCAsmInfoCOFF {
+ void anchor() override;
+
+protected:
+ explicit MCAsmInfoMicrosoft();
+};
+
+class MCAsmInfoGNUCOFF : public MCAsmInfoCOFF {
+ void anchor() override;
+
+protected:
+ explicit MCAsmInfoGNUCOFF();
+};
+
+} // end namespace llvm
#endif // LLVM_MC_MCASMINFOCOFF_H
diff --git a/contrib/llvm/include/llvm/MC/MCAsmInfoDarwin.h b/contrib/llvm/include/llvm/MC/MCAsmInfoDarwin.h
index d587c3c..a533d60 100644
--- a/contrib/llvm/include/llvm/MC/MCAsmInfoDarwin.h
+++ b/contrib/llvm/include/llvm/MC/MCAsmInfoDarwin.h
@@ -1,4 +1,4 @@
-//===---- MCAsmInfoDarwin.h - Darwin asm properties -------------*- C++ -*-===//
+//===- MCAsmInfoDarwin.h - Darwin asm properties ----------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -18,12 +18,14 @@
#include "llvm/MC/MCAsmInfo.h"
namespace llvm {
- class MCAsmInfoDarwin : public MCAsmInfo {
- public:
- explicit MCAsmInfoDarwin();
- bool isSectionAtomizableBySymbols(const MCSection &Section) const override;
- };
-}
+class MCAsmInfoDarwin : public MCAsmInfo {
+public:
+ explicit MCAsmInfoDarwin();
+
+ bool isSectionAtomizableBySymbols(const MCSection &Section) const override;
+};
+
+} // end namespace llvm
#endif // LLVM_MC_MCASMINFODARWIN_H
diff --git a/contrib/llvm/include/llvm/MC/MCAsmInfoELF.h b/contrib/llvm/include/llvm/MC/MCAsmInfoELF.h
index f8bb943..f113afc 100644
--- a/contrib/llvm/include/llvm/MC/MCAsmInfoELF.h
+++ b/contrib/llvm/include/llvm/MC/MCAsmInfoELF.h
@@ -1,4 +1,4 @@
-//===-- llvm/MC/MCAsmInfoELF.h - ELF Asm info -------------------*- C++ -*-===//
+//===- llvm/MC/MCAsmInfoELF.h - ELF Asm info --------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -13,6 +13,7 @@
#include "llvm/MC/MCAsmInfo.h"
namespace llvm {
+
class MCAsmInfoELF : public MCAsmInfo {
virtual void anchor();
MCSection *getNonexecutableStackSection(MCContext &Ctx) const final;
@@ -20,10 +21,11 @@ class MCAsmInfoELF : public MCAsmInfo {
protected:
/// Targets which have non-executable stacks by default can set this to false
/// to disable the special section which requests a non-executable stack.
- bool UsesNonexecutableStackSection;
+ bool UsesNonexecutableStackSection = true;
MCAsmInfoELF();
};
-}
-#endif
+} // end namespace llvm
+
+#endif // LLVM_MC_MCASMINFOELF_H
diff --git a/contrib/llvm/include/llvm/MC/MCAsmInfoWasm.h b/contrib/llvm/include/llvm/MC/MCAsmInfoWasm.h
new file mode 100644
index 0000000..bc46cfd
--- /dev/null
+++ b/contrib/llvm/include/llvm/MC/MCAsmInfoWasm.h
@@ -0,0 +1,24 @@
+//===-- llvm/MC/MCAsmInfoWasm.h - Wasm Asm info -----------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCASMINFOWASM_H
+#define LLVM_MC_MCASMINFOWASM_H
+
+#include "llvm/MC/MCAsmInfo.h"
+
+namespace llvm {
+class MCAsmInfoWasm : public MCAsmInfo {
+ virtual void anchor();
+
+protected:
+ MCAsmInfoWasm();
+};
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/MC/MCAssembler.h b/contrib/llvm/include/llvm/MC/MCAssembler.h
index 641e789..4f1b5a8 100644
--- a/contrib/llvm/include/llvm/MC/MCAssembler.h
+++ b/contrib/llvm/include/llvm/MC/MCAssembler.h
@@ -10,33 +10,35 @@
#ifndef LLVM_MC_MCASSEMBLER_H
#define LLVM_MC_MCASSEMBLER_H
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
-#include "llvm/ADT/ilist.h"
-#include "llvm/ADT/ilist_node.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/iterator.h"
+#include "llvm/ADT/iterator_range.h"
#include "llvm/MC/MCDirectives.h"
#include "llvm/MC/MCDwarf.h"
#include "llvm/MC/MCFixup.h"
#include "llvm/MC/MCFragment.h"
-#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCLinkerOptimizationHint.h"
-#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/MCSymbol.h"
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
+#include <string>
+#include <utility>
+#include <vector>
namespace llvm {
-class raw_ostream;
+
+class MCAsmBackend;
class MCAsmLayout;
-class MCAssembler;
class MCContext;
class MCCodeEmitter;
-class MCExpr;
class MCFragment;
class MCObjectWriter;
class MCSection;
-class MCSubtargetInfo;
class MCValue;
-class MCAsmBackend;
// FIXME: This really doesn't belong here. See comments below.
struct IndirectSymbolData {
@@ -58,41 +60,38 @@ class MCAssembler {
friend class MCAsmLayout;
public:
- typedef std::vector<MCSection *> SectionListType;
- typedef std::vector<const MCSymbol *> SymbolDataListType;
+ using SectionListType = std::vector<MCSection *>;
+ using SymbolDataListType = std::vector<const MCSymbol *>;
- typedef pointee_iterator<SectionListType::const_iterator> const_iterator;
- typedef pointee_iterator<SectionListType::iterator> iterator;
+ using const_iterator = pointee_iterator<SectionListType::const_iterator>;
+ using iterator = pointee_iterator<SectionListType::iterator>;
- typedef pointee_iterator<SymbolDataListType::const_iterator>
- const_symbol_iterator;
- typedef pointee_iterator<SymbolDataListType::iterator> symbol_iterator;
+ using const_symbol_iterator =
+ pointee_iterator<SymbolDataListType::const_iterator>;
+ using symbol_iterator = pointee_iterator<SymbolDataListType::iterator>;
- typedef iterator_range<symbol_iterator> symbol_range;
- typedef iterator_range<const_symbol_iterator> const_symbol_range;
+ using symbol_range = iterator_range<symbol_iterator>;
+ using const_symbol_range = iterator_range<const_symbol_iterator>;
- typedef std::vector<IndirectSymbolData>::const_iterator
- const_indirect_symbol_iterator;
- typedef std::vector<IndirectSymbolData>::iterator indirect_symbol_iterator;
+ using const_indirect_symbol_iterator =
+ std::vector<IndirectSymbolData>::const_iterator;
+ using indirect_symbol_iterator = std::vector<IndirectSymbolData>::iterator;
- typedef std::vector<DataRegionData>::const_iterator
- const_data_region_iterator;
- typedef std::vector<DataRegionData>::iterator data_region_iterator;
+ using const_data_region_iterator =
+ std::vector<DataRegionData>::const_iterator;
+ using data_region_iterator = std::vector<DataRegionData>::iterator;
/// MachO specific deployment target version info.
// A Major version of 0 indicates that no version information was supplied
// and so the corresponding load command should not be emitted.
- typedef struct {
+ using VersionMinInfoType = struct {
MCVersionMinType Kind;
unsigned Major;
unsigned Minor;
unsigned Update;
- } VersionMinInfoType;
+ };
private:
- MCAssembler(const MCAssembler &) = delete;
- void operator=(const MCAssembler &) = delete;
-
MCContext &Context;
MCAsmBackend &Backend;
@@ -131,9 +130,9 @@ private:
/// By default it's 0, which means bundling is disabled.
unsigned BundleAlignSize;
- unsigned RelaxAll : 1;
- unsigned SubsectionsViaSymbols : 1;
- unsigned IncrementalLinkerCompatible : 1;
+ bool RelaxAll : 1;
+ bool SubsectionsViaSymbols : 1;
+ bool IncrementalLinkerCompatible : 1;
/// ELF specific e_header flags
// It would be good if there were an MCELFAssembler class to hold this.
@@ -148,7 +147,6 @@ private:
VersionMinInfoType VersionMinInfo;
-private:
/// Evaluate a fixup to a relocatable expression and the value which should be
/// placed into the fixup.
///
@@ -197,10 +195,22 @@ private:
/// finishLayout - Finalize a layout, including fragment lowering.
void finishLayout(MCAsmLayout &Layout);
- std::pair<uint64_t, bool> handleFixup(const MCAsmLayout &Layout,
- MCFragment &F, const MCFixup &Fixup);
+ std::tuple<MCValue, uint64_t, bool>
+ handleFixup(const MCAsmLayout &Layout, MCFragment &F, const MCFixup &Fixup);
public:
+ /// Construct a new assembler instance.
+ //
+ // FIXME: How are we going to parameterize this? Two obvious options are stay
+ // concrete and require clients to pass in a target like object. The other
+ // option is to make this abstract, and have targets provide concrete
+ // implementations as we do with AsmParser.
+ MCAssembler(MCContext &Context, MCAsmBackend &Backend,
+ MCCodeEmitter &Emitter, MCObjectWriter &Writer);
+ MCAssembler(const MCAssembler &) = delete;
+ MCAssembler &operator=(const MCAssembler &) = delete;
+ ~MCAssembler();
+
/// Compute the effective fragment size assuming it is laid out at the given
/// \p SectionAddress and \p FragmentOffset.
uint64_t computeFragmentSize(const MCAsmLayout &Layout,
@@ -240,17 +250,6 @@ public:
VersionMinInfo.Update = Update;
}
-public:
- /// Construct a new assembler instance.
- //
- // FIXME: How are we going to parameterize this? Two obvious options are stay
- // concrete and require clients to pass in a target like object. The other
- // option is to make this abstract, and have targets provide concrete
- // implementations as we do with AsmParser.
- MCAssembler(MCContext &Context, MCAsmBackend &Backend,
- MCCodeEmitter &Emitter, MCObjectWriter &Writer);
- ~MCAssembler();
-
/// Reuse an assembler instance
///
void reset();
@@ -414,7 +413,7 @@ public:
/// @}
- void dump();
+ void dump() const;
};
/// \brief Compute the amount of padding required before the fragment \p F to
@@ -425,4 +424,4 @@ uint64_t computeBundlePadding(const MCAssembler &Assembler, const MCFragment *F,
} // end namespace llvm
-#endif
+#endif // LLVM_MC_MCASSEMBLER_H
diff --git a/contrib/llvm/include/llvm/MC/MCCodeEmitter.h b/contrib/llvm/include/llvm/MC/MCCodeEmitter.h
index b6c1915..f1b0b78 100644
--- a/contrib/llvm/include/llvm/MC/MCCodeEmitter.h
+++ b/contrib/llvm/include/llvm/MC/MCCodeEmitter.h
@@ -1,4 +1,4 @@
-//===-- llvm/MC/MCCodeEmitter.h - Instruction Encoding ----------*- C++ -*-===//
+//===- llvm/MC/MCCodeEmitter.h - Instruction Encoding -----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -10,9 +10,8 @@
#ifndef LLVM_MC_MCCODEEMITTER_H
#define LLVM_MC_MCCODEEMITTER_H
-#include "llvm/Support/Compiler.h"
-
namespace llvm {
+
class MCFixup;
class MCInst;
class MCSubtargetInfo;
@@ -21,14 +20,12 @@ template<typename T> class SmallVectorImpl;
/// MCCodeEmitter - Generic instruction encoding interface.
class MCCodeEmitter {
-private:
- MCCodeEmitter(const MCCodeEmitter &) = delete;
- void operator=(const MCCodeEmitter &) = delete;
-
protected: // Can only create subclasses.
MCCodeEmitter();
public:
+ MCCodeEmitter(const MCCodeEmitter &) = delete;
+ MCCodeEmitter &operator=(const MCCodeEmitter &) = delete;
virtual ~MCCodeEmitter();
/// Lifetime management
@@ -41,6 +38,6 @@ public:
const MCSubtargetInfo &STI) const = 0;
};
-} // End llvm namespace
+} // end namespace llvm
-#endif
+#endif // LLVM_MC_MCCODEEMITTER_H
diff --git a/contrib/llvm/include/llvm/MC/MCCodeView.h b/contrib/llvm/include/llvm/MC/MCCodeView.h
index 41521a6..c3f1cec 100644
--- a/contrib/llvm/include/llvm/MC/MCCodeView.h
+++ b/contrib/llvm/include/llvm/MC/MCCodeView.h
@@ -14,10 +14,10 @@
#ifndef LLVM_MC_MCCODEVIEW_H
#define LLVM_MC_MCCODEVIEW_H
-#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringMap.h"
-#include "llvm/MC/MCObjectStreamer.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/MC/MCFragment.h"
+#include "llvm/MC/MCObjectStreamer.h"
#include <map>
#include <vector>
diff --git a/contrib/llvm/include/llvm/MC/MCContext.h b/contrib/llvm/include/llvm/MC/MCContext.h
index 5d4c47f..2c60014 100644
--- a/contrib/llvm/include/llvm/MC/MCContext.h
+++ b/contrib/llvm/include/llvm/MC/MCContext.h
@@ -15,45 +15,50 @@
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
+#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/MC/MCDwarf.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/SectionKind.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Compiler.h"
-#include "llvm/Support/Dwarf.h"
#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
#include <map>
-#include <tuple>
-#include <vector> // FIXME: Shouldn't be needed.
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
namespace llvm {
+
+ class CodeViewContext;
class MCAsmInfo;
- class MCExpr;
- class MCSection;
- class MCSymbol;
- class MCSymbolELF;
class MCLabel;
- struct MCDwarfFile;
- class MCDwarfLoc;
class MCObjectFileInfo;
class MCRegisterInfo;
- class MCLineSection;
- class SMLoc;
- class MCSectionMachO;
- class MCSectionELF;
+ class MCSection;
class MCSectionCOFF;
- class CodeViewContext;
+ class MCSectionELF;
+ class MCSectionMachO;
+ class MCSectionWasm;
+ class MCStreamer;
+ class MCSymbol;
+ class MCSymbolELF;
+ class MCSymbolWasm;
+ class SMLoc;
+ class SourceMgr;
/// Context object for machine code objects. This class owns all of the
/// sections that it creates.
///
class MCContext {
- MCContext(const MCContext &) = delete;
- MCContext &operator=(const MCContext &) = delete;
-
public:
- typedef StringMap<MCSymbol *, BumpPtrAllocator &> SymbolTable;
+ using SymbolTable = StringMap<MCSymbol *, BumpPtrAllocator &>;
private:
/// The SourceMgr for this object, if any.
@@ -82,14 +87,11 @@ namespace llvm {
SpecificBumpPtrAllocator<MCSectionCOFF> COFFAllocator;
SpecificBumpPtrAllocator<MCSectionELF> ELFAllocator;
SpecificBumpPtrAllocator<MCSectionMachO> MachOAllocator;
+ SpecificBumpPtrAllocator<MCSectionWasm> WasmAllocator;
/// Bindings of names to symbols.
SymbolTable Symbols;
- /// Sections can have a corresponding symbol. This maps one to the
- /// other.
- DenseMap<const MCSection *, MCSymbol *> SectionSymbols;
-
/// A mapping from a local label number and an instance count to a symbol.
/// For example, in the assembly
/// 1:
@@ -126,7 +128,7 @@ namespace llvm {
/// Boolean toggled when .secure_log_unique / .secure_log_reset is seen to
/// catch errors if .secure_log_unique appears twice without
/// .secure_log_reset appearing between them.
- bool SecureLogUsed;
+ bool SecureLogUsed = false;
/// The compilation directory to use for DW_AT_comp_dir.
SmallString<128> CompilationDir;
@@ -142,14 +144,14 @@ namespace llvm {
/// The current dwarf line information from the last dwarf .loc directive.
MCDwarfLoc CurrentDwarfLoc;
- bool DwarfLocSeen;
+ bool DwarfLocSeen = false;
/// Generate dwarf debugging info for assembly source files.
- bool GenDwarfForAssembly;
+ bool GenDwarfForAssembly = false;
/// The current dwarf file number when generate dwarf debugging info for
/// assembly source files.
- unsigned GenDwarfFileNumber;
+ unsigned GenDwarfFileNumber = 0;
/// Sections for generating the .debug_ranges and .debug_aranges sections.
SetVector<MCSection *> SectionsForRanges;
@@ -167,25 +169,27 @@ namespace llvm {
StringRef DwarfDebugProducer;
/// The maximum version of dwarf that we should emit.
- uint16_t DwarfVersion;
+ uint16_t DwarfVersion = 4;
/// Honor temporary labels, this is useful for debugging semantic
/// differences between temporary and non-temporary labels (primarily on
/// Darwin).
- bool AllowTemporaryLabels;
+ bool AllowTemporaryLabels = true;
bool UseNamesOnTempLabels = true;
/// The Compile Unit ID that we are currently processing.
- unsigned DwarfCompileUnitID;
+ unsigned DwarfCompileUnitID = 0;
struct ELFSectionKey {
std::string SectionName;
StringRef GroupName;
unsigned UniqueID;
+
ELFSectionKey(StringRef SectionName, StringRef GroupName,
unsigned UniqueID)
: SectionName(SectionName), GroupName(GroupName), UniqueID(UniqueID) {
}
+
bool operator<(const ELFSectionKey &Other) const {
if (SectionName != Other.SectionName)
return SectionName < Other.SectionName;
@@ -200,10 +204,12 @@ namespace llvm {
StringRef GroupName;
int SelectionKey;
unsigned UniqueID;
+
COFFSectionKey(StringRef SectionName, StringRef GroupName,
int SelectionKey, unsigned UniqueID)
: SectionName(SectionName), GroupName(GroupName),
SelectionKey(SelectionKey), UniqueID(UniqueID) {}
+
bool operator<(const COFFSectionKey &Other) const {
if (SectionName != Other.SectionName)
return SectionName < Other.SectionName;
@@ -215,17 +221,37 @@ namespace llvm {
}
};
+ struct WasmSectionKey {
+ std::string SectionName;
+ StringRef GroupName;
+ unsigned UniqueID;
+
+ WasmSectionKey(StringRef SectionName, StringRef GroupName,
+ unsigned UniqueID)
+ : SectionName(SectionName), GroupName(GroupName), UniqueID(UniqueID) {
+ }
+
+ bool operator<(const WasmSectionKey &Other) const {
+ if (SectionName != Other.SectionName)
+ return SectionName < Other.SectionName;
+ if (GroupName != Other.GroupName)
+ return GroupName < Other.GroupName;
+ return UniqueID < Other.UniqueID;
+ }
+ };
+
StringMap<MCSectionMachO *> MachOUniquingMap;
std::map<ELFSectionKey, MCSectionELF *> ELFUniquingMap;
std::map<COFFSectionKey, MCSectionCOFF *> COFFUniquingMap;
- StringMap<bool> ELFRelSecNames;
+ std::map<WasmSectionKey, MCSectionWasm *> WasmUniquingMap;
+ StringMap<bool> RelSecNames;
SpecificBumpPtrAllocator<MCSubtargetInfo> MCSubtargetAllocator;
/// Do automatic reset in destructor
bool AutoReset;
- bool HadError;
+ bool HadError = false;
MCSymbol *createSymbolImpl(const StringMapEntry<bool> *Name,
bool CanBeUnnamed);
@@ -235,10 +261,19 @@ namespace llvm {
MCSymbol *getOrCreateDirectionalLocalSymbol(unsigned LocalLabelVal,
unsigned Instance);
+ MCSectionELF *createELFSectionImpl(StringRef Section, unsigned Type,
+ unsigned Flags, SectionKind K,
+ unsigned EntrySize,
+ const MCSymbolELF *Group,
+ unsigned UniqueID,
+ const MCSymbolELF *Associated);
+
public:
explicit MCContext(const MCAsmInfo *MAI, const MCRegisterInfo *MRI,
const MCObjectFileInfo *MOFI,
const SourceMgr *Mgr = nullptr, bool DoAutoReset = true);
+ MCContext(const MCContext &) = delete;
+ MCContext &operator=(const MCContext &) = delete;
~MCContext();
const SourceMgr *getSourceManager() const { return SrcMgr; }
@@ -293,8 +328,6 @@ namespace llvm {
/// \param Name - The symbol name, which must be unique across all symbols.
MCSymbol *getOrCreateSymbol(const Twine &Name);
- MCSymbolELF *getOrCreateSectionSymbol(const MCSectionELF &Section);
-
/// Gets a symbol that will be defined to the final stack offset of a local
/// variable after codegen.
///
@@ -345,25 +378,13 @@ namespace llvm {
MCSectionELF *getELFSection(const Twine &Section, unsigned Type,
unsigned Flags) {
- return getELFSection(Section, Type, Flags, nullptr);
- }
-
- MCSectionELF *getELFSection(const Twine &Section, unsigned Type,
- unsigned Flags, const char *BeginSymName) {
- return getELFSection(Section, Type, Flags, 0, "", BeginSymName);
+ return getELFSection(Section, Type, Flags, 0, "");
}
MCSectionELF *getELFSection(const Twine &Section, unsigned Type,
unsigned Flags, unsigned EntrySize,
const Twine &Group) {
- return getELFSection(Section, Type, Flags, EntrySize, Group, nullptr);
- }
-
- MCSectionELF *getELFSection(const Twine &Section, unsigned Type,
- unsigned Flags, unsigned EntrySize,
- const Twine &Group, const char *BeginSymName) {
- return getELFSection(Section, Type, Flags, EntrySize, Group, ~0,
- BeginSymName);
+ return getELFSection(Section, Type, Flags, EntrySize, Group, ~0);
}
MCSectionELF *getELFSection(const Twine &Section, unsigned Type,
@@ -376,13 +397,12 @@ namespace llvm {
MCSectionELF *getELFSection(const Twine &Section, unsigned Type,
unsigned Flags, unsigned EntrySize,
const Twine &Group, unsigned UniqueID,
- const char *BeginSymName);
+ const MCSymbolELF *Associated);
MCSectionELF *getELFSection(const Twine &Section, unsigned Type,
unsigned Flags, unsigned EntrySize,
const MCSymbolELF *Group, unsigned UniqueID,
- const char *BeginSymName,
- const MCSectionELF *Associated);
+ const MCSymbolELF *Associated);
/// Get a section with the provided group identifier. This section is
/// named by concatenating \p Prefix with '.' then \p Suffix. The \p Type
@@ -395,7 +415,7 @@ namespace llvm {
MCSectionELF *createELFRelSection(const Twine &Name, unsigned Type,
unsigned Flags, unsigned EntrySize,
const MCSymbolELF *Group,
- const MCSectionELF *Associated);
+ const MCSectionELF *RelInfoSection);
void renameELFSection(MCSectionELF *Section, StringRef Name);
@@ -421,6 +441,54 @@ namespace llvm {
getAssociativeCOFFSection(MCSectionCOFF *Sec, const MCSymbol *KeySym,
unsigned UniqueID = GenericSectionID);
+ MCSectionWasm *getWasmSection(const Twine &Section, unsigned Type,
+ unsigned Flags) {
+ return getWasmSection(Section, Type, Flags, nullptr);
+ }
+
+ MCSectionWasm *getWasmSection(const Twine &Section, unsigned Type,
+ unsigned Flags, const char *BeginSymName) {
+ return getWasmSection(Section, Type, Flags, "", BeginSymName);
+ }
+
+ MCSectionWasm *getWasmSection(const Twine &Section, unsigned Type,
+ unsigned Flags, const Twine &Group) {
+ return getWasmSection(Section, Type, Flags, Group, nullptr);
+ }
+
+ MCSectionWasm *getWasmSection(const Twine &Section, unsigned Type,
+ unsigned Flags, const Twine &Group,
+ const char *BeginSymName) {
+ return getWasmSection(Section, Type, Flags, Group, ~0, BeginSymName);
+ }
+
+ MCSectionWasm *getWasmSection(const Twine &Section, unsigned Type,
+ unsigned Flags, const Twine &Group,
+ unsigned UniqueID) {
+ return getWasmSection(Section, Type, Flags, Group, UniqueID, nullptr);
+ }
+
+ MCSectionWasm *getWasmSection(const Twine &Section, unsigned Type,
+ unsigned Flags, const Twine &Group,
+ unsigned UniqueID, const char *BeginSymName);
+
+ MCSectionWasm *getWasmSection(const Twine &Section, unsigned Type,
+ unsigned Flags, const MCSymbolWasm *Group,
+ unsigned UniqueID, const char *BeginSymName);
+
+ /// Get a section with the provided group identifier. This section is
+ /// named by concatenating \p Prefix with '.' then \p Suffix. The \p Type
+ /// describes the type of the section and \p Flags are used to further
+ /// configure this named section.
+ MCSectionWasm *getWasmNamedSection(const Twine &Prefix, const Twine &Suffix,
+ unsigned Type, unsigned Flags);
+
+ MCSectionWasm *createWasmRelSection(const Twine &Name, unsigned Type,
+ unsigned Flags,
+ const MCSymbolWasm *Group);
+
+ void renameWasmSection(MCSectionWasm *Section, StringRef Name);
+
// Create and save a copy of STI and return a reference to the copy.
MCSubtargetInfo &getSubtargetCopy(const MCSubtargetInfo &STI);
@@ -468,6 +536,7 @@ namespace llvm {
const SmallVectorImpl<MCDwarfFile> &getMCDwarfFiles(unsigned CUID = 0) {
return getMCDwarfLineTable(CUID).getMCDwarfFiles();
}
+
const SmallVectorImpl<std::string> &getMCDwarfDirs(unsigned CUID = 0) {
return getMCDwarfLineTable(CUID).getMCDwarfDirs();
}
@@ -478,10 +547,13 @@ namespace llvm {
return true;
return false;
}
+
unsigned getDwarfCompileUnitID() { return DwarfCompileUnitID; }
+
void setDwarfCompileUnitID(unsigned CUIndex) {
DwarfCompileUnitID = CUIndex;
}
+
void setMCLineTableCompilationDir(unsigned CUID, StringRef CompilationDir) {
getMCDwarfLineTable(CUID).setCompilationDir(CompilationDir);
}
@@ -501,6 +573,7 @@ namespace llvm {
CurrentDwarfLoc.setDiscriminator(Discriminator);
DwarfLocSeen = true;
}
+
void clearDwarfLocSeen() { DwarfLocSeen = false; }
bool getDwarfLocSeen() { return DwarfLocSeen; }
@@ -509,20 +582,25 @@ namespace llvm {
bool getGenDwarfForAssembly() { return GenDwarfForAssembly; }
void setGenDwarfForAssembly(bool Value) { GenDwarfForAssembly = Value; }
unsigned getGenDwarfFileNumber() { return GenDwarfFileNumber; }
+
void setGenDwarfFileNumber(unsigned FileNumber) {
GenDwarfFileNumber = FileNumber;
}
+
const SetVector<MCSection *> &getGenDwarfSectionSyms() {
return SectionsForRanges;
}
+
bool addGenDwarfSection(MCSection *Sec) {
return SectionsForRanges.insert(Sec);
}
void finalizeDwarfSections(MCStreamer &MCOS);
+
const std::vector<MCGenDwarfLabelEntry> &getMCGenDwarfLabelEntries() const {
return MCGenDwarfLabelEntries;
}
+
void addMCGenDwarfLabelEntry(const MCGenDwarfLabelEntry &E) {
MCGenDwarfLabelEntries.push_back(E);
}
@@ -532,10 +610,12 @@ namespace llvm {
void setDwarfDebugProducer(StringRef S) { DwarfDebugProducer = S; }
StringRef getDwarfDebugProducer() { return DwarfDebugProducer; }
+
dwarf::DwarfFormat getDwarfFormat() const {
// TODO: Support DWARF64
return dwarf::DWARF32;
}
+
void setDwarfVersion(uint16_t v) { DwarfVersion = v; }
uint16_t getDwarfVersion() const { return DwarfVersion; }
@@ -543,15 +623,18 @@ namespace llvm {
char *getSecureLogFile() { return SecureLogFile; }
raw_fd_ostream *getSecureLog() { return SecureLog.get(); }
- bool getSecureLogUsed() { return SecureLogUsed; }
+
void setSecureLog(std::unique_ptr<raw_fd_ostream> Value) {
SecureLog = std::move(Value);
}
+
+ bool getSecureLogUsed() { return SecureLogUsed; }
void setSecureLogUsed(bool Value) { SecureLogUsed = Value; }
void *allocate(unsigned Size, unsigned Align = 8) {
return Allocator.Allocate(Size, Align);
}
+
void deallocate(void *Ptr) {}
bool hadError() { return HadError; }
@@ -637,4 +720,4 @@ inline void operator delete[](void *Ptr, llvm::MCContext &C) noexcept {
C.deallocate(Ptr);
}
-#endif
+#endif // LLVM_MC_MCCONTEXT_H
diff --git a/contrib/llvm/include/llvm/MC/MCDisassembler/MCDisassembler.h b/contrib/llvm/include/llvm/MC/MCDisassembler/MCDisassembler.h
index 9006d87..7f09c05 100644
--- a/contrib/llvm/include/llvm/MC/MCDisassembler/MCDisassembler.h
+++ b/contrib/llvm/include/llvm/MC/MCDisassembler/MCDisassembler.h
@@ -1,4 +1,4 @@
-//===-- llvm/MC/MCDisassembler.h - Disassembler interface -------*- C++ -*-===//
+//===- llvm/MC/MCDisassembler.h - Disassembler interface --------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -6,20 +6,21 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+
#ifndef LLVM_MC_MCDISASSEMBLER_MCDISASSEMBLER_H
#define LLVM_MC_MCDISASSEMBLER_MCDISASSEMBLER_H
-#include "llvm-c/Disassembler.h"
#include "llvm/MC/MCDisassembler/MCSymbolizer.h"
-#include "llvm/Support/DataTypes.h"
+#include <cstdint>
+#include <memory>
namespace llvm {
template <typename T> class ArrayRef;
+class MCContext;
class MCInst;
class MCSubtargetInfo;
class raw_ostream;
-class MCContext;
/// Superclass for all disassemblers. Consumes a memory region and provides an
/// array of assembly instructions.
@@ -54,7 +55,7 @@ public:
};
MCDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx)
- : Ctx(Ctx), STI(STI), Symbolizer(), CommentStream(nullptr) {}
+ : Ctx(Ctx), STI(STI) {}
virtual ~MCDisassembler();
@@ -67,6 +68,7 @@ public:
/// an invalid instruction.
/// \param Address - The address, in the memory space of region, of the first
/// byte of the instruction.
+ /// \param Bytes - A reference to the actual bytes of the instruction.
/// \param VStream - The stream to print warnings and diagnostic messages on.
/// \param CStream - The stream to print comments and annotations on.
/// \return - MCDisassembler::Success if the instruction is valid,
@@ -105,9 +107,9 @@ public:
// Marked mutable because we cache it inside the disassembler, rather than
// having to pass it around as an argument through all the autogenerated code.
- mutable raw_ostream *CommentStream;
+ mutable raw_ostream *CommentStream = nullptr;
};
-} // namespace llvm
+} // end namespace llvm
-#endif
+#endif // LLVM_MC_MCDISASSEMBLER_MCDISASSEMBLER_H
diff --git a/contrib/llvm/include/llvm/MC/MCDisassembler/MCRelocationInfo.h b/contrib/llvm/include/llvm/MC/MCDisassembler/MCRelocationInfo.h
index 25334f7..7836e88 100644
--- a/contrib/llvm/include/llvm/MC/MCDisassembler/MCRelocationInfo.h
+++ b/contrib/llvm/include/llvm/MC/MCDisassembler/MCRelocationInfo.h
@@ -1,4 +1,4 @@
-//==-- llvm/MC/MCRelocationInfo.h --------------------------------*- C++ -*-==//
+//===- llvm/MC/MCRelocationInfo.h -------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -16,26 +16,20 @@
#ifndef LLVM_MC_MCDISASSEMBLER_MCRELOCATIONINFO_H
#define LLVM_MC_MCDISASSEMBLER_MCRELOCATIONINFO_H
-#include "llvm/Support/Compiler.h"
-
namespace llvm {
-namespace object {
-class RelocationRef;
-}
-class MCExpr;
class MCContext;
+class MCExpr;
/// \brief Create MCExprs from relocations found in an object file.
class MCRelocationInfo {
- MCRelocationInfo(const MCRelocationInfo &) = delete;
- void operator=(const MCRelocationInfo &) = delete;
-
protected:
MCContext &Ctx;
public:
MCRelocationInfo(MCContext &Ctx);
+ MCRelocationInfo(const MCRelocationInfo &) = delete;
+ MCRelocationInfo &operator=(const MCRelocationInfo &) = delete;
virtual ~MCRelocationInfo();
/// \brief Create an MCExpr for the target-specific \p VariantKind.
@@ -46,6 +40,6 @@ public:
unsigned VariantKind);
};
-}
+} // end namespace llvm
-#endif
+#endif // LLVM_MC_MCDISASSEMBLER_MCRELOCATIONINFO_H
diff --git a/contrib/llvm/include/llvm/MC/MCDisassembler/MCSymbolizer.h b/contrib/llvm/include/llvm/MC/MCDisassembler/MCSymbolizer.h
index 713467c..d85cf5e 100644
--- a/contrib/llvm/include/llvm/MC/MCDisassembler/MCSymbolizer.h
+++ b/contrib/llvm/include/llvm/MC/MCDisassembler/MCSymbolizer.h
@@ -1,4 +1,4 @@
-//===-- llvm/MC/MCSymbolizer.h - MCSymbolizer class -------------*- C++ -*-===//
+//===- llvm/MC/MCSymbolizer.h - MCSymbolizer class --------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -17,9 +17,8 @@
#define LLVM_MC_MCDISASSEMBLER_MCSYMBOLIZER_H
#include "llvm/MC/MCDisassembler/MCRelocationInfo.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/DataTypes.h"
-#include <cassert>
+#include <algorithm>
+#include <cstdint>
#include <memory>
namespace llvm {
@@ -38,9 +37,6 @@ class raw_ostream;
/// operands are actually symbolizable, and in what way. I don't think this
/// information exists right now.
class MCSymbolizer {
- MCSymbolizer(const MCSymbolizer &) = delete;
- void operator=(const MCSymbolizer &) = delete;
-
protected:
MCContext &Ctx;
std::unique_ptr<MCRelocationInfo> RelInfo;
@@ -51,6 +47,8 @@ public:
: Ctx(Ctx), RelInfo(std::move(RelInfo)) {
}
+ MCSymbolizer(const MCSymbolizer &) = delete;
+ MCSymbolizer &operator=(const MCSymbolizer &) = delete;
virtual ~MCSymbolizer();
/// \brief Try to add a symbolic operand instead of \p Value to the MCInst.
@@ -80,6 +78,6 @@ public:
uint64_t Address) = 0;
};
-}
+} // end namespace llvm
-#endif
+#endif // LLVM_MC_MCDISASSEMBLER_MCSYMBOLIZER_H
diff --git a/contrib/llvm/include/llvm/MC/MCDwarf.h b/contrib/llvm/include/llvm/MC/MCDwarf.h
index 0c555d3..79f1b95 100644
--- a/contrib/llvm/include/llvm/MC/MCDwarf.h
+++ b/contrib/llvm/include/llvm/MC/MCDwarf.h
@@ -16,24 +16,27 @@
#define LLVM_MC_MCDWARF_H
#include "llvm/ADT/MapVector.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/MC/MCSection.h"
-#include "llvm/Support/Dwarf.h"
+#include <cassert>
+#include <cstdint>
#include <string>
#include <utility>
#include <vector>
namespace llvm {
+
template <typename T> class ArrayRef;
-class raw_ostream;
class MCAsmBackend;
class MCContext;
class MCObjectStreamer;
class MCStreamer;
class MCSymbol;
-class SourceMgr;
+class raw_ostream;
class SMLoc;
+class SourceMgr;
/// \brief Instances of this class represent the name of the dwarf
/// .file directive and its associated dwarf file number in the MC file,
@@ -71,6 +74,7 @@ class MCDwarfLoc {
private: // MCContext manages these
friend class MCContext;
friend class MCDwarfLineEntry;
+
MCDwarfLoc(unsigned fileNum, unsigned line, unsigned column, unsigned flags,
unsigned isa, unsigned discriminator)
: FileNum(fileNum), Line(line), Column(column), Flags(flags), Isa(isa),
@@ -164,10 +168,10 @@ public:
MCLineDivisions[Sec].push_back(LineEntry);
}
- typedef std::vector<MCDwarfLineEntry> MCDwarfLineEntryCollection;
- typedef MCDwarfLineEntryCollection::iterator iterator;
- typedef MCDwarfLineEntryCollection::const_iterator const_iterator;
- typedef MapVector<MCSection *, MCDwarfLineEntryCollection> MCLineDivisionMap;
+ using MCDwarfLineEntryCollection = std::vector<MCDwarfLineEntry>;
+ using iterator = MCDwarfLineEntryCollection::iterator;
+ using const_iterator = MCDwarfLineEntryCollection::const_iterator;
+ using MCLineDivisionMap = MapVector<MCSection *, MCDwarfLineEntryCollection>;
private:
// A collection of MCDwarfLineEntry for each section.
@@ -194,13 +198,14 @@ struct MCDwarfLineTableParams {
};
struct MCDwarfLineTableHeader {
- MCSymbol *Label;
+ MCSymbol *Label = nullptr;
SmallVector<std::string, 3> MCDwarfDirs;
SmallVector<MCDwarfFile, 3> MCDwarfFiles;
StringMap<unsigned> SourceIdMap;
StringRef CompilationDir;
- MCDwarfLineTableHeader() : Label(nullptr) {}
+ MCDwarfLineTableHeader() = default;
+
unsigned getFile(StringRef &Directory, StringRef &FileName,
unsigned FileNumber = 0);
std::pair<MCSymbol *, MCSymbol *> Emit(MCStreamer *MCOS,
@@ -212,13 +217,16 @@ struct MCDwarfLineTableHeader {
class MCDwarfDwoLineTable {
MCDwarfLineTableHeader Header;
+
public:
void setCompilationDir(StringRef CompilationDir) {
Header.CompilationDir = CompilationDir;
}
+
unsigned getFile(StringRef Directory, StringRef FileName) {
return Header.getFile(Directory, FileName);
}
+
void Emit(MCStreamer &MCOS, MCDwarfLineTableParams Params) const;
};
@@ -488,22 +496,19 @@ public:
};
struct MCDwarfFrameInfo {
- MCDwarfFrameInfo()
- : Begin(nullptr), End(nullptr), Personality(nullptr), Lsda(nullptr),
- Instructions(), CurrentCfaRegister(0), PersonalityEncoding(),
- LsdaEncoding(0), CompactUnwindEncoding(0), IsSignalFrame(false),
- IsSimple(false) {}
- MCSymbol *Begin;
- MCSymbol *End;
- const MCSymbol *Personality;
- const MCSymbol *Lsda;
+ MCDwarfFrameInfo() = default;
+
+ MCSymbol *Begin = nullptr;
+ MCSymbol *End = nullptr;
+ const MCSymbol *Personality = nullptr;
+ const MCSymbol *Lsda = nullptr;
std::vector<MCCFIInstruction> Instructions;
- unsigned CurrentCfaRegister;
- unsigned PersonalityEncoding;
- unsigned LsdaEncoding;
- uint32_t CompactUnwindEncoding;
- bool IsSignalFrame;
- bool IsSimple;
+ unsigned CurrentCfaRegister = 0;
+ unsigned PersonalityEncoding = 0;
+ unsigned LsdaEncoding = 0;
+ uint32_t CompactUnwindEncoding = 0;
+ bool IsSignalFrame = false;
+ bool IsSimple = false;
};
class MCDwarfFrameEmitter {
@@ -516,6 +521,7 @@ public:
static void EncodeAdvanceLoc(MCContext &Context, uint64_t AddrDelta,
raw_ostream &OS);
};
+
} // end namespace llvm
-#endif
+#endif // LLVM_MC_MCDWARF_H
diff --git a/contrib/llvm/include/llvm/MC/MCELFObjectWriter.h b/contrib/llvm/include/llvm/MC/MCELFObjectWriter.h
index 376e218..2efd379 100644
--- a/contrib/llvm/include/llvm/MC/MCELFObjectWriter.h
+++ b/contrib/llvm/include/llvm/MC/MCELFObjectWriter.h
@@ -1,4 +1,4 @@
-//===-- llvm/MC/MCELFObjectWriter.h - ELF Object Writer ---------*- C++ -*-===//
+//===- llvm/MC/MCELFObjectWriter.h - ELF Object Writer ----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -11,22 +11,21 @@
#define LLVM_MC_MCELFOBJECTWRITER_H
#include "llvm/ADT/Triple.h"
-#include "llvm/MC/MCValue.h"
-#include "llvm/Support/DataTypes.h"
-#include "llvm/Support/ELF.h"
+#include "llvm/BinaryFormat/ELF.h"
+#include "llvm/Support/Casting.h"
#include "llvm/Support/raw_ostream.h"
+#include <cstdint>
#include <vector>
namespace llvm {
+
class MCAssembler;
class MCContext;
class MCFixup;
-class MCFragment;
class MCObjectWriter;
class MCSymbol;
class MCSymbolELF;
class MCValue;
-class raw_pwrite_stream;
struct ELFRelocationEntry {
uint64_t Offset; // Where is the relocation.
@@ -47,6 +46,7 @@ struct ELFRelocationEntry {
<< ", Addend=" << Addend << ", OriginalSymbol=" << OriginalSymbol
<< ", OriginalAddend=" << OriginalAddend;
}
+
void dump() const { print(errs()); }
};
@@ -58,12 +58,12 @@ class MCELFObjectTargetWriter {
const unsigned IsN64 : 1;
protected:
-
- MCELFObjectTargetWriter(bool Is64Bit_, uint8_t OSABI_,
- uint16_t EMachine_, bool HasRelocationAddend,
- bool IsN64=false);
+ MCELFObjectTargetWriter(bool Is64Bit_, uint8_t OSABI_, uint16_t EMachine_,
+ bool HasRelocationAddend, bool IsN64 = false);
public:
+ virtual ~MCELFObjectTargetWriter() = default;
+
static uint8_t getOSABI(Triple::OSType OSType) {
switch (OSType) {
case Triple::CloudABI:
@@ -76,8 +76,6 @@ public:
}
}
- virtual ~MCELFObjectTargetWriter() {}
-
virtual unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
const MCFixup &Fixup, bool IsPCRel) const = 0;
@@ -144,6 +142,7 @@ public:
MCObjectWriter *createELFObjectWriter(MCELFObjectTargetWriter *MOTW,
raw_pwrite_stream &OS,
bool IsLittleEndian);
-} // End llvm namespace
-#endif
+} // end namespace llvm
+
+#endif // LLVM_MC_MCELFOBJECTWRITER_H
diff --git a/contrib/llvm/include/llvm/MC/MCELFStreamer.h b/contrib/llvm/include/llvm/MC/MCELFStreamer.h
index a5c2638..90434f3 100644
--- a/contrib/llvm/include/llvm/MC/MCELFStreamer.h
+++ b/contrib/llvm/include/llvm/MC/MCELFStreamer.h
@@ -10,27 +10,24 @@
#ifndef LLVM_MC_MCELFSTREAMER_H
#define LLVM_MC_MCELFSTREAMER_H
-#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/MC/MCDirectives.h"
#include "llvm/MC/MCObjectStreamer.h"
-#include "llvm/MC/SectionKind.h"
-#include "llvm/Support/DataTypes.h"
namespace llvm {
+
class MCAsmBackend;
-class MCAssembler;
class MCCodeEmitter;
class MCExpr;
class MCInst;
-class raw_ostream;
class MCELFStreamer : public MCObjectStreamer {
public:
MCELFStreamer(MCContext &Context, MCAsmBackend &TAB, raw_pwrite_stream &OS,
MCCodeEmitter *Emitter)
- : MCObjectStreamer(Context, TAB, OS, Emitter), SeenIdent(false) {}
+ : MCObjectStreamer(Context, TAB, OS, Emitter) {}
- ~MCELFStreamer() override;
+ ~MCELFStreamer() override = default;
/// state management
void reset() override {
@@ -44,7 +41,8 @@ public:
void InitSections(bool NoExecStack) override;
void ChangeSection(MCSection *Section, const MCExpr *Subsection) override;
- void EmitLabel(MCSymbol *Symbol) override;
+ void EmitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override;
+ void EmitLabel(MCSymbol *Symbol, SMLoc Loc, MCFragment *F) override;
void EmitAssemblerFlag(MCAssemblerFlag Flag) override;
void EmitThumbFunc(MCSymbol *Func) override;
void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) override;
@@ -52,10 +50,6 @@ public:
void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) override;
void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment) override;
- void BeginCOFFSymbolDef(const MCSymbol *Symbol) override;
- void EmitCOFFSymbolStorageClass(int StorageClass) override;
- void EmitCOFFSymbolType(int Type) override;
- void EndCOFFSymbolDef() override;
void emitELFSize(MCSymbol *Symbol, const MCExpr *Value) override;
@@ -69,8 +63,6 @@ public:
void EmitValueImpl(const MCExpr *Value, unsigned Size,
SMLoc Loc = SMLoc()) override;
- void EmitFileDirective(StringRef Filename) override;
-
void EmitIdent(StringRef IdentString) override;
void EmitValueToAlignment(unsigned, int64_t, unsigned, unsigned) override;
@@ -91,11 +83,11 @@ private:
/// \brief Merge the content of the fragment \p EF into the fragment \p DF.
void mergeFragment(MCDataFragment *, MCDataFragment *);
- bool SeenIdent;
+ bool SeenIdent = false;
/// BundleGroups - The stack of fragments holding the bundle-locked
/// instructions.
- llvm::SmallVector<MCDataFragment *, 4> BundleGroups;
+ SmallVector<MCDataFragment *, 4> BundleGroups;
};
MCELFStreamer *createARMELFStreamer(MCContext &Context, MCAsmBackend &TAB,
@@ -105,4 +97,4 @@ MCELFStreamer *createARMELFStreamer(MCContext &Context, MCAsmBackend &TAB,
} // end namespace llvm
-#endif
+#endif // LLVM_MC_MCELFSTREAMER_H
diff --git a/contrib/llvm/include/llvm/MC/MCExpr.h b/contrib/llvm/include/llvm/MC/MCExpr.h
index 0d1e675..a91a314 100644
--- a/contrib/llvm/include/llvm/MC/MCExpr.h
+++ b/contrib/llvm/include/llvm/MC/MCExpr.h
@@ -11,10 +11,11 @@
#define LLVM_MC_MCEXPR_H
#include "llvm/ADT/DenseMap.h"
-#include "llvm/Support/Casting.h"
-#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/SMLoc.h"
+#include <cstdint>
namespace llvm {
+
class MCAsmInfo;
class MCAsmLayout;
class MCAssembler;
@@ -27,7 +28,8 @@ class MCSymbol;
class MCValue;
class raw_ostream;
class StringRef;
-typedef DenseMap<const MCSection *, uint64_t> SectionAddrMap;
+
+using SectionAddrMap = DenseMap<const MCSection *, uint64_t>;
/// \brief Base class for the full range of assembler expressions which are
/// needed for parsing.
@@ -43,9 +45,7 @@ public:
private:
ExprKind Kind;
-
- MCExpr(const MCExpr&) = delete;
- void operator=(const MCExpr&) = delete;
+ SMLoc Loc;
bool evaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm,
const MCAsmLayout *Layout,
@@ -56,7 +56,7 @@ private:
const SectionAddrMap *Addrs, bool InSet) const;
protected:
- explicit MCExpr(ExprKind Kind) : Kind(Kind) {}
+ explicit MCExpr(ExprKind Kind, SMLoc Loc) : Kind(Kind), Loc(Loc) {}
bool evaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm,
const MCAsmLayout *Layout,
@@ -64,10 +64,14 @@ protected:
const SectionAddrMap *Addrs, bool InSet) const;
public:
+ MCExpr(const MCExpr &) = delete;
+ MCExpr &operator=(const MCExpr &) = delete;
+
/// \name Accessors
/// @{
ExprKind getKind() const { return Kind; }
+ SMLoc getLoc() const { return Loc; }
/// @}
/// \name Utility Methods
@@ -132,7 +136,7 @@ class MCConstantExpr : public MCExpr {
int64_t Value;
explicit MCConstantExpr(int64_t Value)
- : MCExpr(MCExpr::Constant), Value(Value) {}
+ : MCExpr(MCExpr::Constant, SMLoc()), Value(Value) {}
public:
/// \name Construction
@@ -191,6 +195,8 @@ public:
VK_SIZE, // symbol@SIZE
VK_WEAKREF, // The link between the symbols in .weakref foo, bar
+ VK_X86_ABS8,
+
VK_ARM_NONE,
VK_ARM_GOT_PREL,
VK_ARM_TARGET1,
@@ -265,6 +271,7 @@ public:
VK_Hexagon_IE_GOT,
VK_WebAssembly_FUNCTION, // Function table index, rather than virtual addr
+ VK_WebAssembly_TYPEINDEX,// Type table index
VK_AMDGPU_GOTPCREL32_LO, // symbol@gotpcrel32@lo
VK_AMDGPU_GOTPCREL32_HI, // symbol@gotpcrel32@hi
@@ -289,7 +296,7 @@ private:
const MCSymbol *Symbol;
explicit MCSymbolRefExpr(const MCSymbol *Symbol, VariantKind Kind,
- const MCAsmInfo *MAI);
+ const MCAsmInfo *MAI, SMLoc Loc = SMLoc());
public:
/// \name Construction
@@ -300,7 +307,7 @@ public:
}
static const MCSymbolRefExpr *create(const MCSymbol *Symbol, VariantKind Kind,
- MCContext &Ctx);
+ MCContext &Ctx, SMLoc Loc = SMLoc());
static const MCSymbolRefExpr *create(StringRef Name, VariantKind Kind,
MCContext &Ctx);
@@ -345,26 +352,30 @@ private:
Opcode Op;
const MCExpr *Expr;
- MCUnaryExpr(Opcode Op, const MCExpr *Expr)
- : MCExpr(MCExpr::Unary), Op(Op), Expr(Expr) {}
+ MCUnaryExpr(Opcode Op, const MCExpr *Expr, SMLoc Loc)
+ : MCExpr(MCExpr::Unary, Loc), Op(Op), Expr(Expr) {}
public:
/// \name Construction
/// @{
static const MCUnaryExpr *create(Opcode Op, const MCExpr *Expr,
- MCContext &Ctx);
- static const MCUnaryExpr *createLNot(const MCExpr *Expr, MCContext &Ctx) {
- return create(LNot, Expr, Ctx);
+ MCContext &Ctx, SMLoc Loc = SMLoc());
+
+ static const MCUnaryExpr *createLNot(const MCExpr *Expr, MCContext &Ctx, SMLoc Loc = SMLoc()) {
+ return create(LNot, Expr, Ctx, Loc);
}
- static const MCUnaryExpr *createMinus(const MCExpr *Expr, MCContext &Ctx) {
- return create(Minus, Expr, Ctx);
+
+ static const MCUnaryExpr *createMinus(const MCExpr *Expr, MCContext &Ctx, SMLoc Loc = SMLoc()) {
+ return create(Minus, Expr, Ctx, Loc);
}
- static const MCUnaryExpr *createNot(const MCExpr *Expr, MCContext &Ctx) {
- return create(Not, Expr, Ctx);
+
+ static const MCUnaryExpr *createNot(const MCExpr *Expr, MCContext &Ctx, SMLoc Loc = SMLoc()) {
+ return create(Not, Expr, Ctx, Loc);
}
- static const MCUnaryExpr *createPlus(const MCExpr *Expr, MCContext &Ctx) {
- return create(Plus, Expr, Ctx);
+
+ static const MCUnaryExpr *createPlus(const MCExpr *Expr, MCContext &Ctx, SMLoc Loc = SMLoc()) {
+ return create(Plus, Expr, Ctx, Loc);
}
/// @}
@@ -417,87 +428,108 @@ private:
Opcode Op;
const MCExpr *LHS, *RHS;
- MCBinaryExpr(Opcode Op, const MCExpr *LHS, const MCExpr *RHS)
- : MCExpr(MCExpr::Binary), Op(Op), LHS(LHS), RHS(RHS) {}
+ MCBinaryExpr(Opcode Op, const MCExpr *LHS, const MCExpr *RHS,
+ SMLoc Loc = SMLoc())
+ : MCExpr(MCExpr::Binary, Loc), Op(Op), LHS(LHS), RHS(RHS) {}
public:
/// \name Construction
/// @{
static const MCBinaryExpr *create(Opcode Op, const MCExpr *LHS,
- const MCExpr *RHS, MCContext &Ctx);
+ const MCExpr *RHS, MCContext &Ctx,
+ SMLoc Loc = SMLoc());
+
static const MCBinaryExpr *createAdd(const MCExpr *LHS, const MCExpr *RHS,
MCContext &Ctx) {
return create(Add, LHS, RHS, Ctx);
}
+
static const MCBinaryExpr *createAnd(const MCExpr *LHS, const MCExpr *RHS,
MCContext &Ctx) {
return create(And, LHS, RHS, Ctx);
}
+
static const MCBinaryExpr *createDiv(const MCExpr *LHS, const MCExpr *RHS,
MCContext &Ctx) {
return create(Div, LHS, RHS, Ctx);
}
+
static const MCBinaryExpr *createEQ(const MCExpr *LHS, const MCExpr *RHS,
MCContext &Ctx) {
return create(EQ, LHS, RHS, Ctx);
}
+
static const MCBinaryExpr *createGT(const MCExpr *LHS, const MCExpr *RHS,
MCContext &Ctx) {
return create(GT, LHS, RHS, Ctx);
}
+
static const MCBinaryExpr *createGTE(const MCExpr *LHS, const MCExpr *RHS,
MCContext &Ctx) {
return create(GTE, LHS, RHS, Ctx);
}
+
static const MCBinaryExpr *createLAnd(const MCExpr *LHS, const MCExpr *RHS,
MCContext &Ctx) {
return create(LAnd, LHS, RHS, Ctx);
}
+
static const MCBinaryExpr *createLOr(const MCExpr *LHS, const MCExpr *RHS,
MCContext &Ctx) {
return create(LOr, LHS, RHS, Ctx);
}
+
static const MCBinaryExpr *createLT(const MCExpr *LHS, const MCExpr *RHS,
MCContext &Ctx) {
return create(LT, LHS, RHS, Ctx);
}
+
static const MCBinaryExpr *createLTE(const MCExpr *LHS, const MCExpr *RHS,
MCContext &Ctx) {
return create(LTE, LHS, RHS, Ctx);
}
+
static const MCBinaryExpr *createMod(const MCExpr *LHS, const MCExpr *RHS,
MCContext &Ctx) {
return create(Mod, LHS, RHS, Ctx);
}
+
static const MCBinaryExpr *createMul(const MCExpr *LHS, const MCExpr *RHS,
MCContext &Ctx) {
return create(Mul, LHS, RHS, Ctx);
}
+
static const MCBinaryExpr *createNE(const MCExpr *LHS, const MCExpr *RHS,
MCContext &Ctx) {
return create(NE, LHS, RHS, Ctx);
}
+
static const MCBinaryExpr *createOr(const MCExpr *LHS, const MCExpr *RHS,
MCContext &Ctx) {
return create(Or, LHS, RHS, Ctx);
}
+
static const MCBinaryExpr *createShl(const MCExpr *LHS, const MCExpr *RHS,
MCContext &Ctx) {
return create(Shl, LHS, RHS, Ctx);
}
+
static const MCBinaryExpr *createAShr(const MCExpr *LHS, const MCExpr *RHS,
MCContext &Ctx) {
return create(AShr, LHS, RHS, Ctx);
}
+
static const MCBinaryExpr *createLShr(const MCExpr *LHS, const MCExpr *RHS,
MCContext &Ctx) {
return create(LShr, LHS, RHS, Ctx);
}
+
static const MCBinaryExpr *createSub(const MCExpr *LHS, const MCExpr *RHS,
MCContext &Ctx) {
return create(Sub, LHS, RHS, Ctx);
}
+
static const MCBinaryExpr *createXor(const MCExpr *LHS, const MCExpr *RHS,
MCContext &Ctx) {
return create(Xor, LHS, RHS, Ctx);
@@ -530,9 +562,11 @@ public:
/// MCExprs are bump pointer allocated and not destructed.
class MCTargetExpr : public MCExpr {
virtual void anchor();
+
protected:
- MCTargetExpr() : MCExpr(Target) {}
- virtual ~MCTargetExpr() {}
+ MCTargetExpr() : MCExpr(Target, SMLoc()) {}
+ virtual ~MCTargetExpr() = default;
+
public:
virtual void printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const = 0;
virtual bool evaluateAsRelocatableImpl(MCValue &Res,
@@ -550,4 +584,4 @@ public:
} // end namespace llvm
-#endif
+#endif // LLVM_MC_MCEXPR_H
diff --git a/contrib/llvm/include/llvm/MC/MCFixup.h b/contrib/llvm/include/llvm/MC/MCFixup.h
index b493ca0..b83086c 100644
--- a/contrib/llvm/include/llvm/MC/MCFixup.h
+++ b/contrib/llvm/include/llvm/MC/MCFixup.h
@@ -69,7 +69,7 @@ class MCFixup {
/// an instruction or an assembler directive.
const MCExpr *Value;
- /// The byte index of start of the relocation inside the encoded instruction.
+ /// The byte index of start of the relocation inside the MCFragment.
uint32_t Offset;
/// The target dependent kind of fixup item this is. The kind is used to
diff --git a/contrib/llvm/include/llvm/MC/MCFragment.h b/contrib/llvm/include/llvm/MC/MCFragment.h
index edb740f..284ca50 100644
--- a/contrib/llvm/include/llvm/MC/MCFragment.h
+++ b/contrib/llvm/include/llvm/MC/MCFragment.h
@@ -10,25 +10,26 @@
#ifndef LLVM_MC_MCFRAGMENT_H
#define LLVM_MC_MCFRAGMENT_H
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallString.h"
-#include "llvm/ADT/ilist.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/ilist_node.h"
-#include "llvm/ADT/iterator.h"
#include "llvm/MC/MCFixup.h"
#include "llvm/MC/MCInst.h"
+#include "llvm/Support/SMLoc.h"
+#include <cstdint>
+#include <utility>
namespace llvm {
+
class MCSection;
-class MCSymbol;
class MCSubtargetInfo;
+class MCSymbol;
class MCFragment : public ilist_node_with_parent<MCFragment, MCSection> {
friend class MCAsmLayout;
- MCFragment() = delete;
- MCFragment(const MCFragment &) = delete;
- void operator=(const MCFragment &) = delete;
-
public:
enum FragmentType : uint8_t {
FT_Align,
@@ -86,6 +87,10 @@ protected:
~MCFragment();
public:
+ MCFragment() = delete;
+ MCFragment(const MCFragment &) = delete;
+ MCFragment &operator=(const MCFragment &) = delete;
+
/// Destroys the current fragment.
///
/// This must be used instead of delete as MCFragment is non-virtual.
@@ -125,13 +130,14 @@ public:
/// \brief Return true if given frgment has FT_Dummy type.
bool isDummy() const { return Kind == FT_Dummy; }
- void dump();
+ void dump() const;
};
class MCDummyFragment : public MCFragment {
public:
explicit MCDummyFragment(MCSection *Sec)
- : MCFragment(FT_Dummy, false, 0, Sec){};
+ : MCFragment(FT_Dummy, false, 0, Sec) {}
+
static bool classof(const MCFragment *F) { return F->getKind() == FT_Dummy; }
};
@@ -194,8 +200,8 @@ protected:
Sec) {}
public:
- typedef SmallVectorImpl<MCFixup>::const_iterator const_fixup_iterator;
- typedef SmallVectorImpl<MCFixup>::iterator fixup_iterator;
+ using const_fixup_iterator = SmallVectorImpl<MCFixup>::const_iterator;
+ using fixup_iterator = SmallVectorImpl<MCFixup>::iterator;
SmallVectorImpl<MCFixup> &getFixups() { return Fixups; }
const SmallVectorImpl<MCFixup> &getFixups() const { return Fixups; }
@@ -271,7 +277,6 @@ public:
};
class MCAlignFragment : public MCFragment {
-
/// Alignment - The alignment to ensure, in bytes.
unsigned Alignment;
@@ -319,7 +324,6 @@ public:
};
class MCFillFragment : public MCFragment {
-
/// Value to use for filling bytes.
uint8_t Value;
@@ -339,7 +343,6 @@ public:
};
class MCOrgFragment : public MCFragment {
-
/// Offset - The offset this fragment should start at.
const MCExpr *Offset;
@@ -371,7 +374,6 @@ public:
};
class MCLEBFragment : public MCFragment {
-
/// Value - The value this fragment should contain.
const MCExpr *Value;
@@ -404,7 +406,6 @@ public:
};
class MCDwarfLineAddrFragment : public MCFragment {
-
/// LineDelta - the value of the difference between the two line numbers
/// between two .loc dwarf directives.
int64_t LineDelta;
@@ -441,7 +442,6 @@ public:
};
class MCDwarfCallFrameFragment : public MCFragment {
-
/// AddrDelta - The expression for the difference of the two symbols that
/// make up the address delta between two .cfi_* dwarf directives.
const MCExpr *AddrDelta;
@@ -561,4 +561,4 @@ public:
} // end namespace llvm
-#endif
+#endif // LLVM_MC_MCFRAGMENT_H
diff --git a/contrib/llvm/include/llvm/MC/MCInst.h b/contrib/llvm/include/llvm/MC/MCInst.h
index 4688b5f..9bf440e 100644
--- a/contrib/llvm/include/llvm/MC/MCInst.h
+++ b/contrib/llvm/include/llvm/MC/MCInst.h
@@ -1,4 +1,4 @@
-//===-- llvm/MC/MCInst.h - MCInst class -------------------------*- C++ -*-===//
+//===- llvm/MC/MCInst.h - MCInst class --------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -18,15 +18,17 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/DataTypes.h"
#include "llvm/Support/SMLoc.h"
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
namespace llvm {
-class raw_ostream;
-class MCAsmInfo;
-class MCInstPrinter;
+
class MCExpr;
class MCInst;
+class MCInstPrinter;
+class raw_ostream;
/// \brief Instances of this class represent operands of the MCInst class.
/// This is a simple discriminated union.
@@ -39,7 +41,7 @@ class MCOperand {
kExpr, ///< Relocatable immediate operand.
kInst ///< Sub-instruction operand.
};
- MachineOperandType Kind;
+ MachineOperandType Kind = kInvalid;
union {
unsigned RegVal;
@@ -50,7 +52,7 @@ class MCOperand {
};
public:
- MCOperand() : Kind(kInvalid), FPImmVal(0.0) {}
+ MCOperand() : FPImmVal(0.0) {}
bool isValid() const { return Kind != kInvalid; }
bool isReg() const { return Kind == kRegister; }
@@ -75,6 +77,7 @@ public:
assert(isImm() && "This is not an immediate");
return ImmVal;
}
+
void setImm(int64_t Val) {
assert(isImm() && "This is not an immediate");
ImmVal = Val;
@@ -94,6 +97,7 @@ public:
assert(isExpr() && "This is not an expression");
return ExprVal;
}
+
void setExpr(const MCExpr *Val) {
assert(isExpr() && "This is not an expression");
ExprVal = Val;
@@ -103,6 +107,7 @@ public:
assert(isInst() && "This is not a sub-instruction");
return InstVal;
}
+
void setInst(const MCInst *Val) {
assert(isInst() && "This is not a sub-instruction");
InstVal = Val;
@@ -114,24 +119,28 @@ public:
Op.RegVal = Reg;
return Op;
}
+
static MCOperand createImm(int64_t Val) {
MCOperand Op;
Op.Kind = kImmediate;
Op.ImmVal = Val;
return Op;
}
+
static MCOperand createFPImm(double Val) {
MCOperand Op;
Op.Kind = kFPImmediate;
Op.FPImmVal = Val;
return Op;
}
+
static MCOperand createExpr(const MCExpr *Val) {
MCOperand Op;
Op.Kind = kExpr;
Op.ExprVal = Val;
return Op;
}
+
static MCOperand createInst(const MCInst *Val) {
MCOperand Op;
Op.Kind = kInst;
@@ -148,12 +157,12 @@ template <> struct isPodLike<MCOperand> { static const bool value = true; };
/// \brief Instances of this class represent a single low-level machine
/// instruction.
class MCInst {
- unsigned Opcode;
+ unsigned Opcode = 0;
SMLoc Loc;
SmallVector<MCOperand, 8> Operands;
public:
- MCInst() : Opcode(0) {}
+ MCInst() = default;
void setOpcode(unsigned Op) { Opcode = Op; }
unsigned getOpcode() const { return Opcode; }
@@ -167,8 +176,9 @@ public:
void addOperand(const MCOperand &Op) { Operands.push_back(Op); }
- typedef SmallVectorImpl<MCOperand>::iterator iterator;
- typedef SmallVectorImpl<MCOperand>::const_iterator const_iterator;
+ using iterator = SmallVectorImpl<MCOperand>::iterator;
+ using const_iterator = SmallVectorImpl<MCOperand>::const_iterator;
+
void clear() { Operands.clear(); }
void erase(iterator I) { Operands.erase(I); }
size_t size() const { return Operands.size(); }
@@ -176,6 +186,7 @@ public:
const_iterator begin() const { return Operands.begin(); }
iterator end() { return Operands.end(); }
const_iterator end() const { return Operands.end(); }
+
iterator insert(iterator I, const MCOperand &Op) {
return Operands.insert(I, Op);
}
@@ -202,4 +213,4 @@ inline raw_ostream& operator<<(raw_ostream &OS, const MCInst &MI) {
} // end namespace llvm
-#endif
+#endif // LLVM_MC_MCINST_H
diff --git a/contrib/llvm/include/llvm/MC/MCInstPrinter.h b/contrib/llvm/include/llvm/MC/MCInstPrinter.h
index 320b280..0694030 100644
--- a/contrib/llvm/include/llvm/MC/MCInstPrinter.h
+++ b/contrib/llvm/include/llvm/MC/MCInstPrinter.h
@@ -16,12 +16,12 @@
namespace llvm {
template <typename T> class ArrayRef;
-class MCInst;
-class raw_ostream;
class MCAsmInfo;
+class MCInst;
class MCInstrInfo;
class MCRegisterInfo;
class MCSubtargetInfo;
+class raw_ostream;
class StringRef;
/// Convert `Bytes' to a hex string and output to `OS'
@@ -43,28 +43,26 @@ protected:
/// \brief A stream that comments can be emitted to if desired. Each comment
/// must end with a newline. This will be null if verbose assembly emission
/// is disable.
- raw_ostream *CommentStream;
+ raw_ostream *CommentStream = nullptr;
const MCAsmInfo &MAI;
const MCInstrInfo &MII;
const MCRegisterInfo &MRI;
/// True if we are printing marked up assembly.
- bool UseMarkup;
+ bool UseMarkup = false;
/// True if we are printing immediates as hex.
- bool PrintImmHex;
+ bool PrintImmHex = false;
/// Which style to use for printing hexadecimal values.
- HexStyle::Style PrintHexStyle;
+ HexStyle::Style PrintHexStyle = HexStyle::C;
/// Utility function for printing annotations.
void printAnnotation(raw_ostream &OS, StringRef Annot);
public:
MCInstPrinter(const MCAsmInfo &mai, const MCInstrInfo &mii,
- const MCRegisterInfo &mri)
- : CommentStream(nullptr), MAI(mai), MII(mii), MRI(mri), UseMarkup(false),
- PrintImmHex(false), PrintHexStyle(HexStyle::C) {}
+ const MCRegisterInfo &mri) : MAI(mai), MII(mii), MRI(mri) {}
virtual ~MCInstPrinter();
diff --git a/contrib/llvm/include/llvm/MC/MCInstrAnalysis.h b/contrib/llvm/include/llvm/MC/MCInstrAnalysis.h
index 8f5159e..dd3e1df 100644
--- a/contrib/llvm/include/llvm/MC/MCInstrAnalysis.h
+++ b/contrib/llvm/include/llvm/MC/MCInstrAnalysis.h
@@ -1,4 +1,4 @@
-//===-- llvm/MC/MCInstrAnalysis.h - InstrDesc target hooks ------*- C++ -*-===//
+//===- llvm/MC/MCInstrAnalysis.h - InstrDesc target hooks -------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -18,18 +18,19 @@
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstrDesc.h"
#include "llvm/MC/MCInstrInfo.h"
+#include <cstdint>
namespace llvm {
class MCInstrAnalysis {
protected:
friend class Target;
+
const MCInstrInfo *Info;
public:
MCInstrAnalysis(const MCInstrInfo *Info) : Info(Info) {}
-
- virtual ~MCInstrAnalysis() {}
+ virtual ~MCInstrAnalysis() = default;
virtual bool isBranch(const MCInst &Inst) const {
return Info->get(Inst.getOpcode()).isBranch();
@@ -66,6 +67,6 @@ public:
uint64_t &Target) const;
};
-} // End llvm namespace
+} // end namespace llvm
-#endif
+#endif // LLVM_MC_MCINSTRANALYSIS_H
diff --git a/contrib/llvm/include/llvm/MC/MCInstrDesc.h b/contrib/llvm/include/llvm/MC/MCInstrDesc.h
index 340d825..9150a8b 100644
--- a/contrib/llvm/include/llvm/MC/MCInstrDesc.h
+++ b/contrib/llvm/include/llvm/MC/MCInstrDesc.h
@@ -209,6 +209,15 @@ public:
/// well.
unsigned getNumOperands() const { return NumOperands; }
+ using const_opInfo_iterator = const MCOperandInfo *;
+
+ const_opInfo_iterator opInfo_begin() const { return OpInfo; }
+ const_opInfo_iterator opInfo_end() const { return OpInfo + NumOperands; }
+
+ iterator_range<const_opInfo_iterator> operands() const {
+ return make_range(opInfo_begin(), opInfo_end());
+ }
+
/// \brief Return the number of MachineOperands that are register
/// definitions. Register definitions always occur at the start of the
/// machine operand list. This is the number of "outs" in the .td file,
diff --git a/contrib/llvm/include/llvm/MC/MCInstrItineraries.h b/contrib/llvm/include/llvm/MC/MCInstrItineraries.h
index 1fb276a..4443dd1 100644
--- a/contrib/llvm/include/llvm/MC/MCInstrItineraries.h
+++ b/contrib/llvm/include/llvm/MC/MCInstrItineraries.h
@@ -1,4 +1,4 @@
-//===-- llvm/MC/MCInstrItineraries.h - Scheduling ---------------*- C++ -*-===//
+//===- llvm/MC/MCInstrItineraries.h - Scheduling ----------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -88,7 +88,6 @@ struct InstrStage {
}
};
-
//===----------------------------------------------------------------------===//
/// An itinerary represents the scheduling information for an instruction.
/// This includes a set of stages occupied by the instruction and the pipeline
@@ -102,23 +101,20 @@ struct InstrItinerary {
unsigned LastOperandCycle; ///< Index of last + 1 operand rd/wr
};
-
//===----------------------------------------------------------------------===//
/// Itinerary data supplied by a subtarget to be used by a target.
///
class InstrItineraryData {
public:
- MCSchedModel SchedModel; ///< Basic machine properties.
- const InstrStage *Stages; ///< Array of stages selected
- const unsigned *OperandCycles; ///< Array of operand cycles selected
- const unsigned *Forwardings; ///< Array of pipeline forwarding paths
- const InstrItinerary *Itineraries; ///< Array of itineraries selected
-
- /// Ctors.
- InstrItineraryData() : SchedModel(MCSchedModel::GetDefaultSchedModel()),
- Stages(nullptr), OperandCycles(nullptr),
- Forwardings(nullptr), Itineraries(nullptr) {}
-
+ MCSchedModel SchedModel =
+ MCSchedModel::GetDefaultSchedModel(); ///< Basic machine properties.
+ const InstrStage *Stages = nullptr; ///< Array of stages selected
+ const unsigned *OperandCycles = nullptr; ///< Array of operand cycles selected
+ const unsigned *Forwardings = nullptr; ///< Array of pipeline forwarding paths
+ const InstrItinerary *Itineraries =
+ nullptr; ///< Array of itineraries selected
+
+ InstrItineraryData() = default;
InstrItineraryData(const MCSchedModel &SM, const InstrStage *S,
const unsigned *OS, const unsigned *F)
: SchedModel(SM), Stages(S), OperandCycles(OS), Forwardings(F),
@@ -234,6 +230,6 @@ public:
}
};
-} // End llvm namespace
+} // end namespace llvm
-#endif
+#endif // LLVM_MC_MCINSTRITINERARIES_H
diff --git a/contrib/llvm/include/llvm/MC/MCLabel.h b/contrib/llvm/include/llvm/MC/MCLabel.h
index a12473f..b6579fd 100644
--- a/contrib/llvm/include/llvm/MC/MCLabel.h
+++ b/contrib/llvm/include/llvm/MC/MCLabel.h
@@ -14,10 +14,8 @@
#ifndef LLVM_MC_MCLABEL_H
#define LLVM_MC_MCLABEL_H
-#include "llvm/Support/Compiler.h"
-
namespace llvm {
-class MCContext;
+
class raw_ostream;
/// \brief Instances of this class represent a label name in the MC file,
@@ -29,12 +27,13 @@ class MCLabel {
private: // MCContext creates and uniques these.
friend class MCContext;
+
MCLabel(unsigned instance) : Instance(instance) {}
+public:
MCLabel(const MCLabel &) = delete;
- void operator=(const MCLabel &) = delete;
+ MCLabel &operator=(const MCLabel &) = delete;
-public:
/// \brief Get the current instance of this Directional Local Label.
unsigned getInstance() const { return Instance; }
@@ -52,6 +51,7 @@ inline raw_ostream &operator<<(raw_ostream &OS, const MCLabel &Label) {
Label.print(OS);
return OS;
}
+
} // end namespace llvm
-#endif
+#endif // LLVM_MC_MCLABEL_H
diff --git a/contrib/llvm/include/llvm/MC/MCLinkerOptimizationHint.h b/contrib/llvm/include/llvm/MC/MCLinkerOptimizationHint.h
index 200bb93..f0fd07f 100644
--- a/contrib/llvm/include/llvm/MC/MCLinkerOptimizationHint.h
+++ b/contrib/llvm/include/llvm/MC/MCLinkerOptimizationHint.h
@@ -21,13 +21,14 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/raw_ostream.h"
+#include <cassert>
+#include <cstdint>
namespace llvm {
-// Forward declarations.
+class MachObjectWriter;
class MCAsmLayout;
class MCSymbol;
-class MachObjectWriter;
/// Linker Optimization Hint Type.
enum MCLOHType {
@@ -110,7 +111,7 @@ class MCLOHDirective {
const MCAsmLayout &Layout) const;
public:
- typedef SmallVectorImpl<MCSymbol *> LOHArgs;
+ using LOHArgs = SmallVectorImpl<MCSymbol *>;
MCLOHDirective(MCLOHType Kind, const LOHArgs &Args)
: Kind(Kind), Args(Args.begin(), Args.end()) {
@@ -133,15 +134,15 @@ public:
class MCLOHContainer {
/// Keep track of the emit size of all the LOHs.
- mutable uint64_t EmitSize;
+ mutable uint64_t EmitSize = 0;
/// Keep track of all LOH directives.
SmallVector<MCLOHDirective, 32> Directives;
public:
- typedef SmallVectorImpl<MCLOHDirective> LOHDirectives;
+ using LOHDirectives = SmallVectorImpl<MCLOHDirective>;
- MCLOHContainer() : EmitSize(0) {}
+ MCLOHContainer() = default;
/// Const accessor to the directives.
const LOHDirectives &getDirectives() const {
@@ -178,9 +179,9 @@ public:
};
// Add types for specialized template using MCSymbol.
-typedef MCLOHDirective::LOHArgs MCLOHArgs;
-typedef MCLOHContainer::LOHDirectives MCLOHDirectives;
+using MCLOHArgs = MCLOHDirective::LOHArgs;
+using MCLOHDirectives = MCLOHContainer::LOHDirectives;
} // end namespace llvm
-#endif
+#endif // LLVM_MC_MCLINKEROPTIMIZATIONHINT_H
diff --git a/contrib/llvm/include/llvm/MC/MCMachObjectWriter.h b/contrib/llvm/include/llvm/MC/MCMachObjectWriter.h
index 1a685db..42dc90d 100644
--- a/contrib/llvm/include/llvm/MC/MCMachObjectWriter.h
+++ b/contrib/llvm/include/llvm/MC/MCMachObjectWriter.h
@@ -1,4 +1,4 @@
-//===-- llvm/MC/MCMachObjectWriter.h - Mach Object Writer -------*- C++ -*-===//
+//===- llvm/MC/MCMachObjectWriter.h - Mach Object Writer --------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -11,12 +11,15 @@
#define LLVM_MC_MCMACHOBJECTWRITER_H
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/BinaryFormat/MachO.h"
#include "llvm/MC/MCExpr.h"
-#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCObjectWriter.h"
+#include "llvm/MC/MCSection.h"
#include "llvm/MC/StringTableBuilder.h"
-#include "llvm/Support/DataTypes.h"
-#include "llvm/Support/MachO.h"
+#include <cstdint>
+#include <memory>
+#include <string>
#include <vector>
namespace llvm {
@@ -95,8 +98,8 @@ class MachObjectWriter : public MCObjectWriter {
: Sym(Sym), MRE(MRE) {}
};
- llvm::DenseMap<const MCSection *, std::vector<RelAndSymbol>> Relocations;
- llvm::DenseMap<const MCSection *, unsigned> IndirectSymBase;
+ DenseMap<const MCSection *, std::vector<RelAndSymbol>> Relocations;
+ DenseMap<const MCSection *, unsigned> IndirectSymBase;
SectionAddrMap SectionAddress;
@@ -230,8 +233,7 @@ public:
void recordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout,
const MCFragment *Fragment, const MCFixup &Fixup,
- MCValue Target, bool &IsPCRel,
- uint64_t &FixedValue) override;
+ MCValue Target, uint64_t &FixedValue) override;
void bindIndirectSymbols(MCAssembler &Asm);
@@ -271,6 +273,6 @@ MCObjectWriter *createMachObjectWriter(MCMachObjectTargetWriter *MOTW,
raw_pwrite_stream &OS,
bool IsLittleEndian);
-} // End llvm namespace
+} // end namespace llvm
-#endif
+#endif // LLVM_MC_MCMACHOBJECTWRITER_H
diff --git a/contrib/llvm/include/llvm/MC/MCObjectFileInfo.h b/contrib/llvm/include/llvm/MC/MCObjectFileInfo.h
index 9aa8812..4d63444 100644
--- a/contrib/llvm/include/llvm/MC/MCObjectFileInfo.h
+++ b/contrib/llvm/include/llvm/MC/MCObjectFileInfo.h
@@ -109,6 +109,9 @@ protected:
MCSection *DwarfLineDWOSection;
MCSection *DwarfLocDWOSection;
MCSection *DwarfStrOffDWOSection;
+
+ /// The DWARF v5 string offset and address table sections.
+ MCSection *DwarfStrOffSection;
MCSection *DwarfAddrSection;
// These are for Fission DWP files.
@@ -129,7 +132,7 @@ protected:
/// it'll go here.
MCSection *TLSExtraDataSection;
- /// Section directive for Thread Local data. ELF, MachO and COFF.
+ /// Section directive for Thread Local data. ELF, MachO, COFF, and Wasm.
MCSection *TLSDataSection; // Defaults to ".tdata".
/// Section directive for Thread Local uninitialized data.
@@ -260,6 +263,7 @@ public:
MCSection *getDwarfLineDWOSection() const { return DwarfLineDWOSection; }
MCSection *getDwarfLocDWOSection() const { return DwarfLocDWOSection; }
MCSection *getDwarfStrOffDWOSection() const { return DwarfStrOffDWOSection; }
+ MCSection *getDwarfStrOffSection() const { return DwarfStrOffSection; }
MCSection *getDwarfAddrSection() const { return DwarfAddrSection; }
MCSection *getDwarfCUIndexSection() const { return DwarfCUIndexSection; }
MCSection *getDwarfTUIndexSection() const { return DwarfTUIndexSection; }
@@ -338,7 +342,7 @@ public:
return EHFrameSection;
}
- enum Environment { IsMachO, IsELF, IsCOFF };
+ enum Environment { IsMachO, IsELF, IsCOFF, IsWasm };
Environment getObjectFileType() const { return Env; }
bool isPositionIndependent() const { return PositionIndependent; }
@@ -353,6 +357,7 @@ private:
void initMachOMCObjectFileInfo(const Triple &T);
void initELFMCObjectFileInfo(const Triple &T);
void initCOFFMCObjectFileInfo(const Triple &T);
+ void initWasmMCObjectFileInfo(const Triple &T);
public:
const Triple &getTargetTriple() const { return TT; }
diff --git a/contrib/llvm/include/llvm/MC/MCObjectStreamer.h b/contrib/llvm/include/llvm/MC/MCObjectStreamer.h
index f9111b7..7c1189e 100644
--- a/contrib/llvm/include/llvm/MC/MCObjectStreamer.h
+++ b/contrib/llvm/include/llvm/MC/MCObjectStreamer.h
@@ -89,7 +89,8 @@ public:
/// \name MCStreamer Interface
/// @{
- void EmitLabel(MCSymbol *Symbol) override;
+ void EmitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override;
+ virtual void EmitLabel(MCSymbol *Symbol, SMLoc Loc, MCFragment *F);
void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) override;
void EmitValueImpl(const MCExpr *Value, unsigned Size,
SMLoc Loc = SMLoc()) override;
@@ -97,7 +98,8 @@ public:
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 EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI,
+ bool = false) override;
/// \brief Emit an instruction to a special fragment, because this instruction
/// can change its size during relaxation.
@@ -152,6 +154,7 @@ public:
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 FinishImpl() override;
diff --git a/contrib/llvm/include/llvm/MC/MCObjectWriter.h b/contrib/llvm/include/llvm/MC/MCObjectWriter.h
index 0ecebe4..cd90690 100644
--- a/contrib/llvm/include/llvm/MC/MCObjectWriter.h
+++ b/contrib/llvm/include/llvm/MC/MCObjectWriter.h
@@ -1,4 +1,4 @@
-//===-- llvm/MC/MCObjectWriter.h - Object File Writer Interface -*- C++ -*-===//
+//===- llvm/MC/MCObjectWriter.h - Object File Writer Interface --*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -11,13 +11,15 @@
#define LLVM_MC_MCOBJECTWRITER_H
#include "llvm/ADT/SmallVector.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/DataTypes.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Endian.h"
#include "llvm/Support/EndianStream.h"
#include "llvm/Support/raw_ostream.h"
#include <cassert>
+#include <cstdint>
namespace llvm {
+
class MCAsmLayout;
class MCAssembler;
class MCFixup;
@@ -38,15 +40,12 @@ class MCValue;
/// The object writer also contains a number of helper methods for writing
/// binary data to the output stream.
class MCObjectWriter {
- MCObjectWriter(const MCObjectWriter &) = delete;
- void operator=(const MCObjectWriter &) = delete;
-
raw_pwrite_stream *OS;
protected:
unsigned IsLittleEndian : 1;
-protected: // Can only create subclasses.
+ // Can only create subclasses.
MCObjectWriter(raw_pwrite_stream &OS, bool IsLittleEndian)
: OS(&OS), IsLittleEndian(IsLittleEndian) {}
@@ -55,6 +54,8 @@ protected: // Can only create subclasses.
}
public:
+ MCObjectWriter(const MCObjectWriter &) = delete;
+ MCObjectWriter &operator=(const MCObjectWriter &) = delete;
virtual ~MCObjectWriter();
/// lifetime management
@@ -85,7 +86,7 @@ public:
virtual void recordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout,
const MCFragment *Fragment,
const MCFixup &Fixup, MCValue Target,
- bool &IsPCRel, uint64_t &FixedValue) = 0;
+ uint64_t &FixedValue) = 0;
/// Check whether the difference (A - B) between two symbol references is
/// fully resolved.
@@ -108,11 +109,6 @@ public:
bool InSet,
bool IsPCRel) const;
- /// True if this symbol (which is a variable) is weak. This is not
- /// just STB_WEAK, but more generally whether or not we can evaluate
- /// past it.
- virtual bool isWeak(const MCSymbol &Sym) const;
-
/// Write the object file.
///
/// This routine is called by the assembler after layout and relaxation is
@@ -199,6 +195,6 @@ public:
/// @}
};
-} // End llvm namespace
+} // end namespace llvm
-#endif
+#endif // LLVM_MC_MCOBJECTWRITER_H
diff --git a/contrib/llvm/include/llvm/MC/MCParser/AsmCond.h b/contrib/llvm/include/llvm/MC/MCParser/AsmCond.h
index a918b56..8e7bfc5 100644
--- a/contrib/llvm/include/llvm/MC/MCParser/AsmCond.h
+++ b/contrib/llvm/include/llvm/MC/MCParser/AsmCond.h
@@ -28,13 +28,13 @@ public:
ElseCond // inside else conditional
};
- ConditionalAssemblyType TheCond;
- bool CondMet;
- bool Ignore;
+ ConditionalAssemblyType TheCond = NoCond;
+ bool CondMet = false;
+ bool Ignore = false;
- AsmCond() : TheCond(NoCond), CondMet(false), Ignore(false) {}
+ AsmCond() = default;
};
} // end namespace llvm
-#endif
+#endif // LLVM_MC_MCPARSER_ASMCOND_H
diff --git a/contrib/llvm/include/llvm/MC/MCParser/AsmLexer.h b/contrib/llvm/include/llvm/MC/MCParser/AsmLexer.h
index 029598c..207183a 100644
--- a/contrib/llvm/include/llvm/MC/MCParser/AsmLexer.h
+++ b/contrib/llvm/include/llvm/MC/MCParser/AsmLexer.h
@@ -16,25 +16,22 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/MC/MCParser/MCAsmLexer.h"
-#include "llvm/Support/DataTypes.h"
#include <string>
namespace llvm {
-class MemoryBuffer;
+
class MCAsmInfo;
/// AsmLexer - Lexer class for assembly files.
class AsmLexer : public MCAsmLexer {
const MCAsmInfo &MAI;
- const char *CurPtr;
+ const char *CurPtr = nullptr;
StringRef CurBuf;
- bool IsAtStartOfLine;
- bool IsAtStartOfStatement;
- bool IsParsingMSInlineAsm;
- bool IsPeeking;
- void operator=(const AsmLexer&) = delete;
- AsmLexer(const AsmLexer&) = delete;
+ bool IsAtStartOfLine = true;
+ bool IsAtStartOfStatement = true;
+ bool IsParsingMSInlineAsm = false;
+ bool IsPeeking = false;
protected:
/// LexToken - Read the next token and return its code.
@@ -42,6 +39,8 @@ protected:
public:
AsmLexer(const MCAsmInfo &MAI);
+ AsmLexer(const AsmLexer &) = delete;
+ AsmLexer &operator=(const AsmLexer &) = delete;
~AsmLexer() override;
void setBuffer(StringRef Buf, const char *ptr = nullptr);
@@ -74,4 +73,4 @@ private:
} // end namespace llvm
-#endif
+#endif // LLVM_MC_MCPARSER_ASMLEXER_H
diff --git a/contrib/llvm/include/llvm/MC/MCParser/MCAsmLexer.h b/contrib/llvm/include/llvm/MC/MCParser/MCAsmLexer.h
index 56da6f8..7836ece 100644
--- a/contrib/llvm/include/llvm/MC/MCParser/MCAsmLexer.h
+++ b/contrib/llvm/include/llvm/MC/MCParser/MCAsmLexer.h
@@ -1,4 +1,4 @@
-//===-- llvm/MC/MCAsmLexer.h - Abstract Asm Lexer Interface -----*- C++ -*-===//
+//===- llvm/MC/MCAsmLexer.h - Abstract Asm Lexer Interface ------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,10 +14,12 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/DataTypes.h"
#include "llvm/Support/SMLoc.h"
-#include <utility>
+#include <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
+#include <string>
namespace llvm {
@@ -76,7 +78,7 @@ private:
APInt IntVal;
public:
- AsmToken() {}
+ AsmToken() = default;
AsmToken(TokenKind Kind, StringRef Str, APInt IntVal)
: Kind(Kind), Str(Str), IntVal(std::move(IntVal)) {}
AsmToken(TokenKind Kind, StringRef Str, int64_t IntVal = 0)
@@ -132,7 +134,7 @@ public:
/// it is lexed.
class AsmCommentConsumer {
public:
- virtual ~AsmCommentConsumer() {};
+ virtual ~AsmCommentConsumer() = default;
/// Callback function for when a comment is lexed. Loc is the start of the
/// comment text (excluding the comment-start marker). CommentText is the text
@@ -152,15 +154,14 @@ class MCAsmLexer {
SMLoc ErrLoc;
std::string Err;
- MCAsmLexer(const MCAsmLexer &) = delete;
- void operator=(const MCAsmLexer &) = delete;
protected: // Can only create subclasses.
- const char *TokStart;
- bool SkipSpace;
+ const char *TokStart = nullptr;
+ bool SkipSpace = true;
bool AllowAtInIdentifier;
- bool IsAtStartOfStatement;
- AsmCommentConsumer *CommentConsumer;
+ bool IsAtStartOfStatement = true;
+ AsmCommentConsumer *CommentConsumer = nullptr;
+ bool AltMacroMode;
MCAsmLexer();
virtual AsmToken LexToken() = 0;
@@ -171,8 +172,18 @@ protected: // Can only create subclasses.
}
public:
+ MCAsmLexer(const MCAsmLexer &) = delete;
+ MCAsmLexer &operator=(const MCAsmLexer &) = delete;
virtual ~MCAsmLexer();
+ bool IsaAltMacroMode() {
+ return AltMacroMode;
+ }
+
+ void SetAltMacroMode(bool AltMacroSet) {
+ AltMacroMode = AltMacroSet;
+ }
+
/// Consume the next token from the input stream and return it.
///
/// The lexer will continuosly return the end-of-file token once the end of
@@ -255,6 +266,6 @@ public:
}
};
-} // End llvm namespace
+} // end namespace llvm
-#endif
+#endif // LLVM_MC_MCPARSER_MCASMLEXER_H
diff --git a/contrib/llvm/include/llvm/MC/MCParser/MCAsmParser.h b/contrib/llvm/include/llvm/MC/MCParser/MCAsmParser.h
index 4dc15d6..3a659f0 100644
--- a/contrib/llvm/include/llvm/MC/MCParser/MCAsmParser.h
+++ b/contrib/llvm/include/llvm/MC/MCParser/MCAsmParser.h
@@ -1,4 +1,4 @@
-//===-- llvm/MC/MCAsmParser.h - Abstract Asm Parser Interface ---*- C++ -*-===//
+//===- llvm/MC/MCAsmParser.h - Abstract Asm Parser Interface ----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -10,16 +10,21 @@
#ifndef LLVM_MC_MCPARSER_MCASMPARSER_H
#define LLVM_MC_MCPARSER_MCASMPARSER_H
-#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/None.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
-#include "llvm/MC/MCParser/AsmLexer.h"
-#include "llvm/Support/DataTypes.h"
+#include "llvm/MC/MCParser/MCAsmLexer.h"
+#include "llvm/Support/SMLoc.h"
+#include <cstdint>
+#include <string>
+#include <utility>
namespace llvm {
+
class MCAsmInfo;
-class MCAsmLexer;
class MCAsmParserExtension;
class MCContext;
class MCExpr;
@@ -27,10 +32,7 @@ class MCInstPrinter;
class MCInstrInfo;
class MCStreamer;
class MCTargetAsmParser;
-class SMLoc;
-class SMRange;
class SourceMgr;
-class Twine;
class InlineAsmIdentifierInfo {
public:
@@ -51,12 +53,12 @@ public:
class MCAsmParserSemaCallback {
public:
virtual ~MCAsmParserSemaCallback();
+
virtual void *LookupInlineAsmIdentifier(StringRef &LineBuf,
InlineAsmIdentifierInfo &Info,
bool IsUnevaluatedContext) = 0;
virtual StringRef LookupInlineAsmLabel(StringRef Identifier, SourceMgr &SM,
SMLoc Location, bool Create) = 0;
-
virtual bool LookupInlineAsmField(StringRef Base, StringRef Member,
unsigned &Offset) = 0;
};
@@ -65,9 +67,9 @@ public:
/// assembly parsers.
class MCAsmParser {
public:
- typedef bool (*DirectiveHandler)(MCAsmParserExtension*, StringRef, SMLoc);
- typedef std::pair<MCAsmParserExtension*, DirectiveHandler>
- ExtensionDirectiveHandler;
+ using DirectiveHandler = bool (*)(MCAsmParserExtension*, StringRef, SMLoc);
+ using ExtensionDirectiveHandler =
+ std::pair<MCAsmParserExtension*, DirectiveHandler>;
struct MCPendingError {
SMLoc Loc;
@@ -76,22 +78,21 @@ public:
};
private:
- MCAsmParser(const MCAsmParser &) = delete;
- void operator=(const MCAsmParser &) = delete;
-
- MCTargetAsmParser *TargetParser;
+ MCTargetAsmParser *TargetParser = nullptr;
unsigned ShowParsedOperands : 1;
protected: // Can only create subclasses.
MCAsmParser();
- bool HadError;
+ bool HadError = false;
SmallVector<MCPendingError, 1> PendingErrors;
/// Flag tracking whether any errors have been encountered.
public:
+ MCAsmParser(const MCAsmParser &) = delete;
+ MCAsmParser &operator=(const MCAsmParser &) = delete;
virtual ~MCAsmParser();
virtual void addDirectiveHandler(StringRef Directive,
@@ -186,12 +187,12 @@ public:
bool parseEOL(const Twine &ErrMsg);
- bool parseMany(std::function<bool()> parseOne, bool hasComma = true);
+ bool parseMany(function_ref<bool()> parseOne, bool hasComma = true);
bool parseIntToken(int64_t &V, const Twine &ErrMsg);
- bool check(bool P, const llvm::Twine &Msg);
- bool check(bool P, SMLoc Loc, const llvm::Twine &Msg);
+ bool check(bool P, const Twine &Msg);
+ bool check(bool P, SMLoc Loc, const Twine &Msg);
/// \brief Parse an identifier or string (as a quoted identifier) and set \p
/// Res to the identifier contents.
@@ -260,6 +261,6 @@ public:
MCAsmParser *createMCAsmParser(SourceMgr &, MCContext &, MCStreamer &,
const MCAsmInfo &, unsigned CB = 0);
-} // End llvm namespace
+} // end namespace llvm
-#endif
+#endif // LLVM_MC_MCPARSER_MCASMPARSER_H
diff --git a/contrib/llvm/include/llvm/MC/MCParser/MCAsmParserExtension.h b/contrib/llvm/include/llvm/MC/MCParser/MCAsmParserExtension.h
index dabda0a..ffb8d7a 100644
--- a/contrib/llvm/include/llvm/MC/MCParser/MCAsmParserExtension.h
+++ b/contrib/llvm/include/llvm/MC/MCParser/MCAsmParserExtension.h
@@ -1,4 +1,4 @@
-//===-- llvm/MC/MCAsmParserExtension.h - Asm Parser Hooks -------*- C++ -*-===//
+//===- llvm/MC/MCAsmParserExtension.h - Asm Parser Hooks --------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -10,20 +10,20 @@
#ifndef LLVM_MC_MCPARSER_MCASMPARSEREXTENSION_H
#define LLVM_MC_MCPARSER_MCASMPARSEREXTENSION_H
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/MC/MCParser/MCAsmLexer.h"
#include "llvm/MC/MCParser/MCAsmParser.h"
#include "llvm/Support/SMLoc.h"
namespace llvm {
+
class Twine;
/// \brief Generic interface for extending the MCAsmParser,
/// which is implemented by target and object file assembly parser
/// implementations.
class MCAsmParserExtension {
- MCAsmParserExtension(const MCAsmParserExtension &) = delete;
- void operator=(const MCAsmParserExtension &) = delete;
-
MCAsmParser *Parser;
protected:
@@ -38,9 +38,11 @@ protected:
return (Obj->*Handler)(Directive, DirectiveLoc);
}
- bool BracketExpressionsSupported;
+ bool BracketExpressionsSupported = false;
public:
+ MCAsmParserExtension(const MCAsmParserExtension &) = delete;
+ MCAsmParserExtension &operator=(const MCAsmParserExtension &) = delete;
virtual ~MCAsmParserExtension();
/// \brief Initialize the extension for parsing using the given \p Parser.
@@ -65,15 +67,19 @@ public:
SourceMgr &getSourceManager() { return getParser().getSourceManager(); }
MCStreamer &getStreamer() { return getParser().getStreamer(); }
+
bool Warning(SMLoc L, const Twine &Msg) {
return getParser().Warning(L, Msg);
}
+
bool Error(SMLoc L, const Twine &Msg, SMRange Range = SMRange()) {
return getParser().Error(L, Msg, Range);
}
+
void Note(SMLoc L, const Twine &Msg) {
getParser().Note(L, Msg);
}
+
bool TokError(const Twine &Msg) {
return getParser().TokError(Msg);
}
@@ -85,7 +91,7 @@ public:
return getParser().parseToken(T, Msg);
}
- bool parseMany(std::function<bool()> parseOne, bool hasComma = true) {
+ bool parseMany(function_ref<bool()> parseOne, bool hasComma = true) {
return getParser().parseMany(parseOne, hasComma);
}
@@ -93,11 +99,11 @@ public:
return getParser().parseOptionalToken(T);
}
- bool check(bool P, const llvm::Twine &Msg) {
+ bool check(bool P, const Twine &Msg) {
return getParser().check(P, Msg);
}
- bool check(bool P, SMLoc Loc, const llvm::Twine &Msg) {
+ bool check(bool P, SMLoc Loc, const Twine &Msg) {
return getParser().check(P, Loc, Msg);
}
@@ -110,6 +116,6 @@ public:
/// @}
};
-} // End llvm namespace
+} // end namespace llvm
-#endif
+#endif // LLVM_MC_MCPARSER_MCASMPARSEREXTENSION_H
diff --git a/contrib/llvm/include/llvm/MC/MCParser/MCAsmParserUtils.h b/contrib/llvm/include/llvm/MC/MCParser/MCAsmParserUtils.h
index 9834fe9..84173bb 100644
--- a/contrib/llvm/include/llvm/MC/MCParser/MCAsmParserUtils.h
+++ b/contrib/llvm/include/llvm/MC/MCParser/MCAsmParserUtils.h
@@ -1,4 +1,4 @@
-//===------ llvm/MC/MCAsmParserUtils.h - Asm Parser Utilities ---*- C++ -*-===//
+//===- llvm/MC/MCAsmParserUtils.h - Asm Parser Utilities --------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -28,6 +28,7 @@ bool parseAssignmentExpression(StringRef Name, bool allow_redef,
const MCExpr *&Value);
} // namespace MCParserUtils
+
} // namespace llvm
-#endif
+#endif // LLVM_MC_MCPARSER_MCASMPARSERUTILS_H
diff --git a/contrib/llvm/include/llvm/MC/MCParser/MCParsedAsmOperand.h b/contrib/llvm/include/llvm/MC/MCParser/MCParsedAsmOperand.h
index a90d280..4af76ac 100644
--- a/contrib/llvm/include/llvm/MC/MCParser/MCParsedAsmOperand.h
+++ b/contrib/llvm/include/llvm/MC/MCParser/MCParsedAsmOperand.h
@@ -1,4 +1,4 @@
-//===-- llvm/MC/MCParsedAsmOperand.h - Asm Parser Operand -------*- C++ -*-===//
+//===- llvm/MC/MCParsedAsmOperand.h - Asm Parser Operand --------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -10,11 +10,12 @@
#ifndef LLVM_MC_MCPARSER_MCPARSEDASMOPERAND_H
#define LLVM_MC_MCPARSER_MCPARSEDASMOPERAND_H
-#include <string>
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/SMLoc.h"
+#include <string>
namespace llvm {
+
class raw_ostream;
/// MCParsedAsmOperand - This abstract class represents a source-level assembly
@@ -35,12 +36,12 @@ protected:
// lots of members and MSVC doesn't support defaulted move ops, so to avoid
// that verbosity, just rely on defaulted copy ops. It's only the Constraint
// string member that would benefit from movement anyway.
+ MCParsedAsmOperand() = default;
MCParsedAsmOperand(const MCParsedAsmOperand &RHS) = default;
MCParsedAsmOperand &operator=(const MCParsedAsmOperand &) = default;
- MCParsedAsmOperand() = default;
public:
- virtual ~MCParsedAsmOperand() {}
+ virtual ~MCParsedAsmOperand() = default;
void setConstraint(StringRef C) { Constraint = C.str(); }
StringRef getConstraint() { return Constraint; }
@@ -81,6 +82,7 @@ public:
/// print - Print a debug representation of the operand to the given stream.
virtual void print(raw_ostream &OS) const = 0;
+
/// dump - Print to the debug stream.
virtual void dump() const;
};
@@ -93,6 +95,6 @@ inline raw_ostream& operator<<(raw_ostream &OS, const MCParsedAsmOperand &MO) {
return OS;
}
-} // end namespace llvm.
+} // end namespace llvm
-#endif
+#endif // LLVM_MC_MCPARSER_MCPARSEDASMOPERAND_H
diff --git a/contrib/llvm/include/llvm/MC/MCParser/MCTargetAsmParser.h b/contrib/llvm/include/llvm/MC/MCParser/MCTargetAsmParser.h
index 70cd60c..b8d3180 100644
--- a/contrib/llvm/include/llvm/MC/MCParser/MCTargetAsmParser.h
+++ b/contrib/llvm/include/llvm/MC/MCParser/MCTargetAsmParser.h
@@ -1,4 +1,4 @@
-//===-- llvm/MC/MCTargetAsmParser.h - Target Assembly Parser ----*- C++ -*-===//
+//===- llvm/MC/MCTargetAsmParser.h - Target Assembly Parser -----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -10,22 +10,24 @@
#ifndef LLVM_MC_MCPARSER_MCTARGETASMPARSER_H
#define LLVM_MC_MCPARSER_MCTARGETASMPARSER_H
+#include "llvm/ADT/StringRef.h"
#include "llvm/MC/MCExpr.h"
+#include "llvm/MC/MCParser/MCAsmLexer.h"
#include "llvm/MC/MCParser/MCAsmParserExtension.h"
#include "llvm/MC/MCTargetOptions.h"
+#include "llvm/Support/SMLoc.h"
+#include <cstdint>
#include <memory>
namespace llvm {
-class AsmToken;
+
class MCInst;
class MCParsedAsmOperand;
class MCStreamer;
class MCSubtargetInfo;
-class SMLoc;
-class StringRef;
template <typename T> class SmallVectorImpl;
-typedef SmallVectorImpl<std::unique_ptr<MCParsedAsmOperand>> OperandVector;
+using OperandVector = SmallVectorImpl<std::unique_ptr<MCParsedAsmOperand>>;
enum AsmRewriteKind {
AOK_Delete = 0, // Rewrite should be ignored.
@@ -66,6 +68,7 @@ struct AsmRewrite {
unsigned Len;
unsigned Val;
StringRef Label;
+
public:
AsmRewrite(AsmRewriteKind kind, SMLoc loc, unsigned len = 0, unsigned val = 0)
: Kind(kind), Loc(loc), Len(len), Val(val) {}
@@ -74,10 +77,9 @@ public:
};
struct ParseInstructionInfo {
+ SmallVectorImpl<AsmRewrite> *AsmRewrites = nullptr;
- SmallVectorImpl<AsmRewrite> *AsmRewrites;
-
- ParseInstructionInfo() : AsmRewrites(nullptr) {}
+ ParseInstructionInfo() = default;
ParseInstructionInfo(SmallVectorImpl<AsmRewrite> *rewrites)
: AsmRewrites(rewrites) {}
};
@@ -99,9 +101,6 @@ public:
FIRST_TARGET_MATCH_RESULT_TY
};
-private:
- MCTargetAsmParser(const MCTargetAsmParser &) = delete;
- void operator=(const MCTargetAsmParser &) = delete;
protected: // Can only create subclasses.
MCTargetAsmParser(MCTargetOptions const &, const MCSubtargetInfo &STI);
@@ -109,10 +108,10 @@ protected: // Can only create subclasses.
MCSubtargetInfo &copySTI();
/// AvailableFeatures - The current set of available features.
- uint64_t AvailableFeatures;
+ uint64_t AvailableFeatures = 0;
/// ParsingInlineAsm - Are we parsing ms-style inline assembly?
- bool ParsingInlineAsm;
+ bool ParsingInlineAsm = false;
/// SemaCallback - The Sema callback implementation. Must be set when parsing
/// ms-style inline assembly.
@@ -125,6 +124,9 @@ protected: // Can only create subclasses.
const MCSubtargetInfo *STI;
public:
+ MCTargetAsmParser(const MCTargetAsmParser &) = delete;
+ MCTargetAsmParser &operator=(const MCTargetAsmParser &) = delete;
+
~MCTargetAsmParser() override;
const MCSubtargetInfo &getSTI() const;
@@ -229,11 +231,11 @@ public:
return nullptr;
}
- virtual void onLabelParsed(MCSymbol *Symbol) { }
+ virtual void onLabelParsed(MCSymbol *Symbol) {}
/// Ensure that all previously parsed instructions have been emitted to the
/// output streamer, if the target does not emit them immediately.
- virtual void flushPendingInstructions(MCStreamer &Out) { }
+ virtual void flushPendingInstructions(MCStreamer &Out) {}
virtual const MCExpr *createTargetUnaryExpr(const MCExpr *E,
AsmToken::TokenKind OperatorToken,
@@ -242,6 +244,6 @@ public:
}
};
-} // End llvm namespace
+} // end namespace llvm
-#endif
+#endif // LLVM_MC_MCPARSER_MCTARGETASMPARSER_H
diff --git a/contrib/llvm/include/llvm/MC/MCRegisterInfo.h b/contrib/llvm/include/llvm/MC/MCRegisterInfo.h
index 3dc88a2..de98abe 100644
--- a/contrib/llvm/include/llvm/MC/MCRegisterInfo.h
+++ b/contrib/llvm/include/llvm/MC/MCRegisterInfo.h
@@ -1,4 +1,4 @@
-//=== MC/MCRegisterInfo.h - Target Register Description ---------*- C++ -*-===//
+//===- MC/MCRegisterInfo.h - Target Register Description --------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -17,21 +17,23 @@
#define LLVM_MC_MCREGISTERINFO_H
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/iterator_range.h"
#include "llvm/MC/LaneBitmask.h"
-#include "llvm/Support/ErrorHandling.h"
#include <cassert>
+#include <cstdint>
+#include <utility>
namespace llvm {
/// An unsigned integer type large enough to represent all physical registers,
/// but not necessarily virtual registers.
-typedef uint16_t MCPhysReg;
+using MCPhysReg = uint16_t;
/// MCRegisterClass - Base class of TargetRegisterClass.
class MCRegisterClass {
public:
- typedef const MCPhysReg* iterator;
- typedef const MCPhysReg* const_iterator;
+ using iterator = const MCPhysReg*;
+ using const_iterator = const MCPhysReg*;
const iterator RegsBegin;
const uint8_t *const RegSet;
@@ -39,7 +41,7 @@ public:
const uint16_t RegsSize;
const uint16_t RegSetSize;
const uint16_t ID;
- const uint16_t RegSize, Alignment; // Size & Alignment of register in bytes
+ const uint16_t PhysRegSize;
const int8_t CopyCost;
const bool Allocatable;
@@ -78,13 +80,10 @@ public:
return contains(Reg1) && contains(Reg2);
}
- /// getSize - Return the size of the register in bytes, which is also the size
- /// of a stack slot allocated to hold a spilled copy of this register.
- unsigned getSize() const { return RegSize; }
-
- /// getAlignment - Return the minimum required alignment for a register of
- /// this class.
- unsigned getAlignment() const { return Alignment; }
+ /// Return the size of the physical register in bytes.
+ unsigned getPhysRegSize() const { return PhysRegSize; }
+ /// Temporary function to allow out-of-tree targets to switch.
+ unsigned getSize() const { return getPhysRegSize(); }
/// getCopyCost - Return the cost of copying a value between two registers in
/// this class. A negative number means the register class is very expensive
@@ -135,7 +134,7 @@ struct MCRegisterDesc {
///
class MCRegisterInfo {
public:
- typedef const MCRegisterClass *regclass_iterator;
+ using regclass_iterator = const MCRegisterClass *;
/// DwarfLLVMRegPair - Emitted by tablegen so Dwarf<->LLVM reg mappings can be
/// performed with a binary search.
@@ -152,6 +151,7 @@ public:
uint16_t Offset;
uint16_t Size;
};
+
private:
const MCRegisterDesc *Desc; // Pointer to the descriptor array
unsigned NumRegs; // Number of entries in the array
@@ -191,12 +191,12 @@ public:
/// Don't use this class directly, use one of the specialized sub-classes
/// defined below.
class DiffListIterator {
- uint16_t Val;
- const MCPhysReg *List;
+ uint16_t Val = 0;
+ const MCPhysReg *List = nullptr;
protected:
/// Create an invalid iterator. Call init() to point to something useful.
- DiffListIterator() : Val(0), List(nullptr) {}
+ DiffListIterator() = default;
/// init - Point the iterator to InitVal, decoding subsequent values from
/// DiffList. The iterator will initially point to InitVal, sub-classes are
@@ -217,7 +217,6 @@ public:
}
public:
-
/// isValid - returns true if this iterator is not yet at the end.
bool isValid() const { return List; }
@@ -418,6 +417,9 @@ public:
regclass_iterator regclass_begin() const { return Classes; }
regclass_iterator regclass_end() const { return Classes+NumClasses; }
+ iterator_range<regclass_iterator> regclasses() const {
+ return make_range(regclass_begin(), regclass_end());
+ }
unsigned getNumRegClasses() const {
return (unsigned)(regclass_end()-regclass_begin());
@@ -492,6 +494,7 @@ public:
class MCSubRegIndexIterator {
MCSubRegIterator SRIter;
const uint16_t *SRIndex;
+
public:
/// Constructs an iterator that traverses subregisters and their
/// associated subregister indices.
@@ -504,6 +507,7 @@ public:
unsigned getSubReg() const {
return *SRIter;
}
+
/// Returns sub-register index of the current sub-register.
unsigned getSubRegIndex() const {
return *SRIndex;
@@ -523,7 +527,8 @@ public:
/// If IncludeSelf is set, Reg itself is included in the list.
class MCSuperRegIterator : public MCRegisterInfo::DiffListIterator {
public:
- MCSuperRegIterator() {}
+ MCSuperRegIterator() = default;
+
MCSuperRegIterator(unsigned Reg, const MCRegisterInfo *MCRI,
bool IncludeSelf = false) {
init(Reg, MCRI->DiffLists + MCRI->get(Reg).SuperRegs);
@@ -560,7 +565,8 @@ class MCRegUnitIterator : public MCRegisterInfo::DiffListIterator {
public:
/// MCRegUnitIterator - Create an iterator that traverses the register units
/// in Reg.
- MCRegUnitIterator() {}
+ MCRegUnitIterator() = default;
+
MCRegUnitIterator(unsigned Reg, const MCRegisterInfo *MCRI) {
assert(Reg && "Null register has no regunits");
// Decode the RegUnits MCRegisterDesc field.
@@ -586,8 +592,10 @@ public:
class MCRegUnitMaskIterator {
MCRegUnitIterator RUIter;
const LaneBitmask *MaskListIter;
+
public:
- MCRegUnitMaskIterator() {}
+ MCRegUnitMaskIterator() = default;
+
/// Constructs an iterator that traverses the register units and their
/// associated LaneMasks in Reg.
MCRegUnitMaskIterator(unsigned Reg, const MCRegisterInfo *MCRI)
@@ -622,10 +630,12 @@ public:
/// MCRegUnitRootIterator enumerates the root registers of a register unit.
class MCRegUnitRootIterator {
- uint16_t Reg0;
- uint16_t Reg1;
+ uint16_t Reg0 = 0;
+ uint16_t Reg1 = 0;
+
public:
- MCRegUnitRootIterator() : Reg0(0), Reg1(0) {}
+ MCRegUnitRootIterator() = default;
+
MCRegUnitRootIterator(unsigned RegUnit, const MCRegisterInfo *MCRI) {
assert(RegUnit < MCRI->getNumRegUnits() && "Invalid register unit");
Reg0 = MCRI->RegUnitRoots[RegUnit][0];
@@ -662,11 +672,11 @@ private:
MCRegUnitIterator RI;
MCRegUnitRootIterator RRI;
MCSuperRegIterator SI;
+
public:
MCRegAliasIterator(unsigned Reg, const MCRegisterInfo *MCRI,
bool IncludeSelf)
: Reg(Reg), MCRI(MCRI), IncludeSelf(IncludeSelf) {
-
// Initialize the iterators.
for (RI = MCRegUnitIterator(Reg, MCRI); RI.isValid(); ++RI) {
for (RRI = MCRegUnitRootIterator(*RI, MCRI); RRI.isValid(); ++RRI) {
@@ -681,7 +691,7 @@ public:
bool isValid() const { return RI.isValid(); }
unsigned operator*() const {
- assert (SI.isValid() && "Cannot dereference an invalid iterator.");
+ assert(SI.isValid() && "Cannot dereference an invalid iterator.");
return *SI;
}
@@ -710,6 +720,6 @@ public:
}
};
-} // End llvm namespace
+} // end namespace llvm
-#endif
+#endif // LLVM_MC_MCREGISTERINFO_H
diff --git a/contrib/llvm/include/llvm/MC/MCSection.h b/contrib/llvm/include/llvm/MC/MCSection.h
index d4c31696..2771b1e 100644
--- a/contrib/llvm/include/llvm/MC/MCSection.h
+++ b/contrib/llvm/include/llvm/MC/MCSection.h
@@ -16,20 +16,19 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/ilist.h"
-#include "llvm/ADT/ilist_node.h"
#include "llvm/MC/MCFragment.h"
#include "llvm/MC/SectionKind.h"
-#include "llvm/Support/Compiler.h"
+#include <cassert>
+#include <utility>
namespace llvm {
+
class MCAsmInfo;
-class MCAssembler;
class MCContext;
class MCExpr;
-class MCFragment;
-class MCSection;
class MCSymbol;
class raw_ostream;
+class Triple;
template <> struct ilist_alloc_traits<MCFragment> {
static void deleteNode(MCFragment *V);
@@ -39,7 +38,7 @@ template <> struct ilist_alloc_traits<MCFragment> {
/// current translation unit. The MCContext class uniques and creates these.
class MCSection {
public:
- enum SectionVariant { SV_COFF = 0, SV_ELF, SV_MachO };
+ enum SectionVariant { SV_COFF = 0, SV_ELF, SV_MachO, SV_Wasm };
/// \brief Express the state of bundle locked groups while emitting code.
enum BundleLockStateType {
@@ -48,18 +47,15 @@ public:
BundleLockedAlignToEnd
};
- typedef iplist<MCFragment> FragmentListType;
+ using FragmentListType = iplist<MCFragment>;
- typedef FragmentListType::const_iterator const_iterator;
- typedef FragmentListType::iterator iterator;
+ using const_iterator = FragmentListType::const_iterator;
+ using iterator = FragmentListType::iterator;
- typedef FragmentListType::const_reverse_iterator const_reverse_iterator;
- typedef FragmentListType::reverse_iterator reverse_iterator;
+ using const_reverse_iterator = FragmentListType::const_reverse_iterator;
+ using reverse_iterator = FragmentListType::reverse_iterator;
private:
- MCSection(const MCSection &) = delete;
- void operator=(const MCSection &) = delete;
-
MCSymbol *Begin;
MCSymbol *End = nullptr;
/// The alignment requirement of this section.
@@ -77,12 +73,12 @@ private:
/// \brief We've seen a bundle_lock directive but not its first instruction
/// yet.
- unsigned BundleGroupBeforeFirstInst : 1;
+ bool BundleGroupBeforeFirstInst : 1;
/// Whether this section has had instructions emitted into it.
- unsigned HasInstructions : 1;
+ bool HasInstructions : 1;
- unsigned IsRegistered : 1;
+ bool IsRegistered : 1;
MCDummyFragment DummyFragment;
@@ -93,12 +89,16 @@ private:
SmallVector<std::pair<unsigned, MCFragment *>, 1> SubsectionFragmentMap;
protected:
- MCSection(SectionVariant V, SectionKind K, MCSymbol *Begin);
SectionVariant Variant;
SectionKind Kind;
+
+ MCSection(SectionVariant V, SectionKind K, MCSymbol *Begin);
~MCSection();
public:
+ MCSection(const MCSection &) = delete;
+ MCSection &operator=(const MCSection &) = delete;
+
SectionKind getKind() const { return Kind; }
SectionVariant getVariant() const { return Variant; }
@@ -167,9 +167,10 @@ public:
MCSection::iterator getSubsectionInsertionPoint(unsigned Subsection);
- void dump();
+ void dump() const;
- virtual void PrintSwitchToSection(const MCAsmInfo &MAI, raw_ostream &OS,
+ virtual void PrintSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
+ raw_ostream &OS,
const MCExpr *Subsection) const = 0;
/// Return true if a .align directive should use "optimized nops" to fill
@@ -183,4 +184,4 @@ public:
} // end namespace llvm
-#endif
+#endif // LLVM_MC_MCSECTION_H
diff --git a/contrib/llvm/include/llvm/MC/MCSectionCOFF.h b/contrib/llvm/include/llvm/MC/MCSectionCOFF.h
index 7d5f9f7..24b9f88 100644
--- a/contrib/llvm/include/llvm/MC/MCSectionCOFF.h
+++ b/contrib/llvm/include/llvm/MC/MCSectionCOFF.h
@@ -16,8 +16,11 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/MC/MCSection.h"
+#include "llvm/MC/SectionKind.h"
+#include <cassert>
namespace llvm {
+
class MCSymbol;
/// This represents a section on Windows
@@ -73,7 +76,8 @@ public:
void setSelection(int Selection) const;
- void PrintSwitchToSection(const MCAsmInfo &MAI, raw_ostream &OS,
+ void PrintSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
+ raw_ostream &OS,
const MCExpr *Subsection) const override;
bool UseCodeAlign() const override;
bool isVirtualSection() const override;
@@ -93,4 +97,4 @@ public:
} // end namespace llvm
-#endif
+#endif // LLVM_MC_MCSECTIONCOFF_H
diff --git a/contrib/llvm/include/llvm/MC/MCSectionELF.h b/contrib/llvm/include/llvm/MC/MCSectionELF.h
index dabd787..00c289c 100644
--- a/contrib/llvm/include/llvm/MC/MCSectionELF.h
+++ b/contrib/llvm/include/llvm/MC/MCSectionELF.h
@@ -14,12 +14,10 @@
#ifndef LLVM_MC_MCSECTIONELF_H
#define LLVM_MC_MCSECTIONELF_H
-#include "llvm/ADT/Twine.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCSymbolELF.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/ELF.h"
-#include "llvm/Support/raw_ostream.h"
+#include "llvm/MC/SectionKind.h"
namespace llvm {
@@ -47,17 +45,18 @@ class MCSectionELF final : public MCSection {
const MCSymbolELF *Group;
- /// Depending on the type of the section this is sh_link or sh_info.
- const MCSectionELF *Associated;
+ /// sh_info for SHF_LINK_ORDER (can be null).
+ const MCSymbol *AssociatedSymbol;
private:
friend class MCContext;
+
MCSectionELF(StringRef Section, unsigned type, unsigned flags, SectionKind K,
unsigned entrySize, const MCSymbolELF *group, unsigned UniqueID,
- MCSymbol *Begin, const MCSectionELF *Associated)
+ MCSymbol *Begin, const MCSymbolELF *AssociatedSymbol)
: MCSection(SV_ELF, K, Begin), SectionName(Section), Type(type),
Flags(flags), UniqueID(UniqueID), EntrySize(entrySize), Group(group),
- Associated(Associated) {
+ AssociatedSymbol(AssociatedSymbol) {
if (Group)
Group->setIsSignature();
}
@@ -78,7 +77,8 @@ public:
void setFlags(unsigned F) { Flags = F; }
const MCSymbolELF *getGroup() const { return Group; }
- void PrintSwitchToSection(const MCAsmInfo &MAI, raw_ostream &OS,
+ void PrintSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
+ raw_ostream &OS,
const MCExpr *Subsection) const override;
bool UseCodeAlign() const override;
bool isVirtualSection() const override;
@@ -86,7 +86,8 @@ public:
bool isUnique() const { return UniqueID != ~0U; }
unsigned getUniqueID() const { return UniqueID; }
- const MCSectionELF *getAssociatedSection() const { return Associated; }
+ const MCSection *getAssociatedSection() const { return &AssociatedSymbol->getSection(); }
+ const MCSymbol *getAssociatedSymbol() const { return AssociatedSymbol; }
static bool classof(const MCSection *S) {
return S->getVariant() == SV_ELF;
@@ -95,4 +96,4 @@ public:
} // end namespace llvm
-#endif
+#endif // LLVM_MC_MCSECTIONELF_H
diff --git a/contrib/llvm/include/llvm/MC/MCSectionMachO.h b/contrib/llvm/include/llvm/MC/MCSectionMachO.h
index 658dfcd..89db09c 100644
--- a/contrib/llvm/include/llvm/MC/MCSectionMachO.h
+++ b/contrib/llvm/include/llvm/MC/MCSectionMachO.h
@@ -15,8 +15,8 @@
#define LLVM_MC_MCSECTIONMACHO_H
#include "llvm/ADT/StringRef.h"
+#include "llvm/BinaryFormat/MachO.h"
#include "llvm/MC/MCSection.h"
-#include "llvm/Support/MachO.h"
namespace llvm {
@@ -76,7 +76,8 @@ public:
bool &TAAParsed, // Out.
unsigned &StubSize); // Out.
- void PrintSwitchToSection(const MCAsmInfo &MAI, raw_ostream &OS,
+ void PrintSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
+ raw_ostream &OS,
const MCExpr *Subsection) const override;
bool UseCodeAlign() const override;
bool isVirtualSection() const override;
diff --git a/contrib/llvm/include/llvm/MC/MCSectionWasm.h b/contrib/llvm/include/llvm/MC/MCSectionWasm.h
new file mode 100644
index 0000000..29d62a7
--- /dev/null
+++ b/contrib/llvm/include/llvm/MC/MCSectionWasm.h
@@ -0,0 +1,88 @@
+//===- MCSectionWasm.h - Wasm Machine Code Sections -------------*- 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 the MCSectionWasm class.
+//
+//===----------------------------------------------------------------------===//
+
+#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;
+
+/// This represents a section on wasm.
+class MCSectionWasm final : public MCSection {
+private:
+ /// This is the name of the section. The referenced memory is owned by
+ /// TargetLoweringObjectFileWasm's WasmUniqueMap.
+ StringRef SectionName;
+
+ /// This is the sh_type field of a section, drawn from the enums below.
+ unsigned Type;
+
+ /// This is the sh_flags field of a section, drawn from the enums below.
+ unsigned Flags;
+
+ unsigned UniqueID;
+
+ const MCSymbolWasm *Group;
+
+ // The offset of the MC function/data section in the wasm code/data section.
+ // For data relocations the offset is relative to start of the data payload
+ // itself and does not include the size of the section header.
+ uint64_t SectionOffset;
+
+ friend class MCContext;
+ MCSectionWasm(StringRef Section, unsigned type, unsigned flags, SectionKind K,
+ const MCSymbolWasm *group, unsigned UniqueID, MCSymbol *Begin)
+ : MCSection(SV_Wasm, K, Begin), SectionName(Section), Type(type),
+ Flags(flags), UniqueID(UniqueID), Group(group), SectionOffset(0) {
+ }
+
+ void setSectionName(StringRef Name) { SectionName = Name; }
+
+public:
+ ~MCSectionWasm();
+
+ /// 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; }
+ void setFlags(unsigned F) { Flags = F; }
+ const MCSymbolWasm *getGroup() const { return Group; }
+
+ void PrintSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
+ raw_ostream &OS,
+ const MCExpr *Subsection) const override;
+ bool UseCodeAlign() const override;
+ bool isVirtualSection() const override;
+
+ bool isUnique() const { return UniqueID != ~0U; }
+ unsigned getUniqueID() const { return UniqueID; }
+
+ uint64_t getSectionOffset() const { return SectionOffset; }
+ void setSectionOffset(uint64_t Offset) { SectionOffset = Offset; }
+
+ static bool classof(const MCSection *S) { return S->getVariant() == SV_Wasm; }
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/MC/MCStreamer.h b/contrib/llvm/include/llvm/MC/MCStreamer.h
index 41f00a2..5390e79 100644
--- a/contrib/llvm/include/llvm/MC/MCStreamer.h
+++ b/contrib/llvm/include/llvm/MC/MCStreamer.h
@@ -15,17 +15,26 @@
#define LLVM_MC_MCSTREAMER_H
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/MC/MCDirectives.h"
#include "llvm/MC/MCDwarf.h"
#include "llvm/MC/MCLinkerOptimizationHint.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/MC/MCWinEH.h"
-#include "llvm/Support/DataTypes.h"
#include "llvm/Support/SMLoc.h"
+#include <cassert>
+#include <cstdint>
+#include <memory>
#include <string>
+#include <utility>
+#include <vector>
namespace llvm {
+
+class AssemblerConstantPools;
+class formatted_raw_ostream;
class MCAsmBackend;
class MCCodeEmitter;
class MCContext;
@@ -34,16 +43,12 @@ class MCInst;
class MCInstPrinter;
class MCSection;
class MCStreamer;
-class MCSymbolELF;
class MCSymbolRefExpr;
class MCSubtargetInfo;
-class StringRef;
-class Twine;
class raw_ostream;
-class formatted_raw_ostream;
-class AssemblerConstantPools;
+class Twine;
-typedef std::pair<MCSection *, const MCExpr *> MCSectionSubPair;
+using MCSectionSubPair = std::pair<MCSection *, const MCExpr *>;
/// Target specific streamer interface. This is used so that targets can
/// implement support for target specific assembly directives.
@@ -122,6 +127,7 @@ public:
virtual void emitArch(unsigned Arch);
virtual void emitArchExtension(unsigned ArchExt);
virtual void emitObjectArch(unsigned Arch);
+ void emitTargetAttributes(const MCSubtargetInfo &STI);
virtual void finishAttributeSection();
virtual void emitInst(uint32_t Inst, char Suffix = '\0');
@@ -162,9 +168,6 @@ class MCStreamer {
MCContext &Context;
std::unique_ptr<MCTargetStreamer> TargetStreamer;
- MCStreamer(const MCStreamer &) = delete;
- MCStreamer &operator=(const MCStreamer &) = delete;
-
std::vector<MCDwarfFrameInfo> DwarfFrameInfos;
MCDwarfFrameInfo *getCurrentDwarfFrameInfo();
void EnsureValidDwarfFrame();
@@ -205,6 +208,8 @@ protected:
virtual void EmitRawTextImpl(StringRef String);
public:
+ MCStreamer(const MCStreamer &) = delete;
+ MCStreamer &operator=(const MCStreamer &) = delete;
virtual ~MCStreamer();
void visitUsedExpr(const MCExpr &Expr);
@@ -282,6 +287,7 @@ public:
/// \brief Add explicit comment T. T is required to be a valid
/// comment in the output and does not need to be escaped.
virtual void addExplicitComment(const Twine &T);
+
/// \brief Emit added explicit comments.
virtual void emitExplicitComments();
@@ -393,7 +399,7 @@ 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);
+ virtual void EmitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc());
virtual void EmitEHSymAttributes(const MCSymbol *Symbol, MCSymbol *EHSymbol);
@@ -483,6 +489,14 @@ public:
/// .size symbol, expression
virtual void emitELFSize(MCSymbol *Symbol, const MCExpr *Value);
+ /// \brief Emit an ELF .symver directive.
+ ///
+ /// This corresponds to an assembler statement such as:
+ /// .symver _start, foo@@SOME_VERSION
+ /// \param Alias - The versioned alias (i.e. "foo@@SOME_VERSION")
+ /// \param Aliasee - The aliased symbol (i.e. "_start")
+ virtual void emitELFSymverDirective(MCSymbol *Alias, const MCSymbol *Aliasee);
+
/// \brief Emit a Linker Optimization Hint (LOH) directive.
/// \param Args - Arguments of the LOH.
virtual void EmitLOHDirective(MCLOHType Kind, const MCLOHArgs &Args) {}
@@ -822,7 +836,9 @@ public:
}
/// \brief Emit the given \p Instruction into the current section.
- virtual void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI);
+ /// PrintSchedInfo == true then schedul comment should be added to output
+ virtual void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI,
+ bool PrintSchedInfo = false);
/// \brief 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
@@ -876,6 +892,7 @@ MCStreamer *createAsmStreamer(MCContext &Ctx,
bool isVerboseAsm, bool useDwarfDirectory,
MCInstPrinter *InstPrint, MCCodeEmitter *CE,
MCAsmBackend *TAB, bool ShowInst);
+
} // end namespace llvm
-#endif
+#endif // LLVM_MC_MCSTREAMER_H
diff --git a/contrib/llvm/include/llvm/MC/MCSubtargetInfo.h b/contrib/llvm/include/llvm/MC/MCSubtargetInfo.h
index 5ede043..d1d5d07 100644
--- a/contrib/llvm/include/llvm/MC/MCSubtargetInfo.h
+++ b/contrib/llvm/include/llvm/MC/MCSubtargetInfo.h
@@ -1,4 +1,4 @@
-//==-- llvm/MC/MCSubtargetInfo.h - Subtarget Information ---------*- C++ -*-==//
+//===- llvm/MC/MCSubtargetInfo.h - Subtarget Information --------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -15,13 +15,20 @@
#define LLVM_MC_MCSUBTARGETINFO_H
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Triple.h"
#include "llvm/MC/MCInstrItineraries.h"
+#include "llvm/MC/MCSchedule.h"
#include "llvm/MC/SubtargetFeature.h"
+#include <algorithm>
+#include <cassert>
+#include <cstdint>
#include <string>
namespace llvm {
-class StringRef;
+class MachineInstr;
+class MCInst;
//===----------------------------------------------------------------------===//
///
@@ -45,10 +52,6 @@ class MCSubtargetInfo {
const unsigned *ForwardingPaths; // Forwarding paths
FeatureBitset FeatureBits; // Feature bits for current CPU + FS
- MCSubtargetInfo() = delete;
- MCSubtargetInfo &operator=(MCSubtargetInfo &&) = delete;
- MCSubtargetInfo &operator=(const MCSubtargetInfo &) = delete;
-
public:
MCSubtargetInfo(const MCSubtargetInfo &) = default;
MCSubtargetInfo(const Triple &TT, StringRef CPU, StringRef FS,
@@ -58,6 +61,10 @@ public:
const MCWriteProcResEntry *WPR, const MCWriteLatencyEntry *WL,
const MCReadAdvanceEntry *RA, const InstrStage *IS,
const unsigned *OC, const unsigned *FP);
+ MCSubtargetInfo() = delete;
+ MCSubtargetInfo &operator=(const MCSubtargetInfo &) = delete;
+ MCSubtargetInfo &operator=(MCSubtargetInfo &&) = delete;
+ virtual ~MCSubtargetInfo() = default;
/// getTargetTriple - Return the target triple string.
const Triple &getTargetTriple() const { return TargetTriple; }
@@ -79,6 +86,10 @@ public:
FeatureBits = FeatureBits_;
}
+ bool hasFeature(unsigned Feature) const {
+ return FeatureBits[Feature];
+ }
+
protected:
/// Initialize the scheduling model and feature bits.
///
@@ -164,8 +175,17 @@ public:
auto Found = std::lower_bound(ProcDesc.begin(), ProcDesc.end(), CPU);
return Found != ProcDesc.end() && StringRef(Found->Key) == CPU;
}
+
+ /// Returns string representation of scheduler comment
+ virtual std::string getSchedInfoStr(const MachineInstr &MI) const {
+ return {};
+ }
+
+ virtual std::string getSchedInfoStr(MCInst const &MCI) const {
+ return {};
+ }
};
-} // End llvm namespace
+} // end namespace llvm
-#endif
+#endif // LLVM_MC_MCSUBTARGETINFO_H
diff --git a/contrib/llvm/include/llvm/MC/MCSymbol.h b/contrib/llvm/include/llvm/MC/MCSymbol.h
index 23e34b7..9b1cc6e 100644
--- a/contrib/llvm/include/llvm/MC/MCSymbol.h
+++ b/contrib/llvm/include/llvm/MC/MCSymbol.h
@@ -15,18 +15,21 @@
#define LLVM_MC_MCSYMBOL_H
#include "llvm/ADT/PointerIntPair.h"
-#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/MC/MCFragment.h"
-#include "llvm/Support/Compiler.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/MathExtras.h"
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
namespace llvm {
+
class MCAsmInfo;
+class MCContext;
class MCExpr;
-class MCSymbol;
-class MCFragment;
class MCSection;
-class MCContext;
class raw_ostream;
/// MCSymbol - Instances of this class represent a symbol name in the MC file,
@@ -45,6 +48,7 @@ protected:
SymbolKindCOFF,
SymbolKindELF,
SymbolKindMachO,
+ SymbolKindWasm,
};
/// A symbol can contain an Offset, or Value, or be Common, but never more
@@ -97,7 +101,7 @@ protected:
/// LLVM RTTI discriminator. This is actually a SymbolKind enumerator, but is
/// unsigned to avoid sign extension and achieve better bitpacking with MSVC.
- unsigned Kind : 2;
+ unsigned Kind : 3;
/// True if we have created a relocation that uses this symbol.
mutable unsigned IsUsedInReloc : 1;
@@ -133,7 +137,7 @@ protected:
const MCExpr *Value;
};
-protected: // MCContext creates and uniques these.
+ // MCContext creates and uniques these.
friend class MCExpr;
friend class MCContext;
@@ -141,10 +145,10 @@ protected: // MCContext creates and uniques these.
/// MCSymbol contains a uint64_t so is probably aligned to 8. On a 32-bit
/// system, the name is a pointer so isn't going to satisfy the 8 byte
/// alignment of uint64_t. Account for that here.
- typedef union {
+ using NameEntryStorageTy = union {
const StringMapEntry<bool> *NameEntry;
uint64_t AlignmentPadding;
- } NameEntryStorageTy;
+ };
MCSymbol(SymbolKind Kind, const StringMapEntry<bool> *Name, bool isTemporary)
: IsTemporary(isTemporary), IsRedefinable(false), IsUsed(false),
@@ -163,7 +167,6 @@ protected: // MCContext creates and uniques these.
MCContext &Ctx);
private:
-
void operator delete(void *);
/// \brief Placement delete - required by std, but never called.
void operator delete(void*, unsigned) {
@@ -174,8 +177,6 @@ private:
llvm_unreachable("Constructor throws?");
}
- MCSymbol(const MCSymbol &) = delete;
- void operator=(const MCSymbol &) = delete;
MCSection *getSectionPtr(bool SetUsed = true) const {
if (MCFragment *F = getFragment(SetUsed)) {
assert(F != AbsolutePseudoFragment);
@@ -195,6 +196,9 @@ private:
}
public:
+ MCSymbol(const MCSymbol &) = delete;
+ MCSymbol &operator=(const MCSymbol &) = delete;
+
/// getName - Get the symbol name.
StringRef getName() const {
if (!FragmentAndHasName.getInt())
@@ -281,6 +285,8 @@ public:
bool isMachO() const { return Kind == SymbolKindMachO; }
+ bool isWasm() const { return Kind == SymbolKindWasm; }
+
/// @}
/// \name Variable Symbols
/// @{
@@ -416,6 +422,7 @@ inline raw_ostream &operator<<(raw_ostream &OS, const MCSymbol &Sym) {
Sym.print(OS, nullptr);
return OS;
}
+
} // end namespace llvm
-#endif
+#endif // LLVM_MC_MCSYMBOL_H
diff --git a/contrib/llvm/include/llvm/MC/MCSymbolCOFF.h b/contrib/llvm/include/llvm/MC/MCSymbolCOFF.h
index 2172c67..7918c35 100644
--- a/contrib/llvm/include/llvm/MC/MCSymbolCOFF.h
+++ b/contrib/llvm/include/llvm/MC/MCSymbolCOFF.h
@@ -6,16 +6,18 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+
#ifndef LLVM_MC_MCSYMBOLCOFF_H
#define LLVM_MC_MCSYMBOLCOFF_H
#include "llvm/MC/MCSymbol.h"
+#include <cstdint>
namespace llvm {
-class MCSymbolCOFF : public MCSymbol {
+class MCSymbolCOFF : public MCSymbol {
/// This corresponds to the e_type field of the COFF symbol.
- mutable uint16_t Type;
+ mutable uint16_t Type = 0;
enum SymbolFlags : uint16_t {
SF_ClassMask = 0x00FF,
@@ -27,7 +29,7 @@ class MCSymbolCOFF : public MCSymbol {
public:
MCSymbolCOFF(const StringMapEntry<bool> *Name, bool isTemporary)
- : MCSymbol(SymbolKindCOFF, Name, isTemporary), Type(0) {}
+ : MCSymbol(SymbolKindCOFF, Name, isTemporary) {}
uint16_t getType() const {
return Type;
@@ -59,6 +61,7 @@ public:
static bool classof(const MCSymbol *S) { return S->isCOFF(); }
};
-}
-#endif
+} // end namespace llvm
+
+#endif // LLVM_MC_MCSYMBOLCOFF_H
diff --git a/contrib/llvm/include/llvm/MC/MCSymbolWasm.h b/contrib/llvm/include/llvm/MC/MCSymbolWasm.h
new file mode 100644
index 0000000..9bae6c5
--- /dev/null
+++ b/contrib/llvm/include/llvm/MC/MCSymbolWasm.h
@@ -0,0 +1,73 @@
+//===- MCSymbolWasm.h - ----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_MC_MCSYMBOLWASM_H
+#define LLVM_MC_MCSYMBOLWASM_H
+
+#include "llvm/BinaryFormat/Wasm.h"
+#include "llvm/MC/MCSymbol.h"
+
+namespace llvm {
+
+class MCSymbolWasm : public MCSymbol {
+private:
+ bool IsFunction = false;
+ bool IsWeak = false;
+ std::string ModuleName;
+ SmallVector<wasm::ValType, 1> Returns;
+ SmallVector<wasm::ValType, 4> Params;
+ bool ParamsSet = false;
+ bool ReturnsSet = false;
+
+ /// An expression describing how to calculate the size of a symbol. If a
+ /// symbol has no size this field will be NULL.
+ 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),
+ ModuleName("env") {}
+ static bool classof(const MCSymbol *S) { return S->isWasm(); }
+
+ const MCExpr *getSize() const { return SymbolSize; }
+ void setSize(const MCExpr *SS) { SymbolSize = SS; }
+
+ bool isFunction() const { return IsFunction; }
+ void setIsFunction(bool isFunc) { IsFunction = isFunc; }
+
+ bool isWeak() const { return IsWeak; }
+ void setWeak(bool isWeak) { IsWeak = isWeak; }
+
+ const StringRef getModuleName() const { return ModuleName; }
+
+ const SmallVector<wasm::ValType, 1> &getReturns() const {
+ assert(ReturnsSet);
+ return Returns;
+ }
+
+ void setReturns(SmallVectorImpl<wasm::ValType> &&Rets) {
+ ReturnsSet = true;
+ Returns = std::move(Rets);
+ }
+
+ const SmallVector<wasm::ValType, 4> &getParams() const {
+ assert(ParamsSet);
+ return Params;
+ }
+
+ void setParams(SmallVectorImpl<wasm::ValType> &&Pars) {
+ ParamsSet = true;
+ Params = std::move(Pars);
+ }
+};
+
+} // end namespace llvm
+
+#endif // LLVM_MC_MCSYMBOLWASM_H
diff --git a/contrib/llvm/include/llvm/MC/MCTargetOptions.h b/contrib/llvm/include/llvm/MC/MCTargetOptions.h
index 2564237..5509bb3 100644
--- a/contrib/llvm/include/llvm/MC/MCTargetOptions.h
+++ b/contrib/llvm/include/llvm/MC/MCTargetOptions.h
@@ -1,4 +1,4 @@
-//===- MCTargetOptions.h - MC Target Options -------------------*- C++ -*-===//
+//===- MCTargetOptions.h - MC Target Options --------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -23,6 +23,12 @@ enum class ExceptionHandling {
WinEH, /// Windows Exception Handling
};
+enum class DebugCompressionType {
+ None, /// No compression
+ GNU, /// zlib-gnu style compression
+ Z, /// zlib style complession
+};
+
class StringRef;
class MCTargetOptions {
@@ -51,46 +57,23 @@ public:
/// Preserve Comments in Assembly.
bool PreserveAsmComments : 1;
- int DwarfVersion;
+ int DwarfVersion = 0;
- /// getABIName - If this returns a non-empty string this represents the
- /// textual name of the ABI that we want the backend to use, e.g. o32, or
- /// aapcs-linux.
- StringRef getABIName() const;
std::string ABIName;
+ std::string SplitDwarfFile;
/// Additional paths to search for `.include` directives when using the
/// integrated assembler.
std::vector<std::string> IASSearchPaths;
MCTargetOptions();
-};
-inline bool operator==(const MCTargetOptions &LHS, const MCTargetOptions &RHS) {
-#define ARE_EQUAL(X) LHS.X == RHS.X
- return (ARE_EQUAL(SanitizeAddress) &&
- ARE_EQUAL(MCRelaxAll) &&
- ARE_EQUAL(MCNoExecStack) &&
- ARE_EQUAL(MCFatalWarnings) &&
- ARE_EQUAL(MCNoWarn) &&
- ARE_EQUAL(MCNoDeprecatedWarn) &&
- ARE_EQUAL(MCSaveTempLabels) &&
- ARE_EQUAL(MCUseDwarfDirectory) &&
- ARE_EQUAL(MCIncrementalLinkerCompatible) &&
- ARE_EQUAL(MCPIECopyRelocations) &&
- ARE_EQUAL(ShowMCEncoding) &&
- ARE_EQUAL(ShowMCInst) &&
- ARE_EQUAL(AsmVerbose) &&
- ARE_EQUAL(DwarfVersion) &&
- ARE_EQUAL(ABIName) &&
- ARE_EQUAL(IASSearchPaths));
-#undef ARE_EQUAL
-}
-
-inline bool operator!=(const MCTargetOptions &LHS, const MCTargetOptions &RHS) {
- return !(LHS == RHS);
-}
+ /// getABIName - If this returns a non-empty string this represents the
+ /// textual name of the ABI that we want the backend to use, e.g. o32, or
+ /// aapcs-linux.
+ StringRef getABIName() const;
+};
} // end namespace llvm
-#endif
+#endif // LLVM_MC_MCTARGETOPTIONS_H
diff --git a/contrib/llvm/include/llvm/MC/MCValue.h b/contrib/llvm/include/llvm/MC/MCValue.h
index ead08fd..aa1eaf0 100644
--- a/contrib/llvm/include/llvm/MC/MCValue.h
+++ b/contrib/llvm/include/llvm/MC/MCValue.h
@@ -42,7 +42,7 @@ class MCValue {
int64_t Cst;
uint32_t RefKind;
public:
-
+ MCValue() : SymA(nullptr), SymB(nullptr), Cst(0), RefKind(0) {}
int64_t getConstant() const { return Cst; }
const MCSymbolRefExpr *getSymA() const { return SymA; }
const MCSymbolRefExpr *getSymB() const { return SymB; }
diff --git a/contrib/llvm/include/llvm/MC/MCWasmObjectWriter.h b/contrib/llvm/include/llvm/MC/MCWasmObjectWriter.h
new file mode 100644
index 0000000..bebc0a8
--- /dev/null
+++ b/contrib/llvm/include/llvm/MC/MCWasmObjectWriter.h
@@ -0,0 +1,52 @@
+//===-- llvm/MC/MCWasmObjectWriter.h - Wasm Object Writer -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCWASMOBJECTWRITER_H
+#define LLVM_MC_MCWASMOBJECTWRITER_H
+
+#include "llvm/ADT/Triple.h"
+#include "llvm/BinaryFormat/Wasm.h"
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+
+class MCFixup;
+class MCObjectWriter;
+class MCValue;
+class raw_pwrite_stream;
+
+class MCWasmObjectTargetWriter {
+ const unsigned Is64Bit : 1;
+
+protected:
+ explicit MCWasmObjectTargetWriter(bool Is64Bit_);
+
+public:
+ virtual ~MCWasmObjectTargetWriter();
+
+ virtual unsigned getRelocType(const MCValue &Target,
+ const MCFixup &Fixup) const = 0;
+
+ /// \name Accessors
+ /// @{
+ bool is64Bit() const { return Is64Bit; }
+ /// @}
+};
+
+/// \brief Construct a new Wasm writer instance.
+///
+/// \param MOTW - The target specific Wasm writer subclass.
+/// \param OS - The stream to write to.
+/// \returns The constructed object writer.
+MCObjectWriter *createWasmObjectWriter(MCWasmObjectTargetWriter *MOTW,
+ raw_pwrite_stream &OS);
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/MC/MCWasmStreamer.h b/contrib/llvm/include/llvm/MC/MCWasmStreamer.h
new file mode 100644
index 0000000..bdd6f10
--- /dev/null
+++ b/contrib/llvm/include/llvm/MC/MCWasmStreamer.h
@@ -0,0 +1,83 @@
+//===- MCWasmStreamer.h - MCStreamer Wasm Object File Interface -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCWASMSTREAMER_H
+#define LLVM_MC_MCWASMSTREAMER_H
+
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/MC/MCDirectives.h"
+#include "llvm/MC/MCObjectStreamer.h"
+#include "llvm/MC/SectionKind.h"
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+class MCAsmBackend;
+class MCAssembler;
+class MCCodeEmitter;
+class MCExpr;
+class MCInst;
+class raw_ostream;
+
+class MCWasmStreamer : public MCObjectStreamer {
+public:
+ MCWasmStreamer(MCContext &Context, MCAsmBackend &TAB, raw_pwrite_stream &OS,
+ MCCodeEmitter *Emitter)
+ : MCObjectStreamer(Context, TAB, OS, Emitter), SeenIdent(false) {}
+
+ ~MCWasmStreamer() override;
+
+ /// state management
+ void reset() override {
+ SeenIdent = false;
+ MCObjectStreamer::reset();
+ }
+
+ /// \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,
+ unsigned ByteAlignment) override;
+
+ void emitELFSize(MCSymbol *Symbol, const MCExpr *Value) override;
+
+ void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
+ unsigned ByteAlignment) override;
+
+ void EmitZerofill(MCSection *Section, MCSymbol *Symbol = nullptr,
+ uint64_t Size = 0, unsigned ByteAlignment = 0) override;
+ void EmitTBSSSymbol(MCSection *Section, MCSymbol *Symbol, uint64_t Size,
+ unsigned ByteAlignment = 0) override;
+ void EmitValueImpl(const MCExpr *Value, unsigned Size,
+ SMLoc Loc = SMLoc()) override;
+
+ void EmitIdent(StringRef IdentString) override;
+
+ void EmitValueToAlignment(unsigned, int64_t, unsigned, unsigned) override;
+
+ void FinishImpl() override;
+
+private:
+ void EmitInstToFragment(const MCInst &Inst, const MCSubtargetInfo &) override;
+ void EmitInstToData(const MCInst &Inst, const MCSubtargetInfo &) override;
+
+ /// \brief Merge the content of the fragment \p EF into the fragment \p DF.
+ void mergeFragment(MCDataFragment *, MCDataFragment *);
+
+ bool SeenIdent;
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/MC/MCWinCOFFObjectWriter.h b/contrib/llvm/include/llvm/MC/MCWinCOFFObjectWriter.h
index e2e95c7..198a08b 100644
--- a/contrib/llvm/include/llvm/MC/MCWinCOFFObjectWriter.h
+++ b/contrib/llvm/include/llvm/MC/MCWinCOFFObjectWriter.h
@@ -1,4 +1,4 @@
-//===-- llvm/MC/MCWinCOFFObjectWriter.h - Win COFF Object Writer *- C++ -*-===//
+//===- llvm/MC/MCWinCOFFObjectWriter.h - Win COFF Object Writer -*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -11,26 +11,28 @@
#define LLVM_MC_MCWINCOFFOBJECTWRITER_H
namespace llvm {
+
class MCAsmBackend;
+class MCContext;
class MCFixup;
class MCObjectWriter;
class MCValue;
-class raw_ostream;
class raw_pwrite_stream;
class MCWinCOFFObjectTargetWriter {
virtual void anchor();
+
const unsigned Machine;
protected:
MCWinCOFFObjectTargetWriter(unsigned Machine_);
public:
- virtual ~MCWinCOFFObjectTargetWriter() {}
+ virtual ~MCWinCOFFObjectTargetWriter() = default;
unsigned getMachine() const { return Machine; }
- virtual unsigned getRelocType(const MCValue &Target, const MCFixup &Fixup,
- bool IsCrossSection,
+ virtual unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
+ const MCFixup &Fixup, bool IsCrossSection,
const MCAsmBackend &MAB) const = 0;
virtual bool recordRelocation(const MCFixup &) const { return true; }
};
@@ -42,6 +44,6 @@ class raw_pwrite_stream;
/// \returns The constructed object writer.
MCObjectWriter *createWinCOFFObjectWriter(MCWinCOFFObjectTargetWriter *MOTW,
raw_pwrite_stream &OS);
-} // End llvm namespace
+} // end namespace llvm
-#endif
+#endif // LLVM_MC_MCWINCOFFOBJECTWRITER_H
diff --git a/contrib/llvm/include/llvm/MC/MCWinCOFFStreamer.h b/contrib/llvm/include/llvm/MC/MCWinCOFFStreamer.h
index 63e44f2..84e60b8 100644
--- a/contrib/llvm/include/llvm/MC/MCWinCOFFStreamer.h
+++ b/contrib/llvm/include/llvm/MC/MCWinCOFFStreamer.h
@@ -14,16 +14,15 @@
#include "llvm/MC/MCObjectStreamer.h"
namespace llvm {
+
class MCAsmBackend;
class MCContext;
class MCCodeEmitter;
-class MCExpr;
class MCInst;
class MCSection;
class MCSubtargetInfo;
class MCSymbol;
class StringRef;
-class raw_ostream;
class raw_pwrite_stream;
class MCWinCOFFStreamer : public MCObjectStreamer {
@@ -41,7 +40,7 @@ public:
/// \{
void InitSections(bool NoExecStack) override;
- void EmitLabel(MCSymbol *Symbol) 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;
@@ -61,7 +60,6 @@ public:
unsigned ByteAlignment) override;
void EmitTBSSSymbol(MCSection *Section, MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment) override;
- void EmitFileDirective(StringRef Filename) override;
void EmitIdent(StringRef IdentString) override;
void EmitWinEHHandlerData() override;
void FinishImpl() override;
@@ -70,12 +68,13 @@ public:
protected:
const MCSymbol *CurSymbol;
+
void EmitInstToData(const MCInst &Inst, const MCSubtargetInfo &STI) override;
private:
void Error(const Twine &Msg) const;
};
-}
-#endif
+} // end namespace llvm
+#endif // LLVM_MC_MCWINCOFFSTREAMER_H
diff --git a/contrib/llvm/include/llvm/MC/MachineLocation.h b/contrib/llvm/include/llvm/MC/MachineLocation.h
index 4b5cf43..f4fc6ee 100644
--- a/contrib/llvm/include/llvm/MC/MachineLocation.h
+++ b/contrib/llvm/include/llvm/MC/MachineLocation.h
@@ -1,4 +1,4 @@
-//===-- llvm/MC/MachineLocation.h -------------------------------*- C++ -*-===//
+//===- llvm/MC/MachineLocation.h --------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -12,35 +12,31 @@
// explicitly passing an offset to the constructor.
//===----------------------------------------------------------------------===//
-
#ifndef LLVM_MC_MACHINELOCATION_H
#define LLVM_MC_MACHINELOCATION_H
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/DataTypes.h"
+#include <cstdint>
namespace llvm {
- class MCSymbol;
class MachineLocation {
private:
- bool IsRegister; // True if location is a register.
- unsigned Register; // gcc/gdb register number.
- int Offset; // Displacement if not register.
+ bool IsRegister = false; // True if location is a register.
+ unsigned Register = 0; // gcc/gdb register number.
+ int Offset = 0; // Displacement if not register.
+
public:
enum : uint32_t {
// The target register number for an abstract frame pointer. The value is
// an arbitrary value that doesn't collide with any real target register.
VirtualFP = ~0U
};
- MachineLocation()
- : IsRegister(false), Register(0), Offset(0) {}
+
+ MachineLocation() = default;
/// Create a direct register location.
- explicit MachineLocation(unsigned R)
- : IsRegister(true), Register(R), Offset(0) {}
+ explicit MachineLocation(unsigned R) : IsRegister(true), Register(R) {}
/// Create a register-indirect location with an offset.
- MachineLocation(unsigned R, int O)
- : IsRegister(false), Register(R), Offset(O) {}
+ MachineLocation(unsigned R, int O) : Register(R), Offset(O) {}
bool operator==(const MachineLocation &Other) const {
return IsRegister == Other.IsRegister && Register == Other.Register &&
@@ -56,12 +52,14 @@ public:
void setIsRegister(bool Is) { IsRegister = Is; }
void setRegister(unsigned R) { Register = R; }
void setOffset(int O) { Offset = O; }
+
/// Make this location a direct register location.
void set(unsigned R) {
IsRegister = true;
Register = R;
Offset = 0;
}
+
/// Make this location a register-indirect+offset location.
void set(unsigned R, int O) {
IsRegister = false;
@@ -74,6 +72,6 @@ inline bool operator!=(const MachineLocation &LHS, const MachineLocation &RHS) {
return !(LHS == RHS);
}
-} // End llvm namespace
+} // end namespace llvm
-#endif
+#endif // LLVM_MC_MACHINELOCATION_H
diff --git a/contrib/llvm/include/llvm/MC/StringTableBuilder.h b/contrib/llvm/include/llvm/MC/StringTableBuilder.h
index 7da444f..0df3fcd 100644
--- a/contrib/llvm/include/llvm/MC/StringTableBuilder.h
+++ b/contrib/llvm/include/llvm/MC/StringTableBuilder.h
@@ -1,4 +1,4 @@
-//===-- StringTableBuilder.h - String table building utility ------*- C++ -*-=//
+//===- StringTableBuilder.h - String table building utility -----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -12,9 +12,12 @@
#include "llvm/ADT/CachedHashString.h"
#include "llvm/ADT/DenseMap.h"
-#include <cassert>
+#include "llvm/ADT/StringRef.h"
+#include <cstddef>
+#include <cstdint>
namespace llvm {
+
class raw_ostream;
/// \brief Utility for building string tables with deduplicated suffixes.
@@ -67,6 +70,6 @@ private:
bool isFinalized() const { return Finalized; }
};
-} // end llvm namespace
+} // end namespace llvm
-#endif
+#endif // LLVM_MC_STRINGTABLEBUILDER_H
diff --git a/contrib/llvm/include/llvm/MC/SubtargetFeature.h b/contrib/llvm/include/llvm/MC/SubtargetFeature.h
index ed4abd7..cb03667 100644
--- a/contrib/llvm/include/llvm/MC/SubtargetFeature.h
+++ b/contrib/llvm/include/llvm/MC/SubtargetFeature.h
@@ -1,4 +1,4 @@
-//===-- llvm/MC/SubtargetFeature.h - CPU characteristics --------*- C++ -*-===//
+//===- llvm/MC/SubtargetFeature.h - CPU characteristics ---------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,126 +7,124 @@
//
//===----------------------------------------------------------------------===//
//
-// This file defines and manages user or tool specified CPU characteristics.
-// The intent is to be able to package specific features that should or should
-// not be used on a specific target processor. A tool, such as llc, could, as
-// as example, gather chip info from the command line, a long with features
-// that should be used on that chip.
+/// \file Defines and manages user or tool specified CPU characteristics.
+/// The intent is to be able to package specific features that should or should
+/// not be used on a specific target processor. A tool, such as llc, could, as
+/// as example, gather chip info from the command line, a long with features
+/// that should be used on that chip.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_MC_SUBTARGETFEATURE_H
#define LLVM_MC_SUBTARGETFEATURE_H
-#include "llvm/ADT/Triple.h"
-#include "llvm/Support/DataTypes.h"
+#include "llvm/ADT/StringRef.h"
#include <bitset>
+#include <initializer_list>
+#include <string>
#include <vector>
namespace llvm {
+
template <typename T> class ArrayRef;
- class raw_ostream;
- class StringRef;
+class raw_ostream;
+class Triple;
-// A container class for subtarget features.
-// This is convenient because std::bitset does not have a constructor
-// with an initializer list of set bits.
-const unsigned MAX_SUBTARGET_FEATURES = 128;
+const unsigned MAX_SUBTARGET_FEATURES = 192;
+/// Container class for subtarget features.
+/// This is convenient because std::bitset does not have a constructor
+/// with an initializer list of set bits.
class FeatureBitset : public std::bitset<MAX_SUBTARGET_FEATURES> {
public:
// Cannot inherit constructors because it's not supported by VC++..
- FeatureBitset() : bitset() {}
+ FeatureBitset() = default;
FeatureBitset(const bitset<MAX_SUBTARGET_FEATURES>& B) : bitset(B) {}
- FeatureBitset(std::initializer_list<unsigned> Init) : bitset() {
+ FeatureBitset(std::initializer_list<unsigned> Init) {
for (auto I : Init)
set(I);
}
};
//===----------------------------------------------------------------------===//
-///
-/// SubtargetFeatureKV - Used to provide key value pairs for feature and
-/// CPU bit flags.
-//
+
+/// Used to provide key value pairs for feature and CPU bit flags.
struct SubtargetFeatureKV {
- const char *Key; // K-V key string
- const char *Desc; // Help descriptor
- FeatureBitset Value; // K-V integer value
- FeatureBitset Implies; // K-V bit mask
+ const char *Key; ///< K-V key string
+ const char *Desc; ///< Help descriptor
+ FeatureBitset Value; ///< K-V integer value
+ FeatureBitset Implies; ///< K-V bit mask
- // Compare routine for std::lower_bound
+ /// Compare routine for std::lower_bound
bool operator<(StringRef S) const {
return StringRef(Key) < S;
}
- // Compare routine for std::is_sorted.
+ /// Compare routine for std::is_sorted.
bool operator<(const SubtargetFeatureKV &Other) const {
return StringRef(Key) < StringRef(Other.Key);
}
};
//===----------------------------------------------------------------------===//
-///
-/// SubtargetInfoKV - Used to provide key value pairs for CPU and arbitrary
-/// pointers.
-//
+
+/// Used to provide key value pairs for CPU and arbitrary pointers.
struct SubtargetInfoKV {
- const char *Key; // K-V key string
- const void *Value; // K-V pointer value
+ const char *Key; ///< K-V key string
+ const void *Value; ///< K-V pointer value
- // Compare routine for std::lower_bound
+ /// Compare routine for std::lower_bound
bool operator<(StringRef S) const {
return StringRef(Key) < S;
}
};
//===----------------------------------------------------------------------===//
+
+/// Manages the enabling and disabling of subtarget specific features.
///
-/// SubtargetFeatures - Manages the enabling and disabling of subtarget
-/// specific features. Features are encoded as a string of the form
+/// Features are encoded as a string of the form
/// "+attr1,+attr2,-attr3,...,+attrN"
/// A comma separates each feature from the next (all lowercase.)
/// Each of the remaining features is prefixed with + or - indicating whether
/// that feature should be enabled or disabled contrary to the cpu
/// specification.
-///
-
class SubtargetFeatures {
- std::vector<std::string> Features; // Subtarget features as a vector
+ std::vector<std::string> Features; ///< Subtarget features as a vector
+
public:
explicit SubtargetFeatures(StringRef Initial = "");
- /// Features string accessors.
+ /// Returns features as a string.
std::string getString() const;
- /// Adding Features.
+ /// Adds Features.
void AddFeature(StringRef String, bool Enable = true);
- /// ToggleFeature - Toggle a feature and update the feature bits.
+ /// Toggles a feature and update the feature bits.
static void ToggleFeature(FeatureBitset &Bits, StringRef String,
ArrayRef<SubtargetFeatureKV> FeatureTable);
- /// Apply the feature flag and update the feature bits.
+ /// Applies the feature flag and update the feature bits.
static void ApplyFeatureFlag(FeatureBitset &Bits, StringRef Feature,
ArrayRef<SubtargetFeatureKV> FeatureTable);
- /// Get feature bits of a CPU.
+ /// Returns feature bits of a CPU.
FeatureBitset getFeatureBits(StringRef CPU,
- ArrayRef<SubtargetFeatureKV> CPUTable,
- ArrayRef<SubtargetFeatureKV> FeatureTable);
+ ArrayRef<SubtargetFeatureKV> CPUTable,
+ ArrayRef<SubtargetFeatureKV> FeatureTable);
- /// Print feature string.
+ /// Prints feature string.
void print(raw_ostream &OS) const;
- // Dump feature info.
+ // Dumps feature info.
void dump() const;
/// Adds the default features for the specified target triple.
void getDefaultSubtargetFeatures(const Triple& Triple);
};
-} // End namespace llvm
+} // end namespace llvm
-#endif
+#endif // LLVM_MC_SUBTARGETFEATURE_H
diff --git a/contrib/llvm/include/llvm/Object/Archive.h b/contrib/llvm/include/llvm/Object/Archive.h
index 08128b0..e56e8e4 100644
--- a/contrib/llvm/include/llvm/Object/Archive.h
+++ b/contrib/llvm/include/llvm/Object/Archive.h
@@ -20,9 +20,14 @@
#include "llvm/Object/Binary.h"
#include "llvm/Support/Chrono.h"
#include "llvm/Support/Error.h"
-#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/MemoryBuffer.h"
+#include <algorithm>
+#include <cassert>
+#include <cstdint>
+#include <memory>
+#include <string>
+#include <vector>
namespace llvm {
namespace object {
@@ -32,25 +37,28 @@ class Archive;
class ArchiveMemberHeader {
public:
friend class Archive;
+
ArchiveMemberHeader(Archive const *Parent, const char *RawHeaderPtr,
uint64_t Size, Error *Err);
// ArchiveMemberHeader() = default;
/// Get the name without looking up long names.
- Expected<llvm::StringRef> getRawName() const;
+ Expected<StringRef> getRawName() const;
/// Get the name looking up long names.
- Expected<llvm::StringRef> getName(uint64_t Size) const;
+ Expected<StringRef> getName(uint64_t Size) const;
/// Members are not larger than 4GB.
Expected<uint32_t> getSize() const;
Expected<sys::fs::perms> getAccessMode() const;
Expected<sys::TimePoint<std::chrono::seconds>> getLastModified() const;
- llvm::StringRef getRawLastModified() const {
+
+ StringRef getRawLastModified() const {
return StringRef(ArMemHdr->LastModified,
sizeof(ArMemHdr->LastModified)).rtrim(' ');
}
+
Expected<unsigned> getUID() const;
Expected<unsigned> getGID() const;
@@ -75,11 +83,13 @@ private:
class Archive : public Binary {
virtual void anchor();
+
public:
class Child {
friend Archive;
- const Archive *Parent;
friend ArchiveMemberHeader;
+
+ const Archive *Parent;
ArchiveMemberHeader Header;
/// \brief Includes header but not padding byte.
StringRef Data;
@@ -103,17 +113,22 @@ public:
Expected<StringRef> getName() const;
Expected<std::string> getFullName() const;
Expected<StringRef> getRawName() const { return Header.getRawName(); }
+
Expected<sys::TimePoint<std::chrono::seconds>> getLastModified() const {
return Header.getLastModified();
}
+
StringRef getRawLastModified() const {
return Header.getRawLastModified();
}
+
Expected<unsigned> getUID() const { return Header.getUID(); }
Expected<unsigned> getGID() const { return Header.getGID(); }
+
Expected<sys::fs::perms> getAccessMode() const {
return Header.getAccessMode();
}
+
/// \return the size of the archive member without the header or padding.
Expected<uint64_t> getSize() const;
/// \return the size in the archive header for this member.
@@ -130,11 +145,12 @@ public:
class child_iterator {
Child C;
- Error *E;
+ Error *E = nullptr;
public:
- child_iterator() : C(Child(nullptr, nullptr, nullptr)), E(nullptr) {}
+ child_iterator() : C(Child(nullptr, nullptr, nullptr)) {}
child_iterator(const Child &C, Error *E) : C(C), E(E) {}
+
const Child *operator->() const { return &C; }
const Child &operator*() const { return C; }
@@ -171,14 +187,15 @@ public:
uint32_t StringIndex; // Extra index to the string.
public:
- bool operator ==(const Symbol &other) const {
- return (Parent == other.Parent) && (SymbolIndex == other.SymbolIndex);
- }
-
Symbol(const Archive *p, uint32_t symi, uint32_t stri)
: Parent(p)
, SymbolIndex(symi)
, StringIndex(stri) {}
+
+ bool operator ==(const Symbol &other) const {
+ return (Parent == other.Parent) && (SymbolIndex == other.SymbolIndex);
+ }
+
StringRef getName() const;
Expected<Child> getMember() const;
Symbol getNext() const;
@@ -186,8 +203,10 @@ public:
class symbol_iterator {
Symbol symbol;
+
public:
symbol_iterator(const Symbol &s) : symbol(s) {}
+
const Symbol *operator->() const { return &symbol; }
const Symbol &operator*() const { return symbol; }
@@ -212,6 +231,7 @@ public:
K_GNU,
K_MIPS64,
K_BSD,
+ K_DARWIN,
K_DARWIN64,
K_COFF
};
@@ -233,7 +253,7 @@ public:
}
// Cast methods.
- static inline bool classof(Binary const *v) {
+ static bool classof(Binary const *v) {
return v->isArchive();
}
@@ -263,7 +283,7 @@ private:
mutable std::vector<std::unique_ptr<MemoryBuffer>> ThinBuffers;
};
-}
-}
+} // end namespace object
+} // end namespace llvm
-#endif
+#endif // LLVM_OBJECT_ARCHIVE_H
diff --git a/contrib/llvm/include/llvm/Object/ArchiveWriter.h b/contrib/llvm/include/llvm/Object/ArchiveWriter.h
index 3e84a58..1ed758d 100644
--- a/contrib/llvm/include/llvm/Object/ArchiveWriter.h
+++ b/contrib/llvm/include/llvm/Object/ArchiveWriter.h
@@ -22,6 +22,7 @@ namespace llvm {
struct NewArchiveMember {
std::unique_ptr<MemoryBuffer> Buf;
+ StringRef MemberName;
sys::TimePoint<std::chrono::seconds> ModTime;
unsigned UID = 0, GID = 0, Perms = 0644;
diff --git a/contrib/llvm/include/llvm/Object/Binary.h b/contrib/llvm/include/llvm/Object/Binary.h
index 00d06e3..3f5a233 100644
--- a/contrib/llvm/include/llvm/Object/Binary.h
+++ b/contrib/llvm/include/llvm/Object/Binary.h
@@ -14,10 +14,12 @@
#ifndef LLVM_OBJECT_BINARY_H
#define LLVM_OBJECT_BINARY_H
-#include "llvm/Object/Error.h"
-#include "llvm/Support/ErrorOr.h"
-#include "llvm/Support/FileSystem.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/Support/Error.h"
#include "llvm/Support/MemoryBuffer.h"
+#include <algorithm>
+#include <memory>
+#include <utility>
namespace llvm {
@@ -28,9 +30,6 @@ namespace object {
class Binary {
private:
- Binary() = delete;
- Binary(const Binary &other) = delete;
-
unsigned int TypeID;
protected:
@@ -43,7 +42,6 @@ protected:
ID_MachOUniversalBinary,
ID_COFFImportFile,
ID_IR, // LLVM IR
- ID_ModuleSummaryIndex, // Module summary index
// Object and children.
ID_StartObjects,
@@ -59,6 +57,8 @@ protected:
ID_MachO64L, // MachO 64-bit, little endian
ID_MachO64B, // MachO 64-bit, big endian
+ ID_WinRes, // Windows resource (.res) file.
+
ID_Wasm,
ID_EndObjects
@@ -79,6 +79,8 @@ protected:
}
public:
+ Binary() = delete;
+ Binary(const Binary &other) = delete;
virtual ~Binary();
StringRef getData() const;
@@ -93,9 +95,7 @@ public:
return TypeID > ID_StartObjects && TypeID < ID_EndObjects;
}
- bool isSymbolic() const {
- return isIR() || isObject();
- }
+ bool isSymbolic() const { return isIR() || isObject() || isCOFFImportFile(); }
bool isArchive() const {
return TypeID == ID_Archive;
@@ -127,12 +127,22 @@ public:
return TypeID == ID_IR;
}
- bool isModuleSummaryIndex() const { return TypeID == ID_ModuleSummaryIndex; }
-
bool isLittleEndian() const {
return !(TypeID == ID_ELF32B || TypeID == ID_ELF64B ||
TypeID == ID_MachO32B || TypeID == ID_MachO64B);
}
+
+ bool isWinRes() const { return TypeID == ID_WinRes; }
+
+ Triple::ObjectFormatType getTripleObjectFormat() const {
+ if (isCOFF())
+ return Triple::COFF;
+ if (isMachO())
+ return Triple::MachO;
+ if (isELF())
+ return Triple::ELF;
+ return Triple::UnknownObjectFormat;
+ }
};
/// @brief Create a Binary from Source, autodetecting the file type.
@@ -162,7 +172,7 @@ OwningBinary<T>::OwningBinary(std::unique_ptr<T> Bin,
std::unique_ptr<MemoryBuffer> Buf)
: Bin(std::move(Bin)), Buf(std::move(Buf)) {}
-template <typename T> OwningBinary<T>::OwningBinary() {}
+template <typename T> OwningBinary<T>::OwningBinary() = default;
template <typename T>
OwningBinary<T>::OwningBinary(OwningBinary &&Other)
@@ -190,7 +200,9 @@ template <typename T> const T* OwningBinary<T>::getBinary() const {
}
Expected<OwningBinary<Binary>> createBinary(StringRef Path);
-}
-}
-#endif
+} // end namespace object
+
+} // end namespace llvm
+
+#endif // LLVM_OBJECT_BINARY_H
diff --git a/contrib/llvm/include/llvm/Object/COFF.h b/contrib/llvm/include/llvm/Object/COFF.h
index 696042d..89c1ba6 100644
--- a/contrib/llvm/include/llvm/Object/COFF.h
+++ b/contrib/llvm/include/llvm/Object/COFF.h
@@ -14,28 +14,42 @@
#ifndef LLVM_OBJECT_COFF_H
#define LLVM_OBJECT_COFF_H
-#include "llvm/ADT/PointerUnion.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/BinaryFormat/COFF.h"
#include "llvm/DebugInfo/CodeView/CVDebugRecord.h"
+#include "llvm/MC/SubtargetFeature.h"
+#include "llvm/Object/Binary.h"
+#include "llvm/Object/Error.h"
#include "llvm/Object/ObjectFile.h"
-#include "llvm/Support/COFF.h"
+#include "llvm/Support/BinaryByteStream.h"
+#include "llvm/Support/ConvertUTF.h"
#include "llvm/Support/Endian.h"
+#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/ErrorOr.h"
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
+#include <system_error>
namespace llvm {
+
template <typename T> class ArrayRef;
namespace object {
-class ImportDirectoryEntryRef;
+
+class BaseRelocRef;
class DelayImportDirectoryEntryRef;
class ExportDirectoryEntryRef;
+class ImportDirectoryEntryRef;
class ImportedSymbolRef;
-class BaseRelocRef;
-typedef content_iterator<ImportDirectoryEntryRef> import_directory_iterator;
-typedef content_iterator<DelayImportDirectoryEntryRef>
- delay_import_directory_iterator;
-typedef content_iterator<ExportDirectoryEntryRef> export_directory_iterator;
-typedef content_iterator<ImportedSymbolRef> imported_symbol_iterator;
-typedef content_iterator<BaseRelocRef> base_reloc_iterator;
+class ResourceSectionRef;
+
+using import_directory_iterator = content_iterator<ImportDirectoryEntryRef>;
+using delay_import_directory_iterator =
+ content_iterator<DelayImportDirectoryEntryRef>;
+using export_directory_iterator = content_iterator<ExportDirectoryEntryRef>;
+using imported_symbol_iterator = content_iterator<ImportedSymbolRef>;
+using base_reloc_iterator = content_iterator<BaseRelocRef>;
/// The DOS compatible header at the front of all PE/COFF executables.
struct dos_header {
@@ -190,10 +204,10 @@ struct import_lookup_table_entry {
}
};
-typedef import_lookup_table_entry<support::little32_t>
- import_lookup_table_entry32;
-typedef import_lookup_table_entry<support::little64_t>
- import_lookup_table_entry64;
+using import_lookup_table_entry32 =
+ import_lookup_table_entry<support::little32_t>;
+using import_lookup_table_entry64 =
+ import_lookup_table_entry<support::little64_t>;
struct delay_import_directory_table_entry {
// dumpbin reports this field as "Characteristics" instead of "Attributes".
@@ -226,8 +240,8 @@ union export_address_table_entry {
support::ulittle32_t ForwarderRVA;
};
-typedef support::ulittle32_t export_name_pointer_table_entry;
-typedef support::ulittle16_t export_ordinal_table_entry;
+using export_name_pointer_table_entry = support::ulittle32_t;
+using export_ordinal_table_entry = support::ulittle16_t;
struct StringTableOffset {
support::ulittle32_t Zeroes;
@@ -250,8 +264,8 @@ struct coff_symbol {
uint8_t NumberOfAuxSymbols;
};
-typedef coff_symbol<support::ulittle16_t> coff_symbol16;
-typedef coff_symbol<support::ulittle32_t> coff_symbol32;
+using coff_symbol16 = coff_symbol<support::ulittle16_t>;
+using coff_symbol32 = coff_symbol<support::ulittle32_t>;
// Contains only common parts of coff_symbol16 and coff_symbol32.
struct coff_symbol_generic {
@@ -264,9 +278,9 @@ struct coff_symbol_generic {
class COFFSymbolRef {
public:
- COFFSymbolRef(const coff_symbol16 *CS) : CS16(CS), CS32(nullptr) {}
- COFFSymbolRef(const coff_symbol32 *CS) : CS16(nullptr), CS32(CS) {}
- COFFSymbolRef() : CS16(nullptr), CS32(nullptr) {}
+ COFFSymbolRef() = default;
+ COFFSymbolRef(const coff_symbol16 *CS) : CS16(CS) {}
+ COFFSymbolRef(const coff_symbol32 *CS) : CS32(CS) {}
const void *getRawPtr() const {
return CS16 ? static_cast<const void *>(CS16) : CS32;
@@ -396,8 +410,8 @@ public:
private:
bool isSet() const { return CS16 || CS32; }
- const coff_symbol16 *CS16;
- const coff_symbol32 *CS32;
+ const coff_symbol16 *CS16 = nullptr;
+ const coff_symbol32 *CS32 = nullptr;
};
struct coff_section {
@@ -418,6 +432,7 @@ struct coff_section {
return (Characteristics & COFF::IMAGE_SCN_LNK_NRELOC_OVFL) &&
NumberOfRelocations == UINT16_MAX;
}
+
uint32_t getAlignment() const {
// The IMAGE_SCN_TYPE_NO_PAD bit is a legacy way of getting to
// IMAGE_SCN_ALIGN_1BYTES.
@@ -508,6 +523,7 @@ struct coff_import_header {
support::ulittle32_t SizeOfData;
support::ulittle16_t OrdinalHint;
support::ulittle16_t TypeInfo;
+
int getType() const { return TypeInfo & 0x3; }
int getNameType() const { return (TypeInfo >> 2) & 0x7; }
};
@@ -518,6 +534,7 @@ struct coff_import_directory_table_entry {
support::ulittle32_t ForwarderChain;
support::ulittle32_t NameRVA;
support::ulittle32_t ImportAddressTableRVA;
+
bool isNull() const {
return ImportLookupTableRVA == 0 && TimeDateStamp == 0 &&
ForwarderChain == 0 && NameRVA == 0 && ImportAddressTableRVA == 0;
@@ -532,6 +549,7 @@ struct coff_tls_directory {
IntTy AddressOfCallBacks;
support::ulittle32_t SizeOfZeroFill;
support::ulittle32_t Characteristics;
+
uint32_t getAlignment() const {
// Bit [20:24] contains section alignment.
uint32_t Shift = (Characteristics & 0x00F00000) >> 20;
@@ -541,11 +559,29 @@ struct coff_tls_directory {
}
};
-typedef coff_tls_directory<support::little32_t> coff_tls_directory32;
-typedef coff_tls_directory<support::little64_t> coff_tls_directory64;
+using coff_tls_directory32 = coff_tls_directory<support::little32_t>;
+using coff_tls_directory64 = coff_tls_directory<support::little64_t>;
+
+/// Bits in control flow guard flags as we understand them.
+enum class coff_guard_flags : uint32_t {
+ CFInstrumented = 0x00000100,
+ HasFidTable = 0x00000400,
+ ProtectDelayLoadIAT = 0x00001000,
+ DelayLoadIATSection = 0x00002000, // Delay load in separate section
+ HasLongJmpTable = 0x00010000,
+ FidTableHasFlags = 0x10000000, // Indicates that fid tables are 5 bytes
+};
+
+struct coff_load_config_code_integrity {
+ support::ulittle16_t Flags;
+ support::ulittle16_t Catalog;
+ support::ulittle32_t CatalogOffset;
+ support::ulittle32_t Reserved;
+};
+/// 32-bit load config (IMAGE_LOAD_CONFIG_DIRECTORY32)
struct coff_load_configuration32 {
- support::ulittle32_t Characteristics;
+ support::ulittle32_t Size;
support::ulittle32_t TimeDateStamp;
support::ulittle16_t MajorVersion;
support::ulittle16_t MinorVersion;
@@ -560,34 +596,81 @@ struct coff_load_configuration32 {
support::ulittle32_t ProcessAffinityMask;
support::ulittle32_t ProcessHeapFlags;
support::ulittle16_t CSDVersion;
- support::ulittle16_t Reserved;
+ support::ulittle16_t DependentLoadFlags;
support::ulittle32_t EditList;
support::ulittle32_t SecurityCookie;
support::ulittle32_t SEHandlerTable;
support::ulittle32_t SEHandlerCount;
+
+ // Added in MSVC 2015 for /guard:cf.
+ support::ulittle32_t GuardCFCheckFunction;
+ support::ulittle32_t GuardCFCheckDispatch;
+ support::ulittle32_t GuardCFFunctionTable;
+ support::ulittle32_t GuardCFFunctionCount;
+ support::ulittle32_t GuardFlags; // coff_guard_flags
+
+ // Added in MSVC 2017
+ coff_load_config_code_integrity CodeIntegrity;
+ support::ulittle32_t GuardAddressTakenIatEntryTable;
+ support::ulittle32_t GuardAddressTakenIatEntryCount;
+ support::ulittle32_t GuardLongJumpTargetTable;
+ support::ulittle32_t GuardLongJumpTargetCount;
+ support::ulittle32_t DynamicValueRelocTable;
+ support::ulittle32_t CHPEMetadataPointer;
+ support::ulittle32_t GuardRFFailureRoutine;
+ support::ulittle32_t GuardRFFailureRoutineFunctionPointer;
+ support::ulittle32_t DynamicValueRelocTableOffset;
+ support::ulittle16_t DynamicValueRelocTableSection;
+ support::ulittle16_t Reserved2;
+ support::ulittle32_t GuardRFVerifyStackPointerFunctionPointer;
+ support::ulittle32_t HotPatchTableOffset;
};
+/// 64-bit load config (IMAGE_LOAD_CONFIG_DIRECTORY64)
struct coff_load_configuration64 {
- support::ulittle32_t Characteristics;
+ support::ulittle32_t Size;
support::ulittle32_t TimeDateStamp;
support::ulittle16_t MajorVersion;
support::ulittle16_t MinorVersion;
support::ulittle32_t GlobalFlagsClear;
support::ulittle32_t GlobalFlagsSet;
support::ulittle32_t CriticalSectionDefaultTimeout;
- support::ulittle32_t DeCommitFreeBlockThreshold;
- support::ulittle32_t DeCommitTotalFreeThreshold;
- support::ulittle32_t LockPrefixTable;
- support::ulittle32_t MaximumAllocationSize;
- support::ulittle32_t VirtualMemoryThreshold;
- support::ulittle32_t ProcessAffinityMask;
+ support::ulittle64_t DeCommitFreeBlockThreshold;
+ support::ulittle64_t DeCommitTotalFreeThreshold;
+ support::ulittle64_t LockPrefixTable;
+ support::ulittle64_t MaximumAllocationSize;
+ support::ulittle64_t VirtualMemoryThreshold;
+ support::ulittle64_t ProcessAffinityMask;
support::ulittle32_t ProcessHeapFlags;
support::ulittle16_t CSDVersion;
- support::ulittle16_t Reserved;
- support::ulittle32_t EditList;
+ support::ulittle16_t DependentLoadFlags;
+ support::ulittle64_t EditList;
support::ulittle64_t SecurityCookie;
support::ulittle64_t SEHandlerTable;
support::ulittle64_t SEHandlerCount;
+
+ // Added in MSVC 2015 for /guard:cf.
+ support::ulittle64_t GuardCFCheckFunction;
+ support::ulittle64_t GuardCFCheckDispatch;
+ support::ulittle64_t GuardCFFunctionTable;
+ support::ulittle64_t GuardCFFunctionCount;
+ support::ulittle32_t GuardFlags;
+
+ // Added in MSVC 2017
+ coff_load_config_code_integrity CodeIntegrity;
+ support::ulittle64_t GuardAddressTakenIatEntryTable;
+ support::ulittle64_t GuardAddressTakenIatEntryCount;
+ support::ulittle64_t GuardLongJumpTargetTable;
+ support::ulittle64_t GuardLongJumpTargetCount;
+ support::ulittle64_t DynamicValueRelocTable;
+ support::ulittle64_t CHPEMetadataPointer;
+ support::ulittle64_t GuardRFFailureRoutine;
+ support::ulittle64_t GuardRFFailureRoutineFunctionPointer;
+ support::ulittle32_t DynamicValueRelocTableOffset;
+ support::ulittle16_t DynamicValueRelocTableSection;
+ support::ulittle16_t Reserved2;
+ support::ulittle64_t GuardRFVerifyStackPointerFunctionPointer;
+ support::ulittle32_t HotPatchTableOffset;
};
struct coff_runtime_function_x64 {
@@ -603,10 +686,50 @@ struct coff_base_reloc_block_header {
struct coff_base_reloc_block_entry {
support::ulittle16_t Data;
+
int getType() const { return Data >> 12; }
int getOffset() const { return Data & ((1 << 12) - 1); }
};
+struct coff_resource_dir_entry {
+ union {
+ support::ulittle32_t NameOffset;
+ support::ulittle32_t ID;
+ uint32_t getNameOffset() const {
+ return maskTrailingOnes<uint32_t>(31) & NameOffset;
+ }
+ // Even though the PE/COFF spec doesn't mention this, the high bit of a name
+ // offset is set.
+ void setNameOffset(uint32_t Offset) { NameOffset = Offset | (1 << 31); }
+ } Identifier;
+ union {
+ support::ulittle32_t DataEntryOffset;
+ support::ulittle32_t SubdirOffset;
+
+ bool isSubDir() const { return SubdirOffset >> 31; }
+ uint32_t value() const {
+ return maskTrailingOnes<uint32_t>(31) & SubdirOffset;
+ }
+
+ } Offset;
+};
+
+struct coff_resource_data_entry {
+ support::ulittle32_t DataRVA;
+ support::ulittle32_t DataSize;
+ support::ulittle32_t Codepage;
+ support::ulittle32_t Reserved;
+};
+
+struct coff_resource_dir_table {
+ support::ulittle32_t Characteristics;
+ support::ulittle32_t TimeDateStamp;
+ support::ulittle16_t MajorVersion;
+ support::ulittle16_t MinorVersion;
+ support::ulittle16_t NumberOfNameEntries;
+ support::ulittle16_t NumberOfIDEntries;
+};
+
class COFFObjectFile : public ObjectFile {
private:
friend class ImportDirectoryEntryRef;
@@ -629,6 +752,8 @@ private:
const coff_base_reloc_block_header *BaseRelocEnd;
const debug_directory *DebugDirectoryBegin;
const debug_directory *DebugDirectoryEnd;
+ // Either coff_load_configuration32 or coff_load_configuration64.
+ const void *LoadConfig;
std::error_code getString(uint32_t offset, StringRef &Res) const;
@@ -643,6 +768,7 @@ private:
std::error_code initExportTablePtr();
std::error_code initBaseRelocPtr();
std::error_code initDebugDirectoryPtr();
+ std::error_code initLoadConfigPtr();
public:
uintptr_t getSymbolTable() const {
@@ -652,6 +778,7 @@ public:
return reinterpret_cast<uintptr_t>(SymbolTable32);
return uintptr_t(0);
}
+
uint16_t getMachine() const {
if (COFFHeader)
return COFFHeader->Machine;
@@ -659,6 +786,7 @@ public:
return COFFBigObjHeader->Machine;
llvm_unreachable("no COFF header!");
}
+
uint16_t getSizeOfOptionalHeader() const {
if (COFFHeader)
return COFFHeader->isImportLibrary() ? 0
@@ -668,6 +796,7 @@ public:
return 0;
llvm_unreachable("no COFF header!");
}
+
uint16_t getCharacteristics() const {
if (COFFHeader)
return COFFHeader->isImportLibrary() ? 0 : COFFHeader->Characteristics;
@@ -677,6 +806,7 @@ public:
return 0;
llvm_unreachable("no COFF header!");
}
+
uint32_t getTimeDateStamp() const {
if (COFFHeader)
return COFFHeader->TimeDateStamp;
@@ -684,6 +814,7 @@ public:
return COFFBigObjHeader->TimeDateStamp;
llvm_unreachable("no COFF header!");
}
+
uint32_t getNumberOfSections() const {
if (COFFHeader)
return COFFHeader->isImportLibrary() ? 0 : COFFHeader->NumberOfSections;
@@ -691,6 +822,7 @@ public:
return COFFBigObjHeader->NumberOfSections;
llvm_unreachable("no COFF header!");
}
+
uint32_t getPointerToSymbolTable() const {
if (COFFHeader)
return COFFHeader->isImportLibrary() ? 0
@@ -699,6 +831,7 @@ public:
return COFFBigObjHeader->PointerToSymbolTable;
llvm_unreachable("no COFF header!");
}
+
uint32_t getRawNumberOfSymbols() const {
if (COFFHeader)
return COFFHeader->isImportLibrary() ? 0 : COFFHeader->NumberOfSymbols;
@@ -706,11 +839,23 @@ public:
return COFFBigObjHeader->NumberOfSymbols;
llvm_unreachable("no COFF header!");
}
+
uint32_t getNumberOfSymbols() const {
if (!SymbolTable16 && !SymbolTable32)
return 0;
return getRawNumberOfSymbols();
}
+
+ const coff_load_configuration32 *getLoadConfig32() const {
+ assert(!is64());
+ return reinterpret_cast<const coff_load_configuration32 *>(LoadConfig);
+ }
+
+ const coff_load_configuration64 *getLoadConfig64() const {
+ assert(is64());
+ return reinterpret_cast<const coff_load_configuration64 *>(LoadConfig);
+ }
+
protected:
void moveSymbolNext(DataRefImpl &Symb) const override;
Expected<StringRef> getSymbolName(DataRefImpl Symb) const override;
@@ -725,6 +870,7 @@ protected:
std::error_code getSectionName(DataRefImpl Sec,
StringRef &Res) const override;
uint64_t getSectionAddress(DataRefImpl Sec) const override;
+ uint64_t getSectionIndex(DataRefImpl Sec) const override;
uint64_t getSectionSize(DataRefImpl Sec) const override;
std::error_code getSectionContents(DataRefImpl Sec,
StringRef &Res) const override;
@@ -746,6 +892,7 @@ protected:
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;
@@ -797,6 +944,7 @@ public:
std::error_code getDataDirectory(uint32_t index,
const data_directory *&Res) const;
std::error_code getSection(int32_t index, const coff_section *&Res) const;
+
template <typename coff_symbol_type>
std::error_code getSymbol(uint32_t Index,
const coff_symbol_type *&Res) const {
@@ -821,6 +969,7 @@ public:
}
return object_error::parse_failed;
}
+
template <typename T>
std::error_code getAuxSymbol(uint32_t index, const T *&Res) const {
ErrorOr<COFFSymbolRef> s = getSymbol(index);
@@ -829,6 +978,7 @@ public:
Res = reinterpret_cast<const T *>(s->getRawPtr());
return std::error_code();
}
+
std::error_code getSymbolName(COFFSymbolRef Symbol, StringRef &Res) const;
std::error_code getSymbolName(const coff_symbol_generic *Symbol,
StringRef &Res) const;
@@ -879,13 +1029,13 @@ public:
bool isRelocatableObject() const override;
bool is64() const { return PE32PlusHeader; }
- static inline bool classof(const Binary *v) { return v->isCOFF(); }
+ static bool classof(const Binary *v) { return v->isCOFF(); }
};
// The iterator for the import directory table.
class ImportDirectoryEntryRef {
public:
- ImportDirectoryEntryRef() : OwningObject(nullptr) {}
+ ImportDirectoryEntryRef() = default;
ImportDirectoryEntryRef(const coff_import_directory_table_entry *Table,
uint32_t I, const COFFObjectFile *Owner)
: ImportTable(Table), Index(I), OwningObject(Owner) {}
@@ -911,12 +1061,12 @@ public:
private:
const coff_import_directory_table_entry *ImportTable;
uint32_t Index;
- const COFFObjectFile *OwningObject;
+ const COFFObjectFile *OwningObject = nullptr;
};
class DelayImportDirectoryEntryRef {
public:
- DelayImportDirectoryEntryRef() : OwningObject(nullptr) {}
+ DelayImportDirectoryEntryRef() = default;
DelayImportDirectoryEntryRef(const delay_import_directory_table_entry *T,
uint32_t I, const COFFObjectFile *Owner)
: Table(T), Index(I), OwningObject(Owner) {}
@@ -936,13 +1086,13 @@ public:
private:
const delay_import_directory_table_entry *Table;
uint32_t Index;
- const COFFObjectFile *OwningObject;
+ const COFFObjectFile *OwningObject = nullptr;
};
// The iterator for the export directory table entry.
class ExportDirectoryEntryRef {
public:
- ExportDirectoryEntryRef() : OwningObject(nullptr) {}
+ ExportDirectoryEntryRef() = default;
ExportDirectoryEntryRef(const export_directory_table_entry *Table, uint32_t I,
const COFFObjectFile *Owner)
: ExportTable(Table), Index(I), OwningObject(Owner) {}
@@ -962,12 +1112,12 @@ public:
private:
const export_directory_table_entry *ExportTable;
uint32_t Index;
- const COFFObjectFile *OwningObject;
+ const COFFObjectFile *OwningObject = nullptr;
};
class ImportedSymbolRef {
public:
- ImportedSymbolRef() : OwningObject(nullptr) {}
+ ImportedSymbolRef() = default;
ImportedSymbolRef(const import_lookup_table_entry32 *Entry, uint32_t I,
const COFFObjectFile *Owner)
: Entry32(Entry), Entry64(nullptr), Index(I), OwningObject(Owner) {}
@@ -987,12 +1137,12 @@ private:
const import_lookup_table_entry32 *Entry32;
const import_lookup_table_entry64 *Entry64;
uint32_t Index;
- const COFFObjectFile *OwningObject;
+ const COFFObjectFile *OwningObject = nullptr;
};
class BaseRelocRef {
public:
- BaseRelocRef() : OwningObject(nullptr) {}
+ BaseRelocRef() = default;
BaseRelocRef(const coff_base_reloc_block_header *Header,
const COFFObjectFile *Owner)
: Header(Header), Index(0), OwningObject(Owner) {}
@@ -1006,7 +1156,24 @@ public:
private:
const coff_base_reloc_block_header *Header;
uint32_t Index;
- const COFFObjectFile *OwningObject;
+ const COFFObjectFile *OwningObject = nullptr;
+};
+
+class ResourceSectionRef {
+public:
+ ResourceSectionRef() = default;
+ explicit ResourceSectionRef(StringRef Ref) : BBS(Ref, support::little) {}
+
+ ErrorOr<ArrayRef<UTF16>> getEntryNameString(const coff_resource_dir_entry &Entry);
+ ErrorOr<const coff_resource_dir_table &>
+ getEntrySubDir(const coff_resource_dir_entry &Entry);
+ ErrorOr<const coff_resource_dir_table &> getBaseTable();
+
+private:
+ BinaryByteStream BBS;
+
+ ErrorOr<const coff_resource_dir_table &> getTableAtOffset(uint32_t Offset);
+ ErrorOr<ArrayRef<UTF16>> getDirStringAtOffset(uint32_t Offset);
};
// Corresponds to `_FPO_DATA` structure in the PE/COFF spec.
@@ -1034,6 +1201,7 @@ struct FpoData {
};
} // end namespace object
+
} // end namespace llvm
-#endif
+#endif // LLVM_OBJECT_COFF_H
diff --git a/contrib/llvm/include/llvm/Object/COFFImportFile.h b/contrib/llvm/include/llvm/Object/COFFImportFile.h
index 4192fe7..cf9c80a 100644
--- a/contrib/llvm/include/llvm/Object/COFFImportFile.h
+++ b/contrib/llvm/include/llvm/Object/COFFImportFile.h
@@ -9,13 +9,15 @@
//
// COFF short import file is a special kind of file which contains
// only symbol names for DLL-exported symbols. This class implements
-// SymbolicFile interface for the file.
+// exporting of Symbols to create libraries and a SymbolicFile
+// interface for the file type.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_OBJECT_COFF_IMPORT_FILE_H
#define LLVM_OBJECT_COFF_IMPORT_FILE_H
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/Object/COFF.h"
#include "llvm/Object/IRObjectFile.h"
#include "llvm/Object/ObjectFile.h"
@@ -31,7 +33,7 @@ public:
COFFImportFile(MemoryBufferRef Source)
: SymbolicFile(ID_COFFImportFile, Source) {}
- static inline bool classof(Binary const *V) { return V->isCOFFImportFile(); }
+ static bool classof(Binary const *V) { return V->isCOFFImportFile(); }
void moveSymbolNext(DataRefImpl &Symb) const override { ++Symb.p; }
@@ -53,7 +55,7 @@ public:
basic_symbol_iterator symbol_end() const override {
DataRefImpl Symb;
- Symb.p = isCode() ? 2 : 1;
+ Symb.p = isData() ? 1 : 2;
return BasicSymbolRef(Symb, this);
}
@@ -63,11 +65,43 @@ public:
}
private:
- bool isCode() const {
- return getCOFFImportHeader()->getType() == COFF::IMPORT_CODE;
+ bool isData() const {
+ return getCOFFImportHeader()->getType() == COFF::IMPORT_DATA;
}
};
+struct COFFShortExport {
+ std::string Name;
+ std::string ExtName;
+ std::string SymbolName;
+
+ uint16_t Ordinal = 0;
+ bool Noname = false;
+ bool Data = false;
+ bool Private = false;
+ bool Constant = false;
+
+ bool isWeak() {
+ return ExtName.size() && ExtName != Name;
+ }
+
+ friend bool operator==(const COFFShortExport &L, const COFFShortExport &R) {
+ return L.Name == R.Name && L.ExtName == R.ExtName &&
+ L.Ordinal == R.Ordinal && L.Noname == R.Noname &&
+ L.Data == R.Data && L.Private == R.Private;
+ }
+
+ friend bool operator!=(const COFFShortExport &L, const COFFShortExport &R) {
+ return !(L == R);
+ }
+};
+
+std::error_code writeImportLibrary(StringRef ImportName,
+ StringRef Path,
+ ArrayRef<COFFShortExport> Exports,
+ COFF::MachineTypes Machine,
+ bool MakeWeakAliases);
+
} // namespace object
} // namespace llvm
diff --git a/contrib/llvm/include/llvm/Object/COFFModuleDefinition.h b/contrib/llvm/include/llvm/Object/COFFModuleDefinition.h
new file mode 100644
index 0000000..be139a2
--- /dev/null
+++ b/contrib/llvm/include/llvm/Object/COFFModuleDefinition.h
@@ -0,0 +1,53 @@
+//===--- COFFModuleDefinition.h ---------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Windows-specific.
+// A parser for the module-definition file (.def file).
+// Parsed results are directly written to Config global variable.
+//
+// The format of module-definition files are described in this document:
+// https://msdn.microsoft.com/en-us/library/28d6s79h.aspx
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_COFF_MODULE_DEFINITION_H
+#define LLVM_OBJECT_COFF_MODULE_DEFINITION_H
+
+#include "llvm/Object/COFF.h"
+#include "llvm/Object/COFFImportFile.h"
+
+namespace llvm {
+namespace object {
+
+struct COFFModuleDefinition {
+ std::vector<COFFShortExport> Exports;
+ std::string OutputFile;
+ std::string ImportName;
+ uint64_t ImageBase = 0;
+ uint64_t StackReserve = 0;
+ uint64_t StackCommit = 0;
+ uint64_t HeapReserve = 0;
+ uint64_t HeapCommit = 0;
+ uint32_t MajorImageVersion = 0;
+ uint32_t MinorImageVersion = 0;
+ uint32_t MajorOSVersion = 0;
+ uint32_t MinorOSVersion = 0;
+};
+
+// mingw and wine def files do not mangle _ for x86 which
+// is a consequence of legacy binutils' dlltool functionality.
+// This MingwDef flag should be removed once mingw stops this pratice.
+Expected<COFFModuleDefinition>
+parseCOFFModuleDefinition(MemoryBufferRef MB, COFF::MachineTypes Machine,
+ bool MingwDef = false);
+
+} // End namespace object.
+} // End namespace llvm.
+
+#endif
diff --git a/contrib/llvm/include/llvm/Object/Decompressor.h b/contrib/llvm/include/llvm/Object/Decompressor.h
index a11857d..c8e888d 100644
--- a/contrib/llvm/include/llvm/Object/Decompressor.h
+++ b/contrib/llvm/include/llvm/Object/Decompressor.h
@@ -10,8 +10,8 @@
#ifndef LLVM_OBJECT_DECOMPRESSOR_H
#define LLVM_OBJECT_DECOMPRESSOR_H
-#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/Object/ObjectFile.h"
namespace llvm {
@@ -30,7 +30,10 @@ public:
/// @brief Resize the buffer and uncompress section data into it.
/// @param Out Destination buffer.
- Error decompress(SmallString<32> &Out);
+ template <class T> Error resizeAndDecompress(T &Out) {
+ Out.resize(DecompressedSize);
+ return decompress({Out.data(), (size_t)DecompressedSize});
+ }
/// @brief Uncompress section data to raw buffer provided.
/// @param Buffer Destination buffer.
diff --git a/contrib/llvm/include/llvm/Object/ELF.h b/contrib/llvm/include/llvm/Object/ELF.h
index aaa79ae..670c0bb 100644
--- a/contrib/llvm/include/llvm/Object/ELF.h
+++ b/contrib/llvm/include/llvm/Object/ELF.h
@@ -14,14 +14,25 @@
#ifndef LLVM_OBJECT_ELF_H
#define LLVM_OBJECT_ELF_H
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/BinaryFormat/ELF.h"
#include "llvm/Object/ELFTypes.h"
-#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Object/Error.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
+#include <limits>
+#include <utility>
namespace llvm {
namespace object {
StringRef getELFRelocationTypeName(uint32_t Machine, uint32_t Type);
+StringRef getELFSectionTypeName(uint32_t Machine, uint32_t Type);
// Subclasses of ELFFile may need this for template instantiation
inline std::pair<unsigned char, unsigned char>
@@ -41,27 +52,27 @@ template <class ELFT>
class ELFFile {
public:
LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
- typedef typename ELFT::uint uintX_t;
- typedef typename ELFT::Ehdr Elf_Ehdr;
- typedef typename ELFT::Shdr Elf_Shdr;
- typedef typename ELFT::Sym Elf_Sym;
- typedef typename ELFT::Dyn Elf_Dyn;
- typedef typename ELFT::Phdr Elf_Phdr;
- typedef typename ELFT::Rel Elf_Rel;
- typedef typename ELFT::Rela Elf_Rela;
- typedef typename ELFT::Verdef Elf_Verdef;
- typedef typename ELFT::Verdaux Elf_Verdaux;
- typedef typename ELFT::Verneed Elf_Verneed;
- typedef typename ELFT::Vernaux Elf_Vernaux;
- typedef typename ELFT::Versym Elf_Versym;
- typedef typename ELFT::Hash Elf_Hash;
- typedef typename ELFT::GnuHash Elf_GnuHash;
- typedef typename ELFT::DynRange Elf_Dyn_Range;
- typedef typename ELFT::ShdrRange Elf_Shdr_Range;
- typedef typename ELFT::SymRange Elf_Sym_Range;
- typedef typename ELFT::RelRange Elf_Rel_Range;
- typedef typename ELFT::RelaRange Elf_Rela_Range;
- typedef typename ELFT::PhdrRange Elf_Phdr_Range;
+ using uintX_t = typename ELFT::uint;
+ using Elf_Ehdr = typename ELFT::Ehdr;
+ using Elf_Shdr = typename ELFT::Shdr;
+ using Elf_Sym = typename ELFT::Sym;
+ using Elf_Dyn = typename ELFT::Dyn;
+ using Elf_Phdr = typename ELFT::Phdr;
+ using Elf_Rel = typename ELFT::Rel;
+ using Elf_Rela = typename ELFT::Rela;
+ using Elf_Verdef = typename ELFT::Verdef;
+ using Elf_Verdaux = typename ELFT::Verdaux;
+ using Elf_Verneed = typename ELFT::Verneed;
+ using Elf_Vernaux = typename ELFT::Vernaux;
+ using Elf_Versym = typename ELFT::Versym;
+ using Elf_Hash = typename ELFT::Hash;
+ using Elf_GnuHash = typename ELFT::GnuHash;
+ using Elf_Dyn_Range = typename ELFT::DynRange;
+ using Elf_Shdr_Range = typename ELFT::ShdrRange;
+ using Elf_Sym_Range = typename ELFT::SymRange;
+ using Elf_Rel_Range = typename ELFT::RelRange;
+ using Elf_Rela_Range = typename ELFT::RelaRange;
+ using Elf_Phdr_Range = typename ELFT::PhdrRange;
const uint8_t *base() const {
return reinterpret_cast<const uint8_t *>(Buf.data());
@@ -70,7 +81,6 @@ public:
size_t getBufSize() const { return Buf.size(); }
private:
-
StringRef Buf;
public:
@@ -161,10 +171,10 @@ public:
Expected<ArrayRef<uint8_t>> getSectionContents(const Elf_Shdr *Sec) const;
};
-typedef ELFFile<ELFType<support::little, false>> ELF32LEFile;
-typedef ELFFile<ELFType<support::little, true>> ELF64LEFile;
-typedef ELFFile<ELFType<support::big, false>> ELF32BEFile;
-typedef ELFFile<ELFType<support::big, true>> ELF64BEFile;
+using ELF32LEFile = ELFFile<ELFType<support::little, false>>;
+using ELF64LEFile = ELFFile<ELFType<support::little, true>>;
+using ELF32BEFile = ELFFile<ELFType<support::big, false>>;
+using ELF64BEFile = ELFFile<ELFType<support::big, true>>;
template <class ELFT>
inline Expected<const typename ELFT::Shdr *>
@@ -194,7 +204,7 @@ ELFFile<ELFT>::getSectionIndex(const Elf_Sym *Sym, Elf_Sym_Range Syms,
ArrayRef<Elf_Word> ShndxTable) const {
uint32_t Index = Sym->st_shndx;
if (Index == ELF::SHN_XINDEX) {
- auto ErrorOrIndex = object::getExtendedSymbolTableIndex<ELFT>(
+ auto ErrorOrIndex = getExtendedSymbolTableIndex<ELFT>(
Sym, Syms.begin(), ShndxTable);
if (!ErrorOrIndex)
return ErrorOrIndex.takeError();
@@ -225,10 +235,7 @@ ELFFile<ELFT>::getSection(const Elf_Sym *Sym, Elf_Sym_Range Symbols,
uint32_t Index = *IndexOrErr;
if (Index == 0)
return nullptr;
- auto SectionsOrErr = sections();
- if (!SectionsOrErr)
- return SectionsOrErr.takeError();
- return object::getSection<ELFT>(*SectionsOrErr, Index);
+ return getSection(Index);
}
template <class ELFT>
@@ -340,7 +347,7 @@ ELFFile<ELFT>::ELFFile(StringRef Object) : Buf(Object) {
}
template <class ELFT>
-static bool compareAddr(uint64_t VAddr, const Elf_Phdr_Impl<ELFT> *Phdr) {
+bool compareAddr(uint64_t VAddr, const Elf_Phdr_Impl<ELFT> *Phdr) {
return VAddr < Phdr->p_vaddr;
}
@@ -519,7 +526,8 @@ inline unsigned hashSysV(StringRef SymbolName) {
}
return h;
}
+
} // end namespace object
} // end namespace llvm
-#endif
+#endif // LLVM_OBJECT_ELF_H
diff --git a/contrib/llvm/include/llvm/Object/ELFObjectFile.h b/contrib/llvm/include/llvm/Object/ELFObjectFile.h
index 69987d4..73011f6 100644
--- a/contrib/llvm/include/llvm/Object/ELFObjectFile.h
+++ b/contrib/llvm/include/llvm/Object/ELFObjectFile.h
@@ -19,6 +19,7 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Triple.h"
#include "llvm/ADT/iterator_range.h"
+#include "llvm/BinaryFormat/ELF.h"
#include "llvm/MC/SubtargetFeature.h"
#include "llvm/Object/Binary.h"
#include "llvm/Object/ELF.h"
@@ -26,8 +27,9 @@
#include "llvm/Object/Error.h"
#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/ELF.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/ErrorHandling.h"
@@ -41,13 +43,11 @@ namespace llvm {
namespace object {
class elf_symbol_iterator;
-class ELFSymbolRef;
-class ELFRelocationRef;
class ELFObjectFileBase : public ObjectFile {
- friend class ELFSymbolRef;
- friend class ELFSectionRef;
friend class ELFRelocationRef;
+ friend class ELFSectionRef;
+ friend class ELFSymbolRef;
protected:
ELFObjectFileBase(unsigned int Type, MemoryBufferRef Source);
@@ -64,14 +64,21 @@ protected:
virtual ErrorOr<int64_t> getRelocationAddend(DataRefImpl Rel) const = 0;
public:
- typedef iterator_range<elf_symbol_iterator> elf_symbol_iterator_range;
+ using elf_symbol_iterator_range = iterator_range<elf_symbol_iterator>;
+
virtual elf_symbol_iterator_range getDynamicSymbolIterators() const = 0;
elf_symbol_iterator_range symbols() const;
- static inline bool classof(const Binary *v) { return v->isELF(); }
+ static bool classof(const Binary *v) { return v->isELF(); }
SubtargetFeatures getFeatures() const override;
+
+ SubtargetFeatures getMIPSFeatures() const;
+
+ SubtargetFeatures getARMFeatures() const;
+
+ void setARMSubArch(Triple &TheTriple) const override;
};
class ELFSectionRef : public SectionRef {
@@ -194,14 +201,14 @@ template <class ELFT> class ELFObjectFile : public ELFObjectFileBase {
public:
LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
- typedef typename ELFFile<ELFT>::uintX_t uintX_t;
+ using uintX_t = typename ELFFile<ELFT>::uintX_t;
- typedef typename ELFFile<ELFT>::Elf_Sym Elf_Sym;
- typedef typename ELFFile<ELFT>::Elf_Shdr Elf_Shdr;
- typedef typename ELFFile<ELFT>::Elf_Ehdr Elf_Ehdr;
- typedef typename ELFFile<ELFT>::Elf_Rel Elf_Rel;
- typedef typename ELFFile<ELFT>::Elf_Rela Elf_Rela;
- typedef typename ELFFile<ELFT>::Elf_Dyn Elf_Dyn;
+ using Elf_Sym = typename ELFFile<ELFT>::Elf_Sym;
+ using Elf_Shdr = typename ELFFile<ELFT>::Elf_Shdr;
+ using Elf_Ehdr = typename ELFFile<ELFT>::Elf_Ehdr;
+ using Elf_Rel = typename ELFFile<ELFT>::Elf_Rel;
+ using Elf_Rela = typename ELFFile<ELFT>::Elf_Rela;
+ using Elf_Dyn = typename ELFFile<ELFT>::Elf_Dyn;
protected:
ELFFile<ELFT> EF;
@@ -228,6 +235,7 @@ protected:
std::error_code getSectionName(DataRefImpl Sec,
StringRef &Res) const override;
uint64_t getSectionAddress(DataRefImpl Sec) const override;
+ uint64_t getSectionIndex(DataRefImpl Sec) const override;
uint64_t getSectionSize(DataRefImpl Sec) const override;
std::error_code getSectionContents(DataRefImpl Sec,
StringRef &Res) const override;
@@ -356,10 +364,32 @@ public:
return std::error_code();
}
+ std::error_code getBuildAttributes(ARMAttributeParser &Attributes) const override {
+ auto SectionsOrErr = EF.sections();
+ if (!SectionsOrErr)
+ return errorToErrorCode(SectionsOrErr.takeError());
+
+ for (const Elf_Shdr &Sec : *SectionsOrErr) {
+ if (Sec.sh_type == ELF::SHT_ARM_ATTRIBUTES) {
+ auto ErrorOrContents = EF.getSectionContents(&Sec);
+ if (!ErrorOrContents)
+ return errorToErrorCode(ErrorOrContents.takeError());
+
+ auto Contents = ErrorOrContents.get();
+ if (Contents[0] != ARMBuildAttrs::Format_Version || Contents.size() == 1)
+ return std::error_code();
+
+ Attributes.Parse(Contents, ELFT::TargetEndianness == support::little);
+ break;
+ }
+ }
+ return std::error_code();
+ }
+
const ELFFile<ELFT> *getELFFile() const { return &EF; }
bool isDyldType() const { return isDyldELFObject; }
- static inline bool classof(const Binary *v) {
+ static bool classof(const Binary *v) {
return v->getType() == getELFType(ELFT::TargetEndianness == support::little,
ELFT::Is64Bits);
}
@@ -369,10 +399,10 @@ public:
bool isRelocatableObject() const override;
};
-typedef ELFObjectFile<ELFType<support::little, false>> ELF32LEObjectFile;
-typedef ELFObjectFile<ELFType<support::little, true>> ELF64LEObjectFile;
-typedef ELFObjectFile<ELFType<support::big, false>> ELF32BEObjectFile;
-typedef ELFObjectFile<ELFType<support::big, true>> ELF64BEObjectFile;
+using ELF32LEObjectFile = ELFObjectFile<ELFType<support::little, false>>;
+using ELF64LEObjectFile = ELFObjectFile<ELFType<support::little, true>>;
+using ELF32BEObjectFile = ELFObjectFile<ELFType<support::big, false>>;
+using ELF64BEObjectFile = ELFObjectFile<ELFType<support::big, true>>;
template <class ELFT>
void ELFObjectFile<ELFT>::moveSymbolNext(DataRefImpl &Sym) const {
@@ -617,6 +647,17 @@ uint64_t ELFObjectFile<ELFT>::getSectionAddress(DataRefImpl Sec) const {
}
template <class ELFT>
+uint64_t ELFObjectFile<ELFT>::getSectionIndex(DataRefImpl Sec) const {
+ auto SectionsOrErr = EF.sections();
+ handleAllErrors(std::move(SectionsOrErr.takeError()),
+ [](const ErrorInfoBase &) {
+ llvm_unreachable("unable to get section index");
+ });
+ const Elf_Shdr *First = SectionsOrErr->begin();
+ return getSection(Sec) - First;
+}
+
+template <class ELFT>
uint64_t ELFObjectFile<ELFT>::getSectionSize(DataRefImpl Sec) const {
return getSection(Sec)->sh_size;
}
@@ -866,6 +907,8 @@ elf_symbol_iterator ELFObjectFile<ELFT>::dynamic_symbol_begin() const {
template <class ELFT>
elf_symbol_iterator ELFObjectFile<ELFT>::dynamic_symbol_end() const {
const Elf_Shdr *SymTab = DotDynSymSec;
+ if (!SymTab)
+ return dynamic_symbol_begin();
DataRefImpl Sym = toDRI(SymTab, SymTab->sh_size / sizeof(Elf_Sym));
return basic_symbol_iterator(SymbolRef(Sym, this));
}
diff --git a/contrib/llvm/include/llvm/Object/ELFTypes.h b/contrib/llvm/include/llvm/Object/ELFTypes.h
index 3e03fd8..8081446 100644
--- a/contrib/llvm/include/llvm/Object/ELFTypes.h
+++ b/contrib/llvm/include/llvm/Object/ELFTypes.h
@@ -11,10 +11,15 @@
#define LLVM_OBJECT_ELFTYPES_H
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/BinaryFormat/ELF.h"
#include "llvm/Object/Error.h"
-#include "llvm/Support/ELF.h"
#include "llvm/Support/Endian.h"
-#include "llvm/Support/ErrorOr.h"
+#include "llvm/Support/Error.h"
+#include <cassert>
+#include <cstdint>
+#include <cstring>
+#include <type_traits>
namespace llvm {
namespace object {
@@ -45,58 +50,58 @@ public:
static const endianness TargetEndianness = E;
static const bool Is64Bits = Is64;
- typedef typename std::conditional<Is64, uint64_t, uint32_t>::type uint;
- typedef Elf_Ehdr_Impl<ELFType<E, Is64>> Ehdr;
- typedef Elf_Shdr_Impl<ELFType<E, Is64>> Shdr;
- typedef Elf_Sym_Impl<ELFType<E, Is64>> Sym;
- typedef Elf_Dyn_Impl<ELFType<E, Is64>> Dyn;
- typedef Elf_Phdr_Impl<ELFType<E, Is64>> Phdr;
- typedef Elf_Rel_Impl<ELFType<E, Is64>, false> Rel;
- typedef Elf_Rel_Impl<ELFType<E, Is64>, true> Rela;
- typedef Elf_Verdef_Impl<ELFType<E, Is64>> Verdef;
- typedef Elf_Verdaux_Impl<ELFType<E, Is64>> Verdaux;
- typedef Elf_Verneed_Impl<ELFType<E, Is64>> Verneed;
- typedef Elf_Vernaux_Impl<ELFType<E, Is64>> Vernaux;
- typedef Elf_Versym_Impl<ELFType<E, Is64>> Versym;
- typedef Elf_Hash_Impl<ELFType<E, Is64>> Hash;
- typedef Elf_GnuHash_Impl<ELFType<E, Is64>> GnuHash;
- typedef Elf_Chdr_Impl<ELFType<E, Is64>> Chdr;
- typedef ArrayRef<Dyn> DynRange;
- typedef ArrayRef<Shdr> ShdrRange;
- typedef ArrayRef<Sym> SymRange;
- typedef ArrayRef<Rel> RelRange;
- typedef ArrayRef<Rela> RelaRange;
- typedef ArrayRef<Phdr> PhdrRange;
-
- typedef packed<uint16_t> Half;
- typedef packed<uint32_t> Word;
- typedef packed<int32_t> Sword;
- typedef packed<uint64_t> Xword;
- typedef packed<int64_t> Sxword;
- typedef packed<uint> Addr;
- typedef packed<uint> Off;
-};
-
-typedef ELFType<support::little, false> ELF32LE;
-typedef ELFType<support::big, false> ELF32BE;
-typedef ELFType<support::little, true> ELF64LE;
-typedef ELFType<support::big, true> ELF64BE;
+ using uint = typename std::conditional<Is64, uint64_t, uint32_t>::type;
+ using Ehdr = Elf_Ehdr_Impl<ELFType<E, Is64>>;
+ using Shdr = Elf_Shdr_Impl<ELFType<E, Is64>>;
+ using Sym = Elf_Sym_Impl<ELFType<E, Is64>>;
+ using Dyn = Elf_Dyn_Impl<ELFType<E, Is64>>;
+ using Phdr = Elf_Phdr_Impl<ELFType<E, Is64>>;
+ using Rel = Elf_Rel_Impl<ELFType<E, Is64>, false>;
+ using Rela = Elf_Rel_Impl<ELFType<E, Is64>, true>;
+ using Verdef = Elf_Verdef_Impl<ELFType<E, Is64>>;
+ using Verdaux = Elf_Verdaux_Impl<ELFType<E, Is64>>;
+ using Verneed = Elf_Verneed_Impl<ELFType<E, Is64>>;
+ using Vernaux = Elf_Vernaux_Impl<ELFType<E, Is64>>;
+ using Versym = Elf_Versym_Impl<ELFType<E, Is64>>;
+ using Hash = Elf_Hash_Impl<ELFType<E, Is64>>;
+ using GnuHash = Elf_GnuHash_Impl<ELFType<E, Is64>>;
+ using Chdr = Elf_Chdr_Impl<ELFType<E, Is64>>;
+ using DynRange = ArrayRef<Dyn>;
+ using ShdrRange = ArrayRef<Shdr>;
+ using SymRange = ArrayRef<Sym>;
+ using RelRange = ArrayRef<Rel>;
+ using RelaRange = ArrayRef<Rela>;
+ using PhdrRange = ArrayRef<Phdr>;
+
+ using Half = packed<uint16_t>;
+ using Word = packed<uint32_t>;
+ using Sword = packed<int32_t>;
+ using Xword = packed<uint64_t>;
+ using Sxword = packed<int64_t>;
+ using Addr = packed<uint>;
+ using Off = packed<uint>;
+};
+
+using ELF32LE = ELFType<support::little, false>;
+using ELF32BE = ELFType<support::big, false>;
+using ELF64LE = ELFType<support::little, true>;
+using ELF64BE = ELFType<support::big, true>;
// Use an alignment of 2 for the typedefs since that is the worst case for
// ELF files in archives.
// Templates to choose Elf_Addr and Elf_Off depending on is64Bits.
template <endianness target_endianness> struct ELFDataTypeTypedefHelperCommon {
- typedef support::detail::packed_endian_specific_integral<
- uint16_t, target_endianness, 2> Elf_Half;
- typedef support::detail::packed_endian_specific_integral<
- uint32_t, target_endianness, 2> Elf_Word;
- typedef support::detail::packed_endian_specific_integral<
- int32_t, target_endianness, 2> Elf_Sword;
- typedef support::detail::packed_endian_specific_integral<
- uint64_t, target_endianness, 2> Elf_Xword;
- typedef support::detail::packed_endian_specific_integral<
- int64_t, target_endianness, 2> Elf_Sxword;
+ using Elf_Half = support::detail::packed_endian_specific_integral<
+ uint16_t, target_endianness, 2>;
+ using Elf_Word = support::detail::packed_endian_specific_integral<
+ uint32_t, target_endianness, 2>;
+ using Elf_Sword = support::detail::packed_endian_specific_integral<
+ int32_t, target_endianness, 2>;
+ using Elf_Xword = support::detail::packed_endian_specific_integral<
+ uint64_t, target_endianness, 2>;
+ using Elf_Sxword = support::detail::packed_endian_specific_integral<
+ int64_t, target_endianness, 2>;
};
template <class ELFT> struct ELFDataTypeTypedefHelper;
@@ -105,34 +110,34 @@ template <class ELFT> struct ELFDataTypeTypedefHelper;
template <endianness TargetEndianness>
struct ELFDataTypeTypedefHelper<ELFType<TargetEndianness, false>>
: ELFDataTypeTypedefHelperCommon<TargetEndianness> {
- typedef uint32_t value_type;
- typedef support::detail::packed_endian_specific_integral<
- value_type, TargetEndianness, 2> Elf_Addr;
- typedef support::detail::packed_endian_specific_integral<
- value_type, TargetEndianness, 2> Elf_Off;
+ using value_type = uint32_t;
+ using Elf_Addr = support::detail::packed_endian_specific_integral<
+ value_type, TargetEndianness, 2>;
+ using Elf_Off = support::detail::packed_endian_specific_integral<
+ value_type, TargetEndianness, 2>;
};
/// ELF 64bit types.
template <endianness TargetEndianness>
struct ELFDataTypeTypedefHelper<ELFType<TargetEndianness, true>>
: ELFDataTypeTypedefHelperCommon<TargetEndianness> {
- typedef uint64_t value_type;
- typedef support::detail::packed_endian_specific_integral<
- value_type, TargetEndianness, 2> Elf_Addr;
- typedef support::detail::packed_endian_specific_integral<
- value_type, TargetEndianness, 2> Elf_Off;
+ using value_type = uint64_t;
+ using Elf_Addr = support::detail::packed_endian_specific_integral<
+ value_type, TargetEndianness, 2>;
+ using Elf_Off = support::detail::packed_endian_specific_integral<
+ value_type, TargetEndianness, 2>;
};
// I really don't like doing this, but the alternative is copypasta.
#define LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) \
- typedef typename ELFT::Addr Elf_Addr; \
- typedef typename ELFT::Off Elf_Off; \
- typedef typename ELFT::Half Elf_Half; \
- typedef typename ELFT::Word Elf_Word; \
- typedef typename ELFT::Sword Elf_Sword; \
- typedef typename ELFT::Xword Elf_Xword; \
- typedef typename ELFT::Sxword Elf_Sxword;
+ using Elf_Addr = typename ELFT::Addr; \
+ using Elf_Off = typename ELFT::Off; \
+ using Elf_Half = typename ELFT::Half; \
+ using Elf_Word = typename ELFT::Word; \
+ using Elf_Sword = typename ELFT::Sword; \
+ using Elf_Xword = typename ELFT::Xword; \
+ using Elf_Sxword = typename ELFT::Sxword;
#define LLD_ELF_COMMA ,
#define LLVM_ELF_IMPORT_TYPES(E, W) \
@@ -222,6 +227,7 @@ struct Elf_Sym_Impl : Elf_Sym_Base<ELFT> {
uint64_t getValue() const { return st_value; }
void setBinding(unsigned char b) { setBindingAndType(b, getType()); }
void setType(unsigned char t) { setBindingAndType(getBinding(), t); }
+
void setBindingAndType(unsigned char b, unsigned char t) {
st_info = (b << 4) + (t & 0x0f);
}
@@ -238,22 +244,29 @@ struct Elf_Sym_Impl : Elf_Sym_Base<ELFT> {
}
bool isAbsolute() const { return st_shndx == ELF::SHN_ABS; }
+
bool isCommon() const {
return getType() == ELF::STT_COMMON || st_shndx == ELF::SHN_COMMON;
}
+
bool isDefined() const { return !isUndefined(); }
+
bool isProcessorSpecific() const {
return st_shndx >= ELF::SHN_LOPROC && st_shndx <= ELF::SHN_HIPROC;
}
+
bool isOSSpecific() const {
return st_shndx >= ELF::SHN_LOOS && st_shndx <= ELF::SHN_HIOS;
}
+
bool isReserved() const {
// ELF::SHN_HIRESERVE is 0xffff so st_shndx <= ELF::SHN_HIRESERVE is always
// true and some compilers warn about it.
return st_shndx >= ELF::SHN_LORESERVE;
}
+
bool isUndefined() const { return st_shndx == ELF::SHN_UNDEF; }
+
bool isExternal() const {
return getBinding() != ELF::STB_LOCAL;
}
@@ -277,14 +290,12 @@ struct Elf_Versym_Impl {
Elf_Half vs_index; // Version index with flags (e.g. VERSYM_HIDDEN)
};
-template <class ELFT> struct Elf_Verdaux_Impl;
-
/// Elf_Verdef: This is the structure of entries in the SHT_GNU_verdef section
/// (.gnu.version_d). This structure is identical for ELF32 and ELF64.
template <class ELFT>
struct Elf_Verdef_Impl {
LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
- typedef Elf_Verdaux_Impl<ELFT> Elf_Verdaux;
+ using Elf_Verdaux = Elf_Verdaux_Impl<ELFT>;
Elf_Half vd_version; // Version of this structure (e.g. VER_DEF_CURRENT)
Elf_Half vd_flags; // Bitwise flags (VER_DEF_*)
Elf_Half vd_ndx; // Version index, used in .gnu.version entries
@@ -361,10 +372,10 @@ 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;
- typedef typename std::conditional<ELFT::Is64Bits,
- int64_t, int32_t>::type intX_t;
- typedef typename std::conditional<ELFT::Is64Bits,
- uint64_t, uint32_t>::type uintX_t;
+ 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;
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; }
@@ -430,6 +441,7 @@ struct Elf_Rel_Impl<ELFType<TargetEndianness, true>, false> {
return (t << 32) | ((t >> 8) & 0xff000000) | ((t >> 24) & 0x00ff0000) |
((t >> 40) & 0x0000ff00) | ((t >> 56) & 0x000000ff);
}
+
void setRInfo(uint64_t R, bool IsMips64EL) {
if (IsMips64EL)
r_info = (R >> 32) | ((R & 0xff000000) << 8) | ((R & 0x00ff0000) << 24) |
@@ -483,15 +495,15 @@ struct Elf_Ehdr_Impl {
Elf_Half e_shnum; // Number of entries in the section header table
Elf_Half e_shstrndx; // Section header table index of section name
// string table
+
bool checkMagic() const {
return (memcmp(e_ident, ELF::ElfMagic, strlen(ELF::ElfMagic))) == 0;
}
+
unsigned char getFileClass() const { return e_ident[ELF::EI_CLASS]; }
unsigned char getDataEncoding() const { return e_ident[ELF::EI_DATA]; }
};
-template <class ELFT> struct Elf_Phdr_Impl;
-
template <endianness TargetEndianness>
struct Elf_Phdr_Impl<ELFType<TargetEndianness, false>> {
LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
@@ -582,7 +594,7 @@ struct Elf_Chdr_Impl<ELFType<TargetEndianness, true>> {
template <class ELFT>
struct Elf_Mips_RegInfo;
-template <llvm::support::endianness TargetEndianness>
+template <support::endianness TargetEndianness>
struct Elf_Mips_RegInfo<ELFType<TargetEndianness, false>> {
LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
Elf_Word ri_gprmask; // bit-mask of used general registers
@@ -590,7 +602,7 @@ struct Elf_Mips_RegInfo<ELFType<TargetEndianness, false>> {
Elf_Addr ri_gp_value; // gp register value
};
-template <llvm::support::endianness TargetEndianness>
+template <support::endianness TargetEndianness>
struct Elf_Mips_RegInfo<ELFType<TargetEndianness, true>> {
LLVM_ELF_IMPORT_TYPES(TargetEndianness, true)
Elf_Word ri_gprmask; // bit-mask of used general registers
@@ -609,7 +621,7 @@ template <class ELFT> struct Elf_Mips_Options {
Elf_Word info; // Kind-specific information
Elf_Mips_RegInfo<ELFT> &getRegInfo() {
- assert(kind == llvm::ELF::ODK_REGINFO);
+ assert(kind == ELF::ODK_REGINFO);
return *reinterpret_cast<Elf_Mips_RegInfo<ELFT> *>(
(uint8_t *)this + sizeof(Elf_Mips_Options));
}
@@ -637,4 +649,4 @@ template <class ELFT> struct Elf_Mips_ABIFlags {
} // end namespace object.
} // end namespace llvm.
-#endif
+#endif // LLVM_OBJECT_ELFTYPES_H
diff --git a/contrib/llvm/include/llvm/Object/IRObjectFile.h b/contrib/llvm/include/llvm/Object/IRObjectFile.h
index 0ea8901..9a696bf 100644
--- a/contrib/llvm/include/llvm/Object/IRObjectFile.h
+++ b/contrib/llvm/include/llvm/Object/IRObjectFile.h
@@ -15,10 +15,12 @@
#define LLVM_OBJECT_IROBJECTFILE_H
#include "llvm/ADT/PointerUnion.h"
+#include "llvm/Object/IRSymtab.h"
#include "llvm/Object/ModuleSymbolTable.h"
#include "llvm/Object/SymbolicFile.h"
namespace llvm {
+class BitcodeModule;
class Mangler;
class Module;
class GlobalValue;
@@ -44,7 +46,7 @@ public:
StringRef getTargetTriple() const;
- static inline bool classof(const Binary *v) {
+ static bool classof(const Binary *v) {
return v->isIR();
}
@@ -61,7 +63,20 @@ public:
static Expected<std::unique_ptr<IRObjectFile>> create(MemoryBufferRef Object,
LLVMContext &Context);
};
+
+/// The contents of a bitcode file and its irsymtab. Any underlying data
+/// for the irsymtab are owned by Symtab and Strtab.
+struct IRSymtabFile {
+ std::vector<BitcodeModule> Mods;
+ SmallVector<char, 0> Symtab, Strtab;
+ irsymtab::Reader TheReader;
+};
+
+/// Reads a bitcode file, creating its irsymtab if necessary.
+Expected<IRSymtabFile> readIRSymtab(MemoryBufferRef MBRef);
+
}
+
}
#endif
diff --git a/contrib/llvm/include/llvm/Object/IRSymtab.h b/contrib/llvm/include/llvm/Object/IRSymtab.h
new file mode 100644
index 0000000..824a67a
--- /dev/null
+++ b/contrib/llvm/include/llvm/Object/IRSymtab.h
@@ -0,0 +1,349 @@
+//===- IRSymtab.h - data definitions for IR symbol tables -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains data definitions and a reader and builder for a symbol
+// table for LLVM IR. Its purpose is to allow linkers and other consumers of
+// bitcode files to efficiently read the symbol table for symbol resolution
+// purposes without needing to construct a module in memory.
+//
+// As with most object files the symbol table has two parts: the symbol table
+// itself and a string table which is referenced by the symbol table.
+//
+// A symbol table corresponds to a single bitcode file, which may consist of
+// multiple modules, so symbol tables may likewise contain symbols for multiple
+// modules.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_IRSYMTAB_H
+#define LLVM_OBJECT_IRSYMTAB_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/IR/GlobalValue.h"
+#include "llvm/Object/SymbolicFile.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
+#include <cassert>
+#include <cstdint>
+#include <vector>
+
+namespace llvm {
+
+struct BitcodeFileContents;
+class StringTableBuilder;
+
+namespace irsymtab {
+
+namespace storage {
+
+// The data structures in this namespace define the low-level serialization
+// format. Clients that just want to read a symbol table should use the
+// irsymtab::Reader class.
+
+using Word = support::ulittle32_t;
+
+/// A reference to a string in the string table.
+struct Str {
+ Word Offset, Size;
+
+ StringRef get(StringRef Strtab) const {
+ return {Strtab.data() + Offset, Size};
+ }
+};
+
+/// A reference to a range of objects in the symbol table.
+template <typename T> struct Range {
+ Word Offset, Size;
+
+ ArrayRef<T> get(StringRef Symtab) const {
+ return {reinterpret_cast<const T *>(Symtab.data() + Offset), Size};
+ }
+};
+
+/// Describes the range of a particular module's symbols within the symbol
+/// table.
+struct Module {
+ Word Begin, End;
+
+ /// The index of the first Uncommon for this Module.
+ Word UncBegin;
+};
+
+/// This is equivalent to an IR comdat.
+struct Comdat {
+ Str Name;
+};
+
+/// Contains the information needed by linkers for symbol resolution, as well as
+/// by the LTO implementation itself.
+struct Symbol {
+ /// The mangled symbol name.
+ Str Name;
+
+ /// The unmangled symbol name, or the empty string if this is not an IR
+ /// symbol.
+ Str IRName;
+
+ /// The index into Header::Comdats, or -1 if not a comdat member.
+ Word ComdatIndex;
+
+ Word Flags;
+ enum FlagBits {
+ FB_visibility, // 2 bits
+ FB_has_uncommon = FB_visibility + 2,
+ FB_undefined,
+ FB_weak,
+ FB_common,
+ FB_indirect,
+ FB_used,
+ FB_tls,
+ FB_may_omit,
+ FB_global,
+ FB_format_specific,
+ FB_unnamed_addr,
+ FB_executable,
+ };
+};
+
+/// This data structure contains rarely used symbol fields and is optionally
+/// referenced by a Symbol.
+struct Uncommon {
+ Word CommonSize, CommonAlign;
+
+ /// COFF-specific: the name of the symbol that a weak external resolves to
+ /// if not defined.
+ Str COFFWeakExternFallbackName;
+};
+
+struct Header {
+ /// Version number of the symtab format. This number should be incremented
+ /// when the format changes, but it does not need to be incremented if a
+ /// change to LLVM would cause it to create a different symbol table.
+ Word Version;
+ enum { kCurrentVersion = 0 };
+
+ /// The producer's version string (LLVM_VERSION_STRING " " LLVM_REVISION).
+ /// Consumers should rebuild the symbol table from IR if the producer's
+ /// version does not match the consumer's version due to potential differences
+ /// in symbol table format, symbol enumeration order and so on.
+ Str Producer;
+
+ Range<Module> Modules;
+ Range<Comdat> Comdats;
+ Range<Symbol> Symbols;
+ Range<Uncommon> Uncommons;
+
+ Str TargetTriple, SourceFileName;
+
+ /// COFF-specific: linker directives.
+ Str COFFLinkerOpts;
+};
+
+} // end namespace storage
+
+/// Fills in Symtab and StrtabBuilder with a valid symbol and string table for
+/// Mods.
+Error build(ArrayRef<Module *> Mods, SmallVector<char, 0> &Symtab,
+ StringTableBuilder &StrtabBuilder, BumpPtrAllocator &Alloc);
+
+/// This represents a symbol that has been read from a storage::Symbol and
+/// possibly a storage::Uncommon.
+struct Symbol {
+ // Copied from storage::Symbol.
+ StringRef Name, IRName;
+ int ComdatIndex;
+ uint32_t Flags;
+
+ // Copied from storage::Uncommon.
+ uint32_t CommonSize, CommonAlign;
+ StringRef COFFWeakExternFallbackName;
+
+ /// Returns the mangled symbol name.
+ StringRef getName() const { return Name; }
+
+ /// Returns the unmangled symbol name, or the empty string if this is not an
+ /// IR symbol.
+ StringRef getIRName() const { return IRName; }
+
+ /// Returns the index into the comdat table (see Reader::getComdatTable()), or
+ /// -1 if not a comdat member.
+ int getComdatIndex() const { return ComdatIndex; }
+
+ using S = storage::Symbol;
+
+ GlobalValue::VisibilityTypes getVisibility() const {
+ return GlobalValue::VisibilityTypes((Flags >> S::FB_visibility) & 3);
+ }
+
+ bool isUndefined() const { return (Flags >> S::FB_undefined) & 1; }
+ bool isWeak() const { return (Flags >> S::FB_weak) & 1; }
+ bool isCommon() const { return (Flags >> S::FB_common) & 1; }
+ bool isIndirect() const { return (Flags >> S::FB_indirect) & 1; }
+ bool isUsed() const { return (Flags >> S::FB_used) & 1; }
+ bool isTLS() const { return (Flags >> S::FB_tls) & 1; }
+
+ bool canBeOmittedFromSymbolTable() const {
+ return (Flags >> S::FB_may_omit) & 1;
+ }
+
+ bool isGlobal() const { return (Flags >> S::FB_global) & 1; }
+ bool isFormatSpecific() const { return (Flags >> S::FB_format_specific) & 1; }
+ bool isUnnamedAddr() const { return (Flags >> S::FB_unnamed_addr) & 1; }
+ bool isExecutable() const { return (Flags >> S::FB_executable) & 1; }
+
+ uint64_t getCommonSize() const {
+ assert(isCommon());
+ return CommonSize;
+ }
+
+ uint32_t getCommonAlignment() const {
+ assert(isCommon());
+ return CommonAlign;
+ }
+
+ /// COFF-specific: for weak externals, returns the name of the symbol that is
+ /// used as a fallback if the weak external remains undefined.
+ StringRef getCOFFWeakExternalFallback() const {
+ assert(isWeak() && isIndirect());
+ return COFFWeakExternFallbackName;
+ }
+};
+
+/// This class can be used to read a Symtab and Strtab produced by
+/// irsymtab::build.
+class Reader {
+ StringRef Symtab, Strtab;
+
+ ArrayRef<storage::Module> Modules;
+ ArrayRef<storage::Comdat> Comdats;
+ ArrayRef<storage::Symbol> Symbols;
+ ArrayRef<storage::Uncommon> Uncommons;
+
+ StringRef str(storage::Str S) const { return S.get(Strtab); }
+
+ template <typename T> ArrayRef<T> range(storage::Range<T> R) const {
+ return R.get(Symtab);
+ }
+
+ const storage::Header &header() const {
+ return *reinterpret_cast<const storage::Header *>(Symtab.data());
+ }
+
+public:
+ class SymbolRef;
+
+ Reader() = default;
+ Reader(StringRef Symtab, StringRef Strtab) : Symtab(Symtab), Strtab(Strtab) {
+ Modules = range(header().Modules);
+ Comdats = range(header().Comdats);
+ Symbols = range(header().Symbols);
+ Uncommons = range(header().Uncommons);
+ }
+
+ using symbol_range = iterator_range<object::content_iterator<SymbolRef>>;
+
+ /// Returns the symbol table for the entire bitcode file.
+ /// The symbols enumerated by this method are ephemeral, but they can be
+ /// copied into an irsymtab::Symbol object.
+ symbol_range symbols() const;
+
+ size_t getNumModules() const { return Modules.size(); }
+
+ /// Returns a slice of the symbol table for the I'th module in the file.
+ /// The symbols enumerated by this method are ephemeral, but they can be
+ /// copied into an irsymtab::Symbol object.
+ symbol_range module_symbols(unsigned I) const;
+
+ StringRef getTargetTriple() const { return str(header().TargetTriple); }
+
+ /// Returns the source file path specified at compile time.
+ StringRef getSourceFileName() const { return str(header().SourceFileName); }
+
+ /// Returns a table with all the comdats used by this file.
+ std::vector<StringRef> getComdatTable() const {
+ std::vector<StringRef> ComdatTable;
+ ComdatTable.reserve(Comdats.size());
+ for (auto C : Comdats)
+ ComdatTable.push_back(str(C.Name));
+ return ComdatTable;
+ }
+
+ /// COFF-specific: returns linker options specified in the input file.
+ StringRef getCOFFLinkerOpts() const { return str(header().COFFLinkerOpts); }
+};
+
+/// Ephemeral symbols produced by Reader::symbols() and
+/// Reader::module_symbols().
+class Reader::SymbolRef : public Symbol {
+ const storage::Symbol *SymI, *SymE;
+ const storage::Uncommon *UncI;
+ const Reader *R;
+
+ void read() {
+ if (SymI == SymE)
+ return;
+
+ Name = R->str(SymI->Name);
+ IRName = R->str(SymI->IRName);
+ ComdatIndex = SymI->ComdatIndex;
+ Flags = SymI->Flags;
+
+ if (Flags & (1 << storage::Symbol::FB_has_uncommon)) {
+ CommonSize = UncI->CommonSize;
+ CommonAlign = UncI->CommonAlign;
+ COFFWeakExternFallbackName = R->str(UncI->COFFWeakExternFallbackName);
+ }
+ }
+
+public:
+ SymbolRef(const storage::Symbol *SymI, const storage::Symbol *SymE,
+ const storage::Uncommon *UncI, const Reader *R)
+ : SymI(SymI), SymE(SymE), UncI(UncI), R(R) {
+ read();
+ }
+
+ void moveNext() {
+ ++SymI;
+ if (Flags & (1 << storage::Symbol::FB_has_uncommon))
+ ++UncI;
+ read();
+ }
+
+ bool operator==(const SymbolRef &Other) const { return SymI == Other.SymI; }
+};
+
+inline Reader::symbol_range Reader::symbols() const {
+ return {SymbolRef(Symbols.begin(), Symbols.end(), Uncommons.begin(), this),
+ SymbolRef(Symbols.end(), Symbols.end(), nullptr, this)};
+}
+
+inline Reader::symbol_range Reader::module_symbols(unsigned I) const {
+ const storage::Module &M = Modules[I];
+ const storage::Symbol *MBegin = Symbols.begin() + M.Begin,
+ *MEnd = Symbols.begin() + M.End;
+ return {SymbolRef(MBegin, MEnd, Uncommons.begin() + M.UncBegin, this),
+ SymbolRef(MEnd, MEnd, nullptr, this)};
+}
+
+/// The contents of the irsymtab in a bitcode file. Any underlying data for the
+/// irsymtab are owned by Symtab and Strtab.
+struct FileContents {
+ SmallVector<char, 0> Symtab, Strtab;
+ Reader TheReader;
+};
+
+/// Reads the contents of a bitcode file, creating its irsymtab if necessary.
+Expected<FileContents> readBitcode(const BitcodeFileContents &BFC);
+
+} // end namespace irsymtab
+} // end namespace llvm
+
+#endif // LLVM_OBJECT_IRSYMTAB_H
diff --git a/contrib/llvm/include/llvm/Object/MachO.h b/contrib/llvm/include/llvm/Object/MachO.h
index 8c33ec8..2c3c89d 100644
--- a/contrib/llvm/include/llvm/Object/MachO.h
+++ b/contrib/llvm/include/llvm/Object/MachO.h
@@ -16,10 +16,25 @@
#define LLVM_OBJECT_MACHO_H
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Triple.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/BinaryFormat/MachO.h"
+#include "llvm/MC/SubtargetFeature.h"
+#include "llvm/Object/Binary.h"
#include "llvm/Object/ObjectFile.h"
-#include "llvm/Support/MachO.h"
+#include "llvm/Object/SymbolicFile.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cstdint>
+#include <memory>
+#include <string>
+#include <system_error>
namespace llvm {
namespace object {
@@ -28,11 +43,10 @@ namespace object {
/// data in code entry in the table in a Mach-O object file.
class DiceRef {
DataRefImpl DicePimpl;
- const ObjectFile *OwningObject;
+ const ObjectFile *OwningObject = nullptr;
public:
- DiceRef() : OwningObject(nullptr) { }
-
+ DiceRef() = default;
DiceRef(DataRefImpl DiceP, const ObjectFile *Owner);
bool operator==(const DiceRef &Other) const;
@@ -47,7 +61,7 @@ public:
DataRefImpl getRawDataRefImpl() const;
const ObjectFile *getObjectFile() const;
};
-typedef content_iterator<DiceRef> dice_iterator;
+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
@@ -71,6 +85,7 @@ public:
private:
friend class MachOObjectFile;
+
void moveToFirst();
void moveToEnd();
uint64_t readULEB128(const uint8_t *&p);
@@ -80,38 +95,80 @@ private:
// Represents a node in the mach-o exports trie.
struct NodeState {
NodeState(const uint8_t *Ptr);
+
const uint8_t *Start;
const uint8_t *Current;
- uint64_t Flags;
- uint64_t Address;
- uint64_t Other;
- const char *ImportName;
- unsigned ChildCount;
- unsigned NextChildIndex;
- unsigned ParentStringLength;
- bool IsExportNode;
+ uint64_t Flags = 0;
+ uint64_t Address = 0;
+ uint64_t Other = 0;
+ const char *ImportName = nullptr;
+ unsigned ChildCount = 0;
+ unsigned NextChildIndex = 0;
+ unsigned ParentStringLength = 0;
+ bool IsExportNode = false;
};
ArrayRef<uint8_t> Trie;
SmallString<256> CumulativeString;
SmallVector<NodeState, 16> Stack;
- bool Malformed;
- bool Done;
+ bool Malformed = false;
+ bool Done = false;
+};
+using export_iterator = content_iterator<ExportEntry>;
+
+// Segment info so SegIndex/SegOffset pairs in a Mach-O Bind or Rebase entry
+// can be checked and translated. Only the SegIndex/SegOffset pairs from
+// checked entries are to be used with the segmentName(), sectionName() and
+// address() methods below.
+class BindRebaseSegInfo {
+public:
+ BindRebaseSegInfo(const MachOObjectFile *Obj);
+
+ // Used to check a Mach-O Bind or Rebase entry for errors when iterating.
+ const char *checkSegAndOffset(int32_t SegIndex, uint64_t SegOffset,
+ bool endInvalid);
+ const char *checkCountAndSkip(uint32_t Count, uint32_t Skip,
+ uint8_t PointerSize, int32_t SegIndex,
+ uint64_t SegOffset);
+ // Used with valid SegIndex/SegOffset values from checked entries.
+ StringRef segmentName(int32_t SegIndex);
+ StringRef sectionName(int32_t SegIndex, uint64_t SegOffset);
+ uint64_t address(uint32_t SegIndex, uint64_t SegOffset);
+
+private:
+ struct SectionInfo {
+ uint64_t Address;
+ uint64_t Size;
+ StringRef SectionName;
+ StringRef SegmentName;
+ uint64_t OffsetInSegment;
+ uint64_t SegmentStartAddress;
+ int32_t SegmentIndex;
+ };
+ const SectionInfo &findSection(int32_t SegIndex, uint64_t SegOffset);
+
+ SmallVector<SectionInfo, 32> Sections;
+ int32_t MaxSegIndex;
};
-typedef content_iterator<ExportEntry> export_iterator;
/// MachORebaseEntry encapsulates the current state in the decompression of
/// rebasing opcodes. This allows you to iterate through the compressed table of
/// rebasing using:
-/// for (const llvm::object::MachORebaseEntry &Entry : Obj->rebaseTable()) {
+/// Error Err;
+/// for (const llvm::object::MachORebaseEntry &Entry : Obj->rebaseTable(&Err)) {
/// }
+/// if (Err) { report error ...
class MachORebaseEntry {
public:
- MachORebaseEntry(ArrayRef<uint8_t> opcodes, bool is64Bit);
+ MachORebaseEntry(Error *Err, const MachOObjectFile *O,
+ ArrayRef<uint8_t> opcodes, bool is64Bit);
- uint32_t segmentIndex() const;
+ int32_t segmentIndex() const;
uint64_t segmentOffset() const;
StringRef typeName() const;
+ StringRef segmentName() const;
+ StringRef sectionName() const;
+ uint64_t address() const;
bool operator==(const MachORebaseEntry &) const;
@@ -119,35 +176,40 @@ public:
private:
friend class MachOObjectFile;
+
void moveToFirst();
void moveToEnd();
- uint64_t readULEB128();
+ uint64_t readULEB128(const char **error);
+ Error *E;
+ const MachOObjectFile *O;
ArrayRef<uint8_t> Opcodes;
const uint8_t *Ptr;
- uint64_t SegmentOffset;
- uint32_t SegmentIndex;
- uint64_t RemainingLoopCount;
- uint64_t AdvanceAmount;
- uint8_t RebaseType;
+ uint64_t SegmentOffset = 0;
+ int32_t SegmentIndex = -1;
+ uint64_t RemainingLoopCount = 0;
+ uint64_t AdvanceAmount = 0;
+ uint8_t RebaseType = 0;
uint8_t PointerSize;
- bool Malformed;
- bool Done;
+ bool Done = false;
};
-typedef content_iterator<MachORebaseEntry> rebase_iterator;
+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:
-/// for (const llvm::object::MachOBindEntry &Entry : Obj->bindTable()) {
+/// Error Err;
+/// for (const llvm::object::MachOBindEntry &Entry : Obj->bindTable(&Err)) {
/// }
+/// if (Err) { report error ...
class MachOBindEntry {
public:
enum class Kind { Regular, Lazy, Weak };
- MachOBindEntry(ArrayRef<uint8_t> Opcodes, bool is64Bit, MachOBindEntry::Kind);
+ MachOBindEntry(Error *Err, const MachOObjectFile *O,
+ ArrayRef<uint8_t> Opcodes, bool is64Bit, MachOBindEntry::Kind);
- uint32_t segmentIndex() const;
+ int32_t segmentIndex() const;
uint64_t segmentOffset() const;
StringRef typeName() const;
StringRef symbolName() const;
@@ -155,34 +217,41 @@ public:
int64_t addend() const;
int ordinal() const;
+ StringRef segmentName() const;
+ StringRef sectionName() const;
+ uint64_t address() const;
+
bool operator==(const MachOBindEntry &) const;
void moveNext();
private:
friend class MachOObjectFile;
+
void moveToFirst();
void moveToEnd();
- uint64_t readULEB128();
- int64_t readSLEB128();
+ uint64_t readULEB128(const char **error);
+ int64_t readSLEB128(const char **error);
+ Error *E;
+ const MachOObjectFile *O;
ArrayRef<uint8_t> Opcodes;
const uint8_t *Ptr;
- uint64_t SegmentOffset;
- uint32_t SegmentIndex;
+ uint64_t SegmentOffset = 0;
+ int32_t SegmentIndex = -1;
StringRef SymbolName;
- int Ordinal;
- uint32_t Flags;
- int64_t Addend;
- uint64_t RemainingLoopCount;
- uint64_t AdvanceAmount;
- uint8_t BindType;
+ bool LibraryOrdinalSet = false;
+ int Ordinal = 0;
+ uint32_t Flags = 0;
+ int64_t Addend = 0;
+ uint64_t RemainingLoopCount = 0;
+ uint64_t AdvanceAmount = 0;
+ uint8_t BindType = 0;
uint8_t PointerSize;
Kind TableKind;
- bool Malformed;
- bool Done;
+ bool Done = false;
};
-typedef content_iterator<MachOBindEntry> bind_iterator;
+using bind_iterator = content_iterator<MachOBindEntry>;
class MachOObjectFile : public ObjectFile {
public:
@@ -190,8 +259,8 @@ public:
const char *Ptr; // Where in memory the load command is.
MachO::load_command C; // The command itself.
};
- typedef SmallVector<LoadCommandInfo, 4> LoadCommandList;
- typedef LoadCommandList::const_iterator load_command_iterator;
+ using LoadCommandList = SmallVector<LoadCommandInfo, 4>;
+ using load_command_iterator = LoadCommandList::const_iterator;
static Expected<std::unique_ptr<MachOObjectFile>>
create(MemoryBufferRef Object, bool IsLittleEndian, bool Is64Bits,
@@ -221,6 +290,7 @@ public:
std::error_code getSectionName(DataRefImpl Sec,
StringRef &Res) const override;
uint64_t getSectionAddress(DataRefImpl Sec) const override;
+ uint64_t getSectionIndex(DataRefImpl Sec) const override;
uint64_t getSectionSize(DataRefImpl Sec) const override;
std::error_code getSectionContents(DataRefImpl Sec,
StringRef &Res) const override;
@@ -234,6 +304,12 @@ public:
relocation_iterator section_rel_begin(DataRefImpl Sec) const override;
relocation_iterator section_rel_end(DataRefImpl Sec) const override;
+ relocation_iterator extrel_begin() const;
+ relocation_iterator extrel_end() const;
+ iterator_range<relocation_iterator> external_relocations() const {
+ return make_range(extrel_begin(), extrel_end());
+ }
+
void moveRelocationNext(DataRefImpl &Rel) const override;
uint64_t getRelocationOffset(DataRefImpl Rel) const override;
symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override;
@@ -245,6 +321,7 @@ public:
// MachO specific.
std::error_code getLibraryShortNameByIndex(unsigned Index, StringRef &) const;
+ uint32_t getLibraryCount() const;
section_iterator getRelocationRelocatedSection(relocation_iterator Rel) const;
@@ -285,26 +362,79 @@ public:
static iterator_range<export_iterator> exports(ArrayRef<uint8_t> Trie);
/// For use iterating over all rebase table entries.
- iterator_range<rebase_iterator> rebaseTable() const;
+ iterator_range<rebase_iterator> rebaseTable(Error &Err);
- /// For use examining rebase opcodes not in a MachOObjectFile.
- static iterator_range<rebase_iterator> rebaseTable(ArrayRef<uint8_t> Opcodes,
+ /// For use examining rebase opcodes in a MachOObjectFile.
+ static iterator_range<rebase_iterator> rebaseTable(Error &Err,
+ MachOObjectFile *O,
+ ArrayRef<uint8_t> Opcodes,
bool is64);
/// For use iterating over all bind table entries.
- iterator_range<bind_iterator> bindTable() const;
+ iterator_range<bind_iterator> bindTable(Error &Err);
/// For use iterating over all lazy bind table entries.
- iterator_range<bind_iterator> lazyBindTable() const;
+ iterator_range<bind_iterator> lazyBindTable(Error &Err);
- /// For use iterating over all lazy bind table entries.
- iterator_range<bind_iterator> weakBindTable() const;
+ /// For use iterating over all weak bind table entries.
+ iterator_range<bind_iterator> weakBindTable(Error &Err);
- /// For use examining bind opcodes not in a MachOObjectFile.
- static iterator_range<bind_iterator> bindTable(ArrayRef<uint8_t> Opcodes,
+ /// For use examining bind opcodes in a MachOObjectFile.
+ static iterator_range<bind_iterator> bindTable(Error &Err,
+ MachOObjectFile *O,
+ ArrayRef<uint8_t> Opcodes,
bool is64,
MachOBindEntry::Kind);
+ /// For use with a SegIndex,SegOffset pair in MachOBindEntry::moveNext() to
+ /// validate a MachOBindEntry.
+ const char *BindEntryCheckSegAndOffset(int32_t SegIndex, uint64_t SegOffset,
+ bool endInvalid) const {
+ return BindRebaseSectionTable->checkSegAndOffset(SegIndex, SegOffset,
+ endInvalid);
+ }
+ /// For use in MachOBindEntry::moveNext() to validate a MachOBindEntry for
+ /// the BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB opcode.
+ const char *BindEntryCheckCountAndSkip(uint32_t Count, uint32_t Skip,
+ uint8_t PointerSize, int32_t SegIndex,
+ uint64_t SegOffset) const {
+ return BindRebaseSectionTable->checkCountAndSkip(Count, Skip, PointerSize,
+ SegIndex, SegOffset);
+ }
+
+ /// For use with a SegIndex,SegOffset pair in MachORebaseEntry::moveNext() to
+ /// validate a MachORebaseEntry.
+ const char *RebaseEntryCheckSegAndOffset(int32_t SegIndex, uint64_t SegOffset,
+ bool endInvalid) const {
+ return BindRebaseSectionTable->checkSegAndOffset(SegIndex, SegOffset,
+ endInvalid);
+ }
+ /// For use in MachORebaseEntry::moveNext() to validate a MachORebaseEntry for
+ /// the REBASE_OPCODE_DO_*_TIMES* opcodes.
+ const char *RebaseEntryCheckCountAndSkip(uint32_t Count, uint32_t Skip,
+ uint8_t PointerSize, int32_t SegIndex,
+ uint64_t SegOffset) const {
+ return BindRebaseSectionTable->checkCountAndSkip(Count, Skip, PointerSize,
+ SegIndex, SegOffset);
+ }
+
+ /// For use with the SegIndex of a checked Mach-O Bind or Rebase entry to
+ /// get the segment name.
+ StringRef BindRebaseSegmentName(int32_t SegIndex) const {
+ return BindRebaseSectionTable->segmentName(SegIndex);
+ }
+
+ /// For use with a SegIndex,SegOffset pair from a checked Mach-O Bind or
+ /// Rebase entry to get the section name.
+ StringRef BindRebaseSectionName(uint32_t SegIndex, uint64_t SegOffset) const {
+ return BindRebaseSectionTable->sectionName(SegIndex, SegOffset);
+ }
+
+ /// For use with a SegIndex,SegOffset pair from a checked Mach-O Bind or
+ /// Rebase entry to get the address.
+ uint64_t BindRebaseAddress(uint32_t SegIndex, uint64_t SegOffset) const {
+ return BindRebaseSectionTable->address(SegIndex, SegOffset);
+ }
// In a MachO file, sections have a segment name. This is used in the .o
// files. They have a single segment, but this field specifies which segment
@@ -351,6 +481,12 @@ public:
getLinkerOptionLoadCommand(const LoadCommandInfo &L) const;
MachO::version_min_command
getVersionMinLoadCommand(const LoadCommandInfo &L) const;
+ MachO::note_command
+ getNoteLoadCommand(const LoadCommandInfo &L) const;
+ MachO::build_version_command
+ getBuildVersionLoadCommand(const LoadCommandInfo &L) const;
+ MachO::build_tool_version
+ getBuildToolVersion(unsigned index) const;
MachO::dylib_command
getDylibIDLoadCommand(const LoadCommandInfo &L) const;
MachO::dyld_info_command
@@ -420,6 +556,8 @@ public:
bool isRelocatableObject() const override;
+ StringRef mapDebugSectionName(StringRef Name) const override;
+
bool hasPageZeroSegment() const { return HasPageZeroSegment; }
static bool classof(const Binary *v) {
@@ -444,8 +582,47 @@ public:
return VersionOrSDK & 0xff;
}
-private:
+ static std::string getBuildPlatform(uint32_t platform) {
+ switch (platform) {
+ case MachO::PLATFORM_MACOS: return "macos";
+ case MachO::PLATFORM_IOS: return "ios";
+ case MachO::PLATFORM_TVOS: return "tvos";
+ case MachO::PLATFORM_WATCHOS: return "watchos";
+ case MachO::PLATFORM_BRIDGEOS: return "bridgeos";
+ default:
+ std::string ret;
+ raw_string_ostream ss(ret);
+ ss << format_hex(platform, 8, true);
+ return ss.str();
+ }
+ }
+
+ static std::string getBuildTool(uint32_t tools) {
+ switch (tools) {
+ case MachO::TOOL_CLANG: return "clang";
+ case MachO::TOOL_SWIFT: return "swift";
+ case MachO::TOOL_LD: return "ld";
+ default:
+ std::string ret;
+ raw_string_ostream ss(ret);
+ ss << format_hex(tools, 8, true);
+ return ss.str();
+ }
+ }
+
+ static std::string getVersionString(uint32_t version) {
+ uint32_t major = (version >> 16) & 0xffff;
+ uint32_t minor = (version >> 8) & 0xff;
+ uint32_t update = version & 0xff;
+ SmallString<32> Version;
+ Version = utostr(major) + "." + utostr(minor);
+ if (update != 0)
+ Version += "." + utostr(update);
+ return Version.str();
+ }
+
+private:
MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian, bool Is64Bits,
Error &Err, uint32_t UniversalCputype = 0,
uint32_t UniversalIndex = 0);
@@ -456,20 +633,23 @@ private:
MachO::mach_header_64 Header64;
MachO::mach_header Header;
};
- typedef SmallVector<const char*, 1> SectionList;
+ using SectionList = SmallVector<const char*, 1>;
SectionList Sections;
- typedef SmallVector<const char*, 1> LibraryList;
+ using LibraryList = SmallVector<const char*, 1>;
LibraryList Libraries;
LoadCommandList LoadCommands;
- typedef SmallVector<StringRef, 1> LibraryShortName;
+ using LibraryShortName = SmallVector<StringRef, 1>;
+ using BuildToolList = SmallVector<const char*, 1>;
+ BuildToolList BuildTools;
mutable LibraryShortName LibrariesShortNames;
- const char *SymtabLoadCmd;
- const char *DysymtabLoadCmd;
- const char *DataInCodeLoadCmd;
- const char *LinkOptHintsLoadCmd;
- const char *DyldInfoLoadCmd;
- const char *UuidLoadCmd;
- bool HasPageZeroSegment;
+ std::unique_ptr<BindRebaseSegInfo> BindRebaseSectionTable;
+ const char *SymtabLoadCmd = nullptr;
+ const char *DysymtabLoadCmd = nullptr;
+ const char *DataInCodeLoadCmd = nullptr;
+ const char *LinkOptHintsLoadCmd = nullptr;
+ const char *DyldInfoLoadCmd = nullptr;
+ const char *UuidLoadCmd = nullptr;
+ bool HasPageZeroSegment = false;
};
/// DiceRef
@@ -526,7 +706,7 @@ inline const ObjectFile *DiceRef::getObjectFile() const {
return OwningObject;
}
-}
-}
+} // end namespace object
+} // end namespace llvm
-#endif
+#endif // LLVM_OBJECT_MACHO_H
diff --git a/contrib/llvm/include/llvm/Object/MachOUniversal.h b/contrib/llvm/include/llvm/Object/MachOUniversal.h
index a14c4ca..72837d0 100644
--- a/contrib/llvm/include/llvm/Object/MachOUniversal.h
+++ b/contrib/llvm/include/llvm/Object/MachOUniversal.h
@@ -16,10 +16,10 @@
#include "llvm/ADT/Triple.h"
#include "llvm/ADT/iterator_range.h"
+#include "llvm/BinaryFormat/MachO.h"
#include "llvm/Object/Archive.h"
#include "llvm/Object/Binary.h"
#include "llvm/Object/MachO.h"
-#include "llvm/Support/MachO.h"
namespace llvm {
class StringRef;
@@ -154,7 +154,7 @@ public:
uint32_t getNumberOfObjects() const { return NumberOfObjects; }
// Cast methods.
- static inline bool classof(Binary const *V) {
+ static bool classof(Binary const *V) {
return V->isMachOUniversalBinary();
}
diff --git a/contrib/llvm/include/llvm/Object/ModuleSummaryIndexObjectFile.h b/contrib/llvm/include/llvm/Object/ModuleSummaryIndexObjectFile.h
deleted file mode 100644
index 6205927..0000000
--- a/contrib/llvm/include/llvm/Object/ModuleSummaryIndexObjectFile.h
+++ /dev/null
@@ -1,96 +0,0 @@
-//===- ModuleSummaryIndexObjectFile.h - Summary index file implementation -=//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file declares the ModuleSummaryIndexObjectFile template class.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_OBJECT_MODULESUMMARYINDEXOBJECTFILE_H
-#define LLVM_OBJECT_MODULESUMMARYINDEXOBJECTFILE_H
-
-#include "llvm/IR/DiagnosticInfo.h"
-#include "llvm/Object/SymbolicFile.h"
-
-namespace llvm {
-class ModuleSummaryIndex;
-class Module;
-
-namespace object {
-class ObjectFile;
-
-/// This class is used to read just the module summary index related
-/// sections out of the given object (which may contain a single module's
-/// bitcode or be a combined index bitcode file). It builds a ModuleSummaryIndex
-/// object.
-class ModuleSummaryIndexObjectFile : public SymbolicFile {
- std::unique_ptr<ModuleSummaryIndex> Index;
-
-public:
- ModuleSummaryIndexObjectFile(MemoryBufferRef Object,
- std::unique_ptr<ModuleSummaryIndex> I);
- ~ModuleSummaryIndexObjectFile() override;
-
- // TODO: Walk through GlobalValueMap entries for symbols.
- // However, currently these interfaces are not used by any consumers.
- void moveSymbolNext(DataRefImpl &Symb) const override {
- llvm_unreachable("not implemented");
- }
- std::error_code printSymbolName(raw_ostream &OS,
- DataRefImpl Symb) const override {
- llvm_unreachable("not implemented");
- return std::error_code();
- }
- uint32_t getSymbolFlags(DataRefImpl Symb) const override {
- llvm_unreachable("not implemented");
- return 0;
- }
- basic_symbol_iterator symbol_begin() const override {
- llvm_unreachable("not implemented");
- return basic_symbol_iterator(BasicSymbolRef());
- }
- basic_symbol_iterator symbol_end() const override {
- llvm_unreachable("not implemented");
- return basic_symbol_iterator(BasicSymbolRef());
- }
-
- const ModuleSummaryIndex &getIndex() const {
- return const_cast<ModuleSummaryIndexObjectFile *>(this)->getIndex();
- }
- ModuleSummaryIndex &getIndex() { return *Index; }
- std::unique_ptr<ModuleSummaryIndex> takeIndex();
-
- static inline bool classof(const Binary *v) {
- return v->isModuleSummaryIndex();
- }
-
- /// \brief Finds and returns bitcode embedded in the given object file, or an
- /// error code if not found.
- static ErrorOr<MemoryBufferRef> findBitcodeInObject(const ObjectFile &Obj);
-
- /// \brief Finds and returns bitcode in the given memory buffer (which may
- /// be either a bitcode file or a native object file with embedded bitcode),
- /// or an error code if not found.
- static ErrorOr<MemoryBufferRef>
- findBitcodeInMemBuffer(MemoryBufferRef Object);
-
- /// \brief Parse module summary index in the given memory buffer.
- /// Return new ModuleSummaryIndexObjectFile instance containing parsed module
- /// summary/index.
- static Expected<std::unique_ptr<ModuleSummaryIndexObjectFile>>
- create(MemoryBufferRef Object);
-};
-}
-
-/// Parse the module summary index out of an IR file and return the module
-/// summary index object if found, or nullptr if not.
-Expected<std::unique_ptr<ModuleSummaryIndex>>
-getModuleSummaryIndexForFile(StringRef Path);
-}
-
-#endif
diff --git a/contrib/llvm/include/llvm/Object/ModuleSymbolTable.h b/contrib/llvm/include/llvm/Object/ModuleSymbolTable.h
index 7077535..9e93228 100644
--- a/contrib/llvm/include/llvm/Object/ModuleSymbolTable.h
+++ b/contrib/llvm/include/llvm/Object/ModuleSymbolTable.h
@@ -1,4 +1,4 @@
-//===- ModuleSymbolTable.h - symbol table for in-memory IR ----------------===//
+//===- ModuleSymbolTable.h - symbol table for in-memory IR ------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -16,12 +16,15 @@
#ifndef LLVM_OBJECT_MODULESYMBOLTABLE_H
#define LLVM_OBJECT_MODULESYMBOLTABLE_H
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/PointerUnion.h"
-#include "llvm/ADT/Triple.h"
#include "llvm/IR/Mangler.h"
#include "llvm/Object/SymbolicFile.h"
+#include "llvm/Support/Allocator.h"
+#include <cstdint>
#include <string>
#include <utility>
+#include <vector>
namespace llvm {
@@ -29,8 +32,8 @@ class GlobalValue;
class ModuleSymbolTable {
public:
- typedef std::pair<std::string, uint32_t> AsmSymbol;
- typedef PointerUnion<GlobalValue *, AsmSymbol *> Symbol;
+ using AsmSymbol = std::pair<std::string, uint32_t>;
+ using Symbol = PointerUnion<GlobalValue *, AsmSymbol *>;
private:
Module *FirstMod = nullptr;
@@ -52,10 +55,10 @@ public:
/// For each found symbol, call \p AsmSymbol with the name of the symbol found
/// and the associated flags.
static void CollectAsmSymbols(
- const Triple &TheTriple, StringRef InlineAsm,
+ const Module &M,
function_ref<void(StringRef, object::BasicSymbolRef::Flags)> AsmSymbol);
};
-}
+} // end namespace llvm
-#endif
+#endif // LLVM_OBJECT_MODULESYMBOLTABLE_H
diff --git a/contrib/llvm/include/llvm/Object/ObjectFile.h b/contrib/llvm/include/llvm/Object/ObjectFile.h
index 13d5845..afcad30 100644
--- a/contrib/llvm/include/llvm/Object/ObjectFile.h
+++ b/contrib/llvm/include/llvm/Object/ObjectFile.h
@@ -15,36 +15,46 @@
#define LLVM_OBJECT_OBJECTFILE_H
#include "llvm/ADT/StringRef.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/DataTypes.h"
-#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/ErrorOr.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/MemoryBuffer.h"
-#include <cstring>
+#include <cassert>
+#include <cstdint>
+#include <memory>
+#include <system_error>
namespace llvm {
+
+class ARMAttributeParser;
+
namespace object {
-class ObjectFile;
class COFFObjectFile;
class MachOObjectFile;
-class WasmObjectFile;
-
+class ObjectFile;
+class SectionRef;
class SymbolRef;
class symbol_iterator;
-class SectionRef;
-typedef content_iterator<SectionRef> section_iterator;
+class WasmObjectFile;
+
+using section_iterator = content_iterator<SectionRef>;
/// This is a value type class that represents a single relocation in the list
/// of relocations in the object file.
class RelocationRef {
DataRefImpl RelocationPimpl;
- const ObjectFile *OwningObject;
+ const ObjectFile *OwningObject = nullptr;
public:
- RelocationRef() : OwningObject(nullptr) { }
-
+ RelocationRef() = default;
RelocationRef(DataRefImpl RelocationP, const ObjectFile *Owner);
bool operator==(const RelocationRef &Other) const;
@@ -63,18 +73,19 @@ public:
DataRefImpl getRawDataRefImpl() const;
const ObjectFile *getObject() const;
};
-typedef content_iterator<RelocationRef> relocation_iterator;
+
+using relocation_iterator = content_iterator<RelocationRef>;
/// This is a value type class that represents a single section in the list of
/// sections in the object file.
class SectionRef {
friend class SymbolRef;
+
DataRefImpl SectionPimpl;
- const ObjectFile *OwningObject;
+ const ObjectFile *OwningObject = nullptr;
public:
- SectionRef() : OwningObject(nullptr) { }
-
+ SectionRef() = default;
SectionRef(DataRefImpl SectionP, const ObjectFile *Owner);
bool operator==(const SectionRef &Other) const;
@@ -85,6 +96,7 @@ public:
std::error_code getName(StringRef &Result) const;
uint64_t getAddress() const;
+ uint64_t getIndex() const;
uint64_t getSize() const;
std::error_code getContents(StringRef &Result) const;
@@ -117,8 +129,6 @@ class SymbolRef : public BasicSymbolRef {
friend class SectionRef;
public:
- SymbolRef() : BasicSymbolRef() {}
-
enum Type {
ST_Unknown, // Type not specified
ST_Data,
@@ -128,6 +138,7 @@ public:
ST_Other
};
+ SymbolRef() = default;
SymbolRef(DataRefImpl SymbolP, const ObjectFile *Owner);
SymbolRef(const BasicSymbolRef &B) : BasicSymbolRef(B) {
assert(isa<ObjectFile>(BasicSymbolRef::getObject()));
@@ -177,8 +188,6 @@ public:
/// to create.
class ObjectFile : public SymbolicFile {
virtual void anchor();
- ObjectFile() = delete;
- ObjectFile(const ObjectFile &other) = delete;
protected:
ObjectFile(unsigned int Type, MemoryBufferRef Source);
@@ -196,6 +205,7 @@ protected:
// Implementations assume that the DataRefImpl is valid and has not been
// modified externally. It's UB otherwise.
friend class SymbolRef;
+
virtual Expected<StringRef> getSymbolName(DataRefImpl Symb) const = 0;
std::error_code printSymbolName(raw_ostream &OS,
DataRefImpl Symb) const override;
@@ -209,10 +219,12 @@ protected:
// Same as above for SectionRef.
friend class SectionRef;
+
virtual void moveSectionNext(DataRefImpl &Sec) const = 0;
virtual std::error_code getSectionName(DataRefImpl Sec,
StringRef &Res) const = 0;
virtual uint64_t getSectionAddress(DataRefImpl Sec) const = 0;
+ virtual uint64_t getSectionIndex(DataRefImpl Sec) const = 0;
virtual uint64_t getSectionSize(DataRefImpl Sec) const = 0;
virtual std::error_code getSectionContents(DataRefImpl Sec,
StringRef &Res) const = 0;
@@ -240,12 +252,15 @@ protected:
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);
return getCommonSymbolSizeImpl(Symb);
}
- typedef iterator_range<symbol_iterator> symbol_iterator_range;
+ using symbol_iterator_range = iterator_range<symbol_iterator>;
symbol_iterator_range symbols() const {
return symbol_iterator_range(symbol_begin(), symbol_end());
}
@@ -253,7 +268,7 @@ public:
virtual section_iterator section_begin() const = 0;
virtual section_iterator section_end() const = 0;
- typedef iterator_range<section_iterator> section_iterator_range;
+ using section_iterator_range = iterator_range<section_iterator>;
section_iterator_range sections() const {
return section_iterator_range(section_begin(), section_end());
}
@@ -265,6 +280,7 @@ public:
virtual StringRef getFileFormatName() const = 0;
virtual /* Triple::ArchType */ unsigned getArch() const = 0;
virtual SubtargetFeatures getFeatures() const = 0;
+ virtual void setARMSubArch(Triple &TheTriple) const { }
/// Returns platform-specific object flags, if any.
virtual std::error_code getPlatformFlags(unsigned &Result) const {
@@ -272,6 +288,14 @@ public:
return object_error::invalid_file_type;
}
+ virtual std::error_code
+ getBuildAttributes(ARMAttributeParser &Attributes) const {
+ return std::error_code();
+ }
+
+ /// Maps a debug section name to a standard DWARF section name.
+ virtual StringRef mapDebugSectionName(StringRef Name) const { return Name; }
+
/// True if this is a relocatable object (.o/.obj).
virtual bool isRelocatableObject() const = 0;
@@ -283,14 +307,13 @@ public:
createObjectFile(StringRef ObjectPath);
static Expected<std::unique_ptr<ObjectFile>>
- createObjectFile(MemoryBufferRef Object, sys::fs::file_magic Type);
+ createObjectFile(MemoryBufferRef Object, llvm::file_magic Type);
static Expected<std::unique_ptr<ObjectFile>>
createObjectFile(MemoryBufferRef Object) {
- return createObjectFile(Object, sys::fs::file_magic::unknown);
+ return createObjectFile(Object, llvm::file_magic::unknown);
}
-
- static inline bool classof(const Binary *v) {
+ static bool classof(const Binary *v) {
return v->isObject();
}
@@ -346,7 +369,6 @@ inline const ObjectFile *SymbolRef::getObject() const {
return cast<ObjectFile>(O);
}
-
/// SectionRef
inline SectionRef::SectionRef(DataRefImpl SectionP,
const ObjectFile *Owner)
@@ -377,6 +399,10 @@ inline uint64_t SectionRef::getAddress() const {
return OwningObject->getSectionAddress(SectionPimpl);
}
+inline uint64_t SectionRef::getIndex() const {
+ return OwningObject->getSectionIndex(SectionPimpl);
+}
+
inline uint64_t SectionRef::getSize() const {
return OwningObject->getSectionSize(SectionPimpl);
}
@@ -471,8 +497,8 @@ inline const ObjectFile *RelocationRef::getObject() const {
return OwningObject;
}
-
} // end namespace object
+
} // end namespace llvm
-#endif
+#endif // LLVM_OBJECT_OBJECTFILE_H
diff --git a/contrib/llvm/include/llvm/Object/RelocVisitor.h b/contrib/llvm/include/llvm/Object/RelocVisitor.h
index 3510d29..c358d39 100644
--- a/contrib/llvm/include/llvm/Object/RelocVisitor.h
+++ b/contrib/llvm/include/llvm/Object/RelocVisitor.h
@@ -1,4 +1,4 @@
-//===-- RelocVisitor.h - Visitor for object file relocations -*- C++ -*-===//
+//===- RelocVisitor.h - Visitor for object file relocations -----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -16,262 +16,102 @@
#ifndef LLVM_OBJECT_RELOCVISITOR_H
#define LLVM_OBJECT_RELOCVISITOR_H
+#include "llvm/ADT/Triple.h"
+#include "llvm/BinaryFormat/ELF.h"
+#include "llvm/BinaryFormat/MachO.h"
#include "llvm/Object/COFF.h"
#include "llvm/Object/ELFObjectFile.h"
#include "llvm/Object/MachO.h"
#include "llvm/Object/ObjectFile.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/ELF.h"
-#include "llvm/Support/MachO.h"
-#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/ErrorOr.h"
+#include <cstdint>
+#include <system_error>
namespace llvm {
namespace object {
-struct RelocToApply {
- // The computed value after applying the relevant relocations.
- int64_t Value;
-
- // The width of the value; how many bytes to touch when applying the
- // relocation.
- char Width;
- RelocToApply(int64_t Value, char Width) : Value(Value), Width(Width) {}
- RelocToApply() : Value(0), Width(0) {}
-};
-
/// @brief Base class for object file relocation visitors.
class RelocVisitor {
public:
- explicit RelocVisitor(const ObjectFile &Obj)
- : ObjToVisit(Obj), HasError(false) {}
+ explicit RelocVisitor(const ObjectFile &Obj) : ObjToVisit(Obj) {}
// TODO: Should handle multiple applied relocations via either passing in the
// previously computed value or just count paired relocations as a single
// visit.
- RelocToApply visit(uint32_t RelocType, RelocationRef R, uint64_t Value = 0) {
+ uint64_t visit(uint32_t Rel, RelocationRef R, uint64_t Value = 0) {
if (isa<ELFObjectFileBase>(ObjToVisit))
- return visitELF(RelocType, R, Value);
+ return visitELF(Rel, R, Value);
if (isa<COFFObjectFile>(ObjToVisit))
- return visitCOFF(RelocType, R, Value);
+ return visitCOFF(Rel, R, Value);
if (isa<MachOObjectFile>(ObjToVisit))
- return visitMachO(RelocType, R, Value);
+ return visitMachO(Rel, R, Value);
HasError = true;
- return RelocToApply();
+ return 0;
}
bool error() { return HasError; }
private:
const ObjectFile &ObjToVisit;
- bool HasError;
+ bool HasError = false;
- RelocToApply visitELF(uint32_t RelocType, RelocationRef R, uint64_t Value) {
+ uint64_t visitELF(uint32_t Rel, RelocationRef R, uint64_t Value) {
if (ObjToVisit.getBytesInAddress() == 8) { // 64-bit object file
switch (ObjToVisit.getArch()) {
case Triple::x86_64:
- switch (RelocType) {
- case llvm::ELF::R_X86_64_NONE:
- return visitELF_X86_64_NONE(R);
- case llvm::ELF::R_X86_64_64:
- return visitELF_X86_64_64(R, Value);
- case llvm::ELF::R_X86_64_PC32:
- return visitELF_X86_64_PC32(R, Value);
- case llvm::ELF::R_X86_64_32:
- return visitELF_X86_64_32(R, Value);
- case llvm::ELF::R_X86_64_32S:
- return visitELF_X86_64_32S(R, Value);
- default:
- HasError = true;
- return RelocToApply();
- }
+ return visitX86_64(Rel, R, Value);
case Triple::aarch64:
case Triple::aarch64_be:
- switch (RelocType) {
- case llvm::ELF::R_AARCH64_ABS32:
- return visitELF_AARCH64_ABS32(R, Value);
- case llvm::ELF::R_AARCH64_ABS64:
- return visitELF_AARCH64_ABS64(R, Value);
- default:
- HasError = true;
- return RelocToApply();
- }
+ return visitAarch64(Rel, R, Value);
case Triple::bpfel:
case Triple::bpfeb:
- switch (RelocType) {
- case llvm::ELF::R_BPF_64_64:
- return visitELF_BPF_64_64(R, Value);
- case llvm::ELF::R_BPF_64_32:
- return visitELF_BPF_64_32(R, Value);
- default:
- HasError = true;
- return RelocToApply();
- }
+ return visitBpf(Rel, R, Value);
case Triple::mips64el:
case Triple::mips64:
- switch (RelocType) {
- case llvm::ELF::R_MIPS_32:
- return visitELF_MIPS64_32(R, Value);
- case llvm::ELF::R_MIPS_64:
- return visitELF_MIPS64_64(R, Value);
- default:
- HasError = true;
- return RelocToApply();
- }
+ return visitMips64(Rel, R, Value);
case Triple::ppc64le:
case Triple::ppc64:
- switch (RelocType) {
- case llvm::ELF::R_PPC64_ADDR32:
- return visitELF_PPC64_ADDR32(R, Value);
- case llvm::ELF::R_PPC64_ADDR64:
- return visitELF_PPC64_ADDR64(R, Value);
- default:
- HasError = true;
- return RelocToApply();
- }
+ return visitPPC64(Rel, R, Value);
case Triple::systemz:
- switch (RelocType) {
- case llvm::ELF::R_390_32:
- return visitELF_390_32(R, Value);
- case llvm::ELF::R_390_64:
- return visitELF_390_64(R, Value);
- default:
- HasError = true;
- return RelocToApply();
- }
+ return visitSystemz(Rel, R, Value);
case Triple::sparcv9:
- switch (RelocType) {
- case llvm::ELF::R_SPARC_32:
- case llvm::ELF::R_SPARC_UA32:
- return visitELF_SPARCV9_32(R, Value);
- case llvm::ELF::R_SPARC_64:
- case llvm::ELF::R_SPARC_UA64:
- return visitELF_SPARCV9_64(R, Value);
- default:
- HasError = true;
- return RelocToApply();
- }
+ return visitSparc64(Rel, R, Value);
case Triple::amdgcn:
- switch (RelocType) {
- case llvm::ELF::R_AMDGPU_ABS32:
- return visitELF_AMDGPU_ABS32(R, Value);
- default:
- HasError = true;
- return RelocToApply();
- }
- default:
- HasError = true;
- return RelocToApply();
- }
- } else if (ObjToVisit.getBytesInAddress() == 4) { // 32-bit object file
- switch (ObjToVisit.getArch()) {
- case Triple::x86:
- switch (RelocType) {
- case llvm::ELF::R_386_NONE:
- return visitELF_386_NONE(R);
- case llvm::ELF::R_386_32:
- return visitELF_386_32(R, Value);
- case llvm::ELF::R_386_PC32:
- return visitELF_386_PC32(R, Value);
- default:
- HasError = true;
- return RelocToApply();
- }
- case Triple::ppc:
- switch (RelocType) {
- case llvm::ELF::R_PPC_ADDR32:
- return visitELF_PPC_ADDR32(R, Value);
- default:
- HasError = true;
- return RelocToApply();
- }
- case Triple::arm:
- case Triple::armeb:
- switch (RelocType) {
- default:
- HasError = true;
- return RelocToApply();
- case llvm::ELF::R_ARM_ABS32:
- return visitELF_ARM_ABS32(R, Value);
- }
- case Triple::lanai:
- switch (RelocType) {
- case llvm::ELF::R_LANAI_32:
- return visitELF_Lanai_32(R, Value);
- default:
- HasError = true;
- return RelocToApply();
- }
- case Triple::mipsel:
- case Triple::mips:
- switch (RelocType) {
- case llvm::ELF::R_MIPS_32:
- return visitELF_MIPS_32(R, Value);
- default:
- HasError = true;
- return RelocToApply();
- }
- case Triple::sparc:
- switch (RelocType) {
- case llvm::ELF::R_SPARC_32:
- case llvm::ELF::R_SPARC_UA32:
- return visitELF_SPARC_32(R, Value);
- default:
- HasError = true;
- return RelocToApply();
- }
- case Triple::hexagon:
- switch (RelocType) {
- case llvm::ELF::R_HEX_32:
- return visitELF_HEX_32(R, Value);
- default:
- HasError = true;
- return RelocToApply();
- }
+ return visitAmdgpu(Rel, R, Value);
default:
HasError = true;
- return RelocToApply();
+ return 0;
}
- } else {
- report_fatal_error("Invalid word size in object file");
}
- }
- RelocToApply visitCOFF(uint32_t RelocType, RelocationRef R, uint64_t Value) {
- switch (ObjToVisit.getArch()) {
- case Triple::x86:
- switch (RelocType) {
- case COFF::IMAGE_REL_I386_SECREL:
- return visitCOFF_I386_SECREL(R, Value);
- case COFF::IMAGE_REL_I386_DIR32:
- return visitCOFF_I386_DIR32(R, Value);
- }
- break;
- case Triple::x86_64:
- switch (RelocType) {
- case COFF::IMAGE_REL_AMD64_SECREL:
- return visitCOFF_AMD64_SECREL(R, Value);
- case COFF::IMAGE_REL_AMD64_ADDR64:
- return visitCOFF_AMD64_ADDR64(R, Value);
- }
- break;
- }
- HasError = true;
- return RelocToApply();
- }
+ // 32-bit object file
+ assert(ObjToVisit.getBytesInAddress() == 4 &&
+ "Invalid word size in object file");
- RelocToApply visitMachO(uint32_t RelocType, RelocationRef R, uint64_t Value) {
switch (ObjToVisit.getArch()) {
- default: break;
- case Triple::x86_64:
- switch (RelocType) {
- default: break;
- case MachO::X86_64_RELOC_UNSIGNED:
- return visitMACHO_X86_64_UNSIGNED(R, Value);
- }
+ case Triple::x86:
+ return visitX86(Rel, R, Value);
+ case Triple::ppc:
+ return visitPPC32(Rel, R, Value);
+ case Triple::arm:
+ case Triple::armeb:
+ return visitARM(Rel, R, Value);
+ case Triple::lanai:
+ return visitLanai(Rel, R, Value);
+ case Triple::mipsel:
+ case Triple::mips:
+ return visitMips32(Rel, R, Value);
+ case Triple::sparc:
+ return visitSparc32(Rel, R, Value);
+ case Triple::hexagon:
+ return visitHexagon(Rel, R, Value);
+ default:
+ HasError = true;
+ return 0;
}
- HasError = true;
- return RelocToApply();
}
int64_t getELFAddend(RelocationRef R) {
@@ -281,201 +121,197 @@ private:
return *AddendOrErr;
}
- uint8_t getLengthMachO64(RelocationRef R) {
- const MachOObjectFile *Obj = cast<MachOObjectFile>(R.getObject());
- return Obj->getRelocationLength(R.getRawDataRefImpl());
- }
-
- /// Operations
-
- /// 386-ELF
- RelocToApply visitELF_386_NONE(RelocationRef R) {
- return RelocToApply(0, 0);
- }
-
- // Ideally the Addend here will be the addend in the data for
- // the relocation. It's not actually the case for Rel relocations.
- RelocToApply visitELF_386_32(RelocationRef R, uint64_t Value) {
- return RelocToApply(Value, 4);
- }
-
- RelocToApply visitELF_386_PC32(RelocationRef R, uint64_t Value) {
- uint64_t Address = R.getOffset();
- return RelocToApply(Value - Address, 4);
- }
-
- /// X86-64 ELF
- RelocToApply visitELF_X86_64_NONE(RelocationRef R) {
- return RelocToApply(0, 0);
- }
- RelocToApply visitELF_X86_64_64(RelocationRef R, uint64_t Value) {
- int64_t Addend = getELFAddend(R);
- return RelocToApply(Value + Addend, 8);
- }
- RelocToApply visitELF_X86_64_PC32(RelocationRef R, uint64_t Value) {
- int64_t Addend = getELFAddend(R);
- uint64_t Address = R.getOffset();
- return RelocToApply(Value + Addend - Address, 4);
- }
- RelocToApply visitELF_X86_64_32(RelocationRef R, uint64_t Value) {
- int64_t Addend = getELFAddend(R);
- uint32_t Res = (Value + Addend) & 0xFFFFFFFF;
- return RelocToApply(Res, 4);
- }
- RelocToApply visitELF_X86_64_32S(RelocationRef R, uint64_t Value) {
- int64_t Addend = getELFAddend(R);
- int32_t Res = (Value + Addend) & 0xFFFFFFFF;
- return RelocToApply(Res, 4);
- }
-
- /// BPF ELF
- RelocToApply visitELF_BPF_64_32(RelocationRef R, uint64_t Value) {
- uint32_t Res = Value & 0xFFFFFFFF;
- return RelocToApply(Res, 4);
- }
- RelocToApply visitELF_BPF_64_64(RelocationRef R, uint64_t Value) {
- return RelocToApply(Value, 8);
- }
-
- /// PPC64 ELF
- RelocToApply visitELF_PPC64_ADDR32(RelocationRef R, uint64_t Value) {
- int64_t Addend = getELFAddend(R);
- uint32_t Res = (Value + Addend) & 0xFFFFFFFF;
- return RelocToApply(Res, 4);
- }
- RelocToApply visitELF_PPC64_ADDR64(RelocationRef R, uint64_t Value) {
- int64_t Addend = getELFAddend(R);
- return RelocToApply(Value + Addend, 8);
- }
-
- /// PPC32 ELF
- RelocToApply visitELF_PPC_ADDR32(RelocationRef R, uint64_t Value) {
- int64_t Addend = getELFAddend(R);
- uint32_t Res = (Value + Addend) & 0xFFFFFFFF;
- return RelocToApply(Res, 4);
- }
-
- /// Lanai ELF
- RelocToApply visitELF_Lanai_32(RelocationRef R, uint64_t Value) {
- int64_t Addend = getELFAddend(R);
- uint32_t Res = (Value + Addend) & 0xFFFFFFFF;
- return RelocToApply(Res, 4);
- }
-
- /// MIPS ELF
- RelocToApply visitELF_MIPS_32(RelocationRef R, uint64_t Value) {
- uint32_t Res = Value & 0xFFFFFFFF;
- return RelocToApply(Res, 4);
- }
-
- /// MIPS64 ELF
- RelocToApply visitELF_MIPS64_32(RelocationRef R, uint64_t Value) {
- int64_t Addend = getELFAddend(R);
- uint32_t Res = (Value + Addend) & 0xFFFFFFFF;
- return RelocToApply(Res, 4);
+ uint64_t visitX86_64(uint32_t Rel, RelocationRef R, uint64_t Value) {
+ switch (Rel) {
+ case ELF::R_X86_64_NONE:
+ return 0;
+ case ELF::R_X86_64_64:
+ return Value + getELFAddend(R);
+ case ELF::R_X86_64_PC32:
+ return Value + getELFAddend(R) - R.getOffset();
+ case ELF::R_X86_64_32:
+ case ELF::R_X86_64_32S:
+ return (Value + getELFAddend(R)) & 0xFFFFFFFF;
+ }
+ HasError = true;
+ return 0;
}
- RelocToApply visitELF_MIPS64_64(RelocationRef R, uint64_t Value) {
- int64_t Addend = getELFAddend(R);
- uint64_t Res = (Value + Addend);
- return RelocToApply(Res, 8);
+ uint64_t visitAarch64(uint32_t Rel, RelocationRef R, uint64_t Value) {
+ switch (Rel) {
+ case ELF::R_AARCH64_ABS32: {
+ int64_t Res = Value + getELFAddend(R);
+ if (Res < INT32_MIN || Res > UINT32_MAX)
+ HasError = true;
+ return static_cast<uint32_t>(Res);
+ }
+ case ELF::R_AARCH64_ABS64:
+ return Value + getELFAddend(R);
+ }
+ HasError = true;
+ return 0;
}
- // AArch64 ELF
- RelocToApply visitELF_AARCH64_ABS32(RelocationRef R, uint64_t Value) {
- int64_t Addend = getELFAddend(R);
- int64_t Res = Value + Addend;
-
- // Overflow check allows for both signed and unsigned interpretation.
- if (Res < INT32_MIN || Res > UINT32_MAX)
- HasError = true;
-
- return RelocToApply(static_cast<uint32_t>(Res), 4);
+ uint64_t visitBpf(uint32_t Rel, RelocationRef R, uint64_t Value) {
+ switch (Rel) {
+ case ELF::R_BPF_64_32:
+ return Value & 0xFFFFFFFF;
+ case ELF::R_BPF_64_64:
+ return Value;
+ }
+ HasError = true;
+ return 0;
}
- RelocToApply visitELF_AARCH64_ABS64(RelocationRef R, uint64_t Value) {
- int64_t Addend = getELFAddend(R);
- return RelocToApply(Value + Addend, 8);
+ uint64_t visitMips64(uint32_t Rel, RelocationRef R, uint64_t Value) {
+ switch (Rel) {
+ case ELF::R_MIPS_32:
+ return (Value + getELFAddend(R)) & 0xFFFFFFFF;
+ case ELF::R_MIPS_64:
+ return Value + getELFAddend(R);
+ }
+ HasError = true;
+ return 0;
}
- // SystemZ ELF
- RelocToApply visitELF_390_32(RelocationRef R, uint64_t Value) {
- int64_t Addend = getELFAddend(R);
- int64_t Res = Value + Addend;
-
- // Overflow check allows for both signed and unsigned interpretation.
- if (Res < INT32_MIN || Res > UINT32_MAX)
- HasError = true;
-
- return RelocToApply(static_cast<uint32_t>(Res), 4);
+ uint64_t visitPPC64(uint32_t Rel, RelocationRef R, uint64_t Value) {
+ switch (Rel) {
+ case ELF::R_PPC64_ADDR32:
+ return (Value + getELFAddend(R)) & 0xFFFFFFFF;
+ case ELF::R_PPC64_ADDR64:
+ return Value + getELFAddend(R);
+ }
+ HasError = true;
+ return 0;
}
- RelocToApply visitELF_390_64(RelocationRef R, uint64_t Value) {
- int64_t Addend = getELFAddend(R);
- return RelocToApply(Value + Addend, 8);
+ uint64_t visitSystemz(uint32_t Rel, RelocationRef R, uint64_t Value) {
+ switch (Rel) {
+ case ELF::R_390_32: {
+ int64_t Res = Value + getELFAddend(R);
+ if (Res < INT32_MIN || Res > UINT32_MAX)
+ HasError = true;
+ return static_cast<uint32_t>(Res);
+ }
+ case ELF::R_390_64:
+ return Value + getELFAddend(R);
+ }
+ HasError = true;
+ return 0;
}
- RelocToApply visitELF_SPARC_32(RelocationRef R, uint32_t Value) {
- int32_t Addend = getELFAddend(R);
- return RelocToApply(Value + Addend, 4);
+ uint64_t visitSparc64(uint32_t Rel, RelocationRef R, uint64_t Value) {
+ switch (Rel) {
+ case ELF::R_SPARC_32:
+ case ELF::R_SPARC_64:
+ case ELF::R_SPARC_UA32:
+ case ELF::R_SPARC_UA64:
+ return Value + getELFAddend(R);
+ }
+ HasError = true;
+ return 0;
}
- RelocToApply visitELF_SPARCV9_32(RelocationRef R, uint64_t Value) {
- int32_t Addend = getELFAddend(R);
- return RelocToApply(Value + Addend, 4);
+ uint64_t visitAmdgpu(uint32_t Rel, RelocationRef R, uint64_t Value) {
+ switch (Rel) {
+ case ELF::R_AMDGPU_ABS32:
+ case ELF::R_AMDGPU_ABS64:
+ return Value + getELFAddend(R);
+ }
+ HasError = true;
+ return 0;
}
- RelocToApply visitELF_SPARCV9_64(RelocationRef R, uint64_t Value) {
- int64_t Addend = getELFAddend(R);
- return RelocToApply(Value + Addend, 8);
+ uint64_t visitX86(uint32_t Rel, RelocationRef R, uint64_t Value) {
+ switch (Rel) {
+ case ELF::R_386_NONE:
+ return 0;
+ case ELF::R_386_32:
+ return Value;
+ case ELF::R_386_PC32:
+ return Value - R.getOffset();
+ }
+ HasError = true;
+ return 0;
}
- RelocToApply visitELF_ARM_ABS32(RelocationRef R, uint64_t Value) {
- int64_t Res = Value;
-
- // Overflow check allows for both signed and unsigned interpretation.
- if (Res < INT32_MIN || Res > UINT32_MAX)
- HasError = true;
-
- return RelocToApply(static_cast<uint32_t>(Res), 4);
+ uint64_t visitPPC32(uint32_t Rel, RelocationRef R, uint64_t Value) {
+ if (Rel == ELF::R_PPC_ADDR32)
+ return (Value + getELFAddend(R)) & 0xFFFFFFFF;
+ HasError = true;
+ return 0;
}
- RelocToApply visitELF_HEX_32(RelocationRef R, uint64_t Value) {
- int64_t Addend = getELFAddend(R);
- return RelocToApply(Value + Addend, 4);
+ uint64_t visitARM(uint32_t Rel, RelocationRef R, uint64_t Value) {
+ if (Rel == ELF::R_ARM_ABS32) {
+ if ((int64_t)Value < INT32_MIN || (int64_t)Value > UINT32_MAX)
+ HasError = true;
+ return static_cast<uint32_t>(Value);
+ }
+ HasError = true;
+ return 0;
}
- RelocToApply visitELF_AMDGPU_ABS32(RelocationRef R, uint64_t Value) {
- int64_t Addend = getELFAddend(R);
- return RelocToApply(Value + Addend, 4);
+ uint64_t visitLanai(uint32_t Rel, RelocationRef R, uint64_t Value) {
+ if (Rel == ELF::R_LANAI_32)
+ return (Value + getELFAddend(R)) & 0xFFFFFFFF;
+ HasError = true;
+ return 0;
}
- /// I386 COFF
- RelocToApply visitCOFF_I386_SECREL(RelocationRef R, uint64_t Value) {
- return RelocToApply(static_cast<uint32_t>(Value), /*Width=*/4);
+ uint64_t visitMips32(uint32_t Rel, RelocationRef R, uint64_t Value) {
+ if (Rel == ELF::R_MIPS_32)
+ return Value & 0xFFFFFFFF;
+ HasError = true;
+ return 0;
}
- RelocToApply visitCOFF_I386_DIR32(RelocationRef R, uint64_t Value) {
- return RelocToApply(static_cast<uint32_t>(Value), /*Width=*/4);
+ uint64_t visitSparc32(uint32_t Rel, RelocationRef R, uint64_t Value) {
+ if (Rel == ELF::R_SPARC_32 || Rel == ELF::R_SPARC_UA32)
+ return Value + getELFAddend(R);
+ HasError = true;
+ return 0;
}
- /// AMD64 COFF
- RelocToApply visitCOFF_AMD64_SECREL(RelocationRef R, uint64_t Value) {
- return RelocToApply(static_cast<uint32_t>(Value), /*Width=*/4);
+ uint64_t visitHexagon(uint32_t Rel, RelocationRef R, uint64_t Value) {
+ if (Rel == ELF::R_HEX_32)
+ return Value + getELFAddend(R);
+ HasError = true;
+ return 0;
}
- RelocToApply visitCOFF_AMD64_ADDR64(RelocationRef R, uint64_t Value) {
- return RelocToApply(Value, /*Width=*/8);
+ uint64_t visitCOFF(uint32_t Rel, RelocationRef R, uint64_t Value) {
+ switch (ObjToVisit.getArch()) {
+ case Triple::x86:
+ switch (Rel) {
+ case COFF::IMAGE_REL_I386_SECREL:
+ case COFF::IMAGE_REL_I386_DIR32:
+ return static_cast<uint32_t>(Value);
+ }
+ break;
+ case Triple::x86_64:
+ switch (Rel) {
+ case COFF::IMAGE_REL_AMD64_SECREL:
+ return static_cast<uint32_t>(Value);
+ case COFF::IMAGE_REL_AMD64_ADDR64:
+ return Value;
+ }
+ break;
+ }
+ HasError = true;
+ return 0;
}
- // X86_64 MachO
- RelocToApply visitMACHO_X86_64_UNSIGNED(RelocationRef R, uint64_t Value) {
- uint8_t Length = getLengthMachO64(R);
- Length = 1<<Length;
- return RelocToApply(Value, Length);
+ uint64_t visitMachO(uint32_t Rel, RelocationRef R, uint64_t Value) {
+ if (ObjToVisit.getArch() == Triple::x86_64 &&
+ Rel == MachO::X86_64_RELOC_UNSIGNED)
+ return Value;
+ HasError = true;
+ return 0;
}
};
-}
-}
-#endif
+} // end namespace object
+} // end namespace llvm
+
+#endif // LLVM_OBJECT_RELOCVISITOR_H
diff --git a/contrib/llvm/include/llvm/Object/StackMapParser.h b/contrib/llvm/include/llvm/Object/StackMapParser.h
index efea62b..0c5e1e3 100644
--- a/contrib/llvm/include/llvm/Object/StackMapParser.h
+++ b/contrib/llvm/include/llvm/Object/StackMapParser.h
@@ -1,4 +1,4 @@
-//===-------- StackMapParser.h - StackMap Parsing Support -------*- C++ -*-===//
+//===- StackMapParser.h - StackMap Parsing Support --------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -11,7 +11,11 @@
#define LLVM_CODEGEN_STACKMAPPARSER_H
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/iterator_range.h"
#include "llvm/Support/Endian.h"
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
#include <vector>
namespace llvm {
@@ -19,12 +23,11 @@ namespace llvm {
template <support::endianness Endianness>
class StackMapV2Parser {
public:
-
template <typename AccessorT>
class AccessorIterator {
public:
-
AccessorIterator(AccessorT A) : A(A) {}
+
AccessorIterator& operator++() { A = A.next(); return *this; }
AccessorIterator operator++(int) {
auto tmp = *this;
@@ -48,8 +51,8 @@ public:
/// Accessor for function records.
class FunctionAccessor {
friend class StackMapV2Parser;
- public:
+ public:
/// Get the function address.
uint64_t getFunctionAddress() const {
return read<uint64_t>(P);
@@ -80,13 +83,12 @@ public:
/// Accessor for constants.
class ConstantAccessor {
friend class StackMapV2Parser;
- public:
+ public:
/// Return the value of this constant.
uint64_t getValue() const { return read<uint64_t>(P); }
private:
-
ConstantAccessor(const uint8_t *P) : P(P) {}
const static int ConstantAccessorSize = sizeof(uint64_t);
@@ -98,20 +100,16 @@ public:
const uint8_t *P;
};
- // Forward-declare RecordAccessor so we can friend it below.
- class RecordAccessor;
-
enum class LocationKind : uint8_t {
Register = 1, Direct = 2, Indirect = 3, Constant = 4, ConstantIndex = 5
};
-
/// Accessor for location records.
class LocationAccessor {
friend class StackMapV2Parser;
friend class RecordAccessor;
- public:
+ public:
/// Get the Kind for this location.
LocationKind getKind() const {
return LocationKind(P[KindOffset]);
@@ -144,7 +142,6 @@ public:
}
private:
-
LocationAccessor(const uint8_t *P) : P(P) {}
LocationAccessor next() const {
@@ -163,8 +160,8 @@ public:
class LiveOutAccessor {
friend class StackMapV2Parser;
friend class RecordAccessor;
- public:
+ public:
/// Get the Dwarf register number for this live-out.
uint16_t getDwarfRegNum() const {
return read<uint16_t>(P + DwarfRegNumOffset);
@@ -176,7 +173,6 @@ public:
}
private:
-
LiveOutAccessor(const uint8_t *P) : P(P) {}
LiveOutAccessor next() const {
@@ -194,10 +190,10 @@ public:
/// Accessor for stackmap records.
class RecordAccessor {
friend class StackMapV2Parser;
- public:
- typedef AccessorIterator<LocationAccessor> location_iterator;
- typedef AccessorIterator<LiveOutAccessor> liveout_iterator;
+ public:
+ using location_iterator = AccessorIterator<LocationAccessor>;
+ using liveout_iterator = AccessorIterator<LiveOutAccessor>;
/// Get the patchpoint/stackmap ID for this record.
uint64_t getID() const {
@@ -254,7 +250,6 @@ public:
return liveout_iterator(getLiveOut(0));
}
-
/// End iterator for live-outs.
liveout_iterator liveouts_end() const {
return liveout_iterator(getLiveOut(getNumLiveOuts()));
@@ -266,7 +261,6 @@ public:
}
private:
-
RecordAccessor(const uint8_t *P) : P(P) {}
unsigned getNumLiveOutsOffset() const {
@@ -316,9 +310,9 @@ public:
}
}
- typedef AccessorIterator<FunctionAccessor> function_iterator;
- typedef AccessorIterator<ConstantAccessor> constant_iterator;
- typedef AccessorIterator<RecordAccessor> record_iterator;
+ using function_iterator = AccessorIterator<FunctionAccessor>;
+ using constant_iterator = AccessorIterator<ConstantAccessor>;
+ using record_iterator = AccessorIterator<RecordAccessor>;
/// Get the version number of this stackmap. (Always returns 2).
unsigned getVersion() const { return 2; }
@@ -413,7 +407,6 @@ public:
}
private:
-
template <typename T>
static T read(const uint8_t *P) {
return support::endian::read<T, Endianness, 1>(P);
@@ -441,6 +434,6 @@ private:
std::vector<unsigned> StackMapRecordOffsets;
};
-}
+} // end namespace llvm
-#endif
+#endif // LLVM_CODEGEN_STACKMAPPARSER_H
diff --git a/contrib/llvm/include/llvm/Object/SymbolicFile.h b/contrib/llvm/include/llvm/Object/SymbolicFile.h
index af62e62..5b9549b 100644
--- a/contrib/llvm/include/llvm/Object/SymbolicFile.h
+++ b/contrib/llvm/include/llvm/Object/SymbolicFile.h
@@ -14,9 +14,20 @@
#ifndef LLVM_OBJECT_SYMBOLICFILE_H
#define LLVM_OBJECT_SYMBOLICFILE_H
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/iterator_range.h"
+#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 <utility>
+#include "llvm/Support/MemoryBuffer.h"
+#include <cinttypes>
+#include <cstdint>
+#include <cstring>
+#include <iterator>
+#include <memory>
+#include <system_error>
namespace llvm {
namespace object {
@@ -28,12 +39,14 @@ union DataRefImpl {
uint32_t a, b;
} d;
uintptr_t p;
+
DataRefImpl() { std::memset(this, 0, sizeof(DataRefImpl)); }
};
template <typename OStream>
OStream& operator<<(OStream &OS, const DataRefImpl &D) {
- OS << "(" << format("0x%x8", D.p) << " (" << format("0x%x8", D.d.a) << ", " << format("0x%x8", D.d.b) << "))";
+ OS << "(" << format("0x%08" PRIxPTR, D.p) << " (" << format("0x%08x", D.d.a)
+ << ", " << format("0x%08x", D.d.b) << "))";
return OS;
}
@@ -85,7 +98,7 @@ class SymbolicFile;
/// symbols in the object file.
class BasicSymbolRef {
DataRefImpl SymbolPimpl;
- const SymbolicFile *OwningObject;
+ const SymbolicFile *OwningObject = nullptr;
public:
enum Flags : unsigned {
@@ -106,7 +119,7 @@ public:
// (IR only)
};
- BasicSymbolRef() : OwningObject(nullptr) { }
+ BasicSymbolRef() = default;
BasicSymbolRef(DataRefImpl SymbolP, const SymbolicFile *Owner);
bool operator==(const BasicSymbolRef &Other) const;
@@ -123,12 +136,12 @@ public:
const SymbolicFile *getObject() const;
};
-typedef content_iterator<BasicSymbolRef> basic_symbol_iterator;
+using basic_symbol_iterator = content_iterator<BasicSymbolRef>;
class SymbolicFile : public Binary {
public:
- ~SymbolicFile() override;
SymbolicFile(unsigned int Type, MemoryBufferRef Source);
+ ~SymbolicFile() override;
// virtual interface.
virtual void moveSymbolNext(DataRefImpl &Symb) const = 0;
@@ -143,24 +156,24 @@ public:
virtual basic_symbol_iterator symbol_end() const = 0;
// convenience wrappers.
- typedef iterator_range<basic_symbol_iterator> basic_symbol_iterator_range;
+ using basic_symbol_iterator_range = iterator_range<basic_symbol_iterator>;
basic_symbol_iterator_range symbols() const {
return basic_symbol_iterator_range(symbol_begin(), symbol_end());
}
// construction aux.
static Expected<std::unique_ptr<SymbolicFile>>
- createSymbolicFile(MemoryBufferRef Object, sys::fs::file_magic Type,
+ createSymbolicFile(MemoryBufferRef Object, llvm::file_magic Type,
LLVMContext *Context);
static Expected<std::unique_ptr<SymbolicFile>>
createSymbolicFile(MemoryBufferRef Object) {
- return createSymbolicFile(Object, sys::fs::file_magic::unknown, nullptr);
+ return createSymbolicFile(Object, llvm::file_magic::unknown, nullptr);
}
static Expected<OwningBinary<SymbolicFile>>
createSymbolicFile(StringRef ObjectPath);
- static inline bool classof(const Binary *v) {
+ static bool classof(const Binary *v) {
return v->isSymbolic();
}
};
@@ -197,7 +210,7 @@ inline const SymbolicFile *BasicSymbolRef::getObject() const {
return OwningObject;
}
-}
-}
+} // end namespace object
+} // end namespace llvm
-#endif
+#endif // LLVM_OBJECT_SYMBOLICFILE_H
diff --git a/contrib/llvm/include/llvm/Object/Wasm.h b/contrib/llvm/include/llvm/Object/Wasm.h
index 2ece6a6..07ee4a4 100644
--- a/contrib/llvm/include/llvm/Object/Wasm.h
+++ b/contrib/llvm/include/llvm/Object/Wasm.h
@@ -17,24 +17,112 @@
#ifndef LLVM_OBJECT_WASM_H
#define LLVM_OBJECT_WASM_H
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/BinaryFormat/Wasm.h"
+#include "llvm/Object/Binary.h"
#include "llvm/Object/ObjectFile.h"
-#include "llvm/Support/Wasm.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include <cstddef>
+#include <cstdint>
+#include <vector>
namespace llvm {
namespace object {
+class WasmSymbol {
+public:
+ enum class SymbolType {
+ FUNCTION_IMPORT,
+ FUNCTION_EXPORT,
+ GLOBAL_IMPORT,
+ GLOBAL_EXPORT,
+ DEBUG_FUNCTION_NAME,
+ };
+
+ WasmSymbol(StringRef Name, SymbolType Type, uint32_t Section,
+ uint32_t ElementIndex)
+ : Name(Name), Type(Type), Section(Section), ElementIndex(ElementIndex) {}
+
+ StringRef Name;
+ SymbolType Type;
+ uint32_t Section;
+ uint32_t Flags = 0;
+
+ // Index into the imports, exports or functions array of the object depending
+ // on the type
+ uint32_t ElementIndex;
+
+ bool isWeak() const {
+ return Flags & wasm::WASM_SYMBOL_FLAG_WEAK;
+ }
+
+ void print(raw_ostream &Out) const {
+ Out << "Name=" << Name << ", Type=" << static_cast<int>(Type)
+ << ", Flags=" << Flags << " ElemIndex=" << ElementIndex;
+ }
+
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
+ LLVM_DUMP_METHOD void dump() const { print(dbgs()); }
+#endif
+};
+
+struct WasmSection {
+ WasmSection() = default;
+
+ uint32_t Type = 0; // Section type (See below)
+ uint32_t Offset = 0; // Offset with in the file
+ StringRef Name; // Section name (User-defined sections only)
+ ArrayRef<uint8_t> Content; // Section content
+ std::vector<wasm::WasmRelocation> Relocations; // Relocations for this section
+};
+
+struct WasmSegment {
+ uint32_t SectionOffset;
+ wasm::WasmDataSegment Data;
+};
+
class WasmObjectFile : public ObjectFile {
+
public:
WasmObjectFile(MemoryBufferRef Object, Error &Err);
+
const wasm::WasmObjectHeader &getHeader() const;
- const wasm::WasmSection *getWasmSection(const SectionRef &Section) const;
+ const WasmSymbol &getWasmSymbol(const DataRefImpl &Symb) const;
+ const WasmSymbol &getWasmSymbol(const SymbolRef &Symbol) const;
+ const WasmSection &getWasmSection(const SectionRef &Section) const;
+ const wasm::WasmRelocation &getWasmRelocation(const RelocationRef& Ref) const;
+
static bool classof(const Binary *v) { return v->isWasm(); }
-protected:
- void moveSymbolNext(DataRefImpl &Symb) const override;
+ const std::vector<wasm::WasmSignature>& types() const { return Signatures; }
+ const std::vector<uint32_t>& functionTypes() const { return FunctionTypes; }
+ const std::vector<wasm::WasmImport>& imports() const { return Imports; }
+ const std::vector<wasm::WasmTable>& tables() const { return Tables; }
+ const std::vector<wasm::WasmLimits>& memories() const { return Memories; }
+ const std::vector<wasm::WasmGlobal>& globals() const { return Globals; }
+ const std::vector<wasm::WasmExport>& exports() const { return Exports; }
+ const wasm::WasmLinkingData& linkingData() const { return LinkingData; }
- std::error_code printSymbolName(raw_ostream &OS,
- DataRefImpl Symb) const override;
+ uint32_t getNumberOfSymbols() const {
+ return Symbols.size();
+ }
+
+ const std::vector<wasm::WasmElemSegment>& elements() const {
+ return ElemSegments;
+ }
+
+ const std::vector<WasmSegment>& dataSegments() const {
+ return DataSegments;
+ }
+
+ const std::vector<wasm::WasmFunction>& functions() const { return Functions; }
+ const ArrayRef<uint8_t>& code() const { return CodeSection; }
+ uint32_t startFunction() const { return StartFunction; }
+
+ void moveSymbolNext(DataRefImpl &Symb) const override;
uint32_t getSymbolFlags(DataRefImpl Symb) const override;
@@ -55,6 +143,7 @@ protected:
std::error_code getSectionName(DataRefImpl Sec,
StringRef &Res) const override;
uint64_t getSectionAddress(DataRefImpl Sec) const override;
+ uint64_t getSectionIndex(DataRefImpl Sec) const override;
uint64_t getSectionSize(DataRefImpl Sec) const override;
std::error_code getSectionContents(DataRefImpl Sec,
StringRef &Res) const override;
@@ -67,7 +156,6 @@ protected:
bool isSectionBitcode(DataRefImpl Sec) const override;
relocation_iterator section_rel_begin(DataRefImpl Sec) const override;
relocation_iterator section_rel_end(DataRefImpl Sec) const override;
- section_iterator getRelocatedSection(DataRefImpl Sec) const override;
// Overrides from RelocationRef.
void moveRelocationNext(DataRefImpl &Rel) const override;
@@ -86,14 +174,65 @@ protected:
bool isRelocatableObject() const override;
private:
+ const WasmSection &getWasmSection(DataRefImpl Ref) const;
+ const wasm::WasmRelocation &getWasmRelocation(DataRefImpl Ref) const;
+
+ WasmSection* findCustomSectionByName(StringRef Name);
+ WasmSection* findSectionByType(uint32_t Type);
+
const uint8_t *getPtr(size_t Offset) const;
- Error parseUserSection(wasm::WasmSection &Sec, const uint8_t *Ptr,
- size_t Length);
+ Error parseSection(WasmSection &Sec);
+ Error parseCustomSection(WasmSection &Sec, const uint8_t *Ptr,
+ const uint8_t *End);
+
+ // Standard section types
+ Error parseTypeSection(const uint8_t *Ptr, const uint8_t *End);
+ Error parseImportSection(const uint8_t *Ptr, const uint8_t *End);
+ Error parseFunctionSection(const uint8_t *Ptr, const uint8_t *End);
+ Error parseTableSection(const uint8_t *Ptr, const uint8_t *End);
+ Error parseMemorySection(const uint8_t *Ptr, const uint8_t *End);
+ Error parseGlobalSection(const uint8_t *Ptr, const uint8_t *End);
+ Error parseExportSection(const uint8_t *Ptr, const uint8_t *End);
+ Error parseStartSection(const uint8_t *Ptr, const uint8_t *End);
+ Error parseElemSection(const uint8_t *Ptr, const uint8_t *End);
+ Error parseCodeSection(const uint8_t *Ptr, const uint8_t *End);
+ Error parseDataSection(const uint8_t *Ptr, const uint8_t *End);
+
+ // Custom section types
+ Error parseNameSection(const uint8_t *Ptr, const uint8_t *End);
+ Error parseLinkingSection(const uint8_t *Ptr, const uint8_t *End);
+ Error parseRelocSection(StringRef Name, const uint8_t *Ptr,
+ const uint8_t *End);
wasm::WasmObjectHeader Header;
- std::vector<wasm::WasmSection> Sections;
+ std::vector<WasmSection> Sections;
+ std::vector<wasm::WasmSignature> Signatures;
+ std::vector<uint32_t> FunctionTypes;
+ std::vector<wasm::WasmTable> Tables;
+ std::vector<wasm::WasmLimits> Memories;
+ std::vector<wasm::WasmGlobal> Globals;
+ std::vector<wasm::WasmImport> Imports;
+ std::vector<wasm::WasmExport> Exports;
+ std::vector<wasm::WasmElemSegment> ElemSegments;
+ std::vector<WasmSegment> DataSegments;
+ std::vector<wasm::WasmFunction> Functions;
+ std::vector<WasmSymbol> Symbols;
+ ArrayRef<uint8_t> CodeSection;
+ uint32_t StartFunction = -1;
+ bool HasLinkingSection = false;
+ wasm::WasmLinkingData LinkingData;
+
+ StringMap<uint32_t> SymbolMap;
};
-}
+
+} // end namespace object
+
+inline raw_ostream &operator<<(raw_ostream &OS,
+ const object::WasmSymbol &Sym) {
+ Sym.print(OS);
+ return OS;
}
-#endif
+} // end namespace llvm
+
+#endif // LLVM_OBJECT_WASM_H
diff --git a/contrib/llvm/include/llvm/Object/WindowsResource.h b/contrib/llvm/include/llvm/Object/WindowsResource.h
new file mode 100644
index 0000000..3d32409
--- /dev/null
+++ b/contrib/llvm/include/llvm/Object/WindowsResource.h
@@ -0,0 +1,219 @@
+//===-- WindowsResource.h ---------------------------------------*- 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 the .res file class. .res files are intermediate
+// products of the typical resource-compilation process on Windows. This
+// process is as follows:
+//
+// .rc file(s) ---(rc.exe)---> .res file(s) ---(cvtres.exe)---> COFF file
+//
+// .rc files are human-readable scripts that list all resources a program uses.
+//
+// They are compiled into .res files, which are a list of the resources in
+// binary form.
+//
+// Finally the data stored in the .res is compiled into a COFF file, where it
+// is organized in a directory tree structure for optimized access by the
+// program during runtime.
+//
+// Ref: msdn.microsoft.com/en-us/library/windows/desktop/ms648007(v=vs.85).aspx
+//
+//===---------------------------------------------------------------------===//
+
+#ifndef LLVM_INCLUDE_LLVM_OBJECT_RESFILE_H
+#define LLVM_INCLUDE_LLVM_OBJECT_RESFILE_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/BinaryFormat/COFF.h"
+#include "llvm/Object/Binary.h"
+#include "llvm/Object/Error.h"
+#include "llvm/Support/BinaryByteStream.h"
+#include "llvm/Support/BinaryStreamReader.h"
+#include "llvm/Support/ConvertUTF.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/ScopedPrinter.h"
+
+#include <map>
+
+namespace llvm {
+namespace object {
+
+class WindowsResource;
+
+const size_t WIN_RES_MAGIC_SIZE = 16;
+const size_t WIN_RES_NULL_ENTRY_SIZE = 16;
+const uint32_t WIN_RES_HEADER_ALIGNMENT = 4;
+const uint32_t WIN_RES_DATA_ALIGNMENT = 4;
+const uint16_t WIN_RES_PURE_MOVEABLE = 0x0030;
+
+struct WinResHeaderPrefix {
+ support::ulittle32_t DataSize;
+ support::ulittle32_t HeaderSize;
+};
+
+// Type and Name may each either be an integer ID or a string. This struct is
+// only used in the case where they are both IDs.
+struct WinResIDs {
+ uint16_t TypeFlag;
+ support::ulittle16_t TypeID;
+ uint16_t NameFlag;
+ support::ulittle16_t NameID;
+
+ void setType(uint16_t ID) {
+ TypeFlag = 0xffff;
+ TypeID = ID;
+ }
+
+ void setName(uint16_t ID) {
+ NameFlag = 0xffff;
+ NameID = ID;
+ }
+};
+
+struct WinResHeaderSuffix {
+ support::ulittle32_t DataVersion;
+ support::ulittle16_t MemoryFlags;
+ support::ulittle16_t Language;
+ support::ulittle32_t Version;
+ support::ulittle32_t Characteristics;
+};
+
+class ResourceEntryRef {
+public:
+ Error moveNext(bool &End);
+ bool checkTypeString() const { return IsStringType; }
+ ArrayRef<UTF16> getTypeString() const { return Type; }
+ uint16_t getTypeID() const { return TypeID; }
+ bool checkNameString() const { return IsStringName; }
+ ArrayRef<UTF16> getNameString() const { return Name; }
+ uint16_t getNameID() const { return NameID; }
+ uint16_t getLanguage() const { return Suffix->Language; }
+ uint16_t getMajorVersion() const { return Suffix->Version >> 16; }
+ uint16_t getMinorVersion() const { return Suffix->Version; }
+ uint32_t getCharacteristics() const { return Suffix->Characteristics; }
+ ArrayRef<uint8_t> getData() const { return Data; }
+
+private:
+ friend class WindowsResource;
+
+ ResourceEntryRef(BinaryStreamRef Ref, const WindowsResource *Owner,
+ Error &Err);
+
+ Error loadNext();
+
+ BinaryStreamReader Reader;
+ bool IsStringType;
+ ArrayRef<UTF16> Type;
+ uint16_t TypeID;
+ bool IsStringName;
+ ArrayRef<UTF16> Name;
+ uint16_t NameID;
+ const WinResHeaderSuffix *Suffix = nullptr;
+ ArrayRef<uint8_t> Data;
+ const WindowsResource *OwningRes = nullptr;
+};
+
+class WindowsResource : public Binary {
+public:
+ Expected<ResourceEntryRef> getHeadEntry();
+
+ static bool classof(const Binary *V) { return V->isWinRes(); }
+
+ static Expected<std::unique_ptr<WindowsResource>>
+ createWindowsResource(MemoryBufferRef Source);
+
+private:
+ friend class ResourceEntryRef;
+
+ WindowsResource(MemoryBufferRef Source);
+
+ BinaryByteStream BBS;
+};
+
+class WindowsResourceParser {
+public:
+ class TreeNode;
+ WindowsResourceParser();
+ Error parse(WindowsResource *WR);
+ void printTree(raw_ostream &OS) const;
+ const TreeNode &getTree() const { return Root; }
+ const ArrayRef<std::vector<uint8_t>> getData() const { return Data; }
+ const ArrayRef<std::vector<UTF16>> getStringTable() const {
+ return StringTable;
+ }
+
+ class TreeNode {
+ public:
+ template <typename T>
+ using Children = std::map<T, std::unique_ptr<TreeNode>>;
+
+ void print(ScopedPrinter &Writer, StringRef Name) const;
+ uint32_t getTreeSize() const;
+ uint32_t getStringIndex() const { return StringIndex; }
+ uint32_t getDataIndex() const { return DataIndex; }
+ uint16_t getMajorVersion() const { return MajorVersion; }
+ uint16_t getMinorVersion() const { return MinorVersion; }
+ uint32_t getCharacteristics() const { return Characteristics; }
+ bool checkIsDataNode() const { return IsDataNode; }
+ const Children<uint32_t> &getIDChildren() const { return IDChildren; }
+ const Children<std::string> &getStringChildren() const {
+ return StringChildren;
+ }
+
+ private:
+ friend class WindowsResourceParser;
+
+ static uint32_t StringCount;
+ static uint32_t DataCount;
+
+ static std::unique_ptr<TreeNode> createStringNode();
+ static std::unique_ptr<TreeNode> createIDNode();
+ static std::unique_ptr<TreeNode> createDataNode(uint16_t MajorVersion,
+ uint16_t MinorVersion,
+ uint32_t Characteristics);
+
+ explicit TreeNode(bool IsStringNode);
+ TreeNode(uint16_t MajorVersion, uint16_t MinorVersion,
+ uint32_t Characteristics);
+
+ void addEntry(const ResourceEntryRef &Entry, bool &IsNewTypeString,
+ bool &IsNewNameString);
+ TreeNode &addTypeNode(const ResourceEntryRef &Entry, bool &IsNewTypeString);
+ TreeNode &addNameNode(const ResourceEntryRef &Entry, bool &IsNewNameString);
+ TreeNode &addLanguageNode(const ResourceEntryRef &Entry);
+ TreeNode &addChild(uint32_t ID, bool IsDataNode = false,
+ uint16_t MajorVersion = 0, uint16_t MinorVersion = 0,
+ uint32_t Characteristics = 0);
+ TreeNode &addChild(ArrayRef<UTF16> NameRef, bool &IsNewString);
+
+ bool IsDataNode = false;
+ uint32_t StringIndex;
+ uint32_t DataIndex;
+ Children<uint32_t> IDChildren;
+ Children<std::string> StringChildren;
+ uint16_t MajorVersion = 0;
+ uint16_t MinorVersion = 0;
+ uint32_t Characteristics = 0;
+ };
+
+private:
+ TreeNode Root;
+ std::vector<std::vector<uint8_t>> Data;
+ std::vector<std::vector<UTF16>> StringTable;
+};
+
+Expected<std::unique_ptr<MemoryBuffer>>
+writeWindowsResourceCOFF(llvm::COFF::MachineTypes MachineType,
+ const WindowsResourceParser &Parser);
+
+} // namespace object
+} // namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/ObjectYAML/COFFYAML.h b/contrib/llvm/include/llvm/ObjectYAML/COFFYAML.h
index 65ad1dd..bbceefa 100644
--- a/contrib/llvm/include/llvm/ObjectYAML/COFFYAML.h
+++ b/contrib/llvm/include/llvm/ObjectYAML/COFFYAML.h
@@ -15,12 +15,18 @@
#define LLVM_OBJECTYAML_COFFYAML_H
#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/BinaryFormat/COFF.h"
+#include "llvm/ObjectYAML/CodeViewYAMLDebugSections.h"
+#include "llvm/ObjectYAML/CodeViewYAMLTypes.h"
#include "llvm/ObjectYAML/YAML.h"
-#include "llvm/Support/COFF.h"
+#include <cstdint>
+#include <vector>
namespace llvm {
namespace COFF {
+
inline Characteristics operator|(Characteristics a, Characteristics b) {
uint32_t Ret = static_cast<uint32_t>(a) | static_cast<uint32_t>(b);
return static_cast<Characteristics>(Ret);
@@ -37,58 +43,67 @@ inline DLLCharacteristics operator|(DLLCharacteristics a,
uint16_t Ret = static_cast<uint16_t>(a) | static_cast<uint16_t>(b);
return static_cast<DLLCharacteristics>(Ret);
}
-}
+
+} // end namespace COFF
// The structure of the yaml files is not an exact 1:1 match to COFF. In order
// to use yaml::IO, we use these structures which are closer to the source.
namespace COFFYAML {
- LLVM_YAML_STRONG_TYPEDEF(uint8_t, COMDATType)
- LLVM_YAML_STRONG_TYPEDEF(uint32_t, WeakExternalCharacteristics)
- LLVM_YAML_STRONG_TYPEDEF(uint8_t, AuxSymbolType)
-
- struct Relocation {
- uint32_t VirtualAddress;
- uint16_t Type;
- StringRef SymbolName;
- };
-
- struct Section {
- COFF::section Header;
- unsigned Alignment = 0;
- yaml::BinaryRef SectionData;
- std::vector<Relocation> Relocations;
- StringRef Name;
- Section();
- };
-
- struct Symbol {
- COFF::symbol Header;
- COFF::SymbolBaseType SimpleType = COFF::IMAGE_SYM_TYPE_NULL;
- COFF::SymbolComplexType ComplexType = COFF::IMAGE_SYM_DTYPE_NULL;
- Optional<COFF::AuxiliaryFunctionDefinition> FunctionDefinition;
- Optional<COFF::AuxiliarybfAndefSymbol> bfAndefSymbol;
- Optional<COFF::AuxiliaryWeakExternal> WeakExternal;
- StringRef File;
- Optional<COFF::AuxiliarySectionDefinition> SectionDefinition;
- Optional<COFF::AuxiliaryCLRToken> CLRToken;
- StringRef Name;
- Symbol();
- };
-
- struct PEHeader {
- COFF::PE32Header Header;
- Optional<COFF::DataDirectory> DataDirectories[COFF::NUM_DATA_DIRECTORIES];
- };
-
- struct Object {
- Optional<PEHeader> OptionalHeader;
- COFF::header Header;
- std::vector<Section> Sections;
- std::vector<Symbol> Symbols;
- Object();
- };
-}
-}
+
+LLVM_YAML_STRONG_TYPEDEF(uint8_t, COMDATType)
+LLVM_YAML_STRONG_TYPEDEF(uint32_t, WeakExternalCharacteristics)
+LLVM_YAML_STRONG_TYPEDEF(uint8_t, AuxSymbolType)
+
+struct Relocation {
+ uint32_t VirtualAddress;
+ uint16_t Type;
+ StringRef SymbolName;
+};
+
+struct Section {
+ COFF::section Header;
+ unsigned Alignment = 0;
+ yaml::BinaryRef SectionData;
+ std::vector<CodeViewYAML::YAMLDebugSubsection> DebugS;
+ std::vector<CodeViewYAML::LeafRecord> DebugT;
+ std::vector<Relocation> Relocations;
+ StringRef Name;
+
+ Section();
+};
+
+struct Symbol {
+ COFF::symbol Header;
+ COFF::SymbolBaseType SimpleType = COFF::IMAGE_SYM_TYPE_NULL;
+ COFF::SymbolComplexType ComplexType = COFF::IMAGE_SYM_DTYPE_NULL;
+ Optional<COFF::AuxiliaryFunctionDefinition> FunctionDefinition;
+ Optional<COFF::AuxiliarybfAndefSymbol> bfAndefSymbol;
+ Optional<COFF::AuxiliaryWeakExternal> WeakExternal;
+ StringRef File;
+ Optional<COFF::AuxiliarySectionDefinition> SectionDefinition;
+ Optional<COFF::AuxiliaryCLRToken> CLRToken;
+ StringRef Name;
+
+ Symbol();
+};
+
+struct PEHeader {
+ COFF::PE32Header Header;
+ Optional<COFF::DataDirectory> DataDirectories[COFF::NUM_DATA_DIRECTORIES];
+};
+
+struct Object {
+ Optional<PEHeader> OptionalHeader;
+ COFF::header Header;
+ std::vector<Section> Sections;
+ std::vector<Symbol> Symbols;
+
+ Object();
+};
+
+} // end namespace COFFYAML
+
+} // end namespace llvm
LLVM_YAML_IS_SEQUENCE_VECTOR(COFFYAML::Section)
LLVM_YAML_IS_SEQUENCE_VECTOR(COFFYAML::Symbol)
@@ -220,4 +235,4 @@ struct MappingTraits<COFFYAML::Object> {
} // end namespace yaml
} // end namespace llvm
-#endif
+#endif // LLVM_OBJECTYAML_COFFYAML_H
diff --git a/contrib/llvm/include/llvm/ObjectYAML/CodeViewYAMLDebugSections.h b/contrib/llvm/include/llvm/ObjectYAML/CodeViewYAMLDebugSections.h
new file mode 100644
index 0000000..d620008
--- /dev/null
+++ b/contrib/llvm/include/llvm/ObjectYAML/CodeViewYAMLDebugSections.h
@@ -0,0 +1,140 @@
+//=- CodeViewYAMLDebugSections.h - CodeView YAMLIO debug sections -*- C++ -*-=//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines classes for handling the YAML representation of CodeView
+// Debug Info.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECTYAML_CODEVIEWYAMLDEBUGSECTIONS_H
+#define LLVM_OBJECTYAML_CODEVIEWYAMLDEBUGSECTIONS_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/DebugSubsection.h"
+#include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/YAMLTraits.h"
+#include <cstdint>
+#include <memory>
+#include <vector>
+
+namespace llvm {
+
+namespace codeview {
+
+class StringsAndChecksums;
+class StringsAndChecksumsRef;
+
+} // end namespace codeview
+
+namespace CodeViewYAML {
+
+namespace detail {
+
+struct YAMLSubsectionBase;
+
+} // end namespace detail
+
+struct YAMLFrameData {
+ uint32_t RvaStart;
+ uint32_t CodeSize;
+ uint32_t LocalSize;
+ uint32_t ParamsSize;
+ uint32_t MaxStackSize;
+ StringRef FrameFunc;
+ uint32_t PrologSize;
+ uint32_t SavedRegsSize;
+ uint32_t Flags;
+};
+
+struct YAMLCrossModuleImport {
+ StringRef ModuleName;
+ std::vector<uint32_t> ImportIds;
+};
+
+struct SourceLineEntry {
+ uint32_t Offset;
+ uint32_t LineStart;
+ uint32_t EndDelta;
+ bool IsStatement;
+};
+
+struct SourceColumnEntry {
+ uint16_t StartColumn;
+ uint16_t EndColumn;
+};
+
+struct SourceLineBlock {
+ StringRef FileName;
+ std::vector<SourceLineEntry> Lines;
+ std::vector<SourceColumnEntry> Columns;
+};
+
+struct HexFormattedString {
+ std::vector<uint8_t> Bytes;
+};
+
+struct SourceFileChecksumEntry {
+ StringRef FileName;
+ codeview::FileChecksumKind Kind;
+ HexFormattedString ChecksumBytes;
+};
+
+struct SourceLineInfo {
+ uint32_t RelocOffset;
+ uint32_t RelocSegment;
+ codeview::LineFlags Flags;
+ uint32_t CodeSize;
+ std::vector<SourceLineBlock> Blocks;
+};
+
+struct InlineeSite {
+ uint32_t Inlinee;
+ StringRef FileName;
+ uint32_t SourceLineNum;
+ std::vector<StringRef> ExtraFiles;
+};
+
+struct InlineeInfo {
+ bool HasExtraFiles;
+ std::vector<InlineeSite> Sites;
+};
+
+struct YAMLDebugSubsection {
+ static Expected<YAMLDebugSubsection>
+ fromCodeViewSubection(const codeview::StringsAndChecksumsRef &SC,
+ const codeview::DebugSubsectionRecord &SS);
+
+ std::shared_ptr<detail::YAMLSubsectionBase> Subsection;
+};
+
+struct DebugSubsectionState {};
+
+Expected<std::vector<std::shared_ptr<codeview::DebugSubsection>>>
+toCodeViewSubsectionList(BumpPtrAllocator &Allocator,
+ ArrayRef<YAMLDebugSubsection> Subsections,
+ const codeview::StringsAndChecksums &SC);
+
+std::vector<YAMLDebugSubsection>
+fromDebugS(ArrayRef<uint8_t> Data, const codeview::StringsAndChecksumsRef &SC);
+
+void initializeStringsAndChecksums(ArrayRef<YAMLDebugSubsection> Sections,
+ codeview::StringsAndChecksums &SC);
+
+} // end namespace CodeViewYAML
+
+} // end namespace llvm
+
+LLVM_YAML_DECLARE_MAPPING_TRAITS(CodeViewYAML::YAMLDebugSubsection)
+
+LLVM_YAML_IS_SEQUENCE_VECTOR(CodeViewYAML::YAMLDebugSubsection)
+
+#endif // LLVM_OBJECTYAML_CODEVIEWYAMLDEBUGSECTIONS_H
diff --git a/contrib/llvm/include/llvm/ObjectYAML/CodeViewYAMLSymbols.h b/contrib/llvm/include/llvm/ObjectYAML/CodeViewYAMLSymbols.h
new file mode 100644
index 0000000..791193c
--- /dev/null
+++ b/contrib/llvm/include/llvm/ObjectYAML/CodeViewYAMLSymbols.h
@@ -0,0 +1,49 @@
+//===- CodeViewYAMLSymbols.h - CodeView YAMLIO Symbol implementation ------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines classes for handling the YAML representation of CodeView
+// Debug Info.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECTYAML_CODEVIEWYAMLSYMBOLS_H
+#define LLVM_OBJECTYAML_CODEVIEWYAMLSYMBOLS_H
+
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/YAMLTraits.h"
+#include <memory>
+
+namespace llvm {
+namespace CodeViewYAML {
+
+namespace detail {
+
+struct SymbolRecordBase;
+
+} // end namespace detail
+
+struct SymbolRecord {
+ std::shared_ptr<detail::SymbolRecordBase> Symbol;
+
+ codeview::CVSymbol
+ toCodeViewSymbol(BumpPtrAllocator &Allocator,
+ codeview::CodeViewContainer Container) const;
+
+ static Expected<SymbolRecord> fromCodeViewSymbol(codeview::CVSymbol Symbol);
+};
+
+} // end namespace CodeViewYAML
+} // end namespace llvm
+
+LLVM_YAML_DECLARE_MAPPING_TRAITS(CodeViewYAML::SymbolRecord)
+LLVM_YAML_IS_SEQUENCE_VECTOR(CodeViewYAML::SymbolRecord)
+
+#endif // LLVM_OBJECTYAML_CODEVIEWYAMLSYMBOLS_H
diff --git a/contrib/llvm/include/llvm/ObjectYAML/CodeViewYAMLTypes.h b/contrib/llvm/include/llvm/ObjectYAML/CodeViewYAMLTypes.h
new file mode 100644
index 0000000..88a5668
--- /dev/null
+++ b/contrib/llvm/include/llvm/ObjectYAML/CodeViewYAMLTypes.h
@@ -0,0 +1,71 @@
+//==- CodeViewYAMLTypes.h - CodeView YAMLIO Type implementation --*- C++ -*-==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines classes for handling the YAML representation of CodeView
+// Debug Info.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECTYAML_CODEVIEWYAMLTYPES_H
+#define LLVM_OBJECTYAML_CODEVIEWYAMLTYPES_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/DebugInfo/CodeView/TypeRecord.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/YAMLTraits.h"
+#include <cstdint>
+#include <memory>
+#include <vector>
+
+namespace llvm {
+
+namespace codeview {
+
+class TypeTableBuilder;
+
+} // end namespace codeview
+
+namespace CodeViewYAML {
+
+namespace detail {
+
+struct LeafRecordBase;
+struct MemberRecordBase;
+
+} // end namespace detail
+
+struct MemberRecord {
+ std::shared_ptr<detail::MemberRecordBase> Member;
+};
+
+struct LeafRecord {
+ std::shared_ptr<detail::LeafRecordBase> Leaf;
+
+ codeview::CVType toCodeViewRecord(BumpPtrAllocator &Allocator) const;
+ codeview::CVType toCodeViewRecord(codeview::TypeTableBuilder &TS) const;
+ static Expected<LeafRecord> fromCodeViewRecord(codeview::CVType Type);
+};
+
+std::vector<LeafRecord> fromDebugT(ArrayRef<uint8_t> DebugT);
+ArrayRef<uint8_t> toDebugT(ArrayRef<LeafRecord>, BumpPtrAllocator &Alloc);
+
+} // end namespace CodeViewYAML
+
+} // end namespace llvm
+
+LLVM_YAML_DECLARE_SCALAR_TRAITS(codeview::GUID, true)
+
+LLVM_YAML_DECLARE_MAPPING_TRAITS(CodeViewYAML::LeafRecord)
+LLVM_YAML_DECLARE_MAPPING_TRAITS(CodeViewYAML::MemberRecord)
+
+LLVM_YAML_IS_SEQUENCE_VECTOR(CodeViewYAML::LeafRecord)
+LLVM_YAML_IS_SEQUENCE_VECTOR(CodeViewYAML::MemberRecord)
+
+#endif // LLVM_OBJECTYAML_CODEVIEWYAMLTYPES_H
diff --git a/contrib/llvm/include/llvm/ObjectYAML/DWARFEmitter.h b/contrib/llvm/include/llvm/ObjectYAML/DWARFEmitter.h
new file mode 100644
index 0000000..0d7d8b4
--- /dev/null
+++ b/contrib/llvm/include/llvm/ObjectYAML/DWARFEmitter.h
@@ -0,0 +1,49 @@
+//===--- DWARFEmitter.h - ---------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+/// \file
+/// \brief Common declarations for yaml2obj
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECTYAML_DWARFEMITTER_H
+#define LLVM_OBJECTYAML_DWARFEMITTER_H
+
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/Host.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include <memory>
+
+namespace llvm {
+
+class raw_ostream;
+
+namespace DWARFYAML {
+
+struct Data;
+struct PubSection;
+
+void EmitDebugAbbrev(raw_ostream &OS, const Data &DI);
+void 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);
+
+Expected<StringMap<std::unique_ptr<MemoryBuffer>>>
+EmitDebugSections(StringRef YAMLString,
+ bool IsLittleEndian = sys::IsLittleEndianHost);
+
+} // end namespace DWARFYAML
+
+} // end namespace llvm
+
+#endif // LLVM_OBJECTYAML_DWARFEMITTER_H
diff --git a/contrib/llvm/include/llvm/ObjectYAML/DWARFYAML.h b/contrib/llvm/include/llvm/ObjectYAML/DWARFYAML.h
index d031b5a..2162f0f 100644
--- a/contrib/llvm/include/llvm/ObjectYAML/DWARFYAML.h
+++ b/contrib/llvm/include/llvm/ObjectYAML/DWARFYAML.h
@@ -13,19 +13,42 @@
///
//===----------------------------------------------------------------------===//
-
#ifndef LLVM_OBJECTYAML_DWARFYAML_H
#define LLVM_OBJECTYAML_DWARFYAML_H
-#include "llvm/ObjectYAML/YAML.h"
-#include "llvm/Support/Dwarf.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/BinaryFormat/Dwarf.h"
+#include "llvm/Support/YAMLTraits.h"
+#include <cstdint>
+#include <vector>
namespace llvm {
namespace DWARFYAML {
+struct InitialLength {
+ uint32_t TotalLength;
+ uint64_t TotalLength64;
+
+ bool isDWARF64() const { return TotalLength == UINT32_MAX; }
+
+ uint64_t getLength() const {
+ return isDWARF64() ? TotalLength64 : TotalLength;
+ }
+
+ void setLength(uint64_t Len) {
+ if (Len >= (uint64_t)UINT32_MAX) {
+ TotalLength64 = Len;
+ TotalLength = UINT32_MAX;
+ } else {
+ TotalLength = Len;
+ }
+ }
+};
+
struct AttributeAbbrev {
llvm::dwarf::Attribute Attribute;
llvm::dwarf::Form Form;
+ llvm::yaml::Hex64 Value; // Some DWARF5 attributes have values
};
struct Abbrev {
@@ -41,7 +64,7 @@ struct ARangeDescriptor {
};
struct ARange {
- uint32_t Length;
+ InitialLength Length;
uint16_t Version;
uint32_t CuOffset;
uint8_t AddrSize;
@@ -56,13 +79,11 @@ struct PubEntry {
};
struct PubSection {
- PubSection() : IsGNUStyle(false) {}
-
- uint32_t Length;
+ InitialLength Length;
uint16_t Version;
uint32_t UnitOffset;
uint32_t UnitSize;
- bool IsGNUStyle;
+ bool IsGNUStyle = false;
std::vector<PubEntry> Entries;
};
@@ -78,8 +99,9 @@ struct Entry {
};
struct Unit {
- uint32_t Length;
+ InitialLength Length;
uint16_t Version;
+ llvm::dwarf::UnitType Type; // Added in DWARF 5
uint32_t AbbrOffset;
uint8_t AddrSize;
std::vector<Entry> Entries;
@@ -104,8 +126,7 @@ struct LineTableOpcode {
};
struct LineTable {
- uint32_t TotalLength;
- uint64_t TotalLength64;
+ InitialLength Length;
uint16_t Version;
uint64_t PrologueLength;
uint8_t MinInstLength;
@@ -130,7 +151,7 @@ struct Data {
PubSection GNUPubNames;
PubSection GNUPubTypes;
-
+
std::vector<Unit> CompileUnits;
std::vector<LineTable> DebugLines;
@@ -138,12 +159,10 @@ struct Data {
bool isEmpty() const;
};
-} // namespace llvm::DWARFYAML
-} // namespace llvm
+} // end namespace DWARFYAML
+} // end namespace llvm
-LLVM_YAML_IS_SEQUENCE_VECTOR(uint8_t)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::Hex64)
-LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::StringRef)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::Hex8)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::AttributeAbbrev)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::Abbrev)
@@ -203,7 +222,7 @@ template <> struct MappingTraits<DWARFYAML::FormValue> {
template <> struct MappingTraits<DWARFYAML::File> {
static void mapping(IO &IO, DWARFYAML::File &File);
};
-
+
template <> struct MappingTraits<DWARFYAML::LineTableOpcode> {
static void mapping(IO &IO, DWARFYAML::LineTableOpcode &LineTableOpcode);
};
@@ -212,12 +231,16 @@ template <> struct MappingTraits<DWARFYAML::LineTable> {
static void mapping(IO &IO, DWARFYAML::LineTable &LineTable);
};
-#define HANDLE_DW_TAG(unused, name) \
+template <> struct MappingTraits<DWARFYAML::InitialLength> {
+ static void mapping(IO &IO, DWARFYAML::InitialLength &DWARF);
+};
+
+#define HANDLE_DW_TAG(unused, name, unused2, unused3) \
io.enumCase(value, "DW_TAG_" #name, dwarf::DW_TAG_##name);
template <> struct ScalarEnumerationTraits<dwarf::Tag> {
static void enumeration(IO &io, dwarf::Tag &value) {
-#include "llvm/Support/Dwarf.def"
+#include "llvm/BinaryFormat/Dwarf.def"
io.enumFallback<Hex16>(value);
}
};
@@ -227,7 +250,7 @@ template <> struct ScalarEnumerationTraits<dwarf::Tag> {
template <> struct ScalarEnumerationTraits<dwarf::LineNumberOps> {
static void enumeration(IO &io, dwarf::LineNumberOps &value) {
-#include "llvm/Support/Dwarf.def"
+#include "llvm/BinaryFormat/Dwarf.def"
io.enumFallback<Hex8>(value);
}
};
@@ -237,31 +260,41 @@ template <> struct ScalarEnumerationTraits<dwarf::LineNumberOps> {
template <> struct ScalarEnumerationTraits<dwarf::LineNumberExtendedOps> {
static void enumeration(IO &io, dwarf::LineNumberExtendedOps &value) {
-#include "llvm/Support/Dwarf.def"
+#include "llvm/BinaryFormat/Dwarf.def"
io.enumFallback<Hex16>(value);
}
};
-#define HANDLE_DW_AT(unused, name) \
+#define HANDLE_DW_AT(unused, name, unused2, unused3) \
io.enumCase(value, "DW_AT_" #name, dwarf::DW_AT_##name);
template <> struct ScalarEnumerationTraits<dwarf::Attribute> {
static void enumeration(IO &io, dwarf::Attribute &value) {
-#include "llvm/Support/Dwarf.def"
+#include "llvm/BinaryFormat/Dwarf.def"
io.enumFallback<Hex16>(value);
}
};
-#define HANDLE_DW_FORM(unused, name) \
+#define HANDLE_DW_FORM(unused, name, unused2, unused3) \
io.enumCase(value, "DW_FORM_" #name, dwarf::DW_FORM_##name);
template <> struct ScalarEnumerationTraits<dwarf::Form> {
static void enumeration(IO &io, dwarf::Form &value) {
-#include "llvm/Support/Dwarf.def"
+#include "llvm/BinaryFormat/Dwarf.def"
io.enumFallback<Hex16>(value);
}
};
+#define HANDLE_DW_UT(unused, name) \
+ io.enumCase(value, "DW_UT_" #name, dwarf::DW_UT_##name);
+
+template <> struct ScalarEnumerationTraits<dwarf::UnitType> {
+ static void enumeration(IO &io, dwarf::UnitType &value) {
+#include "llvm/BinaryFormat/Dwarf.def"
+ io.enumFallback<Hex8>(value);
+ }
+};
+
template <> struct ScalarEnumerationTraits<dwarf::Constants> {
static void enumeration(IO &io, dwarf::Constants &value) {
io.enumCase(value, "DW_CHILDREN_no", dwarf::DW_CHILDREN_no);
@@ -270,7 +303,7 @@ template <> struct ScalarEnumerationTraits<dwarf::Constants> {
}
};
-} // namespace llvm::yaml
-} // namespace llvm
+} // end namespace yaml
+} // end namespace llvm
-#endif
+#endif // LLVM_OBJECTYAML_DWARFYAML_H
diff --git a/contrib/llvm/include/llvm/ObjectYAML/ELFYAML.h b/contrib/llvm/include/llvm/ObjectYAML/ELFYAML.h
index 81a4ec2..ed45531 100644
--- a/contrib/llvm/include/llvm/ObjectYAML/ELFYAML.h
+++ b/contrib/llvm/include/llvm/ObjectYAML/ELFYAML.h
@@ -16,8 +16,12 @@
#ifndef LLVM_OBJECTYAML_ELFYAML_H
#define LLVM_OBJECTYAML_ELFYAML_H
+#include "llvm/ADT/StringRef.h"
#include "llvm/ObjectYAML/YAML.h"
-#include "llvm/Support/ELF.h"
+#include "llvm/Support/YAMLTraits.h"
+#include <cstdint>
+#include <memory>
+#include <vector>
namespace llvm {
namespace ELFYAML {
@@ -66,6 +70,7 @@ struct FileHeader {
ELF_EF Flags;
llvm::yaml::Hex64 Entry;
};
+
struct Symbol {
StringRef Name;
ELF_STT Type;
@@ -74,6 +79,7 @@ struct Symbol {
llvm::yaml::Hex64 Size;
uint8_t Other;
};
+
struct LocalGlobalWeakSymbols {
std::vector<Symbol> Local;
std::vector<Symbol> Global;
@@ -100,13 +106,16 @@ struct Section {
StringRef Link;
StringRef Info;
llvm::yaml::Hex64 AddressAlign;
+
Section(SectionKind Kind) : Kind(Kind) {}
virtual ~Section();
};
struct RawContentSection : Section {
yaml::BinaryRef Content;
llvm::yaml::Hex64 Size;
+
RawContentSection() : Section(SectionKind::RawContent) {}
+
static bool classof(const Section *S) {
return S->Kind == SectionKind::RawContent;
}
@@ -114,7 +123,9 @@ struct RawContentSection : Section {
struct NoBitsSection : Section {
llvm::yaml::Hex64 Size;
+
NoBitsSection() : Section(SectionKind::NoBits) {}
+
static bool classof(const Section *S) {
return S->Kind == SectionKind::NoBits;
}
@@ -124,7 +135,9 @@ struct Group : Section {
// Members of a group contain a flag and a list of section indices
// that are part of the group.
std::vector<SectionOrType> Members;
+
Group() : Section(SectionKind::Group) {}
+
static bool classof(const Section *S) {
return S->Kind == SectionKind::Group;
}
@@ -136,9 +149,12 @@ struct Relocation {
ELF_REL Type;
StringRef Symbol;
};
+
struct RelocationSection : Section {
std::vector<Relocation> Relocations;
+
RelocationSection() : Section(SectionKind::Relocation) {}
+
static bool classof(const Section *S) {
return S->Kind == SectionKind::Relocation;
}
@@ -157,7 +173,9 @@ struct MipsABIFlags : Section {
MIPS_AFL_ASE ASEs;
MIPS_AFL_FLAGS1 Flags1;
llvm::yaml::Hex32 Flags2;
+
MipsABIFlags() : Section(SectionKind::MipsABIFlags) {}
+
static bool classof(const Section *S) {
return S->Kind == SectionKind::MipsABIFlags;
}
@@ -316,4 +334,4 @@ template <> struct MappingTraits<ELFYAML::SectionOrType> {
} // end namespace yaml
} // end namespace llvm
-#endif
+#endif // LLVM_OBJECTYAML_ELFYAML_H
diff --git a/contrib/llvm/include/llvm/ObjectYAML/MachOYAML.h b/contrib/llvm/include/llvm/ObjectYAML/MachOYAML.h
index 9ec32d2..305497b 100644
--- a/contrib/llvm/include/llvm/ObjectYAML/MachOYAML.h
+++ b/contrib/llvm/include/llvm/ObjectYAML/MachOYAML.h
@@ -16,9 +16,13 @@
#ifndef LLVM_OBJECTYAML_MACHOYAML_H
#define LLVM_OBJECTYAML_MACHOYAML_H
-#include "llvm/ObjectYAML/YAML.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/BinaryFormat/MachO.h"
#include "llvm/ObjectYAML/DWARFYAML.h"
-#include "llvm/Support/MachO.h"
+#include "llvm/Support/YAMLTraits.h"
+#include <cstdint>
+#include <string>
+#include <vector>
namespace llvm {
namespace MachOYAML {
@@ -51,8 +55,10 @@ struct FileHeader {
struct LoadCommand {
virtual ~LoadCommand();
+
llvm::MachO::macho_load_command Data;
std::vector<Section> Sections;
+ std::vector<MachO::build_tool_version> Tools;
std::vector<llvm::yaml::Hex8> PayloadBytes;
std::string PayloadString;
uint64_t ZeroPadBytes;
@@ -65,6 +71,7 @@ struct NListEntry {
uint16_t n_desc;
uint64_t n_value;
};
+
struct RebaseOpcode {
MachO::RebaseOpcode Opcode;
uint8_t Imm;
@@ -80,15 +87,12 @@ struct BindOpcode {
};
struct ExportEntry {
- ExportEntry()
- : TerminalSize(0), NodeOffset(0), Name(), Flags(0), Address(0), Other(0),
- ImportName(), Children() {}
- uint64_t TerminalSize;
- uint64_t NodeOffset;
+ uint64_t TerminalSize = 0;
+ uint64_t NodeOffset = 0;
std::string Name;
- llvm::yaml::Hex64 Flags;
- llvm::yaml::Hex64 Address;
- llvm::yaml::Hex64 Other;
+ llvm::yaml::Hex64 Flags = 0;
+ llvm::yaml::Hex64 Address = 0;
+ llvm::yaml::Hex64 Other = 0;
std::string ImportName;
std::vector<MachOYAML::ExportEntry> Children;
};
@@ -134,20 +138,23 @@ struct UniversalBinary {
std::vector<Object> Slices;
};
-} // namespace llvm::MachOYAML
-} // namespace llvm
+} // end namespace MachOYAML
+} // end namespace llvm
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::LoadCommand)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::Section)
-LLVM_YAML_IS_SEQUENCE_VECTOR(int64_t)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::RebaseOpcode)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::BindOpcode)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::ExportEntry)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::NListEntry)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::Object)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::FatArch)
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachO::build_tool_version)
namespace llvm {
+
+class raw_ostream;
+
namespace yaml {
template <> struct MappingTraits<MachOYAML::FileHeader> {
@@ -198,12 +205,16 @@ template <> struct MappingTraits<MachOYAML::NListEntry> {
static void mapping(IO &IO, MachOYAML::NListEntry &NListEntry);
};
+template <> struct MappingTraits<MachO::build_tool_version> {
+ static void mapping(IO &IO, MachO::build_tool_version &tool);
+};
+
#define HANDLE_LOAD_COMMAND(LCName, LCValue, LCStruct) \
io.enumCase(value, #LCName, MachO::LCName);
template <> struct ScalarEnumerationTraits<MachO::LoadCommandType> {
static void enumeration(IO &io, MachO::LoadCommandType &value) {
-#include "llvm/Support/MachO.def"
+#include "llvm/BinaryFormat/MachO.def"
io.enumFallback<Hex32>(value);
}
};
@@ -245,22 +256,20 @@ template <> struct ScalarEnumerationTraits<MachO::BindOpcode> {
};
// This trait is used for 16-byte chars in Mach structures used for strings
-typedef char char_16[16];
+using char_16 = char[16];
template <> struct ScalarTraits<char_16> {
- static void output(const char_16 &Val, void *, llvm::raw_ostream &Out);
-
+ static void output(const char_16 &Val, void *, raw_ostream &Out);
static StringRef input(StringRef Scalar, void *, char_16 &Val);
static bool mustQuote(StringRef S);
};
// This trait is used for UUIDs. It reads and writes them matching otool's
// formatting style.
-typedef uint8_t uuid_t[16];
+using uuid_t = uint8_t[16];
template <> struct ScalarTraits<uuid_t> {
- static void output(const uuid_t &Val, void *, llvm::raw_ostream &Out);
-
+ static void output(const uuid_t &Val, void *, raw_ostream &Out);
static StringRef input(StringRef Scalar, void *, uuid_t &Val);
static bool mustQuote(StringRef S);
};
@@ -272,7 +281,7 @@ template <> struct ScalarTraits<uuid_t> {
static void mapping(IO &IO, MachO::LCStruct &LoadCommand); \
};
-#include "llvm/Support/MachO.def"
+#include "llvm/BinaryFormat/MachO.def"
// Extra structures used by load commands
template <> struct MappingTraits<MachO::dylib> {
@@ -291,8 +300,8 @@ template <> struct MappingTraits<MachO::section_64> {
static void mapping(IO &IO, MachO::section_64 &LoadCommand);
};
-} // namespace llvm::yaml
+} // end namespace yaml
-} // namespace llvm
+} // end namespace llvm
-#endif
+#endif // LLVM_OBJECTYAML_MACHOYAML_H
diff --git a/contrib/llvm/include/llvm/ObjectYAML/ObjectYAML.h b/contrib/llvm/include/llvm/ObjectYAML/ObjectYAML.h
index 1d64623..00ce864 100644
--- a/contrib/llvm/include/llvm/ObjectYAML/ObjectYAML.h
+++ b/contrib/llvm/include/llvm/ObjectYAML/ObjectYAML.h
@@ -10,26 +10,31 @@
#ifndef LLVM_OBJECTYAML_OBJECTYAML_H
#define LLVM_OBJECTYAML_OBJECTYAML_H
-#include "llvm/Support/YAMLTraits.h"
-#include "llvm/ObjectYAML/ELFYAML.h"
#include "llvm/ObjectYAML/COFFYAML.h"
+#include "llvm/ObjectYAML/ELFYAML.h"
#include "llvm/ObjectYAML/MachOYAML.h"
+#include "llvm/ObjectYAML/WasmYAML.h"
+#include "llvm/Support/YAMLTraits.h"
+#include <memory>
namespace llvm {
namespace yaml {
+class IO;
+
struct YamlObjectFile {
std::unique_ptr<ELFYAML::Object> Elf;
std::unique_ptr<COFFYAML::Object> Coff;
std::unique_ptr<MachOYAML::Object> MachO;
std::unique_ptr<MachOYAML::UniversalBinary> FatMachO;
+ std::unique_ptr<WasmYAML::Object> Wasm;
};
template <> struct MappingTraits<YamlObjectFile> {
static void mapping(IO &IO, YamlObjectFile &ObjectFile);
};
-} // namespace yaml
-} // namespace llvm
+} // end namespace yaml
+} // end namespace llvm
-#endif
+#endif // LLVM_OBJECTYAML_OBJECTYAML_H
diff --git a/contrib/llvm/include/llvm/ObjectYAML/WasmYAML.h b/contrib/llvm/include/llvm/ObjectYAML/WasmYAML.h
new file mode 100644
index 0000000..709ad8e
--- /dev/null
+++ b/contrib/llvm/include/llvm/ObjectYAML/WasmYAML.h
@@ -0,0 +1,400 @@
+//===- WasmYAML.h - Wasm YAMLIO implementation ------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief This file declares classes for handling the YAML representation
+/// of wasm binaries.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECTYAML_WASMYAML_H
+#define LLVM_OBJECTYAML_WASMYAML_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/BinaryFormat/Wasm.h"
+#include "llvm/ObjectYAML/YAML.h"
+#include "llvm/Support/Casting.h"
+#include <cstdint>
+#include <memory>
+#include <vector>
+
+namespace llvm {
+namespace WasmYAML {
+
+LLVM_YAML_STRONG_TYPEDEF(uint32_t, SectionType)
+LLVM_YAML_STRONG_TYPEDEF(int32_t, ValueType)
+LLVM_YAML_STRONG_TYPEDEF(int32_t, TableType)
+LLVM_YAML_STRONG_TYPEDEF(int32_t, SignatureForm)
+LLVM_YAML_STRONG_TYPEDEF(uint32_t, ExportKind)
+LLVM_YAML_STRONG_TYPEDEF(uint32_t, Opcode)
+LLVM_YAML_STRONG_TYPEDEF(uint32_t, RelocType)
+
+struct FileHeader {
+ yaml::Hex32 Version;
+};
+
+struct Limits {
+ yaml::Hex32 Flags;
+ yaml::Hex32 Initial;
+ yaml::Hex32 Maximum;
+};
+
+struct Table {
+ TableType ElemType;
+ Limits TableLimits;
+};
+
+struct Export {
+ StringRef Name;
+ ExportKind Kind;
+ uint32_t Index;
+};
+
+struct ElemSegment {
+ uint32_t TableIndex;
+ wasm::WasmInitExpr Offset;
+ std::vector<uint32_t> Functions;
+};
+
+struct Global {
+ ValueType Type;
+ bool Mutable;
+ wasm::WasmInitExpr InitExpr;
+};
+
+struct Import {
+ StringRef Module;
+ StringRef Field;
+ ExportKind Kind;
+ union {
+ uint32_t SigIndex;
+ Global GlobalImport;
+ Table TableImport;
+ Limits Memory;
+ };
+};
+
+struct LocalDecl {
+ ValueType Type;
+ uint32_t Count;
+};
+
+struct Function {
+ std::vector<LocalDecl> Locals;
+ yaml::BinaryRef Body;
+};
+
+struct Relocation {
+ RelocType Type;
+ uint32_t Index;
+ yaml::Hex32 Offset;
+ int32_t Addend;
+};
+
+struct DataSegment {
+ uint32_t MemoryIndex;
+ uint32_t SectionOffset;
+ wasm::WasmInitExpr Offset;
+ yaml::BinaryRef Content;
+};
+
+struct NameEntry {
+ uint32_t Index;
+ StringRef Name;
+};
+
+struct Signature {
+ uint32_t Index;
+ SignatureForm Form = wasm::WASM_TYPE_FUNC;
+ std::vector<ValueType> ParamTypes;
+ ValueType ReturnType;
+};
+
+struct SymbolInfo {
+ StringRef Name;
+ uint32_t Flags;
+};
+
+struct Section {
+ explicit Section(SectionType SecType) : Type(SecType) {}
+ virtual ~Section();
+
+ SectionType Type;
+ std::vector<Relocation> Relocations;
+};
+
+struct CustomSection : Section {
+ explicit CustomSection(StringRef Name)
+ : Section(wasm::WASM_SEC_CUSTOM), Name(Name) {}
+
+ static bool classof(const Section *S) {
+ return S->Type == wasm::WASM_SEC_CUSTOM;
+ }
+
+ StringRef Name;
+ yaml::BinaryRef Payload;
+};
+
+struct NameSection : CustomSection {
+ NameSection() : CustomSection("name") {}
+
+ static bool classof(const Section *S) {
+ auto C = dyn_cast<CustomSection>(S);
+ return C && C->Name == "name";
+ }
+
+ std::vector<NameEntry> FunctionNames;
+};
+
+struct LinkingSection : CustomSection {
+ LinkingSection() : CustomSection("linking") {}
+
+ static bool classof(const Section *S) {
+ auto C = dyn_cast<CustomSection>(S);
+ return C && C->Name == "linking";
+ }
+
+ std::vector<SymbolInfo> SymbolInfos;
+ uint32_t DataSize;
+ uint32_t DataAlignment;
+};
+
+struct TypeSection : Section {
+ TypeSection() : Section(wasm::WASM_SEC_TYPE) {}
+
+ static bool classof(const Section *S) {
+ return S->Type == wasm::WASM_SEC_TYPE;
+ }
+
+ std::vector<Signature> Signatures;
+};
+
+struct ImportSection : Section {
+ ImportSection() : Section(wasm::WASM_SEC_IMPORT) {}
+
+ static bool classof(const Section *S) {
+ return S->Type == wasm::WASM_SEC_IMPORT;
+ }
+
+ std::vector<Import> Imports;
+};
+
+struct FunctionSection : Section {
+ FunctionSection() : Section(wasm::WASM_SEC_FUNCTION) {}
+
+ static bool classof(const Section *S) {
+ return S->Type == wasm::WASM_SEC_FUNCTION;
+ }
+
+ std::vector<uint32_t> FunctionTypes;
+};
+
+struct TableSection : Section {
+ TableSection() : Section(wasm::WASM_SEC_TABLE) {}
+
+ static bool classof(const Section *S) {
+ return S->Type == wasm::WASM_SEC_TABLE;
+ }
+
+ std::vector<Table> Tables;
+};
+
+struct MemorySection : Section {
+ MemorySection() : Section(wasm::WASM_SEC_MEMORY) {}
+
+ static bool classof(const Section *S) {
+ return S->Type == wasm::WASM_SEC_MEMORY;
+ }
+
+ std::vector<Limits> Memories;
+};
+
+struct GlobalSection : Section {
+ GlobalSection() : Section(wasm::WASM_SEC_GLOBAL) {}
+
+ static bool classof(const Section *S) {
+ return S->Type == wasm::WASM_SEC_GLOBAL;
+ }
+
+ std::vector<Global> Globals;
+};
+
+struct ExportSection : Section {
+ ExportSection() : Section(wasm::WASM_SEC_EXPORT) {}
+
+ static bool classof(const Section *S) {
+ return S->Type == wasm::WASM_SEC_EXPORT;
+ }
+
+ std::vector<Export> Exports;
+};
+
+struct StartSection : Section {
+ StartSection() : Section(wasm::WASM_SEC_START) {}
+
+ static bool classof(const Section *S) {
+ return S->Type == wasm::WASM_SEC_START;
+ }
+
+ uint32_t StartFunction;
+};
+
+struct ElemSection : Section {
+ ElemSection() : Section(wasm::WASM_SEC_ELEM) {}
+
+ static bool classof(const Section *S) {
+ return S->Type == wasm::WASM_SEC_ELEM;
+ }
+
+ std::vector<ElemSegment> Segments;
+};
+
+struct CodeSection : Section {
+ CodeSection() : Section(wasm::WASM_SEC_CODE) {}
+
+ static bool classof(const Section *S) {
+ return S->Type == wasm::WASM_SEC_CODE;
+ }
+
+ std::vector<Function> Functions;
+};
+
+struct DataSection : Section {
+ DataSection() : Section(wasm::WASM_SEC_DATA) {}
+
+ static bool classof(const Section *S) {
+ return S->Type == wasm::WASM_SEC_DATA;
+ }
+
+ std::vector<DataSegment> Segments;
+};
+
+struct Object {
+ FileHeader Header;
+ std::vector<std::unique_ptr<Section>> Sections;
+};
+
+} // end namespace WasmYAML
+} // end namespace llvm
+
+LLVM_YAML_IS_SEQUENCE_VECTOR(std::unique_ptr<llvm::WasmYAML::Section>)
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Signature)
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::ValueType)
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Table)
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Import)
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Export)
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::ElemSegment)
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Limits)
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::DataSegment)
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Global)
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Function)
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::LocalDecl)
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Relocation)
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::NameEntry)
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::SymbolInfo)
+
+namespace llvm {
+namespace yaml {
+
+template <> struct MappingTraits<WasmYAML::FileHeader> {
+ static void mapping(IO &IO, WasmYAML::FileHeader &FileHdr);
+};
+
+template <> struct MappingTraits<std::unique_ptr<WasmYAML::Section>> {
+ static void mapping(IO &IO, std::unique_ptr<WasmYAML::Section> &Section);
+};
+
+template <> struct MappingTraits<WasmYAML::Object> {
+ static void mapping(IO &IO, WasmYAML::Object &Object);
+};
+
+template <> struct MappingTraits<WasmYAML::Import> {
+ static void mapping(IO &IO, WasmYAML::Import &Import);
+};
+
+template <> struct MappingTraits<WasmYAML::Export> {
+ static void mapping(IO &IO, WasmYAML::Export &Export);
+};
+
+template <> struct MappingTraits<WasmYAML::Global> {
+ static void mapping(IO &IO, WasmYAML::Global &Global);
+};
+
+template <> struct ScalarEnumerationTraits<WasmYAML::SectionType> {
+ static void enumeration(IO &IO, WasmYAML::SectionType &Type);
+};
+
+template <> struct MappingTraits<WasmYAML::Signature> {
+ static void mapping(IO &IO, WasmYAML::Signature &Signature);
+};
+
+template <> struct MappingTraits<WasmYAML::Table> {
+ static void mapping(IO &IO, WasmYAML::Table &Table);
+};
+
+template <> struct MappingTraits<WasmYAML::Limits> {
+ static void mapping(IO &IO, WasmYAML::Limits &Limits);
+};
+
+template <> struct MappingTraits<WasmYAML::Function> {
+ static void mapping(IO &IO, WasmYAML::Function &Function);
+};
+
+template <> struct MappingTraits<WasmYAML::Relocation> {
+ static void mapping(IO &IO, WasmYAML::Relocation &Relocation);
+};
+
+template <> struct MappingTraits<WasmYAML::NameEntry> {
+ static void mapping(IO &IO, WasmYAML::NameEntry &NameEntry);
+};
+
+template <> struct MappingTraits<WasmYAML::LocalDecl> {
+ static void mapping(IO &IO, WasmYAML::LocalDecl &LocalDecl);
+};
+
+template <> struct MappingTraits<wasm::WasmInitExpr> {
+ static void mapping(IO &IO, wasm::WasmInitExpr &Expr);
+};
+
+template <> struct MappingTraits<WasmYAML::DataSegment> {
+ static void mapping(IO &IO, WasmYAML::DataSegment &Segment);
+};
+
+template <> struct MappingTraits<WasmYAML::ElemSegment> {
+ static void mapping(IO &IO, WasmYAML::ElemSegment &Segment);
+};
+
+template <> struct MappingTraits<WasmYAML::SymbolInfo> {
+ static void mapping(IO &IO, WasmYAML::SymbolInfo &Info);
+};
+
+template <> struct ScalarEnumerationTraits<WasmYAML::ValueType> {
+ static void enumeration(IO &IO, WasmYAML::ValueType &Type);
+};
+
+template <> struct ScalarEnumerationTraits<WasmYAML::ExportKind> {
+ static void enumeration(IO &IO, WasmYAML::ExportKind &Kind);
+};
+
+template <> struct ScalarEnumerationTraits<WasmYAML::TableType> {
+ static void enumeration(IO &IO, WasmYAML::TableType &Type);
+};
+
+template <> struct ScalarEnumerationTraits<WasmYAML::Opcode> {
+ static void enumeration(IO &IO, WasmYAML::Opcode &Opcode);
+};
+
+template <> struct ScalarEnumerationTraits<WasmYAML::RelocType> {
+ static void enumeration(IO &IO, WasmYAML::RelocType &Kind);
+};
+
+} // end namespace yaml
+} // end namespace llvm
+
+#endif // LLVM_OBJECTYAML_WASMYAML_H
diff --git a/contrib/llvm/include/llvm/ObjectYAML/YAML.h b/contrib/llvm/include/llvm/ObjectYAML/YAML.h
index 7f68368..29151a2 100644
--- a/contrib/llvm/include/llvm/ObjectYAML/YAML.h
+++ b/contrib/llvm/include/llvm/ObjectYAML/YAML.h
@@ -10,10 +10,17 @@
#ifndef LLVM_OBJECTYAML_YAML_H
#define LLVM_OBJECTYAML_YAML_H
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/Support/YAMLTraits.h"
+#include <cstdint>
namespace llvm {
+
+class raw_ostream;
+
namespace yaml {
+
/// \brief Specialized YAMLIO scalar type for representing a binary blob.
///
/// A typical use case would be to represent the content of a section in a
@@ -56,18 +63,20 @@ namespace yaml {
/// \endcode
class BinaryRef {
friend bool operator==(const BinaryRef &LHS, const BinaryRef &RHS);
+
/// \brief Either raw binary data, or a string of hex bytes (must always
/// be an even number of characters).
ArrayRef<uint8_t> Data;
+
/// \brief Discriminator between the two states of the `Data` member.
- bool DataIsHexString;
+ bool DataIsHexString = true;
public:
+ BinaryRef() = default;
BinaryRef(ArrayRef<uint8_t> Data) : Data(Data), DataIsHexString(false) {}
BinaryRef(StringRef Data)
- : Data(reinterpret_cast<const uint8_t *>(Data.data()), Data.size()),
- DataIsHexString(true) {}
- BinaryRef() : DataIsHexString(true) {}
+ : Data(reinterpret_cast<const uint8_t *>(Data.data()), Data.size()) {}
+
/// \brief The number of bytes that are represented by this BinaryRef.
/// This is the number of bytes that writeAsBinary() will write.
ArrayRef<uint8_t>::size_type binary_size() const {
@@ -75,9 +84,11 @@ public:
return Data.size() / 2;
return Data.size();
}
+
/// \brief Write the contents (regardless of whether it is binary or a
/// hex string) as binary to the given raw_ostream.
void writeAsBinary(raw_ostream &OS) const;
+
/// \brief Write the contents (regardless of whether it is binary or a
/// hex string) as hex to the given raw_ostream.
///
@@ -94,10 +105,13 @@ inline bool operator==(const BinaryRef &LHS, const BinaryRef &RHS) {
}
template <> struct ScalarTraits<BinaryRef> {
- static void output(const BinaryRef &, void *, llvm::raw_ostream &);
+ static void output(const BinaryRef &, void *, raw_ostream &);
static StringRef input(StringRef, void *, BinaryRef &);
static bool mustQuote(StringRef S) { return needsQuotes(S); }
};
-}
-}
-#endif
+
+} // end namespace yaml
+
+} // end namespace llvm
+
+#endif // LLVM_OBJECTYAML_YAML_H
diff --git a/contrib/llvm/include/llvm/Option/Arg.h b/contrib/llvm/include/llvm/Option/Arg.h
index 99d3296..c519a4a 100644
--- a/contrib/llvm/include/llvm/Option/Arg.h
+++ b/contrib/llvm/include/llvm/Option/Arg.h
@@ -1,4 +1,4 @@
-//===--- Arg.h - Parsed Argument Classes ------------------------*- C++ -*-===//
+//===- Arg.h - Parsed Argument Classes --------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -21,7 +21,11 @@
#include <string>
namespace llvm {
+
+class raw_ostream;
+
namespace opt {
+
class ArgList;
/// \brief A concrete instance of a particular driver option.
@@ -29,9 +33,6 @@ class ArgList;
/// The Arg class encodes just enough information to be able to
/// derive the argument values efficiently.
class Arg {
- Arg(const Arg &) = delete;
- void operator=(const Arg &) = delete;
-
private:
/// \brief The option this argument is an instance of.
const Option Opt;
@@ -65,6 +66,8 @@ public:
const char *Value0, const Arg *BaseArg = nullptr);
Arg(const Option Opt, StringRef Spelling, unsigned Index,
const char *Value0, const char *Value1, const Arg *BaseArg = nullptr);
+ Arg(const Arg &) = delete;
+ Arg &operator=(const Arg &) = delete;
~Arg();
const Option &getOption() const { return Opt; }
@@ -89,6 +92,7 @@ public:
void claim() const { getBaseArg().Claimed = true; }
unsigned getNumValues() const { return Values.size(); }
+
const char *getValue(unsigned N = 0) const {
return Values[N];
}
@@ -122,6 +126,7 @@ public:
};
} // end namespace opt
+
} // end namespace llvm
-#endif
+#endif // LLVM_OPTION_ARG_H
diff --git a/contrib/llvm/include/llvm/Option/ArgList.h b/contrib/llvm/include/llvm/Option/ArgList.h
index 53cb0d8..aaea68b 100644
--- a/contrib/llvm/include/llvm/Option/ArgList.h
+++ b/contrib/llvm/include/llvm/Option/ArgList.h
@@ -1,4 +1,4 @@
-//===--- ArgList.h - Argument List Management -------------------*- C++ -*-===//
+//===- ArgList.h - Argument List Management ---------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -10,58 +10,84 @@
#ifndef LLVM_OPTION_ARGLIST_H
#define LLVM_OPTION_ARGLIST_H
-#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/iterator_range.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Option/Arg.h"
#include "llvm/Option/OptSpecifier.h"
#include "llvm/Option/Option.h"
+#include <algorithm>
+#include <cstddef>
+#include <initializer_list>
+#include <iterator>
#include <list>
#include <memory>
#include <string>
+#include <utility>
#include <vector>
namespace llvm {
+
+class raw_ostream;
+
namespace opt {
-class ArgList;
-class Option;
/// arg_iterator - Iterates through arguments stored inside an ArgList.
+template<typename BaseIter, unsigned NumOptSpecifiers = 0>
class arg_iterator {
- /// The current argument.
- SmallVectorImpl<Arg*>::const_iterator Current;
-
- /// The argument list we are iterating over.
- const ArgList &Args;
-
- /// Optional filters on the arguments which will be match. Most clients
- /// should never want to iterate over arguments without filters, so we won't
- /// bother to factor this into two separate iterator implementations.
- //
- // FIXME: Make efficient; the idea is to provide efficient iteration over
- // all arguments which match a particular id and then just provide an
- // iterator combinator which takes multiple iterators which can be
- // efficiently compared and returns them in order.
- OptSpecifier Id0, Id1, Id2;
+ /// The current argument and the end of the sequence we're iterating.
+ BaseIter Current, End;
+
+ /// Optional filters on the arguments which will be match. To avoid a
+ /// zero-sized array, we store one specifier even if we're asked for none.
+ OptSpecifier Ids[NumOptSpecifiers ? NumOptSpecifiers : 1];
+
+ void SkipToNextArg() {
+ for (; Current != End; ++Current) {
+ // Skip erased elements.
+ if (!*Current)
+ continue;
+
+ // Done if there are no filters.
+ if (!NumOptSpecifiers)
+ return;
+
+ // Otherwise require a match.
+ const Option &O = (*Current)->getOption();
+ for (auto Id : Ids) {
+ if (!Id.isValid())
+ break;
+ if (O.matches(Id))
+ return;
+ }
+ }
+ }
- void SkipToNextArg();
+ using Traits = std::iterator_traits<BaseIter>;
public:
- typedef Arg * const * value_type;
- typedef Arg * const & reference;
- typedef Arg * const * pointer;
- typedef std::forward_iterator_tag iterator_category;
- typedef std::ptrdiff_t difference_type;
-
- arg_iterator(SmallVectorImpl<Arg *>::const_iterator it, const ArgList &Args,
- OptSpecifier Id0 = 0U, OptSpecifier Id1 = 0U,
- OptSpecifier Id2 = 0U)
- : Current(it), Args(Args), Id0(Id0), Id1(Id1), Id2(Id2) {
+ using value_type = typename Traits::value_type;
+ using reference = typename Traits::reference;
+ using pointer = typename Traits::pointer;
+ using iterator_category = std::forward_iterator_tag;
+ using difference_type = std::ptrdiff_t;
+
+ arg_iterator(
+ BaseIter Current, BaseIter End,
+ const OptSpecifier (&Ids)[NumOptSpecifiers ? NumOptSpecifiers : 1] = {})
+ : Current(Current), End(End) {
+ for (unsigned I = 0; I != NumOptSpecifiers; ++I)
+ this->Ids[I] = Ids[I];
SkipToNextArg();
}
+ // FIXME: This conversion function makes no sense.
operator const Arg*() { return *Current; }
+
reference operator*() const { return *Current; }
pointer operator->() const { return Current; }
@@ -93,44 +119,71 @@ public:
/// and to iterate over groups of arguments.
class ArgList {
public:
- typedef SmallVector<Arg*, 16> arglist_type;
- typedef arglist_type::iterator iterator;
- typedef arglist_type::const_iterator const_iterator;
- typedef arglist_type::reverse_iterator reverse_iterator;
- typedef arglist_type::const_reverse_iterator const_reverse_iterator;
+ using arglist_type = SmallVector<Arg *, 16>;
+ using iterator = arg_iterator<arglist_type::iterator>;
+ using const_iterator = arg_iterator<arglist_type::const_iterator>;
+ using reverse_iterator = arg_iterator<arglist_type::reverse_iterator>;
+ using const_reverse_iterator =
+ arg_iterator<arglist_type::const_reverse_iterator>;
+
+ template<unsigned N> using filtered_iterator =
+ arg_iterator<arglist_type::const_iterator, N>;
+ template<unsigned N> using filtered_reverse_iterator =
+ arg_iterator<arglist_type::const_reverse_iterator, N>;
private:
/// The internal list of arguments.
arglist_type Args;
+ using OptRange = std::pair<unsigned, unsigned>;
+ static OptRange emptyRange() { return {-1u, 0u}; }
+
+ /// The first and last index of each different OptSpecifier ID.
+ DenseMap<unsigned, OptRange> OptRanges;
+
+ /// Get the range of indexes in which options with the specified IDs might
+ /// reside, or (0, 0) if there are no such options.
+ OptRange getRange(std::initializer_list<OptSpecifier> Ids) const;
+
protected:
// Make the default special members protected so they won't be used to slice
// derived objects, but can still be used by derived objects to implement
// their own special members.
ArgList() = default;
+
// Explicit move operations to ensure the container is cleared post-move
// otherwise it could lead to a double-delete in the case of moving of an
// InputArgList which deletes the contents of the container. If we could fix
// up the ownership here (delegate storage/ownership to the derived class so
// it can be a container of unique_ptr) this would be simpler.
- ArgList(ArgList &&RHS) : Args(std::move(RHS.Args)) { RHS.Args.clear(); }
+ ArgList(ArgList &&RHS)
+ : Args(std::move(RHS.Args)), OptRanges(std::move(RHS.OptRanges)) {
+ RHS.Args.clear();
+ RHS.OptRanges.clear();
+ }
+
ArgList &operator=(ArgList &&RHS) {
Args = std::move(RHS.Args);
RHS.Args.clear();
+ OptRanges = std::move(RHS.OptRanges);
+ RHS.OptRanges.clear();
return *this;
}
+
// Protect the dtor to ensure this type is never destroyed polymorphically.
~ArgList() = default;
-public:
+ // Implicitly convert a value to an OptSpecifier. Used to work around a bug
+ // in MSVC's implementation of narrowing conversion checking.
+ static OptSpecifier toOptSpecifier(OptSpecifier S) { return S; }
+public:
/// @name Arg Access
/// @{
/// append - Append \p A to the arg list.
void append(Arg *A);
- arglist_type &getArgs() { return Args; }
const arglist_type &getArgs() const { return Args; }
unsigned size() const { return Args.size(); }
@@ -139,30 +192,38 @@ public:
/// @name Arg Iteration
/// @{
- iterator begin() { return Args.begin(); }
- iterator end() { return Args.end(); }
+ iterator begin() { return {Args.begin(), Args.end()}; }
+ iterator end() { return {Args.end(), Args.end()}; }
- reverse_iterator rbegin() { return Args.rbegin(); }
- reverse_iterator rend() { return Args.rend(); }
+ reverse_iterator rbegin() { return {Args.rbegin(), Args.rend()}; }
+ reverse_iterator rend() { return {Args.rend(), Args.rend()}; }
- const_iterator begin() const { return Args.begin(); }
- const_iterator end() const { return Args.end(); }
+ const_iterator begin() const { return {Args.begin(), Args.end()}; }
+ const_iterator end() const { return {Args.end(), Args.end()}; }
- const_reverse_iterator rbegin() const { return Args.rbegin(); }
- const_reverse_iterator rend() const { return Args.rend(); }
+ const_reverse_iterator rbegin() const { return {Args.rbegin(), Args.rend()}; }
+ const_reverse_iterator rend() const { return {Args.rend(), Args.rend()}; }
- arg_iterator filtered_begin(OptSpecifier Id0 = 0U, OptSpecifier Id1 = 0U,
- OptSpecifier Id2 = 0U) const {
- return arg_iterator(Args.begin(), *this, Id0, Id1, Id2);
- }
- arg_iterator filtered_end() const {
- return arg_iterator(Args.end(), *this);
+ template<typename ...OptSpecifiers>
+ iterator_range<filtered_iterator<sizeof...(OptSpecifiers)>>
+ filtered(OptSpecifiers ...Ids) const {
+ OptRange Range = getRange({toOptSpecifier(Ids)...});
+ auto B = Args.begin() + Range.first;
+ auto E = Args.begin() + Range.second;
+ using Iterator = filtered_iterator<sizeof...(OptSpecifiers)>;
+ return make_range(Iterator(B, E, {toOptSpecifier(Ids)...}),
+ Iterator(E, E, {toOptSpecifier(Ids)...}));
}
- iterator_range<arg_iterator> filtered(OptSpecifier Id0 = 0U,
- OptSpecifier Id1 = 0U,
- OptSpecifier Id2 = 0U) const {
- return make_range(filtered_begin(Id0, Id1, Id2), filtered_end());
+ template<typename ...OptSpecifiers>
+ iterator_range<filtered_reverse_iterator<sizeof...(OptSpecifiers)>>
+ filtered_reverse(OptSpecifiers ...Ids) const {
+ OptRange Range = getRange({toOptSpecifier(Ids)...});
+ auto B = Args.rend() - Range.second;
+ auto E = Args.rend() - Range.first;
+ using Iterator = filtered_reverse_iterator<sizeof...(OptSpecifiers)>;
+ return make_range(Iterator(B, E, {toOptSpecifier(Ids)...}),
+ Iterator(E, E, {toOptSpecifier(Ids)...}));
}
/// @}
@@ -179,43 +240,34 @@ public:
/// hasArg - Does the arg list contain any option matching \p Id.
///
/// \p Claim Whether the argument should be claimed, if it exists.
- bool hasArgNoClaim(OptSpecifier Id) const {
- return getLastArgNoClaim(Id) != nullptr;
- }
- bool hasArg(OptSpecifier Id) const {
- return getLastArg(Id) != nullptr;
+ template<typename ...OptSpecifiers>
+ bool hasArgNoClaim(OptSpecifiers ...Ids) const {
+ return getLastArgNoClaim(Ids...) != nullptr;
}
- bool hasArg(OptSpecifier Id0, OptSpecifier Id1) const {
- return getLastArg(Id0, Id1) != nullptr;
+ template<typename ...OptSpecifiers>
+ bool hasArg(OptSpecifiers ...Ids) const {
+ return getLastArg(Ids...) != nullptr;
}
- bool hasArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2) const {
- return getLastArg(Id0, Id1, Id2) != nullptr;
+
+ /// Return the last argument matching \p Id, or null.
+ template<typename ...OptSpecifiers>
+ Arg *getLastArg(OptSpecifiers ...Ids) const {
+ Arg *Res = nullptr;
+ for (Arg *A : filtered(Ids...)) {
+ Res = A;
+ Res->claim();
+ }
+ return Res;
}
- /// getLastArg - Return the last argument matching \p Id, or null.
- ///
- /// \p Claim Whether the argument should be claimed, if it exists.
- Arg *getLastArgNoClaim(OptSpecifier Id) const;
- Arg *getLastArgNoClaim(OptSpecifier Id0, OptSpecifier Id1) const;
- Arg *getLastArgNoClaim(OptSpecifier Id0, OptSpecifier Id1,
- OptSpecifier Id2) const;
- Arg *getLastArgNoClaim(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2,
- OptSpecifier Id3) const;
- Arg *getLastArg(OptSpecifier Id) const;
- Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1) const;
- Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2) const;
- Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2,
- OptSpecifier Id3) const;
- Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2,
- OptSpecifier Id3, OptSpecifier Id4) const;
- Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2,
- OptSpecifier Id3, OptSpecifier Id4, OptSpecifier Id5) const;
- Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2,
- OptSpecifier Id3, OptSpecifier Id4, OptSpecifier Id5,
- OptSpecifier Id6) const;
- Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2,
- OptSpecifier Id3, OptSpecifier Id4, OptSpecifier Id5,
- OptSpecifier Id6, OptSpecifier Id7) const;
+ /// Return the last argument matching \p Id, or null. Do not "claim" the
+ /// option (don't mark it as having been used).
+ template<typename ...OptSpecifiers>
+ Arg *getLastArgNoClaim(OptSpecifiers ...Ids) const {
+ for (Arg *A : filtered_reverse(Ids...))
+ return A;
+ return nullptr;
+ }
/// getArgString - Return the input argument string at \p Index.
virtual const char *getArgString(unsigned Index) const = 0;
@@ -230,8 +282,7 @@ public:
/// @{
/// getLastArgValue - Return the value of the last argument, or a default.
- StringRef getLastArgValue(OptSpecifier Id,
- StringRef Default = "") const;
+ StringRef getLastArgValue(OptSpecifier Id, StringRef Default = "") const;
/// getAllArgValues - Get the values of all instances of the given argument
/// as strings.
@@ -273,7 +324,7 @@ public:
/// AddAllArgValues - Render the argument values of all arguments
/// matching the given ids.
void AddAllArgValues(ArgStringList &Output, OptSpecifier Id0,
- OptSpecifier Id1 = 0U, OptSpecifier Id2 = 0U) const;
+ OptSpecifier Id1 = 0U, OptSpecifier Id2 = 0U) const;
/// AddAllArgsTranslated - Render all the arguments matching the
/// given ids, but forced to separate args and using the provided
@@ -340,10 +391,12 @@ private:
public:
InputArgList(const char* const *ArgBegin, const char* const *ArgEnd);
+
InputArgList(InputArgList &&RHS)
: ArgList(std::move(RHS)), ArgStrings(std::move(RHS.ArgStrings)),
SynthesizedStrings(std::move(RHS.SynthesizedStrings)),
NumInputArgStrings(RHS.NumInputArgStrings) {}
+
InputArgList &operator=(InputArgList &&RHS) {
releaseMemory();
ArgList::operator=(std::move(RHS));
@@ -352,6 +405,7 @@ public:
NumInputArgStrings = RHS.NumInputArgStrings;
return *this;
}
+
~InputArgList() { releaseMemory(); }
const char *getArgString(unsigned Index) const override {
@@ -424,7 +478,6 @@ public:
append(MakePositionalArg(BaseArg, Opt, Value));
}
-
/// AddSeparateArg - Construct a new Positional arg for the given option
/// \p Id, with the provided \p Value and append it to the argument
/// list.
@@ -433,7 +486,6 @@ public:
append(MakeSeparateArg(BaseArg, Opt, Value));
}
-
/// AddJoinedArg - Construct a new Positional arg for the given option
/// \p Id, with the provided \p Value and append it to the argument list.
void AddJoinedArg(const Arg *BaseArg, const Option Opt,
@@ -441,7 +493,6 @@ public:
append(MakeJoinedArg(BaseArg, Opt, Value));
}
-
/// MakeFlagArg - Construct a new FlagArg for the given option \p Id.
Arg *MakeFlagArg(const Arg *BaseArg, const Option Opt) const;
@@ -464,6 +515,7 @@ public:
};
} // end namespace opt
+
} // end namespace llvm
-#endif
+#endif // LLVM_OPTION_ARGLIST_H
diff --git a/contrib/llvm/include/llvm/Option/OptParser.td b/contrib/llvm/include/llvm/Option/OptParser.td
index 4da86f0..4812236 100644
--- a/contrib/llvm/include/llvm/Option/OptParser.td
+++ b/contrib/llvm/include/llvm/Option/OptParser.td
@@ -92,6 +92,7 @@ class Option<list<string> prefixes, string name, OptionKind kind> {
int NumArgs = 0;
string HelpText = ?;
string MetaVarName = ?;
+ string Values = ?;
list<OptionFlag> Flags = [];
OptionGroup Group = ?;
Option Alias = ?;
@@ -126,6 +127,7 @@ class Flags<list<OptionFlag> flags> { list<OptionFlag> Flags = flags; }
class Group<OptionGroup group> { OptionGroup Group = group; }
class HelpText<string text> { string HelpText = text; }
class MetaVarName<string name> { string MetaVarName = name; }
+class Values<string value> { string Values = value; }
// Predefined options.
diff --git a/contrib/llvm/include/llvm/Option/OptSpecifier.h b/contrib/llvm/include/llvm/Option/OptSpecifier.h
index 0b2aaae..84c3cf8 100644
--- a/contrib/llvm/include/llvm/Option/OptSpecifier.h
+++ b/contrib/llvm/include/llvm/Option/OptSpecifier.h
@@ -1,4 +1,4 @@
-//===--- OptSpecifier.h - Option Specifiers ---------------------*- C++ -*-===//
+//===- OptSpecifier.h - Option Specifiers -----------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -10,32 +10,30 @@
#ifndef LLVM_OPTION_OPTSPECIFIER_H
#define LLVM_OPTION_OPTSPECIFIER_H
-#include "llvm/Support/Compiler.h"
-
namespace llvm {
namespace opt {
- class Option;
- /// OptSpecifier - Wrapper class for abstracting references to option IDs.
- class OptSpecifier {
- unsigned ID;
+class Option;
+
+/// OptSpecifier - Wrapper class for abstracting references to option IDs.
+class OptSpecifier {
+ unsigned ID = 0;
- private:
- explicit OptSpecifier(bool) = delete;
+public:
+ OptSpecifier() = default;
+ explicit OptSpecifier(bool) = delete;
+ /*implicit*/ OptSpecifier(unsigned ID) : ID(ID) {}
+ /*implicit*/ OptSpecifier(const Option *Opt);
- public:
- OptSpecifier() : ID(0) {}
- /*implicit*/ OptSpecifier(unsigned ID) : ID(ID) {}
- /*implicit*/ OptSpecifier(const Option *Opt);
+ bool isValid() const { return ID != 0; }
- bool isValid() const { return ID != 0; }
+ unsigned getID() const { return ID; }
- unsigned getID() const { return ID; }
+ bool operator==(OptSpecifier Opt) const { return ID == Opt.getID(); }
+ bool operator!=(OptSpecifier Opt) const { return !(*this == Opt); }
+};
- bool operator==(OptSpecifier Opt) const { return ID == Opt.getID(); }
- bool operator!=(OptSpecifier Opt) const { return !(*this == Opt); }
- };
-}
-}
+} // end namespace opt
+} // end namespace llvm
-#endif
+#endif // LLVM_OPTION_OPTSPECIFIER_H
diff --git a/contrib/llvm/include/llvm/Option/OptTable.h b/contrib/llvm/include/llvm/Option/OptTable.h
index 390e527..a35e182 100644
--- a/contrib/llvm/include/llvm/Option/OptTable.h
+++ b/contrib/llvm/include/llvm/Option/OptTable.h
@@ -1,4 +1,4 @@
-//===--- OptTable.h - Option Table ------------------------------*- C++ -*-===//
+//===- OptTable.h - Option Table --------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -11,12 +11,19 @@
#define LLVM_OPTION_OPTTABLE_H
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/Option/OptSpecifier.h"
+#include <cassert>
+#include <string>
+#include <vector>
namespace llvm {
+
class raw_ostream;
+
namespace opt {
+
class Arg;
class ArgList;
class InputArgList;
@@ -46,6 +53,7 @@ public:
unsigned short GroupID;
unsigned short AliasID;
const char *AliasArgs;
+ const char *Values;
};
private:
@@ -53,12 +61,12 @@ private:
ArrayRef<Info> OptionInfos;
bool IgnoreCase;
- unsigned TheInputOptionID;
- unsigned TheUnknownOptionID;
+ unsigned TheInputOptionID = 0;
+ unsigned TheUnknownOptionID = 0;
/// The index of the first option which can be parsed (i.e., is not a
/// special option like 'input' or 'unknown', and is not an option group).
- unsigned FirstSearchableIndex;
+ unsigned FirstSearchableIndex = 0;
/// The union of all option prefixes. If an argument does not begin with
/// one of these, it is an input.
@@ -113,6 +121,28 @@ public:
return getInfo(id).MetaVar;
}
+ /// Find possible value for given flags. This is used for shell
+ /// autocompletion.
+ ///
+ /// \param [in] Option - Key flag like "-stdlib=" when "-stdlib=l"
+ /// was passed to clang.
+ ///
+ /// \param [in] Arg - Value which we want to autocomplete like "l"
+ /// when "-stdlib=l" was passed to clang.
+ ///
+ /// \return The vector of possible values.
+ std::vector<std::string> suggestValueCompletions(StringRef Option,
+ StringRef Arg) const;
+
+ /// Find flags from OptTable which starts with Cur.
+ ///
+ /// \param [in] Cur - String prefix that all returned flags need
+ // to start with.
+ ///
+ /// \return The vector of flags which start with Cur.
+ std::vector<std::string> findByPrefix(StringRef Cur,
+ unsigned short DisableFlags) const;
+
/// \brief Parse a single argument; returning the new argument and
/// updating Index.
///
@@ -168,7 +198,9 @@ public:
void PrintHelp(raw_ostream &OS, const char *Name,
const char *Title, bool ShowHidden = false) const;
};
+
} // end namespace opt
+
} // end namespace llvm
-#endif
+#endif // LLVM_OPTION_OPTTABLE_H
diff --git a/contrib/llvm/include/llvm/Option/Option.h b/contrib/llvm/include/llvm/Option/Option.h
index 139f281..d9aebd5 100644
--- a/contrib/llvm/include/llvm/Option/Option.h
+++ b/contrib/llvm/include/llvm/Option/Option.h
@@ -1,4 +1,4 @@
-//===--- Option.h - Abstract Driver Options ---------------------*- C++ -*-===//
+//===- Option.h - Abstract Driver Options -----------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -12,15 +12,23 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/Option/OptSpecifier.h"
#include "llvm/Option/OptTable.h"
#include "llvm/Support/ErrorHandling.h"
+#include <cassert>
+#include <string>
namespace llvm {
+
+class raw_ostream;
+
namespace opt {
+
class Arg;
class ArgList;
+
/// ArgStringList - Type used for constructing argv lists for subprocesses.
-typedef SmallVector<const char*, 16> ArgStringList;
+using ArgStringList = SmallVector<const char *, 16>;
/// Base flags for all options. Custom flags may be added after.
enum DriverFlag {
@@ -49,6 +57,7 @@ public:
UnknownClass,
FlagClass,
JoinedClass,
+ ValuesClass,
SeparateClass,
RemainingArgsClass,
RemainingArgsJoinedClass,
@@ -147,6 +156,7 @@ public:
case CommaJoinedClass:
return RenderCommaJoinedStyle;
case FlagClass:
+ case ValuesClass:
case SeparateClass:
case MultiArgClass:
case JoinedOrSeparateClass:
@@ -202,6 +212,7 @@ public:
};
} // end namespace opt
+
} // end namespace llvm
-#endif
+#endif // LLVM_OPTION_OPTION_H
diff --git a/contrib/llvm/include/llvm/Pass.h b/contrib/llvm/include/llvm/Pass.h
index e9c8ca3..2dd6935 100644
--- a/contrib/llvm/include/llvm/Pass.h
+++ b/contrib/llvm/include/llvm/Pass.h
@@ -384,7 +384,7 @@ extern bool isFunctionInPrintList(StringRef FunctionName);
// Include support files that contain important APIs commonly used by Passes,
// but that we want to separate out to make it easier to read the header files.
//
-#include "llvm/PassSupport.h"
#include "llvm/PassAnalysisSupport.h"
+#include "llvm/PassSupport.h"
#endif
diff --git a/contrib/llvm/include/llvm/PassInfo.h b/contrib/llvm/include/llvm/PassInfo.h
index 21ade85..81dface 100644
--- a/contrib/llvm/include/llvm/PassInfo.h
+++ b/contrib/llvm/include/llvm/PassInfo.h
@@ -32,7 +32,6 @@ class TargetMachine;
class PassInfo {
public:
typedef Pass* (*NormalCtor_t)();
- typedef Pass *(*TargetMachineCtor_t)(TargetMachine *);
private:
StringRef PassName; // Nice name for Pass
@@ -44,24 +43,20 @@ private:
std::vector<const PassInfo *> ItfImpl; // Interfaces implemented by this pass
NormalCtor_t NormalCtor;
- TargetMachineCtor_t TargetMachineCtor;
public:
/// PassInfo ctor - Do not call this directly, this should only be invoked
/// through RegisterPass.
PassInfo(StringRef name, StringRef arg, const void *pi, NormalCtor_t normal,
- bool isCFGOnly, bool is_analysis,
- TargetMachineCtor_t machine = nullptr)
+ bool isCFGOnly, bool is_analysis)
: PassName(name), PassArgument(arg), PassID(pi), IsCFGOnlyPass(isCFGOnly),
- IsAnalysis(is_analysis), IsAnalysisGroup(false), NormalCtor(normal),
- TargetMachineCtor(machine) {}
+ IsAnalysis(is_analysis), IsAnalysisGroup(false), NormalCtor(normal) {}
/// PassInfo ctor - Do not call this directly, this should only be invoked
/// through RegisterPass. This version is for use by analysis groups; it
/// does not auto-register the pass.
PassInfo(StringRef name, const void *pi)
: PassName(name), PassArgument(""), PassID(pi), IsCFGOnlyPass(false),
- IsAnalysis(false), IsAnalysisGroup(true), NormalCtor(nullptr),
- TargetMachineCtor(nullptr) {}
+ IsAnalysis(false), IsAnalysisGroup(true), NormalCtor(nullptr) {}
/// getPassName - Return the friendly name for the pass, never returns null
///
@@ -101,16 +96,6 @@ public:
NormalCtor = Ctor;
}
- /// getTargetMachineCtor - Return a pointer to a function, that when called
- /// with a TargetMachine, creates an instance of the pass and returns it.
- /// This pointer may be null if there is no constructor with a TargetMachine
- /// for the pass.
- ///
- TargetMachineCtor_t getTargetMachineCtor() const { return TargetMachineCtor; }
- void setTargetMachineCtor(TargetMachineCtor_t Ctor) {
- TargetMachineCtor = Ctor;
- }
-
/// createPass() - Use this method to create an instance of this pass.
Pass *createPass() const {
assert((!isAnalysisGroup() || NormalCtor) &&
diff --git a/contrib/llvm/include/llvm/PassSupport.h b/contrib/llvm/include/llvm/PassSupport.h
index e77a0b9..602f45a 100644
--- a/contrib/llvm/include/llvm/PassSupport.h
+++ b/contrib/llvm/include/llvm/PassSupport.h
@@ -31,8 +31,6 @@
namespace llvm {
-class TargetMachine;
-
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis) \
static void *initialize##passName##PassOnce(PassRegistry &Registry) { \
PassInfo *PI = new PassInfo( \
@@ -41,7 +39,7 @@ class TargetMachine;
Registry.registerPass(*PI, true); \
return PI; \
} \
- LLVM_DEFINE_ONCE_FLAG(Initialize##passName##PassFlag); \
+ static llvm::once_flag Initialize##passName##PassFlag; \
void llvm::initialize##passName##Pass(PassRegistry &Registry) { \
llvm::call_once(Initialize##passName##PassFlag, \
initialize##passName##PassOnce, std::ref(Registry)); \
@@ -61,7 +59,7 @@ class TargetMachine;
Registry.registerPass(*PI, true); \
return PI; \
} \
- LLVM_DEFINE_ONCE_FLAG(Initialize##passName##PassFlag); \
+ static llvm::once_flag Initialize##passName##PassFlag; \
void llvm::initialize##passName##Pass(PassRegistry &Registry) { \
llvm::call_once(Initialize##passName##PassFlag, \
initialize##passName##PassOnce, std::ref(Registry)); \
@@ -78,10 +76,6 @@ class TargetMachine;
template <typename PassName> Pass *callDefaultCtor() { return new PassName(); }
-template <typename PassName> Pass *callTargetMachineCtor(TargetMachine *TM) {
- return new PassName(TM);
-}
-
//===---------------------------------------------------------------------------
/// RegisterPass<t> template - This template class is used to notify the system
/// that a Pass is available for use, and registers it into the internal
@@ -93,11 +87,7 @@ template <typename PassName> Pass *callTargetMachineCtor(TargetMachine *TM) {
/// static RegisterPass<YourPassClassName> tmp("passopt", "My Pass Name");
///
/// This statement will cause your pass to be created by calling the default
-/// constructor exposed by the pass. If you have a different constructor that
-/// must be called, create a global constructor function (which takes the
-/// arguments you need and returns a Pass*) and register your pass like this:
-///
-/// static RegisterPass<PassClassName> tmp("passopt", "My Name");
+/// constructor exposed by the pass.
///
template <typename passName> struct RegisterPass : public PassInfo {
// Register Pass using default constructor...
@@ -152,7 +142,7 @@ struct RegisterAnalysisGroup : public RegisterAGBase {
Registry.registerAnalysisGroup(&agName::ID, 0, *AI, false, true); \
return AI; \
} \
- LLVM_DEFINE_ONCE_FLAG(Initialize##agName##AnalysisGroupFlag); \
+ static llvm::once_flag Initialize##agName##AnalysisGroupFlag; \
void llvm::initialize##agName##AnalysisGroup(PassRegistry &Registry) { \
llvm::call_once(Initialize##agName##AnalysisGroupFlag, \
initialize##agName##AnalysisGroupOnce, \
@@ -173,7 +163,7 @@ struct RegisterAnalysisGroup : public RegisterAGBase {
true); \
return AI; \
} \
- LLVM_DEFINE_ONCE_FLAG(Initialize##passName##PassFlag); \
+ static llvm::once_flag Initialize##passName##PassFlag; \
void llvm::initialize##passName##Pass(PassRegistry &Registry) { \
llvm::call_once(Initialize##passName##PassFlag, \
initialize##passName##PassOnce, std::ref(Registry)); \
@@ -194,7 +184,7 @@ struct RegisterAnalysisGroup : public RegisterAGBase {
Registry.registerAnalysisGroup(&agName::ID, &passName::ID, *AI, def, true); \
return AI; \
} \
- LLVM_DEFINE_ONCE_FLAG(Initialize##passName##PassFlag); \
+ static llvm::once_flag Initialize##passName##PassFlag; \
void llvm::initialize##passName##Pass(PassRegistry &Registry) { \
llvm::call_once(Initialize##passName##PassFlag, \
initialize##passName##PassOnce, std::ref(Registry)); \
diff --git a/contrib/llvm/include/llvm/Passes/PassBuilder.h b/contrib/llvm/include/llvm/Passes/PassBuilder.h
index d76c139..33433f6b 100644
--- a/contrib/llvm/include/llvm/Passes/PassBuilder.h
+++ b/contrib/llvm/include/llvm/Passes/PassBuilder.h
@@ -27,6 +27,14 @@ class StringRef;
class AAManager;
class TargetMachine;
+/// A struct capturing PGO tunables.
+struct PGOOptions {
+ std::string ProfileGenFile = "";
+ std::string ProfileUseFile = "";
+ std::string SampleProfileFile = "";
+ bool RunProfileGen = false;
+};
+
/// \brief This class provides access to building LLVM's passes.
///
/// It's members provide the baseline state available to passes during their
@@ -35,8 +43,22 @@ class TargetMachine;
/// construction.
class PassBuilder {
TargetMachine *TM;
+ Optional<PGOOptions> PGOOpt;
public:
+ /// \brief A struct to capture parsed pass pipeline names.
+ ///
+ /// A pipeline is defined as a series of names, each of which may in itself
+ /// recursively contain a nested pipeline. A name is either the name of a pass
+ /// (e.g. "instcombine") or the name of a pipeline type (e.g. "cgscc"). If the
+ /// name is the name of a pass, the InnerPipeline is empty, since passes
+ /// cannot contain inner pipelines. See parsePassPipeline() for a more
+ /// detailed description of the textual pipeline format.
+ struct PipelineElement {
+ StringRef Name;
+ std::vector<PipelineElement> InnerPipeline;
+ };
+
/// \brief LLVM-provided high-level optimization levels.
///
/// This enumerates the LLVM-provided high-level optimization levels. Each
@@ -123,7 +145,9 @@ public:
Oz
};
- explicit PassBuilder(TargetMachine *TM = nullptr) : TM(TM) {}
+ explicit PassBuilder(TargetMachine *TM = nullptr,
+ Optional<PGOOptions> PGOOpt = None)
+ : TM(TM), PGOOpt(PGOOpt) {}
/// \brief Cross register the analysis managers through their proxies.
///
@@ -177,9 +201,52 @@ public:
/// only intended for use when attempting to optimize code. If frontends
/// require some transformations for semantic reasons, they should explicitly
/// build them.
+ ///
+ /// \p PrepareForThinLTO indicates whether this is invoked in
+ /// PrepareForThinLTO phase. Special handling is needed for sample PGO to
+ /// ensure profile accurate in the backend profile annotation phase.
FunctionPassManager
buildFunctionSimplificationPipeline(OptimizationLevel Level,
- bool DebugLogging = false);
+ bool DebugLogging = false,
+ bool PrepareForThinLTO = false);
+
+ /// Construct the core LLVM module canonicalization and simplification
+ /// pipeline.
+ ///
+ /// This pipeline focuses on canonicalizing and simplifying the entire module
+ /// of IR. Much like the function simplification pipeline above, it is
+ /// suitable to run repeatedly over the IR and is not expected to destroy
+ /// important information. It does, however, perform inlining and other
+ /// heuristic based simplifications that are not strictly reversible.
+ ///
+ /// Note that \p Level cannot be `O0` here. The pipelines produced are
+ /// only intended for use when attempting to optimize code. If frontends
+ /// require some transformations for semantic reasons, they should explicitly
+ /// build them.
+ ///
+ /// \p PrepareForThinLTO indicates whether this is invoked in
+ /// PrepareForThinLTO phase. Special handling is needed for sample PGO to
+ /// ensure profile accurate in the backend profile annotation phase.
+ ModulePassManager
+ buildModuleSimplificationPipeline(OptimizationLevel Level,
+ bool DebugLogging = false,
+ bool PrepareForThinLTO = false);
+
+ /// Construct the core LLVM module optimization pipeline.
+ ///
+ /// This pipeline focuses on optimizing the execution speed of the IR. It
+ /// uses cost modeling and thresholds to balance code growth against runtime
+ /// improvements. It includes vectorization and other information destroying
+ /// transformations. It also cannot generally be run repeatedly on a module
+ /// without potentially seriously regressing either runtime performance of
+ /// the code or serious code size growth.
+ ///
+ /// Note that \p Level cannot be `O0` here. The pipelines produced are
+ /// only intended for use when attempting to optimize code. If frontends
+ /// require some transformations for semantic reasons, they should explicitly
+ /// build them.
+ ModulePassManager buildModuleOptimizationPipeline(OptimizationLevel Level,
+ bool DebugLogging = false);
/// Build a per-module default optimization pipeline.
///
@@ -195,6 +262,36 @@ public:
ModulePassManager buildPerModuleDefaultPipeline(OptimizationLevel Level,
bool DebugLogging = false);
+ /// Build a pre-link, ThinLTO-targeting default optimization pipeline to
+ /// a pass manager.
+ ///
+ /// This adds the pre-link optimizations tuned to prepare a module for
+ /// a ThinLTO run. It works to minimize the IR which needs to be analyzed
+ /// without making irreversible decisions which could be made better during
+ /// the LTO run.
+ ///
+ /// Note that \p Level cannot be `O0` here. The pipelines produced are
+ /// only intended for use when attempting to optimize code. If frontends
+ /// require some transformations for semantic reasons, they should explicitly
+ /// build them.
+ ModulePassManager
+ buildThinLTOPreLinkDefaultPipeline(OptimizationLevel Level,
+ bool DebugLogging = false);
+
+ /// Build an ThinLTO default optimization pipeline to a pass manager.
+ ///
+ /// This provides a good default optimization pipeline for link-time
+ /// optimization and code generation. It is particularly tuned to fit well
+ /// when IR coming into the LTO phase was first run through \c
+ /// addPreLinkLTODefaultPipeline, and the two coordinate closely.
+ ///
+ /// Note that \p Level cannot be `O0` here. The pipelines produced are
+ /// only intended for use when attempting to optimize code. If frontends
+ /// require some transformations for semantic reasons, they should explicitly
+ /// build them.
+ ModulePassManager buildThinLTODefaultPipeline(OptimizationLevel Level,
+ bool DebugLogging = false);
+
/// Build a pre-link, LTO-targeting default optimization pipeline to a pass
/// manager.
///
@@ -228,7 +325,8 @@ public:
/// registered.
AAManager buildDefaultAAPipeline();
- /// \brief Parse a textual pass pipeline description into a \c ModulePassManager.
+ /// \brief Parse a textual pass pipeline description into a \c
+ /// ModulePassManager.
///
/// The format of the textual pass pipeline description looks something like:
///
@@ -238,8 +336,8 @@ public:
/// are comma separated. As a special shortcut, if the very first pass is not
/// a module pass (as a module pass manager is), this will automatically form
/// the shortest stack of pass managers that allow inserting that first pass.
- /// So, assuming function passes 'fpassN', CGSCC passes 'cgpassN', and loop passes
- /// 'lpassN', all of these are valid:
+ /// So, assuming function passes 'fpassN', CGSCC passes 'cgpassN', and loop
+ /// passes 'lpassN', all of these are valid:
///
/// fpass1,fpass2,fpass3
/// cgpass1,cgpass2,cgpass3
@@ -252,13 +350,28 @@ public:
/// module(function(loop(lpass1,lpass2,lpass3)))
///
/// This shortcut is especially useful for debugging and testing small pass
- /// combinations. Note that these shortcuts don't introduce any other magic. If
- /// the sequence of passes aren't all the exact same kind of pass, it will be
- /// an error. You cannot mix different levels implicitly, you must explicitly
- /// form a pass manager in which to nest passes.
+ /// combinations. Note that these shortcuts don't introduce any other magic.
+ /// If the sequence of passes aren't all the exact same kind of pass, it will
+ /// be an error. You cannot mix different levels implicitly, you must
+ /// explicitly form a pass manager in which to nest passes.
bool parsePassPipeline(ModulePassManager &MPM, StringRef PipelineText,
bool VerifyEachPass = true, bool DebugLogging = false);
+ /// {{@ Parse a textual pass pipeline description into a specific PassManager
+ ///
+ /// Automatic deduction of an appropriate pass manager stack is not supported.
+ /// For example, to insert a loop pass 'lpass' into a FunctinoPassManager,
+ /// this is the valid pipeline text:
+ ///
+ /// function(lpass)
+ bool parsePassPipeline(CGSCCPassManager &CGPM, StringRef PipelineText,
+ bool VerifyEachPass = true, bool DebugLogging = false);
+ bool parsePassPipeline(FunctionPassManager &FPM, StringRef PipelineText,
+ bool VerifyEachPass = true, bool DebugLogging = false);
+ bool parsePassPipeline(LoopPassManager &LPM, StringRef PipelineText,
+ bool VerifyEachPass = true, bool DebugLogging = false);
+ /// @}}
+
/// Parse a textual alias analysis pipeline into the provided AA manager.
///
/// The format of the textual AA pipeline is a comma separated list of AA
@@ -276,13 +389,139 @@ public:
/// returns false.
bool parseAAPipeline(AAManager &AA, StringRef PipelineText);
-private:
- /// A struct to capture parsed pass pipeline names.
- struct PipelineElement {
- StringRef Name;
- std::vector<PipelineElement> InnerPipeline;
- };
+ /// \brief Register a callback for a default optimizer pipeline extension
+ /// point
+ ///
+ /// This extension point allows adding passes that perform peephole
+ /// optimizations similar to the instruction combiner. These passes will be
+ /// inserted after each instance of the instruction combiner pass.
+ void registerPeepholeEPCallback(
+ const std::function<void(FunctionPassManager &, OptimizationLevel)> &C) {
+ PeepholeEPCallbacks.push_back(C);
+ }
+ /// \brief Register a callback for a default optimizer pipeline extension
+ /// point
+ ///
+ /// This extension point allows adding late loop canonicalization and
+ /// simplification passes. This is the last point in the loop optimization
+ /// pipeline before loop deletion. Each pass added
+ /// here must be an instance of LoopPass.
+ /// This is the place to add passes that can remove loops, such as target-
+ /// specific loop idiom recognition.
+ void registerLateLoopOptimizationsEPCallback(
+ const std::function<void(LoopPassManager &, OptimizationLevel)> &C) {
+ LateLoopOptimizationsEPCallbacks.push_back(C);
+ }
+
+ /// \brief Register a callback for a default optimizer pipeline extension
+ /// point
+ ///
+ /// This extension point allows adding loop passes to the end of the loop
+ /// optimizer.
+ void registerLoopOptimizerEndEPCallback(
+ const std::function<void(LoopPassManager &, OptimizationLevel)> &C) {
+ LoopOptimizerEndEPCallbacks.push_back(C);
+ }
+
+ /// \brief Register a callback for a default optimizer pipeline extension
+ /// point
+ ///
+ /// This extension point allows adding optimization passes after most of the
+ /// main optimizations, but before the last cleanup-ish optimizations.
+ void registerScalarOptimizerLateEPCallback(
+ const std::function<void(FunctionPassManager &, OptimizationLevel)> &C) {
+ ScalarOptimizerLateEPCallbacks.push_back(C);
+ }
+
+ /// \brief Register a callback for a default optimizer pipeline extension
+ /// point
+ ///
+ /// This extension point allows adding CallGraphSCC passes at the end of the
+ /// main CallGraphSCC passes and before any function simplification passes run
+ /// by CGPassManager.
+ void registerCGSCCOptimizerLateEPCallback(
+ const std::function<void(CGSCCPassManager &, OptimizationLevel)> &C) {
+ CGSCCOptimizerLateEPCallbacks.push_back(C);
+ }
+
+ /// \brief Register a callback for a default optimizer pipeline extension
+ /// point
+ ///
+ /// This extension point allows adding optimization passes before the
+ /// vectorizer and other highly target specific optimization passes are
+ /// executed.
+ void registerVectorizerStartEPCallback(
+ const std::function<void(FunctionPassManager &, OptimizationLevel)> &C) {
+ VectorizerStartEPCallbacks.push_back(C);
+ }
+
+ /// \brief Register a callback for parsing an AliasAnalysis Name to populate
+ /// the given AAManager \p AA
+ void registerParseAACallback(
+ const std::function<bool(StringRef Name, AAManager &AA)> &C) {
+ AAParsingCallbacks.push_back(C);
+ }
+
+ /// {{@ Register callbacks for analysis registration with this PassBuilder
+ /// instance.
+ /// Callees register their analyses with the given AnalysisManager objects.
+ void registerAnalysisRegistrationCallback(
+ const std::function<void(CGSCCAnalysisManager &)> &C) {
+ CGSCCAnalysisRegistrationCallbacks.push_back(C);
+ }
+ void registerAnalysisRegistrationCallback(
+ const std::function<void(FunctionAnalysisManager &)> &C) {
+ FunctionAnalysisRegistrationCallbacks.push_back(C);
+ }
+ void registerAnalysisRegistrationCallback(
+ const std::function<void(LoopAnalysisManager &)> &C) {
+ LoopAnalysisRegistrationCallbacks.push_back(C);
+ }
+ void registerAnalysisRegistrationCallback(
+ const std::function<void(ModuleAnalysisManager &)> &C) {
+ ModuleAnalysisRegistrationCallbacks.push_back(C);
+ }
+ /// @}}
+
+ /// {{@ Register pipeline parsing callbacks with this pass builder instance.
+ /// Using these callbacks, callers can parse both a single pass name, as well
+ /// as entire sub-pipelines, and populate the PassManager instance
+ /// accordingly.
+ void registerPipelineParsingCallback(
+ const std::function<bool(StringRef Name, CGSCCPassManager &,
+ ArrayRef<PipelineElement>)> &C) {
+ CGSCCPipelineParsingCallbacks.push_back(C);
+ }
+ void registerPipelineParsingCallback(
+ const std::function<bool(StringRef Name, FunctionPassManager &,
+ ArrayRef<PipelineElement>)> &C) {
+ FunctionPipelineParsingCallbacks.push_back(C);
+ }
+ void registerPipelineParsingCallback(
+ const std::function<bool(StringRef Name, LoopPassManager &,
+ ArrayRef<PipelineElement>)> &C) {
+ LoopPipelineParsingCallbacks.push_back(C);
+ }
+ void registerPipelineParsingCallback(
+ const std::function<bool(StringRef Name, ModulePassManager &,
+ ArrayRef<PipelineElement>)> &C) {
+ ModulePipelineParsingCallbacks.push_back(C);
+ }
+ /// @}}
+
+ /// \brief Register a callback for a top-level pipeline entry.
+ ///
+ /// If the PassManager type is not given at the top level of the pipeline
+ /// text, this Callback should be used to determine the appropriate stack of
+ /// PassManagers and populate the passed ModulePassManager.
+ void registerParseTopLevelPipelineCallback(
+ const std::function<bool(ModulePassManager &, ArrayRef<PipelineElement>,
+ bool VerifyEachPass, bool DebugLogging)> &C) {
+ TopLevelPipelineParsingCallbacks.push_back(C);
+ }
+
+private:
static Optional<std::vector<PipelineElement>>
parsePipelineText(StringRef Text);
@@ -308,7 +547,106 @@ private:
bool parseModulePassPipeline(ModulePassManager &MPM,
ArrayRef<PipelineElement> Pipeline,
bool VerifyEachPass, bool DebugLogging);
+
+ void addPGOInstrPasses(ModulePassManager &MPM, bool DebugLogging,
+ OptimizationLevel Level, bool RunProfileGen,
+ std::string ProfileGenFile,
+ std::string ProfileUseFile);
+
+ void invokePeepholeEPCallbacks(FunctionPassManager &, OptimizationLevel);
+
+ // Extension Point callbacks
+ SmallVector<std::function<void(FunctionPassManager &, OptimizationLevel)>, 2>
+ PeepholeEPCallbacks;
+ SmallVector<std::function<void(LoopPassManager &, OptimizationLevel)>, 2>
+ LateLoopOptimizationsEPCallbacks;
+ SmallVector<std::function<void(LoopPassManager &, OptimizationLevel)>, 2>
+ LoopOptimizerEndEPCallbacks;
+ SmallVector<std::function<void(FunctionPassManager &, OptimizationLevel)>, 2>
+ ScalarOptimizerLateEPCallbacks;
+ SmallVector<std::function<void(CGSCCPassManager &, OptimizationLevel)>, 2>
+ CGSCCOptimizerLateEPCallbacks;
+ SmallVector<std::function<void(FunctionPassManager &, OptimizationLevel)>, 2>
+ VectorizerStartEPCallbacks;
+ // Module callbacks
+ SmallVector<std::function<void(ModuleAnalysisManager &)>, 2>
+ ModuleAnalysisRegistrationCallbacks;
+ SmallVector<std::function<bool(StringRef, ModulePassManager &,
+ ArrayRef<PipelineElement>)>,
+ 2>
+ ModulePipelineParsingCallbacks;
+ SmallVector<std::function<bool(ModulePassManager &, ArrayRef<PipelineElement>,
+ bool VerifyEachPass, bool DebugLogging)>,
+ 2>
+ TopLevelPipelineParsingCallbacks;
+ // CGSCC callbacks
+ SmallVector<std::function<void(CGSCCAnalysisManager &)>, 2>
+ CGSCCAnalysisRegistrationCallbacks;
+ SmallVector<std::function<bool(StringRef, CGSCCPassManager &,
+ ArrayRef<PipelineElement>)>,
+ 2>
+ CGSCCPipelineParsingCallbacks;
+ // Function callbacks
+ SmallVector<std::function<void(FunctionAnalysisManager &)>, 2>
+ FunctionAnalysisRegistrationCallbacks;
+ SmallVector<std::function<bool(StringRef, FunctionPassManager &,
+ ArrayRef<PipelineElement>)>,
+ 2>
+ FunctionPipelineParsingCallbacks;
+ // Loop callbacks
+ SmallVector<std::function<void(LoopAnalysisManager &)>, 2>
+ LoopAnalysisRegistrationCallbacks;
+ SmallVector<std::function<bool(StringRef, LoopPassManager &,
+ ArrayRef<PipelineElement>)>,
+ 2>
+ LoopPipelineParsingCallbacks;
+ // AA callbacks
+ SmallVector<std::function<bool(StringRef Name, AAManager &AA)>, 2>
+ AAParsingCallbacks;
};
+
+/// This utility template takes care of adding require<> and invalidate<>
+/// passes for an analysis to a given \c PassManager. It is intended to be used
+/// during parsing of a pass pipeline when parsing a single PipelineName.
+/// When registering a new function analysis FancyAnalysis with the pass
+/// pipeline name "fancy-analysis", a matching ParsePipelineCallback could look
+/// like this:
+///
+/// static bool parseFunctionPipeline(StringRef Name, FunctionPassManager &FPM,
+/// ArrayRef<PipelineElement> P) {
+/// if (parseAnalysisUtilityPasses<FancyAnalysis>("fancy-analysis", Name,
+/// FPM))
+/// return true;
+/// return false;
+/// }
+template <typename AnalysisT, typename IRUnitT, typename AnalysisManagerT,
+ typename... ExtraArgTs>
+bool parseAnalysisUtilityPasses(
+ StringRef AnalysisName, StringRef PipelineName,
+ PassManager<IRUnitT, AnalysisManagerT, ExtraArgTs...> &PM) {
+ if (!PipelineName.endswith(">"))
+ return false;
+ // See if this is an invalidate<> pass name
+ if (PipelineName.startswith("invalidate<")) {
+ PipelineName = PipelineName.substr(11, PipelineName.size() - 12);
+ if (PipelineName != AnalysisName)
+ return false;
+ PM.addPass(InvalidateAnalysisPass<AnalysisT>());
+ return true;
+ }
+
+ // See if this is a require<> pass name
+ if (PipelineName.startswith("require<")) {
+ PipelineName = PipelineName.substr(8, PipelineName.size() - 9);
+ if (PipelineName != AnalysisName)
+ return false;
+ PM.addPass(RequireAnalysisPass<AnalysisT, IRUnitT, AnalysisManagerT,
+ ExtraArgTs...>());
+ return true;
+ }
+
+ return false;
+}
}
#endif
diff --git a/contrib/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h b/contrib/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h
index d6051ff..fa9a87a 100644
--- a/contrib/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h
+++ b/contrib/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h
@@ -1,4 +1,4 @@
-//=-- CoverageMapping.h - Code coverage mapping support ---------*- C++ -*-=//
+//===- CoverageMapping.h - Code coverage mapping support --------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -12,25 +12,42 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_PROFILEDATA_COVERAGEMAPPING_H_
-#define LLVM_PROFILEDATA_COVERAGEMAPPING_H_
+#ifndef LLVM_PROFILEDATA_COVERAGE_COVERAGEMAPPING_H
+#define LLVM_PROFILEDATA_COVERAGE_COVERAGEMAPPING_H
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/Hashing.h"
+#include "llvm/ADT/None.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSet.h"
-#include "llvm/ADT/Triple.h"
#include "llvm/ADT/iterator.h"
+#include "llvm/ADT/iterator_range.h"
#include "llvm/ProfileData/InstrProf.h"
+#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
#include "llvm/Support/raw_ostream.h"
+#include <cassert>
+#include <cstdint>
+#include <iterator>
+#include <memory>
+#include <string>
#include <system_error>
#include <tuple>
+#include <utility>
+#include <vector>
namespace llvm {
+
+class IndexedInstrProfReader;
+
namespace coverage {
+class CoverageMappingReader;
+struct CoverageMappingRecord;
+
enum class coveragemap_error {
success = 0,
eof,
@@ -68,19 +85,6 @@ private:
coveragemap_error Err;
};
-} // end of coverage namespace.
-} // end of llvm namespace
-
-namespace llvm {
-class IndexedInstrProfReader;
-namespace coverage {
-
-class CoverageMappingReader;
-struct CoverageMappingRecord;
-
-class CoverageMapping;
-struct CounterExpressions;
-
/// \brief A Counter is an abstract value that describes how to compute the
/// execution count for a region of code using the collected profile count data.
struct Counter {
@@ -91,13 +95,13 @@ struct Counter {
EncodingTagBits + 1;
private:
- CounterKind Kind;
- unsigned ID;
+ CounterKind Kind = Zero;
+ unsigned ID = 0;
Counter(CounterKind Kind, unsigned ID) : Kind(Kind), ID(ID) {}
public:
- Counter() : Kind(Zero), ID(0) {}
+ Counter() = default;
CounterKind getKind() const { return Kind; }
@@ -153,8 +157,9 @@ struct CounterExpression {
class CounterExpressionBuilder {
/// \brief A list of all the counter expressions
std::vector<CounterExpression> Expressions;
+
/// \brief A lookup table for the index of a given expression.
- llvm::DenseMap<CounterExpression, unsigned> ExpressionIndices;
+ DenseMap<CounterExpression, unsigned> ExpressionIndices;
/// \brief Return the counter which corresponds to the given expression.
///
@@ -163,13 +168,21 @@ class CounterExpressionBuilder {
/// expression is added to the builder's collection of expressions.
Counter get(const CounterExpression &E);
+ /// Represents a term in a counter expression tree.
+ struct Term {
+ unsigned CounterID;
+ int Factor;
+
+ Term(unsigned CounterID, int Factor)
+ : CounterID(CounterID), Factor(Factor) {}
+ };
+
/// \brief Gather the terms of the expression tree for processing.
///
/// This collects each addition and subtraction referenced by the counter into
/// a sequence that can be sorted and combined to build a simplified counter
/// expression.
- void extractTerms(Counter C, int Sign,
- SmallVectorImpl<std::pair<unsigned, int>> &Terms);
+ void extractTerms(Counter C, int Sign, SmallVectorImpl<Term> &Terms);
/// \brief Simplifies the given expression tree
/// by getting rid of algebraically redundant operations.
@@ -238,7 +251,6 @@ struct CounterMappingRegion {
LineEnd, ColumnEnd, SkippedRegion);
}
-
inline std::pair<unsigned, unsigned> startLoc() const {
return std::pair<unsigned, unsigned>(LineStart, ColumnStart);
}
@@ -269,7 +281,7 @@ public:
void setCounts(ArrayRef<uint64_t> Counts) { CounterValues = Counts; }
- void dump(const Counter &C, llvm::raw_ostream &OS) const;
+ void dump(const Counter &C, raw_ostream &OS) const;
void dump(const Counter &C) const { dump(C, dbgs()); }
/// \brief Return the number of times that a region of code associated with
@@ -390,13 +402,14 @@ struct CoverageSegment {
/// provides a sequence of CoverageSegments to iterate through, as well as the
/// list of expansions that can be further processed.
class CoverageData {
+ friend class CoverageMapping;
+
std::string Filename;
std::vector<CoverageSegment> Segments;
std::vector<ExpansionRecord> Expansions;
- friend class CoverageMapping;
public:
- CoverageData() {}
+ CoverageData() = default;
CoverageData(StringRef Filename) : Filename(Filename) {}
@@ -406,9 +419,11 @@ public:
std::vector<CoverageSegment>::const_iterator begin() const {
return Segments.begin();
}
+
std::vector<CoverageSegment>::const_iterator end() const {
return Segments.end();
}
+
bool empty() const { return Segments.empty(); }
/// \brief Expansions that can be further processed.
@@ -422,34 +437,23 @@ public:
class CoverageMapping {
StringSet<> FunctionNames;
std::vector<FunctionRecord> Functions;
- unsigned MismatchedFunctionCount;
-
- CoverageMapping() : MismatchedFunctionCount(0) {}
+ unsigned MismatchedFunctionCount = 0;
- CoverageMapping(const CoverageMapping &) = delete;
- const CoverageMapping &operator=(const CoverageMapping &) = delete;
+ CoverageMapping() = default;
/// \brief Add a function record corresponding to \p Record.
Error loadFunctionRecord(const CoverageMappingRecord &Record,
IndexedInstrProfReader &ProfileReader);
public:
- /// \brief Load the coverage mapping using the given readers.
- static Expected<std::unique_ptr<CoverageMapping>>
- load(CoverageMappingReader &CoverageReader,
- IndexedInstrProfReader &ProfileReader);
+ CoverageMapping(const CoverageMapping &) = delete;
+ CoverageMapping &operator=(const CoverageMapping &) = delete;
+ /// \brief Load the coverage mapping using the given readers.
static Expected<std::unique_ptr<CoverageMapping>>
load(ArrayRef<std::unique_ptr<CoverageMappingReader>> CoverageReaders,
IndexedInstrProfReader &ProfileReader);
- /// \brief Load the coverage mapping from the given files.
- static Expected<std::unique_ptr<CoverageMapping>>
- load(StringRef ObjectFilename, StringRef ProfileFilename,
- StringRef Arch = StringRef()) {
- return load(ArrayRef<StringRef>(ObjectFilename), ProfileFilename, Arch);
- }
-
static Expected<std::unique_ptr<CoverageMapping>>
load(ArrayRef<StringRef> ObjectFilenames, StringRef ProfileFilename,
StringRef Arch = StringRef());
@@ -517,14 +521,17 @@ template <class IntPtrT> struct CovMapFunctionRecordV1 {
template <support::endianness Endian> uint64_t getFuncHash() const {
return support::endian::byte_swap<uint64_t, Endian>(FuncHash);
}
+
// 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);
}
+
// 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 */
template <support::endianness Endian>
Error getFuncName(InstrProfSymtab &ProfileNames, StringRef &FuncName) const {
@@ -545,14 +552,17 @@ struct CovMapFunctionRecord {
template <support::endianness Endian> uint64_t getFuncHash() const {
return support::endian::byte_swap<uint64_t, Endian>(FuncHash);
}
+
// 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);
}
+
// 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 the PGO name of the function */
template <support::endianness Endian>
Error getFuncName(InstrProfSymtab &ProfileNames, StringRef &FuncName) const {
@@ -570,12 +580,15 @@ struct CovMapHeader {
template <support::endianness Endian> uint32_t getNRecords() const {
return support::endian::byte_swap<uint32_t, Endian>(NRecords);
}
+
template <support::endianness Endian> uint32_t getFilenamesSize() const {
return support::endian::byte_swap<uint32_t, Endian>(FilenamesSize);
}
+
template <support::endianness Endian> uint32_t getCoverageSize() const {
return support::endian::byte_swap<uint32_t, Endian>(CoverageSize);
}
+
template <support::endianness Endian> uint32_t getVersion() const {
return support::endian::byte_swap<uint32_t, Endian>(Version);
}
@@ -594,13 +607,13 @@ enum CovMapVersion {
};
template <int CovMapVersion, class IntPtrT> struct CovMapTraits {
- typedef CovMapFunctionRecord CovMapFuncRecordType;
- typedef uint64_t NameRefType;
+ using CovMapFuncRecordType = CovMapFunctionRecord;
+ using NameRefType = uint64_t;
};
template <class IntPtrT> struct CovMapTraits<CovMapVersion::Version1, IntPtrT> {
- typedef CovMapFunctionRecordV1<IntPtrT> CovMapFuncRecordType;
- typedef IntPtrT NameRefType;
+ using CovMapFuncRecordType = CovMapFunctionRecordV1<IntPtrT>;
+ using NameRefType = IntPtrT;
};
} // end namespace coverage
@@ -609,6 +622,7 @@ template <class IntPtrT> struct CovMapTraits<CovMapVersion::Version1, IntPtrT> {
template<> struct DenseMapInfo<coverage::CounterExpression> {
static inline coverage::CounterExpression getEmptyKey() {
using namespace coverage;
+
return CounterExpression(CounterExpression::ExprKind::Subtract,
Counter::getCounter(~0U),
Counter::getCounter(~0U));
@@ -616,6 +630,7 @@ template<> struct DenseMapInfo<coverage::CounterExpression> {
static inline coverage::CounterExpression getTombstoneKey() {
using namespace coverage;
+
return CounterExpression(CounterExpression::ExprKind::Add,
Counter::getCounter(~0U),
Counter::getCounter(~0U));
@@ -635,4 +650,4 @@ template<> struct DenseMapInfo<coverage::CounterExpression> {
} // end namespace llvm
-#endif // LLVM_PROFILEDATA_COVERAGEMAPPING_H_
+#endif // LLVM_PROFILEDATA_COVERAGE_COVERAGEMAPPING_H
diff --git a/contrib/llvm/include/llvm/ProfileData/Coverage/CoverageMappingReader.h b/contrib/llvm/include/llvm/ProfileData/Coverage/CoverageMappingReader.h
index db907f1..5b37225 100644
--- a/contrib/llvm/include/llvm/ProfileData/Coverage/CoverageMappingReader.h
+++ b/contrib/llvm/include/llvm/ProfileData/Coverage/CoverageMappingReader.h
@@ -1,4 +1,4 @@
-//=-- CoverageMappingReader.h - Code coverage mapping reader ------*- C++ -*-=//
+//===- CoverageMappingReader.h - Code coverage mapping reader ---*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -12,18 +12,20 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_PROFILEDATA_COVERAGEMAPPINGREADER_H
-#define LLVM_PROFILEDATA_COVERAGEMAPPINGREADER_H
+#ifndef LLVM_PROFILEDATA_COVERAGE_COVERAGEMAPPINGREADER_H
+#define LLVM_PROFILEDATA_COVERAGE_COVERAGEMAPPINGREADER_H
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/Triple.h"
-#include "llvm/Object/ObjectFile.h"
#include "llvm/ProfileData/Coverage/CoverageMapping.h"
#include "llvm/ProfileData/InstrProf.h"
-#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Error.h"
#include "llvm/Support/MemoryBuffer.h"
+#include <cstddef>
+#include <cstdint>
#include <iterator>
+#include <memory>
+#include <vector>
namespace llvm {
namespace coverage {
@@ -42,13 +44,14 @@ struct CoverageMappingRecord {
/// \brief A file format agnostic iterator over coverage mapping data.
class CoverageMappingIterator
: public std::iterator<std::input_iterator_tag, CoverageMappingRecord> {
- CoverageMappingReader *Reader;
+ CoverageMappingReader *Reader = nullptr;
CoverageMappingRecord Record;
void increment();
public:
- CoverageMappingIterator() : Reader(nullptr) {}
+ CoverageMappingIterator() = default;
+
CoverageMappingIterator(CoverageMappingReader *Reader) : Reader(Reader) {
increment();
}
@@ -69,10 +72,11 @@ public:
class CoverageMappingReader {
public:
+ virtual ~CoverageMappingReader() = default;
+
virtual Error readNextRecord(CoverageMappingRecord &Record) = 0;
CoverageMappingIterator begin() { return CoverageMappingIterator(this); }
CoverageMappingIterator end() { return CoverageMappingIterator(); }
- virtual ~CoverageMappingReader() {}
};
/// \brief Base class for the raw coverage mapping and filenames data readers.
@@ -92,13 +96,12 @@ protected:
class RawCoverageFilenamesReader : public RawCoverageReader {
std::vector<StringRef> &Filenames;
- RawCoverageFilenamesReader(const RawCoverageFilenamesReader &) = delete;
- RawCoverageFilenamesReader &
- operator=(const RawCoverageFilenamesReader &) = delete;
-
public:
RawCoverageFilenamesReader(StringRef Data, std::vector<StringRef> &Filenames)
: RawCoverageReader(Data), Filenames(Filenames) {}
+ RawCoverageFilenamesReader(const RawCoverageFilenamesReader &) = delete;
+ RawCoverageFilenamesReader &
+ operator=(const RawCoverageFilenamesReader &) = delete;
Error read();
};
@@ -120,10 +123,6 @@ class RawCoverageMappingReader : public RawCoverageReader {
std::vector<CounterExpression> &Expressions;
std::vector<CounterMappingRegion> &MappingRegions;
- RawCoverageMappingReader(const RawCoverageMappingReader &) = delete;
- RawCoverageMappingReader &
- operator=(const RawCoverageMappingReader &) = delete;
-
public:
RawCoverageMappingReader(StringRef MappingData,
ArrayRef<StringRef> TranslationUnitFilenames,
@@ -134,6 +133,9 @@ public:
TranslationUnitFilenames(TranslationUnitFilenames),
Filenames(Filenames), Expressions(Expressions),
MappingRegions(MappingRegions) {}
+ RawCoverageMappingReader(const RawCoverageMappingReader &) = delete;
+ RawCoverageMappingReader &
+ operator=(const RawCoverageMappingReader &) = delete;
Error read();
@@ -169,17 +171,17 @@ private:
std::vector<StringRef> Filenames;
std::vector<ProfileMappingRecord> MappingRecords;
InstrProfSymtab ProfileNames;
- size_t CurrentRecord;
+ size_t CurrentRecord = 0;
std::vector<StringRef> FunctionsFilenames;
std::vector<CounterExpression> Expressions;
std::vector<CounterMappingRegion> MappingRegions;
+ BinaryCoverageReader() = default;
+
+public:
BinaryCoverageReader(const BinaryCoverageReader &) = delete;
BinaryCoverageReader &operator=(const BinaryCoverageReader &) = delete;
- BinaryCoverageReader() : CurrentRecord(0) {}
-
-public:
static Expected<std::unique_ptr<BinaryCoverageReader>>
create(std::unique_ptr<MemoryBuffer> &ObjectBuffer,
StringRef Arch);
@@ -190,4 +192,4 @@ public:
} // end namespace coverage
} // end namespace llvm
-#endif
+#endif // LLVM_PROFILEDATA_COVERAGE_COVERAGEMAPPINGREADER_H
diff --git a/contrib/llvm/include/llvm/ProfileData/Coverage/CoverageMappingWriter.h b/contrib/llvm/include/llvm/ProfileData/Coverage/CoverageMappingWriter.h
index 24fb946..b6f864a 100644
--- a/contrib/llvm/include/llvm/ProfileData/Coverage/CoverageMappingWriter.h
+++ b/contrib/llvm/include/llvm/ProfileData/Coverage/CoverageMappingWriter.h
@@ -1,4 +1,4 @@
-//=-- CoverageMappingWriter.h - Code coverage mapping writer ------*- C++ -*-=//
+//===- CoverageMappingWriter.h - Code coverage mapping writer ---*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -12,15 +12,17 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_PROFILEDATA_COVERAGEMAPPINGWRITER_H
-#define LLVM_PROFILEDATA_COVERAGEMAPPINGWRITER_H
+#ifndef LLVM_PROFILEDATA_COVERAGE_COVERAGEMAPPINGWRITER_H
+#define LLVM_PROFILEDATA_COVERAGE_COVERAGEMAPPINGWRITER_H
#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/ProfileData/Coverage/CoverageMapping.h"
-#include "llvm/Support/raw_ostream.h"
namespace llvm {
+
+class raw_ostream;
+
namespace coverage {
/// \brief Writer of the filenames section for the instrumentation
@@ -54,6 +56,7 @@ public:
};
} // end namespace coverage
+
} // end namespace llvm
-#endif
+#endif // LLVM_PROFILEDATA_COVERAGE_COVERAGEMAPPINGWRITER_H
diff --git a/contrib/llvm/include/llvm/ProfileData/InstrProf.h b/contrib/llvm/include/llvm/ProfileData/InstrProf.h
index c7e558e..772187f 100644
--- a/contrib/llvm/include/llvm/ProfileData/InstrProf.h
+++ b/contrib/llvm/include/llvm/ProfileData/InstrProf.h
@@ -1,4 +1,4 @@
-//===-- InstrProf.h - Instrumented profiling format support -----*- C++ -*-===//
+//===- InstrProf.h - Instrumented profiling format support ------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -16,62 +16,57 @@
#ifndef LLVM_PROFILEDATA_INSTRPROF_H
#define LLVM_PROFILEDATA_INSTRPROF_H
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSet.h"
+#include "llvm/ADT/Triple.h"
#include "llvm/IR/GlobalValue.h"
-#include "llvm/IR/Metadata.h"
+#include "llvm/IR/ProfileSummary.h"
#include "llvm/ProfileData/InstrProfData.inc"
-#include "llvm/ProfileData/ProfileCommon.h"
+#include "llvm/Support/Compiler.h"
#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/Host.h"
#include "llvm/Support/MD5.h"
#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+#include <cassert>
+#include <cstddef>
#include <cstdint>
+#include <cstring>
#include <list>
+#include <memory>
+#include <string>
#include <system_error>
+#include <utility>
#include <vector>
namespace llvm {
class Function;
class GlobalVariable;
+struct InstrProfRecord;
+class InstrProfSymtab;
+class Instruction;
+class MDNode;
class Module;
-/// Return the name of data section containing profile counter variables.
-inline StringRef getInstrProfCountersSectionName(bool AddSegment) {
- return AddSegment ? "__DATA," INSTR_PROF_CNTS_SECT_NAME_STR
- : INSTR_PROF_CNTS_SECT_NAME_STR;
-}
-
-/// Return the name of data section containing names of instrumented
-/// functions.
-inline StringRef getInstrProfNameSectionName(bool AddSegment) {
- return AddSegment ? "__DATA," INSTR_PROF_NAME_SECT_NAME_STR
- : INSTR_PROF_NAME_SECT_NAME_STR;
-}
-
-/// Return the name of the data section containing per-function control
-/// data.
-inline StringRef getInstrProfDataSectionName(bool AddSegment) {
- return AddSegment ? "__DATA," INSTR_PROF_DATA_SECT_NAME_STR
- ",regular,live_support"
- : INSTR_PROF_DATA_SECT_NAME_STR;
-}
-
-/// Return the name of data section containing pointers to value profile
-/// counters/nodes.
-inline StringRef getInstrProfValuesSectionName(bool AddSegment) {
- return AddSegment ? "__DATA," INSTR_PROF_VALS_SECT_NAME_STR
- : INSTR_PROF_VALS_SECT_NAME_STR;
-}
+enum InstrProfSectKind {
+#define INSTR_PROF_SECT_ENTRY(Kind, SectNameCommon, SectNameCoff, Prefix) Kind,
+#include "llvm/ProfileData/InstrProfData.inc"
+};
-/// Return the name of data section containing nodes holdling value
-/// profiling data.
-inline StringRef getInstrProfVNodesSectionName(bool AddSegment) {
- return AddSegment ? "__DATA," INSTR_PROF_VNODES_SECT_NAME_STR
- : INSTR_PROF_VNODES_SECT_NAME_STR;
-}
+/// Return the name of the profile section corresponding to \p IPSK.
+///
+/// The name of the section depends on the object format type \p OF. If
+/// \p AddSegmentInfo is true, a segment prefix and additional linker hints may
+/// be added to the section name (this is the default).
+std::string getInstrProfSectionName(InstrProfSectKind IPSK,
+ Triple::ObjectFormatType OF,
+ bool AddSegmentInfo = true);
/// Return the name profile runtime entry point to do value profiling
/// for a given site.
@@ -79,11 +74,9 @@ inline StringRef getInstrProfValueProfFuncName() {
return INSTR_PROF_VALUE_PROF_FUNC_STR;
}
-/// Return the name of the section containing function coverage mapping
-/// data.
-inline StringRef getInstrProfCoverageSectionName(bool AddSegment) {
- return AddSegment ? "__LLVM_COV," INSTR_PROF_COVMAP_SECT_NAME_STR
- : INSTR_PROF_COVMAP_SECT_NAME_STR;
+/// Return the name profile runtime entry point to do value range profiling.
+inline StringRef getInstrProfValueRangeProfFuncName() {
+ return INSTR_PROF_VALUE_RANGE_PROF_FUNC_STR;
}
/// Return the name prefix of variables containing instrumented function names.
@@ -201,6 +194,7 @@ GlobalVariable *createPGOFuncNameVar(Function &F, StringRef PGOFuncName);
GlobalVariable *createPGOFuncNameVar(Module &M,
GlobalValue::LinkageTypes Linkage,
StringRef PGOFuncName);
+
/// Return the initializer in string of the PGO name var \c NameVar.
StringRef getPGOFuncNameVarInitializer(GlobalVariable *NameVar);
@@ -218,13 +212,14 @@ StringRef getFuncNameWithoutPrefix(StringRef PGOFuncName,
/// third field is the uncompressed strings; otherwise it is the
/// compressed string. When the string compression is off, the
/// second field will have value zero.
-Error collectPGOFuncNameStrings(const std::vector<std::string> &NameStrs,
+Error collectPGOFuncNameStrings(ArrayRef<std::string> NameStrs,
bool doCompression, std::string &Result);
+
/// Produce \c Result string with the same format described above. The input
/// is vector of PGO function name variables that are referenced.
-Error collectPGOFuncNameStrings(const std::vector<GlobalVariable *> &NameVars,
+Error collectPGOFuncNameStrings(ArrayRef<GlobalVariable *> NameVars,
std::string &Result, bool doCompression = true);
-class InstrProfSymtab;
+
/// \c NameStrings is a string composed of one of more sub-strings encoded in
/// the format described above. The substrings are separated by 0 or more zero
/// bytes. This method decodes the string and populates the \c Symtab.
@@ -244,8 +239,6 @@ enum InstrProfValueKind : uint32_t {
#include "llvm/ProfileData/InstrProfData.inc"
};
-struct InstrProfRecord;
-
/// Get the value profile data for value site \p SiteIdx from \p InstrProfR
/// and annotate the instruction \p Inst with the value profile meta data.
/// Annotate up to \p MaxMDCount (default 3) number of records per value site.
@@ -253,11 +246,11 @@ void annotateValueSite(Module &M, Instruction &Inst,
const InstrProfRecord &InstrProfR,
InstrProfValueKind ValueKind, uint32_t SiteIndx,
uint32_t MaxMDCount = 3);
+
/// Same as the above interface but using an ArrayRef, as well as \p Sum.
void annotateValueSite(Module &M, Instruction &Inst,
- ArrayRef<InstrProfValueData> VDs,
- uint64_t Sum, InstrProfValueKind ValueKind,
- uint32_t MaxMDCount);
+ ArrayRef<InstrProfValueData> VDs, uint64_t Sum,
+ InstrProfValueKind ValueKind, uint32_t MaxMDCount);
/// Extract the value profile data from \p Inst which is annotated with
/// value profile meta data. Return false if there is no value data annotated,
@@ -347,25 +340,22 @@ class SoftInstrProfErrors {
/// the first such error for reporting purposes.
/// The first soft error encountered.
- instrprof_error FirstError;
+ instrprof_error FirstError = instrprof_error::success;
/// The number of hash mismatches.
- unsigned NumHashMismatches;
+ unsigned NumHashMismatches = 0;
/// The number of count mismatches.
- unsigned NumCountMismatches;
+ unsigned NumCountMismatches = 0;
/// The number of counter overflows.
- unsigned NumCounterOverflows;
+ unsigned NumCounterOverflows = 0;
/// The number of value site count mismatches.
- unsigned NumValueSiteCountMismatches;
+ unsigned NumValueSiteCountMismatches = 0;
public:
- SoftInstrProfErrors()
- : FirstError(instrprof_error::success), NumHashMismatches(0),
- NumCountMismatches(0), NumCounterOverflows(0),
- NumValueSiteCountMismatches(0) {}
+ SoftInstrProfErrors() = default;
~SoftInstrProfErrors() {
assert(FirstError == instrprof_error::success &&
@@ -401,12 +391,16 @@ public:
};
namespace object {
+
class SectionRef;
-}
+
+} // end namespace object
namespace IndexedInstrProf {
+
uint64_t ComputeHash(StringRef K);
-}
+
+} // end namespace IndexedInstrProf
/// A symbol table used for function PGO name look-up with keys
/// (such as pointers, md5hash values) to the function. A function's
@@ -415,11 +409,11 @@ uint64_t ComputeHash(StringRef K);
/// on how PGO name is formed.
class InstrProfSymtab {
public:
- typedef std::vector<std::pair<uint64_t, uint64_t>> AddrHashMap;
+ using AddrHashMap = std::vector<std::pair<uint64_t, uint64_t>>;
private:
StringRef Data;
- uint64_t Address;
+ uint64_t Address = 0;
// Unique name strings.
StringSet<> NameTab;
// A map from MD5 keys to function name strings.
@@ -432,9 +426,7 @@ private:
AddrHashMap AddrToMD5Map;
public:
- InstrProfSymtab()
- : Data(), Address(0), NameTab(), MD5NameMap(), MD5FuncMap(),
- AddrToMD5Map() {}
+ InstrProfSymtab() = default;
/// Create InstrProfSymtab from an object file section which
/// contains function PGO names. When section may contain raw
@@ -443,53 +435,69 @@ public:
/// the section base address. The decompression will be delayed
/// until before it is used. See also \c create(StringRef) method.
Error create(object::SectionRef &Section);
+
/// This interface is used by reader of CoverageMapping test
/// format.
inline Error create(StringRef D, uint64_t BaseAddr);
+
/// \c NameStrings is a string composed of one of more sub-strings
/// encoded in the format described in \c collectPGOFuncNameStrings.
/// This method is a wrapper to \c readPGOFuncNameStrings method.
inline Error create(StringRef NameStrings);
+
/// A wrapper interface to populate the PGO symtab with functions
/// decls from module \c M. This interface is used by transformation
/// passes such as indirect function call promotion. Variable \c InLTO
/// indicates if this is called from LTO optimization passes.
- void create(Module &M, bool InLTO = false);
+ Error create(Module &M, bool InLTO = false);
+
/// Create InstrProfSymtab from a set of names iteratable from
/// \p IterRange. This interface is used by IndexedProfReader.
- template <typename NameIterRange> void create(const NameIterRange &IterRange);
+ template <typename NameIterRange> Error create(const NameIterRange &IterRange);
+
// If the symtab is created by a series of calls to \c addFuncName, \c
// finalizeSymtab needs to be called before looking up function names.
// This is required because the underlying map is a vector (for space
// efficiency) which needs to be sorted.
inline void finalizeSymtab();
+
/// Update the symtab by adding \p FuncName to the table. This interface
/// is used by the raw and text profile readers.
- void addFuncName(StringRef FuncName) {
+ Error addFuncName(StringRef FuncName) {
+ if (FuncName.empty())
+ return make_error<InstrProfError>(instrprof_error::malformed);
auto Ins = NameTab.insert(FuncName);
if (Ins.second)
MD5NameMap.push_back(std::make_pair(
IndexedInstrProf::ComputeHash(FuncName), Ins.first->getKey()));
+ return Error::success();
}
+
/// Map a function address to its name's MD5 hash. This interface
/// is only used by the raw profiler reader.
void mapAddress(uint64_t Addr, uint64_t MD5Val) {
AddrToMD5Map.push_back(std::make_pair(Addr, MD5Val));
}
+
AddrHashMap &getAddrHashMap() { return AddrToMD5Map; }
+
/// Return function's PGO name from the function name's symbol
/// address in the object file. If an error occurs, return
/// an empty string.
StringRef getFuncName(uint64_t FuncNameAddress, size_t NameSize);
+
/// Return function's PGO name from the name's md5 hash value.
/// If not found, return an empty string.
inline StringRef getFuncName(uint64_t FuncMD5Hash);
+
/// Return function from the name's md5 hash. Return nullptr if not found.
inline Function *getFunction(uint64_t FuncMD5Hash);
+
/// Return the function's original assembly name by stripping off
/// the prefix attached (to symbols with priviate linkage). For
/// global functions, it returns the same string as getFuncName.
inline StringRef getOrigFuncName(uint64_t FuncMD5Hash);
+
/// Return the name section data.
inline StringRef getNameData() const { return Data; }
};
@@ -505,11 +513,13 @@ Error InstrProfSymtab::create(StringRef NameStrings) {
}
template <typename NameIterRange>
-void InstrProfSymtab::create(const NameIterRange &IterRange) {
+Error InstrProfSymtab::create(const NameIterRange &IterRange) {
for (auto Name : IterRange)
- addFuncName(Name);
+ if (Error E = addFuncName(Name))
+ return E;
finalizeSymtab();
+ return Error::success();
}
void InstrProfSymtab::finalizeSymtab() {
@@ -571,48 +581,70 @@ struct InstrProfValueSiteRecord {
/// Merge data from another InstrProfValueSiteRecord
/// Optionally scale merged counts by \p Weight.
- void merge(SoftInstrProfErrors &SIPE, InstrProfValueSiteRecord &Input,
- uint64_t Weight = 1);
+ void merge(InstrProfValueSiteRecord &Input, uint64_t Weight,
+ function_ref<void(instrprof_error)> Warn);
/// Scale up value profile data counts.
- void scale(SoftInstrProfErrors &SIPE, uint64_t Weight);
+ void scale(uint64_t Weight, function_ref<void(instrprof_error)> Warn);
};
/// Profiling information for a single function.
struct InstrProfRecord {
- InstrProfRecord() : SIPE() {}
- InstrProfRecord(StringRef Name, uint64_t Hash, std::vector<uint64_t> Counts)
- : Name(Name), Hash(Hash), Counts(std::move(Counts)), SIPE() {}
- StringRef Name;
- uint64_t Hash;
std::vector<uint64_t> Counts;
- SoftInstrProfErrors SIPE;
- typedef std::vector<std::pair<uint64_t, uint64_t>> ValueMapType;
+ InstrProfRecord() = default;
+ InstrProfRecord(std::vector<uint64_t> Counts) : Counts(std::move(Counts)) {}
+ InstrProfRecord(InstrProfRecord &&) = default;
+ InstrProfRecord(const InstrProfRecord &RHS)
+ : Counts(RHS.Counts),
+ ValueData(RHS.ValueData
+ ? llvm::make_unique<ValueProfData>(*RHS.ValueData)
+ : nullptr) {}
+ InstrProfRecord &operator=(InstrProfRecord &&) = default;
+ InstrProfRecord &operator=(const InstrProfRecord &RHS) {
+ Counts = RHS.Counts;
+ if (!RHS.ValueData) {
+ ValueData = nullptr;
+ return *this;
+ }
+ if (!ValueData)
+ ValueData = llvm::make_unique<ValueProfData>(*RHS.ValueData);
+ else
+ *ValueData = *RHS.ValueData;
+ return *this;
+ }
+
+ using ValueMapType = std::vector<std::pair<uint64_t, uint64_t>>;
/// Return the number of value profile kinds with non-zero number
/// of profile sites.
inline uint32_t getNumValueKinds() const;
/// Return the number of instrumented sites for ValueKind.
inline uint32_t getNumValueSites(uint32_t ValueKind) const;
+
/// Return the total number of ValueData for ValueKind.
inline uint32_t getNumValueData(uint32_t ValueKind) const;
+
/// Return the number of value data collected for ValueKind at profiling
/// site: Site.
inline uint32_t getNumValueDataForSite(uint32_t ValueKind,
uint32_t Site) const;
+
/// Return the array of profiled values at \p Site. If \p TotalC
/// is not null, the total count of all target values at this site
/// will be stored in \c *TotalC.
inline std::unique_ptr<InstrProfValueData[]>
getValueForSite(uint32_t ValueKind, uint32_t Site,
- uint64_t *TotalC = 0) const;
+ uint64_t *TotalC = nullptr) const;
+
/// Get the target value/counts of kind \p ValueKind collected at site
/// \p Site and store the result in array \p Dest. Return the total
/// counts of all target values at this site.
inline uint64_t getValueForSite(InstrProfValueData Dest[], uint32_t ValueKind,
uint32_t Site) const;
+
/// Reserve space for NumValueSites sites.
inline void reserveSites(uint32_t ValueKind, uint32_t NumValueSites);
+
/// Add ValueData for ValueKind at value Site.
void addValueData(uint32_t ValueKind, uint32_t Site,
InstrProfValueData *VData, uint32_t N,
@@ -620,48 +652,72 @@ struct InstrProfRecord {
/// Merge the counts in \p Other into this one.
/// Optionally scale merged counts by \p Weight.
- void merge(InstrProfRecord &Other, uint64_t Weight = 1);
+ void merge(InstrProfRecord &Other, uint64_t Weight,
+ function_ref<void(instrprof_error)> Warn);
/// Scale up profile counts (including value profile data) by
/// \p Weight.
- void scale(uint64_t Weight);
+ void scale(uint64_t Weight, function_ref<void(instrprof_error)> Warn);
/// Sort value profile data (per site) by count.
void sortValueData() {
- for (uint32_t Kind = IPVK_First; Kind <= IPVK_Last; ++Kind) {
- std::vector<InstrProfValueSiteRecord> &SiteRecords =
- getValueSitesForKind(Kind);
- for (auto &SR : SiteRecords)
+ for (uint32_t Kind = IPVK_First; Kind <= IPVK_Last; ++Kind)
+ for (auto &SR : getValueSitesForKind(Kind))
SR.sortByCount();
- }
}
- /// Clear value data entries
- void clearValueData() {
- for (uint32_t Kind = IPVK_First; Kind <= IPVK_Last; ++Kind)
- getValueSitesForKind(Kind).clear();
+
+ /// Clear value data entries and edge counters.
+ void Clear() {
+ Counts.clear();
+ clearValueData();
}
- /// Get the error contained within the record's soft error counter.
- Error takeError() { return SIPE.takeError(); }
+ /// Clear value data entries
+ void clearValueData() { ValueData = nullptr; }
private:
- std::vector<InstrProfValueSiteRecord> IndirectCallSites;
- const std::vector<InstrProfValueSiteRecord> &
+ struct ValueProfData {
+ std::vector<InstrProfValueSiteRecord> IndirectCallSites;
+ std::vector<InstrProfValueSiteRecord> MemOPSizes;
+ };
+ std::unique_ptr<ValueProfData> ValueData;
+
+ MutableArrayRef<InstrProfValueSiteRecord>
+ getValueSitesForKind(uint32_t ValueKind) {
+ // Cast to /add/ const (should be an implicit_cast, ideally, if that's ever
+ // implemented in LLVM) to call the const overload of this function, then
+ // cast away the constness from the result.
+ auto AR = const_cast<const InstrProfRecord *>(this)->getValueSitesForKind(
+ ValueKind);
+ return makeMutableArrayRef(
+ const_cast<InstrProfValueSiteRecord *>(AR.data()), AR.size());
+ }
+ ArrayRef<InstrProfValueSiteRecord>
getValueSitesForKind(uint32_t ValueKind) const {
+ if (!ValueData)
+ return None;
switch (ValueKind) {
case IPVK_IndirectCallTarget:
- return IndirectCallSites;
+ return ValueData->IndirectCallSites;
+ case IPVK_MemOPSize:
+ return ValueData->MemOPSizes;
default:
llvm_unreachable("Unknown value kind!");
}
- return IndirectCallSites;
}
std::vector<InstrProfValueSiteRecord> &
- getValueSitesForKind(uint32_t ValueKind) {
- return const_cast<std::vector<InstrProfValueSiteRecord> &>(
- const_cast<const InstrProfRecord *>(this)
- ->getValueSitesForKind(ValueKind));
+ getOrCreateValueSitesForKind(uint32_t ValueKind) {
+ if (!ValueData)
+ ValueData = llvm::make_unique<ValueProfData>();
+ switch (ValueKind) {
+ case IPVK_IndirectCallTarget:
+ return ValueData->IndirectCallSites;
+ case IPVK_MemOPSize:
+ return ValueData->MemOPSizes;
+ default:
+ llvm_unreachable("Unknown value kind!");
+ }
}
// Map indirect call target name hash to name string.
@@ -670,10 +726,23 @@ private:
// Merge Value Profile data from Src record to this record for ValueKind.
// Scale merged value counts by \p Weight.
- void mergeValueProfData(uint32_t ValueKind, InstrProfRecord &Src,
- uint64_t Weight);
+ void mergeValueProfData(uint32_t ValkeKind, InstrProfRecord &Src,
+ uint64_t Weight,
+ function_ref<void(instrprof_error)> Warn);
+
// Scale up value profile data count.
- void scaleValueProfData(uint32_t ValueKind, uint64_t Weight);
+ void scaleValueProfData(uint32_t ValueKind, uint64_t Weight,
+ function_ref<void(instrprof_error)> Warn);
+};
+
+struct NamedInstrProfRecord : InstrProfRecord {
+ StringRef Name;
+ uint64_t Hash;
+
+ NamedInstrProfRecord() = default;
+ NamedInstrProfRecord(StringRef Name, uint64_t Hash,
+ std::vector<uint64_t> Counts)
+ : InstrProfRecord(std::move(Counts)), Name(Name), Hash(Hash) {}
};
uint32_t InstrProfRecord::getNumValueKinds() const {
@@ -685,11 +754,8 @@ uint32_t InstrProfRecord::getNumValueKinds() const {
uint32_t InstrProfRecord::getNumValueData(uint32_t ValueKind) const {
uint32_t N = 0;
- const std::vector<InstrProfValueSiteRecord> &SiteRecords =
- getValueSitesForKind(ValueKind);
- for (auto &SR : SiteRecords) {
+ for (auto &SR : getValueSitesForKind(ValueKind))
N += SR.ValueData.size();
- }
return N;
}
@@ -706,7 +772,7 @@ std::unique_ptr<InstrProfValueData[]>
InstrProfRecord::getValueForSite(uint32_t ValueKind, uint32_t Site,
uint64_t *TotalC) const {
uint64_t Dummy;
- uint64_t &TotalCount = (TotalC == 0 ? Dummy : *TotalC);
+ uint64_t &TotalCount = (TotalC == nullptr ? Dummy : *TotalC);
uint32_t N = getNumValueDataForSite(ValueKind, Site);
if (N == 0) {
TotalCount = 0;
@@ -734,9 +800,9 @@ uint64_t InstrProfRecord::getValueForSite(InstrProfValueData Dest[],
}
void InstrProfRecord::reserveSites(uint32_t ValueKind, uint32_t NumValueSites) {
- std::vector<InstrProfValueSiteRecord> &ValueSites =
- getValueSitesForKind(ValueKind);
- ValueSites.reserve(NumValueSites);
+ if (!NumValueSites)
+ return;
+ getOrCreateValueSitesForKind(ValueKind).reserve(NumValueSites);
}
inline support::endianness getHostEndianness() {
@@ -762,7 +828,6 @@ namespace IndexedInstrProf {
enum class HashT : uint32_t {
MD5,
-
Last = MD5
};
@@ -816,7 +881,6 @@ struct Header {
// format. It is introduced in version 4. The summary data follows
// right after the profile file header.
struct Summary {
-
struct Entry {
uint64_t Cutoff; ///< The required percentile of total execution count.
uint64_t
@@ -849,6 +913,11 @@ struct Summary {
// The number of Cutoff Entries (Summary::Entry) following summary fields.
uint64_t NumCutoffEntries;
+ Summary() = delete;
+ Summary(uint32_t Size) { memset(this, 0, Size); }
+
+ void operator delete(void *ptr) { ::operator delete(ptr); }
+
static uint32_t getSize(uint32_t NumSumFields, uint32_t NumCutoffEntries) {
return sizeof(Summary) + NumCutoffEntries * sizeof(Entry) +
NumSumFields * sizeof(uint64_t);
@@ -857,13 +926,16 @@ struct Summary {
const uint64_t *getSummaryDataBase() const {
return reinterpret_cast<const uint64_t *>(this + 1);
}
+
uint64_t *getSummaryDataBase() {
return reinterpret_cast<uint64_t *>(this + 1);
}
+
const Entry *getCutoffEntryBase() const {
return reinterpret_cast<const Entry *>(
&getSummaryDataBase()[NumSummaryFields]);
}
+
Entry *getCutoffEntryBase() {
return reinterpret_cast<Entry *>(&getSummaryDataBase()[NumSummaryFields]);
}
@@ -877,23 +949,20 @@ struct Summary {
}
const Entry &getEntry(uint32_t I) const { return getCutoffEntryBase()[I]; }
+
void setEntry(uint32_t I, const ProfileSummaryEntry &E) {
Entry &ER = getCutoffEntryBase()[I];
ER.Cutoff = E.Cutoff;
ER.MinBlockCount = E.MinCount;
ER.NumBlocks = E.NumCounts;
}
-
- Summary(uint32_t Size) { memset(this, 0, Size); }
- void operator delete(void *ptr) { ::operator delete(ptr); }
-
- Summary() = delete;
};
inline std::unique_ptr<Summary> allocSummary(uint32_t TotalSize) {
return std::unique_ptr<Summary>(new (::operator new(TotalSize))
Summary(TotalSize));
}
+
} // end namespace IndexedInstrProf
namespace RawInstrProf {
@@ -937,6 +1006,10 @@ struct Header {
} // end namespace RawInstrProf
+// Parse MemOP Size range option.
+void getMemOPSizeRangeFromOption(StringRef Str, int64_t &RangeStart,
+ int64_t &RangeLast);
+
} // end namespace llvm
#endif // LLVM_PROFILEDATA_INSTRPROF_H
diff --git a/contrib/llvm/include/llvm/ProfileData/InstrProfData.inc b/contrib/llvm/include/llvm/ProfileData/InstrProfData.inc
index f7c22d1..be0dd4a 100644
--- a/contrib/llvm/include/llvm/ProfileData/InstrProfData.inc
+++ b/contrib/llvm/include/llvm/ProfileData/InstrProfData.inc
@@ -153,7 +153,17 @@ INSTR_PROF_RAW_HEADER(uint64_t, ValueKindLast, IPVK_Last)
VALUE_PROF_FUNC_PARAM(uint64_t, TargetValue, Type::getInt64Ty(Ctx)) \
INSTR_PROF_COMMA
VALUE_PROF_FUNC_PARAM(void *, Data, Type::getInt8PtrTy(Ctx)) INSTR_PROF_COMMA
+#ifndef VALUE_RANGE_PROF
VALUE_PROF_FUNC_PARAM(uint32_t, CounterIndex, Type::getInt32Ty(Ctx))
+#else /* VALUE_RANGE_PROF */
+VALUE_PROF_FUNC_PARAM(uint32_t, CounterIndex, Type::getInt32Ty(Ctx)) \
+ INSTR_PROF_COMMA
+VALUE_PROF_FUNC_PARAM(uint64_t, PreciseRangeStart, Type::getInt64Ty(Ctx)) \
+ INSTR_PROF_COMMA
+VALUE_PROF_FUNC_PARAM(uint64_t, PreciseRangeLast, Type::getInt64Ty(Ctx)) \
+ INSTR_PROF_COMMA
+VALUE_PROF_FUNC_PARAM(uint64_t, LargeValue, Type::getInt64Ty(Ctx))
+#endif /*VALUE_RANGE_PROF */
#undef VALUE_PROF_FUNC_PARAM
#undef INSTR_PROF_COMMA
/* VALUE_PROF_FUNC_PARAM end */
@@ -174,13 +184,15 @@ VALUE_PROF_FUNC_PARAM(uint32_t, CounterIndex, Type::getInt32Ty(Ctx))
* name hash and the function address.
*/
VALUE_PROF_KIND(IPVK_IndirectCallTarget, 0)
+/* For memory intrinsic functions size profiling. */
+VALUE_PROF_KIND(IPVK_MemOPSize, 1)
/* These two kinds must be the last to be
* declared. This is to make sure the string
* array created with the template can be
* indexed with the kind value.
*/
VALUE_PROF_KIND(IPVK_First, IPVK_IndirectCallTarget)
-VALUE_PROF_KIND(IPVK_Last, IPVK_IndirectCallTarget)
+VALUE_PROF_KIND(IPVK_Last, IPVK_MemOPSize)
#undef VALUE_PROF_KIND
/* VALUE_PROF_KIND end */
@@ -234,6 +246,31 @@ COVMAP_HEADER(uint32_t, Int32Ty, Version, \
/* COVMAP_HEADER end. */
+#ifdef INSTR_PROF_SECT_ENTRY
+#define INSTR_PROF_DATA_DEFINED
+INSTR_PROF_SECT_ENTRY(IPSK_data, \
+ INSTR_PROF_QUOTE(INSTR_PROF_DATA_COMMON), \
+ INSTR_PROF_QUOTE(INSTR_PROF_DATA_COFF), "__DATA,")
+INSTR_PROF_SECT_ENTRY(IPSK_cnts, \
+ INSTR_PROF_QUOTE(INSTR_PROF_CNTS_COMMON), \
+ INSTR_PROF_QUOTE(INSTR_PROF_CNTS_COFF), "__DATA,")
+INSTR_PROF_SECT_ENTRY(IPSK_name, \
+ INSTR_PROF_QUOTE(INSTR_PROF_NAME_COMMON), \
+ INSTR_PROF_QUOTE(INSTR_PROF_NAME_COFF), "__DATA,")
+INSTR_PROF_SECT_ENTRY(IPSK_vals, \
+ INSTR_PROF_QUOTE(INSTR_PROF_VALS_COMMON), \
+ INSTR_PROF_QUOTE(INSTR_PROF_VALS_COFF), "__DATA,")
+INSTR_PROF_SECT_ENTRY(IPSK_vnodes, \
+ INSTR_PROF_QUOTE(INSTR_PROF_VNODES_COMMON), \
+ INSTR_PROF_QUOTE(INSTR_PROF_VNODES_COFF), "__DATA,")
+INSTR_PROF_SECT_ENTRY(IPSK_covmap, \
+ INSTR_PROF_QUOTE(INSTR_PROF_COVMAP_COMMON), \
+ INSTR_PROF_QUOTE(INSTR_PROF_COVMAP_COFF), "__LLVM_COV,")
+
+#undef INSTR_PROF_SECT_ENTRY
+#endif
+
+
#ifdef INSTR_PROF_VALUE_PROF_DATA
#define INSTR_PROF_DATA_DEFINED
@@ -610,17 +647,47 @@ serializeValueProfDataFrom(ValueProfRecordClosure *Closure,
* specified via command line. */
#define INSTR_PROF_PROFILE_NAME_VAR __llvm_profile_filename
+/* section name strings common to all targets other
+ than WIN32 */
+#define INSTR_PROF_DATA_COMMON __llvm_prf_data
+#define INSTR_PROF_NAME_COMMON __llvm_prf_names
+#define INSTR_PROF_CNTS_COMMON __llvm_prf_cnts
+#define INSTR_PROF_VALS_COMMON __llvm_prf_vals
+#define INSTR_PROF_VNODES_COMMON __llvm_prf_vnds
+#define INSTR_PROF_COVMAP_COMMON __llvm_covmap
+/* Win32 */
+#define INSTR_PROF_DATA_COFF .lprfd
+#define INSTR_PROF_NAME_COFF .lprfn
+#define INSTR_PROF_CNTS_COFF .lprfc
+#define INSTR_PROF_VALS_COFF .lprfv
+#define INSTR_PROF_VNODES_COFF .lprfnd
+#define INSTR_PROF_COVMAP_COFF .lcovmap
+
+#ifdef _WIN32
/* Runtime section names and name strings. */
-#define INSTR_PROF_DATA_SECT_NAME __llvm_prf_data
-#define INSTR_PROF_NAME_SECT_NAME __llvm_prf_names
-#define INSTR_PROF_CNTS_SECT_NAME __llvm_prf_cnts
+#define INSTR_PROF_DATA_SECT_NAME INSTR_PROF_DATA_COFF
+#define INSTR_PROF_NAME_SECT_NAME INSTR_PROF_NAME_COFF
+#define INSTR_PROF_CNTS_SECT_NAME INSTR_PROF_CNTS_COFF
/* Array of pointers. Each pointer points to a list
* of value nodes associated with one value site.
*/
-#define INSTR_PROF_VALS_SECT_NAME __llvm_prf_vals
+#define INSTR_PROF_VALS_SECT_NAME INSTR_PROF_VALS_COFF
/* Value profile nodes section. */
-#define INSTR_PROF_VNODES_SECT_NAME __llvm_prf_vnds
-#define INSTR_PROF_COVMAP_SECT_NAME __llvm_covmap
+#define INSTR_PROF_VNODES_SECT_NAME INSTR_PROF_VNODES_COFF
+#define INSTR_PROF_COVMAP_SECT_NAME INSTR_PROF_COVMAP_COFF
+#else
+/* Runtime section names and name strings. */
+#define INSTR_PROF_DATA_SECT_NAME INSTR_PROF_DATA_COMMON
+#define INSTR_PROF_NAME_SECT_NAME INSTR_PROF_NAME_COMMON
+#define INSTR_PROF_CNTS_SECT_NAME INSTR_PROF_CNTS_COMMON
+/* Array of pointers. Each pointer points to a list
+ * of value nodes associated with one value site.
+ */
+#define INSTR_PROF_VALS_SECT_NAME INSTR_PROF_VALS_COMMON
+/* Value profile nodes section. */
+#define INSTR_PROF_VNODES_SECT_NAME INSTR_PROF_VNODES_COMMON
+#define INSTR_PROF_COVMAP_SECT_NAME INSTR_PROF_COVMAP_COMMON
+#endif
#define INSTR_PROF_DATA_SECT_NAME_STR \
INSTR_PROF_QUOTE(INSTR_PROF_DATA_SECT_NAME)
@@ -649,6 +716,9 @@ serializeValueProfDataFrom(ValueProfRecordClosure *Closure,
#define INSTR_PROF_VALUE_PROF_FUNC __llvm_profile_instrument_target
#define INSTR_PROF_VALUE_PROF_FUNC_STR \
INSTR_PROF_QUOTE(INSTR_PROF_VALUE_PROF_FUNC)
+#define INSTR_PROF_VALUE_RANGE_PROF_FUNC __llvm_profile_instrument_range
+#define INSTR_PROF_VALUE_RANGE_PROF_FUNC_STR \
+ INSTR_PROF_QUOTE(INSTR_PROF_VALUE_RANGE_PROF_FUNC)
/* InstrProfile per-function control data alignment. */
#define INSTR_PROF_DATA_ALIGNMENT 8
diff --git a/contrib/llvm/include/llvm/ProfileData/InstrProfReader.h b/contrib/llvm/include/llvm/ProfileData/InstrProfReader.h
index 65b11f6..424360e 100644
--- a/contrib/llvm/include/llvm/ProfileData/InstrProfReader.h
+++ b/contrib/llvm/include/llvm/ProfileData/InstrProfReader.h
@@ -1,4 +1,4 @@
-//=-- InstrProfReader.h - Instrumented profiling readers ----------*- C++ -*-=//
+//===- InstrProfReader.h - Instrumented profiling readers -------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -16,14 +16,23 @@
#define LLVM_PROFILEDATA_INSTRPROFREADER_H
#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/IR/ProfileSummary.h"
#include "llvm/ProfileData/InstrProf.h"
-#include "llvm/Support/EndianStream.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
#include "llvm/Support/LineIterator.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/OnDiskHashTable.h"
-#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/SwapByteOrder.h"
+#include <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
#include <iterator>
+#include <memory>
+#include <utility>
+#include <vector>
namespace llvm {
@@ -31,38 +40,42 @@ class InstrProfReader;
/// A file format agnostic iterator over profiling data.
class InstrProfIterator : public std::iterator<std::input_iterator_tag,
- InstrProfRecord> {
- InstrProfReader *Reader;
- InstrProfRecord Record;
+ NamedInstrProfRecord> {
+ InstrProfReader *Reader = nullptr;
+ value_type Record;
void Increment();
+
public:
- InstrProfIterator() : Reader(nullptr) {}
+ InstrProfIterator() = default;
InstrProfIterator(InstrProfReader *Reader) : Reader(Reader) { Increment(); }
InstrProfIterator &operator++() { Increment(); return *this; }
bool operator==(const InstrProfIterator &RHS) { return Reader == RHS.Reader; }
bool operator!=(const InstrProfIterator &RHS) { return Reader != RHS.Reader; }
- InstrProfRecord &operator*() { return Record; }
- InstrProfRecord *operator->() { return &Record; }
+ value_type &operator*() { return Record; }
+ value_type *operator->() { return &Record; }
};
/// Base class and interface for reading profiling data of any known instrprof
-/// format. Provides an iterator over InstrProfRecords.
+/// format. Provides an iterator over NamedInstrProfRecords.
class InstrProfReader {
- instrprof_error LastError;
+ instrprof_error LastError = instrprof_error::success;
public:
- InstrProfReader() : LastError(instrprof_error::success), Symtab() {}
- virtual ~InstrProfReader() {}
+ InstrProfReader() = default;
+ virtual ~InstrProfReader() = default;
/// Read the header. Required before reading first record.
virtual Error readHeader() = 0;
+
/// Read a single record.
- virtual Error readNextRecord(InstrProfRecord &Record) = 0;
+ virtual Error readNextRecord(NamedInstrProfRecord &Record) = 0;
+
/// Iterator over profile data.
InstrProfIterator begin() { return InstrProfIterator(this); }
InstrProfIterator end() { return InstrProfIterator(); }
+
virtual bool isIRLevelProfile() const = 0;
/// Return the PGO symtab. There are three different readers:
@@ -79,6 +92,7 @@ public:
protected:
std::unique_ptr<InstrProfSymtab> Symtab;
+
/// Set the current error and return same.
Error error(instrprof_error Err) {
LastError = Err;
@@ -86,6 +100,7 @@ protected:
return Error::success();
return make_error<InstrProfError>(Err);
}
+
Error error(Error E) { return error(InstrProfError::take(std::move(E))); }
/// Clear the current error and return a successful one.
@@ -94,8 +109,10 @@ protected:
public:
/// Return true if the reader has finished reading the profile data.
bool isEOF() { return LastError == instrprof_error::eof; }
+
/// Return true if the reader encountered an error reading profiling data.
bool hasError() { return LastError != instrprof_error::success && !isEOF(); }
+
/// Get the current error.
Error getError() {
if (hasError())
@@ -125,16 +142,15 @@ private:
std::unique_ptr<MemoryBuffer> DataBuffer;
/// Iterator over the profile data.
line_iterator Line;
- bool IsIRLevelProfile;
+ bool IsIRLevelProfile = false;
- TextInstrProfReader(const TextInstrProfReader &) = delete;
- TextInstrProfReader &operator=(const TextInstrProfReader &) = delete;
Error readValueProfileData(InstrProfRecord &Record);
public:
TextInstrProfReader(std::unique_ptr<MemoryBuffer> DataBuffer_)
- : DataBuffer(std::move(DataBuffer_)), Line(*DataBuffer, true, '#'),
- IsIRLevelProfile(false) {}
+ : DataBuffer(std::move(DataBuffer_)), Line(*DataBuffer, true, '#') {}
+ TextInstrProfReader(const TextInstrProfReader &) = delete;
+ TextInstrProfReader &operator=(const TextInstrProfReader &) = delete;
/// Return true if the given buffer is in text instrprof format.
static bool hasFormat(const MemoryBuffer &Buffer);
@@ -143,8 +159,9 @@ public:
/// Read the header.
Error readHeader() override;
+
/// Read a single record.
- Error readNextRecord(InstrProfRecord &Record) override;
+ Error readNextRecord(NamedInstrProfRecord &Record) override;
InstrProfSymtab &getSymtab() override {
assert(Symtab.get());
@@ -184,15 +201,16 @@ private:
InstrProfRecord::ValueMapType FunctionPtrToNameMap;
- RawInstrProfReader(const RawInstrProfReader &) = delete;
- RawInstrProfReader &operator=(const RawInstrProfReader &) = delete;
public:
RawInstrProfReader(std::unique_ptr<MemoryBuffer> DataBuffer)
- : DataBuffer(std::move(DataBuffer)) { }
+ : DataBuffer(std::move(DataBuffer)) {}
+ RawInstrProfReader(const RawInstrProfReader &) = delete;
+ RawInstrProfReader &operator=(const RawInstrProfReader &) = delete;
static bool hasFormat(const MemoryBuffer &DataBuffer);
Error readHeader() override;
- Error readNextRecord(InstrProfRecord &Record) override;
+ Error readNextRecord(NamedInstrProfRecord &Record) override;
+
bool isIRLevelProfile() const override {
return (Version & VARIANT_MASK_IR_PROF) != 0;
}
@@ -206,9 +224,11 @@ private:
Error createSymtab(InstrProfSymtab &Symtab);
Error readNextHeader(const char *CurrentPos);
Error readHeader(const RawInstrProf::Header &Header);
+
template <class IntT> IntT swap(IntT Int) const {
return ShouldSwapBytes ? sys::getSwappedBytes(Int) : Int;
}
+
support::endianness getDataEndianness() const {
support::endianness HostEndian = getHostEndianness();
if (!ShouldSwapBytes)
@@ -222,15 +242,18 @@ private:
inline uint8_t getNumPaddingBytes(uint64_t SizeInBytes) {
return 7 & (sizeof(uint64_t) - SizeInBytes % sizeof(uint64_t));
}
- Error readName(InstrProfRecord &Record);
- Error readFuncHash(InstrProfRecord &Record);
+
+ Error readName(NamedInstrProfRecord &Record);
+ Error readFuncHash(NamedInstrProfRecord &Record);
Error readRawCounts(InstrProfRecord &Record);
Error readValueProfilingData(InstrProfRecord &Record);
bool atEnd() const { return Data == DataEnd; }
+
void advanceData() {
Data++;
ValueDataStart += CurValueDataSize;
}
+
const char *getNextHeaderPos() const {
assert(atEnd());
return (const char *)ValueDataStart;
@@ -240,40 +263,42 @@ private:
ptrdiff_t Offset = (swap(CounterPtr) - CountersDelta) / sizeof(uint64_t);
return CountersStart + Offset;
}
+
StringRef getName(uint64_t NameRef) const {
return Symtab->getFuncName(swap(NameRef));
}
};
-typedef RawInstrProfReader<uint32_t> RawInstrProfReader32;
-typedef RawInstrProfReader<uint64_t> RawInstrProfReader64;
+using RawInstrProfReader32 = RawInstrProfReader<uint32_t>;
+using RawInstrProfReader64 = RawInstrProfReader<uint64_t>;
namespace IndexedInstrProf {
+
enum class HashT : uint32_t;
-}
+
+} // end namespace IndexedInstrProf
/// Trait for lookups into the on-disk hash table for the binary instrprof
/// format.
class InstrProfLookupTrait {
- std::vector<InstrProfRecord> DataBuffer;
+ std::vector<NamedInstrProfRecord> DataBuffer;
IndexedInstrProf::HashT HashType;
unsigned FormatVersion;
// Endianness of the input value profile data.
// It should be LE by default, but can be changed
// for testing purpose.
- support::endianness ValueProfDataEndianness;
+ support::endianness ValueProfDataEndianness = support::little;
public:
InstrProfLookupTrait(IndexedInstrProf::HashT HashType, unsigned FormatVersion)
- : HashType(HashType), FormatVersion(FormatVersion),
- ValueProfDataEndianness(support::little) {}
+ : HashType(HashType), FormatVersion(FormatVersion) {}
- typedef ArrayRef<InstrProfRecord> data_type;
+ using data_type = ArrayRef<NamedInstrProfRecord>;
- typedef StringRef internal_key_type;
- typedef StringRef external_key_type;
- typedef uint64_t hash_value_type;
- typedef uint64_t offset_type;
+ using internal_key_type = StringRef;
+ using external_key_type = StringRef;
+ using hash_value_type = uint64_t;
+ using offset_type = uint64_t;
static bool EqualKey(StringRef A, StringRef B) { return A == B; }
static StringRef GetInternalKey(StringRef K) { return K; }
@@ -284,6 +309,7 @@ public:
static std::pair<offset_type, offset_type>
ReadKeyDataLength(const unsigned char *&D) {
using namespace support;
+
offset_type KeyLen = endian::readNext<offset_type, little, unaligned>(D);
offset_type DataLen = endian::readNext<offset_type, little, unaligned>(D);
return std::make_pair(KeyLen, DataLen);
@@ -304,27 +330,28 @@ public:
};
struct InstrProfReaderIndexBase {
+ virtual ~InstrProfReaderIndexBase() = default;
+
// Read all the profile records with the same key pointed to the current
// iterator.
- virtual Error getRecords(ArrayRef<InstrProfRecord> &Data) = 0;
+ virtual Error getRecords(ArrayRef<NamedInstrProfRecord> &Data) = 0;
+
// Read all the profile records with the key equal to FuncName
virtual Error getRecords(StringRef FuncName,
- ArrayRef<InstrProfRecord> &Data) = 0;
+ ArrayRef<NamedInstrProfRecord> &Data) = 0;
virtual void advanceToNextKey() = 0;
virtual bool atEnd() const = 0;
virtual void setValueProfDataEndianness(support::endianness Endianness) = 0;
- virtual ~InstrProfReaderIndexBase() {}
virtual uint64_t getVersion() const = 0;
virtual bool isIRLevelProfile() const = 0;
- virtual void populateSymtab(InstrProfSymtab &) = 0;
+ virtual Error populateSymtab(InstrProfSymtab &) = 0;
};
-typedef OnDiskIterableChainedHashTable<InstrProfLookupTrait>
- OnDiskHashTableImplV3;
+using OnDiskHashTableImplV3 =
+ OnDiskIterableChainedHashTable<InstrProfLookupTrait>;
template <typename HashTableImpl>
class InstrProfReaderIndex : public InstrProfReaderIndexBase {
-
private:
std::unique_ptr<HashTableImpl> HashTable;
typename HashTableImpl::data_iterator RecordIterator;
@@ -335,24 +362,29 @@ public:
const unsigned char *const Payload,
const unsigned char *const Base,
IndexedInstrProf::HashT HashType, uint64_t Version);
+ ~InstrProfReaderIndex() override = default;
- Error getRecords(ArrayRef<InstrProfRecord> &Data) override;
+ Error getRecords(ArrayRef<NamedInstrProfRecord> &Data) override;
Error getRecords(StringRef FuncName,
- ArrayRef<InstrProfRecord> &Data) override;
+ ArrayRef<NamedInstrProfRecord> &Data) override;
void advanceToNextKey() override { RecordIterator++; }
+
bool atEnd() const override {
return RecordIterator == HashTable->data_end();
}
+
void setValueProfDataEndianness(support::endianness Endianness) override {
HashTable->getInfoObj().setValueProfDataEndianness(Endianness);
}
- ~InstrProfReaderIndex() override {}
+
uint64_t getVersion() const override { return GET_VERSION(FormatVersion); }
+
bool isIRLevelProfile() const override {
return (FormatVersion & VARIANT_MASK_IR_PROF) != 0;
}
- void populateSymtab(InstrProfSymtab &Symtab) override {
- Symtab.create(HashTable->keys());
+
+ Error populateSymtab(InstrProfSymtab &Symtab) override {
+ return Symtab.create(HashTable->keys());
}
};
@@ -366,20 +398,20 @@ private:
/// Profile summary data.
std::unique_ptr<ProfileSummary> Summary;
- IndexedInstrProfReader(const IndexedInstrProfReader &) = delete;
- IndexedInstrProfReader &operator=(const IndexedInstrProfReader &) = delete;
-
// Read the profile summary. Return a pointer pointing to one byte past the
// end of the summary data if it exists or the input \c Cur.
const unsigned char *readSummary(IndexedInstrProf::ProfVersion Version,
const unsigned char *Cur);
public:
+ IndexedInstrProfReader(std::unique_ptr<MemoryBuffer> DataBuffer)
+ : DataBuffer(std::move(DataBuffer)) {}
+ IndexedInstrProfReader(const IndexedInstrProfReader &) = delete;
+ IndexedInstrProfReader &operator=(const IndexedInstrProfReader &) = delete;
+
/// Return the profile version.
uint64_t getVersion() const { return Index->getVersion(); }
bool isIRLevelProfile() const override { return Index->isIRLevelProfile(); }
- IndexedInstrProfReader(std::unique_ptr<MemoryBuffer> DataBuffer)
- : DataBuffer(std::move(DataBuffer)), Index(nullptr) {}
/// Return true if the given buffer is in an indexed instrprof format.
static bool hasFormat(const MemoryBuffer &DataBuffer);
@@ -387,10 +419,9 @@ public:
/// Read the file header.
Error readHeader() override;
/// Read a single record.
- Error readNextRecord(InstrProfRecord &Record) override;
+ Error readNextRecord(NamedInstrProfRecord &Record) override;
- /// Return the pointer to InstrProfRecord associated with FuncName
- /// and FuncHash
+ /// Return the NamedInstrProfRecord associated with FuncName and FuncHash
Expected<InstrProfRecord> getInstrProfRecord(StringRef FuncName,
uint64_t FuncHash);
@@ -422,4 +453,4 @@ public:
} // end namespace llvm
-#endif
+#endif // LLVM_PROFILEDATA_INSTRPROFREADER_H
diff --git a/contrib/llvm/include/llvm/ProfileData/InstrProfWriter.h b/contrib/llvm/include/llvm/ProfileData/InstrProfWriter.h
index f7780fb..8107ab3 100644
--- a/contrib/llvm/include/llvm/ProfileData/InstrProfWriter.h
+++ b/contrib/llvm/include/llvm/ProfileData/InstrProfWriter.h
@@ -1,4 +1,4 @@
-//=-- InstrProfWriter.h - Instrumented profiling writer -----------*- C++ -*-=//
+//===- InstrProfWriter.h - Instrumented profiling writer --------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -16,26 +16,30 @@
#define LLVM_PROFILEDATA_INSTRPROFWRITER_H
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/StringMap.h"
#include "llvm/ProfileData/InstrProf.h"
-#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/raw_ostream.h"
+#include <cstdint>
+#include <memory>
namespace llvm {
/// Writer for instrumentation based profile data.
-class ProfOStream;
class InstrProfRecordWriterTrait;
+class ProfOStream;
+class raw_fd_ostream;
class InstrProfWriter {
public:
- typedef SmallDenseMap<uint64_t, InstrProfRecord, 1> ProfilingData;
+ using ProfilingData = SmallDenseMap<uint64_t, InstrProfRecord>;
enum ProfKind { PF_Unknown = 0, PF_FE, PF_IRLevel };
private:
bool Sparse;
StringMap<ProfilingData> FunctionData;
- ProfKind ProfileKind;
+ ProfKind ProfileKind = PF_Unknown;
// Use raw pointer here for the incomplete type object.
InstrProfRecordWriterTrait *InfoObj;
@@ -46,16 +50,27 @@ public:
/// Add function counts for the given function. If there are already counts
/// for this function and the hash and number of counts match, each counter is
/// summed. Optionally scale counts by \p Weight.
- Error addRecord(InstrProfRecord &&I, uint64_t Weight = 1);
+ void addRecord(NamedInstrProfRecord &&I, uint64_t Weight,
+ function_ref<void(Error)> Warn);
+ void addRecord(NamedInstrProfRecord &&I, function_ref<void(Error)> Warn) {
+ addRecord(std::move(I), 1, Warn);
+ }
+
/// Merge existing function counts from the given writer.
- Error mergeRecordsFromWriter(InstrProfWriter &&IPW);
+ void mergeRecordsFromWriter(InstrProfWriter &&IPW,
+ function_ref<void(Error)> Warn);
+
/// Write the profile to \c OS
void write(raw_fd_ostream &OS);
+
/// Write the profile in text format to \c OS
- void writeText(raw_fd_ostream &OS);
+ Error writeText(raw_fd_ostream &OS);
+
/// Write \c Record in text format to \c OS
- static void writeRecordInText(const InstrProfRecord &Record,
+ static void writeRecordInText(StringRef Name, uint64_t Hash,
+ const InstrProfRecord &Counters,
InstrProfSymtab &Symtab, raw_fd_ostream &OS);
+
/// Write the profile, returning the raw data. For testing.
std::unique_ptr<MemoryBuffer> writeBuffer();
@@ -76,10 +91,12 @@ public:
void setOutputSparse(bool Sparse);
private:
+ void addRecord(StringRef Name, uint64_t Hash, InstrProfRecord &&I,
+ uint64_t Weight, function_ref<void(Error)> Warn);
bool shouldEncodeData(const ProfilingData &PD);
void writeImpl(ProfOStream &OS);
};
} // end namespace llvm
-#endif
+#endif // LLVM_PROFILEDATA_INSTRPROFWRITER_H
diff --git a/contrib/llvm/include/llvm/ProfileData/ProfileCommon.h b/contrib/llvm/include/llvm/ProfileData/ProfileCommon.h
index e955755..51b065b 100644
--- a/contrib/llvm/include/llvm/ProfileData/ProfileCommon.h
+++ b/contrib/llvm/include/llvm/ProfileData/ProfileCommon.h
@@ -1,4 +1,4 @@
-//===-- ProfileCommon.h - Common profiling APIs. ----------------*- C++ -*-===//
+//===- ProfileCommon.h - Common profiling APIs. -----------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -12,38 +12,32 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_PROFILEDATA_PROFILE_COMMON_H
-#define LLVM_PROFILEDATA_PROFILE_COMMON_H
+#ifndef LLVM_PROFILEDATA_PROFILECOMMON_H
+#define LLVM_PROFILEDATA_PROFILECOMMON_H
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/IR/ProfileSummary.h"
+#include "llvm/ProfileData/InstrProf.h"
+#include "llvm/Support/Error.h"
+#include <algorithm>
#include <cstdint>
#include <functional>
#include <map>
-#include <utility>
+#include <memory>
#include <vector>
-#include "llvm/IR/ProfileSummary.h"
-#include "llvm/Support/Error.h"
-#include "llvm/ADT/ArrayRef.h"
-
namespace llvm {
-class Function;
-namespace IndexedInstrProf {
-struct Summary;
-}
+
namespace sampleprof {
+
class FunctionSamples;
-}
-struct InstrProfRecord;
-class LLVMContext;
-class Metadata;
-class MDTuple;
-class MDNode;
+
+} // end namespace sampleprof
inline const char *getHotSectionPrefix() { return ".hot"; }
inline const char *getUnlikelySectionPrefix() { return ".unlikely"; }
class ProfileSummaryBuilder {
-
private:
/// We keep track of the number of times a count (block count or samples)
/// appears in the profile. The map is kept sorted in the descending order of
@@ -53,13 +47,18 @@ private:
protected:
SummaryEntryVector DetailedSummary;
+ uint64_t TotalCount = 0;
+ uint64_t MaxCount = 0;
+ uint64_t MaxFunctionCount = 0;
+ uint32_t NumCounts = 0;
+ uint32_t NumFunctions = 0;
+
ProfileSummaryBuilder(std::vector<uint32_t> Cutoffs)
: DetailedSummaryCutoffs(std::move(Cutoffs)) {}
- inline void addCount(uint64_t Count);
~ProfileSummaryBuilder() = default;
+
+ inline void addCount(uint64_t Count);
void computeDetailedSummary();
- uint64_t TotalCount = 0, MaxCount = 0, MaxFunctionCount = 0;
- uint32_t NumCounts = 0, NumFunctions = 0;
public:
/// \brief A vector of useful cutoff values for detailed summary.
@@ -68,22 +67,24 @@ public:
class InstrProfSummaryBuilder final : public ProfileSummaryBuilder {
uint64_t MaxInternalBlockCount = 0;
+
inline void addEntryCount(uint64_t Count);
inline void addInternalCount(uint64_t Count);
public:
InstrProfSummaryBuilder(std::vector<uint32_t> Cutoffs)
: ProfileSummaryBuilder(std::move(Cutoffs)) {}
+
void addRecord(const InstrProfRecord &);
std::unique_ptr<ProfileSummary> getSummary();
};
class SampleProfileSummaryBuilder final : public ProfileSummaryBuilder {
-
public:
- void addRecord(const sampleprof::FunctionSamples &FS);
SampleProfileSummaryBuilder(std::vector<uint32_t> Cutoffs)
: ProfileSummaryBuilder(std::move(Cutoffs)) {}
+
+ void addRecord(const sampleprof::FunctionSamples &FS);
std::unique_ptr<ProfileSummary> getSummary();
};
@@ -96,6 +97,6 @@ void ProfileSummaryBuilder::addCount(uint64_t Count) {
CountFrequencies[Count]++;
}
-
} // end namespace llvm
-#endif
+
+#endif // LLVM_PROFILEDATA_PROFILECOMMON_H
diff --git a/contrib/llvm/include/llvm/ProfileData/SampleProf.h b/contrib/llvm/include/llvm/ProfileData/SampleProf.h
index a96f836..7fc2588 100644
--- a/contrib/llvm/include/llvm/ProfileData/SampleProf.h
+++ b/contrib/llvm/include/llvm/ProfileData/SampleProf.h
@@ -1,4 +1,4 @@
-//=-- SampleProf.h - Sampling profiling format support --------------------===//
+//===- SampleProf.h - Sampling profiling format support ---------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -12,20 +12,30 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_PROFILEDATA_SAMPLEPROF_H_
-#define LLVM_PROFILEDATA_SAMPLEPROF_H_
+#ifndef LLVM_PROFILEDATA_SAMPLEPROF_H
+#define LLVM_PROFILEDATA_SAMPLEPROF_H
+#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/GlobalValue.h"
+#include "llvm/IR/Module.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorOr.h"
-#include "llvm/Support/raw_ostream.h"
-
+#include "llvm/Support/MathExtras.h"
+#include <algorithm>
+#include <cstdint>
#include <map>
+#include <string>
#include <system_error>
+#include <utility>
namespace llvm {
+class raw_ostream;
+
const std::error_category &sampleprof_category();
enum class sampleprof_error {
@@ -59,12 +69,13 @@ inline sampleprof_error MergeResult(sampleprof_error &Accumulator,
} // end namespace llvm
namespace std {
+
template <>
struct is_error_code_enum<llvm::sampleprof_error> : std::true_type {};
-}
-namespace llvm {
+} // end namespace std
+namespace llvm {
namespace sampleprof {
static inline uint64_t SPMagic() {
@@ -87,8 +98,10 @@ static inline uint64_t SPVersion() { return 103; }
/// (e.g., the two post-increment instructions in "if (p) x++; else y++;").
struct LineLocation {
LineLocation(uint32_t L, uint32_t D) : LineOffset(L), Discriminator(D) {}
+
void print(raw_ostream &OS) const;
void dump() const;
+
bool operator<(const LineLocation &O) const {
return LineOffset < O.LineOffset ||
(LineOffset == O.LineOffset && Discriminator < O.Discriminator);
@@ -112,9 +125,9 @@ raw_ostream &operator<<(raw_ostream &OS, const LineLocation &Loc);
/// will be a list of one or more functions.
class SampleRecord {
public:
- typedef StringMap<uint64_t> CallTargetMap;
+ using CallTargetMap = StringMap<uint64_t>;
- SampleRecord() : NumSamples(0), CallTargets() {}
+ SampleRecord() = default;
/// Increment the number of samples for this record by \p S.
/// Optionally scale sample count \p S by \p Weight.
@@ -144,7 +157,7 @@ public:
}
/// Return true if this sample record contains function calls.
- bool hasCalls() const { return CallTargets.size() > 0; }
+ bool hasCalls() const { return !CallTargets.empty(); }
uint64_t getSamples() const { return NumSamples; }
const CallTargetMap &getCallTargets() const { return CallTargets; }
@@ -163,15 +176,17 @@ public:
void dump() const;
private:
- uint64_t NumSamples;
+ uint64_t NumSamples = 0;
CallTargetMap CallTargets;
};
raw_ostream &operator<<(raw_ostream &OS, const SampleRecord &Sample);
-typedef std::map<LineLocation, SampleRecord> BodySampleMap;
class FunctionSamples;
-typedef std::map<LineLocation, FunctionSamples> CallsiteSampleMap;
+
+using BodySampleMap = std::map<LineLocation, SampleRecord>;
+using FunctionSamplesMap = StringMap<FunctionSamples>;
+using CallsiteSampleMap = std::map<LineLocation, FunctionSamplesMap>;
/// Representation of the samples collected for a function.
///
@@ -180,9 +195,11 @@ typedef std::map<LineLocation, FunctionSamples> CallsiteSampleMap;
/// within the body of the function.
class FunctionSamples {
public:
- FunctionSamples() : Name(), TotalSamples(0), TotalHeadSamples(0) {}
+ FunctionSamples() = default;
+
void print(raw_ostream &OS = dbgs(), unsigned Indent = 0) const;
void dump() const;
+
sampleprof_error addTotalSamples(uint64_t Num, uint64_t Weight = 1) {
bool Overflowed;
TotalSamples =
@@ -190,6 +207,7 @@ public:
return Overflowed ? sampleprof_error::counter_overflow
: sampleprof_error::success;
}
+
sampleprof_error addHeadSamples(uint64_t Num, uint64_t Weight = 1) {
bool Overflowed;
TotalHeadSamples =
@@ -197,11 +215,13 @@ public:
return Overflowed ? sampleprof_error::counter_overflow
: sampleprof_error::success;
}
+
sampleprof_error addBodySamples(uint32_t LineOffset, uint32_t Discriminator,
uint64_t Num, uint64_t Weight = 1) {
return BodySamples[LineLocation(LineOffset, Discriminator)].addSamples(
Num, Weight);
}
+
sampleprof_error addCalledTargetSamples(uint32_t LineOffset,
uint32_t Discriminator,
const std::string &FName,
@@ -222,34 +242,53 @@ public:
return ret->second.getSamples();
}
- /// Return the total number of call target samples collected at a given
- /// location. Each location is specified by \p LineOffset and
- /// \p Discriminator. If the location is not found in profile, return error.
- ErrorOr<uint64_t> findCallSamplesAt(uint32_t LineOffset,
- uint32_t Discriminator) const {
+ /// Returns the call target map collected at a given location.
+ /// Each location is specified by \p LineOffset and \p Discriminator.
+ /// If the location is not found in profile, return error.
+ ErrorOr<SampleRecord::CallTargetMap>
+ findCallTargetMapAt(uint32_t LineOffset, uint32_t Discriminator) const {
const auto &ret = BodySamples.find(LineLocation(LineOffset, Discriminator));
if (ret == BodySamples.end())
return std::error_code();
- uint64_t T = 0;
- for (const auto &t_c : ret->second.getCallTargets()) {
- T += t_c.second;
- }
- return T;
+ return ret->second.getCallTargets();
}
/// Return the function samples at the given callsite location.
- FunctionSamples &functionSamplesAt(const LineLocation &Loc) {
+ FunctionSamplesMap &functionSamplesAt(const LineLocation &Loc) {
return CallsiteSamples[Loc];
}
- /// Return a pointer to function samples at the given callsite location.
- const FunctionSamples *findFunctionSamplesAt(const LineLocation &Loc) const {
+ /// Returns the FunctionSamplesMap at the given \p Loc.
+ const FunctionSamplesMap *
+ findFunctionSamplesMapAt(const LineLocation &Loc) const {
auto iter = CallsiteSamples.find(Loc);
- if (iter == CallsiteSamples.end()) {
+ if (iter == CallsiteSamples.end())
return nullptr;
- } else {
- return &iter->second;
- }
+ return &iter->second;
+ }
+
+ /// Returns a pointer to FunctionSamples at the given callsite location \p Loc
+ /// with callee \p CalleeName. If no callsite can be found, relax the
+ /// restriction to return the FunctionSamples at callsite location \p Loc
+ /// with the maximum total sample count.
+ const FunctionSamples *findFunctionSamplesAt(const LineLocation &Loc,
+ StringRef CalleeName) const {
+ auto iter = CallsiteSamples.find(Loc);
+ if (iter == CallsiteSamples.end())
+ return nullptr;
+ auto FS = iter->second.find(CalleeName);
+ if (FS != iter->second.end())
+ return &FS->getValue();
+ // If we cannot find exact match of the callee name, return the FS with
+ // the max total count.
+ uint64_t MaxTotalSamples = 0;
+ const FunctionSamples *R = nullptr;
+ for (const auto &NameFS : iter->second)
+ if (NameFS.second.getTotalSamples() >= MaxTotalSamples) {
+ MaxTotalSamples = NameFS.second.getTotalSamples();
+ R = &NameFS.second;
+ }
+ return R;
}
bool empty() const { return TotalSamples == 0; }
@@ -283,12 +322,28 @@ public:
}
for (const auto &I : Other.getCallsiteSamples()) {
const LineLocation &Loc = I.first;
- const FunctionSamples &Rec = I.second;
- MergeResult(Result, functionSamplesAt(Loc).merge(Rec, Weight));
+ FunctionSamplesMap &FSMap = functionSamplesAt(Loc);
+ for (const auto &Rec : I.second)
+ MergeResult(Result, FSMap[Rec.first()].merge(Rec.second, Weight));
}
return Result;
}
+ /// Recursively traverses all children, if the corresponding function is
+ /// not defined in module \p M, and its total sample is no less than
+ /// \p Threshold, add its corresponding GUID to \p S.
+ void findImportedFunctions(DenseSet<GlobalValue::GUID> &S, const Module *M,
+ uint64_t Threshold) const {
+ if (TotalSamples <= Threshold)
+ return;
+ Function *F = M->getFunction(Name);
+ if (!F || !F->getSubprogram())
+ S.insert(Function::getGUID(Name));
+ for (auto CS : CallsiteSamples)
+ for (const auto &NameFS : CS.second)
+ NameFS.second.findImportedFunctions(S, M, Threshold);
+ }
+
/// Set the name of the function.
void setName(StringRef FunctionName) { Name = FunctionName; }
@@ -303,12 +358,12 @@ private:
///
/// Samples are cumulative, they include all the samples collected
/// inside this function and all its inlined callees.
- uint64_t TotalSamples;
+ uint64_t TotalSamples = 0;
/// Total number of samples collected at the head of the function.
/// This is an approximation of the number of calls made to this function
/// at runtime.
- uint64_t TotalHeadSamples;
+ uint64_t TotalHeadSamples = 0;
/// Map instruction locations to collected samples.
///
@@ -344,8 +399,8 @@ raw_ostream &operator<<(raw_ostream &OS, const FunctionSamples &FS);
/// order of LocationT.
template <class LocationT, class SampleT> class SampleSorter {
public:
- typedef std::pair<const LocationT, SampleT> SamplesWithLoc;
- typedef SmallVector<const SamplesWithLoc *, 20> SamplesWithLocList;
+ using SamplesWithLoc = std::pair<const LocationT, SampleT>;
+ using SamplesWithLocList = SmallVector<const SamplesWithLoc *, 20>;
SampleSorter(const std::map<LocationT, SampleT> &Samples) {
for (const auto &I : Samples)
@@ -355,6 +410,7 @@ public:
return A->first < B->first;
});
}
+
const SamplesWithLocList &get() const { return V; }
private:
@@ -362,7 +418,6 @@ private:
};
} // end namespace sampleprof
-
} // end namespace llvm
-#endif // LLVM_PROFILEDATA_SAMPLEPROF_H_
+#endif // LLVM_PROFILEDATA_SAMPLEPROF_H
diff --git a/contrib/llvm/include/llvm/ProfileData/SampleProfReader.h b/contrib/llvm/include/llvm/ProfileData/SampleProfReader.h
index bf86721..9c1f357 100644
--- a/contrib/llvm/include/llvm/ProfileData/SampleProfReader.h
+++ b/contrib/llvm/include/llvm/ProfileData/SampleProfReader.h
@@ -1,4 +1,4 @@
-//===- SampleProfReader.h - Read LLVM sample profile data -----------------===//
+//===- SampleProfReader.h - Read LLVM sample profile data -------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -205,26 +205,34 @@
// FUNCTION BODY
// A FUNCTION BODY entry describing the inlined function.
//===----------------------------------------------------------------------===//
+
#ifndef LLVM_PROFILEDATA_SAMPLEPROFREADER_H
#define LLVM_PROFILEDATA_SAMPLEPROFREADER_H
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/IR/DiagnosticInfo.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/LLVMContext.h"
-#include "llvm/ProfileData/ProfileCommon.h"
+#include "llvm/IR/ProfileSummary.h"
#include "llvm/ProfileData/SampleProf.h"
#include "llvm/Support/Debug.h"
-#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/ErrorOr.h"
#include "llvm/Support/GCOV.h"
#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+#include <cstdint>
+#include <memory>
+#include <string>
+#include <system_error>
+#include <vector>
namespace llvm {
+class raw_ostream;
+
namespace sampleprof {
/// \brief Sample-based profile reader.
@@ -259,7 +267,7 @@ public:
SampleProfileReader(std::unique_ptr<MemoryBuffer> B, LLVMContext &C)
: Profiles(0), Ctx(C), Buffer(std::move(B)) {}
- virtual ~SampleProfileReader() {}
+ virtual ~SampleProfileReader() = default;
/// \brief Read and validate the file header.
virtual std::error_code readHeader() = 0;
@@ -275,7 +283,12 @@ public:
/// \brief Return the samples collected for function \p F.
FunctionSamples *getSamplesFor(const Function &F) {
- return &Profiles[F.getName()];
+ // The function name may have been updated by adding suffix. In sample
+ // profile, the function names are all stripped, so we need to strip
+ // the function name suffix before matching with profile.
+ if (Profiles.count(F.getName().split('.').first))
+ return &Profiles[(F.getName().split('.').first)];
+ return nullptr;
}
/// \brief Return all the profiles.
@@ -337,7 +350,7 @@ public:
class SampleProfileReaderBinary : public SampleProfileReader {
public:
SampleProfileReaderBinary(std::unique_ptr<MemoryBuffer> B, LLVMContext &C)
- : SampleProfileReader(std::move(B), C), Data(nullptr), End(nullptr) {}
+ : SampleProfileReader(std::move(B), C) {}
/// \brief Read and validate the file header.
std::error_code readHeader() override;
@@ -375,10 +388,10 @@ protected:
std::error_code readProfile(FunctionSamples &FProfile);
/// \brief Points to the current location in the buffer.
- const uint8_t *Data;
+ const uint8_t *Data = nullptr;
/// \brief Points to the end of the buffer.
- const uint8_t *End;
+ const uint8_t *End = nullptr;
/// Function name table.
std::vector<StringRef> NameTable;
@@ -390,7 +403,7 @@ private:
std::error_code readSummary();
};
-typedef SmallVector<FunctionSamples *, 10> InlineCallStack;
+using InlineCallStack = SmallVector<FunctionSamples *, 10>;
// Supported histogram types in GCC. Currently, we only need support for
// call target histograms.
@@ -442,8 +455,8 @@ protected:
static const uint32_t GCOVTagAFDOFunction = 0xac000000;
};
-} // End namespace sampleprof
+} // end namespace sampleprof
-} // End namespace llvm
+} // end namespace llvm
#endif // LLVM_PROFILEDATA_SAMPLEPROFREADER_H
diff --git a/contrib/llvm/include/llvm/ProfileData/SampleProfWriter.h b/contrib/llvm/include/llvm/ProfileData/SampleProfWriter.h
index f6f2e27..86af103 100644
--- a/contrib/llvm/include/llvm/ProfileData/SampleProfWriter.h
+++ b/contrib/llvm/include/llvm/ProfileData/SampleProfWriter.h
@@ -1,4 +1,4 @@
-//===- SampleProfWriter.h - Write LLVM sample profile data ----------------===//
+//===- SampleProfWriter.h - Write LLVM sample profile data ------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,15 +14,18 @@
#define LLVM_PROFILEDATA_SAMPLEPROFWRITER_H
#include "llvm/ADT/MapVector.h"
+#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/ProfileData/ProfileCommon.h"
+#include "llvm/IR/ProfileSummary.h"
#include "llvm/ProfileData/SampleProf.h"
#include "llvm/Support/ErrorOr.h"
-#include "llvm/Support/FileSystem.h"
#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+#include <cstdint>
+#include <memory>
+#include <system_error>
namespace llvm {
-
namespace sampleprof {
enum SampleProfileFormat { SPF_None = 0, SPF_Text, SPF_Binary, SPF_GCC };
@@ -30,7 +33,7 @@ enum SampleProfileFormat { SPF_None = 0, SPF_Text, SPF_Binary, SPF_GCC };
/// \brief Sample-based profile writer. Base class.
class SampleProfileWriter {
public:
- virtual ~SampleProfileWriter() {}
+ virtual ~SampleProfileWriter() = default;
/// Write sample profiles in \p S.
///
@@ -40,16 +43,7 @@ public:
/// Write all the sample profiles in the given map of samples.
///
/// \returns status code of the file update operation.
- std::error_code write(const StringMap<FunctionSamples> &ProfileMap) {
- if (std::error_code EC = writeHeader(ProfileMap))
- return EC;
- for (const auto &I : ProfileMap) {
- const FunctionSamples &Profile = I.second;
- if (std::error_code EC = write(Profile))
- return EC;
- }
- return sampleprof_error::success;
- }
+ std::error_code write(const StringMap<FunctionSamples> &ProfileMap);
raw_ostream &getOutputStream() { return *OutputStream; }
@@ -114,7 +108,7 @@ public:
protected:
SampleProfileWriterBinary(std::unique_ptr<raw_ostream> &OS)
- : SampleProfileWriter(OS), NameTable() {}
+ : SampleProfileWriter(OS) {}
std::error_code
writeHeader(const StringMap<FunctionSamples> &ProfileMap) override;
@@ -133,8 +127,7 @@ private:
SampleProfileFormat Format);
};
-} // End namespace sampleprof
-
-} // End namespace llvm
+} // end namespace sampleprof
+} // end namespace llvm
#endif // LLVM_PROFILEDATA_SAMPLEPROFWRITER_H
diff --git a/contrib/llvm/include/llvm/Support/AArch64TargetParser.def b/contrib/llvm/include/llvm/Support/AArch64TargetParser.def
index c4416f0..09f9602 100644
--- a/contrib/llvm/include/llvm/Support/AArch64TargetParser.def
+++ b/contrib/llvm/include/llvm/Support/AArch64TargetParser.def
@@ -20,8 +20,7 @@ AARCH64_ARCH("invalid", AK_INVALID, nullptr, nullptr,
ARMBuildAttrs::CPUArch::v8_A, FK_NONE, AArch64::AEK_NONE)
AARCH64_ARCH("armv8-a", AK_ARMV8A, "8-A", "v8", ARMBuildAttrs::CPUArch::v8_A,
FK_CRYPTO_NEON_FP_ARMV8,
- (AArch64::AEK_CRC | AArch64::AEK_CRYPTO | AArch64::AEK_FP |
- AArch64::AEK_SIMD | AArch64::AEK_LSE))
+ (AArch64::AEK_CRYPTO | AArch64::AEK_FP | AArch64::AEK_SIMD))
AARCH64_ARCH("armv8.1-a", AK_ARMV8_1A, "8.1-A", "v8.1a",
ARMBuildAttrs::CPUArch::v8_A, FK_CRYPTO_NEON_FP_ARMV8,
(AArch64::AEK_CRC | AArch64::AEK_CRYPTO | AArch64::AEK_FP |
@@ -44,37 +43,46 @@ AARCH64_ARCH_EXT_NAME("crypto", AArch64::AEK_CRYPTO, "+crypto","-crypto")
AARCH64_ARCH_EXT_NAME("fp", AArch64::AEK_FP, "+fp-armv8", "-fp-armv8")
AARCH64_ARCH_EXT_NAME("simd", AArch64::AEK_SIMD, "+neon", "-neon")
AARCH64_ARCH_EXT_NAME("fp16", AArch64::AEK_FP16, "+fullfp16", "-fullfp16")
-AARCH64_ARCH_EXT_NAME("profile", AArch64::AEK_PROFILE, "+spe", "-spe")
-AARCH64_ARCH_EXT_NAME("ras", AArch64::AEK_RAS, "+ras", "-ras")
+AARCH64_ARCH_EXT_NAME("profile", AArch64::AEK_PROFILE, "+spe", "-spe")
+AARCH64_ARCH_EXT_NAME("ras", AArch64::AEK_RAS, "+ras", "-ras")
+AARCH64_ARCH_EXT_NAME("sve", AArch64::AEK_SVE, "+sve", "-sve")
#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-a35", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false,
- (AArch64::AEK_SIMD | AArch64::AEK_CRC | AArch64::AEK_CRYPTO))
+ (AArch64::AEK_CRC))
AARCH64_CPU_NAME("cortex-a53", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, true,
- ( AArch64::AEK_SIMD | AArch64::AEK_CRC | AArch64::AEK_CRYPTO))
+ (AArch64::AEK_CRC))
AARCH64_CPU_NAME("cortex-a57", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false,
- (AArch64::AEK_SIMD | AArch64::AEK_CRC | AArch64::AEK_CRYPTO))
+ (AArch64::AEK_CRC))
AARCH64_CPU_NAME("cortex-a72", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false,
- (AArch64::AEK_SIMD | AArch64::AEK_CRC | AArch64::AEK_CRYPTO))
+ (AArch64::AEK_CRC))
AARCH64_CPU_NAME("cortex-a73", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false,
- (AArch64::AEK_SIMD | AArch64::AEK_CRC | AArch64::AEK_CRYPTO))
+ (AArch64::AEK_CRC))
AARCH64_CPU_NAME("cyclone", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false,
- (AArch64::AEK_SIMD | AArch64::AEK_CRYPTO))
+ (AArch64::AEK_NONE))
AARCH64_CPU_NAME("exynos-m1", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false,
- (AArch64::AEK_SIMD | AArch64::AEK_CRC | AArch64::AEK_CRYPTO))
+ (AArch64::AEK_CRC))
AARCH64_CPU_NAME("exynos-m2", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false,
- (AArch64::AEK_SIMD | AArch64::AEK_CRC | AArch64::AEK_CRYPTO))
+ (AArch64::AEK_CRC))
AARCH64_CPU_NAME("exynos-m3", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false,
- (AArch64::AEK_SIMD | AArch64::AEK_CRC | AArch64::AEK_CRYPTO))
+ (AArch64::AEK_CRC))
AARCH64_CPU_NAME("falkor", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false,
- (AArch64::AEK_SIMD | AArch64::AEK_CRC | AArch64::AEK_CRYPTO))
+ (AArch64::AEK_CRC))
AARCH64_CPU_NAME("kryo", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false,
- (AArch64::AEK_SIMD | AArch64::AEK_CRC | AArch64::AEK_CRYPTO))
-AARCH64_CPU_NAME("vulcan", AK_ARMV8_1A, FK_CRYPTO_NEON_FP_ARMV8, false,
- (AArch64::AEK_SIMD | AArch64::AEK_CRC | AArch64::AEK_CRYPTO))
+ (AArch64::AEK_CRC))
+AARCH64_CPU_NAME("thunderx2t99", AK_ARMV8_1A, FK_CRYPTO_NEON_FP_ARMV8, false,
+ (AArch64::AEK_NONE))
+AARCH64_CPU_NAME("thunderx", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false,
+ (AArch64::AEK_CRC | AArch64::AEK_PROFILE))
+AARCH64_CPU_NAME("thunderxt88", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false,
+ (AArch64::AEK_CRC | AArch64::AEK_PROFILE))
+AARCH64_CPU_NAME("thunderxt81", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false,
+ (AArch64::AEK_CRC | AArch64::AEK_PROFILE))
+AARCH64_CPU_NAME("thunderxt83", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false,
+ (AArch64::AEK_CRC | AArch64::AEK_PROFILE))
// Invalid CPU
AARCH64_CPU_NAME("invalid", AK_INVALID, FK_INVALID, true, AArch64::AEK_INVALID)
#undef AARCH64_CPU_NAME
diff --git a/contrib/llvm/include/llvm/Support/AMDGPUCodeObjectMetadata.h b/contrib/llvm/include/llvm/Support/AMDGPUCodeObjectMetadata.h
new file mode 100644
index 0000000..d274c5e
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/AMDGPUCodeObjectMetadata.h
@@ -0,0 +1,422 @@
+//===--- AMDGPUCodeObjectMetadata.h -----------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+/// \file
+/// \brief AMDGPU Code Object Metadata definitions and in-memory
+/// representations.
+///
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_AMDGPUCODEOBJECTMETADATA_H
+#define LLVM_SUPPORT_AMDGPUCODEOBJECTMETADATA_H
+
+#include <cstdint>
+#include <string>
+#include <system_error>
+#include <vector>
+
+namespace llvm {
+namespace AMDGPU {
+
+//===----------------------------------------------------------------------===//
+// Code Object Metadata.
+//===----------------------------------------------------------------------===//
+namespace CodeObject {
+
+/// \brief Code object metadata major version.
+constexpr uint32_t MetadataVersionMajor = 1;
+/// \brief Code object metadata minor version.
+constexpr uint32_t MetadataVersionMinor = 0;
+
+/// \brief Code object metadata beginning assembler directive.
+constexpr char MetadataAssemblerDirectiveBegin[] =
+ ".amdgpu_code_object_metadata";
+/// \brief Code object metadata ending assembler directive.
+constexpr char MetadataAssemblerDirectiveEnd[] =
+ ".end_amdgpu_code_object_metadata";
+
+/// \brief Access qualifiers.
+enum class AccessQualifier : uint8_t {
+ Default = 0,
+ ReadOnly = 1,
+ WriteOnly = 2,
+ ReadWrite = 3,
+ Unknown = 0xff
+};
+
+/// \brief Address space qualifiers.
+enum class AddressSpaceQualifier : uint8_t {
+ Private = 0,
+ Global = 1,
+ Constant = 2,
+ Local = 3,
+ Generic = 4,
+ Region = 5,
+ Unknown = 0xff
+};
+
+/// \brief Value kinds.
+enum class ValueKind : uint8_t {
+ ByValue = 0,
+ GlobalBuffer = 1,
+ DynamicSharedPointer = 2,
+ Sampler = 3,
+ Image = 4,
+ Pipe = 5,
+ Queue = 6,
+ HiddenGlobalOffsetX = 7,
+ HiddenGlobalOffsetY = 8,
+ HiddenGlobalOffsetZ = 9,
+ HiddenNone = 10,
+ HiddenPrintfBuffer = 11,
+ HiddenDefaultQueue = 12,
+ HiddenCompletionAction = 13,
+ Unknown = 0xff
+};
+
+/// \brief Value types.
+enum class ValueType : uint8_t {
+ Struct = 0,
+ I8 = 1,
+ U8 = 2,
+ I16 = 3,
+ U16 = 4,
+ F16 = 5,
+ I32 = 6,
+ U32 = 7,
+ F32 = 8,
+ I64 = 9,
+ U64 = 10,
+ F64 = 11,
+ Unknown = 0xff
+};
+
+//===----------------------------------------------------------------------===//
+// Kernel Metadata.
+//===----------------------------------------------------------------------===//
+namespace Kernel {
+
+//===----------------------------------------------------------------------===//
+// Kernel Attributes Metadata.
+//===----------------------------------------------------------------------===//
+namespace Attrs {
+
+namespace Key {
+/// \brief Key for Kernel::Attr::Metadata::mReqdWorkGroupSize.
+constexpr char ReqdWorkGroupSize[] = "ReqdWorkGroupSize";
+/// \brief Key for Kernel::Attr::Metadata::mWorkGroupSizeHint.
+constexpr char WorkGroupSizeHint[] = "WorkGroupSizeHint";
+/// \brief Key for Kernel::Attr::Metadata::mVecTypeHint.
+constexpr char VecTypeHint[] = "VecTypeHint";
+} // end namespace Key
+
+/// \brief In-memory representation of kernel attributes metadata.
+struct Metadata final {
+ /// \brief 'reqd_work_group_size' attribute. Optional.
+ std::vector<uint32_t> mReqdWorkGroupSize = std::vector<uint32_t>();
+ /// \brief 'work_group_size_hint' attribute. Optional.
+ std::vector<uint32_t> mWorkGroupSizeHint = std::vector<uint32_t>();
+ /// \brief 'vec_type_hint' attribute. Optional.
+ std::string mVecTypeHint = std::string();
+
+ /// \brief Default constructor.
+ Metadata() = default;
+
+ /// \returns True if kernel attributes metadata is empty, false otherwise.
+ bool empty() const {
+ return mReqdWorkGroupSize.empty() &&
+ mWorkGroupSizeHint.empty() &&
+ mVecTypeHint.empty();
+ }
+
+ /// \returns True if kernel attributes metadata is not empty, false otherwise.
+ bool notEmpty() const {
+ return !empty();
+ }
+};
+
+} // end namespace Attrs
+
+//===----------------------------------------------------------------------===//
+// Kernel Argument Metadata.
+//===----------------------------------------------------------------------===//
+namespace Arg {
+
+namespace Key {
+/// \brief Key for Kernel::Arg::Metadata::mSize.
+constexpr char Size[] = "Size";
+/// \brief Key for Kernel::Arg::Metadata::mAlign.
+constexpr char Align[] = "Align";
+/// \brief Key for Kernel::Arg::Metadata::mValueKind.
+constexpr char ValueKind[] = "ValueKind";
+/// \brief Key for Kernel::Arg::Metadata::mValueType.
+constexpr char ValueType[] = "ValueType";
+/// \brief Key for Kernel::Arg::Metadata::mPointeeAlign.
+constexpr char PointeeAlign[] = "PointeeAlign";
+/// \brief Key for Kernel::Arg::Metadata::mAccQual.
+constexpr char AccQual[] = "AccQual";
+/// \brief Key for Kernel::Arg::Metadata::mAddrSpaceQual.
+constexpr char AddrSpaceQual[] = "AddrSpaceQual";
+/// \brief Key for Kernel::Arg::Metadata::mIsConst.
+constexpr char IsConst[] = "IsConst";
+/// \brief Key for Kernel::Arg::Metadata::mIsPipe.
+constexpr char IsPipe[] = "IsPipe";
+/// \brief Key for Kernel::Arg::Metadata::mIsRestrict.
+constexpr char IsRestrict[] = "IsRestrict";
+/// \brief Key for Kernel::Arg::Metadata::mIsVolatile.
+constexpr char IsVolatile[] = "IsVolatile";
+/// \brief Key for Kernel::Arg::Metadata::mName.
+constexpr char Name[] = "Name";
+/// \brief Key for Kernel::Arg::Metadata::mTypeName.
+constexpr char TypeName[] = "TypeName";
+} // end namespace Key
+
+/// \brief In-memory representation of kernel argument metadata.
+struct Metadata final {
+ /// \brief Size in bytes. Required.
+ uint32_t mSize = 0;
+ /// \brief Alignment in bytes. Required.
+ uint32_t mAlign = 0;
+ /// \brief Value kind. Required.
+ ValueKind mValueKind = ValueKind::Unknown;
+ /// \brief Value type. Required.
+ ValueType mValueType = ValueType::Unknown;
+ /// \brief Pointee alignment in bytes. Optional.
+ uint32_t mPointeeAlign = 0;
+ /// \brief Access qualifier. Optional.
+ AccessQualifier mAccQual = AccessQualifier::Unknown;
+ /// \brief Address space qualifier. Optional.
+ AddressSpaceQualifier mAddrSpaceQual = AddressSpaceQualifier::Unknown;
+ /// \brief True if 'const' qualifier is specified. Optional.
+ bool mIsConst = false;
+ /// \brief True if 'pipe' qualifier is specified. Optional.
+ bool mIsPipe = false;
+ /// \brief True if 'restrict' qualifier is specified. Optional.
+ bool mIsRestrict = false;
+ /// \brief True if 'volatile' qualifier is specified. Optional.
+ bool mIsVolatile = false;
+ /// \brief Name. Optional.
+ std::string mName = std::string();
+ /// \brief Type name. Optional.
+ std::string mTypeName = std::string();
+
+ /// \brief Default constructor.
+ Metadata() = default;
+};
+
+} // end namespace Arg
+
+//===----------------------------------------------------------------------===//
+// Kernel Code Properties Metadata.
+//===----------------------------------------------------------------------===//
+namespace CodeProps {
+
+namespace Key {
+/// \brief Key for Kernel::CodeProps::Metadata::mKernargSegmentSize.
+constexpr char KernargSegmentSize[] = "KernargSegmentSize";
+/// \brief Key for Kernel::CodeProps::Metadata::mWorkgroupGroupSegmentSize.
+constexpr char WorkgroupGroupSegmentSize[] = "WorkgroupGroupSegmentSize";
+/// \brief Key for Kernel::CodeProps::Metadata::mWorkitemPrivateSegmentSize.
+constexpr char WorkitemPrivateSegmentSize[] = "WorkitemPrivateSegmentSize";
+/// \brief Key for Kernel::CodeProps::Metadata::mWavefrontNumSGPRs.
+constexpr char WavefrontNumSGPRs[] = "WavefrontNumSGPRs";
+/// \brief Key for Kernel::CodeProps::Metadata::mWorkitemNumVGPRs.
+constexpr char WorkitemNumVGPRs[] = "WorkitemNumVGPRs";
+/// \brief Key for Kernel::CodeProps::Metadata::mKernargSegmentAlign.
+constexpr char KernargSegmentAlign[] = "KernargSegmentAlign";
+/// \brief Key for Kernel::CodeProps::Metadata::mGroupSegmentAlign.
+constexpr char GroupSegmentAlign[] = "GroupSegmentAlign";
+/// \brief Key for Kernel::CodeProps::Metadata::mPrivateSegmentAlign.
+constexpr char PrivateSegmentAlign[] = "PrivateSegmentAlign";
+/// \brief Key for Kernel::CodeProps::Metadata::mWavefrontSize.
+constexpr char WavefrontSize[] = "WavefrontSize";
+} // end namespace Key
+
+/// \brief In-memory representation of kernel code properties metadata.
+struct Metadata final {
+ /// \brief Size in bytes of the kernarg segment memory. Kernarg segment memory
+ /// holds the values of the arguments to the kernel. Optional.
+ uint64_t mKernargSegmentSize = 0;
+ /// \brief Size in bytes of the group segment memory required by a workgroup.
+ /// This value does not include any dynamically allocated group segment memory
+ /// that may be added when the kernel is dispatched. Optional.
+ uint32_t mWorkgroupGroupSegmentSize = 0;
+ /// \brief Size in bytes of the private segment memory required by a workitem.
+ /// Private segment memory includes arg, spill and private segments. Optional.
+ uint32_t mWorkitemPrivateSegmentSize = 0;
+ /// \brief Total number of SGPRs used by a wavefront. Optional.
+ uint16_t mWavefrontNumSGPRs = 0;
+ /// \brief Total number of VGPRs used by a workitem. Optional.
+ uint16_t mWorkitemNumVGPRs = 0;
+ /// \brief Maximum byte alignment of variables used by the kernel in the
+ /// kernarg memory segment. Expressed as a power of two. Optional.
+ uint8_t mKernargSegmentAlign = 0;
+ /// \brief Maximum byte alignment of variables used by the kernel in the
+ /// group memory segment. Expressed as a power of two. Optional.
+ uint8_t mGroupSegmentAlign = 0;
+ /// \brief Maximum byte alignment of variables used by the kernel in the
+ /// private memory segment. Expressed as a power of two. Optional.
+ uint8_t mPrivateSegmentAlign = 0;
+ /// \brief Wavefront size. Expressed as a power of two. Optional.
+ uint8_t mWavefrontSize = 0;
+
+ /// \brief Default constructor.
+ Metadata() = default;
+
+ /// \returns True if kernel code properties metadata is empty, false
+ /// otherwise.
+ bool empty() const {
+ return !notEmpty();
+ }
+
+ /// \returns True if kernel code properties metadata is not empty, false
+ /// otherwise.
+ bool notEmpty() const {
+ return mKernargSegmentSize || mWorkgroupGroupSegmentSize ||
+ mWorkitemPrivateSegmentSize || mWavefrontNumSGPRs ||
+ mWorkitemNumVGPRs || mKernargSegmentAlign || mGroupSegmentAlign ||
+ mPrivateSegmentAlign || mWavefrontSize;
+ }
+};
+
+} // end namespace CodeProps
+
+//===----------------------------------------------------------------------===//
+// Kernel Debug Properties Metadata.
+//===----------------------------------------------------------------------===//
+namespace DebugProps {
+
+namespace Key {
+/// \brief Key for Kernel::DebugProps::Metadata::mDebuggerABIVersion.
+constexpr char DebuggerABIVersion[] = "DebuggerABIVersion";
+/// \brief Key for Kernel::DebugProps::Metadata::mReservedNumVGPRs.
+constexpr char ReservedNumVGPRs[] = "ReservedNumVGPRs";
+/// \brief Key for Kernel::DebugProps::Metadata::mReservedFirstVGPR.
+constexpr char ReservedFirstVGPR[] = "ReservedFirstVGPR";
+/// \brief Key for Kernel::DebugProps::Metadata::mPrivateSegmentBufferSGPR.
+constexpr char PrivateSegmentBufferSGPR[] = "PrivateSegmentBufferSGPR";
+/// \brief Key for
+/// Kernel::DebugProps::Metadata::mWavefrontPrivateSegmentOffsetSGPR.
+constexpr char WavefrontPrivateSegmentOffsetSGPR[] =
+ "WavefrontPrivateSegmentOffsetSGPR";
+} // end namespace Key
+
+/// \brief In-memory representation of kernel debug properties metadata.
+struct Metadata final {
+ /// \brief Debugger ABI version. Optional.
+ std::vector<uint32_t> mDebuggerABIVersion = std::vector<uint32_t>();
+ /// \brief Consecutive number of VGPRs reserved for debugger use. Must be 0 if
+ /// mDebuggerABIVersion is not set. Optional.
+ uint16_t mReservedNumVGPRs = 0;
+ /// \brief First fixed VGPR reserved. Must be uint16_t(-1) if
+ /// mDebuggerABIVersion is not set or mReservedFirstVGPR is 0. Optional.
+ uint16_t mReservedFirstVGPR = uint16_t(-1);
+ /// \brief Fixed SGPR of the first of 4 SGPRs used to hold the scratch V# used
+ /// for the entire kernel execution. Must be uint16_t(-1) if
+ /// mDebuggerABIVersion is not set or SGPR not used or not known. Optional.
+ uint16_t mPrivateSegmentBufferSGPR = uint16_t(-1);
+ /// \brief Fixed SGPR used to hold the wave scratch offset for the entire
+ /// kernel execution. Must be uint16_t(-1) if mDebuggerABIVersion is not set
+ /// or SGPR is not used or not known. Optional.
+ uint16_t mWavefrontPrivateSegmentOffsetSGPR = uint16_t(-1);
+
+ /// \brief Default constructor.
+ Metadata() = default;
+
+ /// \returns True if kernel debug properties metadata is empty, false
+ /// otherwise.
+ bool empty() const {
+ return !notEmpty();
+ }
+
+ /// \returns True if kernel debug properties metadata is not empty, false
+ /// otherwise.
+ bool notEmpty() const {
+ return !mDebuggerABIVersion.empty();
+ }
+};
+
+} // end namespace DebugProps
+
+namespace Key {
+/// \brief Key for Kernel::Metadata::mName.
+constexpr char Name[] = "Name";
+/// \brief Key for Kernel::Metadata::mLanguage.
+constexpr char Language[] = "Language";
+/// \brief Key for Kernel::Metadata::mLanguageVersion.
+constexpr char LanguageVersion[] = "LanguageVersion";
+/// \brief Key for Kernel::Metadata::mAttrs.
+constexpr char Attrs[] = "Attrs";
+/// \brief Key for Kernel::Metadata::mArgs.
+constexpr char Args[] = "Args";
+/// \brief Key for Kernel::Metadata::mCodeProps.
+constexpr char CodeProps[] = "CodeProps";
+/// \brief Key for Kernel::Metadata::mDebugProps.
+constexpr char DebugProps[] = "DebugProps";
+} // end namespace Key
+
+/// \brief In-memory representation of kernel metadata.
+struct Metadata final {
+ /// \brief Name. Required.
+ std::string mName = std::string();
+ /// \brief Language. Optional.
+ std::string mLanguage = std::string();
+ /// \brief Language version. Optional.
+ std::vector<uint32_t> mLanguageVersion = std::vector<uint32_t>();
+ /// \brief Attributes metadata. Optional.
+ Attrs::Metadata mAttrs = Attrs::Metadata();
+ /// \brief Arguments metadata. Optional.
+ std::vector<Arg::Metadata> mArgs = std::vector<Arg::Metadata>();
+ /// \brief Code properties metadata. Optional.
+ CodeProps::Metadata mCodeProps = CodeProps::Metadata();
+ /// \brief Debug properties metadata. Optional.
+ DebugProps::Metadata mDebugProps = DebugProps::Metadata();
+
+ /// \brief Default constructor.
+ Metadata() = default;
+};
+
+} // end namespace Kernel
+
+namespace Key {
+/// \brief Key for CodeObject::Metadata::mVersion.
+constexpr char Version[] = "Version";
+/// \brief Key for CodeObject::Metadata::mPrintf.
+constexpr char Printf[] = "Printf";
+/// \brief Key for CodeObject::Metadata::mKernels.
+constexpr char Kernels[] = "Kernels";
+} // end namespace Key
+
+/// \brief In-memory representation of code object metadata.
+struct Metadata final {
+ /// \brief Code object metadata version. Required.
+ std::vector<uint32_t> mVersion = std::vector<uint32_t>();
+ /// \brief Printf metadata. Optional.
+ std::vector<std::string> mPrintf = std::vector<std::string>();
+ /// \brief Kernels metadata. Optional.
+ std::vector<Kernel::Metadata> mKernels = std::vector<Kernel::Metadata>();
+
+ /// \brief Default constructor.
+ Metadata() = default;
+
+ /// \brief Converts \p YamlString to \p CodeObjectMetadata.
+ static std::error_code fromYamlString(std::string YamlString,
+ Metadata &CodeObjectMetadata);
+
+ /// \brief Converts \p CodeObjectMetadata to \p YamlString.
+ static std::error_code toYamlString(Metadata CodeObjectMetadata,
+ std::string &YamlString);
+};
+
+} // end namespace CodeObject
+} // end namespace AMDGPU
+} // end namespace llvm
+
+#endif // LLVM_SUPPORT_AMDGPUCODEOBJECTMETADATA_H
diff --git a/contrib/llvm/include/llvm/Support/ARMAttributeParser.h b/contrib/llvm/include/llvm/Support/ARMAttributeParser.h
new file mode 100644
index 0000000..919f397
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/ARMAttributeParser.h
@@ -0,0 +1,140 @@
+//===--- ARMAttributeParser.h - ARM Attribute Information Printer ---------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_ARMATTRIBUTEPARSER_H
+#define LLVM_SUPPORT_ARMATTRIBUTEPARSER_H
+
+#include "ARMBuildAttributes.h"
+#include "ScopedPrinter.h"
+
+#include <map>
+
+namespace llvm {
+class StringRef;
+
+class ARMAttributeParser {
+ ScopedPrinter *SW;
+
+ std::map<unsigned, unsigned> Attributes;
+
+ struct DisplayHandler {
+ ARMBuildAttrs::AttrType Attribute;
+ void (ARMAttributeParser::*Routine)(ARMBuildAttrs::AttrType,
+ const uint8_t *, uint32_t &);
+ };
+ 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 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);
+
+ 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;
+ }
+};
+
+}
+
+#endif
+
diff --git a/contrib/llvm/include/llvm/Support/ARMBuildAttributes.h b/contrib/llvm/include/llvm/Support/ARMBuildAttributes.h
index e254457..6c83e44 100644
--- a/contrib/llvm/include/llvm/Support/ARMBuildAttributes.h
+++ b/contrib/llvm/include/llvm/Support/ARMBuildAttributes.h
@@ -176,14 +176,25 @@ enum {
WCharWidth2Bytes = 2, // sizeof(wchar_t) == 2
WCharWidth4Bytes = 4, // sizeof(wchar_t) == 4
+ // Tag_ABI_align_needed, (=24), uleb128
+ Align8Byte = 1,
+ Align4Byte = 2,
+ AlignReserved = 3,
+
+ // Tag_ABI_align_needed, (=25), uleb128
+ AlignNotPreserved = 0,
+ AlignPreserve8Byte = 1,
+ AlignPreserveAll = 2,
+
// Tag_ABI_FP_denormal, (=20), uleb128
PositiveZero = 0,
IEEEDenormals = 1,
PreserveFPSign = 2, // sign when flushed-to-zero is preserved
// Tag_ABI_FP_number_model, (=23), uleb128
+ AllowIEEENormal = 1,
AllowRTABI = 2, // numbers, infinities, and one quiet NaN (see [RTABI])
- AllowIEE754 = 3, // this code to use all the IEEE 754-defined FP encodings
+ AllowIEEE754 = 3, // this code to use all the IEEE 754-defined FP encodings
// Tag_ABI_enum_size, (=26), uleb128
EnumProhibited = 0, // The user prohibited the use of enums when building
@@ -208,6 +219,7 @@ enum {
// Tag_FP_16bit_format, (=38), uleb128
FP16FormatIEEE = 1,
+ FP16VFP3 = 2,
// Tag_MPextension_use, (=42), uleb128
AllowMP = 1, // Allow use of MP extensions
diff --git a/contrib/llvm/include/llvm/Support/ARMTargetParser.def b/contrib/llvm/include/llvm/Support/ARMTargetParser.def
index 58cb638..65cb271 100644
--- a/contrib/llvm/include/llvm/Support/ARMTargetParser.def
+++ b/contrib/llvm/include/llvm/Support/ARMTargetParser.def
@@ -76,32 +76,35 @@ ARM_ARCH("armv6-m", AK_ARMV6M, "6-M", "v6m", ARMBuildAttrs::CPUArch::v6_M,
FK_NONE, ARM::AEK_NONE)
ARM_ARCH("armv7-a", AK_ARMV7A, "7-A", "v7", ARMBuildAttrs::CPUArch::v7,
FK_NEON, ARM::AEK_DSP)
+ARM_ARCH("armv7ve", AK_ARMV7VE, "7VE", "v7ve", ARMBuildAttrs::CPUArch::v7,
+ FK_NEON, (ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT |
+ ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP))
ARM_ARCH("armv7-r", AK_ARMV7R, "7-R", "v7r", ARMBuildAttrs::CPUArch::v7,
- FK_NONE, (ARM::AEK_HWDIV | ARM::AEK_DSP))
+ FK_NONE, (ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP))
ARM_ARCH("armv7-m", AK_ARMV7M, "7-M", "v7m", ARMBuildAttrs::CPUArch::v7,
- FK_NONE, ARM::AEK_HWDIV)
+ FK_NONE, ARM::AEK_HWDIVTHUMB)
ARM_ARCH("armv7e-m", AK_ARMV7EM, "7E-M", "v7em", ARMBuildAttrs::CPUArch::v7E_M,
- FK_NONE, (ARM::AEK_HWDIV | ARM::AEK_DSP))
+ FK_NONE, (ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP))
ARM_ARCH("armv8-a", AK_ARMV8A, "8-A", "v8", ARMBuildAttrs::CPUArch::v8_A,
FK_CRYPTO_NEON_FP_ARMV8,
(ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
- ARM::AEK_HWDIV | ARM::AEK_DSP | ARM::AEK_CRC))
+ ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | ARM::AEK_CRC))
ARM_ARCH("armv8.1-a", AK_ARMV8_1A, "8.1-A", "v8.1a",
ARMBuildAttrs::CPUArch::v8_A, FK_CRYPTO_NEON_FP_ARMV8,
(ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
- ARM::AEK_HWDIV | ARM::AEK_DSP | ARM::AEK_CRC))
+ ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | ARM::AEK_CRC))
ARM_ARCH("armv8.2-a", AK_ARMV8_2A, "8.2-A", "v8.2a",
ARMBuildAttrs::CPUArch::v8_A, FK_CRYPTO_NEON_FP_ARMV8,
(ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
- ARM::AEK_HWDIV | ARM::AEK_DSP | ARM::AEK_CRC | ARM::AEK_RAS))
+ ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | ARM::AEK_CRC | ARM::AEK_RAS))
ARM_ARCH("armv8-r", AK_ARMV8R, "8-R", "v8r", ARMBuildAttrs::CPUArch::v8_R,
FK_NEON_FP_ARMV8,
- (ARM::AEK_MP | ARM::AEK_VIRT | ARM::AEK_HWDIVARM | ARM::AEK_HWDIV |
+ (ARM::AEK_MP | ARM::AEK_VIRT | ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB |
ARM::AEK_DSP | ARM::AEK_CRC))
ARM_ARCH("armv8-m.base", AK_ARMV8MBaseline, "8-M.Baseline", "v8m.base",
- ARMBuildAttrs::CPUArch::v8_M_Base, FK_NONE, ARM::AEK_HWDIV)
+ ARMBuildAttrs::CPUArch::v8_M_Base, FK_NONE, ARM::AEK_HWDIVTHUMB)
ARM_ARCH("armv8-m.main", AK_ARMV8MMainline, "8-M.Mainline", "v8m.main",
- ARMBuildAttrs::CPUArch::v8_M_Main, FK_FPV5_D16, ARM::AEK_HWDIV)
+ ARMBuildAttrs::CPUArch::v8_M_Main, FK_FPV5_D16, ARM::AEK_HWDIVTHUMB)
// Non-standard Arch names.
ARM_ARCH("iwmmxt", AK_IWMMXT, "iwmmxt", "", ARMBuildAttrs::CPUArch::v5TE,
FK_NONE, ARM::AEK_NONE)
@@ -125,7 +128,7 @@ ARM_ARCH_EXT_NAME("crc", ARM::AEK_CRC, "+crc", "-crc")
ARM_ARCH_EXT_NAME("crypto", ARM::AEK_CRYPTO, "+crypto","-crypto")
ARM_ARCH_EXT_NAME("dsp", ARM::AEK_DSP, "+dsp", "-dsp")
ARM_ARCH_EXT_NAME("fp", ARM::AEK_FP, nullptr, nullptr)
-ARM_ARCH_EXT_NAME("idiv", (ARM::AEK_HWDIVARM | ARM::AEK_HWDIV), nullptr, nullptr)
+ARM_ARCH_EXT_NAME("idiv", (ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB), nullptr, nullptr)
ARM_ARCH_EXT_NAME("mp", ARM::AEK_MP, nullptr, nullptr)
ARM_ARCH_EXT_NAME("simd", ARM::AEK_SIMD, nullptr, nullptr)
ARM_ARCH_EXT_NAME("sec", ARM::AEK_SEC, nullptr, nullptr)
@@ -144,9 +147,9 @@ ARM_ARCH_EXT_NAME("xscale", ARM::AEK_XSCALE, nullptr, nullptr)
#endif
ARM_HW_DIV_NAME("invalid", ARM::AEK_INVALID)
ARM_HW_DIV_NAME("none", ARM::AEK_NONE)
-ARM_HW_DIV_NAME("thumb", ARM::AEK_HWDIV)
+ARM_HW_DIV_NAME("thumb", ARM::AEK_HWDIVTHUMB)
ARM_HW_DIV_NAME("arm", ARM::AEK_HWDIVARM)
-ARM_HW_DIV_NAME("arm,thumb", (ARM::AEK_HWDIVARM | ARM::AEK_HWDIV))
+ARM_HW_DIV_NAME("arm,thumb", (ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB))
#undef ARM_HW_DIV_NAME
#ifndef ARM_CPU_NAME
@@ -202,20 +205,20 @@ ARM_CPU_NAME("cortex-a5", AK_ARMV7A, FK_NEON_VFPV4, false,
(ARM::AEK_SEC | ARM::AEK_MP))
ARM_CPU_NAME("cortex-a7", AK_ARMV7A, FK_NEON_VFPV4, false,
(ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
- ARM::AEK_HWDIV))
-ARM_CPU_NAME("cortex-a8", AK_ARMV7A, FK_NEON, true, ARM::AEK_SEC)
+ ARM::AEK_HWDIVTHUMB))
+ARM_CPU_NAME("cortex-a8", AK_ARMV7A, FK_NEON, false, ARM::AEK_SEC)
ARM_CPU_NAME("cortex-a9", AK_ARMV7A, FK_NEON_FP16, false, (ARM::AEK_SEC | ARM::AEK_MP))
ARM_CPU_NAME("cortex-a12", AK_ARMV7A, FK_NEON_VFPV4, false,
(ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
- ARM::AEK_HWDIV))
+ ARM::AEK_HWDIVTHUMB))
ARM_CPU_NAME("cortex-a15", AK_ARMV7A, FK_NEON_VFPV4, false,
(ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
- ARM::AEK_HWDIV))
+ ARM::AEK_HWDIVTHUMB))
ARM_CPU_NAME("cortex-a17", AK_ARMV7A, FK_NEON_VFPV4, false,
(ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
- ARM::AEK_HWDIV))
+ ARM::AEK_HWDIVTHUMB))
ARM_CPU_NAME("krait", AK_ARMV7A, FK_NEON_VFPV4, false,
- (ARM::AEK_HWDIVARM | ARM::AEK_HWDIV))
+ (ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB))
ARM_CPU_NAME("cortex-r4", AK_ARMV7R, FK_NONE, true, ARM::AEK_NONE)
ARM_CPU_NAME("cortex-r4f", AK_ARMV7R, FK_VFPV3_D16, false, ARM::AEK_NONE)
ARM_CPU_NAME("cortex-r5", AK_ARMV7R, FK_VFPV3_D16, false,
@@ -229,9 +232,11 @@ ARM_CPU_NAME("sc300", AK_ARMV7M, FK_NONE, false, ARM::AEK_NONE)
ARM_CPU_NAME("cortex-m3", AK_ARMV7M, FK_NONE, true, ARM::AEK_NONE)
ARM_CPU_NAME("cortex-m4", AK_ARMV7EM, FK_FPV4_SP_D16, true, ARM::AEK_NONE)
ARM_CPU_NAME("cortex-m7", AK_ARMV7EM, FK_FPV5_D16, false, ARM::AEK_NONE)
+ARM_CPU_NAME("cortex-m23", AK_ARMV8MBaseline, FK_NONE, false, ARM::AEK_NONE)
+ARM_CPU_NAME("cortex-m33", AK_ARMV8MMainline, FK_FPV5_SP_D16, false, ARM::AEK_DSP)
ARM_CPU_NAME("cortex-a32", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false, ARM::AEK_CRC)
ARM_CPU_NAME("cortex-a35", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false, ARM::AEK_CRC)
-ARM_CPU_NAME("cortex-a53", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, true, ARM::AEK_CRC)
+ARM_CPU_NAME("cortex-a53", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false, ARM::AEK_CRC)
ARM_CPU_NAME("cortex-a57", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false, ARM::AEK_CRC)
ARM_CPU_NAME("cortex-a72", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false, ARM::AEK_CRC)
ARM_CPU_NAME("cortex-a73", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false, ARM::AEK_CRC)
@@ -239,11 +244,12 @@ ARM_CPU_NAME("cyclone", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false, ARM::AEK_CRC)
ARM_CPU_NAME("exynos-m1", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false, ARM::AEK_CRC)
ARM_CPU_NAME("exynos-m2", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false, ARM::AEK_CRC)
ARM_CPU_NAME("exynos-m3", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false, ARM::AEK_CRC)
+ARM_CPU_NAME("kryo", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false, ARM::AEK_CRC)
// Non-standard Arch names.
ARM_CPU_NAME("iwmmxt", AK_IWMMXT, FK_NONE, true, ARM::AEK_NONE)
ARM_CPU_NAME("xscale", AK_XSCALE, FK_NONE, true, ARM::AEK_NONE)
ARM_CPU_NAME("swift", AK_ARMV7S, FK_NEON_VFPV4, true,
- (ARM::AEK_HWDIVARM | ARM::AEK_HWDIV))
+ (ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB))
// Invalid CPU
ARM_CPU_NAME("invalid", AK_INVALID, FK_INVALID, true, ARM::AEK_INVALID)
#undef ARM_CPU_NAME
diff --git a/contrib/llvm/include/llvm/Support/Allocator.h b/contrib/llvm/include/llvm/Support/Allocator.h
index c71759a..a5e662f 100644
--- a/contrib/llvm/include/llvm/Support/Allocator.h
+++ b/contrib/llvm/include/llvm/Support/Allocator.h
@@ -1,4 +1,4 @@
-//===--- Allocator.h - Simple memory allocation abstraction -----*- C++ -*-===//
+//===- Allocator.h - Simple memory allocation abstraction -------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -144,19 +144,18 @@ public:
"that objects larger than a slab go into their own memory "
"allocation.");
- BumpPtrAllocatorImpl()
- : CurPtr(nullptr), End(nullptr), BytesAllocated(0), Allocator() {}
+ BumpPtrAllocatorImpl() = default;
+
template <typename T>
BumpPtrAllocatorImpl(T &&Allocator)
- : CurPtr(nullptr), End(nullptr), BytesAllocated(0),
- Allocator(std::forward<T &&>(Allocator)) {}
+ : Allocator(std::forward<T &&>(Allocator)) {}
// Manually implement a move constructor as we must clear the old allocator's
// slabs as a matter of correctness.
BumpPtrAllocatorImpl(BumpPtrAllocatorImpl &&Old)
: CurPtr(Old.CurPtr), End(Old.End), Slabs(std::move(Old.Slabs)),
CustomSizedSlabs(std::move(Old.CustomSizedSlabs)),
- BytesAllocated(Old.BytesAllocated),
+ BytesAllocated(Old.BytesAllocated), RedZoneSize(Old.RedZoneSize),
Allocator(std::move(Old.Allocator)) {
Old.CurPtr = Old.End = nullptr;
Old.BytesAllocated = 0;
@@ -176,6 +175,7 @@ public:
CurPtr = RHS.CurPtr;
End = RHS.End;
BytesAllocated = RHS.BytesAllocated;
+ RedZoneSize = RHS.RedZoneSize;
Slabs = std::move(RHS.Slabs);
CustomSizedSlabs = std::move(RHS.CustomSizedSlabs);
Allocator = std::move(RHS.Allocator);
@@ -218,10 +218,16 @@ public:
size_t Adjustment = alignmentAdjustment(CurPtr, Alignment);
assert(Adjustment + Size >= Size && "Adjustment + Size must not overflow");
+ size_t SizeToAllocate = Size;
+#if LLVM_ADDRESS_SANITIZER_BUILD
+ // Add trailing bytes as a "red zone" under ASan.
+ SizeToAllocate += RedZoneSize;
+#endif
+
// Check if we have enough space.
- if (Adjustment + Size <= size_t(End - CurPtr)) {
+ if (Adjustment + SizeToAllocate <= size_t(End - CurPtr)) {
char *AlignedPtr = CurPtr + Adjustment;
- CurPtr = AlignedPtr + Size;
+ CurPtr = AlignedPtr + SizeToAllocate;
// Update the allocation point of this memory block in MemorySanitizer.
// Without this, MemorySanitizer messages for values originated from here
// will point to the allocation of the entire slab.
@@ -232,7 +238,7 @@ public:
}
// If Size is really big, allocate a separate slab for it.
- size_t PaddedSize = Size + Alignment - 1;
+ size_t PaddedSize = SizeToAllocate + Alignment - 1;
if (PaddedSize > SizeThreshold) {
void *NewSlab = Allocator.Allocate(PaddedSize, 0);
// We own the new slab and don't want anyone reading anyting other than
@@ -251,10 +257,10 @@ public:
// Otherwise, start a new slab and try again.
StartNewSlab();
uintptr_t AlignedAddr = alignAddr(CurPtr, Alignment);
- assert(AlignedAddr + Size <= (uintptr_t)End &&
+ assert(AlignedAddr + SizeToAllocate <= (uintptr_t)End &&
"Unable to allocate memory!");
char *AlignedPtr = (char*)AlignedAddr;
- CurPtr = AlignedPtr + Size;
+ CurPtr = AlignedPtr + SizeToAllocate;
__msan_allocated_memory(AlignedPtr, Size);
__asan_unpoison_memory_region(AlignedPtr, Size);
return AlignedPtr;
@@ -283,6 +289,10 @@ public:
size_t getBytesAllocated() const { return BytesAllocated; }
+ void setRedZoneSize(size_t NewSize) {
+ RedZoneSize = NewSize;
+ }
+
void PrintStats() const {
detail::printBumpPtrAllocatorStats(Slabs.size(), BytesAllocated,
getTotalMemory());
@@ -292,10 +302,10 @@ private:
/// \brief The current pointer into the current slab.
///
/// This points to the next free byte in the slab.
- char *CurPtr;
+ char *CurPtr = nullptr;
/// \brief The end of the current slab.
- char *End;
+ char *End = nullptr;
/// \brief The slabs allocated so far.
SmallVector<void *, 4> Slabs;
@@ -306,7 +316,11 @@ private:
/// \brief How many bytes we've allocated.
///
/// Used so that we can compute how much space was wasted.
- size_t BytesAllocated;
+ size_t BytesAllocated = 0;
+
+ /// \brief The number of bytes to put between allocations when running under
+ /// a sanitizer.
+ size_t RedZoneSize = 1;
/// \brief The allocator instance we use to get slabs of memory.
AllocatorT Allocator;
@@ -357,7 +371,7 @@ private:
};
/// \brief The standard BumpPtrAllocator which just uses the default template
-/// paramaters.
+/// parameters.
typedef BumpPtrAllocatorImpl<> BumpPtrAllocator;
/// \brief A BumpPtrAllocator that allows only elements of a specific type to be
@@ -369,7 +383,11 @@ template <typename T> class SpecificBumpPtrAllocator {
BumpPtrAllocator Allocator;
public:
- SpecificBumpPtrAllocator() = default;
+ SpecificBumpPtrAllocator() {
+ // Because SpecificBumpPtrAllocator walks the memory to call destructors,
+ // it can't have red zones between allocations.
+ Allocator.setRedZoneSize(0);
+ }
SpecificBumpPtrAllocator(SpecificBumpPtrAllocator &&Old)
: Allocator(std::move(Old.Allocator)) {}
~SpecificBumpPtrAllocator() { DestroyAll(); }
diff --git a/contrib/llvm/include/llvm/Support/ArrayRecycler.h b/contrib/llvm/include/llvm/Support/ArrayRecycler.h
index 4698f12..68696be 100644
--- a/contrib/llvm/include/llvm/Support/ArrayRecycler.h
+++ b/contrib/llvm/include/llvm/Support/ArrayRecycler.h
@@ -47,7 +47,9 @@ template <class T, size_t Align = alignof(T)> class ArrayRecycler {
FreeList *Entry = Bucket[Idx];
if (!Entry)
return nullptr;
+ __asan_unpoison_memory_region(Entry, Capacity::get(Idx).getSize());
Bucket[Idx] = Entry->Next;
+ __msan_allocated_memory(Entry, Capacity::get(Idx).getSize());
return reinterpret_cast<T*>(Entry);
}
@@ -59,6 +61,7 @@ template <class T, size_t Align = alignof(T)> class ArrayRecycler {
Bucket.resize(size_t(Idx) + 1);
Entry->Next = Bucket[Idx];
Bucket[Idx] = Entry;
+ __asan_poison_memory_region(Ptr, Capacity::get(Idx).getSize());
}
public:
diff --git a/contrib/llvm/include/llvm/Support/Atomic.h b/contrib/llvm/include/llvm/Support/Atomic.h
index d03714b..552313f 100644
--- a/contrib/llvm/include/llvm/Support/Atomic.h
+++ b/contrib/llvm/include/llvm/Support/Atomic.h
@@ -20,6 +20,11 @@
#include "llvm/Support/DataTypes.h"
+// Windows will at times define MemoryFence.
+#ifdef MemoryFence
+#undef MemoryFence
+#endif
+
namespace llvm {
namespace sys {
void MemoryFence();
diff --git a/contrib/llvm/include/llvm/Support/BinaryByteStream.h b/contrib/llvm/include/llvm/Support/BinaryByteStream.h
new file mode 100644
index 0000000..694be28
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/BinaryByteStream.h
@@ -0,0 +1,192 @@
+//===- BinaryByteStream.h ---------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//===----------------------------------------------------------------------===//
+// A BinaryStream which stores data in a single continguous memory buffer.
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_BINARYBYTESTREAM_H
+#define LLVM_SUPPORT_BINARYBYTESTREAM_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/BinaryStream.h"
+#include "llvm/Support/BinaryStreamError.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/FileOutputBuffer.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include <algorithm>
+#include <cstdint>
+#include <cstring>
+#include <memory>
+
+namespace llvm {
+
+/// \brief An implementation of BinaryStream which holds its entire data set
+/// in a single contiguous buffer. BinaryByteStream guarantees that no read
+/// operation will ever incur a copy. Note that BinaryByteStream does not
+/// own the underlying buffer.
+class BinaryByteStream : public BinaryStream {
+public:
+ BinaryByteStream() = default;
+ BinaryByteStream(ArrayRef<uint8_t> Data, llvm::support::endianness Endian)
+ : Endian(Endian), Data(Data) {}
+ BinaryByteStream(StringRef Data, llvm::support::endianness Endian)
+ : Endian(Endian), Data(Data.bytes_begin(), Data.bytes_end()) {}
+
+ llvm::support::endianness getEndian() const override { return Endian; }
+
+ Error readBytes(uint32_t Offset, uint32_t Size,
+ ArrayRef<uint8_t> &Buffer) override {
+ if (auto EC = checkOffset(Offset, Size))
+ return EC;
+ Buffer = Data.slice(Offset, Size);
+ return Error::success();
+ }
+
+ Error readLongestContiguousChunk(uint32_t Offset,
+ ArrayRef<uint8_t> &Buffer) override {
+ if (auto EC = checkOffset(Offset, 1))
+ return EC;
+ Buffer = Data.slice(Offset);
+ return Error::success();
+ }
+
+ uint32_t getLength() override { return Data.size(); }
+
+ ArrayRef<uint8_t> data() const { return Data; }
+
+ StringRef str() const {
+ const char *CharData = reinterpret_cast<const char *>(Data.data());
+ return StringRef(CharData, Data.size());
+ }
+
+protected:
+ llvm::support::endianness Endian;
+ ArrayRef<uint8_t> Data;
+};
+
+/// \brief An implementation of BinaryStream whose data is backed by an llvm
+/// MemoryBuffer object. MemoryBufferByteStream owns the MemoryBuffer in
+/// question. As with BinaryByteStream, reading from a MemoryBufferByteStream
+/// will never cause a copy.
+class MemoryBufferByteStream : public BinaryByteStream {
+public:
+ MemoryBufferByteStream(std::unique_ptr<MemoryBuffer> Buffer,
+ llvm::support::endianness Endian)
+ : BinaryByteStream(Buffer->getBuffer(), Endian),
+ MemBuffer(std::move(Buffer)) {}
+
+ std::unique_ptr<MemoryBuffer> MemBuffer;
+};
+
+/// \brief An implementation of BinaryStream which holds its entire data set
+/// in a single contiguous buffer. As with BinaryByteStream, the mutable
+/// version also guarantees that no read operation will ever incur a copy,
+/// and similarly it does not own the underlying buffer.
+class MutableBinaryByteStream : public WritableBinaryStream {
+public:
+ MutableBinaryByteStream() = default;
+ MutableBinaryByteStream(MutableArrayRef<uint8_t> Data,
+ llvm::support::endianness Endian)
+ : Data(Data), ImmutableStream(Data, Endian) {}
+
+ llvm::support::endianness getEndian() const override {
+ return ImmutableStream.getEndian();
+ }
+
+ Error readBytes(uint32_t Offset, uint32_t Size,
+ ArrayRef<uint8_t> &Buffer) override {
+ return ImmutableStream.readBytes(Offset, Size, Buffer);
+ }
+
+ Error readLongestContiguousChunk(uint32_t Offset,
+ ArrayRef<uint8_t> &Buffer) override {
+ return ImmutableStream.readLongestContiguousChunk(Offset, Buffer);
+ }
+
+ uint32_t getLength() override { return ImmutableStream.getLength(); }
+
+ Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Buffer) override {
+ if (Buffer.empty())
+ return Error::success();
+
+ if (auto EC = checkOffset(Offset, Buffer.size()))
+ return EC;
+
+ uint8_t *DataPtr = const_cast<uint8_t *>(Data.data());
+ ::memcpy(DataPtr + Offset, Buffer.data(), Buffer.size());
+ return Error::success();
+ }
+
+ Error commit() override { return Error::success(); }
+
+ MutableArrayRef<uint8_t> data() const { return Data; }
+
+private:
+ MutableArrayRef<uint8_t> Data;
+ BinaryByteStream ImmutableStream;
+};
+
+/// \brief An implementation of WritableBinaryStream backed by an llvm
+/// FileOutputBuffer.
+class FileBufferByteStream : public WritableBinaryStream {
+private:
+ class StreamImpl : public MutableBinaryByteStream {
+ public:
+ StreamImpl(std::unique_ptr<FileOutputBuffer> Buffer,
+ llvm::support::endianness Endian)
+ : MutableBinaryByteStream(
+ MutableArrayRef<uint8_t>(Buffer->getBufferStart(),
+ Buffer->getBufferEnd()),
+ Endian),
+ FileBuffer(std::move(Buffer)) {}
+
+ Error commit() override {
+ if (FileBuffer->commit())
+ return make_error<BinaryStreamError>(
+ stream_error_code::filesystem_error);
+ return Error::success();
+ }
+
+ private:
+ std::unique_ptr<FileOutputBuffer> FileBuffer;
+ };
+
+public:
+ FileBufferByteStream(std::unique_ptr<FileOutputBuffer> Buffer,
+ llvm::support::endianness Endian)
+ : Impl(std::move(Buffer), Endian) {}
+
+ llvm::support::endianness getEndian() const override {
+ return Impl.getEndian();
+ }
+
+ Error readBytes(uint32_t Offset, uint32_t Size,
+ ArrayRef<uint8_t> &Buffer) override {
+ return Impl.readBytes(Offset, Size, Buffer);
+ }
+
+ Error readLongestContiguousChunk(uint32_t Offset,
+ ArrayRef<uint8_t> &Buffer) override {
+ return Impl.readLongestContiguousChunk(Offset, Buffer);
+ }
+
+ uint32_t getLength() override { return Impl.getLength(); }
+
+ Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Data) override {
+ return Impl.writeBytes(Offset, Data);
+ }
+
+ Error commit() override { return Impl.commit(); }
+
+private:
+ StreamImpl Impl;
+};
+
+} // end namespace llvm
+
+#endif // LLVM_SUPPORT_BYTESTREAM_H
diff --git a/contrib/llvm/include/llvm/Support/BinaryItemStream.h b/contrib/llvm/include/llvm/Support/BinaryItemStream.h
new file mode 100644
index 0000000..fe7e6ca
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/BinaryItemStream.h
@@ -0,0 +1,108 @@
+//===- BinaryItemStream.h ---------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_BINARYITEMSTREAM_H
+#define LLVM_SUPPORT_BINARYITEMSTREAM_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/Support/BinaryStream.h"
+#include "llvm/Support/BinaryStreamError.h"
+#include "llvm/Support/Error.h"
+#include <cstddef>
+#include <cstdint>
+
+namespace llvm {
+
+template <typename T> struct BinaryItemTraits {
+ static size_t length(const T &Item) = delete;
+ static ArrayRef<uint8_t> bytes(const T &Item) = delete;
+};
+
+/// BinaryItemStream represents a sequence of objects stored in some kind of
+/// external container but for which it is useful to view as a stream of
+/// contiguous bytes. An example of this might be if you have a collection of
+/// records and you serialize each one into a buffer, and store these serialized
+/// records in a container. The pointers themselves are not laid out
+/// contiguously in memory, but we may wish to read from or write to these
+/// records as if they were.
+template <typename T, typename Traits = BinaryItemTraits<T>>
+class BinaryItemStream : public BinaryStream {
+public:
+ explicit BinaryItemStream(llvm::support::endianness Endian)
+ : Endian(Endian) {}
+
+ llvm::support::endianness getEndian() const override { return Endian; }
+
+ Error readBytes(uint32_t Offset, uint32_t Size,
+ ArrayRef<uint8_t> &Buffer) override {
+ auto ExpectedIndex = translateOffsetIndex(Offset);
+ if (!ExpectedIndex)
+ return ExpectedIndex.takeError();
+ const auto &Item = Items[*ExpectedIndex];
+ if (auto EC = checkOffset(Offset, Size))
+ return EC;
+ if (Size > Traits::length(Item))
+ return make_error<BinaryStreamError>(stream_error_code::stream_too_short);
+ Buffer = Traits::bytes(Item).take_front(Size);
+ return Error::success();
+ }
+
+ Error readLongestContiguousChunk(uint32_t Offset,
+ ArrayRef<uint8_t> &Buffer) override {
+ auto ExpectedIndex = translateOffsetIndex(Offset);
+ if (!ExpectedIndex)
+ return ExpectedIndex.takeError();
+ Buffer = Traits::bytes(Items[*ExpectedIndex]);
+ return Error::success();
+ }
+
+ void setItems(ArrayRef<T> ItemArray) {
+ Items = ItemArray;
+ computeItemOffsets();
+ }
+
+ uint32_t getLength() override {
+ return ItemEndOffsets.empty() ? 0 : ItemEndOffsets.back();
+ }
+
+private:
+ void computeItemOffsets() {
+ ItemEndOffsets.clear();
+ ItemEndOffsets.reserve(Items.size());
+ uint32_t CurrentOffset = 0;
+ for (const auto &Item : Items) {
+ uint32_t Len = Traits::length(Item);
+ assert(Len > 0 && "no empty items");
+ CurrentOffset += Len;
+ ItemEndOffsets.push_back(CurrentOffset);
+ }
+ }
+
+ Expected<uint32_t> translateOffsetIndex(uint32_t Offset) {
+ // Make sure the offset is somewhere in our items array.
+ if (Offset >= getLength())
+ return make_error<BinaryStreamError>(stream_error_code::stream_too_short);
+ ++Offset;
+ auto Iter =
+ std::lower_bound(ItemEndOffsets.begin(), ItemEndOffsets.end(), Offset);
+ size_t Idx = std::distance(ItemEndOffsets.begin(), Iter);
+ assert(Idx < Items.size() && "binary search for offset failed");
+ return Idx;
+ }
+
+ llvm::support::endianness Endian;
+ ArrayRef<T> Items;
+
+ // Sorted vector of offsets to accelerate lookup.
+ std::vector<uint32_t> ItemEndOffsets;
+};
+
+} // end namespace llvm
+
+#endif // LLVM_SUPPORT_BINARYITEMSTREAM_H
diff --git a/contrib/llvm/include/llvm/Support/BinaryStream.h b/contrib/llvm/include/llvm/Support/BinaryStream.h
new file mode 100644
index 0000000..a227117
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/BinaryStream.h
@@ -0,0 +1,78 @@
+//===- BinaryStream.h - Base interface for a stream of data -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_BINARYSTREAM_H
+#define LLVM_SUPPORT_BINARYSTREAM_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/Support/BinaryStreamError.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
+#include <cstdint>
+
+namespace llvm {
+
+/// \brief An interface for accessing data in a stream-like format, but which
+/// discourages copying. Instead of specifying a buffer in which to copy
+/// data on a read, the API returns an ArrayRef to data owned by the stream's
+/// implementation. Since implementations may not necessarily store data in a
+/// single contiguous buffer (or even in memory at all), in such cases a it may
+/// be necessary for an implementation to cache such a buffer so that it can
+/// return it.
+class BinaryStream {
+public:
+ virtual ~BinaryStream() = default;
+
+ virtual llvm::support::endianness getEndian() const = 0;
+
+ /// \brief Given an offset into the stream and a number of bytes, attempt to
+ /// read the bytes and set the output ArrayRef to point to data owned by the
+ /// stream.
+ virtual Error readBytes(uint32_t Offset, uint32_t Size,
+ ArrayRef<uint8_t> &Buffer) = 0;
+
+ /// \brief Given an offset into the stream, read as much as possible without
+ /// copying any data.
+ virtual Error readLongestContiguousChunk(uint32_t Offset,
+ ArrayRef<uint8_t> &Buffer) = 0;
+
+ /// \brief Return the number of bytes of data in this stream.
+ virtual uint32_t getLength() = 0;
+
+protected:
+ Error checkOffset(uint32_t Offset, uint32_t DataSize) {
+ if (Offset > getLength())
+ return make_error<BinaryStreamError>(stream_error_code::invalid_offset);
+ if (getLength() < DataSize + Offset)
+ return make_error<BinaryStreamError>(stream_error_code::stream_too_short);
+ return Error::success();
+ }
+};
+
+/// \brief A BinaryStream which can be read from as well as written to. Note
+/// that writing to a BinaryStream always necessitates copying from the input
+/// buffer to the stream's backing store. Streams are assumed to be buffered
+/// so that to be portable it is necessary to call commit() on the stream when
+/// all data has been written.
+class WritableBinaryStream : public BinaryStream {
+public:
+ ~WritableBinaryStream() override = default;
+
+ /// \brief Attempt to write the given bytes into the stream at the desired
+ /// offset. This will always necessitate a copy. Cannot shrink or grow the
+ /// stream, only writes into existing allocated space.
+ virtual Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Data) = 0;
+
+ /// \brief For buffered streams, commits changes to the backing store.
+ virtual Error commit() = 0;
+};
+
+} // end namespace llvm
+
+#endif // LLVM_SUPPORT_BINARYSTREAM_H
diff --git a/contrib/llvm/include/llvm/DebugInfo/MSF/StreamArray.h b/contrib/llvm/include/llvm/Support/BinaryStreamArray.h
index 5dfeb8c..3f5562b 100644
--- a/contrib/llvm/include/llvm/DebugInfo/MSF/StreamArray.h
+++ b/contrib/llvm/include/llvm/Support/BinaryStreamArray.h
@@ -1,4 +1,4 @@
-//===- StreamArray.h - Array backed by an arbitrary stream ------*- C++ -*-===//
+//===- BinaryStreamArray.h - Array backed by an arbitrary stream *- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,21 +7,30 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_DEBUGINFO_MSF_STREAMARRAY_H
-#define LLVM_DEBUGINFO_MSF_STREAMARRAY_H
+#ifndef LLVM_SUPPORT_BINARYSTREAMARRAY_H
+#define LLVM_SUPPORT_BINARYSTREAMARRAY_H
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/iterator.h"
-#include "llvm/DebugInfo/MSF/StreamRef.h"
+#include "llvm/Support/BinaryStreamRef.h"
#include "llvm/Support/Error.h"
#include <cassert>
#include <cstdint>
+/// Lightweight arrays that are backed by an arbitrary BinaryStream. This file
+/// provides two different array implementations.
+///
+/// VarStreamArray - Arrays of variable length records. The user specifies
+/// an Extractor type that can extract a record from a given offset and
+/// return the number of bytes consumed by the record.
+///
+/// FixedStreamArray - Arrays of fixed length records. This is similar in
+/// spirit to ArrayRef<T>, but since it is backed by a BinaryStream, the
+/// elements of the array need not be laid out in contiguous memory.
namespace llvm {
-namespace msf {
/// VarStreamArrayExtractor is intended to be specialized to provide customized
-/// extraction logic. On input it receives a StreamRef pointing to the
+/// extraction logic. On input it receives a BinaryStreamRef pointing to the
/// beginning of the next record, but where the length of the record is not yet
/// known. Upon completion, it should return an appropriate Error instance if
/// a record could not be extracted, or if one could be extracted it should
@@ -35,7 +44,7 @@ namespace msf {
template <typename T> struct VarStreamArrayExtractor {
// Method intentionally deleted. You must provide an explicit specialization
// with the following method implemented.
- Error operator()(ReadableStreamRef Stream, uint32_t &Len,
+ Error operator()(BinaryStreamRef Stream, uint32_t &Len,
T &Item) const = delete;
};
@@ -49,10 +58,10 @@ template <typename T> struct VarStreamArrayExtractor {
/// abstracting this out, we need not duplicate this memory, and we can
/// iterate over arrays in arbitrarily formatted streams. Elements are parsed
/// lazily on iteration, so there is no upfront cost associated with building
-/// a VarStreamArray, no matter how large it may be.
+/// or copying a VarStreamArray, no matter how large it may be.
///
/// You create a VarStreamArray by specifying a ValueType and an Extractor type.
-/// If you do not specify an Extractor type, it expects you to specialize
+/// If you do not specify an Extractor type, you are expected to specialize
/// VarStreamArrayExtractor<T> for your ValueType.
///
/// By default an Extractor is default constructed in the class, but in some
@@ -72,11 +81,11 @@ template <typename T> struct VarStreamArrayExtractor {
/// MyExtractor E(SomeContext);
/// VarStreamArray<MyType, MyExtractor> MyTypeArray3(E);
///
+
template <typename ValueType, typename Extractor> class VarStreamArrayIterator;
template <typename ValueType,
typename Extractor = VarStreamArrayExtractor<ValueType>>
-
class VarStreamArray {
friend class VarStreamArrayIterator<ValueType, Extractor>;
@@ -84,27 +93,40 @@ public:
typedef VarStreamArrayIterator<ValueType, Extractor> Iterator;
VarStreamArray() = default;
+
explicit VarStreamArray(const Extractor &E) : E(E) {}
- explicit VarStreamArray(ReadableStreamRef Stream) : Stream(Stream) {}
- VarStreamArray(ReadableStreamRef Stream, const Extractor &E)
- : Stream(Stream), E(E) {}
+ explicit VarStreamArray(BinaryStreamRef Stream) : Stream(Stream) {}
- VarStreamArray(const VarStreamArray<ValueType, Extractor> &Other)
- : Stream(Other.Stream), E(Other.E) {}
+ VarStreamArray(BinaryStreamRef Stream, const Extractor &E)
+ : Stream(Stream), E(E) {}
Iterator begin(bool *HadError = nullptr) const {
return Iterator(*this, E, HadError);
}
+ bool valid() const { return Stream.valid(); }
+
Iterator end() const { return Iterator(E); }
+ bool empty() const { return Stream.getLength() == 0; }
+
+ /// \brief given an offset into the array's underlying stream, return an
+ /// iterator to the record at that offset. This is considered unsafe
+ /// since the behavior is undefined if \p Offset does not refer to the
+ /// beginning of a valid record.
+ Iterator at(uint32_t Offset) const {
+ return Iterator(*this, E, Offset, nullptr);
+ }
+
const Extractor &getExtractor() const { return E; }
+ Extractor &getExtractor() { return E; }
- ReadableStreamRef getUnderlyingStream() const { return Stream; }
+ BinaryStreamRef getUnderlyingStream() const { return Stream; }
+ void setUnderlyingStream(BinaryStreamRef S) { Stream = S; }
private:
- ReadableStreamRef Stream;
+ BinaryStreamRef Stream;
Extractor E;
};
@@ -117,8 +139,13 @@ class VarStreamArrayIterator
public:
VarStreamArrayIterator(const ArrayType &Array, const Extractor &E,
- bool *HadError = nullptr)
- : IterRef(Array.Stream), Array(&Array), HadError(HadError), Extract(E) {
+ bool *HadError)
+ : VarStreamArrayIterator(Array, E, 0, HadError) {}
+
+ VarStreamArrayIterator(const ArrayType &Array, const Extractor &E,
+ uint32_t Offset, bool *HadError)
+ : IterRef(Array.Stream.drop_front(Offset)), Extract(E),
+ Array(&Array), AbsOffset(Offset), HadError(HadError) {
if (IterRef.getLength() == 0)
moveToEnd();
else {
@@ -129,6 +156,7 @@ public:
}
}
}
+
VarStreamArrayIterator() = default;
explicit VarStreamArrayIterator(const Extractor &E) : Extract(E) {}
~VarStreamArrayIterator() = default;
@@ -153,28 +181,39 @@ public:
return ThisValue;
}
- IterType &operator++() {
- // We are done with the current record, discard it so that we are
- // positioned at the next record.
- IterRef = IterRef.drop_front(ThisLen);
- if (IterRef.getLength() == 0) {
- // There is nothing after the current record, we must make this an end
- // iterator.
- moveToEnd();
- } else {
- // There is some data after the current record.
- auto EC = Extract(IterRef, ThisLen, ThisValue);
- if (EC) {
- consumeError(std::move(EC));
- markError();
- } else if (ThisLen == 0) {
- // An empty record? Make this an end iterator.
+ ValueType &operator*() {
+ assert(Array && !HasError);
+ return ThisValue;
+ }
+
+ IterType &operator+=(unsigned N) {
+ for (unsigned I = 0; I < N; ++I) {
+ // We are done with the current record, discard it so that we are
+ // positioned at the next record.
+ AbsOffset += ThisLen;
+ IterRef = IterRef.drop_front(ThisLen);
+ if (IterRef.getLength() == 0) {
+ // There is nothing after the current record, we must make this an end
+ // iterator.
moveToEnd();
+ } else {
+ // There is some data after the current record.
+ auto EC = Extract(IterRef, ThisLen, ThisValue);
+ if (EC) {
+ consumeError(std::move(EC));
+ markError();
+ } else if (ThisLen == 0) {
+ // An empty record? Make this an end iterator.
+ moveToEnd();
+ }
}
}
return *this;
}
+ uint32_t offset() const { return AbsOffset; }
+ uint32_t getRecordLength() const { return ThisLen; }
+
private:
void moveToEnd() {
Array = nullptr;
@@ -188,22 +227,30 @@ private:
}
ValueType ThisValue;
- ReadableStreamRef IterRef;
+ BinaryStreamRef IterRef;
+ Extractor Extract;
const ArrayType *Array{nullptr};
uint32_t ThisLen{0};
+ uint32_t AbsOffset{0};
bool HasError{false};
bool *HadError{nullptr};
- Extractor Extract;
};
template <typename T> class FixedStreamArrayIterator;
+/// FixedStreamArray is similar to VarStreamArray, except with each record
+/// having a fixed-length. As with VarStreamArray, there is no upfront
+/// cost associated with building or copying a FixedStreamArray, as the
+/// memory for each element is not read from the backing stream until that
+/// element is iterated.
template <typename T> class FixedStreamArray {
friend class FixedStreamArrayIterator<T>;
public:
+ typedef FixedStreamArrayIterator<T> Iterator;
+
FixedStreamArray() = default;
- FixedStreamArray(ReadableStreamRef Stream) : Stream(Stream) {
+ explicit FixedStreamArray(BinaryStreamRef Stream) : Stream(Stream) {
assert(Stream.getLength() % sizeof(T) == 0);
}
@@ -227,6 +274,7 @@ public:
// an exact multiple of the element size.
consumeError(std::move(EC));
}
+ assert(llvm::alignmentAdjustment(Data.data(), alignof(T)) == 0);
return *reinterpret_cast<const T *>(Data.data());
}
@@ -242,16 +290,22 @@ public:
return FixedStreamArrayIterator<T>(*this, size());
}
- ReadableStreamRef getUnderlyingStream() const { return Stream; }
+ const T &front() const { return *begin(); }
+ const T &back() const {
+ FixedStreamArrayIterator<T> I = end();
+ return *(--I);
+ }
+
+ BinaryStreamRef getUnderlyingStream() const { return Stream; }
private:
- ReadableStreamRef Stream;
+ BinaryStreamRef Stream;
};
template <typename T>
class FixedStreamArrayIterator
: public iterator_facade_base<FixedStreamArrayIterator<T>,
- std::random_access_iterator_tag, T> {
+ std::random_access_iterator_tag, const T> {
public:
FixedStreamArrayIterator(const FixedStreamArray<T> &Array, uint32_t Index)
@@ -265,6 +319,7 @@ public:
}
const T &operator*() const { return Array[Index]; }
+ const T &operator*() { return Array[Index]; }
bool operator==(const FixedStreamArrayIterator<T> &R) const {
assert(Array == R.Array);
@@ -277,7 +332,7 @@ public:
}
FixedStreamArrayIterator<T> &operator-=(std::ptrdiff_t N) {
- assert(Index >= N);
+ assert(std::ptrdiff_t(Index) >= N);
Index -= N;
return *this;
}
@@ -298,7 +353,6 @@ private:
uint32_t Index;
};
-} // namespace msf
} // namespace llvm
-#endif // LLVM_DEBUGINFO_MSF_STREAMARRAY_H
+#endif // LLVM_SUPPORT_BINARYSTREAMARRAY_H
diff --git a/contrib/llvm/include/llvm/Support/BinaryStreamError.h b/contrib/llvm/include/llvm/Support/BinaryStreamError.h
new file mode 100644
index 0000000..7d9699d
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/BinaryStreamError.h
@@ -0,0 +1,48 @@
+//===- BinaryStreamError.h - Error extensions for Binary Streams *- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_BINARYSTREAMERROR_H
+#define LLVM_SUPPORT_BINARYSTREAMERROR_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Error.h"
+
+#include <string>
+
+namespace llvm {
+enum class stream_error_code {
+ unspecified,
+ stream_too_short,
+ invalid_array_size,
+ invalid_offset,
+ filesystem_error
+};
+
+/// Base class for errors originating when parsing raw PDB files
+class BinaryStreamError : public ErrorInfo<BinaryStreamError> {
+public:
+ static char ID;
+ explicit BinaryStreamError(stream_error_code C);
+ explicit BinaryStreamError(StringRef Context);
+ BinaryStreamError(stream_error_code C, StringRef Context);
+
+ void log(raw_ostream &OS) const override;
+ std::error_code convertToErrorCode() const override;
+
+ StringRef getErrorMessage() const;
+
+ stream_error_code getErrorCode() const { return Code; }
+
+private:
+ std::string ErrMsg;
+ stream_error_code Code;
+};
+} // namespace llvm
+
+#endif // LLVM_SUPPORT_BINARYSTREAMERROR_H
diff --git a/contrib/llvm/include/llvm/Support/BinaryStreamReader.h b/contrib/llvm/include/llvm/Support/BinaryStreamReader.h
new file mode 100644
index 0000000..ae5ebb2
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/BinaryStreamReader.h
@@ -0,0 +1,270 @@
+//===- BinaryStreamReader.h - Reads objects from a binary stream *- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_BINARYSTREAMREADER_H
+#define LLVM_SUPPORT_BINARYSTREAMREADER_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/BinaryStreamArray.h"
+#include "llvm/Support/BinaryStreamRef.h"
+#include "llvm/Support/ConvertUTF.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/type_traits.h"
+
+#include <string>
+#include <type_traits>
+
+namespace llvm {
+
+/// \brief Provides read only access to a subclass of `BinaryStream`. Provides
+/// bounds checking and helpers for writing certain common data types such as
+/// null-terminated strings, integers in various flavors of endianness, etc.
+/// Can be subclassed to provide reading of custom datatypes, although no
+/// are overridable.
+class BinaryStreamReader {
+public:
+ BinaryStreamReader() = default;
+ explicit BinaryStreamReader(BinaryStreamRef Ref);
+ explicit BinaryStreamReader(BinaryStream &Stream);
+ explicit BinaryStreamReader(ArrayRef<uint8_t> Data,
+ llvm::support::endianness Endian);
+ explicit BinaryStreamReader(StringRef Data, llvm::support::endianness Endian);
+
+ BinaryStreamReader(const BinaryStreamReader &Other)
+ : Stream(Other.Stream), Offset(Other.Offset) {}
+
+ BinaryStreamReader &operator=(const BinaryStreamReader &Other) {
+ Stream = Other.Stream;
+ Offset = Other.Offset;
+ return *this;
+ }
+
+ virtual ~BinaryStreamReader() {}
+
+ /// Read as much as possible from the underlying string at the current offset
+ /// without invoking a copy, and set \p Buffer to the resulting data slice.
+ /// Updates the stream's offset to point after the newly read data.
+ ///
+ /// \returns a success error code if the data was successfully read, otherwise
+ /// returns an appropriate error code.
+ Error readLongestContiguousChunk(ArrayRef<uint8_t> &Buffer);
+
+ /// Read \p Size bytes from the underlying stream at the current offset and
+ /// and set \p Buffer to the resulting data slice. Whether a copy occurs
+ /// depends on the implementation of the underlying stream. Updates the
+ /// stream's offset to point after the newly read data.
+ ///
+ /// \returns a success error code if the data was successfully read, otherwise
+ /// returns an appropriate error code.
+ Error readBytes(ArrayRef<uint8_t> &Buffer, uint32_t Size);
+
+ /// Read an integer of the specified endianness into \p Dest and update the
+ /// stream's offset. The data is always copied from the stream's underlying
+ /// buffer into \p Dest. Updates the stream's offset to point after the newly
+ /// read data.
+ ///
+ /// \returns a success error code if the data was successfully read, otherwise
+ /// returns an appropriate error code.
+ template <typename T> Error readInteger(T &Dest) {
+ static_assert(std::is_integral<T>::value,
+ "Cannot call readInteger with non-integral value!");
+
+ ArrayRef<uint8_t> Bytes;
+ if (auto EC = readBytes(Bytes, sizeof(T)))
+ return EC;
+
+ Dest = llvm::support::endian::read<T, llvm::support::unaligned>(
+ Bytes.data(), Stream.getEndian());
+ return Error::success();
+ }
+
+ /// Similar to readInteger.
+ 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;
+ if (auto EC = readInteger(N))
+ return EC;
+ Dest = static_cast<T>(N);
+ return Error::success();
+ }
+
+ /// Read a null terminated string from \p Dest. Whether a copy occurs depends
+ /// on the implementation of the underlying stream. Updates the stream's
+ /// offset to point after the newly read data.
+ ///
+ /// \returns a success error code if the data was successfully read, otherwise
+ /// returns an appropriate error code.
+ Error readCString(StringRef &Dest);
+
+ /// Similar to readCString, however read a null-terminated UTF16 string
+ /// instead.
+ ///
+ /// \returns a success error code if the data was successfully read, otherwise
+ /// returns an appropriate error code.
+ Error readWideString(ArrayRef<UTF16> &Dest);
+
+ /// Read a \p Length byte string into \p Dest. Whether a copy occurs depends
+ /// on the implementation of the underlying stream. Updates the stream's
+ /// offset to point after the newly read data.
+ ///
+ /// \returns a success error code if the data was successfully read, otherwise
+ /// returns an appropriate error code.
+ Error readFixedString(StringRef &Dest, uint32_t Length);
+
+ /// Read the entire remainder of the underlying stream into \p Ref. This is
+ /// equivalent to calling getUnderlyingStream().slice(Offset). Updates the
+ /// stream's offset to point to the end of the stream. Never causes a copy.
+ ///
+ /// \returns a success error code if the data was successfully read, otherwise
+ /// returns an appropriate error code.
+ Error readStreamRef(BinaryStreamRef &Ref);
+
+ /// Read \p Length bytes from the underlying stream into \p Ref. This is
+ /// equivalent to calling getUnderlyingStream().slice(Offset, Length).
+ /// Updates the stream's offset to point after the newly read object. Never
+ /// causes a copy.
+ ///
+ /// \returns a success error code if the data was successfully read, otherwise
+ /// returns an appropriate error code.
+ Error readStreamRef(BinaryStreamRef &Ref, uint32_t Length);
+
+ /// Read \p Length bytes from the underlying stream into \p Stream. This is
+ /// equivalent to calling getUnderlyingStream().slice(Offset, Length).
+ /// Updates the stream's offset to point after the newly read object. Never
+ /// causes a copy.
+ ///
+ /// \returns a success error code if the data was successfully read, otherwise
+ /// returns an appropriate error code.
+ Error readSubstream(BinarySubstreamRef &Stream, uint32_t Size);
+
+ /// Get a pointer to an object of type T from the underlying stream, as if by
+ /// memcpy, and store the result into \p Dest. It is up to the caller to
+ /// ensure that objects of type T can be safely treated in this manner.
+ /// Updates the stream's offset to point after the newly read object. Whether
+ /// a copy occurs depends upon the implementation of the underlying
+ /// stream.
+ ///
+ /// \returns a success error code if the data was successfully read, otherwise
+ /// returns an appropriate error code.
+ template <typename T> Error readObject(const T *&Dest) {
+ ArrayRef<uint8_t> Buffer;
+ if (auto EC = readBytes(Buffer, sizeof(T)))
+ return EC;
+ Dest = reinterpret_cast<const T *>(Buffer.data());
+ return Error::success();
+ }
+
+ /// Get a reference to a \p NumElements element array of objects of type T
+ /// from the underlying stream as if by memcpy, and store the resulting array
+ /// slice into \p array. It is up to the caller to ensure that objects of
+ /// type T can be safely treated in this manner. Updates the stream's offset
+ /// to point after the newly read object. Whether a copy occurs depends upon
+ /// the implementation of the underlying stream.
+ ///
+ /// \returns a success error code if the data was successfully read, otherwise
+ /// returns an appropriate error code.
+ template <typename T>
+ Error readArray(ArrayRef<T> &Array, uint32_t NumElements) {
+ ArrayRef<uint8_t> Bytes;
+ if (NumElements == 0) {
+ Array = ArrayRef<T>();
+ return Error::success();
+ }
+
+ if (NumElements > UINT32_MAX / sizeof(T))
+ return make_error<BinaryStreamError>(
+ stream_error_code::invalid_array_size);
+
+ if (auto EC = readBytes(Bytes, NumElements * sizeof(T)))
+ return EC;
+
+ assert(alignmentAdjustment(Bytes.data(), alignof(T)) == 0 &&
+ "Reading at invalid alignment!");
+
+ Array = ArrayRef<T>(reinterpret_cast<const T *>(Bytes.data()), NumElements);
+ return Error::success();
+ }
+
+ /// Read a VarStreamArray of size \p Size bytes and store the result into
+ /// \p Array. Updates the stream's offset to point after the newly read
+ /// array. Never causes a copy (although iterating the elements of the
+ /// VarStreamArray may, depending upon the implementation of the underlying
+ /// stream).
+ ///
+ /// \returns a success error code if the data was successfully read, otherwise
+ /// returns an appropriate error code.
+ template <typename T, typename U>
+ Error readArray(VarStreamArray<T, U> &Array, uint32_t Size) {
+ BinaryStreamRef S;
+ if (auto EC = readStreamRef(S, Size))
+ return EC;
+ Array.setUnderlyingStream(S);
+ return Error::success();
+ }
+
+ /// Read a FixedStreamArray of \p NumItems elements and store the result into
+ /// \p Array. Updates the stream's offset to point after the newly read
+ /// array. Never causes a copy (although iterating the elements of the
+ /// FixedStreamArray may, depending upon the implementation of the underlying
+ /// stream).
+ ///
+ /// \returns a success error code if the data was successfully read, otherwise
+ /// returns an appropriate error code.
+ template <typename T>
+ Error readArray(FixedStreamArray<T> &Array, uint32_t NumItems) {
+ if (NumItems == 0) {
+ Array = FixedStreamArray<T>();
+ return Error::success();
+ }
+
+ if (NumItems > UINT32_MAX / sizeof(T))
+ return make_error<BinaryStreamError>(
+ stream_error_code::invalid_array_size);
+
+ BinaryStreamRef View;
+ if (auto EC = readStreamRef(View, NumItems * sizeof(T)))
+ return EC;
+
+ Array = FixedStreamArray<T>(View);
+ return Error::success();
+ }
+
+ bool empty() const { return bytesRemaining() == 0; }
+ void setOffset(uint32_t Off) { Offset = Off; }
+ uint32_t getOffset() const { return Offset; }
+ uint32_t getLength() const { return Stream.getLength(); }
+ uint32_t bytesRemaining() const { return getLength() - getOffset(); }
+
+ /// Advance the stream's offset by \p Amount bytes.
+ ///
+ /// \returns a success error code if at least \p Amount bytes remain in the
+ /// stream, otherwise returns an appropriate error code.
+ Error skip(uint32_t Amount);
+
+ /// Examine the next byte of the underlying stream without advancing the
+ /// stream's offset. If the stream is empty the behavior is undefined.
+ ///
+ /// \returns the next byte in the stream.
+ uint8_t peek() const;
+
+ Error padToAlignment(uint32_t Align);
+
+ std::pair<BinaryStreamReader, BinaryStreamReader>
+ split(uint32_t Offset) const;
+
+private:
+ BinaryStreamRef Stream;
+ uint32_t Offset = 0;
+};
+} // namespace llvm
+
+#endif // LLVM_SUPPORT_BINARYSTREAMREADER_H
diff --git a/contrib/llvm/include/llvm/Support/BinaryStreamRef.h b/contrib/llvm/include/llvm/Support/BinaryStreamRef.h
new file mode 100644
index 0000000..6d5135c
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/BinaryStreamRef.h
@@ -0,0 +1,229 @@
+//===- BinaryStreamRef.h - A copyable reference to a stream -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_BINARYSTREAMREF_H
+#define LLVM_SUPPORT_BINARYSTREAMREF_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/Support/BinaryStream.h"
+#include "llvm/Support/BinaryStreamError.h"
+#include "llvm/Support/Error.h"
+#include <algorithm>
+#include <cstdint>
+#include <memory>
+
+namespace llvm {
+
+/// Common stuff for mutable and immutable StreamRefs.
+template <class RefType, class StreamType> class BinaryStreamRefBase {
+protected:
+ BinaryStreamRefBase() = default;
+ BinaryStreamRefBase(std::shared_ptr<StreamType> SharedImpl, uint32_t Offset,
+ uint32_t Length)
+ : SharedImpl(SharedImpl), BorrowedImpl(SharedImpl.get()),
+ ViewOffset(Offset), Length(Length) {}
+ BinaryStreamRefBase(StreamType &BorrowedImpl, uint32_t Offset,
+ uint32_t Length)
+ : BorrowedImpl(&BorrowedImpl), ViewOffset(Offset), Length(Length) {}
+ BinaryStreamRefBase(const BinaryStreamRefBase &Other) {
+ SharedImpl = Other.SharedImpl;
+ BorrowedImpl = Other.BorrowedImpl;
+ ViewOffset = Other.ViewOffset;
+ Length = Other.Length;
+ }
+
+public:
+ llvm::support::endianness getEndian() const {
+ return BorrowedImpl->getEndian();
+ }
+
+ uint32_t getLength() const { return Length; }
+
+ /// Return a new BinaryStreamRef with the first \p N elements removed.
+ RefType drop_front(uint32_t N) const {
+ if (!BorrowedImpl)
+ return RefType();
+
+ N = std::min(N, Length);
+ RefType Result(static_cast<const RefType &>(*this));
+ Result.ViewOffset += N;
+ Result.Length -= N;
+ return Result;
+ }
+
+ /// Return a new BinaryStreamRef with the first \p N elements removed.
+ RefType drop_back(uint32_t N) const {
+ if (!BorrowedImpl)
+ return RefType();
+
+ N = std::min(N, Length);
+ RefType Result(static_cast<const RefType &>(*this));
+ Result.Length -= N;
+ return Result;
+ }
+
+ /// Return a new BinaryStreamRef with only the first \p N elements remaining.
+ RefType keep_front(uint32_t N) const {
+ assert(N <= getLength());
+ return drop_back(getLength() - N);
+ }
+
+ /// Return a new BinaryStreamRef with only the last \p N elements remaining.
+ RefType keep_back(uint32_t N) const {
+ assert(N <= getLength());
+ return drop_front(getLength() - N);
+ }
+
+ /// Return a new BinaryStreamRef with the first and last \p N elements
+ /// removed.
+ RefType drop_symmetric(uint32_t N) const {
+ return drop_front(N).drop_back(N);
+ }
+
+ /// Return a new BinaryStreamRef with the first \p Offset elements removed,
+ /// and retaining exactly \p Len elements.
+ RefType slice(uint32_t Offset, uint32_t Len) const {
+ return drop_front(Offset).keep_front(Len);
+ }
+
+ bool valid() const { return BorrowedImpl != nullptr; }
+
+ bool operator==(const RefType &Other) const {
+ if (BorrowedImpl != Other.BorrowedImpl)
+ return false;
+ if (ViewOffset != Other.ViewOffset)
+ return false;
+ if (Length != Other.Length)
+ return false;
+ return true;
+ }
+
+protected:
+ Error checkOffset(uint32_t Offset, uint32_t DataSize) const {
+ if (Offset > getLength())
+ return make_error<BinaryStreamError>(stream_error_code::invalid_offset);
+ if (getLength() < DataSize + Offset)
+ return make_error<BinaryStreamError>(stream_error_code::stream_too_short);
+ return Error::success();
+ }
+
+ std::shared_ptr<StreamType> SharedImpl;
+ StreamType *BorrowedImpl = nullptr;
+ uint32_t ViewOffset = 0;
+ uint32_t Length = 0;
+};
+
+/// \brief BinaryStreamRef is to BinaryStream what ArrayRef is to an Array. It
+/// provides copy-semantics and read only access to a "window" of the underlying
+/// BinaryStream. Note that BinaryStreamRef is *not* a BinaryStream. That is to
+/// say, it does not inherit and override the methods of BinaryStream. In
+/// general, you should not pass around pointers or references to BinaryStreams
+/// and use inheritance to achieve polymorphism. Instead, you should pass
+/// around BinaryStreamRefs by value and achieve polymorphism that way.
+class BinaryStreamRef
+ : public BinaryStreamRefBase<BinaryStreamRef, BinaryStream> {
+ friend BinaryStreamRefBase<BinaryStreamRef, BinaryStream>;
+ friend class WritableBinaryStreamRef;
+ BinaryStreamRef(std::shared_ptr<BinaryStream> Impl, uint32_t ViewOffset,
+ uint32_t Length)
+ : BinaryStreamRefBase(Impl, ViewOffset, Length) {}
+
+public:
+ BinaryStreamRef() = default;
+ BinaryStreamRef(BinaryStream &Stream);
+ BinaryStreamRef(BinaryStream &Stream, uint32_t Offset, uint32_t Length);
+ explicit BinaryStreamRef(ArrayRef<uint8_t> Data,
+ llvm::support::endianness Endian);
+ explicit BinaryStreamRef(StringRef Data, llvm::support::endianness Endian);
+
+ BinaryStreamRef(const BinaryStreamRef &Other);
+
+ // Use BinaryStreamRef.slice() instead.
+ BinaryStreamRef(BinaryStreamRef &S, uint32_t Offset,
+ uint32_t Length) = delete;
+
+ /// Given an Offset into this StreamRef and a Size, return a reference to a
+ /// buffer owned by the stream.
+ ///
+ /// \returns a success error code if the entire range of data is within the
+ /// bounds of this BinaryStreamRef's view and the implementation could read
+ /// the data, and an appropriate error code otherwise.
+ Error readBytes(uint32_t Offset, uint32_t Size,
+ ArrayRef<uint8_t> &Buffer) const;
+
+ /// Given an Offset into this BinaryStreamRef, return a reference to the
+ /// largest buffer the stream could support without necessitating a copy.
+ ///
+ /// \returns a success error code if implementation could read the data,
+ /// and an appropriate error code otherwise.
+ Error readLongestContiguousChunk(uint32_t Offset,
+ ArrayRef<uint8_t> &Buffer) const;
+};
+
+struct BinarySubstreamRef {
+ uint32_t Offset; // Offset in the parent stream
+ BinaryStreamRef StreamData; // Stream Data
+
+ BinarySubstreamRef slice(uint32_t Off, uint32_t Size) const {
+ BinaryStreamRef SubSub = StreamData.slice(Off, Size);
+ return {Off + Offset, SubSub};
+ }
+ BinarySubstreamRef drop_front(uint32_t N) const {
+ return slice(N, size() - N);
+ }
+ BinarySubstreamRef keep_front(uint32_t N) const { return slice(0, N); }
+
+ std::pair<BinarySubstreamRef, BinarySubstreamRef>
+ split(uint32_t Offset) const {
+ return std::make_pair(keep_front(Offset), drop_front(Offset));
+ }
+
+ uint32_t size() const { return StreamData.getLength(); }
+ bool empty() const { return size() == 0; }
+};
+
+class WritableBinaryStreamRef
+ : public BinaryStreamRefBase<WritableBinaryStreamRef,
+ WritableBinaryStream> {
+ friend BinaryStreamRefBase<WritableBinaryStreamRef, WritableBinaryStream>;
+ WritableBinaryStreamRef(std::shared_ptr<WritableBinaryStream> Impl,
+ uint32_t ViewOffset, uint32_t Length)
+ : BinaryStreamRefBase(Impl, ViewOffset, Length) {}
+
+public:
+ WritableBinaryStreamRef() = default;
+ WritableBinaryStreamRef(WritableBinaryStream &Stream);
+ WritableBinaryStreamRef(WritableBinaryStream &Stream, uint32_t Offset,
+ uint32_t Length);
+ explicit WritableBinaryStreamRef(MutableArrayRef<uint8_t> Data,
+ llvm::support::endianness Endian);
+ WritableBinaryStreamRef(const WritableBinaryStreamRef &Other);
+
+ // Use WritableBinaryStreamRef.slice() instead.
+ WritableBinaryStreamRef(WritableBinaryStreamRef &S, uint32_t Offset,
+ uint32_t Length) = delete;
+
+ /// Given an Offset into this WritableBinaryStreamRef and some input data,
+ /// writes the data to the underlying stream.
+ ///
+ /// \returns a success error code if the data could fit within the underlying
+ /// stream at the specified location and the implementation could write the
+ /// data, and an appropriate error code otherwise.
+ Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Data) const;
+
+ /// Conver this WritableBinaryStreamRef to a read-only BinaryStreamRef.
+ operator BinaryStreamRef() const;
+
+ /// \brief For buffered streams, commits changes to the backing store.
+ Error commit();
+};
+
+} // end namespace llvm
+
+#endif // LLVM_SUPPORT_BINARYSTREAMREF_H
diff --git a/contrib/llvm/include/llvm/Support/BinaryStreamWriter.h b/contrib/llvm/include/llvm/Support/BinaryStreamWriter.h
new file mode 100644
index 0000000..a4495a1
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/BinaryStreamWriter.h
@@ -0,0 +1,183 @@
+//===- BinaryStreamWriter.h - Writes objects to a BinaryStream ---*- C++-*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_BINARYSTREAMWRITER_H
+#define LLVM_SUPPORT_BINARYSTREAMWRITER_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/BinaryStreamArray.h"
+#include "llvm/Support/BinaryStreamError.h"
+#include "llvm/Support/BinaryStreamRef.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
+#include <cstdint>
+#include <type_traits>
+#include <utility>
+
+namespace llvm {
+
+/// \brief Provides write only access to a subclass of `WritableBinaryStream`.
+/// Provides bounds checking and helpers for writing certain common data types
+/// such as null-terminated strings, integers in various flavors of endianness,
+/// etc. Can be subclassed to provide reading and writing of custom datatypes,
+/// although no methods are overridable.
+class BinaryStreamWriter {
+public:
+ BinaryStreamWriter() = default;
+ explicit BinaryStreamWriter(WritableBinaryStreamRef Ref);
+ explicit BinaryStreamWriter(WritableBinaryStream &Stream);
+ explicit BinaryStreamWriter(MutableArrayRef<uint8_t> Data,
+ llvm::support::endianness Endian);
+
+ BinaryStreamWriter(const BinaryStreamWriter &Other)
+ : Stream(Other.Stream), Offset(Other.Offset) {}
+
+ BinaryStreamWriter &operator=(const BinaryStreamWriter &Other) {
+ Stream = Other.Stream;
+ Offset = Other.Offset;
+ return *this;
+ }
+
+ virtual ~BinaryStreamWriter() {}
+
+ /// Write the bytes specified in \p Buffer to the underlying stream.
+ /// On success, updates the offset so that subsequent writes will occur
+ /// at the next unwritten position.
+ ///
+ /// \returns a success error code if the data was successfully written,
+ /// otherwise returns an appropriate error code.
+ Error writeBytes(ArrayRef<uint8_t> Buffer);
+
+ /// Write the the integer \p Value to the underlying stream in the
+ /// specified endianness. On success, updates the offset so that
+ /// subsequent writes occur at the next unwritten position.
+ ///
+ /// \returns a success error code if the data was successfully written,
+ /// otherwise returns an appropriate error code.
+ template <typename T> Error writeInteger(T Value) {
+ static_assert(std::is_integral<T>::value,
+ "Cannot call writeInteger with non-integral value!");
+ uint8_t Buffer[sizeof(T)];
+ llvm::support::endian::write<T, llvm::support::unaligned>(
+ Buffer, Value, Stream.getEndian());
+ return writeBytes(Buffer);
+ }
+
+ /// Similar to writeInteger
+ template <typename T> Error writeEnum(T Num) {
+ static_assert(std::is_enum<T>::value,
+ "Cannot call writeEnum with non-Enum type");
+
+ using U = typename std::underlying_type<T>::type;
+ return writeInteger<U>(static_cast<U>(Num));
+ }
+
+ /// Write the the string \p Str to the underlying stream followed by a null
+ /// terminator. On success, updates the offset so that subsequent writes
+ /// occur at the next unwritten position. \p Str need not be null terminated
+ /// on input.
+ ///
+ /// \returns a success error code if the data was successfully written,
+ /// otherwise returns an appropriate error code.
+ Error writeCString(StringRef Str);
+
+ /// Write the the string \p Str to the underlying stream without a null
+ /// terminator. On success, updates the offset so that subsequent writes
+ /// occur at the next unwritten position.
+ ///
+ /// \returns a success error code if the data was successfully written,
+ /// otherwise returns an appropriate error code.
+ Error writeFixedString(StringRef Str);
+
+ /// Efficiently reads all data from \p Ref, and writes it to this stream.
+ /// This operation will not invoke any copies of the source data, regardless
+ /// of the source stream's implementation.
+ ///
+ /// \returns a success error code if the data was successfully written,
+ /// otherwise returns an appropriate error code.
+ Error writeStreamRef(BinaryStreamRef Ref);
+
+ /// Efficiently reads \p Size bytes from \p Ref, and writes it to this stream.
+ /// This operation will not invoke any copies of the source data, regardless
+ /// of the source stream's implementation.
+ ///
+ /// \returns a success error code if the data was successfully written,
+ /// otherwise returns an appropriate error code.
+ Error writeStreamRef(BinaryStreamRef Ref, uint32_t Size);
+
+ /// Writes the object \p Obj to the underlying stream, as if by using memcpy.
+ /// It is up to the caller to ensure that type of \p Obj can be safely copied
+ /// in this fashion, as no checks are made to ensure that this is safe.
+ ///
+ /// \returns a success error code if the data was successfully written,
+ /// otherwise returns an appropriate error code.
+ template <typename T> Error writeObject(const T &Obj) {
+ static_assert(!std::is_pointer<T>::value,
+ "writeObject should not be used with pointers, to write "
+ "the pointed-to value dereference the pointer before calling "
+ "writeObject");
+ return writeBytes(
+ ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(&Obj), sizeof(T)));
+ }
+
+ /// Writes an array of objects of type T to the underlying stream, as if by
+ /// using memcpy. It is up to the caller to ensure that type of \p Obj can
+ /// be safely copied in this fashion, as no checks are made to ensure that
+ /// this is safe.
+ ///
+ /// \returns a success error code if the data was successfully written,
+ /// otherwise returns an appropriate error code.
+ template <typename T> Error writeArray(ArrayRef<T> Array) {
+ if (Array.empty())
+ return Error::success();
+ if (Array.size() > UINT32_MAX / sizeof(T))
+ return make_error<BinaryStreamError>(
+ stream_error_code::invalid_array_size);
+
+ return writeBytes(
+ ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(Array.data()),
+ Array.size() * sizeof(T)));
+ }
+
+ /// Writes all data from the array \p Array to the underlying stream.
+ ///
+ /// \returns a success error code if the data was successfully written,
+ /// otherwise returns an appropriate error code.
+ template <typename T, typename U>
+ Error writeArray(VarStreamArray<T, U> Array) {
+ return writeStreamRef(Array.getUnderlyingStream());
+ }
+
+ /// Writes all elements from the array \p Array to the underlying stream.
+ ///
+ /// \returns a success error code if the data was successfully written,
+ /// otherwise returns an appropriate error code.
+ template <typename T> Error writeArray(FixedStreamArray<T> Array) {
+ return writeStreamRef(Array.getUnderlyingStream());
+ }
+
+ /// Splits the Writer into two Writers at a given offset.
+ std::pair<BinaryStreamWriter, BinaryStreamWriter> split(uint32_t Off) const;
+
+ void setOffset(uint32_t Off) { Offset = Off; }
+ uint32_t getOffset() const { return Offset; }
+ uint32_t getLength() const { return Stream.getLength(); }
+ uint32_t bytesRemaining() const { return getLength() - getOffset(); }
+ Error padToAlignment(uint32_t Align);
+
+protected:
+ WritableBinaryStreamRef Stream;
+ uint32_t Offset = 0;
+};
+
+} // end namespace llvm
+
+#endif // LLVM_SUPPORT_BINARYSTREAMWRITER_H
diff --git a/contrib/llvm/include/llvm/Support/BlockFrequency.h b/contrib/llvm/include/llvm/Support/BlockFrequency.h
index 1b45cc5..2e75cbd 100644
--- a/contrib/llvm/include/llvm/Support/BlockFrequency.h
+++ b/contrib/llvm/include/llvm/Support/BlockFrequency.h
@@ -71,6 +71,10 @@ public:
bool operator>=(BlockFrequency RHS) const {
return Frequency >= RHS.Frequency;
}
+
+ bool operator==(BlockFrequency RHS) const {
+ return Frequency == RHS.Frequency;
+ }
};
}
diff --git a/contrib/llvm/include/llvm/Support/BranchProbability.h b/contrib/llvm/include/llvm/Support/BranchProbability.h
index e8eb50d..b403d7f 100644
--- a/contrib/llvm/include/llvm/Support/BranchProbability.h
+++ b/contrib/llvm/include/llvm/Support/BranchProbability.h
@@ -112,6 +112,13 @@ public:
return *this;
}
+ BranchProbability &operator*=(uint32_t RHS) {
+ assert(N != UnknownN &&
+ "Unknown probability cannot participate in arithmetics.");
+ N = (uint64_t(N) * RHS > D) ? D : N * RHS;
+ return *this;
+ }
+
BranchProbability &operator/=(uint32_t RHS) {
assert(N != UnknownN &&
"Unknown probability cannot participate in arithmetics.");
@@ -135,6 +142,11 @@ public:
return Prob *= RHS;
}
+ BranchProbability operator*(uint32_t RHS) const {
+ BranchProbability Prob(*this);
+ return Prob *= RHS;
+ }
+
BranchProbability operator/(uint32_t RHS) const {
BranchProbability Prob(*this);
return Prob /= RHS;
diff --git a/contrib/llvm/include/llvm/Support/CBindingWrapping.h b/contrib/llvm/include/llvm/Support/CBindingWrapping.h
index d4633aa..f60f99d 100644
--- a/contrib/llvm/include/llvm/Support/CBindingWrapping.h
+++ b/contrib/llvm/include/llvm/Support/CBindingWrapping.h
@@ -14,8 +14,8 @@
#ifndef LLVM_SUPPORT_CBINDINGWRAPPING_H
#define LLVM_SUPPORT_CBINDINGWRAPPING_H
-#include "llvm/Support/Casting.h"
#include "llvm-c/Types.h"
+#include "llvm/Support/Casting.h"
#define DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ty, ref) \
inline ty *unwrap(ref P) { \
diff --git a/contrib/llvm/include/llvm/Support/COFF.h b/contrib/llvm/include/llvm/Support/COFF.h
deleted file mode 100644
index 1922330..0000000
--- a/contrib/llvm/include/llvm/Support/COFF.h
+++ /dev/null
@@ -1,680 +0,0 @@
-//===-- llvm/Support/COFF.h -------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file contains an definitions used in Windows COFF Files.
-//
-// Structures and enums defined within this file where created using
-// information from Microsoft's publicly available PE/COFF format document:
-//
-// Microsoft Portable Executable and Common Object File Format Specification
-// Revision 8.1 - February 15, 2008
-//
-// As of 5/2/2010, hosted by Microsoft at:
-// http://www.microsoft.com/whdc/system/platform/firmware/pecoff.mspx
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SUPPORT_COFF_H
-#define LLVM_SUPPORT_COFF_H
-
-#include "llvm/Support/DataTypes.h"
-#include <cassert>
-#include <cstring>
-
-namespace llvm {
-namespace COFF {
-
- // The maximum number of sections that a COFF object can have (inclusive).
- const int32_t MaxNumberOfSections16 = 65279;
-
- // The PE signature bytes that follows the DOS stub header.
- static const char PEMagic[] = { 'P', 'E', '\0', '\0' };
-
- static const char BigObjMagic[] = {
- '\xc7', '\xa1', '\xba', '\xd1', '\xee', '\xba', '\xa9', '\x4b',
- '\xaf', '\x20', '\xfa', '\xf6', '\x6a', '\xa4', '\xdc', '\xb8',
- };
-
- static const char ClGlObjMagic[] = {
- '\x38', '\xfe', '\xb3', '\x0c', '\xa5', '\xd9', '\xab', '\x4d',
- '\xac', '\x9b', '\xd6', '\xb6', '\x22', '\x26', '\x53', '\xc2',
- };
-
- // Sizes in bytes of various things in the COFF format.
- enum {
- Header16Size = 20,
- Header32Size = 56,
- NameSize = 8,
- Symbol16Size = 18,
- Symbol32Size = 20,
- SectionSize = 40,
- RelocationSize = 10
- };
-
- struct header {
- uint16_t Machine;
- int32_t NumberOfSections;
- uint32_t TimeDateStamp;
- uint32_t PointerToSymbolTable;
- uint32_t NumberOfSymbols;
- uint16_t SizeOfOptionalHeader;
- uint16_t Characteristics;
- };
-
- struct BigObjHeader {
- enum : uint16_t { MinBigObjectVersion = 2 };
-
- uint16_t Sig1; ///< Must be IMAGE_FILE_MACHINE_UNKNOWN (0).
- uint16_t Sig2; ///< Must be 0xFFFF.
- uint16_t Version;
- uint16_t Machine;
- uint32_t TimeDateStamp;
- uint8_t UUID[16];
- uint32_t unused1;
- uint32_t unused2;
- uint32_t unused3;
- uint32_t unused4;
- uint32_t NumberOfSections;
- uint32_t PointerToSymbolTable;
- uint32_t NumberOfSymbols;
- };
-
- enum MachineTypes {
- MT_Invalid = 0xffff,
-
- IMAGE_FILE_MACHINE_UNKNOWN = 0x0,
- IMAGE_FILE_MACHINE_AM33 = 0x13,
- IMAGE_FILE_MACHINE_AMD64 = 0x8664,
- IMAGE_FILE_MACHINE_ARM = 0x1C0,
- IMAGE_FILE_MACHINE_ARMNT = 0x1C4,
- IMAGE_FILE_MACHINE_ARM64 = 0xAA64,
- IMAGE_FILE_MACHINE_EBC = 0xEBC,
- IMAGE_FILE_MACHINE_I386 = 0x14C,
- IMAGE_FILE_MACHINE_IA64 = 0x200,
- IMAGE_FILE_MACHINE_M32R = 0x9041,
- IMAGE_FILE_MACHINE_MIPS16 = 0x266,
- IMAGE_FILE_MACHINE_MIPSFPU = 0x366,
- IMAGE_FILE_MACHINE_MIPSFPU16 = 0x466,
- IMAGE_FILE_MACHINE_POWERPC = 0x1F0,
- IMAGE_FILE_MACHINE_POWERPCFP = 0x1F1,
- IMAGE_FILE_MACHINE_R4000 = 0x166,
- IMAGE_FILE_MACHINE_SH3 = 0x1A2,
- IMAGE_FILE_MACHINE_SH3DSP = 0x1A3,
- IMAGE_FILE_MACHINE_SH4 = 0x1A6,
- IMAGE_FILE_MACHINE_SH5 = 0x1A8,
- IMAGE_FILE_MACHINE_THUMB = 0x1C2,
- IMAGE_FILE_MACHINE_WCEMIPSV2 = 0x169
- };
-
- enum Characteristics {
- C_Invalid = 0,
-
- /// The file does not contain base relocations and must be loaded at its
- /// preferred base. If this cannot be done, the loader will error.
- IMAGE_FILE_RELOCS_STRIPPED = 0x0001,
- /// The file is valid and can be run.
- IMAGE_FILE_EXECUTABLE_IMAGE = 0x0002,
- /// COFF line numbers have been stripped. This is deprecated and should be
- /// 0.
- IMAGE_FILE_LINE_NUMS_STRIPPED = 0x0004,
- /// COFF symbol table entries for local symbols have been removed. This is
- /// deprecated and should be 0.
- IMAGE_FILE_LOCAL_SYMS_STRIPPED = 0x0008,
- /// Aggressively trim working set. This is deprecated and must be 0.
- IMAGE_FILE_AGGRESSIVE_WS_TRIM = 0x0010,
- /// Image can handle > 2GiB addresses.
- IMAGE_FILE_LARGE_ADDRESS_AWARE = 0x0020,
- /// Little endian: the LSB precedes the MSB in memory. This is deprecated
- /// and should be 0.
- IMAGE_FILE_BYTES_REVERSED_LO = 0x0080,
- /// Machine is based on a 32bit word architecture.
- IMAGE_FILE_32BIT_MACHINE = 0x0100,
- /// Debugging info has been removed.
- IMAGE_FILE_DEBUG_STRIPPED = 0x0200,
- /// If the image is on removable media, fully load it and copy it to swap.
- IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP = 0x0400,
- /// If the image is on network media, fully load it and copy it to swap.
- IMAGE_FILE_NET_RUN_FROM_SWAP = 0x0800,
- /// The image file is a system file, not a user program.
- IMAGE_FILE_SYSTEM = 0x1000,
- /// The image file is a DLL.
- IMAGE_FILE_DLL = 0x2000,
- /// This file should only be run on a uniprocessor machine.
- IMAGE_FILE_UP_SYSTEM_ONLY = 0x4000,
- /// Big endian: the MSB precedes the LSB in memory. This is deprecated
- /// and should be 0.
- IMAGE_FILE_BYTES_REVERSED_HI = 0x8000
- };
-
- struct symbol {
- char Name[NameSize];
- uint32_t Value;
- int32_t SectionNumber;
- uint16_t Type;
- uint8_t StorageClass;
- uint8_t NumberOfAuxSymbols;
- };
-
- enum SymbolSectionNumber : int32_t {
- IMAGE_SYM_DEBUG = -2,
- IMAGE_SYM_ABSOLUTE = -1,
- IMAGE_SYM_UNDEFINED = 0
- };
-
- /// Storage class tells where and what the symbol represents
- enum SymbolStorageClass {
- SSC_Invalid = 0xff,
-
- IMAGE_SYM_CLASS_END_OF_FUNCTION = -1, ///< Physical end of function
- IMAGE_SYM_CLASS_NULL = 0, ///< No symbol
- IMAGE_SYM_CLASS_AUTOMATIC = 1, ///< Stack variable
- IMAGE_SYM_CLASS_EXTERNAL = 2, ///< External symbol
- IMAGE_SYM_CLASS_STATIC = 3, ///< Static
- IMAGE_SYM_CLASS_REGISTER = 4, ///< Register variable
- IMAGE_SYM_CLASS_EXTERNAL_DEF = 5, ///< External definition
- IMAGE_SYM_CLASS_LABEL = 6, ///< Label
- IMAGE_SYM_CLASS_UNDEFINED_LABEL = 7, ///< Undefined label
- IMAGE_SYM_CLASS_MEMBER_OF_STRUCT = 8, ///< Member of structure
- IMAGE_SYM_CLASS_ARGUMENT = 9, ///< Function argument
- IMAGE_SYM_CLASS_STRUCT_TAG = 10, ///< Structure tag
- IMAGE_SYM_CLASS_MEMBER_OF_UNION = 11, ///< Member of union
- IMAGE_SYM_CLASS_UNION_TAG = 12, ///< Union tag
- IMAGE_SYM_CLASS_TYPE_DEFINITION = 13, ///< Type definition
- IMAGE_SYM_CLASS_UNDEFINED_STATIC = 14, ///< Undefined static
- IMAGE_SYM_CLASS_ENUM_TAG = 15, ///< Enumeration tag
- IMAGE_SYM_CLASS_MEMBER_OF_ENUM = 16, ///< Member of enumeration
- IMAGE_SYM_CLASS_REGISTER_PARAM = 17, ///< Register parameter
- IMAGE_SYM_CLASS_BIT_FIELD = 18, ///< Bit field
- /// ".bb" or ".eb" - beginning or end of block
- IMAGE_SYM_CLASS_BLOCK = 100,
- /// ".bf" or ".ef" - beginning or end of function
- IMAGE_SYM_CLASS_FUNCTION = 101,
- IMAGE_SYM_CLASS_END_OF_STRUCT = 102, ///< End of structure
- IMAGE_SYM_CLASS_FILE = 103, ///< File name
- /// Line number, reformatted as symbol
- IMAGE_SYM_CLASS_SECTION = 104,
- IMAGE_SYM_CLASS_WEAK_EXTERNAL = 105, ///< Duplicate tag
- /// External symbol in dmert public lib
- IMAGE_SYM_CLASS_CLR_TOKEN = 107
- };
-
- enum SymbolBaseType {
- IMAGE_SYM_TYPE_NULL = 0, ///< No type information or unknown base type.
- IMAGE_SYM_TYPE_VOID = 1, ///< Used with void pointers and functions.
- IMAGE_SYM_TYPE_CHAR = 2, ///< A character (signed byte).
- IMAGE_SYM_TYPE_SHORT = 3, ///< A 2-byte signed integer.
- IMAGE_SYM_TYPE_INT = 4, ///< A natural integer type on the target.
- IMAGE_SYM_TYPE_LONG = 5, ///< A 4-byte signed integer.
- IMAGE_SYM_TYPE_FLOAT = 6, ///< A 4-byte floating-point number.
- IMAGE_SYM_TYPE_DOUBLE = 7, ///< An 8-byte floating-point number.
- IMAGE_SYM_TYPE_STRUCT = 8, ///< A structure.
- IMAGE_SYM_TYPE_UNION = 9, ///< An union.
- IMAGE_SYM_TYPE_ENUM = 10, ///< An enumerated type.
- IMAGE_SYM_TYPE_MOE = 11, ///< A member of enumeration (a specific value).
- IMAGE_SYM_TYPE_BYTE = 12, ///< A byte; unsigned 1-byte integer.
- IMAGE_SYM_TYPE_WORD = 13, ///< A word; unsigned 2-byte integer.
- IMAGE_SYM_TYPE_UINT = 14, ///< An unsigned integer of natural size.
- IMAGE_SYM_TYPE_DWORD = 15 ///< An unsigned 4-byte integer.
- };
-
- enum SymbolComplexType {
- IMAGE_SYM_DTYPE_NULL = 0, ///< No complex type; simple scalar variable.
- IMAGE_SYM_DTYPE_POINTER = 1, ///< A pointer to base type.
- IMAGE_SYM_DTYPE_FUNCTION = 2, ///< A function that returns a base type.
- IMAGE_SYM_DTYPE_ARRAY = 3, ///< An array of base type.
-
- /// Type is formed as (base + (derived << SCT_COMPLEX_TYPE_SHIFT))
- SCT_COMPLEX_TYPE_SHIFT = 4
- };
-
- enum AuxSymbolType {
- IMAGE_AUX_SYMBOL_TYPE_TOKEN_DEF = 1
- };
-
- struct section {
- char Name[NameSize];
- uint32_t VirtualSize;
- uint32_t VirtualAddress;
- uint32_t SizeOfRawData;
- uint32_t PointerToRawData;
- uint32_t PointerToRelocations;
- uint32_t PointerToLineNumbers;
- uint16_t NumberOfRelocations;
- uint16_t NumberOfLineNumbers;
- uint32_t Characteristics;
- };
-
- enum SectionCharacteristics : uint32_t {
- SC_Invalid = 0xffffffff,
-
- IMAGE_SCN_TYPE_NOLOAD = 0x00000002,
- IMAGE_SCN_TYPE_NO_PAD = 0x00000008,
- IMAGE_SCN_CNT_CODE = 0x00000020,
- IMAGE_SCN_CNT_INITIALIZED_DATA = 0x00000040,
- IMAGE_SCN_CNT_UNINITIALIZED_DATA = 0x00000080,
- IMAGE_SCN_LNK_OTHER = 0x00000100,
- IMAGE_SCN_LNK_INFO = 0x00000200,
- IMAGE_SCN_LNK_REMOVE = 0x00000800,
- IMAGE_SCN_LNK_COMDAT = 0x00001000,
- IMAGE_SCN_GPREL = 0x00008000,
- IMAGE_SCN_MEM_PURGEABLE = 0x00020000,
- IMAGE_SCN_MEM_16BIT = 0x00020000,
- IMAGE_SCN_MEM_LOCKED = 0x00040000,
- IMAGE_SCN_MEM_PRELOAD = 0x00080000,
- IMAGE_SCN_ALIGN_1BYTES = 0x00100000,
- IMAGE_SCN_ALIGN_2BYTES = 0x00200000,
- IMAGE_SCN_ALIGN_4BYTES = 0x00300000,
- IMAGE_SCN_ALIGN_8BYTES = 0x00400000,
- IMAGE_SCN_ALIGN_16BYTES = 0x00500000,
- IMAGE_SCN_ALIGN_32BYTES = 0x00600000,
- IMAGE_SCN_ALIGN_64BYTES = 0x00700000,
- IMAGE_SCN_ALIGN_128BYTES = 0x00800000,
- IMAGE_SCN_ALIGN_256BYTES = 0x00900000,
- IMAGE_SCN_ALIGN_512BYTES = 0x00A00000,
- IMAGE_SCN_ALIGN_1024BYTES = 0x00B00000,
- IMAGE_SCN_ALIGN_2048BYTES = 0x00C00000,
- IMAGE_SCN_ALIGN_4096BYTES = 0x00D00000,
- IMAGE_SCN_ALIGN_8192BYTES = 0x00E00000,
- IMAGE_SCN_LNK_NRELOC_OVFL = 0x01000000,
- IMAGE_SCN_MEM_DISCARDABLE = 0x02000000,
- IMAGE_SCN_MEM_NOT_CACHED = 0x04000000,
- IMAGE_SCN_MEM_NOT_PAGED = 0x08000000,
- IMAGE_SCN_MEM_SHARED = 0x10000000,
- IMAGE_SCN_MEM_EXECUTE = 0x20000000,
- IMAGE_SCN_MEM_READ = 0x40000000,
- IMAGE_SCN_MEM_WRITE = 0x80000000
- };
-
- struct relocation {
- uint32_t VirtualAddress;
- uint32_t SymbolTableIndex;
- uint16_t Type;
- };
-
- enum RelocationTypeI386 {
- IMAGE_REL_I386_ABSOLUTE = 0x0000,
- IMAGE_REL_I386_DIR16 = 0x0001,
- IMAGE_REL_I386_REL16 = 0x0002,
- IMAGE_REL_I386_DIR32 = 0x0006,
- IMAGE_REL_I386_DIR32NB = 0x0007,
- IMAGE_REL_I386_SEG12 = 0x0009,
- IMAGE_REL_I386_SECTION = 0x000A,
- IMAGE_REL_I386_SECREL = 0x000B,
- IMAGE_REL_I386_TOKEN = 0x000C,
- IMAGE_REL_I386_SECREL7 = 0x000D,
- IMAGE_REL_I386_REL32 = 0x0014
- };
-
- enum RelocationTypeAMD64 {
- IMAGE_REL_AMD64_ABSOLUTE = 0x0000,
- IMAGE_REL_AMD64_ADDR64 = 0x0001,
- IMAGE_REL_AMD64_ADDR32 = 0x0002,
- IMAGE_REL_AMD64_ADDR32NB = 0x0003,
- IMAGE_REL_AMD64_REL32 = 0x0004,
- IMAGE_REL_AMD64_REL32_1 = 0x0005,
- IMAGE_REL_AMD64_REL32_2 = 0x0006,
- IMAGE_REL_AMD64_REL32_3 = 0x0007,
- IMAGE_REL_AMD64_REL32_4 = 0x0008,
- IMAGE_REL_AMD64_REL32_5 = 0x0009,
- IMAGE_REL_AMD64_SECTION = 0x000A,
- IMAGE_REL_AMD64_SECREL = 0x000B,
- IMAGE_REL_AMD64_SECREL7 = 0x000C,
- IMAGE_REL_AMD64_TOKEN = 0x000D,
- IMAGE_REL_AMD64_SREL32 = 0x000E,
- IMAGE_REL_AMD64_PAIR = 0x000F,
- IMAGE_REL_AMD64_SSPAN32 = 0x0010
- };
-
- enum RelocationTypesARM {
- IMAGE_REL_ARM_ABSOLUTE = 0x0000,
- IMAGE_REL_ARM_ADDR32 = 0x0001,
- IMAGE_REL_ARM_ADDR32NB = 0x0002,
- IMAGE_REL_ARM_BRANCH24 = 0x0003,
- IMAGE_REL_ARM_BRANCH11 = 0x0004,
- IMAGE_REL_ARM_TOKEN = 0x0005,
- IMAGE_REL_ARM_BLX24 = 0x0008,
- IMAGE_REL_ARM_BLX11 = 0x0009,
- IMAGE_REL_ARM_SECTION = 0x000E,
- IMAGE_REL_ARM_SECREL = 0x000F,
- IMAGE_REL_ARM_MOV32A = 0x0010,
- IMAGE_REL_ARM_MOV32T = 0x0011,
- IMAGE_REL_ARM_BRANCH20T = 0x0012,
- IMAGE_REL_ARM_BRANCH24T = 0x0014,
- IMAGE_REL_ARM_BLX23T = 0x0015
- };
-
- enum COMDATType {
- IMAGE_COMDAT_SELECT_NODUPLICATES = 1,
- IMAGE_COMDAT_SELECT_ANY,
- IMAGE_COMDAT_SELECT_SAME_SIZE,
- IMAGE_COMDAT_SELECT_EXACT_MATCH,
- IMAGE_COMDAT_SELECT_ASSOCIATIVE,
- IMAGE_COMDAT_SELECT_LARGEST,
- IMAGE_COMDAT_SELECT_NEWEST
- };
-
- // Auxiliary Symbol Formats
- struct AuxiliaryFunctionDefinition {
- uint32_t TagIndex;
- uint32_t TotalSize;
- uint32_t PointerToLinenumber;
- uint32_t PointerToNextFunction;
- char unused[2];
- };
-
- struct AuxiliarybfAndefSymbol {
- uint8_t unused1[4];
- uint16_t Linenumber;
- uint8_t unused2[6];
- uint32_t PointerToNextFunction;
- uint8_t unused3[2];
- };
-
- struct AuxiliaryWeakExternal {
- uint32_t TagIndex;
- uint32_t Characteristics;
- uint8_t unused[10];
- };
-
- enum WeakExternalCharacteristics {
- IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY = 1,
- IMAGE_WEAK_EXTERN_SEARCH_LIBRARY = 2,
- IMAGE_WEAK_EXTERN_SEARCH_ALIAS = 3
- };
-
- struct AuxiliarySectionDefinition {
- uint32_t Length;
- uint16_t NumberOfRelocations;
- uint16_t NumberOfLinenumbers;
- uint32_t CheckSum;
- uint32_t Number;
- uint8_t Selection;
- char unused;
- };
-
- struct AuxiliaryCLRToken {
- uint8_t AuxType;
- uint8_t unused1;
- uint32_t SymbolTableIndex;
- char unused2[12];
- };
-
- union Auxiliary {
- AuxiliaryFunctionDefinition FunctionDefinition;
- AuxiliarybfAndefSymbol bfAndefSymbol;
- AuxiliaryWeakExternal WeakExternal;
- AuxiliarySectionDefinition SectionDefinition;
- };
-
- /// @brief The Import Directory Table.
- ///
- /// There is a single array of these and one entry per imported DLL.
- struct ImportDirectoryTableEntry {
- uint32_t ImportLookupTableRVA;
- uint32_t TimeDateStamp;
- uint32_t ForwarderChain;
- uint32_t NameRVA;
- uint32_t ImportAddressTableRVA;
- };
-
- /// @brief The PE32 Import Lookup Table.
- ///
- /// There is an array of these for each imported DLL. It represents either
- /// the ordinal to import from the target DLL, or a name to lookup and import
- /// from the target DLL.
- ///
- /// This also happens to be the same format used by the Import Address Table
- /// when it is initially written out to the image.
- struct ImportLookupTableEntry32 {
- uint32_t data;
-
- /// @brief Is this entry specified by ordinal, or name?
- bool isOrdinal() const { return data & 0x80000000; }
-
- /// @brief Get the ordinal value of this entry. isOrdinal must be true.
- uint16_t getOrdinal() const {
- assert(isOrdinal() && "ILT entry is not an ordinal!");
- return data & 0xFFFF;
- }
-
- /// @brief Set the ordinal value and set isOrdinal to true.
- void setOrdinal(uint16_t o) {
- data = o;
- data |= 0x80000000;
- }
-
- /// @brief Get the Hint/Name entry RVA. isOrdinal must be false.
- uint32_t getHintNameRVA() const {
- assert(!isOrdinal() && "ILT entry is not a Hint/Name RVA!");
- return data;
- }
-
- /// @brief Set the Hint/Name entry RVA and set isOrdinal to false.
- void setHintNameRVA(uint32_t rva) { data = rva; }
- };
-
- /// @brief The DOS compatible header at the front of all PEs.
- struct DOSHeader {
- uint16_t Magic;
- uint16_t UsedBytesInTheLastPage;
- uint16_t FileSizeInPages;
- uint16_t NumberOfRelocationItems;
- uint16_t HeaderSizeInParagraphs;
- uint16_t MinimumExtraParagraphs;
- uint16_t MaximumExtraParagraphs;
- uint16_t InitialRelativeSS;
- uint16_t InitialSP;
- uint16_t Checksum;
- uint16_t InitialIP;
- uint16_t InitialRelativeCS;
- uint16_t AddressOfRelocationTable;
- uint16_t OverlayNumber;
- uint16_t Reserved[4];
- uint16_t OEMid;
- uint16_t OEMinfo;
- uint16_t Reserved2[10];
- uint32_t AddressOfNewExeHeader;
- };
-
- struct PE32Header {
- enum {
- PE32 = 0x10b,
- PE32_PLUS = 0x20b
- };
-
- uint16_t Magic;
- uint8_t MajorLinkerVersion;
- uint8_t MinorLinkerVersion;
- uint32_t SizeOfCode;
- uint32_t SizeOfInitializedData;
- uint32_t SizeOfUninitializedData;
- uint32_t AddressOfEntryPoint; // RVA
- uint32_t BaseOfCode; // RVA
- uint32_t BaseOfData; // RVA
- uint32_t ImageBase;
- uint32_t SectionAlignment;
- uint32_t FileAlignment;
- uint16_t MajorOperatingSystemVersion;
- uint16_t MinorOperatingSystemVersion;
- uint16_t MajorImageVersion;
- uint16_t MinorImageVersion;
- uint16_t MajorSubsystemVersion;
- uint16_t MinorSubsystemVersion;
- uint32_t Win32VersionValue;
- uint32_t SizeOfImage;
- uint32_t SizeOfHeaders;
- uint32_t CheckSum;
- uint16_t Subsystem;
- // FIXME: This should be DllCharacteristics to match the COFF spec.
- uint16_t DLLCharacteristics;
- uint32_t SizeOfStackReserve;
- uint32_t SizeOfStackCommit;
- uint32_t SizeOfHeapReserve;
- uint32_t SizeOfHeapCommit;
- uint32_t LoaderFlags;
- // FIXME: This should be NumberOfRvaAndSizes to match the COFF spec.
- uint32_t NumberOfRvaAndSize;
- };
-
- struct DataDirectory {
- uint32_t RelativeVirtualAddress;
- uint32_t Size;
- };
-
- enum DataDirectoryIndex {
- EXPORT_TABLE = 0,
- IMPORT_TABLE,
- RESOURCE_TABLE,
- EXCEPTION_TABLE,
- CERTIFICATE_TABLE,
- BASE_RELOCATION_TABLE,
- DEBUG_DIRECTORY,
- ARCHITECTURE,
- GLOBAL_PTR,
- TLS_TABLE,
- LOAD_CONFIG_TABLE,
- BOUND_IMPORT,
- IAT,
- DELAY_IMPORT_DESCRIPTOR,
- CLR_RUNTIME_HEADER,
-
- NUM_DATA_DIRECTORIES
- };
-
- enum WindowsSubsystem {
- IMAGE_SUBSYSTEM_UNKNOWN = 0, ///< An unknown subsystem.
- IMAGE_SUBSYSTEM_NATIVE = 1, ///< Device drivers and native Windows processes
- IMAGE_SUBSYSTEM_WINDOWS_GUI = 2, ///< The Windows GUI subsystem.
- IMAGE_SUBSYSTEM_WINDOWS_CUI = 3, ///< The Windows character subsystem.
- IMAGE_SUBSYSTEM_OS2_CUI = 5, ///< The OS/2 character subsytem.
- IMAGE_SUBSYSTEM_POSIX_CUI = 7, ///< The POSIX character subsystem.
- IMAGE_SUBSYSTEM_NATIVE_WINDOWS = 8, ///< Native Windows 9x driver.
- IMAGE_SUBSYSTEM_WINDOWS_CE_GUI = 9, ///< Windows CE.
- IMAGE_SUBSYSTEM_EFI_APPLICATION = 10, ///< An EFI application.
- IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER = 11, ///< An EFI driver with boot
- /// services.
- IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER = 12, ///< An EFI driver with run-time
- /// services.
- IMAGE_SUBSYSTEM_EFI_ROM = 13, ///< An EFI ROM image.
- IMAGE_SUBSYSTEM_XBOX = 14, ///< XBOX.
- IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION = 16 ///< A BCD application.
- };
-
- enum DLLCharacteristics {
- /// ASLR with 64 bit address space.
- IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA = 0x0020,
- /// DLL can be relocated at load time.
- IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE = 0x0040,
- /// Code integrity checks are enforced.
- IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY = 0x0080,
- ///< Image is NX compatible.
- IMAGE_DLL_CHARACTERISTICS_NX_COMPAT = 0x0100,
- /// Isolation aware, but do not isolate the image.
- IMAGE_DLL_CHARACTERISTICS_NO_ISOLATION = 0x0200,
- /// Does not use structured exception handling (SEH). No SEH handler may be
- /// called in this image.
- IMAGE_DLL_CHARACTERISTICS_NO_SEH = 0x0400,
- /// Do not bind the image.
- IMAGE_DLL_CHARACTERISTICS_NO_BIND = 0x0800,
- ///< Image should execute in an AppContainer.
- IMAGE_DLL_CHARACTERISTICS_APPCONTAINER = 0x1000,
- ///< A WDM driver.
- IMAGE_DLL_CHARACTERISTICS_WDM_DRIVER = 0x2000,
- ///< Image supports Control Flow Guard.
- IMAGE_DLL_CHARACTERISTICS_GUARD_CF = 0x4000,
- /// Terminal Server aware.
- IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE = 0x8000
- };
-
- enum DebugType {
- IMAGE_DEBUG_TYPE_UNKNOWN = 0,
- IMAGE_DEBUG_TYPE_COFF = 1,
- IMAGE_DEBUG_TYPE_CODEVIEW = 2,
- IMAGE_DEBUG_TYPE_FPO = 3,
- IMAGE_DEBUG_TYPE_MISC = 4,
- IMAGE_DEBUG_TYPE_EXCEPTION = 5,
- IMAGE_DEBUG_TYPE_FIXUP = 6,
- IMAGE_DEBUG_TYPE_OMAP_TO_SRC = 7,
- IMAGE_DEBUG_TYPE_OMAP_FROM_SRC = 8,
- IMAGE_DEBUG_TYPE_BORLAND = 9,
- IMAGE_DEBUG_TYPE_RESERVED10 = 10,
- IMAGE_DEBUG_TYPE_CLSID = 11,
- IMAGE_DEBUG_TYPE_VC_FEATURE = 12,
- IMAGE_DEBUG_TYPE_POGO = 13,
- IMAGE_DEBUG_TYPE_ILTCG = 14,
- IMAGE_DEBUG_TYPE_MPX = 15,
- IMAGE_DEBUG_TYPE_REPRO = 16,
- };
-
- enum BaseRelocationType {
- IMAGE_REL_BASED_ABSOLUTE = 0,
- IMAGE_REL_BASED_HIGH = 1,
- IMAGE_REL_BASED_LOW = 2,
- IMAGE_REL_BASED_HIGHLOW = 3,
- IMAGE_REL_BASED_HIGHADJ = 4,
- IMAGE_REL_BASED_MIPS_JMPADDR = 5,
- IMAGE_REL_BASED_ARM_MOV32A = 5,
- IMAGE_REL_BASED_ARM_MOV32T = 7,
- IMAGE_REL_BASED_MIPS_JMPADDR16 = 9,
- IMAGE_REL_BASED_DIR64 = 10
- };
-
- enum ImportType {
- IMPORT_CODE = 0,
- IMPORT_DATA = 1,
- IMPORT_CONST = 2
- };
-
- enum ImportNameType {
- /// Import is by ordinal. This indicates that the value in the Ordinal/Hint
- /// field of the import header is the import's ordinal. If this constant is
- /// not specified, then the Ordinal/Hint field should always be interpreted
- /// as the import's hint.
- IMPORT_ORDINAL = 0,
- /// The import name is identical to the public symbol name
- IMPORT_NAME = 1,
- /// The import name is the public symbol name, but skipping the leading ?,
- /// @, or optionally _.
- IMPORT_NAME_NOPREFIX = 2,
- /// The import name is the public symbol name, but skipping the leading ?,
- /// @, or optionally _, and truncating at the first @.
- IMPORT_NAME_UNDECORATE = 3
- };
-
- struct ImportHeader {
- uint16_t Sig1; ///< Must be IMAGE_FILE_MACHINE_UNKNOWN (0).
- uint16_t Sig2; ///< Must be 0xFFFF.
- uint16_t Version;
- uint16_t Machine;
- uint32_t TimeDateStamp;
- uint32_t SizeOfData;
- uint16_t OrdinalHint;
- uint16_t TypeInfo;
-
- ImportType getType() const {
- return static_cast<ImportType>(TypeInfo & 0x3);
- }
-
- ImportNameType getNameType() const {
- return static_cast<ImportNameType>((TypeInfo & 0x1C) >> 2);
- }
- };
-
- enum CodeViewIdentifiers {
- DEBUG_SECTION_MAGIC = 0x4,
- };
-
- inline bool isReservedSectionNumber(int32_t SectionNumber) {
- return SectionNumber <= 0;
- }
-
-} // End namespace COFF.
-} // End namespace llvm.
-
-#endif
diff --git a/contrib/llvm/include/llvm/Support/CachePruning.h b/contrib/llvm/include/llvm/Support/CachePruning.h
index 954fd8a..46e3435 100644
--- a/contrib/llvm/include/llvm/Support/CachePruning.h
+++ b/contrib/llvm/include/llvm/Support/CachePruning.h
@@ -20,51 +20,49 @@
namespace llvm {
-/// Handle pruning a directory provided a path and some options to control what
-/// to prune.
-class CachePruning {
-public:
- /// Prepare to prune \p Path.
- CachePruning(StringRef Path) : Path(Path) {}
+template <typename T> class Expected;
- /// Define the pruning interval. This is intended to be used to avoid scanning
- /// the directory too often. It does not impact the decision of which file to
- /// prune. A value of 0 forces the scan to occurs.
- CachePruning &setPruningInterval(std::chrono::seconds PruningInterval) {
- Interval = PruningInterval;
- return *this;
- }
+/// Policy for the pruneCache() function. A default constructed
+/// CachePruningPolicy provides a reasonable default policy.
+struct CachePruningPolicy {
+ /// The pruning interval. This is intended to be used to avoid scanning the
+ /// directory too often. It does not impact the decision of which file to
+ /// prune. A value of 0 forces the scan to occur.
+ std::chrono::seconds Interval = std::chrono::seconds(1200);
- /// Define the expiration for a file. When a file hasn't been accessed for
- /// \p ExpireAfter seconds, it is removed from the cache. A value of 0 disable
- /// the expiration-based pruning.
- CachePruning &setEntryExpiration(std::chrono::seconds ExpireAfter) {
- Expiration = ExpireAfter;
- return *this;
- }
+ /// The expiration for a file. When a file hasn't been accessed for Expiration
+ /// seconds, it is removed from the cache. A value of 0 disables the
+ /// expiration-based pruning.
+ std::chrono::seconds Expiration = std::chrono::hours(7 * 24); // 1w
- /// Define the maximum size for the cache directory, in terms of percentage of
- /// the available space on the the disk. Set to 100 to indicate no limit, 50
- /// to indicate that the cache size will not be left over half the
- /// available disk space. A value over 100 will be reduced to 100. A value of
- /// 0 disable the size-based pruning.
- CachePruning &setMaxSize(unsigned Percentage) {
- PercentageOfAvailableSpace = std::min(100u, Percentage);
- return *this;
- }
+ /// The maximum size for the cache directory, in terms of percentage of the
+ /// available space on the the disk. Set to 100 to indicate no limit, 50 to
+ /// indicate that the cache size will not be left over half the available disk
+ /// space. A value over 100 will be reduced to 100. A value of 0 disables the
+ /// percentage size-based pruning.
+ unsigned MaxSizePercentageOfAvailableSpace = 75;
- /// Peform pruning using the supplied options, returns true if pruning
- /// occured, i.e. if PruningInterval was expired.
- bool prune();
-
-private:
- // Options that matches the setters above.
- std::string Path;
- std::chrono::seconds Expiration = std::chrono::seconds::zero();
- std::chrono::seconds Interval = std::chrono::seconds::zero();
- unsigned PercentageOfAvailableSpace = 0;
+ /// The maximum size for the cache directory in bytes. A value over the amount
+ /// of available space on the disk will be reduced to the amount of available
+ /// space. A value of 0 disables the absolute size-based pruning.
+ uint64_t MaxSizeBytes = 0;
};
+/// Parse the given string as a cache pruning policy. Defaults are taken from a
+/// default constructed CachePruningPolicy object.
+/// For example: "prune_interval=30s:prune_after=24h:cache_size=50%"
+/// which means a pruning interval of 30 seconds, expiration time of 24 hours
+/// and maximum cache size of 50% of available disk space.
+Expected<CachePruningPolicy> parseCachePruningPolicy(StringRef PolicyStr);
+
+/// Peform pruning using the supplied policy, returns true if pruning
+/// occured, i.e. if Policy.Interval was expired.
+///
+/// As a safeguard against data loss if the user specifies the wrong directory
+/// as their cache directory, this function will ignore files not matching the
+/// pattern "llvmcache-*".
+bool pruneCache(StringRef Path, CachePruningPolicy Policy);
+
} // namespace llvm
#endif
diff --git a/contrib/llvm/include/llvm/Support/Casting.h b/contrib/llvm/include/llvm/Support/Casting.h
index a73047b..baa2a81 100644
--- a/contrib/llvm/include/llvm/Support/Casting.h
+++ b/contrib/llvm/include/llvm/Support/Casting.h
@@ -1,4 +1,4 @@
-//===-- llvm/Support/Casting.h - Allow flexible, checked, casts -*- C++ -*-===//
+//===- llvm/Support/Casting.h - Allow flexible, checked, casts --*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -18,6 +18,8 @@
#include "llvm/Support/Compiler.h"
#include "llvm/Support/type_traits.h"
#include <cassert>
+#include <memory>
+#include <type_traits>
namespace llvm {
@@ -30,18 +32,19 @@ namespace llvm {
// template selection process... the default implementation is a noop.
//
template<typename From> struct simplify_type {
- typedef From SimpleType; // The real type this represents...
+ using SimpleType = From; // The real type this represents...
// An accessor to get the real value...
static SimpleType &getSimplifiedValue(From &Val) { return Val; }
};
template<typename From> struct simplify_type<const From> {
- typedef typename simplify_type<From>::SimpleType NonConstSimpleType;
- typedef typename add_const_past_pointer<NonConstSimpleType>::type
- SimpleType;
- typedef typename add_lvalue_reference_if_not_pointer<SimpleType>::type
- RetType;
+ using NonConstSimpleType = typename simplify_type<From>::SimpleType;
+ using SimpleType =
+ typename add_const_past_pointer<NonConstSimpleType>::type;
+ using RetType =
+ typename add_lvalue_reference_if_not_pointer<SimpleType>::type;
+
static RetType getSimplifiedValue(const From& Val) {
return simplify_type<From>::getSimplifiedValue(const_cast<From&>(Val));
}
@@ -76,6 +79,14 @@ template <typename To, typename From> struct isa_impl_cl<To, const From> {
}
};
+template <typename To, typename From>
+struct isa_impl_cl<To, const std::unique_ptr<From>> {
+ static inline bool doit(const std::unique_ptr<From> &Val) {
+ assert(Val && "isa<> used on a null pointer");
+ return isa_impl_cl<To, From>::doit(*Val);
+ }
+};
+
template <typename To, typename From> struct isa_impl_cl<To, From*> {
static inline bool doit(const From *Val) {
assert(Val && "isa<> used on a null pointer");
@@ -139,47 +150,55 @@ template <class X, class Y> LLVM_NODISCARD inline bool isa(const Y &Val) {
template<class To, class From> struct cast_retty;
-
// Calculate what type the 'cast' function should return, based on a requested
// type of To and a source type of From.
template<class To, class From> struct cast_retty_impl {
- typedef To& ret_type; // Normal case, return Ty&
+ using ret_type = To &; // Normal case, return Ty&
};
template<class To, class From> struct cast_retty_impl<To, const From> {
- typedef const To &ret_type; // Normal case, return Ty&
+ using ret_type = const To &; // Normal case, return Ty&
};
template<class To, class From> struct cast_retty_impl<To, From*> {
- typedef To* ret_type; // Pointer arg case, return Ty*
+ using ret_type = To *; // Pointer arg case, return Ty*
};
template<class To, class From> struct cast_retty_impl<To, const From*> {
- typedef const To* ret_type; // Constant pointer arg case, return const Ty*
+ using ret_type = const To *; // Constant pointer arg case, return const Ty*
};
template<class To, class From> struct cast_retty_impl<To, const From*const> {
- typedef const To* ret_type; // Constant pointer arg case, return const Ty*
+ using ret_type = const To *; // Constant pointer arg case, return const Ty*
};
+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;
+
+public:
+ using ret_type = std::unique_ptr<ResultType>;
+};
template<class To, class From, class SimpleFrom>
struct cast_retty_wrap {
// When the simplified type and the from type are not the same, use the type
// simplifier to reduce the type, then reuse cast_retty_impl to get the
// resultant type.
- typedef typename cast_retty<To, SimpleFrom>::ret_type ret_type;
+ using ret_type = typename cast_retty<To, SimpleFrom>::ret_type;
};
template<class To, class FromTy>
struct cast_retty_wrap<To, FromTy, FromTy> {
// When the simplified type is equal to the from type, use it directly.
- typedef typename cast_retty_impl<To,FromTy>::ret_type ret_type;
+ using ret_type = typename cast_retty_impl<To,FromTy>::ret_type;
};
template<class To, class From>
struct cast_retty {
- typedef typename cast_retty_wrap<To, From,
- typename simplify_type<From>::SimpleType>::ret_type ret_type;
+ using ret_type = typename cast_retty_wrap<
+ To, From, typename simplify_type<From>::SimpleType>::ret_type;
};
// Ensure the non-simple values are converted using the simplify_type template
@@ -238,6 +257,16 @@ inline typename cast_retty<X, Y *>::ret_type cast(Y *Val) {
typename simplify_type<Y*>::SimpleType>::doit(Val);
}
+template <class X, class Y>
+inline typename cast_retty<X, std::unique_ptr<Y>>::ret_type
+cast(std::unique_ptr<Y> &&Val) {
+ assert(isa<X>(Val.get()) && "cast<Ty>() argument of incompatible type!");
+ using ret_type = typename cast_retty<X, std::unique_ptr<Y>>::ret_type;
+ return ret_type(
+ cast_convert_val<X, Y *, typename simplify_type<Y *>::SimpleType>::doit(
+ Val.release()));
+}
+
// cast_or_null<X> - Functionally identical to cast, except that a null value is
// accepted.
//
@@ -271,6 +300,13 @@ cast_or_null(Y *Val) {
return cast<X>(Val);
}
+template <class X, class Y>
+inline typename cast_retty<X, std::unique_ptr<Y>>::ret_type
+cast_or_null(std::unique_ptr<Y> &&Val) {
+ if (!Val)
+ return nullptr;
+ return cast<X>(std::move(Val));
+}
// dyn_cast<X> - Return the argument parameter cast to the specified type. This
// casting operator returns null if the argument is of the wrong type, so it can
@@ -323,6 +359,41 @@ dyn_cast_or_null(Y *Val) {
return (Val && isa<X>(Val)) ? cast<X>(Val) : nullptr;
}
-} // End llvm namespace
+// unique_dyn_cast<X> - Given a unique_ptr<Y>, try to return a unique_ptr<X>,
+// taking ownership of the input pointer iff isa<X>(Val) is true. If the
+// cast is successful, From refers to nullptr on exit and the casted value
+// is returned. If the cast is unsuccessful, the function returns nullptr
+// and From is unchanged.
+template <class X, class Y>
+LLVM_NODISCARD inline auto unique_dyn_cast(std::unique_ptr<Y> &Val)
+ -> decltype(cast<X>(Val)) {
+ if (!isa<X>(Val))
+ return nullptr;
+ return cast<X>(std::move(Val));
+}
+
+template <class X, class Y>
+LLVM_NODISCARD inline auto unique_dyn_cast(std::unique_ptr<Y> &&Val)
+ -> decltype(cast<X>(Val)) {
+ return unique_dyn_cast<X, Y>(Val);
+}
+
+// dyn_cast_or_null<X> - Functionally identical to unique_dyn_cast, except that
+// a null value is accepted.
+template <class X, class Y>
+LLVM_NODISCARD inline auto unique_dyn_cast_or_null(std::unique_ptr<Y> &Val)
+ -> decltype(cast<X>(Val)) {
+ if (!Val)
+ return nullptr;
+ return unique_dyn_cast<X, 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)) {
+ return unique_dyn_cast_or_null<X, Y>(Val);
+}
+
+} // end namespace llvm
-#endif
+#endif // LLVM_SUPPORT_CASTING_H
diff --git a/contrib/llvm/include/llvm/Support/Chrono.h b/contrib/llvm/include/llvm/Support/Chrono.h
index 203439c..6118ed0 100644
--- a/contrib/llvm/include/llvm/Support/Chrono.h
+++ b/contrib/llvm/include/llvm/Support/Chrono.h
@@ -11,6 +11,7 @@
#define LLVM_SUPPORT_CHRONO_H
#include "llvm/Support/Compiler.h"
+#include "llvm/Support/FormatProviders.h"
#include <chrono>
#include <ctime>
@@ -50,6 +51,100 @@ toTimePoint(std::time_t T) {
raw_ostream &operator<<(raw_ostream &OS, sys::TimePoint<> TP);
+/// Implementation of format_provider<T> for duration types.
+///
+/// The options string of a duration type has the grammar:
+///
+/// duration_options ::= [unit][show_unit [number_options]]
+/// unit ::= `h`|`m`|`s`|`ms|`us`|`ns`
+/// show_unit ::= `+` | `-`
+/// number_options ::= options string for a integral or floating point type
+///
+/// Examples
+/// =================================
+/// | options | Input | Output |
+/// =================================
+/// | "" | 1s | 1 s |
+/// | "ms" | 1s | 1000 ms |
+/// | "ms-" | 1s | 1000 |
+/// | "ms-n" | 1s | 1,000 |
+/// | "" | 1.0s | 1.00 s |
+/// =================================
+///
+/// If the unit of the duration type is not one of the units specified above,
+/// it is still possible to format it, provided you explicitly request a
+/// display unit or you request that the unit is not displayed.
+
+namespace detail {
+template <typename Period> struct unit { static const char value[]; };
+template <typename Period> const char unit<Period>::value[] = "";
+
+template <> struct unit<std::ratio<3600>> { static const char value[]; };
+template <> struct unit<std::ratio<60>> { static const char value[]; };
+template <> struct unit<std::ratio<1>> { static const char value[]; };
+template <> struct unit<std::milli> { static const char value[]; };
+template <> struct unit<std::micro> { static const char value[]; };
+template <> struct unit<std::nano> { static const char value[]; };
+} // namespace detail
+
+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
+ InternalRep;
+
+ template <typename AsPeriod> static InternalRep getAs(const Dur &D) {
+ using namespace std::chrono;
+ return duration_cast<duration<InternalRep, AsPeriod>>(D).count();
+ }
+
+ static std::pair<InternalRep, StringRef> consumeUnit(StringRef &Style,
+ const Dur &D) {
+ using namespace std::chrono;
+ if (Style.consume_front("ns"))
+ return {getAs<std::nano>(D), "ns"};
+ if (Style.consume_front("us"))
+ return {getAs<std::micro>(D), "us"};
+ if (Style.consume_front("ms"))
+ return {getAs<std::milli>(D), "ms"};
+ if (Style.consume_front("s"))
+ return {getAs<std::ratio<1>>(D), "s"};
+ if (Style.consume_front("m"))
+ return {getAs<std::ratio<60>>(D), "m"};
+ if (Style.consume_front("h"))
+ return {getAs<std::ratio<3600>>(D), "h"};
+ return {D.count(), detail::unit<Period>::value};
+ }
+
+ static bool consumeShowUnit(StringRef &Style) {
+ if (Style.empty())
+ return true;
+ if (Style.consume_front("-"))
+ return false;
+ if (Style.consume_front("+"))
+ return true;
+ assert(0 && "Unrecognised duration format");
+ return true;
+ }
+
+public:
+ static void format(const Dur &D, llvm::raw_ostream &Stream, StringRef Style) {
+ InternalRep count;
+ StringRef unit;
+ std::tie(count, unit) = consumeUnit(Style, D);
+ bool show_unit = consumeShowUnit(Style);
+
+ format_provider<InternalRep>::format(count, Stream, Style);
+
+ if (show_unit) {
+ assert(!unit.empty());
+ Stream << " " << unit;
+ }
+ }
+};
+
} // namespace llvm
#endif // LLVM_SUPPORT_CHRONO_H
diff --git a/contrib/llvm/include/llvm/Support/CommandLine.h b/contrib/llvm/include/llvm/Support/CommandLine.h
index 8d4ac81..71d2f02 100644
--- a/contrib/llvm/include/llvm/Support/CommandLine.h
+++ b/contrib/llvm/include/llvm/Support/CommandLine.h
@@ -21,18 +21,19 @@
#define LLVM_SUPPORT_COMMANDLINE_H
#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/iterator_range.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
+#include "llvm/ADT/iterator_range.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/ManagedStatic.h"
#include <cassert>
#include <climits>
#include <cstddef>
+#include <functional>
#include <initializer_list>
#include <string>
#include <type_traits>
@@ -41,6 +42,7 @@
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
@@ -50,9 +52,12 @@ namespace cl {
//===----------------------------------------------------------------------===//
// ParseCommandLineOptions - Command line option processing entry point.
//
+// Returns true on success. Otherwise, this will print the error message to
+// stderr and exit if \p Errs is not set (nullptr by default), or print the
+// error message to \p Errs and return false if \p Errs is provided.
bool ParseCommandLineOptions(int argc, const char *const *argv,
StringRef Overview = "",
- bool IgnoreErrors = false);
+ raw_ostream *Errs = nullptr);
//===----------------------------------------------------------------------===//
// ParseEnvironmentOptions - Environment variable option processing alternate
@@ -239,7 +244,7 @@ class Option {
// Out of line virtual function to provide home for the class.
virtual void anchor();
- int NumOccurrences; // The number of times specified
+ int NumOccurrences = 0; // The number of times specified
// Occurrences, HiddenFlag, and Formatting are all enum types but to avoid
// problems with signed enums in bitfields.
unsigned Occurrences : 3; // enum NumOccurrencesFlag
@@ -249,8 +254,8 @@ class Option {
unsigned HiddenFlag : 2; // enum OptionHidden
unsigned Formatting : 2; // enum FormattingFlags
unsigned Misc : 3;
- unsigned Position; // Position of last occurrence of the option
- unsigned AdditionalVals; // Greater than 0 for multi-valued option.
+ unsigned Position = 0; // Position of last occurrence of the option
+ unsigned AdditionalVals = 0; // Greater than 0 for multi-valued option.
public:
StringRef ArgStr; // The argument string itself (ex: "help", "o")
@@ -258,7 +263,7 @@ public:
StringRef ValueStr; // String describing what the value of this option is
OptionCategory *Category; // The Category this option belongs to
SmallPtrSet<SubCommand *, 4> Subs; // The subcommands this option belongs to.
- bool FullyInitialized; // Has addArguemnt been called?
+ bool FullyInitialized = false; // Has addArguemnt been called?
inline enum NumOccurrencesFlag getNumOccurrencesFlag() const {
return (enum NumOccurrencesFlag)Occurrences;
@@ -313,10 +318,8 @@ public:
protected:
explicit Option(enum NumOccurrencesFlag OccurrencesFlag,
enum OptionHidden Hidden)
- : NumOccurrences(0), Occurrences(OccurrencesFlag), Value(0),
- HiddenFlag(Hidden), Formatting(NormalFormatting), Misc(0), Position(0),
- AdditionalVals(0), Category(&GeneralCategory), FullyInitialized(false) {
- }
+ : Occurrences(OccurrencesFlag), Value(0), HiddenFlag(Hidden),
+ Formatting(NormalFormatting), Misc(0), Category(&GeneralCategory) {}
inline void setNumAdditionalVals(unsigned n) { AdditionalVals = n; }
@@ -343,6 +346,9 @@ public:
virtual void printOptionValue(size_t GlobalWidth, bool Force) const = 0;
+ static void printHelpStr(StringRef HelpStr, size_t Indent,
+ size_t FirstLineIndentedBy);
+
virtual void getExtraOptionNames(SmallVectorImpl<StringRef> &) {}
// addOccurrence - Wrapper around handleOccurrence that enforces Flags.
@@ -441,8 +447,8 @@ struct GenericOptionValue {
protected:
GenericOptionValue() = default;
GenericOptionValue(const GenericOptionValue&) = default;
- ~GenericOptionValue() = default;
GenericOptionValue &operator=(const GenericOptionValue &) = default;
+ ~GenericOptionValue() = default;
private:
virtual void anchor();
@@ -455,7 +461,7 @@ template <class DataType> struct OptionValue;
template <class DataType, bool isClass>
struct OptionValueBase : public GenericOptionValue {
// Temporary storage for argument passing.
- typedef OptionValue<DataType> WrapperType;
+ using WrapperType = OptionValue<DataType>;
bool hasValue() const { return false; }
@@ -481,8 +487,8 @@ template <class DataType> class OptionValueCopy : public GenericOptionValue {
protected:
OptionValueCopy(const OptionValueCopy&) = default;
+ OptionValueCopy &operator=(const OptionValueCopy &) = default;
~OptionValueCopy() = default;
- OptionValueCopy &operator=(const OptionValueCopy&) = default;
public:
OptionValueCopy() = default;
@@ -513,13 +519,13 @@ public:
// Non-class option values.
template <class DataType>
struct OptionValueBase<DataType, false> : OptionValueCopy<DataType> {
- typedef DataType WrapperType;
+ using WrapperType = DataType;
protected:
OptionValueBase() = default;
OptionValueBase(const OptionValueBase&) = default;
+ OptionValueBase &operator=(const OptionValueBase &) = default;
~OptionValueBase() = default;
- OptionValueBase &operator=(const OptionValueBase&) = default;
};
// Top-level option class.
@@ -542,7 +548,7 @@ enum boolOrDefault { BOU_UNSET, BOU_TRUE, BOU_FALSE };
template <>
struct OptionValue<cl::boolOrDefault> final
: OptionValueCopy<cl::boolOrDefault> {
- typedef cl::boolOrDefault WrapperType;
+ using WrapperType = cl::boolOrDefault;
OptionValue() = default;
@@ -559,7 +565,7 @@ private:
template <>
struct OptionValue<std::string> final : OptionValueCopy<std::string> {
- typedef StringRef WrapperType;
+ using WrapperType = StringRef;
OptionValue() = default;
@@ -730,13 +736,15 @@ protected:
public:
OptionInfo(StringRef name, DataType v, StringRef helpStr)
: GenericOptionInfo(name, helpStr), V(v) {}
+
OptionValue<DataType> V;
};
SmallVector<OptionInfo, 8> Values;
public:
parser(Option &O) : generic_parser_base(O) {}
- typedef DataType parser_data_type;
+
+ using parser_data_type = DataType;
// Implement virtual functions needed by generic_parser_base
unsigned getNumOptions() const override { return unsigned(Values.size()); }
@@ -831,10 +839,10 @@ protected:
//
template <class DataType> class basic_parser : public basic_parser_impl {
public:
- basic_parser(Option &O) : basic_parser_impl(O) {}
+ using parser_data_type = DataType;
+ using OptVal = OptionValue<DataType>;
- typedef DataType parser_data_type;
- typedef OptionValue<DataType> OptVal;
+ basic_parser(Option &O) : basic_parser_impl(O) {}
protected:
~basic_parser() = default;
@@ -1286,6 +1294,7 @@ class opt : public Option,
enum ValueExpected getValueExpectedFlagDefault() const override {
return Parser.getValueExpectedFlagDefault();
}
+
void getExtraOptionNames(SmallVectorImpl<StringRef> &OptionNames) override {
return Parser.getExtraOptionNames(OptionNames);
}
@@ -1294,6 +1303,7 @@ class opt : public Option,
size_t getOptionWidth() const override {
return Parser.getOptionWidth(*this);
}
+
void printOptionInfo(size_t GlobalWidth) const override {
Parser.printOptionInfo(*this, GlobalWidth);
}
@@ -1378,16 +1388,18 @@ template <class DataType> class list_storage<DataType, bool> {
std::vector<DataType> Storage;
public:
- typedef typename std::vector<DataType>::iterator iterator;
+ using iterator = typename std::vector<DataType>::iterator;
iterator begin() { return Storage.begin(); }
iterator end() { return Storage.end(); }
- typedef typename std::vector<DataType>::const_iterator const_iterator;
+ using const_iterator = typename std::vector<DataType>::const_iterator;
+
const_iterator begin() const { return Storage.begin(); }
const_iterator end() const { return Storage.end(); }
- typedef typename std::vector<DataType>::size_type size_type;
+ using size_type = typename std::vector<DataType>::size_type;
+
size_type size() const { return Storage.size(); }
bool empty() const { return Storage.empty(); }
@@ -1395,8 +1407,9 @@ public:
void push_back(const DataType &value) { Storage.push_back(value); }
void push_back(DataType &&value) { Storage.push_back(value); }
- typedef typename std::vector<DataType>::reference reference;
- typedef typename std::vector<DataType>::const_reference const_reference;
+ using reference = typename std::vector<DataType>::reference;
+ using const_reference = typename std::vector<DataType>::const_reference;
+
reference operator[](size_type pos) { return Storage[pos]; }
const_reference operator[](size_type pos) const { return Storage[pos]; }
@@ -1447,6 +1460,7 @@ class list : public Option, public list_storage<DataType, StorageClass> {
enum ValueExpected getValueExpectedFlagDefault() const override {
return Parser.getValueExpectedFlagDefault();
}
+
void getExtraOptionNames(SmallVectorImpl<StringRef> &OptionNames) override {
return Parser.getExtraOptionNames(OptionNames);
}
@@ -1467,6 +1481,7 @@ class list : public Option, public list_storage<DataType, StorageClass> {
size_t getOptionWidth() const override {
return Parser.getOptionWidth(*this);
}
+
void printOptionInfo(size_t GlobalWidth) const override {
Parser.printOptionInfo(*this, GlobalWidth);
}
@@ -1586,6 +1601,7 @@ class bits : public Option, public bits_storage<DataType, Storage> {
enum ValueExpected getValueExpectedFlagDefault() const override {
return Parser.getValueExpectedFlagDefault();
}
+
void getExtraOptionNames(SmallVectorImpl<StringRef> &OptionNames) override {
return Parser.getExtraOptionNames(OptionNames);
}
@@ -1606,6 +1622,7 @@ class bits : public Option, public bits_storage<DataType, Storage> {
size_t getOptionWidth() const override {
return Parser.getOptionWidth(*this);
}
+
void printOptionInfo(size_t GlobalWidth) const override {
Parser.printOptionInfo(*this, GlobalWidth);
}
@@ -1818,9 +1835,9 @@ void TokenizeWindowsCommandLine(StringRef Source, StringSaver &Saver,
/// \brief String tokenization function type. Should be compatible with either
/// Windows or Unix command line tokenizers.
-typedef void (*TokenizerCallback)(StringRef Source, StringSaver &Saver,
- SmallVectorImpl<const char *> &NewArgv,
- bool MarkEOLs);
+using TokenizerCallback = void (*)(StringRef Source, StringSaver &Saver,
+ SmallVectorImpl<const char *> &NewArgv,
+ bool MarkEOLs);
/// \brief Expand response files on a command line recursively using the given
/// StringSaver and tokenization strategy. Argv should contain the command line
@@ -1874,6 +1891,7 @@ void ResetAllOptionOccurrences();
void ResetCommandLineParser();
} // end namespace cl
+
} // end namespace llvm
#endif // LLVM_SUPPORT_COMMANDLINE_H
diff --git a/contrib/llvm/include/llvm/Support/Compiler.h b/contrib/llvm/include/llvm/Support/Compiler.h
index 55148a4..b19e372 100644
--- a/contrib/llvm/include/llvm/Support/Compiler.h
+++ b/contrib/llvm/include/llvm/Support/Compiler.h
@@ -111,12 +111,6 @@
#define LLVM_PREFETCH(addr, rw, locality)
#endif
-#if __has_attribute(sentinel) || LLVM_GNUC_PREREQ(3, 0, 0)
-#define LLVM_END_WITH_NULL __attribute__((sentinel))
-#else
-#define LLVM_END_WITH_NULL
-#endif
-
#if __has_attribute(used) || LLVM_GNUC_PREREQ(3, 1, 0)
#define LLVM_ATTRIBUTE_USED __attribute__((__used__))
#else
@@ -233,6 +227,8 @@
/// LLVM_FALLTHROUGH - Mark fallthrough cases in switch statements.
#if __cplusplus > 201402L && __has_cpp_attribute(fallthrough)
#define LLVM_FALLTHROUGH [[fallthrough]]
+#elif __has_cpp_attribute(gnu::fallthrough)
+#define LLVM_FALLTHROUGH [[gnu::fallthrough]]
#elif !__cplusplus
// Workaround for llvm.org/PR23435, since clang 3.6 and below emit a spurious
// error when __has_cpp_attribute is given a scoped attribute in C mode.
@@ -343,7 +339,7 @@
/// int k;
/// long long l;
/// };
-/// LLVM_PACKED_END
+/// LLVM_PACKED_END
#ifdef _MSC_VER
# define LLVM_PACKED(d) __pragma(pack(push, 1)) d __pragma(pack(pop))
# define LLVM_PACKED_START __pragma(pack(push, 1))
@@ -445,6 +441,9 @@ void AnnotateIgnoreWritesEnd(const char *file, int line);
/// \brief Mark debug helper function definitions like dump() that should not be
/// stripped from debug builds.
+/// Note that you should also surround dump() functions with
+/// `#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)` so they do always
+/// get stripped in release builds.
// FIXME: Move this to a private config.h as it's not usable in public headers.
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
#define LLVM_DUMP_METHOD LLVM_ATTRIBUTE_NOINLINE LLVM_ATTRIBUTE_USED
@@ -461,7 +460,7 @@ void AnnotateIgnoreWritesEnd(const char *file, int line);
#define LLVM_PRETTY_FUNCTION __FUNCSIG__
#elif defined(__GNUC__) || defined(__clang__)
#define LLVM_PRETTY_FUNCTION __PRETTY_FUNCTION__
-#else
+#else
#define LLVM_PRETTY_FUNCTION __func__
#endif
@@ -494,4 +493,14 @@ void AnnotateIgnoreWritesEnd(const char *file, int line);
#define LLVM_THREAD_LOCAL
#endif
+/// \macro LLVM_ENABLE_EXCEPTIONS
+/// \brief Whether LLVM is built with exception support.
+#if __has_feature(cxx_exceptions)
+#define LLVM_ENABLE_EXCEPTIONS 1
+#elif defined(__GNUC__) && defined(__EXCEPTIONS)
+#define LLVM_ENABLE_EXCEPTIONS 1
+#elif defined(_MSC_VER) && defined(_CPPUNWIND)
+#define LLVM_ENABLE_EXCEPTIONS 1
+#endif
+
#endif
diff --git a/contrib/llvm/include/llvm/Support/Compression.h b/contrib/llvm/include/llvm/Support/Compression.h
index 5bf7031..2d191ab 100644
--- a/contrib/llvm/include/llvm/Support/Compression.h
+++ b/contrib/llvm/include/llvm/Support/Compression.h
@@ -18,6 +18,7 @@
namespace llvm {
template <typename T> class SmallVectorImpl;
+class Error;
class StringRef;
namespace zlib {
@@ -29,26 +30,17 @@ enum CompressionLevel {
BestSizeCompression
};
-enum Status {
- StatusOK,
- StatusUnsupported, // zlib is unavailable
- StatusOutOfMemory, // there was not enough memory
- StatusBufferTooShort, // there was not enough room in the output buffer
- StatusInvalidArg, // invalid input parameter
- StatusInvalidData // data was corrupted or incomplete
-};
-
bool isAvailable();
-Status compress(StringRef InputBuffer, SmallVectorImpl<char> &CompressedBuffer,
- CompressionLevel Level = DefaultCompression);
+Error compress(StringRef InputBuffer, SmallVectorImpl<char> &CompressedBuffer,
+ CompressionLevel Level = DefaultCompression);
-Status uncompress(StringRef InputBuffer, char *UncompressedBuffer,
- size_t &UncompressedSize);
+Error uncompress(StringRef InputBuffer, char *UncompressedBuffer,
+ size_t &UncompressedSize);
-Status uncompress(StringRef InputBuffer,
- SmallVectorImpl<char> &UncompressedBuffer,
- size_t UncompressedSize);
+Error uncompress(StringRef InputBuffer,
+ SmallVectorImpl<char> &UncompressedBuffer,
+ size_t UncompressedSize);
uint32_t crc32(StringRef Buffer);
diff --git a/contrib/llvm/include/llvm/Support/ConvertUTF.h b/contrib/llvm/include/llvm/Support/ConvertUTF.h
index f714c0e..bd439f3 100644
--- a/contrib/llvm/include/llvm/Support/ConvertUTF.h
+++ b/contrib/llvm/include/llvm/Support/ConvertUTF.h
@@ -90,8 +90,8 @@
#ifndef LLVM_SUPPORT_CONVERTUTF_H
#define LLVM_SUPPORT_CONVERTUTF_H
-#include <string>
#include <cstddef>
+#include <string>
// Wrap everything in namespace llvm so that programs can link with llvm and
// their own version of the unicode libraries.
diff --git a/contrib/llvm/include/llvm/Support/DataExtractor.h b/contrib/llvm/include/llvm/Support/DataExtractor.h
index 2d1180c..3144788 100644
--- a/contrib/llvm/include/llvm/Support/DataExtractor.h
+++ b/contrib/llvm/include/llvm/Support/DataExtractor.h
@@ -14,6 +14,30 @@
#include "llvm/Support/DataTypes.h"
namespace llvm {
+
+/// An auxiliary type to facilitate extraction of 3-byte entities.
+struct Uint24 {
+ uint8_t Bytes[3];
+ Uint24(uint8_t U) {
+ Bytes[0] = Bytes[1] = Bytes[2] = U;
+ }
+ Uint24(uint8_t U0, uint8_t U1, uint8_t U2) {
+ Bytes[0] = U0; Bytes[1] = U1; Bytes[2] = U2;
+ }
+ uint32_t getAsUint32(bool IsLittleEndian) const {
+ int LoIx = IsLittleEndian ? 0 : 2;
+ return Bytes[LoIx] + (Bytes[1] << 8) + (Bytes[2-LoIx] << 16);
+ }
+};
+
+using uint24_t = Uint24;
+static_assert(sizeof(uint24_t) == 3, "sizeof(uint24_t) != 3");
+
+/// Needed by swapByteOrder().
+inline uint24_t getSwappedBytes(uint24_t C) {
+ return uint24_t(C.Bytes[2], C.Bytes[1], C.Bytes[0]);
+}
+
class DataExtractor {
StringRef Data;
uint8_t IsLittleEndian;
@@ -58,6 +82,28 @@ public:
/// NULL will be returned.
const char *getCStr(uint32_t *offset_ptr) const;
+ /// Extract a C string from \a *OffsetPtr.
+ ///
+ /// Returns a StringRef for the C String from the data at the offset
+ /// pointed to by \a OffsetPtr. A variable length NULL terminated C
+ /// string will be extracted and the \a OffsetPtr will be
+ /// updated with the offset of the byte that follows the NULL
+ /// terminator byte.
+ ///
+ /// \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.
+ ///
+ /// \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 getCStrRef(uint32_t *OffsetPtr) const;
+
/// Extract an unsigned integer of size \a byte_size from \a
/// *offset_ptr.
///
@@ -214,6 +260,23 @@ public:
/// NULL otherise.
uint16_t *getU16(uint32_t *offset_ptr, uint16_t *dst, uint32_t count) const;
+ /// Extract a 24-bit unsigned value from \a *offset_ptr and return it
+ /// in a uint32_t.
+ ///
+ /// Extract 3 bytes from the binary data at the offset pointed to by
+ /// \a offset_ptr, construct a uint32_t from them and update the offset
+ /// on success.
+ ///
+ /// @param[in,out] offset_ptr
+ /// 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.
+ ///
+ /// @return
+ /// The extracted 24-bit value represented in a uint32_t.
+ uint32_t getU24(uint32_t *offset_ptr) const;
+
/// Extract a uint32_t value from \a *offset_ptr.
///
/// Extract a single uint32_t from the binary data at the offset
diff --git a/contrib/llvm/include/llvm/Support/Debug.h b/contrib/llvm/include/llvm/Support/Debug.h
index 3465c40..48e9e1b 100644
--- a/contrib/llvm/include/llvm/Support/Debug.h
+++ b/contrib/llvm/include/llvm/Support/Debug.h
@@ -33,11 +33,6 @@ namespace llvm {
class raw_ostream;
#ifndef NDEBUG
-/// DebugFlag - This boolean is set to true if the '-debug' command line option
-/// is specified. This should probably not be referenced directly, instead, use
-/// the DEBUG macro below.
-///
-extern bool DebugFlag;
/// isCurrentDebugType - Return true if the specified string is the debug type
/// specified on the command line, or if none was specified on the command line
@@ -77,6 +72,29 @@ void setCurrentDebugTypes(const char **Types, unsigned Count);
#define DEBUG_WITH_TYPE(TYPE, X) do { } while (false)
#endif
+/// This boolean is set to true if the '-debug' command line option
+/// is specified. This should probably not be referenced directly, instead, use
+/// the DEBUG macro below.
+///
+extern bool DebugFlag;
+
+/// \name Verification flags.
+///
+/// These flags turns on/off that are expensive and are turned off by default,
+/// unless macro EXPENSIVE_CHECKS is defined. The flags allow selectively
+/// turning the checks on without need to recompile.
+/// \{
+
+/// Enables verification of dominator trees.
+///
+extern bool VerifyDomInfo;
+
+/// Enables verification of loop info.
+///
+extern bool VerifyLoopInfo;
+
+///\}
+
/// EnableDebugBuffering - This defaults to false. If true, the debug
/// stream will install signal handlers to dump any buffered debug
/// output. It allows clients to selectively allow the debug stream
diff --git a/contrib/llvm/include/llvm/Support/DebugCounter.h b/contrib/llvm/include/llvm/Support/DebugCounter.h
new file mode 100644
index 0000000..a533fea
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/DebugCounter.h
@@ -0,0 +1,165 @@
+//===- llvm/Support/DebugCounter.h - Debug counter support ------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+/// \file
+/// \brief This file provides an implementation of debug counters. Debug
+/// counters are a tool that let you narrow down a miscompilation to a specific
+/// thing happening.
+///
+/// To give a use case: Imagine you have a file, very large, and you
+/// are trying to understand the minimal transformation that breaks it. Bugpoint
+/// and bisection is often helpful here in narrowing it down to a specific pass,
+/// but it's still a very large file, and a very complicated pass to try to
+/// debug. That is where debug counting steps in. You can instrument the pass
+/// with a debug counter before it does a certain thing, and depending on the
+/// counts, it will either execute that thing or not. The debug counter itself
+/// consists of a skip and a count. Skip is the number of times shouldExecute
+/// needs to be called before it returns true. Count is the number of times to
+/// return true once Skip is 0. So a skip=47, count=2 ,would skip the first 47
+/// executions by returning false from shouldExecute, then execute twice, and
+/// then return false again.
+/// Note that a counter set to a negative number will always execute.
+/// For a concrete example, during predicateinfo creation, the renaming pass
+/// replaces each use with a renamed use.
+////
+/// If I use DEBUG_COUNTER to create a counter called "predicateinfo", and
+/// variable name RenameCounter, and then instrument this renaming with a debug
+/// counter, like so:
+///
+/// if (!DebugCounter::shouldExecute(RenameCounter)
+/// <continue or return or whatever not executing looks like>
+///
+/// Now I can, from the command line, make it rename or not rename certain uses
+/// by setting the skip and count.
+/// So for example
+/// bin/opt -debug-counter=predicateinfo-skip=47,predicateinfo-count=1
+/// will skip renaming the first 47 uses, then rename one, then skip the rest.
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_DEBUGCOUNTER_H
+#define LLVM_SUPPORT_DEBUGCOUNTER_H
+
+#include "llvm/ADT/DenseMap.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 DebugCounter {
+public:
+ /// \brief Returns a reference to the singleton instance.
+ static DebugCounter &instance();
+
+ // Used by the command line option parser to push a new value it parsed.
+ void push_back(const std::string &);
+
+ // Register a counter with the specified name.
+ //
+ // FIXME: Currently, counter registration is required to happen before command
+ // 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);
+ }
+ inline static bool shouldExecute(unsigned CounterName) {
+// Compile to nothing when debugging is off
+#ifdef NDEBUG
+ return true;
+#else
+ auto &Us = instance();
+ auto Result = Us.Counters.find(CounterName);
+ if (Result != Us.Counters.end()) {
+ auto &CounterPair = Result->second;
+ // We only execute while the skip (first) is zero and the count (second)
+ // is non-zero.
+ // Negative counters always execute.
+ if (CounterPair.first < 0)
+ return true;
+ if (CounterPair.first != 0) {
+ --CounterPair.first;
+ return false;
+ }
+ if (CounterPair.second < 0)
+ return true;
+ if (CounterPair.second != 0) {
+ --CounterPair.second;
+ return true;
+ }
+ return false;
+ }
+ // Didn't find the counter, should we warn?
+ return true;
+#endif // NDEBUG
+ }
+
+ // Return true if a given counter had values set (either programatically or on
+ // the command line). This will return true even if those values are
+ // currently in a state where the counter will always execute.
+ static bool isCounterSet(unsigned ID) {
+ return instance().Counters.count(ID);
+ }
+
+ // Return the skip and count for a counter. This only works for set counters.
+ static std::pair<int, int> getCounterValue(unsigned ID) {
+ auto &Us = instance();
+ auto Result = Us.Counters.find(ID);
+ assert(Result != Us.Counters.end() && "Asking about a non-set counter");
+ return Result->second;
+ }
+
+ // Set a registered counter to a given value.
+ static void setCounterValue(unsigned ID, const std::pair<int, int> &Val) {
+ auto &Us = instance();
+ Us.Counters[ID] = Val;
+ }
+
+ // Dump or print the current counter set into llvm::dbgs().
+ LLVM_DUMP_METHOD void dump() const;
+
+ void print(raw_ostream &OS) const;
+
+ // Get the counter ID for a given named counter, or return 0 if none is found.
+ unsigned getCounterId(const std::string &Name) const {
+ return RegisteredCounters.idFor(Name);
+ }
+
+ // Return the number of registered counters.
+ unsigned int getNumCounters() const { return RegisteredCounters.size(); }
+
+ // Return the name and description of the counter with the given ID.
+ std::pair<std::string, std::string> getCounterInfo(unsigned ID) const {
+ return std::make_pair(RegisteredCounters[ID], CounterDesc.lookup(ID));
+ }
+
+ // Iterate through the registered counters
+ typedef UniqueVector<std::string> CounterVector;
+ CounterVector::const_iterator begin() const {
+ return RegisteredCounters.begin();
+ }
+ CounterVector::const_iterator end() const { return RegisteredCounters.end(); }
+
+private:
+ unsigned addCounter(const std::string &Name, const std::string &Desc) {
+ unsigned Result = RegisteredCounters.insert(Name);
+ CounterDesc[Result] = Desc;
+ return Result;
+ }
+ DenseMap<unsigned, std::pair<long, long>> Counters;
+ DenseMap<unsigned, std::string> CounterDesc;
+ CounterVector RegisteredCounters;
+};
+
+#define DEBUG_COUNTER(VARNAME, COUNTERNAME, DESC) \
+ static const unsigned VARNAME = \
+ DebugCounter::registerCounter(COUNTERNAME, DESC);
+
+} // namespace llvm
+#endif
diff --git a/contrib/llvm/include/llvm/Support/Dwarf.def b/contrib/llvm/include/llvm/Support/Dwarf.def
deleted file mode 100644
index 841fc7d..0000000
--- a/contrib/llvm/include/llvm/Support/Dwarf.def
+++ /dev/null
@@ -1,811 +0,0 @@
-//===- llvm/Support/Dwarf.def - Dwarf definitions ---------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Macros for running through Dwarf enumerators.
-//
-//===----------------------------------------------------------------------===//
-
-// TODO: Add other DW-based macros.
-#if !(defined HANDLE_DW_TAG || defined HANDLE_DW_AT || \
- defined HANDLE_DW_FORM || defined HANDLE_DW_OP || \
- defined HANDLE_DW_LANG || defined HANDLE_DW_ATE || \
- 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_DW_RLE || \
- defined HANDLE_DW_CFA || defined HANDLE_DW_APPLE_PROPERTY)
-#error "Missing macro definition of HANDLE_DW*"
-#endif
-
-#ifndef HANDLE_DW_TAG
-#define HANDLE_DW_TAG(ID, NAME)
-#endif
-
-#ifndef HANDLE_DW_AT
-#define HANDLE_DW_AT(ID, NAME)
-#endif
-
-#ifndef HANDLE_DW_FORM
-#define HANDLE_DW_FORM(ID, NAME)
-#endif
-
-#ifndef HANDLE_DW_OP
-#define HANDLE_DW_OP(ID, NAME)
-#endif
-
-#ifndef HANDLE_DW_LANG
-#define HANDLE_DW_LANG(ID, NAME)
-#endif
-
-#ifndef HANDLE_DW_ATE
-#define HANDLE_DW_ATE(ID, NAME)
-#endif
-
-#ifndef HANDLE_DW_VIRTUALITY
-#define HANDLE_DW_VIRTUALITY(ID, NAME)
-#endif
-
-#ifndef HANDLE_DW_DEFAULTED
-#define HANDLE_DW_DEFAULTED(ID, NAME)
-#endif
-
-#ifndef HANDLE_DW_CC
-#define HANDLE_DW_CC(ID, NAME)
-#endif
-
-#ifndef HANDLE_DW_LNS
-#define HANDLE_DW_LNS(ID, NAME)
-#endif
-
-#ifndef HANDLE_DW_LNE
-#define HANDLE_DW_LNE(ID, NAME)
-#endif
-
-#ifndef HANDLE_DW_LNCT
-#define HANDLE_DW_LNCT(ID, NAME)
-#endif
-
-#ifndef HANDLE_DW_MACRO
-#define HANDLE_DW_MACRO(ID, NAME)
-#endif
-
-#ifndef HANDLE_DW_RLE
-#define HANDLE_DW_RLE(ID, NAME)
-#endif
-
-#ifndef HANDLE_DW_CFA
-#define HANDLE_DW_CFA(ID, NAME)
-#endif
-
-#ifndef HANDLE_DW_APPLE_PROPERTY
-#define HANDLE_DW_APPLE_PROPERTY(ID, NAME)
-#endif
-
-HANDLE_DW_TAG(0x0000, null)
-HANDLE_DW_TAG(0x0001, array_type)
-HANDLE_DW_TAG(0x0002, class_type)
-HANDLE_DW_TAG(0x0003, entry_point)
-HANDLE_DW_TAG(0x0004, enumeration_type)
-HANDLE_DW_TAG(0x0005, formal_parameter)
-HANDLE_DW_TAG(0x0008, imported_declaration)
-HANDLE_DW_TAG(0x000a, label)
-HANDLE_DW_TAG(0x000b, lexical_block)
-HANDLE_DW_TAG(0x000d, member)
-HANDLE_DW_TAG(0x000f, pointer_type)
-HANDLE_DW_TAG(0x0010, reference_type)
-HANDLE_DW_TAG(0x0011, compile_unit)
-HANDLE_DW_TAG(0x0012, string_type)
-HANDLE_DW_TAG(0x0013, structure_type)
-HANDLE_DW_TAG(0x0015, subroutine_type)
-HANDLE_DW_TAG(0x0016, typedef)
-HANDLE_DW_TAG(0x0017, union_type)
-HANDLE_DW_TAG(0x0018, unspecified_parameters)
-HANDLE_DW_TAG(0x0019, variant)
-HANDLE_DW_TAG(0x001a, common_block)
-HANDLE_DW_TAG(0x001b, common_inclusion)
-HANDLE_DW_TAG(0x001c, inheritance)
-HANDLE_DW_TAG(0x001d, inlined_subroutine)
-HANDLE_DW_TAG(0x001e, module)
-HANDLE_DW_TAG(0x001f, ptr_to_member_type)
-HANDLE_DW_TAG(0x0020, set_type)
-HANDLE_DW_TAG(0x0021, subrange_type)
-HANDLE_DW_TAG(0x0022, with_stmt)
-HANDLE_DW_TAG(0x0023, access_declaration)
-HANDLE_DW_TAG(0x0024, base_type)
-HANDLE_DW_TAG(0x0025, catch_block)
-HANDLE_DW_TAG(0x0026, const_type)
-HANDLE_DW_TAG(0x0027, constant)
-HANDLE_DW_TAG(0x0028, enumerator)
-HANDLE_DW_TAG(0x0029, file_type)
-HANDLE_DW_TAG(0x002a, friend)
-HANDLE_DW_TAG(0x002b, namelist)
-HANDLE_DW_TAG(0x002c, namelist_item)
-HANDLE_DW_TAG(0x002d, packed_type)
-HANDLE_DW_TAG(0x002e, subprogram)
-HANDLE_DW_TAG(0x002f, template_type_parameter)
-HANDLE_DW_TAG(0x0030, template_value_parameter)
-HANDLE_DW_TAG(0x0031, thrown_type)
-HANDLE_DW_TAG(0x0032, try_block)
-HANDLE_DW_TAG(0x0033, variant_part)
-HANDLE_DW_TAG(0x0034, variable)
-HANDLE_DW_TAG(0x0035, volatile_type)
-HANDLE_DW_TAG(0x0036, dwarf_procedure)
-HANDLE_DW_TAG(0x0037, restrict_type)
-HANDLE_DW_TAG(0x0038, interface_type)
-HANDLE_DW_TAG(0x0039, namespace)
-HANDLE_DW_TAG(0x003a, imported_module)
-HANDLE_DW_TAG(0x003b, unspecified_type)
-HANDLE_DW_TAG(0x003c, partial_unit)
-HANDLE_DW_TAG(0x003d, imported_unit)
-HANDLE_DW_TAG(0x003f, condition)
-HANDLE_DW_TAG(0x0040, shared_type)
-HANDLE_DW_TAG(0x0041, type_unit)
-HANDLE_DW_TAG(0x0042, rvalue_reference_type)
-HANDLE_DW_TAG(0x0043, template_alias)
-
-// New in DWARF v5.
-HANDLE_DW_TAG(0x0044, coarray_type)
-HANDLE_DW_TAG(0x0045, generic_subrange)
-HANDLE_DW_TAG(0x0046, dynamic_type)
-HANDLE_DW_TAG(0x0047, atomic_type)
-HANDLE_DW_TAG(0x0048, call_site)
-HANDLE_DW_TAG(0x0049, call_site_parameter)
-HANDLE_DW_TAG(0x004a, skeleton_unit)
-HANDLE_DW_TAG(0x004b, immutable_type)
-
-// User-defined tags.
-HANDLE_DW_TAG(0x4081, MIPS_loop)
-HANDLE_DW_TAG(0x4101, format_label)
-HANDLE_DW_TAG(0x4102, function_template)
-HANDLE_DW_TAG(0x4103, class_template)
-HANDLE_DW_TAG(0x4106, GNU_template_template_param)
-HANDLE_DW_TAG(0x4107, GNU_template_parameter_pack)
-HANDLE_DW_TAG(0x4108, GNU_formal_parameter_pack)
-HANDLE_DW_TAG(0x4200, APPLE_property)
-HANDLE_DW_TAG(0xb000, BORLAND_property)
-HANDLE_DW_TAG(0xb001, BORLAND_Delphi_string)
-HANDLE_DW_TAG(0xb002, BORLAND_Delphi_dynamic_array)
-HANDLE_DW_TAG(0xb003, BORLAND_Delphi_set)
-HANDLE_DW_TAG(0xb004, BORLAND_Delphi_variant)
-
-// Attributes.
-HANDLE_DW_AT(0x01, sibling)
-HANDLE_DW_AT(0x02, location)
-HANDLE_DW_AT(0x03, name)
-HANDLE_DW_AT(0x09, ordering)
-HANDLE_DW_AT(0x0b, byte_size)
-HANDLE_DW_AT(0x0c, bit_offset)
-HANDLE_DW_AT(0x0d, bit_size)
-HANDLE_DW_AT(0x10, stmt_list)
-HANDLE_DW_AT(0x11, low_pc)
-HANDLE_DW_AT(0x12, high_pc)
-HANDLE_DW_AT(0x13, language)
-HANDLE_DW_AT(0x15, discr)
-HANDLE_DW_AT(0x16, discr_value)
-HANDLE_DW_AT(0x17, visibility)
-HANDLE_DW_AT(0x18, import)
-HANDLE_DW_AT(0x19, string_length)
-HANDLE_DW_AT(0x1a, common_reference)
-HANDLE_DW_AT(0x1b, comp_dir)
-HANDLE_DW_AT(0x1c, const_value)
-HANDLE_DW_AT(0x1d, containing_type)
-HANDLE_DW_AT(0x1e, default_value)
-HANDLE_DW_AT(0x20, inline)
-HANDLE_DW_AT(0x21, is_optional)
-HANDLE_DW_AT(0x22, lower_bound)
-HANDLE_DW_AT(0x25, producer)
-HANDLE_DW_AT(0x27, prototyped)
-HANDLE_DW_AT(0x2a, return_addr)
-HANDLE_DW_AT(0x2c, start_scope)
-HANDLE_DW_AT(0x2e, bit_stride)
-HANDLE_DW_AT(0x2f, upper_bound)
-HANDLE_DW_AT(0x31, abstract_origin)
-HANDLE_DW_AT(0x32, accessibility)
-HANDLE_DW_AT(0x33, address_class)
-HANDLE_DW_AT(0x34, artificial)
-HANDLE_DW_AT(0x35, base_types)
-HANDLE_DW_AT(0x36, calling_convention)
-HANDLE_DW_AT(0x37, count)
-HANDLE_DW_AT(0x38, data_member_location)
-HANDLE_DW_AT(0x39, decl_column)
-HANDLE_DW_AT(0x3a, decl_file)
-HANDLE_DW_AT(0x3b, decl_line)
-HANDLE_DW_AT(0x3c, declaration)
-HANDLE_DW_AT(0x3d, discr_list)
-HANDLE_DW_AT(0x3e, encoding)
-HANDLE_DW_AT(0x3f, external)
-HANDLE_DW_AT(0x40, frame_base)
-HANDLE_DW_AT(0x41, friend)
-HANDLE_DW_AT(0x42, identifier_case)
-HANDLE_DW_AT(0x43, macro_info)
-HANDLE_DW_AT(0x44, namelist_item)
-HANDLE_DW_AT(0x45, priority)
-HANDLE_DW_AT(0x46, segment)
-HANDLE_DW_AT(0x47, specification)
-HANDLE_DW_AT(0x48, static_link)
-HANDLE_DW_AT(0x49, type)
-HANDLE_DW_AT(0x4a, use_location)
-HANDLE_DW_AT(0x4b, variable_parameter)
-HANDLE_DW_AT(0x4c, virtuality)
-HANDLE_DW_AT(0x4d, vtable_elem_location)
-HANDLE_DW_AT(0x4e, allocated)
-HANDLE_DW_AT(0x4f, associated)
-HANDLE_DW_AT(0x50, data_location)
-HANDLE_DW_AT(0x51, byte_stride)
-HANDLE_DW_AT(0x52, entry_pc)
-HANDLE_DW_AT(0x53, use_UTF8)
-HANDLE_DW_AT(0x54, extension)
-HANDLE_DW_AT(0x55, ranges)
-HANDLE_DW_AT(0x56, trampoline)
-HANDLE_DW_AT(0x57, call_column)
-HANDLE_DW_AT(0x58, call_file)
-HANDLE_DW_AT(0x59, call_line)
-HANDLE_DW_AT(0x5a, description)
-HANDLE_DW_AT(0x5b, binary_scale)
-HANDLE_DW_AT(0x5c, decimal_scale)
-HANDLE_DW_AT(0x5d, small)
-HANDLE_DW_AT(0x5e, decimal_sign)
-HANDLE_DW_AT(0x5f, digit_count)
-HANDLE_DW_AT(0x60, picture_string)
-HANDLE_DW_AT(0x61, mutable)
-HANDLE_DW_AT(0x62, threads_scaled)
-HANDLE_DW_AT(0x63, explicit)
-HANDLE_DW_AT(0x64, object_pointer)
-HANDLE_DW_AT(0x65, endianity)
-HANDLE_DW_AT(0x66, elemental)
-HANDLE_DW_AT(0x67, pure)
-HANDLE_DW_AT(0x68, recursive)
-HANDLE_DW_AT(0x69, signature)
-HANDLE_DW_AT(0x6a, main_subprogram)
-HANDLE_DW_AT(0x6b, data_bit_offset)
-HANDLE_DW_AT(0x6c, const_expr)
-HANDLE_DW_AT(0x6d, enum_class)
-HANDLE_DW_AT(0x6e, linkage_name)
-
-// New in DWARF 5:
-HANDLE_DW_AT(0x6f, string_length_bit_size)
-HANDLE_DW_AT(0x70, string_length_byte_size)
-HANDLE_DW_AT(0x71, rank)
-HANDLE_DW_AT(0x72, str_offsets_base)
-HANDLE_DW_AT(0x73, addr_base)
-HANDLE_DW_AT(0x74, rnglists_base)
-HANDLE_DW_AT(0x75, dwo_id) ///< Retracted from DWARF 5.
-HANDLE_DW_AT(0x76, dwo_name)
-HANDLE_DW_AT(0x77, reference)
-HANDLE_DW_AT(0x78, rvalue_reference)
-HANDLE_DW_AT(0x79, macros)
-HANDLE_DW_AT(0x7a, call_all_calls)
-HANDLE_DW_AT(0x7b, call_all_source_calls)
-HANDLE_DW_AT(0x7c, call_all_tail_calls)
-HANDLE_DW_AT(0x7d, call_return_pc)
-HANDLE_DW_AT(0x7e, call_value)
-HANDLE_DW_AT(0x7f, call_origin)
-HANDLE_DW_AT(0x80, call_parameter)
-HANDLE_DW_AT(0x81, call_pc)
-HANDLE_DW_AT(0x82, call_tail_call)
-HANDLE_DW_AT(0x83, call_target)
-HANDLE_DW_AT(0x84, call_target_clobbered)
-HANDLE_DW_AT(0x85, call_data_location)
-HANDLE_DW_AT(0x86, call_data_value)
-HANDLE_DW_AT(0x87, noreturn)
-HANDLE_DW_AT(0x88, alignment)
-HANDLE_DW_AT(0x89, export_symbols)
-HANDLE_DW_AT(0x8a, deleted)
-HANDLE_DW_AT(0x8b, defaulted)
-HANDLE_DW_AT(0x8c, loclists_base)
-
-HANDLE_DW_AT(0x2002, MIPS_loop_begin)
-HANDLE_DW_AT(0x2003, MIPS_tail_loop_begin)
-HANDLE_DW_AT(0x2004, MIPS_epilog_begin)
-HANDLE_DW_AT(0x2005, MIPS_loop_unroll_factor)
-HANDLE_DW_AT(0x2006, MIPS_software_pipeline_depth)
-HANDLE_DW_AT(0x2007, MIPS_linkage_name)
-HANDLE_DW_AT(0x2008, MIPS_stride)
-HANDLE_DW_AT(0x2009, MIPS_abstract_name)
-HANDLE_DW_AT(0x200a, MIPS_clone_origin)
-HANDLE_DW_AT(0x200b, MIPS_has_inlines)
-HANDLE_DW_AT(0x200c, MIPS_stride_byte)
-HANDLE_DW_AT(0x200d, MIPS_stride_elem)
-HANDLE_DW_AT(0x200e, MIPS_ptr_dopetype)
-HANDLE_DW_AT(0x200f, MIPS_allocatable_dopetype)
-HANDLE_DW_AT(0x2010, MIPS_assumed_shape_dopetype)
-
-// This one appears to have only been implemented by Open64 for
-// fortran and may conflict with other extensions.
-HANDLE_DW_AT(0x2011, MIPS_assumed_size)
-
-// GNU extensions
-HANDLE_DW_AT(0x2101, sf_names)
-HANDLE_DW_AT(0x2102, src_info)
-HANDLE_DW_AT(0x2103, mac_info)
-HANDLE_DW_AT(0x2104, src_coords)
-HANDLE_DW_AT(0x2105, body_begin)
-HANDLE_DW_AT(0x2106, body_end)
-HANDLE_DW_AT(0x2107, GNU_vector)
-HANDLE_DW_AT(0x2110, GNU_template_name)
-
-HANDLE_DW_AT(0x210f, GNU_odr_signature)
-HANDLE_DW_AT(0x2119, GNU_macros)
-
-// Extensions for Fission proposal.
-HANDLE_DW_AT(0x2130, GNU_dwo_name)
-HANDLE_DW_AT(0x2131, GNU_dwo_id)
-HANDLE_DW_AT(0x2132, GNU_ranges_base)
-HANDLE_DW_AT(0x2133, GNU_addr_base)
-HANDLE_DW_AT(0x2134, GNU_pubnames)
-HANDLE_DW_AT(0x2135, GNU_pubtypes)
-HANDLE_DW_AT(0x2136, GNU_discriminator)
-
-// Borland extensions.
-HANDLE_DW_AT(0x3b11, BORLAND_property_read)
-HANDLE_DW_AT(0x3b12, BORLAND_property_write)
-HANDLE_DW_AT(0x3b13, BORLAND_property_implements)
-HANDLE_DW_AT(0x3b14, BORLAND_property_index)
-HANDLE_DW_AT(0x3b15, BORLAND_property_default)
-HANDLE_DW_AT(0x3b20, BORLAND_Delphi_unit)
-HANDLE_DW_AT(0x3b21, BORLAND_Delphi_class)
-HANDLE_DW_AT(0x3b22, BORLAND_Delphi_record)
-HANDLE_DW_AT(0x3b23, BORLAND_Delphi_metaclass)
-HANDLE_DW_AT(0x3b24, BORLAND_Delphi_constructor)
-HANDLE_DW_AT(0x3b25, BORLAND_Delphi_destructor)
-HANDLE_DW_AT(0x3b26, BORLAND_Delphi_anonymous_method)
-HANDLE_DW_AT(0x3b27, BORLAND_Delphi_interface)
-HANDLE_DW_AT(0x3b28, BORLAND_Delphi_ABI)
-HANDLE_DW_AT(0x3b29, BORLAND_Delphi_return)
-HANDLE_DW_AT(0x3b30, BORLAND_Delphi_frameptr)
-HANDLE_DW_AT(0x3b31, BORLAND_closure)
-
-// LLVM project extensions.
-HANDLE_DW_AT(0x3e00, LLVM_include_path)
-HANDLE_DW_AT(0x3e01, LLVM_config_macros)
-HANDLE_DW_AT(0x3e02, LLVM_isysroot)
-
-// Apple extensions.
-HANDLE_DW_AT(0x3fe1, APPLE_optimized)
-HANDLE_DW_AT(0x3fe2, APPLE_flags)
-HANDLE_DW_AT(0x3fe3, APPLE_isa)
-HANDLE_DW_AT(0x3fe4, APPLE_block)
-HANDLE_DW_AT(0x3fe5, APPLE_major_runtime_vers)
-HANDLE_DW_AT(0x3fe6, APPLE_runtime_class)
-HANDLE_DW_AT(0x3fe7, APPLE_omit_frame_ptr)
-HANDLE_DW_AT(0x3fe8, APPLE_property_name)
-HANDLE_DW_AT(0x3fe9, APPLE_property_getter)
-HANDLE_DW_AT(0x3fea, APPLE_property_setter)
-HANDLE_DW_AT(0x3feb, APPLE_property_attribute)
-HANDLE_DW_AT(0x3fec, APPLE_objc_complete_type)
-HANDLE_DW_AT(0x3fed, APPLE_property)
-
-// Attribute form encodings.
-HANDLE_DW_FORM(0x01, addr)
-HANDLE_DW_FORM(0x03, block2)
-HANDLE_DW_FORM(0x04, block4)
-HANDLE_DW_FORM(0x05, data2)
-HANDLE_DW_FORM(0x06, data4)
-HANDLE_DW_FORM(0x07, data8)
-HANDLE_DW_FORM(0x08, string)
-HANDLE_DW_FORM(0x09, block)
-HANDLE_DW_FORM(0x0a, block1)
-HANDLE_DW_FORM(0x0b, data1)
-HANDLE_DW_FORM(0x0c, flag)
-HANDLE_DW_FORM(0x0d, sdata)
-HANDLE_DW_FORM(0x0e, strp)
-HANDLE_DW_FORM(0x0f, udata)
-HANDLE_DW_FORM(0x10, ref_addr)
-HANDLE_DW_FORM(0x11, ref1)
-HANDLE_DW_FORM(0x12, ref2)
-HANDLE_DW_FORM(0x13, ref4)
-HANDLE_DW_FORM(0x14, ref8)
-HANDLE_DW_FORM(0x15, ref_udata)
-HANDLE_DW_FORM(0x16, indirect)
-HANDLE_DW_FORM(0x17, sec_offset)
-HANDLE_DW_FORM(0x18, exprloc)
-HANDLE_DW_FORM(0x19, flag_present)
-
-// New in DWARF v5.
-HANDLE_DW_FORM(0x1a, strx)
-HANDLE_DW_FORM(0x1b, addrx)
-HANDLE_DW_FORM(0x1c, ref_sup)
-HANDLE_DW_FORM(0x1d, strp_sup)
-HANDLE_DW_FORM(0x1e, data16)
-HANDLE_DW_FORM(0x1f, line_strp)
-HANDLE_DW_FORM(0x20, ref_sig8)
-HANDLE_DW_FORM(0x21, implicit_const)
-HANDLE_DW_FORM(0x22, loclistx)
-HANDLE_DW_FORM(0x23, rnglistx)
-
-// Extensions for Fission proposal
-HANDLE_DW_FORM(0x1f01, GNU_addr_index)
-HANDLE_DW_FORM(0x1f02, GNU_str_index)
-
-// Alternate debug sections proposal (output of "dwz" tool).
-HANDLE_DW_FORM(0x1f20, GNU_ref_alt)
-HANDLE_DW_FORM(0x1f21, GNU_strp_alt)
-
-// DWARF Expression operators.
-HANDLE_DW_OP(0x03, addr)
-HANDLE_DW_OP(0x06, deref)
-HANDLE_DW_OP(0x08, const1u)
-HANDLE_DW_OP(0x09, const1s)
-HANDLE_DW_OP(0x0a, const2u)
-HANDLE_DW_OP(0x0b, const2s)
-HANDLE_DW_OP(0x0c, const4u)
-HANDLE_DW_OP(0x0d, const4s)
-HANDLE_DW_OP(0x0e, const8u)
-HANDLE_DW_OP(0x0f, const8s)
-HANDLE_DW_OP(0x10, constu)
-HANDLE_DW_OP(0x11, consts)
-HANDLE_DW_OP(0x12, dup)
-HANDLE_DW_OP(0x13, drop)
-HANDLE_DW_OP(0x14, over)
-HANDLE_DW_OP(0x15, pick)
-HANDLE_DW_OP(0x16, swap)
-HANDLE_DW_OP(0x17, rot)
-HANDLE_DW_OP(0x18, xderef)
-HANDLE_DW_OP(0x19, abs)
-HANDLE_DW_OP(0x1a, and)
-HANDLE_DW_OP(0x1b, div)
-HANDLE_DW_OP(0x1c, minus)
-HANDLE_DW_OP(0x1d, mod)
-HANDLE_DW_OP(0x1e, mul)
-HANDLE_DW_OP(0x1f, neg)
-HANDLE_DW_OP(0x20, not)
-HANDLE_DW_OP(0x21, or)
-HANDLE_DW_OP(0x22, plus)
-HANDLE_DW_OP(0x23, plus_uconst)
-HANDLE_DW_OP(0x24, shl)
-HANDLE_DW_OP(0x25, shr)
-HANDLE_DW_OP(0x26, shra)
-HANDLE_DW_OP(0x27, xor)
-HANDLE_DW_OP(0x2f, skip)
-HANDLE_DW_OP(0x28, bra)
-HANDLE_DW_OP(0x29, eq)
-HANDLE_DW_OP(0x2a, ge)
-HANDLE_DW_OP(0x2b, gt)
-HANDLE_DW_OP(0x2c, le)
-HANDLE_DW_OP(0x2d, lt)
-HANDLE_DW_OP(0x2e, ne)
-HANDLE_DW_OP(0x30, lit0)
-HANDLE_DW_OP(0x31, lit1)
-HANDLE_DW_OP(0x32, lit2)
-HANDLE_DW_OP(0x33, lit3)
-HANDLE_DW_OP(0x34, lit4)
-HANDLE_DW_OP(0x35, lit5)
-HANDLE_DW_OP(0x36, lit6)
-HANDLE_DW_OP(0x37, lit7)
-HANDLE_DW_OP(0x38, lit8)
-HANDLE_DW_OP(0x39, lit9)
-HANDLE_DW_OP(0x3a, lit10)
-HANDLE_DW_OP(0x3b, lit11)
-HANDLE_DW_OP(0x3c, lit12)
-HANDLE_DW_OP(0x3d, lit13)
-HANDLE_DW_OP(0x3e, lit14)
-HANDLE_DW_OP(0x3f, lit15)
-HANDLE_DW_OP(0x40, lit16)
-HANDLE_DW_OP(0x41, lit17)
-HANDLE_DW_OP(0x42, lit18)
-HANDLE_DW_OP(0x43, lit19)
-HANDLE_DW_OP(0x44, lit20)
-HANDLE_DW_OP(0x45, lit21)
-HANDLE_DW_OP(0x46, lit22)
-HANDLE_DW_OP(0x47, lit23)
-HANDLE_DW_OP(0x48, lit24)
-HANDLE_DW_OP(0x49, lit25)
-HANDLE_DW_OP(0x4a, lit26)
-HANDLE_DW_OP(0x4b, lit27)
-HANDLE_DW_OP(0x4c, lit28)
-HANDLE_DW_OP(0x4d, lit29)
-HANDLE_DW_OP(0x4e, lit30)
-HANDLE_DW_OP(0x4f, lit31)
-HANDLE_DW_OP(0x50, reg0)
-HANDLE_DW_OP(0x51, reg1)
-HANDLE_DW_OP(0x52, reg2)
-HANDLE_DW_OP(0x53, reg3)
-HANDLE_DW_OP(0x54, reg4)
-HANDLE_DW_OP(0x55, reg5)
-HANDLE_DW_OP(0x56, reg6)
-HANDLE_DW_OP(0x57, reg7)
-HANDLE_DW_OP(0x58, reg8)
-HANDLE_DW_OP(0x59, reg9)
-HANDLE_DW_OP(0x5a, reg10)
-HANDLE_DW_OP(0x5b, reg11)
-HANDLE_DW_OP(0x5c, reg12)
-HANDLE_DW_OP(0x5d, reg13)
-HANDLE_DW_OP(0x5e, reg14)
-HANDLE_DW_OP(0x5f, reg15)
-HANDLE_DW_OP(0x60, reg16)
-HANDLE_DW_OP(0x61, reg17)
-HANDLE_DW_OP(0x62, reg18)
-HANDLE_DW_OP(0x63, reg19)
-HANDLE_DW_OP(0x64, reg20)
-HANDLE_DW_OP(0x65, reg21)
-HANDLE_DW_OP(0x66, reg22)
-HANDLE_DW_OP(0x67, reg23)
-HANDLE_DW_OP(0x68, reg24)
-HANDLE_DW_OP(0x69, reg25)
-HANDLE_DW_OP(0x6a, reg26)
-HANDLE_DW_OP(0x6b, reg27)
-HANDLE_DW_OP(0x6c, reg28)
-HANDLE_DW_OP(0x6d, reg29)
-HANDLE_DW_OP(0x6e, reg30)
-HANDLE_DW_OP(0x6f, reg31)
-HANDLE_DW_OP(0x70, breg0)
-HANDLE_DW_OP(0x71, breg1)
-HANDLE_DW_OP(0x72, breg2)
-HANDLE_DW_OP(0x73, breg3)
-HANDLE_DW_OP(0x74, breg4)
-HANDLE_DW_OP(0x75, breg5)
-HANDLE_DW_OP(0x76, breg6)
-HANDLE_DW_OP(0x77, breg7)
-HANDLE_DW_OP(0x78, breg8)
-HANDLE_DW_OP(0x79, breg9)
-HANDLE_DW_OP(0x7a, breg10)
-HANDLE_DW_OP(0x7b, breg11)
-HANDLE_DW_OP(0x7c, breg12)
-HANDLE_DW_OP(0x7d, breg13)
-HANDLE_DW_OP(0x7e, breg14)
-HANDLE_DW_OP(0x7f, breg15)
-HANDLE_DW_OP(0x80, breg16)
-HANDLE_DW_OP(0x81, breg17)
-HANDLE_DW_OP(0x82, breg18)
-HANDLE_DW_OP(0x83, breg19)
-HANDLE_DW_OP(0x84, breg20)
-HANDLE_DW_OP(0x85, breg21)
-HANDLE_DW_OP(0x86, breg22)
-HANDLE_DW_OP(0x87, breg23)
-HANDLE_DW_OP(0x88, breg24)
-HANDLE_DW_OP(0x89, breg25)
-HANDLE_DW_OP(0x8a, breg26)
-HANDLE_DW_OP(0x8b, breg27)
-HANDLE_DW_OP(0x8c, breg28)
-HANDLE_DW_OP(0x8d, breg29)
-HANDLE_DW_OP(0x8e, breg30)
-HANDLE_DW_OP(0x8f, breg31)
-HANDLE_DW_OP(0x90, regx)
-HANDLE_DW_OP(0x91, fbreg)
-HANDLE_DW_OP(0x92, bregx)
-HANDLE_DW_OP(0x93, piece)
-HANDLE_DW_OP(0x94, deref_size)
-HANDLE_DW_OP(0x95, xderef_size)
-HANDLE_DW_OP(0x96, nop)
-HANDLE_DW_OP(0x97, push_object_address)
-HANDLE_DW_OP(0x98, call2)
-HANDLE_DW_OP(0x99, call4)
-HANDLE_DW_OP(0x9a, call_ref)
-HANDLE_DW_OP(0x9b, form_tls_address)
-HANDLE_DW_OP(0x9c, call_frame_cfa)
-HANDLE_DW_OP(0x9d, bit_piece)
-HANDLE_DW_OP(0x9e, implicit_value)
-HANDLE_DW_OP(0x9f, stack_value)
-HANDLE_DW_OP(0xa0, implicit_pointer)
-HANDLE_DW_OP(0xa1, addrx)
-HANDLE_DW_OP(0xa2, constx)
-HANDLE_DW_OP(0xa3, entry_value)
-HANDLE_DW_OP(0xa4, const_type)
-HANDLE_DW_OP(0xa5, regval_type)
-HANDLE_DW_OP(0xa6, deref_type)
-HANDLE_DW_OP(0xa7, xderef_type)
-HANDLE_DW_OP(0xa8, convert)
-HANDLE_DW_OP(0xa9, reinterpret)
-
-// Vendor extensions.
-// Extensions for GNU-style thread-local storage.
-HANDLE_DW_OP(0xe0, GNU_push_tls_address)
-
-// Extensions for Fission proposal.
-HANDLE_DW_OP(0xfb, GNU_addr_index)
-HANDLE_DW_OP(0xfc, GNU_const_index)
-
-// DWARF languages.
-HANDLE_DW_LANG(0x0001, C89)
-HANDLE_DW_LANG(0x0002, C)
-HANDLE_DW_LANG(0x0003, Ada83)
-HANDLE_DW_LANG(0x0004, C_plus_plus)
-HANDLE_DW_LANG(0x0005, Cobol74)
-HANDLE_DW_LANG(0x0006, Cobol85)
-HANDLE_DW_LANG(0x0007, Fortran77)
-HANDLE_DW_LANG(0x0008, Fortran90)
-HANDLE_DW_LANG(0x0009, Pascal83)
-HANDLE_DW_LANG(0x000a, Modula2)
-HANDLE_DW_LANG(0x000b, Java)
-HANDLE_DW_LANG(0x000c, C99)
-HANDLE_DW_LANG(0x000d, Ada95)
-HANDLE_DW_LANG(0x000e, Fortran95)
-HANDLE_DW_LANG(0x000f, PLI)
-HANDLE_DW_LANG(0x0010, ObjC)
-HANDLE_DW_LANG(0x0011, ObjC_plus_plus)
-HANDLE_DW_LANG(0x0012, UPC)
-HANDLE_DW_LANG(0x0013, D)
-
-// New in DWARF 5:
-HANDLE_DW_LANG(0x0014, Python)
-HANDLE_DW_LANG(0x0015, OpenCL)
-HANDLE_DW_LANG(0x0016, Go)
-HANDLE_DW_LANG(0x0017, Modula3)
-HANDLE_DW_LANG(0x0018, Haskell)
-HANDLE_DW_LANG(0x0019, C_plus_plus_03)
-HANDLE_DW_LANG(0x001a, C_plus_plus_11)
-HANDLE_DW_LANG(0x001b, OCaml)
-HANDLE_DW_LANG(0x001c, Rust)
-HANDLE_DW_LANG(0x001d, C11)
-HANDLE_DW_LANG(0x001e, Swift)
-HANDLE_DW_LANG(0x001f, Julia)
-HANDLE_DW_LANG(0x0020, Dylan)
-HANDLE_DW_LANG(0x0021, C_plus_plus_14)
-HANDLE_DW_LANG(0x0022, Fortran03)
-HANDLE_DW_LANG(0x0023, Fortran08)
-HANDLE_DW_LANG(0x0024, RenderScript)
-
-// Vendor extensions.
-HANDLE_DW_LANG(0x8001, Mips_Assembler)
-HANDLE_DW_LANG(0x8e57, GOOGLE_RenderScript)
-HANDLE_DW_LANG(0xb000, BORLAND_Delphi)
-
-// DWARF attribute type encodings.
-HANDLE_DW_ATE(0x01, address)
-HANDLE_DW_ATE(0x02, boolean)
-HANDLE_DW_ATE(0x03, complex_float)
-HANDLE_DW_ATE(0x04, float)
-HANDLE_DW_ATE(0x05, signed)
-HANDLE_DW_ATE(0x06, signed_char)
-HANDLE_DW_ATE(0x07, unsigned)
-HANDLE_DW_ATE(0x08, unsigned_char)
-HANDLE_DW_ATE(0x09, imaginary_float)
-HANDLE_DW_ATE(0x0a, packed_decimal)
-HANDLE_DW_ATE(0x0b, numeric_string)
-HANDLE_DW_ATE(0x0c, edited)
-HANDLE_DW_ATE(0x0d, signed_fixed)
-HANDLE_DW_ATE(0x0e, unsigned_fixed)
-HANDLE_DW_ATE(0x0f, decimal_float)
-HANDLE_DW_ATE(0x10, UTF)
-HANDLE_DW_ATE(0x11, UCS)
-HANDLE_DW_ATE(0x12, ASCII)
-
-// DWARF virtuality codes.
-HANDLE_DW_VIRTUALITY(0x00, none)
-HANDLE_DW_VIRTUALITY(0x01, virtual)
-HANDLE_DW_VIRTUALITY(0x02, pure_virtual)
-
-// DWARF v5 Defaulted Member Encodings.
-HANDLE_DW_DEFAULTED(0x00, no)
-HANDLE_DW_DEFAULTED(0x01, in_class)
-HANDLE_DW_DEFAULTED(0x02, out_of_class)
-
-// DWARF calling convention codes.
-HANDLE_DW_CC(0x01, normal)
-HANDLE_DW_CC(0x02, program)
-HANDLE_DW_CC(0x03, nocall)
-HANDLE_DW_CC(0x04, pass_by_reference)
-HANDLE_DW_CC(0x05, pass_by_value)
-HANDLE_DW_CC(0x41, GNU_borland_fastcall_i386)
-HANDLE_DW_CC(0xb0, BORLAND_safecall)
-HANDLE_DW_CC(0xb1, BORLAND_stdcall)
-HANDLE_DW_CC(0xb2, BORLAND_pascal)
-HANDLE_DW_CC(0xb3, BORLAND_msfastcall)
-HANDLE_DW_CC(0xb4, BORLAND_msreturn)
-HANDLE_DW_CC(0xb5, BORLAND_thiscall)
-HANDLE_DW_CC(0xb6, BORLAND_fastcall)
-HANDLE_DW_CC(0xc0, LLVM_vectorcall)
-
-// Line Number Extended Opcode Encodings
-HANDLE_DW_LNE(0x01, end_sequence)
-HANDLE_DW_LNE(0x02, set_address)
-HANDLE_DW_LNE(0x03, define_file)
-HANDLE_DW_LNE(0x04, set_discriminator)
-
-// Line Number Standard Opcode Encodings.
-HANDLE_DW_LNS(0x00, extended_op)
-HANDLE_DW_LNS(0x01, copy)
-HANDLE_DW_LNS(0x02, advance_pc)
-HANDLE_DW_LNS(0x03, advance_line)
-HANDLE_DW_LNS(0x04, set_file)
-HANDLE_DW_LNS(0x05, set_column)
-HANDLE_DW_LNS(0x06, negate_stmt)
-HANDLE_DW_LNS(0x07, set_basic_block)
-HANDLE_DW_LNS(0x08, const_add_pc)
-HANDLE_DW_LNS(0x09, fixed_advance_pc)
-HANDLE_DW_LNS(0x0a, set_prologue_end)
-HANDLE_DW_LNS(0x0b, set_epilogue_begin)
-HANDLE_DW_LNS(0x0c, set_isa)
-
-// DWARF v5 Line number header entry format.
-HANDLE_DW_LNCT(0x01, path)
-HANDLE_DW_LNCT(0x02, directory_index)
-HANDLE_DW_LNCT(0x03, timestamp)
-HANDLE_DW_LNCT(0x04, size)
-HANDLE_DW_LNCT(0x05, MD5)
-
-HANDLE_DW_MACRO(0x01, define)
-HANDLE_DW_MACRO(0x02, undef)
-HANDLE_DW_MACRO(0x03, start_file)
-HANDLE_DW_MACRO(0x04, end_file)
-HANDLE_DW_MACRO(0x05, define_strp)
-HANDLE_DW_MACRO(0x06, undef_strp)
-HANDLE_DW_MACRO(0x07, import)
-HANDLE_DW_MACRO(0x08, define_sup)
-HANDLE_DW_MACRO(0x09, undef_sup)
-HANDLE_DW_MACRO(0x0a, import_sup)
-HANDLE_DW_MACRO(0x0b, define_strx)
-HANDLE_DW_MACRO(0x0c, undef_strx)
-
-// Range list entry encoding values.
-HANDLE_DW_RLE(0x00, end_of_list)
-HANDLE_DW_RLE(0x01, base_addressx)
-HANDLE_DW_RLE(0x02, startx_endx)
-HANDLE_DW_RLE(0x03, startx_length)
-HANDLE_DW_RLE(0x04, offset_pair)
-HANDLE_DW_RLE(0x05, base_address)
-HANDLE_DW_RLE(0x06, start_end)
-HANDLE_DW_RLE(0x07, start_length)
-
-// Call frame instruction encodings.
-HANDLE_DW_CFA(0x00, nop)
-HANDLE_DW_CFA(0x40, advance_loc)
-HANDLE_DW_CFA(0x80, offset)
-HANDLE_DW_CFA(0xc0, restore)
-HANDLE_DW_CFA(0x01, set_loc)
-HANDLE_DW_CFA(0x02, advance_loc1)
-HANDLE_DW_CFA(0x03, advance_loc2)
-HANDLE_DW_CFA(0x04, advance_loc4)
-HANDLE_DW_CFA(0x05, offset_extended)
-HANDLE_DW_CFA(0x06, restore_extended)
-HANDLE_DW_CFA(0x07, undefined)
-HANDLE_DW_CFA(0x08, same_value)
-HANDLE_DW_CFA(0x09, register)
-HANDLE_DW_CFA(0x0a, remember_state)
-HANDLE_DW_CFA(0x0b, restore_state)
-HANDLE_DW_CFA(0x0c, def_cfa)
-HANDLE_DW_CFA(0x0d, def_cfa_register)
-HANDLE_DW_CFA(0x0e, def_cfa_offset)
-HANDLE_DW_CFA(0x0f, def_cfa_expression)
-HANDLE_DW_CFA(0x10, expression)
-HANDLE_DW_CFA(0x11, offset_extended_sf)
-HANDLE_DW_CFA(0x12, def_cfa_sf)
-HANDLE_DW_CFA(0x13, def_cfa_offset_sf)
-HANDLE_DW_CFA(0x14, val_offset)
-HANDLE_DW_CFA(0x15, val_offset_sf)
-HANDLE_DW_CFA(0x16, val_expression)
-HANDLE_DW_CFA(0x1d, MIPS_advance_loc8)
-HANDLE_DW_CFA(0x2d, GNU_window_save)
-HANDLE_DW_CFA(0x2e, GNU_args_size)
-
-// Apple Objective-C Property Attributes.
-// Keep this list in sync with clang's DeclSpec.h ObjCPropertyAttributeKind!
-HANDLE_DW_APPLE_PROPERTY(0x01, readonly)
-HANDLE_DW_APPLE_PROPERTY(0x02, getter)
-HANDLE_DW_APPLE_PROPERTY(0x04, assign)
-HANDLE_DW_APPLE_PROPERTY(0x08, readwrite)
-HANDLE_DW_APPLE_PROPERTY(0x10, retain)
-HANDLE_DW_APPLE_PROPERTY(0x20, copy)
-HANDLE_DW_APPLE_PROPERTY(0x40, nonatomic)
-HANDLE_DW_APPLE_PROPERTY(0x80, setter)
-HANDLE_DW_APPLE_PROPERTY(0x100, atomic)
-HANDLE_DW_APPLE_PROPERTY(0x200, weak)
-HANDLE_DW_APPLE_PROPERTY(0x400, strong)
-HANDLE_DW_APPLE_PROPERTY(0x800, unsafe_unretained)
-HANDLE_DW_APPLE_PROPERTY(0x1000, nullability)
-HANDLE_DW_APPLE_PROPERTY(0x2000, null_resettable)
-HANDLE_DW_APPLE_PROPERTY(0x4000, class)
-
-
-#undef HANDLE_DW_TAG
-#undef HANDLE_DW_AT
-#undef HANDLE_DW_FORM
-#undef HANDLE_DW_OP
-#undef HANDLE_DW_LANG
-#undef HANDLE_DW_ATE
-#undef HANDLE_DW_VIRTUALITY
-#undef HANDLE_DW_DEFAULTED
-#undef HANDLE_DW_CC
-#undef HANDLE_DW_LNS
-#undef HANDLE_DW_LNE
-#undef HANDLE_DW_LNCT
-#undef HANDLE_DW_MACRO
-#undef HANDLE_DW_RLE
-#undef HANDLE_DW_CFA
-#undef HANDLE_DW_APPLE_PROPERTY
diff --git a/contrib/llvm/include/llvm/Support/DynamicLibrary.h b/contrib/llvm/include/llvm/Support/DynamicLibrary.h
index a7d2221..469d5df 100644
--- a/contrib/llvm/include/llvm/Support/DynamicLibrary.h
+++ b/contrib/llvm/include/llvm/Support/DynamicLibrary.h
@@ -58,7 +58,7 @@ namespace sys {
void *getAddressOfSymbol(const char *symbolName);
/// This function permanently loads the dynamic library at the given path.
- /// The library will only be unloaded when the program terminates.
+ /// The library will only be unloaded when llvm_shutdown() is called.
/// This returns a valid DynamicLibrary instance on success and an invalid
/// instance on failure (see isValid()). \p *errMsg will only be modified
/// if the library fails to load.
@@ -68,6 +68,16 @@ namespace sys {
static DynamicLibrary getPermanentLibrary(const char *filename,
std::string *errMsg = nullptr);
+ /// Registers an externally loaded library. The library will be unloaded
+ /// when the program terminates.
+ ///
+ /// It is safe to call this function multiple times for the same library,
+ /// though ownership is only taken if there was no error.
+ ///
+ /// \returns An empty \p DynamicLibrary if the library was already loaded.
+ static DynamicLibrary addPermanentLibrary(void *handle,
+ std::string *errMsg = nullptr);
+
/// This function permanently loads the dynamic library at the given path.
/// Use this instead of getPermanentLibrary() when you won't need to get
/// symbols from the library itself.
@@ -78,6 +88,22 @@ namespace sys {
return !getPermanentLibrary(Filename, ErrMsg).isValid();
}
+ enum SearchOrdering {
+ /// SO_Linker - Search as a call to dlsym(dlopen(NULL)) would when
+ /// DynamicLibrary::getPermanentLibrary(NULL) has been called or
+ /// search the list of explcitly loaded symbols if not.
+ SO_Linker,
+ /// SO_LoadedFirst - Search all loaded libraries, then as SO_Linker would.
+ SO_LoadedFirst,
+ /// SO_LoadedLast - Search as SO_Linker would, then loaded libraries.
+ /// Only useful to search if libraries with RTLD_LOCAL have been added.
+ SO_LoadedLast,
+ /// SO_LoadOrder - Or this in to search libraries in the ordered loaded.
+ /// The default bahaviour is to search loaded libraries in reverse.
+ SO_LoadOrder = 4
+ };
+ static SearchOrdering SearchOrder; // = SO_Linker
+
/// This function will search through all previously loaded dynamic
/// libraries for the symbol \p symbolName. If it is found, the address of
/// that symbol is returned. If not, null is returned. Note that this will
@@ -97,6 +123,8 @@ namespace sys {
/// libraries.
/// @brief Add searchable symbol/value pair.
static void AddSymbol(StringRef symbolName, void *symbolValue);
+
+ class HandleSet;
};
} // End sys namespace
diff --git a/contrib/llvm/include/llvm/Support/Endian.h b/contrib/llvm/include/llvm/Support/Endian.h
index cbe3d67..f50d9b5 100644
--- a/contrib/llvm/include/llvm/Support/Endian.h
+++ b/contrib/llvm/include/llvm/Support/Endian.h
@@ -14,67 +14,101 @@
#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>
+#include <cstdint>
+#include <cstring>
+#include <type_traits>
namespace llvm {
namespace support {
+
enum endianness {big, little, native};
// These are named values for common alignments.
enum {aligned = 0, unaligned = 1};
namespace detail {
- /// \brief ::value is either alignment, or alignof(T) if alignment is 0.
- template<class T, int alignment>
- struct PickAlignment {
- enum { value = alignment == 0 ? alignof(T) : alignment };
- };
+
+/// \brief ::value is either alignment, or alignof(T) if alignment is 0.
+template<class T, int alignment>
+struct PickAlignment {
+ enum { value = alignment == 0 ? alignof(T) : alignment };
+};
+
} // end namespace detail
namespace endian {
+
+constexpr endianness system_endianness() {
+ return sys::IsBigEndianHost ? big : little;
+}
+
+template <typename value_type>
+inline value_type byte_swap(value_type value, endianness endian) {
+ if ((endian != native) && (endian != system_endianness()))
+ sys::swapByteOrder(value);
+ return value;
+}
+
/// Swap the bytes of value to match the given endianness.
template<typename value_type, endianness endian>
inline value_type byte_swap(value_type value) {
- if (endian != native && sys::IsBigEndianHost != (endian == big))
- sys::swapByteOrder(value);
- return value;
+ return byte_swap(value, endian);
}
/// Read a value of a particular endianness from memory.
-template<typename value_type,
- endianness endian,
- std::size_t alignment>
-inline value_type read(const void *memory) {
+template <typename value_type, std::size_t alignment>
+inline value_type read(const void *memory, endianness endian) {
value_type ret;
memcpy(&ret,
- LLVM_ASSUME_ALIGNED(memory,
- (detail::PickAlignment<value_type, alignment>::value)),
+ LLVM_ASSUME_ALIGNED(
+ memory, (detail::PickAlignment<value_type, alignment>::value)),
sizeof(value_type));
- return byte_swap<value_type, endian>(ret);
+ return byte_swap<value_type>(ret, endian);
+}
+
+template<typename value_type,
+ endianness endian,
+ std::size_t alignment>
+inline value_type read(const void *memory) {
+ return read<value_type, alignment>(memory, endian);
}
/// Read a value of a particular endianness from a buffer, and increment the
/// buffer past that value.
+template <typename value_type, std::size_t alignment, typename CharT>
+inline value_type readNext(const CharT *&memory, endianness endian) {
+ value_type ret = read<value_type, alignment>(memory, endian);
+ memory += sizeof(value_type);
+ return ret;
+}
+
template<typename value_type, endianness endian, std::size_t alignment,
typename CharT>
inline value_type readNext(const CharT *&memory) {
- value_type ret = read<value_type, endian, alignment>(memory);
- memory += sizeof(value_type);
- return ret;
+ return readNext<value_type, alignment, CharT>(memory, endian);
}
/// Write a value to memory with a particular endianness.
+template <typename value_type, std::size_t alignment>
+inline void write(void *memory, value_type value, endianness endian) {
+ value = byte_swap<value_type>(value, endian);
+ memcpy(LLVM_ASSUME_ALIGNED(
+ memory, (detail::PickAlignment<value_type, alignment>::value)),
+ &value, sizeof(value_type));
+}
+
template<typename value_type,
endianness endian,
std::size_t alignment>
inline void write(void *memory, value_type value) {
- value = byte_swap<value_type, endian>(value);
- memcpy(LLVM_ASSUME_ALIGNED(memory,
- (detail::PickAlignment<value_type, alignment>::value)),
- &value,
- sizeof(value_type));
+ write<value_type, alignment>(memory, value, endian);
}
template <typename value_type>
@@ -165,9 +199,11 @@ inline void writeAtBitAlignment(void *memory, value_type value,
&val[0], sizeof(value_type) * 2);
}
}
+
} // end namespace endian
namespace detail {
+
template<typename value_type,
endianness endian,
std::size_t alignment>
@@ -229,81 +265,96 @@ public:
} // end namespace detail
-typedef detail::packed_endian_specific_integral
- <uint16_t, little, unaligned> ulittle16_t;
-typedef detail::packed_endian_specific_integral
- <uint32_t, little, unaligned> ulittle32_t;
-typedef detail::packed_endian_specific_integral
- <uint64_t, little, unaligned> ulittle64_t;
-
-typedef detail::packed_endian_specific_integral
- <int16_t, little, unaligned> little16_t;
-typedef detail::packed_endian_specific_integral
- <int32_t, little, unaligned> little32_t;
-typedef detail::packed_endian_specific_integral
- <int64_t, little, unaligned> little64_t;
-
-typedef detail::packed_endian_specific_integral
- <uint16_t, little, aligned> aligned_ulittle16_t;
-typedef detail::packed_endian_specific_integral
- <uint32_t, little, aligned> aligned_ulittle32_t;
-typedef detail::packed_endian_specific_integral
- <uint64_t, little, aligned> aligned_ulittle64_t;
-
-typedef detail::packed_endian_specific_integral
- <int16_t, little, aligned> aligned_little16_t;
-typedef detail::packed_endian_specific_integral
- <int32_t, little, aligned> aligned_little32_t;
-typedef detail::packed_endian_specific_integral
- <int64_t, little, aligned> aligned_little64_t;
-
-typedef detail::packed_endian_specific_integral
- <uint16_t, big, unaligned> ubig16_t;
-typedef detail::packed_endian_specific_integral
- <uint32_t, big, unaligned> ubig32_t;
-typedef detail::packed_endian_specific_integral
- <uint64_t, big, unaligned> ubig64_t;
-
-typedef detail::packed_endian_specific_integral
- <int16_t, big, unaligned> big16_t;
-typedef detail::packed_endian_specific_integral
- <int32_t, big, unaligned> big32_t;
-typedef detail::packed_endian_specific_integral
- <int64_t, big, unaligned> big64_t;
-
-typedef detail::packed_endian_specific_integral
- <uint16_t, big, aligned> aligned_ubig16_t;
-typedef detail::packed_endian_specific_integral
- <uint32_t, big, aligned> aligned_ubig32_t;
-typedef detail::packed_endian_specific_integral
- <uint64_t, big, aligned> aligned_ubig64_t;
-
-typedef detail::packed_endian_specific_integral
- <int16_t, big, aligned> aligned_big16_t;
-typedef detail::packed_endian_specific_integral
- <int32_t, big, aligned> aligned_big32_t;
-typedef detail::packed_endian_specific_integral
- <int64_t, big, aligned> aligned_big64_t;
-
-typedef detail::packed_endian_specific_integral
- <uint16_t, native, unaligned> unaligned_uint16_t;
-typedef detail::packed_endian_specific_integral
- <uint32_t, native, unaligned> unaligned_uint32_t;
-typedef detail::packed_endian_specific_integral
- <uint64_t, native, unaligned> unaligned_uint64_t;
-
-typedef detail::packed_endian_specific_integral
- <int16_t, native, unaligned> unaligned_int16_t;
-typedef detail::packed_endian_specific_integral
- <int32_t, native, unaligned> unaligned_int32_t;
-typedef detail::packed_endian_specific_integral
- <int64_t, native, unaligned> unaligned_int64_t;
+using ulittle16_t =
+ detail::packed_endian_specific_integral<uint16_t, little, unaligned>;
+using ulittle32_t =
+ detail::packed_endian_specific_integral<uint32_t, little, unaligned>;
+using ulittle64_t =
+ detail::packed_endian_specific_integral<uint64_t, little, unaligned>;
+
+using little16_t =
+ detail::packed_endian_specific_integral<int16_t, little, unaligned>;
+using little32_t =
+ detail::packed_endian_specific_integral<int32_t, little, unaligned>;
+using little64_t =
+ detail::packed_endian_specific_integral<int64_t, little, unaligned>;
+
+using aligned_ulittle16_t =
+ detail::packed_endian_specific_integral<uint16_t, little, aligned>;
+using aligned_ulittle32_t =
+ detail::packed_endian_specific_integral<uint32_t, little, aligned>;
+using aligned_ulittle64_t =
+ detail::packed_endian_specific_integral<uint64_t, little, aligned>;
+
+using aligned_little16_t =
+ detail::packed_endian_specific_integral<int16_t, little, aligned>;
+using aligned_little32_t =
+ detail::packed_endian_specific_integral<int32_t, little, aligned>;
+using aligned_little64_t =
+ detail::packed_endian_specific_integral<int64_t, little, aligned>;
+
+using ubig16_t =
+ detail::packed_endian_specific_integral<uint16_t, big, unaligned>;
+using ubig32_t =
+ detail::packed_endian_specific_integral<uint32_t, big, unaligned>;
+using ubig64_t =
+ detail::packed_endian_specific_integral<uint64_t, big, unaligned>;
+
+using big16_t =
+ detail::packed_endian_specific_integral<int16_t, big, unaligned>;
+using big32_t =
+ detail::packed_endian_specific_integral<int32_t, big, unaligned>;
+using big64_t =
+ detail::packed_endian_specific_integral<int64_t, big, unaligned>;
+
+using aligned_ubig16_t =
+ detail::packed_endian_specific_integral<uint16_t, big, aligned>;
+using aligned_ubig32_t =
+ detail::packed_endian_specific_integral<uint32_t, big, aligned>;
+using aligned_ubig64_t =
+ detail::packed_endian_specific_integral<uint64_t, big, aligned>;
+
+using aligned_big16_t =
+ detail::packed_endian_specific_integral<int16_t, big, aligned>;
+using aligned_big32_t =
+ detail::packed_endian_specific_integral<int32_t, big, aligned>;
+using aligned_big64_t =
+ detail::packed_endian_specific_integral<int64_t, big, aligned>;
+
+using unaligned_uint16_t =
+ detail::packed_endian_specific_integral<uint16_t, native, unaligned>;
+using unaligned_uint32_t =
+ detail::packed_endian_specific_integral<uint32_t, native, unaligned>;
+using unaligned_uint64_t =
+ detail::packed_endian_specific_integral<uint64_t, native, unaligned>;
+
+using unaligned_int16_t =
+ detail::packed_endian_specific_integral<int16_t, native, unaligned>;
+using unaligned_int32_t =
+ detail::packed_endian_specific_integral<int32_t, native, unaligned>;
+using unaligned_int64_t =
+ detail::packed_endian_specific_integral<int64_t, native, unaligned>;
namespace endian {
+
+template <typename T> inline T read(const void *P, endianness E) {
+ return read<T, unaligned>(P, E);
+}
+
template <typename T, endianness E> inline T read(const void *P) {
return *(const detail::packed_endian_specific_integral<T, E, unaligned> *)P;
}
+inline uint16_t read16(const void *P, endianness E) {
+ return read<uint16_t>(P, E);
+}
+inline uint32_t read32(const void *P, endianness E) {
+ return read<uint32_t>(P, E);
+}
+inline uint64_t read64(const void *P, endianness E) {
+ return read<uint64_t>(P, E);
+}
+
template <endianness E> inline uint16_t read16(const void *P) {
return read<uint16_t, E>(P);
}
@@ -321,10 +372,24 @@ inline uint16_t read16be(const void *P) { return read16<big>(P); }
inline uint32_t read32be(const void *P) { return read32<big>(P); }
inline uint64_t read64be(const void *P) { return read64<big>(P); }
+template <typename T> inline void write(void *P, T V, endianness E) {
+ write<T, unaligned>(P, V, E);
+}
+
template <typename T, endianness E> inline void write(void *P, T V) {
*(detail::packed_endian_specific_integral<T, E, unaligned> *)P = V;
}
+inline void write16(void *P, uint16_t V, endianness E) {
+ write<uint16_t>(P, V, E);
+}
+inline void write32(void *P, uint32_t V, endianness E) {
+ write<uint32_t>(P, V, E);
+}
+inline void write64(void *P, uint64_t V, endianness E) {
+ write<uint64_t>(P, V, E);
+}
+
template <endianness E> inline void write16(void *P, uint16_t V) {
write<uint16_t, E>(P, V);
}
@@ -341,8 +406,10 @@ inline void write64le(void *P, uint64_t V) { write64<little>(P, V); }
inline void write16be(void *P, uint16_t V) { write16<big>(P, V); }
inline void write32be(void *P, uint32_t V) { write32<big>(P, V); }
inline void write64be(void *P, uint64_t V) { write64<big>(P, V); }
+
} // end namespace endian
+
} // end namespace support
} // end namespace llvm
-#endif
+#endif // LLVM_SUPPORT_ENDIAN_H
diff --git a/contrib/llvm/include/llvm/Support/Errno.h b/contrib/llvm/include/llvm/Support/Errno.h
index 8e145c7..35dc1ea 100644
--- a/contrib/llvm/include/llvm/Support/Errno.h
+++ b/contrib/llvm/include/llvm/Support/Errno.h
@@ -14,7 +14,9 @@
#ifndef LLVM_SUPPORT_ERRNO_H
#define LLVM_SUPPORT_ERRNO_H
+#include <cerrno>
#include <string>
+#include <type_traits>
namespace llvm {
namespace sys {
@@ -28,6 +30,16 @@ std::string StrError();
/// Like the no-argument version above, but uses \p errnum instead of errno.
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...)) {
+ decltype(F(As...)) Res;
+ do
+ Res = F(As...);
+ while (Res == Fail && errno == EINTR);
+ return Res;
+}
+
} // namespace sys
} // namespace llvm
diff --git a/contrib/llvm/include/llvm/Support/Error.h b/contrib/llvm/include/llvm/Support/Error.h
index f13c948..9a7fa0a 100644
--- a/contrib/llvm/include/llvm/Support/Error.h
+++ b/contrib/llvm/include/llvm/Support/Error.h
@@ -1,4 +1,4 @@
-//===----- llvm/Support/Error.h - Recoverable error handling ----*- C++ -*-===//
+//===- llvm/Support/Error.h - Recoverable error handling --------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -22,6 +22,7 @@
#include "llvm/Support/AlignOf.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
+#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/ErrorOr.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
@@ -64,6 +65,12 @@ public:
/// using std::error_code. It will be removed in the future.
virtual std::error_code convertToErrorCode() const = 0;
+ // Returns the class ID for this type.
+ static const void *classID() { return &ID; }
+
+ // Returns the class ID for the dynamic type of this ErrorInfoBase instance.
+ virtual const void *dynamicClassID() const = 0;
+
// Check whether this instance is a subclass of the class identified by
// ClassID.
virtual bool isA(const void *const ClassID) const {
@@ -75,9 +82,6 @@ public:
return isA(ErrorInfoT::classID());
}
- // Returns the class ID for this type.
- static const void *classID() { return &ID; }
-
private:
virtual void anchor();
@@ -164,7 +168,7 @@ class LLVM_NODISCARD Error {
protected:
/// Create a success value. Prefer using 'Error::success()' for readability
- Error() : Payload(nullptr) {
+ Error() {
setPtr(nullptr);
setChecked(false);
}
@@ -179,7 +183,7 @@ public:
/// Move-construct an error value. The newly constructed error is considered
/// unchecked, even if the source error had been checked. The original error
/// becomes a checked Success value, regardless of its original state.
- Error(Error &&Other) : Payload(nullptr) {
+ Error(Error &&Other) {
setChecked(true);
*this = std::move(Other);
}
@@ -233,6 +237,14 @@ public:
return getPtr() && getPtr()->isA(ErrT::classID());
}
+ /// Returns the dynamic class id of this error, or null if this is a success
+ /// value.
+ const void* dynamicClassID() const {
+ if (!getPtr())
+ return nullptr;
+ return getPtr()->dynamicClassID();
+ }
+
private:
void assertIsChecked() {
#if LLVM_ENABLE_ABI_BREAKING_CHECKS
@@ -288,7 +300,7 @@ private:
return Tmp;
}
- ErrorInfoBase *Payload;
+ ErrorInfoBase *Payload = nullptr;
};
/// Subclass of Error for the sole purpose of identifying the success path in
@@ -316,11 +328,13 @@ template <typename ErrT, typename... ArgTs> Error make_error(ArgTs &&... Args) {
template <typename ThisErrT, typename ParentErrT = ErrorInfoBase>
class ErrorInfo : public ParentErrT {
public:
+ static const void *classID() { return &ThisErrT::ID; }
+
+ const void *dynamicClassID() const override { return &ThisErrT::ID; }
+
bool isA(const void *const ClassID) const override {
return ClassID == classID() || ParentErrT::isA(ClassID);
}
-
- static const void *classID() { return &ThisErrT::ID; }
};
/// Special ErrorInfo subclass representing a list of ErrorInfos.
@@ -629,21 +643,24 @@ private:
/// takeError(). It also adds an bool errorIsA<ErrT>() method for testing the
/// error class type.
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;
- typedef ReferenceStorage<typename std::remove_reference<T>::type> wrap;
- typedef std::unique_ptr<ErrorInfoBase> error_type;
+ using wrap = ReferenceStorage<typename std::remove_reference<T>::type>;
+
+ using error_type = std::unique_ptr<ErrorInfoBase>;
public:
- typedef typename std::conditional<isRef, wrap, T>::type storage_type;
- typedef T value_type;
+ using storage_type = typename std::conditional<isRef, wrap, T>::type;
+ using value_type = T;
private:
- typedef typename std::remove_reference<T>::type &reference;
- typedef const typename std::remove_reference<T>::type &const_reference;
- typedef typename std::remove_reference<T>::type *pointer;
- typedef const typename std::remove_reference<T>::type *const_pointer;
+ 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 *;
public:
/// Create an Expected<T> error value from the given Error.
@@ -737,7 +754,7 @@ public:
/// \brief Check that this Expected<T> is an error of type ErrT.
template <typename ErrT> bool errorIsA() const {
- return HasError && getErrorStorage()->template isA<ErrT>();
+ return HasError && (*getErrorStorage())->template isA<ErrT>();
}
/// \brief Take ownership of the stored error.
@@ -832,6 +849,18 @@ private:
return reinterpret_cast<error_type *>(ErrorStorage.buffer);
}
+ const error_type *getErrorStorage() const {
+ assert(HasError && "Cannot get error when a value exists!");
+ return reinterpret_cast<const error_type *>(ErrorStorage.buffer);
+ }
+
+ // Used by ExpectedAsOutParameter to reset the checked flag.
+ void setUnchecked() {
+#if LLVM_ENABLE_ABI_BREAKING_CHECKS
+ Unchecked = true;
+#endif
+ }
+
void assertIsChecked() {
#if LLVM_ENABLE_ABI_BREAKING_CHECKS
if (Unchecked) {
@@ -858,6 +887,27 @@ private:
#endif
};
+/// Helper for Expected<T>s used as out-parameters.
+///
+/// See ErrorAsOutParameter.
+template <typename T>
+class ExpectedAsOutParameter {
+public:
+ ExpectedAsOutParameter(Expected<T> *ValOrErr)
+ : ValOrErr(ValOrErr) {
+ if (ValOrErr)
+ (void)!!*ValOrErr;
+ }
+
+ ~ExpectedAsOutParameter() {
+ if (ValOrErr)
+ ValOrErr->setUnchecked();
+ }
+
+private:
+ Expected<T> *ValOrErr;
+};
+
/// This class wraps a std::error_code in a Error.
///
/// This is useful if you're writing an interface that returns a Error
@@ -926,6 +976,8 @@ public:
void log(raw_ostream &OS) const override;
std::error_code convertToErrorCode() const override;
+ const std::string &getMessage() const { return Msg; }
+
private:
std::string Msg;
std::error_code EC;
@@ -985,6 +1037,66 @@ private:
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err,
bool gen_crash_diag = true);
+/// Report a fatal error if Err is a failure value.
+///
+/// This function can be used to wrap calls to fallible functions ONLY when it
+/// is known that the Error will always be a success value. E.g.
+///
+/// @code{.cpp}
+/// // foo only attempts the fallible operation if DoFallibleOperation is
+/// // true. If DoFallibleOperation is false then foo always returns
+/// // Error::success().
+/// Error foo(bool DoFallibleOperation);
+///
+/// cantFail(foo(false));
+/// @endcode
+inline void cantFail(Error Err) {
+ if (Err)
+ llvm_unreachable("Failure value returned from cantFail wrapped call");
+}
+
+/// Report a fatal error if ValOrErr is a failure value, otherwise unwraps and
+/// returns the contained value.
+///
+/// This function can be used to wrap calls to fallible functions ONLY when it
+/// is known that the Error will always be a success value. E.g.
+///
+/// @code{.cpp}
+/// // foo only attempts the fallible operation if DoFallibleOperation is
+/// // true. If DoFallibleOperation is false then foo always returns an int.
+/// Expected<int> foo(bool DoFallibleOperation);
+///
+/// int X = cantFail(foo(false));
+/// @endcode
+template <typename T>
+T cantFail(Expected<T> ValOrErr) {
+ if (ValOrErr)
+ return std::move(*ValOrErr);
+ else
+ llvm_unreachable("Failure value returned from cantFail wrapped call");
+}
+
+/// Report a fatal error if ValOrErr is a failure value, otherwise unwraps and
+/// returns the contained reference.
+///
+/// This function can be used to wrap calls to fallible functions ONLY when it
+/// is known that the Error will always be a success value. E.g.
+///
+/// @code{.cpp}
+/// // foo only attempts the fallible operation if DoFallibleOperation is
+/// // true. If DoFallibleOperation is false then foo always returns a Bar&.
+/// Expected<Bar&> foo(bool DoFallibleOperation);
+///
+/// Bar &X = cantFail(foo(false));
+/// @endcode
+template <typename T>
+T& cantFail(Expected<T&> ValOrErr) {
+ if (ValOrErr)
+ return *ValOrErr;
+ else
+ llvm_unreachable("Failure value returned from cantFail wrapped call");
+}
+
} // end namespace llvm
#endif // LLVM_SUPPORT_ERROR_H
diff --git a/contrib/llvm/include/llvm/Support/ErrorHandling.h b/contrib/llvm/include/llvm/Support/ErrorHandling.h
index 7c1edd8..b45f634 100644
--- a/contrib/llvm/include/llvm/Support/ErrorHandling.h
+++ b/contrib/llvm/include/llvm/Support/ErrorHandling.h
@@ -78,12 +78,48 @@ LLVM_ATTRIBUTE_NORETURN void report_fatal_error(StringRef reason,
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const Twine &reason,
bool gen_crash_diag = true);
- /// This function calls abort(), and prints the optional message to stderr.
- /// Use the llvm_unreachable macro (that adds location info), instead of
- /// calling this function directly.
- LLVM_ATTRIBUTE_NORETURN void
- llvm_unreachable_internal(const char *msg=nullptr, const char *file=nullptr,
- unsigned line=0);
+/// Installs a new bad alloc error handler that should be used whenever a
+/// bad alloc error, e.g. failing malloc/calloc, is encountered by LLVM.
+///
+/// The user can install a bad alloc handler, in order to define the behavior
+/// in case of failing allocations, e.g. throwing an exception. Note that this
+/// handler must not trigger any additional allocations itself.
+///
+/// If no error handler is installed the default is to print the error message
+/// to stderr, and call exit(1). If an error handler is installed then it is
+/// the handler's responsibility to log the message, it will no longer be
+/// printed to stderr. If the error handler returns, then exit(1) will be
+/// called.
+///
+///
+/// \param user_data - An argument which will be passed to the installed error
+/// handler.
+void install_bad_alloc_error_handler(fatal_error_handler_t handler,
+ void *user_data = nullptr);
+
+/// Restores default bad alloc error handling behavior.
+void remove_bad_alloc_error_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.
+///
+/// Note: When throwing an exception in the bad alloc handler, make sure that
+/// the following unwind succeeds, e.g. do not trigger additional allocations
+/// in the unwind chain.
+///
+/// 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);
+
+/// This function calls abort(), and prints the optional message to stderr.
+/// Use the llvm_unreachable macro (that adds location info), instead of
+/// calling this function directly.
+LLVM_ATTRIBUTE_NORETURN void
+llvm_unreachable_internal(const char *msg = nullptr, const char *file = nullptr,
+ unsigned line = 0);
}
/// Marks that the current location is not supposed to be reachable.
diff --git a/contrib/llvm/include/llvm/Support/ErrorOr.h b/contrib/llvm/include/llvm/Support/ErrorOr.h
index 877f406..061fb65 100644
--- a/contrib/llvm/include/llvm/Support/ErrorOr.h
+++ b/contrib/llvm/include/llvm/Support/ErrorOr.h
@@ -16,13 +16,14 @@
#ifndef LLVM_SUPPORT_ERROROR_H
#define LLVM_SUPPORT_ERROROR_H
-#include "llvm/ADT/PointerIntPair.h"
#include "llvm/Support/AlignOf.h"
#include <cassert>
#include <system_error>
#include <type_traits>
+#include <utility>
namespace llvm {
+
/// \brief Stores a reference that can be changed.
template <typename T>
class ReferenceStorage {
@@ -67,17 +68,19 @@ public:
template<class T>
class ErrorOr {
template <class OtherT> friend class ErrorOr;
+
static const bool isRef = std::is_reference<T>::value;
- typedef ReferenceStorage<typename std::remove_reference<T>::type> wrap;
+
+ using wrap = ReferenceStorage<typename std::remove_reference<T>::type>;
public:
- typedef typename std::conditional<isRef, wrap, T>::type storage_type;
+ using storage_type = typename std::conditional<isRef, wrap, T>::type;
private:
- typedef typename std::remove_reference<T>::type &reference;
- typedef const typename std::remove_reference<T>::type &const_reference;
- typedef typename std::remove_reference<T>::type *pointer;
- typedef const typename std::remove_reference<T>::type *const_pointer;
+ 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 *;
public:
template <class E>
@@ -282,6 +285,7 @@ typename std::enable_if<std::is_error_code_enum<E>::value ||
operator==(const ErrorOr<T> &Err, E Code) {
return Err.getError() == Code;
}
+
} // end namespace llvm
#endif // LLVM_SUPPORT_ERROROR_H
diff --git a/contrib/llvm/include/llvm/Support/FileSystem.h b/contrib/llvm/include/llvm/Support/FileSystem.h
index ad21d8a..21c5fcd 100644
--- a/contrib/llvm/include/llvm/Support/FileSystem.h
+++ b/contrib/llvm/include/llvm/Support/FileSystem.h
@@ -33,6 +33,7 @@
#include "llvm/Support/Chrono.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/ErrorOr.h"
+#include "llvm/Support/MD5.h"
#include <cassert>
#include <cstdint>
#include <ctime>
@@ -93,6 +94,7 @@ enum perms {
set_uid_on_exe = 04000,
set_gid_on_exe = 02000,
sticky_bit = 01000,
+ all_perms = all_all | set_uid_on_exe | set_gid_on_exe | sticky_bit,
perms_not_known = 0xFFFF
};
@@ -114,7 +116,9 @@ inline perms &operator&=(perms &l, perms r) {
return l;
}
inline perms operator~(perms x) {
- return static_cast<perms>(~static_cast<unsigned short>(x));
+ // Avoid UB by explicitly truncating the (unsigned) ~ result.
+ return static_cast<perms>(
+ static_cast<unsigned short>(~static_cast<unsigned short>(x)));
}
class UniqueID {
@@ -141,70 +145,61 @@ public:
/// a platform-specific member to store the result.
class file_status
{
+ friend bool equivalent(file_status A, file_status B);
+
#if defined(LLVM_ON_UNIX)
- dev_t fs_st_dev;
- ino_t fs_st_ino;
- time_t fs_st_atime;
- time_t fs_st_mtime;
- uid_t fs_st_uid;
- gid_t fs_st_gid;
- off_t fs_st_size;
+ dev_t fs_st_dev = 0;
+ nlink_t fs_st_nlinks = 0;
+ ino_t fs_st_ino = 0;
+ time_t fs_st_atime = 0;
+ time_t fs_st_mtime = 0;
+ uid_t fs_st_uid = 0;
+ gid_t fs_st_gid = 0;
+ off_t fs_st_size = 0;
#elif defined (LLVM_ON_WIN32)
- uint32_t LastAccessedTimeHigh;
- uint32_t LastAccessedTimeLow;
- uint32_t LastWriteTimeHigh;
- uint32_t LastWriteTimeLow;
- uint32_t VolumeSerialNumber;
- uint32_t FileSizeHigh;
- uint32_t FileSizeLow;
- uint32_t FileIndexHigh;
- uint32_t FileIndexLow;
+ uint32_t NumLinks = 0;
+ uint32_t LastAccessedTimeHigh = 0;
+ uint32_t LastAccessedTimeLow = 0;
+ uint32_t LastWriteTimeHigh = 0;
+ uint32_t LastWriteTimeLow = 0;
+ uint32_t VolumeSerialNumber = 0;
+ uint32_t FileSizeHigh = 0;
+ uint32_t FileSizeLow = 0;
+ uint32_t FileIndexHigh = 0;
+ uint32_t FileIndexLow = 0;
#endif
- friend bool equivalent(file_status A, file_status B);
- file_type Type;
- perms Perms;
+ file_type Type = file_type::status_error;
+ perms Perms = perms_not_known;
public:
#if defined(LLVM_ON_UNIX)
- file_status()
- : fs_st_dev(0), fs_st_ino(0), fs_st_atime(0), fs_st_mtime(0),
- fs_st_uid(0), fs_st_gid(0), fs_st_size(0),
- Type(file_type::status_error), Perms(perms_not_known) {}
-
- file_status(file_type Type)
- : fs_st_dev(0), fs_st_ino(0), fs_st_atime(0), fs_st_mtime(0),
- fs_st_uid(0), fs_st_gid(0), fs_st_size(0), Type(Type),
- Perms(perms_not_known) {}
-
- file_status(file_type Type, perms Perms, dev_t Dev, ino_t Ino, time_t ATime,
- time_t MTime, uid_t UID, gid_t GID, off_t Size)
- : fs_st_dev(Dev), fs_st_ino(Ino), fs_st_atime(ATime), fs_st_mtime(MTime),
- fs_st_uid(UID), fs_st_gid(GID), fs_st_size(Size), Type(Type),
- Perms(Perms) {}
+ file_status() = default;
+
+ file_status(file_type Type) : Type(Type) {}
+
+ file_status(file_type Type, perms Perms, dev_t Dev, nlink_t Links, ino_t Ino,
+ time_t ATime, time_t MTime, uid_t UID, gid_t GID, off_t Size)
+ : fs_st_dev(Dev), fs_st_nlinks(Links), fs_st_ino(Ino), fs_st_atime(ATime),
+ fs_st_mtime(MTime), fs_st_uid(UID), fs_st_gid(GID), fs_st_size(Size),
+ Type(Type), Perms(Perms) {}
#elif defined(LLVM_ON_WIN32)
- file_status()
- : LastAccessedTimeHigh(0), LastAccessedTimeLow(0), LastWriteTimeHigh(0),
- LastWriteTimeLow(0), VolumeSerialNumber(0), FileSizeHigh(0),
- FileSizeLow(0), FileIndexHigh(0), FileIndexLow(0),
- Type(file_type::status_error), Perms(perms_not_known) {}
-
- file_status(file_type Type)
- : LastAccessedTimeHigh(0), LastAccessedTimeLow(0), LastWriteTimeHigh(0),
- LastWriteTimeLow(0), VolumeSerialNumber(0), FileSizeHigh(0),
- FileSizeLow(0), FileIndexHigh(0), FileIndexLow(0), Type(Type),
- Perms(perms_not_known) {}
-
- file_status(file_type Type, uint32_t LastAccessTimeHigh,
- uint32_t LastAccessTimeLow, uint32_t LastWriteTimeHigh,
- uint32_t LastWriteTimeLow, uint32_t VolumeSerialNumber,
- uint32_t FileSizeHigh, uint32_t FileSizeLow,
- uint32_t FileIndexHigh, uint32_t FileIndexLow)
- : LastAccessedTimeHigh(LastAccessTimeHigh), LastAccessedTimeLow(LastAccessTimeLow),
+ file_status() = default;
+
+ file_status(file_type Type) : Type(Type) {}
+
+ file_status(file_type Type, perms Perms, uint32_t LinkCount,
+ uint32_t LastAccessTimeHigh, uint32_t LastAccessTimeLow,
+ uint32_t LastWriteTimeHigh, uint32_t LastWriteTimeLow,
+ uint32_t VolumeSerialNumber, uint32_t FileSizeHigh,
+ uint32_t FileSizeLow, uint32_t FileIndexHigh,
+ uint32_t FileIndexLow)
+ : NumLinks(LinkCount), LastAccessedTimeHigh(LastAccessTimeHigh),
+ LastAccessedTimeLow(LastAccessTimeLow),
LastWriteTimeHigh(LastWriteTimeHigh),
LastWriteTimeLow(LastWriteTimeLow),
VolumeSerialNumber(VolumeSerialNumber), FileSizeHigh(FileSizeHigh),
FileSizeLow(FileSizeLow), FileIndexHigh(FileIndexHigh),
- FileIndexLow(FileIndexLow), Type(Type), Perms(perms_not_known) {}
+ FileIndexLow(FileIndexLow), Type(Type), Perms(Perms) {}
#endif
// getters
@@ -213,6 +208,7 @@ public:
TimePoint<> getLastAccessedTime() const;
TimePoint<> getLastModificationTime() const;
UniqueID getUniqueID() const;
+ uint32_t getLinkCount() const;
#if defined(LLVM_ON_UNIX)
uint32_t getUser() const { return fs_st_uid; }
@@ -222,9 +218,11 @@ public:
uint32_t getUser() const {
return 9999; // Not applicable to Windows, so...
}
+
uint32_t getGroup() const {
return 9999; // Not applicable to Windows, so...
}
+
uint64_t getSize() const {
return (uint64_t(FileSizeHigh) << 32) + FileSizeLow;
}
@@ -235,50 +233,6 @@ public:
void permissions(perms p) { Perms = p; }
};
-/// file_magic - An "enum class" enumeration of file types based on magic (the first
-/// N bytes of the file).
-struct file_magic {
- enum Impl {
- unknown = 0, ///< Unrecognized file
- bitcode, ///< Bitcode file
- archive, ///< ar style archive file
- elf, ///< ELF Unknown type
- elf_relocatable, ///< ELF Relocatable object file
- elf_executable, ///< ELF Executable image
- elf_shared_object, ///< ELF dynamically linked shared lib
- elf_core, ///< ELF core image
- macho_object, ///< Mach-O Object file
- macho_executable, ///< Mach-O Executable
- macho_fixed_virtual_memory_shared_lib, ///< Mach-O Shared Lib, FVM
- macho_core, ///< Mach-O Core File
- macho_preload_executable, ///< Mach-O Preloaded Executable
- macho_dynamically_linked_shared_lib, ///< Mach-O dynlinked shared lib
- macho_dynamic_linker, ///< The Mach-O dynamic linker
- macho_bundle, ///< Mach-O Bundle file
- macho_dynamically_linked_shared_lib_stub, ///< Mach-O Shared lib stub
- macho_dsym_companion, ///< Mach-O dSYM companion file
- macho_kext_bundle, ///< Mach-O kext bundle file
- macho_universal_binary, ///< Mach-O universal binary
- coff_cl_gl_object, ///< Microsoft cl.exe's intermediate code file
- coff_object, ///< COFF object file
- coff_import_library, ///< COFF import library
- pecoff_executable, ///< PECOFF executable file
- windows_resource, ///< Windows compiled resource file (.rc)
- wasm_object ///< WebAssembly Object file
- };
-
- bool is_object() const {
- return V != unknown;
- }
-
- file_magic() : V(unknown) {}
- file_magic(Impl V) : V(V) {}
- operator Impl() const { return V; }
-
-private:
- Impl V;
-};
-
/// @}
/// @name Physical Operators
/// @{
@@ -350,6 +304,16 @@ std::error_code create_link(const Twine &to, const Twine &from);
/// specific error_code.
std::error_code create_hard_link(const Twine &to, const Twine &from);
+/// @brief Collapse all . and .. patterns, resolve all symlinks, and optionally
+/// expand ~ expressions to the user's home directory.
+///
+/// @param path The path to resolve.
+/// @param output The location to store the resolved path.
+/// @param expand_tilde If true, resolves ~ expressions to the user's home
+/// directory.
+std::error_code real_path(const Twine &path, SmallVectorImpl<char> &output,
+ bool expand_tilde = false);
+
/// @brief Get the current path.
///
/// @param result Holds the current path on return.
@@ -357,6 +321,13 @@ std::error_code create_hard_link(const Twine &to, const Twine &from);
/// otherwise a platform-specific error_code.
std::error_code current_path(SmallVectorImpl<char> &result);
+/// @brief Set the current path.
+///
+/// @param path The path to set.
+/// @returns errc::success if the current path was successfully set,
+/// otherwise a platform-specific error_code.
+std::error_code set_current_path(const Twine &path);
+
/// @brief Remove path. Equivalent to POSIX remove().
///
/// @param path Input path.
@@ -365,6 +336,13 @@ std::error_code current_path(SmallVectorImpl<char> &result);
/// returns error if the file didn't exist.
std::error_code remove(const Twine &path, bool IgnoreNonExisting = true);
+/// @brief Recursively delete a directory.
+///
+/// @param path Input path.
+/// @returns errc::success if path has been removed or didn't exist, otherwise a
+/// platform-specific error code.
+std::error_code remove_directories(const Twine &path, bool IgnoreErrors = true);
+
/// @brief Rename \a from to \a to. Files are renamed as if by POSIX rename().
///
/// @param from The path to rename from.
@@ -385,6 +363,16 @@ std::error_code copy_file(const Twine &From, const Twine &To);
/// platform-specific error_code.
std::error_code resize_file(int FD, uint64_t Size);
+/// @brief Compute an MD5 hash of a file's contents.
+///
+/// @param FD Input file descriptor.
+/// @returns An MD5Result with the hash computed, if successful, otherwise a
+/// std::error_code.
+ErrorOr<MD5::MD5Result> md5_contents(int FD);
+
+/// @brief Version of compute_md5 that doesn't require an open file descriptor.
+ErrorOr<MD5::MD5Result> md5_contents(const Twine &Path);
+
/// @}
/// @name Physical Observers
/// @{
@@ -457,6 +445,40 @@ inline bool equivalent(const Twine &A, const Twine &B) {
return !equivalent(A, B, result) && result;
}
+/// @brief Is the file mounted on a local filesystem?
+///
+/// @param path Input path.
+/// @param result Set to true if \a path is on fixed media such as a hard disk,
+/// false if it is not.
+/// @returns errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+std::error_code is_local(const Twine &path, bool &result);
+
+/// @brief Version of is_local accepting an open file descriptor.
+std::error_code is_local(int FD, bool &result);
+
+/// @brief Simpler version of is_local for clients that don't need to
+/// differentiate between an error and false.
+inline bool is_local(const Twine &Path) {
+ bool Result;
+ return !is_local(Path, Result) && Result;
+}
+
+/// @brief Simpler version of is_local accepting an open file descriptor for
+/// clients that don't need to differentiate between an error and false.
+inline bool is_local(int FD) {
+ bool Result;
+ return !is_local(FD, Result) && Result;
+}
+
+/// @brief Does status represent a directory?
+///
+/// @param Path The path to get the type of.
+/// @param Follow For symbolic links, indicates whether to return the file type
+/// of the link itself, or of the target.
+/// @returns A value from the file_type enumeration indicating the type of file.
+file_type get_file_type(const Twine &Path, bool Follow = true);
+
/// @brief Does status represent a directory?
///
/// @param status A file_status previously returned from status.
@@ -466,8 +488,8 @@ bool is_directory(file_status status);
/// @brief Is path a directory?
///
/// @param path Input path.
-/// @param result Set to true if \a path is a directory, false if it is not.
-/// Undefined otherwise.
+/// @param result Set to true if \a path is a directory (after following
+/// symlinks, false if it is not. Undefined otherwise.
/// @returns errc::success if result has been successfully set, otherwise a
/// platform-specific error_code.
std::error_code is_directory(const Twine &path, bool &result);
@@ -488,8 +510,8 @@ bool is_regular_file(file_status status);
/// @brief Is path a regular file?
///
/// @param path Input path.
-/// @param result Set to true if \a path is a regular file, false if it is not.
-/// Undefined otherwise.
+/// @param result Set to true if \a path is a regular file (after following
+/// symlinks), false if it is not. Undefined otherwise.
/// @returns errc::success if result has been successfully set, otherwise a
/// platform-specific error_code.
std::error_code is_regular_file(const Twine &path, bool &result);
@@ -503,8 +525,32 @@ inline bool is_regular_file(const Twine &Path) {
return Result;
}
+/// @brief Does status represent a symlink file?
+///
+/// @param status A file_status previously returned from status.
+/// @returns status_known(status) && status.type() == file_type::symlink_file.
+bool is_symlink_file(file_status status);
+
+/// @brief Is path a symlink file?
+///
+/// @param path Input path.
+/// @param result Set to true if \a path is a symlink file, false if it is not.
+/// Undefined otherwise.
+/// @returns errc::success if result has been successfully set, otherwise a
+/// platform-specific error_code.
+std::error_code is_symlink_file(const Twine &path, bool &result);
+
+/// @brief Simpler version of is_symlink_file for clients that don't need to
+/// differentiate between an error and false.
+inline bool is_symlink_file(const Twine &Path) {
+ bool Result;
+ if (is_symlink_file(Path, Result))
+ return false;
+ return Result;
+}
+
/// @brief Does this status represent something that exists but is not a
-/// directory, regular file, or symlink?
+/// directory or regular file?
///
/// @param status A file_status previously returned from status.
/// @returns exists(s) && !is_regular_file(s) && !is_directory(s)
@@ -524,13 +570,37 @@ std::error_code is_other(const Twine &path, bool &result);
///
/// @param path Input path.
/// @param result Set to the file status.
+/// @param follow When true, follows symlinks. Otherwise, the symlink itself is
+/// statted.
/// @returns errc::success if result has been successfully set, otherwise a
/// platform-specific error_code.
-std::error_code status(const Twine &path, file_status &result);
+std::error_code status(const Twine &path, file_status &result,
+ bool follow = true);
/// @brief A version for when a file descriptor is already available.
std::error_code status(int FD, file_status &Result);
+/// @brief Set file permissions.
+///
+/// @param Path File to set permissions on.
+/// @param Permissions New file permissions.
+/// @returns errc::success if the permissions were successfully set, otherwise
+/// a platform-specific error_code.
+/// @note On Windows, all permissions except *_write are ignored. Using any of
+/// owner_write, group_write, or all_write will make the file writable.
+/// Otherwise, the file will be marked as read-only.
+std::error_code setPermissions(const Twine &Path, perms Permissions);
+
+/// @brief Get file permissions.
+///
+/// @param Path File to get permissions from.
+/// @returns the permissions if they were successfully retrieved, otherwise a
+/// platform-specific error_code.
+/// @note On Windows, if the file does not have the FILE_ATTRIBUTE_READONLY
+/// attribute, all_all will be returned. Otherwise, all_read | all_exe
+/// will be returned.
+ErrorOr<perms> getPermissions(const Twine &Path);
+
/// @brief Get file size.
///
/// @param Path Input path.
@@ -656,17 +726,6 @@ std::error_code openFileForWrite(const Twine &Name, int &ResultFD,
std::error_code openFileForRead(const Twine &Name, int &ResultFD,
SmallVectorImpl<char> *RealPath = nullptr);
-/// @brief Identify the type of a binary file based on how magical it is.
-file_magic identify_magic(StringRef magic);
-
-/// @brief Get and identify \a path's type based on its content.
-///
-/// @param path Input path.
-/// @param result Set to the type of file, or file_magic::unknown.
-/// @returns errc::success if result has been successfully set, otherwise a
-/// platform-specific error_code.
-std::error_code identify_magic(const Twine &path, file_magic &result);
-
std::error_code getUniqueID(const Twine Path, UniqueID &Result);
/// @brief Get disk space usage information.
@@ -735,12 +794,13 @@ std::string getMainExecutable(const char *argv0, void *MainExecAddr);
/// called.
class directory_entry {
std::string Path;
+ bool FollowSymlinks;
mutable file_status Status;
public:
- explicit directory_entry(const Twine &path, file_status st = file_status())
- : Path(path.str())
- , Status(st) {}
+ explicit directory_entry(const Twine &path, bool follow_symlinks = true,
+ file_status st = file_status())
+ : Path(path.str()), FollowSymlinks(follow_symlinks), Status(st) {}
directory_entry() = default;
@@ -763,9 +823,10 @@ public:
};
namespace detail {
+
struct DirIterState;
- std::error_code directory_iterator_construct(DirIterState &, StringRef);
+ std::error_code directory_iterator_construct(DirIterState &, StringRef, bool);
std::error_code directory_iterator_increment(DirIterState &);
std::error_code directory_iterator_destruct(DirIterState &);
@@ -778,6 +839,7 @@ namespace detail {
intptr_t IterationHandle = 0;
directory_entry CurrentEntry;
};
+
} // end namespace detail
/// directory_iterator - Iterates through the entries in path. There is no
@@ -785,18 +847,24 @@ namespace detail {
/// it call report_fatal_error on error.
class directory_iterator {
std::shared_ptr<detail::DirIterState> State;
+ bool FollowSymlinks = true;
public:
- explicit directory_iterator(const Twine &path, std::error_code &ec) {
+ explicit directory_iterator(const Twine &path, std::error_code &ec,
+ bool follow_symlinks = true)
+ : FollowSymlinks(follow_symlinks) {
State = std::make_shared<detail::DirIterState>();
SmallString<128> path_storage;
- ec = detail::directory_iterator_construct(*State,
- path.toStringRef(path_storage));
+ ec = detail::directory_iterator_construct(
+ *State, path.toStringRef(path_storage), FollowSymlinks);
}
- explicit directory_iterator(const directory_entry &de, std::error_code &ec) {
+ explicit directory_iterator(const directory_entry &de, std::error_code &ec,
+ bool follow_symlinks = true)
+ : FollowSymlinks(follow_symlinks) {
State = std::make_shared<detail::DirIterState>();
- ec = detail::directory_iterator_construct(*State, de.path());
+ ec =
+ detail::directory_iterator_construct(*State, de.path(), FollowSymlinks);
}
/// Construct end iterator.
@@ -829,24 +897,29 @@ public:
};
namespace detail {
+
/// Keeps state for the recursive_directory_iterator.
struct RecDirIterState {
std::stack<directory_iterator, std::vector<directory_iterator>> Stack;
uint16_t Level = 0;
bool HasNoPushRequest = false;
};
+
} // end namespace detail
/// recursive_directory_iterator - Same as directory_iterator except for it
/// recurses down into child directories.
class recursive_directory_iterator {
std::shared_ptr<detail::RecDirIterState> State;
+ bool Follow;
public:
recursive_directory_iterator() = default;
- explicit recursive_directory_iterator(const Twine &path, std::error_code &ec)
- : State(std::make_shared<detail::RecDirIterState>()) {
- State->Stack.push(directory_iterator(path, ec));
+ explicit recursive_directory_iterator(const Twine &path, std::error_code &ec,
+ bool follow_symlinks = true)
+ : State(std::make_shared<detail::RecDirIterState>()),
+ Follow(follow_symlinks) {
+ State->Stack.push(directory_iterator(path, ec, Follow));
if (State->Stack.top() == directory_iterator())
State.reset();
}
@@ -861,7 +934,7 @@ public:
file_status st;
if ((ec = State->Stack.top()->status(st))) return *this;
if (is_directory(st)) {
- State->Stack.push(directory_iterator(*State->Stack.top(), ec));
+ State->Stack.push(directory_iterator(*State->Stack.top(), ec, Follow));
if (ec) return *this;
if (State->Stack.top() != end_itr) {
++State->Level;
diff --git a/contrib/llvm/include/llvm/Support/Format.h b/contrib/llvm/include/llvm/Support/Format.h
index 017b497..bcbd2be 100644
--- a/contrib/llvm/include/llvm/Support/Format.h
+++ b/contrib/llvm/include/llvm/Support/Format.h
@@ -125,30 +125,39 @@ inline format_object<Ts...> format(const char *Fmt, const Ts &... Vals) {
return format_object<Ts...>(Fmt, Vals...);
}
-/// This is a helper class used for left_justify() and right_justify().
+/// This is a helper class for left_justify, right_justify, and center_justify.
class FormattedString {
+public:
+ enum Justification { JustifyNone, JustifyLeft, JustifyRight, JustifyCenter };
+ FormattedString(StringRef S, unsigned W, Justification J)
+ : Str(S), Width(W), Justify(J) {}
+
+private:
StringRef Str;
unsigned Width;
- bool RightJustify;
+ Justification Justify;
friend class raw_ostream;
-
-public:
- FormattedString(StringRef S, unsigned W, bool R)
- : Str(S), Width(W), RightJustify(R) { }
};
/// left_justify - append spaces after string so total output is
/// \p Width characters. If \p Str is larger that \p Width, full string
/// is written with no padding.
inline FormattedString left_justify(StringRef Str, unsigned Width) {
- return FormattedString(Str, Width, false);
+ return FormattedString(Str, Width, FormattedString::JustifyLeft);
}
/// right_justify - add spaces before string so total output is
/// \p Width characters. If \p Str is larger that \p Width, full string
/// is written with no padding.
inline FormattedString right_justify(StringRef Str, unsigned Width) {
- return FormattedString(Str, Width, true);
+ return FormattedString(Str, Width, FormattedString::JustifyRight);
+}
+
+/// center_justify - add spaces before and after string so total output is
+/// \p Width characters. If \p Str is larger that \p Width, full string
+/// is written with no padding.
+inline FormattedString center_justify(StringRef Str, unsigned Width) {
+ return FormattedString(Str, Width, FormattedString::JustifyCenter);
}
/// This is a helper class used for format_hex() and format_decimal().
diff --git a/contrib/llvm/include/llvm/Support/FormatAdapters.h b/contrib/llvm/include/llvm/Support/FormatAdapters.h
index 7bacd2e..197beb7 100644
--- a/contrib/llvm/include/llvm/Support/FormatAdapters.h
+++ b/contrib/llvm/include/llvm/Support/FormatAdapters.h
@@ -22,23 +22,22 @@ protected:
explicit FormatAdapter(T &&Item) : Item(Item) {}
T Item;
-
- static_assert(!detail::uses_missing_provider<T>::value,
- "Item does not have a format provider!");
};
namespace detail {
template <typename T> class AlignAdapter final : public FormatAdapter<T> {
AlignStyle Where;
size_t Amount;
+ char Fill;
public:
- AlignAdapter(T &&Item, AlignStyle Where, size_t Amount)
- : FormatAdapter<T>(std::forward<T>(Item)), Where(Where), Amount(Amount) {}
+ AlignAdapter(T &&Item, AlignStyle Where, size_t Amount, char Fill)
+ : FormatAdapter<T>(std::forward<T>(Item)), Where(Where), Amount(Amount),
+ Fill(Fill) {}
void format(llvm::raw_ostream &Stream, StringRef Style) {
auto Adapter = detail::build_format_adapter(std::forward<T>(this->Item));
- FmtAlign(Adapter, Where, Amount).format(Stream, Style);
+ FmtAlign(Adapter, Where, Amount, Fill).format(Stream, Style);
}
};
@@ -75,8 +74,9 @@ public:
}
template <typename T>
-detail::AlignAdapter<T> fmt_align(T &&Item, AlignStyle Where, size_t Amount) {
- return detail::AlignAdapter<T>(std::forward<T>(Item), Where, Amount);
+detail::AlignAdapter<T> fmt_align(T &&Item, AlignStyle Where, size_t Amount,
+ char Fill = ' ') {
+ return detail::AlignAdapter<T>(std::forward<T>(Item), Where, Amount, Fill);
}
template <typename T>
diff --git a/contrib/llvm/include/llvm/Support/FormatCommon.h b/contrib/llvm/include/llvm/Support/FormatCommon.h
index a8c5fde..36fbad2 100644
--- a/contrib/llvm/include/llvm/Support/FormatCommon.h
+++ b/contrib/llvm/include/llvm/Support/FormatCommon.h
@@ -21,9 +21,11 @@ struct FmtAlign {
detail::format_adapter &Adapter;
AlignStyle Where;
size_t Amount;
+ char Fill;
- FmtAlign(detail::format_adapter &Adapter, AlignStyle Where, size_t Amount)
- : Adapter(Adapter), Where(Where), Amount(Amount) {}
+ FmtAlign(detail::format_adapter &Adapter, AlignStyle Where, size_t Amount,
+ char Fill = ' ')
+ : Adapter(Adapter), Where(Where), Amount(Amount), Fill(Fill) {}
void format(raw_ostream &S, StringRef Options) {
// If we don't need to align, we can format straight into the underlying
@@ -48,21 +50,27 @@ struct FmtAlign {
switch (Where) {
case AlignStyle::Left:
S << Item;
- S.indent(PadAmount);
+ fill(S, PadAmount);
break;
case AlignStyle::Center: {
size_t X = PadAmount / 2;
- S.indent(X);
+ fill(S, X);
S << Item;
- S.indent(PadAmount - X);
+ fill(S, PadAmount - X);
break;
}
default:
- S.indent(PadAmount);
+ fill(S, PadAmount);
S << Item;
break;
}
}
+
+private:
+ void fill(llvm::raw_ostream &S, uint32_t Count) {
+ for (uint32_t I = 0; I < Count; ++I)
+ S << Fill;
+ }
};
}
diff --git a/contrib/llvm/include/llvm/Support/FormatProviders.h b/contrib/llvm/include/llvm/Support/FormatProviders.h
index 1f0768c..4e57034 100644
--- a/contrib/llvm/include/llvm/Support/FormatProviders.h
+++ b/contrib/llvm/include/llvm/Support/FormatProviders.h
@@ -18,6 +18,7 @@
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringSwitch.h"
+#include "llvm/ADT/Twine.h"
#include "llvm/Support/FormatVariadicDetails.h"
#include "llvm/Support/NativeFormatting.h"
@@ -45,9 +46,8 @@ struct is_cstring
template <typename T>
struct use_string_formatter
- : public std::integral_constant<
- bool, is_one_of<T, llvm::StringRef, std::string>::value ||
- is_cstring<T>::value> {};
+ : public std::integral_constant<bool,
+ std::is_convertible<T, llvm::StringRef>::value> {};
template <typename T>
struct use_pointer_formatter
@@ -205,11 +205,22 @@ struct format_provider<
if (!Style.empty() && Style.getAsInteger(10, N)) {
assert(false && "Style is not a valid integer");
}
- llvm::StringRef S(V);
+ llvm::StringRef S = V;
Stream << S.substr(0, N);
}
};
+/// Implementation of format_provider<T> for llvm::Twine.
+///
+/// This follows the same rules as the string formatter.
+
+template <> struct format_provider<Twine> {
+ static void format(const Twine &V, llvm::raw_ostream &Stream,
+ StringRef Style) {
+ format_provider<std::string>::format(V.str(), Stream, Style);
+ }
+};
+
/// Implementation of format_provider<T> for characters.
///
/// The options string of a character type has the grammar:
@@ -359,8 +370,7 @@ template <typename IterT> class format_provider<llvm::iterator_range<IterT>> {
return Default;
}
- std::vector<const char *> Delims = {"[]", "<>", "()"};
- for (const char *D : Delims) {
+ for (const char *D : {"[]", "<>", "()"}) {
if (Style.front() != D[0])
continue;
size_t End = Style.find_first_of(D[1]);
diff --git a/contrib/llvm/include/llvm/Support/FormatVariadic.h b/contrib/llvm/include/llvm/Support/FormatVariadic.h
index e5f5c96..c1153e8 100644
--- a/contrib/llvm/include/llvm/Support/FormatVariadic.h
+++ b/contrib/llvm/include/llvm/Support/FormatVariadic.h
@@ -27,8 +27,8 @@
#define LLVM_SUPPORT_FORMATVARIADIC_H
#include "llvm/ADT/Optional.h"
-#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/FormatCommon.h"
#include "llvm/Support/FormatProviders.h"
@@ -196,7 +196,7 @@ public:
// "}}" to print a literal '}'.
//
// ===Parameter Indexing===
-// `index` specifies the index of the paramter in the parameter pack to format
+// `index` specifies the index of the parameter in the parameter pack to format
// into the output. Note that it is possible to refer to the same parameter
// index multiple times in a given format string. This makes it possible to
// output the same value multiple times without passing it multiple times to the
diff --git a/contrib/llvm/include/llvm/Support/GCOV.h b/contrib/llvm/include/llvm/Support/GCOV.h
index f297fe6..02016e7 100644
--- a/contrib/llvm/include/llvm/Support/GCOV.h
+++ b/contrib/llvm/include/llvm/Support/GCOV.h
@@ -16,12 +16,12 @@
#define LLVM_SUPPORT_GCOV_H
#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/iterator.h"
-#include "llvm/ADT/iterator_range.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/iterator.h"
+#include "llvm/ADT/iterator_range.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/raw_ostream.h"
#include <cassert>
@@ -63,7 +63,7 @@ struct Options {
/// read operations.
class GCOVBuffer {
public:
- GCOVBuffer(MemoryBuffer *B) : Buffer(B), Cursor(0) {}
+ GCOVBuffer(MemoryBuffer *B) : Buffer(B) {}
/// readGCNOFormat - Check GCNO signature is valid at the beginning of buffer.
bool readGCNOFormat() {
@@ -234,48 +234,48 @@ public:
private:
MemoryBuffer *Buffer;
- uint64_t Cursor;
+ uint64_t Cursor = 0;
};
/// GCOVFile - Collects coverage information for one pair of coverage file
/// (.gcno and .gcda).
class GCOVFile {
public:
- GCOVFile()
- : GCNOInitialized(false), Checksum(0), RunCount(0),
- ProgramCount(0) {}
+ GCOVFile() = default;
bool readGCNO(GCOVBuffer &Buffer);
bool readGCDA(GCOVBuffer &Buffer);
uint32_t getChecksum() const { return Checksum; }
+ void print(raw_ostream &OS) const;
void dump() const;
void collectLineCounts(FileInfo &FI);
private:
- bool GCNOInitialized;
+ bool GCNOInitialized = false;
GCOV::GCOVVersion Version;
- uint32_t Checksum;
+ uint32_t Checksum = 0;
SmallVector<std::unique_ptr<GCOVFunction>, 16> Functions;
- uint32_t RunCount;
- uint32_t ProgramCount;
+ uint32_t RunCount = 0;
+ uint32_t ProgramCount = 0;
};
/// GCOVEdge - Collects edge information.
struct GCOVEdge {
- GCOVEdge(GCOVBlock &S, GCOVBlock &D) : Src(S), Dst(D), Count(0) {}
+ GCOVEdge(GCOVBlock &S, GCOVBlock &D) : Src(S), Dst(D) {}
GCOVBlock &Src;
GCOVBlock &Dst;
- uint64_t Count;
+ uint64_t Count = 0;
};
/// GCOVFunction - Collects function information.
class GCOVFunction {
public:
- typedef pointee_iterator<SmallVectorImpl<
- std::unique_ptr<GCOVBlock>>::const_iterator> BlockIterator;
+ using BlockIterator = pointee_iterator<SmallVectorImpl<
+ std::unique_ptr<GCOVBlock>>::const_iterator>;
+
+ GCOVFunction(GCOVFile &P) : Parent(P) {}
- GCOVFunction(GCOVFile &P) : Parent(P), Ident(0), LineNumber(0) {}
bool readGCNO(GCOVBuffer &Buffer, GCOV::GCOVVersion Version);
bool readGCDA(GCOVBuffer &Buffer, GCOV::GCOVVersion Version);
StringRef getName() const { return Name; }
@@ -290,14 +290,15 @@ public:
return make_range(block_begin(), block_end());
}
+ void print(raw_ostream &OS) const;
void dump() const;
void collectLineCounts(FileInfo &FI);
private:
GCOVFile &Parent;
- uint32_t Ident;
+ uint32_t Ident = 0;
uint32_t Checksum;
- uint32_t LineNumber;
+ uint32_t LineNumber = 0;
StringRef Name;
StringRef Filename;
SmallVector<std::unique_ptr<GCOVBlock>, 16> Blocks;
@@ -307,10 +308,10 @@ private:
/// GCOVBlock - Collects block information.
class GCOVBlock {
struct EdgeWeight {
- EdgeWeight(GCOVBlock *D) : Dst(D), Count(0) {}
+ EdgeWeight(GCOVBlock *D) : Dst(D) {}
GCOVBlock *Dst;
- uint64_t Count;
+ uint64_t Count = 0;
};
struct SortDstEdgesFunctor {
@@ -320,10 +321,9 @@ class GCOVBlock {
};
public:
- typedef SmallVectorImpl<GCOVEdge *>::const_iterator EdgeIterator;
+ using EdgeIterator = SmallVectorImpl<GCOVEdge *>::const_iterator;
- GCOVBlock(GCOVFunction &P, uint32_t N)
- : Parent(P), Number(N), Counter(0), DstEdgesAreSorted(true) {}
+ GCOVBlock(GCOVFunction &P, uint32_t N) : Parent(P), Number(N) {}
~GCOVBlock();
const GCOVFunction &getParent() const { return Parent; }
@@ -361,14 +361,15 @@ public:
return make_range(dst_begin(), dst_end());
}
+ void print(raw_ostream &OS) const;
void dump() const;
void collectLineCounts(FileInfo &FI);
private:
GCOVFunction &Parent;
uint32_t Number;
- uint64_t Counter;
- bool DstEdgesAreSorted;
+ uint64_t Counter = 0;
+ bool DstEdgesAreSorted = true;
SmallVector<GCOVEdge *, 16> SrcEdges;
SmallVector<GCOVEdge *, 16> DstEdges;
SmallVector<uint32_t, 16> Lines;
@@ -380,36 +381,34 @@ class FileInfo {
// Therefore this typedef allows LineData.Functions to store multiple
// functions
// per instance. This is rare, however, so optimize for the common case.
- typedef SmallVector<const GCOVFunction *, 1> FunctionVector;
- typedef DenseMap<uint32_t, FunctionVector> FunctionLines;
- typedef SmallVector<const GCOVBlock *, 4> BlockVector;
- typedef DenseMap<uint32_t, BlockVector> BlockLines;
+ using FunctionVector = SmallVector<const GCOVFunction *, 1>;
+ using FunctionLines = DenseMap<uint32_t, FunctionVector>;
+ using BlockVector = SmallVector<const GCOVBlock *, 4>;
+ using BlockLines = DenseMap<uint32_t, BlockVector>;
struct LineData {
- LineData() : LastLine(0) {}
+ LineData() = default;
+
BlockLines Blocks;
FunctionLines Functions;
- uint32_t LastLine;
+ uint32_t LastLine = 0;
};
struct GCOVCoverage {
- GCOVCoverage(StringRef Name)
- : Name(Name), LogicalLines(0), LinesExec(0), Branches(0),
- BranchesExec(0), BranchesTaken(0) {}
+ GCOVCoverage(StringRef Name) : Name(Name) {}
StringRef Name;
- uint32_t LogicalLines;
- uint32_t LinesExec;
+ uint32_t LogicalLines = 0;
+ uint32_t LinesExec = 0;
- uint32_t Branches;
- uint32_t BranchesExec;
- uint32_t BranchesTaken;
+ uint32_t Branches = 0;
+ uint32_t BranchesExec = 0;
+ uint32_t BranchesTaken = 0;
};
public:
- FileInfo(const GCOV::Options &Options)
- : Options(Options), RunCount(0), ProgramCount(0) {}
+ FileInfo(const GCOV::Options &Options) : Options(Options) {}
void addBlockLine(StringRef Filename, uint32_t Line, const GCOVBlock *Block) {
if (Line > LineInfo[Filename].LastLine)
@@ -446,11 +445,11 @@ private:
const GCOV::Options &Options;
StringMap<LineData> LineInfo;
- uint32_t RunCount;
- uint32_t ProgramCount;
+ uint32_t RunCount = 0;
+ uint32_t ProgramCount = 0;
- typedef SmallVector<std::pair<std::string, GCOVCoverage>, 4> FileCoverageList;
- typedef MapVector<const GCOVFunction *, GCOVCoverage> FuncCoverageMap;
+ using FileCoverageList = SmallVector<std::pair<std::string, GCOVCoverage>, 4>;
+ using FuncCoverageMap = MapVector<const GCOVFunction *, GCOVCoverage>;
FileCoverageList FileCoverages;
FuncCoverageMap FuncCoverages;
diff --git a/contrib/llvm/include/llvm/Support/GenericDomTree.h b/contrib/llvm/include/llvm/Support/GenericDomTree.h
index 6e6ee40..706320f 100644
--- a/contrib/llvm/include/llvm/Support/GenericDomTree.h
+++ b/contrib/llvm/include/llvm/Support/GenericDomTree.h
@@ -13,7 +13,7 @@
/// dominance queries on the CFG, but is fully generic w.r.t. the underlying
/// graph types.
///
-/// Unlike ADT/* graph algorithms, generic dominator tree has more reuiqrement
+/// Unlike ADT/* graph algorithms, generic dominator tree has more requirements
/// on the graph's NodeRef. The NodeRef should be a pointer and, depending on
/// the implementation, e.g. NodeRef->getParent() return the parent node.
///
@@ -25,82 +25,52 @@
#define LLVM_SUPPORT_GENERICDOMTREE_H
#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/DepthFirstIterator.h"
#include "llvm/ADT/GraphTraits.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/Support/Compiler.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <iterator>
+#include <memory>
+#include <type_traits>
+#include <utility>
+#include <vector>
namespace llvm {
-template <class NodeT> class DominatorTreeBase;
+template <typename NodeT, bool IsPostDom>
+class DominatorTreeBase;
-namespace detail {
-
-template <typename GT> struct DominatorTreeBaseTraits {
- static_assert(std::is_pointer<typename GT::NodeRef>::value,
- "Currently NodeRef must be a pointer type.");
- using type = DominatorTreeBase<
- typename std::remove_pointer<typename GT::NodeRef>::type>;
-};
-
-} // End namespace detail
-
-template <typename GT>
-using DominatorTreeBaseByGraphTraits =
- typename detail::DominatorTreeBaseTraits<GT>::type;
-
-/// \brief Base class that other, more interesting dominator analyses
-/// inherit from.
-template <class NodeT> class DominatorBase {
-protected:
- std::vector<NodeT *> Roots;
- bool IsPostDominators;
- explicit DominatorBase(bool isPostDom)
- : Roots(), IsPostDominators(isPostDom) {}
- DominatorBase(DominatorBase &&Arg)
- : Roots(std::move(Arg.Roots)),
- IsPostDominators(std::move(Arg.IsPostDominators)) {
- Arg.Roots.clear();
- }
- DominatorBase &operator=(DominatorBase &&RHS) {
- Roots = std::move(RHS.Roots);
- IsPostDominators = std::move(RHS.IsPostDominators);
- RHS.Roots.clear();
- return *this;
- }
-
-public:
- /// 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 std::vector<NodeT *> &getRoots() const { return Roots; }
-
- /// isPostDominator - Returns true if analysis based of postdoms
- ///
- bool isPostDominator() const { return IsPostDominators; }
-};
-
-struct PostDominatorTree;
+namespace DomTreeBuilder {
+template <class DomTreeT>
+struct SemiNCAInfo;
+} // namespace DomTreeBuilder
/// \brief Base class for the actual dominator tree node.
template <class NodeT> class DomTreeNodeBase {
+ friend struct PostDominatorTree;
+ friend class DominatorTreeBase<NodeT, false>;
+ friend class DominatorTreeBase<NodeT, true>;
+ friend struct DomTreeBuilder::SemiNCAInfo<DominatorTreeBase<NodeT, false>>;
+ friend struct DomTreeBuilder::SemiNCAInfo<DominatorTreeBase<NodeT, true>>;
+
NodeT *TheBB;
- DomTreeNodeBase<NodeT> *IDom;
- std::vector<DomTreeNodeBase<NodeT> *> Children;
- mutable int DFSNumIn, DFSNumOut;
+ DomTreeNodeBase *IDom;
+ unsigned Level;
+ std::vector<DomTreeNodeBase *> Children;
+ mutable unsigned DFSNumIn = ~0;
+ mutable unsigned DFSNumOut = ~0;
- template <class N> friend class DominatorTreeBase;
- friend struct PostDominatorTree;
+ public:
+ DomTreeNodeBase(NodeT *BB, DomTreeNodeBase *iDom)
+ : TheBB(BB), IDom(iDom), Level(IDom ? IDom->Level + 1 : 0) {}
-public:
- typedef typename std::vector<DomTreeNodeBase<NodeT> *>::iterator iterator;
- typedef typename std::vector<DomTreeNodeBase<NodeT> *>::const_iterator
- const_iterator;
+ using iterator = typename std::vector<DomTreeNodeBase *>::iterator;
+ using const_iterator =
+ typename std::vector<DomTreeNodeBase *>::const_iterator;
iterator begin() { return Children.begin(); }
iterator end() { return Children.end(); }
@@ -108,16 +78,13 @@ public:
const_iterator end() const { return Children.end(); }
NodeT *getBlock() const { return TheBB; }
- DomTreeNodeBase<NodeT> *getIDom() const { return IDom; }
- const std::vector<DomTreeNodeBase<NodeT> *> &getChildren() const {
- return Children;
- }
+ DomTreeNodeBase *getIDom() const { return IDom; }
+ unsigned getLevel() const { return Level; }
- DomTreeNodeBase(NodeT *BB, DomTreeNodeBase<NodeT> *iDom)
- : TheBB(BB), IDom(iDom), DFSNumIn(-1), DFSNumOut(-1) {}
+ const std::vector<DomTreeNodeBase *> &getChildren() const { return Children; }
- std::unique_ptr<DomTreeNodeBase<NodeT>>
- addChild(std::unique_ptr<DomTreeNodeBase<NodeT>> C) {
+ std::unique_ptr<DomTreeNodeBase> addChild(
+ std::unique_ptr<DomTreeNodeBase> C) {
Children.push_back(C.get());
return C;
}
@@ -126,10 +93,12 @@ public:
void clearAllChildren() { Children.clear(); }
- bool compare(const DomTreeNodeBase<NodeT> *Other) const {
+ bool compare(const DomTreeNodeBase *Other) const {
if (getNumChildren() != Other->getNumChildren())
return true;
+ if (Level != Other->Level) return true;
+
SmallPtrSet<const NodeT *, 4> OtherChildren;
for (const DomTreeNodeBase *I : *Other) {
const NodeT *Nd = I->getBlock();
@@ -144,20 +113,21 @@ public:
return false;
}
- void setIDom(DomTreeNodeBase<NodeT> *NewIDom) {
+ void setIDom(DomTreeNodeBase *NewIDom) {
assert(IDom && "No immediate dominator?");
- if (IDom != NewIDom) {
- typename std::vector<DomTreeNodeBase<NodeT> *>::iterator I =
- find(IDom->Children, this);
- assert(I != IDom->Children.end() &&
- "Not in immediate dominator children set!");
- // I am no longer your child...
- IDom->Children.erase(I);
+ if (IDom == NewIDom) return;
- // Switch to new dominator
- IDom = NewIDom;
- IDom->Children.push_back(this);
- }
+ auto I = find(IDom->Children, this);
+ assert(I != IDom->Children.end() &&
+ "Not in immediate dominator children set!");
+ // I am no longer your child...
+ IDom->Children.erase(I);
+
+ // Switch to new dominator
+ IDom = NewIDom;
+ IDom->Children.push_back(this);
+
+ UpdateLevel();
}
/// getDFSNumIn/getDFSNumOut - These return the DFS visitation order for nodes
@@ -169,208 +139,143 @@ public:
private:
// Return true if this node is dominated by other. Use this only if DFS info
// is valid.
- bool DominatedBy(const DomTreeNodeBase<NodeT> *other) const {
+ bool DominatedBy(const DomTreeNodeBase *other) const {
return this->DFSNumIn >= other->DFSNumIn &&
this->DFSNumOut <= other->DFSNumOut;
}
+
+ void UpdateLevel() {
+ assert(IDom);
+ if (Level == IDom->Level + 1) return;
+
+ SmallVector<DomTreeNodeBase *, 64> WorkStack = {this};
+
+ while (!WorkStack.empty()) {
+ DomTreeNodeBase *Current = WorkStack.pop_back_val();
+ Current->Level = Current->IDom->Level + 1;
+
+ for (DomTreeNodeBase *C : *Current) {
+ assert(C->IDom);
+ if (C->Level != C->IDom->Level + 1) WorkStack.push_back(C);
+ }
+ }
+ }
};
template <class NodeT>
-raw_ostream &operator<<(raw_ostream &o, const DomTreeNodeBase<NodeT> *Node) {
+raw_ostream &operator<<(raw_ostream &O, const DomTreeNodeBase<NodeT> *Node) {
if (Node->getBlock())
- Node->getBlock()->printAsOperand(o, false);
+ Node->getBlock()->printAsOperand(O, false);
else
- o << " <<exit node>>";
+ O << " <<exit node>>";
- o << " {" << Node->getDFSNumIn() << "," << Node->getDFSNumOut() << "}";
+ O << " {" << Node->getDFSNumIn() << "," << Node->getDFSNumOut() << "} ["
+ << Node->getLevel() << "]\n";
- return o << "\n";
+ return O;
}
template <class NodeT>
-void PrintDomTree(const DomTreeNodeBase<NodeT> *N, raw_ostream &o,
+void PrintDomTree(const DomTreeNodeBase<NodeT> *N, raw_ostream &O,
unsigned Lev) {
- o.indent(2 * Lev) << "[" << Lev << "] " << N;
+ O.indent(2 * Lev) << "[" << Lev << "] " << N;
for (typename DomTreeNodeBase<NodeT>::const_iterator I = N->begin(),
E = N->end();
I != E; ++I)
- PrintDomTree<NodeT>(*I, o, Lev + 1);
+ PrintDomTree<NodeT>(*I, O, Lev + 1);
}
-// The calculate routine is provided in a separate header but referenced here.
-template <class FuncT, class N>
-void Calculate(DominatorTreeBaseByGraphTraits<GraphTraits<N>> &DT, FuncT &F);
+namespace DomTreeBuilder {
+// The routines below are provided in a separate header but referenced here.
+template <typename DomTreeT, typename FuncT>
+void Calculate(DomTreeT &DT, FuncT &F);
+
+template <class DomTreeT>
+void InsertEdge(DomTreeT &DT, typename DomTreeT::NodePtr From,
+ typename DomTreeT::NodePtr To);
+
+template <class DomTreeT>
+void DeleteEdge(DomTreeT &DT, typename DomTreeT::NodePtr From,
+ typename DomTreeT::NodePtr To);
+
+template <typename DomTreeT>
+bool Verify(const DomTreeT &DT);
+} // namespace DomTreeBuilder
/// \brief Core dominator tree base class.
///
/// This class is a generic template over graph nodes. It is instantiated for
/// various graphs in the LLVM IR or in the code generator.
-template <class NodeT> class DominatorTreeBase : public DominatorBase<NodeT> {
- DominatorTreeBase(const DominatorTreeBase &) = delete;
- DominatorTreeBase &operator=(const DominatorTreeBase &) = delete;
-
- bool dominatedBySlowTreeWalk(const DomTreeNodeBase<NodeT> *A,
- const DomTreeNodeBase<NodeT> *B) const {
- assert(A != B);
- assert(isReachableFromEntry(B));
- assert(isReachableFromEntry(A));
-
- const DomTreeNodeBase<NodeT> *IDom;
- while ((IDom = B->getIDom()) != nullptr && IDom != A && IDom != B)
- B = IDom; // Walk up the tree
- return IDom != nullptr;
- }
-
- /// \brief Wipe this tree's state without releasing any resources.
- ///
- /// This is essentially a post-move helper only. It leaves the object in an
- /// assignable and destroyable state, but otherwise invalid.
- void wipe() {
- DomTreeNodes.clear();
- IDoms.clear();
- Vertex.clear();
- Info.clear();
- RootNode = nullptr;
- }
+template <typename NodeT, bool IsPostDom>
+class DominatorTreeBase {
+ protected:
+ std::vector<NodeT *> Roots;
-protected:
- typedef DenseMap<NodeT *, std::unique_ptr<DomTreeNodeBase<NodeT>>>
- DomTreeNodeMapType;
+ using DomTreeNodeMapType =
+ DenseMap<NodeT *, std::unique_ptr<DomTreeNodeBase<NodeT>>>;
DomTreeNodeMapType DomTreeNodes;
DomTreeNodeBase<NodeT> *RootNode;
+ using ParentPtr = decltype(std::declval<NodeT *>()->getParent());
+ ParentPtr Parent = nullptr;
- mutable bool DFSInfoValid;
- mutable unsigned int SlowQueries;
- // Information record used during immediate dominators computation.
- struct InfoRec {
- unsigned DFSNum;
- unsigned Parent;
- unsigned Semi;
- NodeT *Label;
-
- InfoRec() : DFSNum(0), Parent(0), Semi(0), Label(nullptr) {}
- };
-
- DenseMap<NodeT *, NodeT *> IDoms;
-
- // Vertex - Map the DFS number to the NodeT*
- std::vector<NodeT *> Vertex;
-
- // Info - Collection of information used during the computation of idoms.
- DenseMap<NodeT *, InfoRec> Info;
-
- void reset() {
- DomTreeNodes.clear();
- IDoms.clear();
- this->Roots.clear();
- Vertex.clear();
- RootNode = nullptr;
- DFSInfoValid = false;
- SlowQueries = 0;
- }
-
- // NewBB is split and now it has one successor. Update dominator tree to
- // reflect this change.
- template <class N, class GraphT>
- void Split(DominatorTreeBaseByGraphTraits<GraphT> &DT,
- typename GraphT::NodeRef NewBB) {
- assert(std::distance(GraphT::child_begin(NewBB),
- GraphT::child_end(NewBB)) == 1 &&
- "NewBB should have a single successor!");
- typename GraphT::NodeRef NewBBSucc = *GraphT::child_begin(NewBB);
-
- std::vector<typename GraphT::NodeRef> PredBlocks;
- typedef GraphTraits<Inverse<N>> InvTraits;
- for (typename InvTraits::ChildIteratorType
- PI = InvTraits::child_begin(NewBB),
- PE = InvTraits::child_end(NewBB);
- PI != PE; ++PI)
- PredBlocks.push_back(*PI);
-
- assert(!PredBlocks.empty() && "No predblocks?");
-
- bool NewBBDominatesNewBBSucc = true;
- for (typename InvTraits::ChildIteratorType
- PI = InvTraits::child_begin(NewBBSucc),
- E = InvTraits::child_end(NewBBSucc);
- PI != E; ++PI) {
- typename InvTraits::NodeRef ND = *PI;
- if (ND != NewBB && !DT.dominates(NewBBSucc, ND) &&
- DT.isReachableFromEntry(ND)) {
- NewBBDominatesNewBBSucc = false;
- break;
- }
- }
-
- // Find NewBB's immediate dominator and create new dominator tree node for
- // NewBB.
- NodeT *NewBBIDom = nullptr;
- unsigned i = 0;
- for (i = 0; i < PredBlocks.size(); ++i)
- if (DT.isReachableFromEntry(PredBlocks[i])) {
- NewBBIDom = PredBlocks[i];
- break;
- }
+ mutable bool DFSInfoValid = false;
+ mutable unsigned int SlowQueries = 0;
- // It's possible that none of the predecessors of NewBB are reachable;
- // in that case, NewBB itself is unreachable, so nothing needs to be
- // changed.
- if (!NewBBIDom)
- return;
+ friend struct DomTreeBuilder::SemiNCAInfo<DominatorTreeBase>;
- for (i = i + 1; i < PredBlocks.size(); ++i) {
- if (DT.isReachableFromEntry(PredBlocks[i]))
- NewBBIDom = DT.findNearestCommonDominator(NewBBIDom, PredBlocks[i]);
- }
+ public:
+ static_assert(std::is_pointer<typename GraphTraits<NodeT *>::NodeRef>::value,
+ "Currently DominatorTreeBase supports only pointer nodes");
+ using NodeType = NodeT;
+ using NodePtr = NodeT *;
+ static constexpr bool IsPostDominator = IsPostDom;
- // Create the new dominator tree node... and set the idom of NewBB.
- DomTreeNodeBase<NodeT> *NewBBNode = DT.addNewBlock(NewBB, NewBBIDom);
-
- // If NewBB strictly dominates other blocks, then it is now the immediate
- // dominator of NewBBSucc. Update the dominator tree as appropriate.
- if (NewBBDominatesNewBBSucc) {
- DomTreeNodeBase<NodeT> *NewBBSuccNode = DT.getNode(NewBBSucc);
- DT.changeImmediateDominator(NewBBSuccNode, NewBBNode);
- }
- }
-
-public:
- explicit DominatorTreeBase(bool isPostDom)
- : DominatorBase<NodeT>(isPostDom), DFSInfoValid(false), SlowQueries(0) {}
+ DominatorTreeBase() {}
DominatorTreeBase(DominatorTreeBase &&Arg)
- : DominatorBase<NodeT>(
- std::move(static_cast<DominatorBase<NodeT> &>(Arg))),
+ : Roots(std::move(Arg.Roots)),
DomTreeNodes(std::move(Arg.DomTreeNodes)),
- RootNode(std::move(Arg.RootNode)),
- DFSInfoValid(std::move(Arg.DFSInfoValid)),
- SlowQueries(std::move(Arg.SlowQueries)), IDoms(std::move(Arg.IDoms)),
- Vertex(std::move(Arg.Vertex)), Info(std::move(Arg.Info)) {
+ RootNode(Arg.RootNode),
+ Parent(Arg.Parent),
+ DFSInfoValid(Arg.DFSInfoValid),
+ SlowQueries(Arg.SlowQueries) {
Arg.wipe();
}
+
DominatorTreeBase &operator=(DominatorTreeBase &&RHS) {
- DominatorBase<NodeT>::operator=(
- std::move(static_cast<DominatorBase<NodeT> &>(RHS)));
+ Roots = std::move(RHS.Roots);
DomTreeNodes = std::move(RHS.DomTreeNodes);
- RootNode = std::move(RHS.RootNode);
- DFSInfoValid = std::move(RHS.DFSInfoValid);
- SlowQueries = std::move(RHS.SlowQueries);
- IDoms = std::move(RHS.IDoms);
- Vertex = std::move(RHS.Vertex);
- Info = std::move(RHS.Info);
+ RootNode = RHS.RootNode;
+ Parent = RHS.Parent;
+ DFSInfoValid = RHS.DFSInfoValid;
+ SlowQueries = RHS.SlowQueries;
RHS.wipe();
return *this;
}
+ 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).
+ ///
+ const std::vector<NodeT *> &getRoots() const { return Roots; }
+
+ /// isPostDominator - Returns true if analysis based of postdoms
+ ///
+ bool isPostDominator() const { return IsPostDominator; }
+
/// compare - Return false if the other dominator tree base matches this
/// dominator tree base. Otherwise return true.
bool compare(const DominatorTreeBase &Other) const {
+ if (Parent != Other.Parent) return true;
const DomTreeNodeMapType &OtherDomTreeNodes = Other.DomTreeNodes;
if (DomTreeNodes.size() != OtherDomTreeNodes.size())
return true;
- for (const auto &DomTreeNode : this->DomTreeNodes) {
+ for (const auto &DomTreeNode : DomTreeNodes) {
NodeT *BB = DomTreeNode.first;
typename DomTreeNodeMapType::const_iterator OI =
OtherDomTreeNodes.find(BB);
@@ -470,6 +375,13 @@ public:
if (!isReachableFromEntry(A))
return false;
+ if (B->getIDom() == A) return true;
+
+ if (A->getIDom() == B) return false;
+
+ // A can only dominate B if it is higher in the tree.
+ if (A->getLevel() >= B->getLevel()) return false;
+
// Compare the result of the tree walk and the dfs numbers, if expensive
// checks are enabled.
#ifdef EXPENSIVE_CHECKS
@@ -501,7 +413,7 @@ public:
/// findNearestCommonDominator - Find nearest common dominator basic block
/// for basic block A and B. If there is no such block then return NULL.
- NodeT *findNearestCommonDominator(NodeT *A, NodeT *B) {
+ NodeT *findNearestCommonDominator(NodeT *A, NodeT *B) const {
assert(A->getParent() == B->getParent() &&
"Two blocks are not in same function");
@@ -513,64 +425,74 @@ public:
return &Entry;
}
- // If B dominates A then B is nearest common dominator.
- if (dominates(B, A))
- return B;
-
- // If A dominates B then A is nearest common dominator.
- if (dominates(A, B))
- return A;
-
DomTreeNodeBase<NodeT> *NodeA = getNode(A);
DomTreeNodeBase<NodeT> *NodeB = getNode(B);
- // If we have DFS info, then we can avoid all allocations by just querying
- // it from each IDom. Note that because we call 'dominates' twice above, we
- // expect to call through this code at most 16 times in a row without
- // building valid DFS information. This is important as below is a *very*
- // slow tree walk.
- if (DFSInfoValid) {
- DomTreeNodeBase<NodeT> *IDomA = NodeA->getIDom();
- while (IDomA) {
- if (NodeB->DominatedBy(IDomA))
- return IDomA->getBlock();
- IDomA = IDomA->getIDom();
- }
- return nullptr;
- }
-
- // Collect NodeA dominators set.
- SmallPtrSet<DomTreeNodeBase<NodeT> *, 16> NodeADoms;
- NodeADoms.insert(NodeA);
- DomTreeNodeBase<NodeT> *IDomA = NodeA->getIDom();
- while (IDomA) {
- NodeADoms.insert(IDomA);
- IDomA = IDomA->getIDom();
- }
+ if (!NodeA || !NodeB) return nullptr;
- // Walk NodeB immediate dominators chain and find common dominator node.
- DomTreeNodeBase<NodeT> *IDomB = NodeB->getIDom();
- while (IDomB) {
- if (NodeADoms.count(IDomB) != 0)
- return IDomB->getBlock();
+ // Use level information to go up the tree until the levels match. Then
+ // continue going up til we arrive at the same node.
+ while (NodeA && NodeA != NodeB) {
+ if (NodeA->getLevel() < NodeB->getLevel()) std::swap(NodeA, NodeB);
- IDomB = IDomB->getIDom();
+ NodeA = NodeA->IDom;
}
- return nullptr;
+ return NodeA ? NodeA->getBlock() : nullptr;
}
- const NodeT *findNearestCommonDominator(const NodeT *A, const NodeT *B) {
+ const NodeT *findNearestCommonDominator(const NodeT *A,
+ const NodeT *B) const {
// Cast away the const qualifiers here. This is ok since
// const is re-introduced on the return type.
return findNearestCommonDominator(const_cast<NodeT *>(A),
const_cast<NodeT *>(B));
}
+ bool isVirtualRoot(const DomTreeNodeBase<NodeT> *A) const {
+ return isPostDominator() && !A->getBlock();
+ }
+
//===--------------------------------------------------------------------===//
// API to update (Post)DominatorTree information based on modifications to
// the CFG...
+ /// Inform the dominator tree about a CFG edge insertion and update the tree.
+ ///
+ /// This function has to be called just before or just after making the update
+ /// on the actual CFG. There cannot be any other updates that the dominator
+ /// tree doesn't know about.
+ ///
+ /// Note that for postdominators it automatically takes care of inserting
+ /// a reverse edge internally (so there's no need to swap the parameters).
+ ///
+ void insertEdge(NodeT *From, NodeT *To) {
+ assert(From);
+ assert(To);
+ assert(From->getParent() == Parent);
+ assert(To->getParent() == Parent);
+ DomTreeBuilder::InsertEdge(*this, From, To);
+ }
+
+ /// Inform the dominator tree about a CFG edge deletion and update the tree.
+ ///
+ /// This function has to be called just after making the update
+ /// on the actual CFG. There cannot be any other updates that the dominator
+ /// tree doesn't know about. The only exception is when the deletion that the
+ /// tree is informed about makes some (domominator) subtree unreachable -- in
+ /// this case, it is fine to perform deletions within this subtree.
+ ///
+ /// Note that for postdominators it automatically takes care of deleting
+ /// a reverse edge internally (so there's no need to swap the parameters).
+ ///
+ void deleteEdge(NodeT *From, NodeT *To) {
+ assert(From);
+ assert(To);
+ assert(From->getParent() == Parent);
+ assert(To->getParent() == Parent);
+ DomTreeBuilder::DeleteEdge(*this, From, To);
+ }
+
/// Add a new node to the dominator tree information.
///
/// This creates a new node as a child of DomBB dominator node, linking it
@@ -599,7 +521,6 @@ public:
assert(!this->isPostDominator() &&
"Cannot change root of post-dominator tree");
DFSInfoValid = false;
- auto &Roots = DominatorBase<NodeT>::Roots;
DomTreeNodeBase<NodeT> *NewNode = (DomTreeNodes[BB] =
llvm::make_unique<DomTreeNodeBase<NodeT>>(BB, nullptr)).get();
if (Roots.empty()) {
@@ -607,8 +528,10 @@ public:
} else {
assert(Roots.size() == 1);
NodeT *OldRoot = Roots.front();
- DomTreeNodes[OldRoot] =
- NewNode->addChild(std::move(DomTreeNodes[OldRoot]));
+ auto &OldNode = DomTreeNodes[OldRoot];
+ OldNode = NewNode->addChild(std::move(DomTreeNodes[OldRoot]));
+ OldNode->IDom = NewNode;
+ OldNode->UpdateLevel();
Roots[0] = BB;
}
return RootNode = NewNode;
@@ -653,70 +576,32 @@ public:
/// splitBlock - BB is split and now it has one successor. Update dominator
/// tree to reflect this change.
void splitBlock(NodeT *NewBB) {
- if (this->IsPostDominators)
- this->Split<Inverse<NodeT *>, GraphTraits<Inverse<NodeT *>>>(*this,
- NewBB);
+ if (IsPostDominator)
+ Split<Inverse<NodeT *>>(NewBB);
else
- this->Split<NodeT *, GraphTraits<NodeT *>>(*this, NewBB);
+ Split<NodeT *>(NewBB);
}
/// print - Convert to human readable form
///
- void print(raw_ostream &o) const {
- o << "=============================--------------------------------\n";
+ void print(raw_ostream &O) const {
+ O << "=============================--------------------------------\n";
if (this->isPostDominator())
- o << "Inorder PostDominator Tree: ";
+ O << "Inorder PostDominator Tree: ";
else
- o << "Inorder Dominator Tree: ";
- if (!this->DFSInfoValid)
- o << "DFSNumbers invalid: " << SlowQueries << " slow queries.";
- o << "\n";
+ O << "Inorder Dominator Tree: ";
+ if (!DFSInfoValid)
+ O << "DFSNumbers invalid: " << SlowQueries << " slow queries.";
+ O << "\n";
// The postdom tree can have a null root if there are no returns.
- if (getRootNode())
- PrintDomTree<NodeT>(getRootNode(), o, 1);
- }
-
-protected:
- template <class GraphT>
- friend typename GraphT::NodeRef
- Eval(DominatorTreeBaseByGraphTraits<GraphT> &DT, typename GraphT::NodeRef V,
- unsigned LastLinked);
-
- template <class GraphT>
- friend unsigned DFSPass(DominatorTreeBaseByGraphTraits<GraphT> &DT,
- typename GraphT::NodeRef V, unsigned N);
-
- template <class FuncT, class N>
- friend void Calculate(DominatorTreeBaseByGraphTraits<GraphTraits<N>> &DT,
- FuncT &F);
-
- DomTreeNodeBase<NodeT> *getNodeForBlock(NodeT *BB) {
- if (DomTreeNodeBase<NodeT> *Node = getNode(BB))
- return Node;
-
- // Haven't calculated this node yet? Get or calculate the node for the
- // immediate dominator.
- NodeT *IDom = getIDom(BB);
-
- assert(IDom || this->DomTreeNodes[nullptr]);
- DomTreeNodeBase<NodeT> *IDomNode = getNodeForBlock(IDom);
-
- // Add a new tree node for this NodeT, and link it as a child of
- // IDomNode
- return (this->DomTreeNodes[BB] = IDomNode->addChild(
- llvm::make_unique<DomTreeNodeBase<NodeT>>(BB, IDomNode))).get();
+ if (getRootNode()) PrintDomTree<NodeT>(getRootNode(), O, 1);
}
- NodeT *getIDom(NodeT *BB) const { return IDoms.lookup(BB); }
-
- void addRoot(NodeT *BB) { this->Roots.push_back(BB); }
-
public:
/// updateDFSNumbers - Assign In and Out numbers to the nodes while walking
/// dominator tree in dfs order.
void updateDFSNumbers() const {
-
if (DFSInfoValid) {
SlowQueries = 0;
return;
@@ -766,33 +651,131 @@ public:
/// recalculate - compute a dominator tree for the given function
template <class FT> void recalculate(FT &F) {
- typedef GraphTraits<FT *> TraitsTy;
+ using TraitsTy = GraphTraits<FT *>;
reset();
- this->Vertex.push_back(nullptr);
+ Parent = &F;
- if (!this->IsPostDominators) {
+ if (!IsPostDominator) {
// Initialize root
NodeT *entry = TraitsTy::getEntryNode(&F);
addRoot(entry);
-
- Calculate<FT, NodeT *>(*this, F);
} else {
// Initialize the roots list
- for (typename TraitsTy::nodes_iterator I = TraitsTy::nodes_begin(&F),
- E = TraitsTy::nodes_end(&F);
- I != E; ++I)
- if (TraitsTy::child_begin(*I) == TraitsTy::child_end(*I))
- addRoot(*I);
+ for (auto *Node : nodes(&F))
+ if (TraitsTy::child_begin(Node) == TraitsTy::child_end(Node))
+ addRoot(Node);
+ }
+
+ DomTreeBuilder::Calculate(*this, F);
+ }
+
+ /// verify - check parent and sibling property
+ bool verify() const { return DomTreeBuilder::Verify(*this); }
+
+ protected:
+ void addRoot(NodeT *BB) { this->Roots.push_back(BB); }
+
+ void reset() {
+ DomTreeNodes.clear();
+ Roots.clear();
+ RootNode = nullptr;
+ Parent = nullptr;
+ DFSInfoValid = false;
+ SlowQueries = 0;
+ }
- Calculate<FT, Inverse<NodeT *>>(*this, F);
+ // NewBB is split and now it has one successor. Update dominator tree to
+ // reflect this change.
+ template <class N>
+ void Split(typename GraphTraits<N>::NodeRef NewBB) {
+ using GraphT = GraphTraits<N>;
+ using NodeRef = typename GraphT::NodeRef;
+ assert(std::distance(GraphT::child_begin(NewBB),
+ GraphT::child_end(NewBB)) == 1 &&
+ "NewBB should have a single successor!");
+ NodeRef NewBBSucc = *GraphT::child_begin(NewBB);
+
+ std::vector<NodeRef> PredBlocks;
+ for (const auto &Pred : children<Inverse<N>>(NewBB))
+ PredBlocks.push_back(Pred);
+
+ assert(!PredBlocks.empty() && "No predblocks?");
+
+ bool NewBBDominatesNewBBSucc = true;
+ for (const auto &Pred : children<Inverse<N>>(NewBBSucc)) {
+ if (Pred != NewBB && !dominates(NewBBSucc, Pred) &&
+ isReachableFromEntry(Pred)) {
+ NewBBDominatesNewBBSucc = false;
+ break;
+ }
+ }
+
+ // Find NewBB's immediate dominator and create new dominator tree node for
+ // NewBB.
+ NodeT *NewBBIDom = nullptr;
+ unsigned i = 0;
+ for (i = 0; i < PredBlocks.size(); ++i)
+ if (isReachableFromEntry(PredBlocks[i])) {
+ NewBBIDom = PredBlocks[i];
+ break;
+ }
+
+ // It's possible that none of the predecessors of NewBB are reachable;
+ // in that case, NewBB itself is unreachable, so nothing needs to be
+ // changed.
+ if (!NewBBIDom) return;
+
+ for (i = i + 1; i < PredBlocks.size(); ++i) {
+ if (isReachableFromEntry(PredBlocks[i]))
+ NewBBIDom = findNearestCommonDominator(NewBBIDom, PredBlocks[i]);
+ }
+
+ // Create the new dominator tree node... and set the idom of NewBB.
+ DomTreeNodeBase<NodeT> *NewBBNode = addNewBlock(NewBB, NewBBIDom);
+
+ // If NewBB strictly dominates other blocks, then it is now the immediate
+ // dominator of NewBBSucc. Update the dominator tree as appropriate.
+ if (NewBBDominatesNewBBSucc) {
+ DomTreeNodeBase<NodeT> *NewBBSuccNode = getNode(NewBBSucc);
+ changeImmediateDominator(NewBBSuccNode, NewBBNode);
}
}
+
+ private:
+ bool dominatedBySlowTreeWalk(const DomTreeNodeBase<NodeT> *A,
+ const DomTreeNodeBase<NodeT> *B) const {
+ assert(A != B);
+ assert(isReachableFromEntry(B));
+ assert(isReachableFromEntry(A));
+
+ const DomTreeNodeBase<NodeT> *IDom;
+ while ((IDom = B->getIDom()) != nullptr && IDom != A && IDom != B)
+ B = IDom; // Walk up the tree
+ return IDom != nullptr;
+ }
+
+ /// \brief Wipe this tree's state without releasing any resources.
+ ///
+ /// This is essentially a post-move helper only. It leaves the object in an
+ /// assignable and destroyable state, but otherwise invalid.
+ void wipe() {
+ DomTreeNodes.clear();
+ RootNode = nullptr;
+ Parent = nullptr;
+ }
};
+template <typename T>
+using DomTreeBase = DominatorTreeBase<T, false>;
+
+template <typename T>
+using PostDomTreeBase = DominatorTreeBase<T, true>;
+
// These two functions are declared out of line as a workaround for building
// with old (< r147295) versions of clang because of pr11642.
-template <class NodeT>
-bool DominatorTreeBase<NodeT>::dominates(const NodeT *A, const NodeT *B) const {
+template <typename NodeT, bool IsPostDom>
+bool DominatorTreeBase<NodeT, IsPostDom>::dominates(const NodeT *A,
+ const NodeT *B) const {
if (A == B)
return true;
@@ -802,9 +785,9 @@ bool DominatorTreeBase<NodeT>::dominates(const NodeT *A, const NodeT *B) const {
return dominates(getNode(const_cast<NodeT *>(A)),
getNode(const_cast<NodeT *>(B)));
}
-template <class NodeT>
-bool DominatorTreeBase<NodeT>::properlyDominates(const NodeT *A,
- const NodeT *B) const {
+template <typename NodeT, bool IsPostDom>
+bool DominatorTreeBase<NodeT, IsPostDom>::properlyDominates(
+ const NodeT *A, const NodeT *B) const {
if (A == B)
return false;
@@ -815,6 +798,6 @@ bool DominatorTreeBase<NodeT>::properlyDominates(const NodeT *A,
getNode(const_cast<NodeT *>(B)));
}
-}
+} // end namespace llvm
-#endif
+#endif // LLVM_SUPPORT_GENERICDOMTREE_H
diff --git a/contrib/llvm/include/llvm/Support/GenericDomTreeConstruction.h b/contrib/llvm/include/llvm/Support/GenericDomTreeConstruction.h
index 54e55cc..be90afa 100644
--- a/contrib/llvm/include/llvm/Support/GenericDomTreeConstruction.h
+++ b/contrib/llvm/include/llvm/Support/GenericDomTreeConstruction.h
@@ -10,278 +10,973 @@
///
/// Generic dominator tree construction - This file provides routines to
/// construct immediate dominator information for a flow-graph based on the
-/// algorithm described in this document:
+/// Semi-NCA algorithm described in this dissertation:
///
-/// A Fast Algorithm for Finding Dominators in a Flowgraph
-/// T. Lengauer & R. Tarjan, ACM TOPLAS July 1979, pgs 121-141.
+/// 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
///
/// This implements the O(n*log(n)) versions of EVAL and LINK, because it turns
/// out that the theoretically slower O(n*log(n)) implementation is actually
/// faster than the almost-linear O(n*alpha(n)) version, even for large CFGs.
///
+/// The file uses the Depth Based Search algorithm to perform incremental
+/// upates (insertion and deletions). The implemented algorithm is based on this
+/// publication:
+///
+/// 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
+///
//===----------------------------------------------------------------------===//
#ifndef LLVM_SUPPORT_GENERICDOMTREECONSTRUCTION_H
#define LLVM_SUPPORT_GENERICDOMTREECONSTRUCTION_H
+#include <queue>
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/DepthFirstIterator.h"
#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/Support/Debug.h"
#include "llvm/Support/GenericDomTree.h"
+#define DEBUG_TYPE "dom-tree-builder"
+
namespace llvm {
+namespace DomTreeBuilder {
-template <class GraphT>
-unsigned DFSPass(DominatorTreeBaseByGraphTraits<GraphT> &DT,
- typename GraphT::NodeRef V, unsigned N) {
- // This is more understandable as a recursive algorithm, but we can't use the
- // recursive algorithm due to stack depth issues. Keep it here for
- // documentation purposes.
-#if 0
- InfoRec &VInfo = DT.Info[DT.Roots[i]];
- VInfo.DFSNum = VInfo.Semi = ++N;
- VInfo.Label = V;
-
- Vertex.push_back(V); // Vertex[n] = V;
-
- for (succ_iterator SI = succ_begin(V), E = succ_end(V); SI != E; ++SI) {
- InfoRec &SuccVInfo = DT.Info[*SI];
- if (SuccVInfo.Semi == 0) {
- SuccVInfo.Parent = V;
- N = DTDFSPass(DT, *SI, N);
- }
+template <typename NodePtr, bool Inverse>
+struct ChildrenGetter {
+ static auto Get(NodePtr N) -> decltype(reverse(children<NodePtr>(N))) {
+ return reverse(children<NodePtr>(N));
}
-#else
- bool IsChildOfArtificialExit = (N != 0);
-
- SmallVector<
- std::pair<typename GraphT::NodeRef, typename GraphT::ChildIteratorType>,
- 32>
- Worklist;
- Worklist.push_back(std::make_pair(V, GraphT::child_begin(V)));
- while (!Worklist.empty()) {
- typename GraphT::NodeRef BB = Worklist.back().first;
- typename GraphT::ChildIteratorType NextSucc = Worklist.back().second;
-
- auto &BBInfo = DT.Info[BB];
-
- // First time we visited this BB?
- if (NextSucc == GraphT::child_begin(BB)) {
- BBInfo.DFSNum = BBInfo.Semi = ++N;
+};
+
+template <typename NodePtr>
+struct ChildrenGetter<NodePtr, true> {
+ static auto Get(NodePtr N) -> decltype(inverse_children<NodePtr>(N)) {
+ return inverse_children<NodePtr>(N);
+ }
+};
+
+template <typename DomTreeT>
+struct SemiNCAInfo {
+ using NodePtr = typename DomTreeT::NodePtr;
+ using NodeT = typename DomTreeT::NodeType;
+ using TreeNodePtr = DomTreeNodeBase<NodeT> *;
+ static constexpr bool IsPostDom = DomTreeT::IsPostDominator;
+
+ // Information record used by Semi-NCA during tree construction.
+ struct InfoRec {
+ unsigned DFSNum = 0;
+ unsigned Parent = 0;
+ unsigned Semi = 0;
+ NodePtr Label = nullptr;
+ NodePtr IDom = nullptr;
+ SmallVector<NodePtr, 2> ReverseChildren;
+ };
+
+ // Number to node mapping is 1-based. Initialize the mapping to start with
+ // a dummy element.
+ std::vector<NodePtr> NumToNode = {nullptr};
+ DenseMap<NodePtr, InfoRec> NodeToInfo;
+
+ void clear() {
+ NumToNode = {nullptr}; // Restore to initial state with a dummy start node.
+ NodeToInfo.clear();
+ }
+
+ NodePtr getIDom(NodePtr BB) const {
+ auto InfoIt = NodeToInfo.find(BB);
+ if (InfoIt == NodeToInfo.end()) return nullptr;
+
+ return InfoIt->second.IDom;
+ }
+
+ TreeNodePtr getNodeForBlock(NodePtr BB, DomTreeT &DT) {
+ if (TreeNodePtr Node = DT.getNode(BB)) return Node;
+
+ // Haven't calculated this node yet? Get or calculate the node for the
+ // immediate dominator.
+ NodePtr IDom = getIDom(BB);
+
+ assert(IDom || DT.DomTreeNodes[nullptr]);
+ TreeNodePtr IDomNode = getNodeForBlock(IDom, DT);
+
+ // Add a new tree node for this NodeT, and link it as a child of
+ // IDomNode
+ return (DT.DomTreeNodes[BB] = IDomNode->addChild(
+ llvm::make_unique<DomTreeNodeBase<NodeT>>(BB, IDomNode)))
+ .get();
+ }
+
+ static bool AlwaysDescend(NodePtr, NodePtr) { return true; }
+
+ struct BlockNamePrinter {
+ NodePtr N;
+
+ BlockNamePrinter(NodePtr Block) : N(Block) {}
+ BlockNamePrinter(TreeNodePtr TN) : N(TN ? TN->getBlock() : nullptr) {}
+
+ friend raw_ostream &operator<<(raw_ostream &O, const BlockNamePrinter &BP) {
+ if (!BP.N)
+ O << "nullptr";
+ else
+ BP.N->printAsOperand(O, false);
+
+ return O;
+ }
+ };
+
+ // Custom DFS implementation which can skip nodes based on a provided
+ // predicate. It also collects ReverseChildren so that we don't have to spend
+ // time getting predecessors in SemiNCA.
+ template <bool Inverse, typename DescendCondition>
+ unsigned runDFS(NodePtr V, unsigned LastNum, DescendCondition Condition,
+ unsigned AttachToNum) {
+ assert(V);
+ SmallVector<NodePtr, 64> WorkList = {V};
+ if (NodeToInfo.count(V) != 0) NodeToInfo[V].Parent = AttachToNum;
+
+ while (!WorkList.empty()) {
+ const NodePtr BB = WorkList.pop_back_val();
+ auto &BBInfo = NodeToInfo[BB];
+
+ // Visited nodes always have positive DFS numbers.
+ if (BBInfo.DFSNum != 0) continue;
+ BBInfo.DFSNum = BBInfo.Semi = ++LastNum;
BBInfo.Label = BB;
+ NumToNode.push_back(BB);
+
+ for (const NodePtr Succ : ChildrenGetter<NodePtr, Inverse>::Get(BB)) {
+ const auto SIT = NodeToInfo.find(Succ);
+ // Don't visit nodes more than once but remember to collect
+ // RerverseChildren.
+ if (SIT != NodeToInfo.end() && SIT->second.DFSNum != 0) {
+ if (Succ != BB) SIT->second.ReverseChildren.push_back(BB);
+ continue;
+ }
+
+ if (!Condition(BB, Succ)) continue;
+
+ // It's fine to add Succ to the map, because we know that it will be
+ // visited later.
+ auto &SuccInfo = NodeToInfo[Succ];
+ WorkList.push_back(Succ);
+ SuccInfo.Parent = LastNum;
+ SuccInfo.ReverseChildren.push_back(BB);
+ }
+ }
+
+ return LastNum;
+ }
+
+ NodePtr eval(NodePtr VIn, unsigned LastLinked) {
+ auto &VInInfo = NodeToInfo[VIn];
+ if (VInInfo.DFSNum < LastLinked)
+ return VIn;
- DT.Vertex.push_back(BB); // Vertex[n] = V;
+ SmallVector<NodePtr, 32> Work;
+ SmallPtrSet<NodePtr, 32> Visited;
- if (IsChildOfArtificialExit)
- BBInfo.Parent = 1;
+ if (VInInfo.Parent >= LastLinked)
+ Work.push_back(VIn);
- IsChildOfArtificialExit = false;
+ while (!Work.empty()) {
+ NodePtr V = Work.back();
+ auto &VInfo = NodeToInfo[V];
+ NodePtr VAncestor = NumToNode[VInfo.Parent];
+
+ // Process Ancestor first
+ if (Visited.insert(VAncestor).second && VInfo.Parent >= LastLinked) {
+ Work.push_back(VAncestor);
+ continue;
+ }
+ Work.pop_back();
+
+ // Update VInfo based on Ancestor info
+ if (VInfo.Parent < LastLinked)
+ continue;
+
+ auto &VAInfo = NodeToInfo[VAncestor];
+ NodePtr VAncestorLabel = VAInfo.Label;
+ NodePtr VLabel = VInfo.Label;
+ if (NodeToInfo[VAncestorLabel].Semi < NodeToInfo[VLabel].Semi)
+ VInfo.Label = VAncestorLabel;
+ VInfo.Parent = VAInfo.Parent;
}
- // store the DFS number of the current BB - the reference to BBInfo might
- // get invalidated when processing the successors.
- unsigned BBDFSNum = BBInfo.DFSNum;
+ return VInInfo.Label;
+ }
- // If we are done with this block, remove it from the worklist.
- if (NextSucc == GraphT::child_end(BB)) {
- Worklist.pop_back();
- continue;
+ // This function requires DFS to be run before calling it.
+ void runSemiNCA(DomTreeT &DT, const unsigned MinLevel = 0) {
+ const unsigned NextDFSNum(NumToNode.size());
+ // Initialize IDoms to spanning tree parents.
+ for (unsigned i = 1; i < NextDFSNum; ++i) {
+ const NodePtr V = NumToNode[i];
+ auto &VInfo = NodeToInfo[V];
+ VInfo.IDom = NumToNode[VInfo.Parent];
}
- // Increment the successor number for the next time we get to it.
- ++Worklist.back().second;
+ // Step #1: Calculate the semidominators of all vertices.
+ for (unsigned i = NextDFSNum - 1; i >= 2; --i) {
+ NodePtr W = NumToNode[i];
+ auto &WInfo = NodeToInfo[W];
+
+ // Initialize the semi dominator to point to the parent node.
+ WInfo.Semi = WInfo.Parent;
+ for (const auto &N : WInfo.ReverseChildren) {
+ if (NodeToInfo.count(N) == 0) // Skip unreachable predecessors.
+ continue;
- // Visit the successor next, if it isn't already visited.
- typename GraphT::NodeRef Succ = *NextSucc;
+ const TreeNodePtr TN = DT.getNode(N);
+ // Skip predecessors whose level is above the subtree we are processing.
+ if (TN && TN->getLevel() < MinLevel)
+ continue;
+
+ unsigned SemiU = NodeToInfo[eval(N, i + 1)].Semi;
+ if (SemiU < WInfo.Semi) WInfo.Semi = SemiU;
+ }
+ }
- auto &SuccVInfo = DT.Info[Succ];
- if (SuccVInfo.Semi == 0) {
- SuccVInfo.Parent = BBDFSNum;
- Worklist.push_back(std::make_pair(Succ, GraphT::child_begin(Succ)));
+ // Step #2: Explicitly define the immediate dominator of each vertex.
+ // IDom[i] = NCA(SDom[i], SpanningTreeParent(i)).
+ // Note that the parents were stored in IDoms and later got invalidated
+ // during path compression in Eval.
+ for (unsigned i = 2; i < NextDFSNum; ++i) {
+ const NodePtr W = NumToNode[i];
+ auto &WInfo = NodeToInfo[W];
+ const unsigned SDomNum = NodeToInfo[NumToNode[WInfo.Semi]].DFSNum;
+ NodePtr WIDomCandidate = WInfo.IDom;
+ while (NodeToInfo[WIDomCandidate].DFSNum > SDomNum)
+ WIDomCandidate = NodeToInfo[WIDomCandidate].IDom;
+
+ WInfo.IDom = WIDomCandidate;
}
}
-#endif
- return N;
-}
-template <class GraphT>
-typename GraphT::NodeRef Eval(DominatorTreeBaseByGraphTraits<GraphT> &DT,
- typename GraphT::NodeRef VIn,
- unsigned LastLinked) {
- auto &VInInfo = DT.Info[VIn];
- if (VInInfo.DFSNum < LastLinked)
- return VIn;
-
- SmallVector<typename GraphT::NodeRef, 32> Work;
- SmallPtrSet<typename GraphT::NodeRef, 32> Visited;
-
- if (VInInfo.Parent >= LastLinked)
- Work.push_back(VIn);
-
- while (!Work.empty()) {
- typename GraphT::NodeRef V = Work.back();
- auto &VInfo = DT.Info[V];
- typename GraphT::NodeRef VAncestor = DT.Vertex[VInfo.Parent];
-
- // Process Ancestor first
- if (Visited.insert(VAncestor).second && VInfo.Parent >= LastLinked) {
- Work.push_back(VAncestor);
- continue;
+ template <typename DescendCondition>
+ unsigned doFullDFSWalk(const DomTreeT &DT, DescendCondition DC) {
+ unsigned Num = 0;
+
+ if (DT.Roots.size() > 1) {
+ auto &BBInfo = NodeToInfo[nullptr];
+ BBInfo.DFSNum = BBInfo.Semi = ++Num;
+ BBInfo.Label = nullptr;
+
+ NumToNode.push_back(nullptr); // NumToNode[n] = V;
}
- Work.pop_back();
-
- // Update VInfo based on Ancestor info
- if (VInfo.Parent < LastLinked)
- continue;
-
- auto &VAInfo = DT.Info[VAncestor];
- typename GraphT::NodeRef VAncestorLabel = VAInfo.Label;
- typename GraphT::NodeRef VLabel = VInfo.Label;
- if (DT.Info[VAncestorLabel].Semi < DT.Info[VLabel].Semi)
- VInfo.Label = VAncestorLabel;
- VInfo.Parent = VAInfo.Parent;
+
+ if (DT.isPostDominator()) {
+ for (auto *Root : DT.Roots) Num = runDFS<true>(Root, Num, DC, 1);
+ } else {
+ assert(DT.Roots.size() == 1);
+ Num = runDFS<false>(DT.Roots[0], Num, DC, Num);
+ }
+
+ return Num;
}
- return VInInfo.Label;
-}
+ void calculateFromScratch(DomTreeT &DT, const unsigned NumBlocks) {
+ // Step #0: Number blocks in depth-first order and initialize variables used
+ // in later stages of the algorithm.
+ const unsigned LastDFSNum = doFullDFSWalk(DT, AlwaysDescend);
+
+ runSemiNCA(DT);
+
+ if (DT.Roots.empty()) return;
+
+ // Add a node for the root. This node might be the actual root, if there is
+ // one exit block, or it may be the virtual exit (denoted by
+ // (BasicBlock *)0) which postdominates all real exits if there are multiple
+ // exit blocks, or an infinite loop.
+ // It might be that some blocks did not get a DFS number (e.g., blocks of
+ // infinite loops). In these cases an artificial exit node is required.
+ const bool MultipleRoots = DT.Roots.size() > 1 || (DT.isPostDominator() &&
+ LastDFSNum != NumBlocks);
+ NodePtr Root = !MultipleRoots ? DT.Roots[0] : nullptr;
+
+ DT.RootNode = (DT.DomTreeNodes[Root] =
+ llvm::make_unique<DomTreeNodeBase<NodeT>>(Root, nullptr))
+ .get();
+ attachNewSubtree(DT, DT.RootNode);
+ }
+
+ void attachNewSubtree(DomTreeT& DT, const TreeNodePtr AttachTo) {
+ // Attach the first unreachable block to AttachTo.
+ NodeToInfo[NumToNode[1]].IDom = AttachTo->getBlock();
+ // 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];
+ 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?
-template <class FuncT, class NodeT>
-void Calculate(DominatorTreeBaseByGraphTraits<GraphTraits<NodeT>> &DT,
- FuncT &F) {
- typedef GraphTraits<NodeT> GraphT;
- static_assert(std::is_pointer<typename GraphT::NodeRef>::value,
- "NodeRef should be pointer type");
- typedef typename std::remove_pointer<typename GraphT::NodeRef>::type NodeType;
-
- unsigned N = 0;
- bool MultipleRoots = (DT.Roots.size() > 1);
- if (MultipleRoots) {
- auto &BBInfo = DT.Info[nullptr];
- BBInfo.DFSNum = BBInfo.Semi = ++N;
- BBInfo.Label = nullptr;
-
- DT.Vertex.push_back(nullptr); // Vertex[n] = V;
+ NodePtr ImmDom = getIDom(W);
+
+ // Get or calculate the node for the immediate dominator
+ TreeNodePtr IDomNode = getNodeForBlock(ImmDom, DT);
+
+ // Add a new tree node for this BasicBlock, and link it as a child of
+ // IDomNode
+ DT.DomTreeNodes[W] = IDomNode->addChild(
+ llvm::make_unique<DomTreeNodeBase<NodeT>>(W, IDomNode));
+ }
}
- // Step #1: Number blocks in depth-first order and initialize variables used
- // in later stages of the algorithm.
- for (unsigned i = 0, e = static_cast<unsigned>(DT.Roots.size());
- i != e; ++i)
- N = DFSPass<GraphT>(DT, DT.Roots[i], N);
+ void reattachExistingSubtree(DomTreeT &DT, const TreeNodePtr AttachTo) {
+ NodeToInfo[NumToNode[1]].IDom = AttachTo->getBlock();
+ for (size_t i = 1, e = NumToNode.size(); i != e; ++i) {
+ const NodePtr N = NumToNode[i];
+ const TreeNodePtr TN = DT.getNode(N);
+ assert(TN);
+ const TreeNodePtr NewIDom = DT.getNode(NodeToInfo[N].IDom);
+ TN->setIDom(NewIDom);
+ }
+ }
- // it might be that some blocks did not get a DFS number (e.g., blocks of
- // infinite loops). In these cases an artificial exit node is required.
- MultipleRoots |= (DT.isPostDominator() && N != GraphTraits<FuncT*>::size(&F));
+ // Helper struct used during edge insertions.
+ struct InsertionInfo {
+ using BucketElementTy = std::pair<unsigned, TreeNodePtr>;
+ struct DecreasingLevel {
+ bool operator()(const BucketElementTy &First,
+ const BucketElementTy &Second) const {
+ return First.first > Second.first;
+ }
+ };
+
+ std::priority_queue<BucketElementTy, SmallVector<BucketElementTy, 8>,
+ DecreasingLevel>
+ Bucket; // Queue of tree nodes sorted by level in descending order.
+ SmallDenseSet<TreeNodePtr, 8> Affected;
+ SmallDenseSet<TreeNodePtr, 8> Visited;
+ SmallVector<TreeNodePtr, 8> AffectedQueue;
+ SmallVector<TreeNodePtr, 8> VisitedNotAffectedQueue;
+ };
+
+ static void InsertEdge(DomTreeT &DT, const NodePtr From, const NodePtr To) {
+ assert(From && To && "Cannot connect nullptrs");
+ DEBUG(dbgs() << "Inserting edge " << BlockNamePrinter(From) << " -> "
+ << BlockNamePrinter(To) << "\n");
+ const TreeNodePtr FromTN = DT.getNode(From);
+
+ // Ignore edges from unreachable nodes.
+ if (!FromTN) return;
+
+ DT.DFSInfoValid = false;
+
+ const TreeNodePtr ToTN = DT.getNode(To);
+ if (!ToTN)
+ InsertUnreachable(DT, FromTN, To);
+ else
+ InsertReachable(DT, FromTN, ToTN);
+ }
- // When naively implemented, the Lengauer-Tarjan algorithm requires a separate
- // bucket for each vertex. However, this is unnecessary, because each vertex
- // is only placed into a single bucket (that of its semidominator), and each
- // vertex's bucket is processed before it is added to any bucket itself.
- //
- // Instead of using a bucket per vertex, we use a single array Buckets that
- // has two purposes. Before the vertex V with preorder number i is processed,
- // Buckets[i] stores the index of the first element in V's bucket. After V's
- // bucket is processed, Buckets[i] stores the index of the next element in the
- // bucket containing V, if any.
- SmallVector<unsigned, 32> Buckets;
- Buckets.resize(N + 1);
- for (unsigned i = 1; i <= N; ++i)
- Buckets[i] = i;
-
- for (unsigned i = N; i >= 2; --i) {
- typename GraphT::NodeRef W = DT.Vertex[i];
- auto &WInfo = DT.Info[W];
-
- // Step #2: Implicitly define the immediate dominator of vertices
- for (unsigned j = i; Buckets[j] != i; j = Buckets[j]) {
- typename GraphT::NodeRef V = DT.Vertex[Buckets[j]];
- typename GraphT::NodeRef U = Eval<GraphT>(DT, V, i + 1);
- DT.IDoms[V] = DT.Info[U].Semi < i ? U : W;
+ // Handles insertion to a node already in the dominator tree.
+ static void InsertReachable(DomTreeT &DT, const TreeNodePtr From,
+ const TreeNodePtr To) {
+ DEBUG(dbgs() << "\tReachable " << BlockNamePrinter(From->getBlock())
+ << " -> " << BlockNamePrinter(To->getBlock()) << "\n");
+ const NodePtr NCDBlock =
+ DT.findNearestCommonDominator(From->getBlock(), To->getBlock());
+ assert(NCDBlock || DT.isPostDominator());
+ const TreeNodePtr NCD = DT.getNode(NCDBlock);
+ assert(NCD);
+
+ DEBUG(dbgs() << "\t\tNCA == " << BlockNamePrinter(NCD) << "\n");
+ const TreeNodePtr ToIDom = To->getIDom();
+
+ // Nothing affected -- NCA property holds.
+ // (Based on the lemma 2.5 from the second paper.)
+ if (NCD == To || NCD == ToIDom) return;
+
+ // Identify and collect affected nodes.
+ InsertionInfo II;
+ DEBUG(dbgs() << "Marking " << BlockNamePrinter(To) << " as affected\n");
+ II.Affected.insert(To);
+ const unsigned ToLevel = To->getLevel();
+ DEBUG(dbgs() << "Putting " << BlockNamePrinter(To) << " into a Bucket\n");
+ II.Bucket.push({ToLevel, To});
+
+ while (!II.Bucket.empty()) {
+ const TreeNodePtr CurrentNode = II.Bucket.top().second;
+ II.Bucket.pop();
+ DEBUG(dbgs() << "\tAdding to Visited and AffectedQueue: "
+ << BlockNamePrinter(CurrentNode) << "\n");
+ II.Visited.insert(CurrentNode);
+ II.AffectedQueue.push_back(CurrentNode);
+
+ // Discover and collect affected successors of the current node.
+ VisitInsertion(DT, CurrentNode, CurrentNode->getLevel(), NCD, II);
}
- // Step #3: Calculate the semidominators of all vertices
-
- // initialize the semi dominator to point to the parent node
- WInfo.Semi = WInfo.Parent;
- typedef GraphTraits<Inverse<NodeT> > InvTraits;
- for (typename InvTraits::ChildIteratorType CI =
- InvTraits::child_begin(W),
- E = InvTraits::child_end(W); CI != E; ++CI) {
- typename InvTraits::NodeRef N = *CI;
- if (DT.Info.count(N)) { // Only if this predecessor is reachable!
- unsigned SemiU = DT.Info[Eval<GraphT>(DT, N, i + 1)].Semi;
- if (SemiU < WInfo.Semi)
- WInfo.Semi = SemiU;
+ // Finish by updating immediate dominators and levels.
+ UpdateInsertion(DT, NCD, II);
+ }
+
+ // Visits an affected node and collect its affected successors.
+ static void VisitInsertion(DomTreeT &DT, const TreeNodePtr TN,
+ const unsigned RootLevel, const TreeNodePtr NCD,
+ InsertionInfo &II) {
+ const unsigned NCDLevel = NCD->getLevel();
+ DEBUG(dbgs() << "Visiting " << BlockNamePrinter(TN) << "\n");
+
+ assert(TN->getBlock());
+ for (const NodePtr Succ :
+ ChildrenGetter<NodePtr, IsPostDom>::Get(TN->getBlock())) {
+ const TreeNodePtr SuccTN = DT.getNode(Succ);
+ assert(SuccTN && "Unreachable successor found at reachable insertion");
+ const unsigned SuccLevel = SuccTN->getLevel();
+
+ DEBUG(dbgs() << "\tSuccessor " << BlockNamePrinter(Succ)
+ << ", level = " << SuccLevel << "\n");
+
+ // Succ dominated by subtree From -- not affected.
+ // (Based on the lemma 2.5 from the second paper.)
+ if (SuccLevel > RootLevel) {
+ DEBUG(dbgs() << "\t\tDominated by subtree From\n");
+ if (II.Visited.count(SuccTN) != 0) continue;
+
+ DEBUG(dbgs() << "\t\tMarking visited not affected "
+ << BlockNamePrinter(Succ) << "\n");
+ II.Visited.insert(SuccTN);
+ II.VisitedNotAffectedQueue.push_back(SuccTN);
+ VisitInsertion(DT, SuccTN, RootLevel, NCD, II);
+ } else if ((SuccLevel > NCDLevel + 1) && II.Affected.count(SuccTN) == 0) {
+ DEBUG(dbgs() << "\t\tMarking affected and adding "
+ << BlockNamePrinter(Succ) << " to a Bucket\n");
+ II.Affected.insert(SuccTN);
+ II.Bucket.push({SuccLevel, SuccTN});
}
}
+ }
- // If V is a non-root vertex and sdom(V) = parent(V), then idom(V) is
- // necessarily parent(V). In this case, set idom(V) here and avoid placing
- // V into a bucket.
- if (WInfo.Semi == WInfo.Parent) {
- DT.IDoms[W] = DT.Vertex[WInfo.Parent];
- } else {
- Buckets[i] = Buckets[WInfo.Semi];
- Buckets[WInfo.Semi] = i;
+ // Updates immediate dominators and levels after insertion.
+ static void UpdateInsertion(DomTreeT &DT, const TreeNodePtr NCD,
+ InsertionInfo &II) {
+ DEBUG(dbgs() << "Updating NCD = " << BlockNamePrinter(NCD) << "\n");
+
+ for (const TreeNodePtr TN : II.AffectedQueue) {
+ DEBUG(dbgs() << "\tIDom(" << BlockNamePrinter(TN)
+ << ") = " << BlockNamePrinter(NCD) << "\n");
+ TN->setIDom(NCD);
+ }
+
+ UpdateLevelsAfterInsertion(II);
+ }
+
+ static void UpdateLevelsAfterInsertion(InsertionInfo &II) {
+ DEBUG(dbgs() << "Updating levels for visited but not affected nodes\n");
+
+ for (const TreeNodePtr TN : II.VisitedNotAffectedQueue) {
+ DEBUG(dbgs() << "\tlevel(" << BlockNamePrinter(TN) << ") = ("
+ << BlockNamePrinter(TN->getIDom()) << ") "
+ << TN->getIDom()->getLevel() << " + 1\n");
+ TN->UpdateLevel();
+ }
+ }
+
+ // Handles insertion to previously unreachable nodes.
+ static void InsertUnreachable(DomTreeT &DT, const TreeNodePtr From,
+ const NodePtr To) {
+ DEBUG(dbgs() << "Inserting " << BlockNamePrinter(From)
+ << " -> (unreachable) " << BlockNamePrinter(To) << "\n");
+
+ // Collect discovered edges to already reachable nodes.
+ SmallVector<std::pair<NodePtr, TreeNodePtr>, 8> DiscoveredEdgesToReachable;
+ // Discover and connect nodes that became reachable with the insertion.
+ ComputeUnreachableDominators(DT, To, From, DiscoveredEdgesToReachable);
+
+ DEBUG(dbgs() << "Inserted " << BlockNamePrinter(From)
+ << " -> (prev unreachable) " << BlockNamePrinter(To) << "\n");
+
+ DEBUG(DT.print(dbgs()));
+
+ // Used the discovered edges and inset discovered connecting (incoming)
+ // edges.
+ for (const auto &Edge : DiscoveredEdgesToReachable) {
+ DEBUG(dbgs() << "\tInserting discovered connecting edge "
+ << BlockNamePrinter(Edge.first) << " -> "
+ << BlockNamePrinter(Edge.second) << "\n");
+ InsertReachable(DT, DT.getNode(Edge.first), Edge.second);
}
}
- if (N >= 1) {
- typename GraphT::NodeRef Root = DT.Vertex[1];
- for (unsigned j = 1; Buckets[j] != 1; j = Buckets[j]) {
- typename GraphT::NodeRef V = DT.Vertex[Buckets[j]];
- DT.IDoms[V] = Root;
+ // Connects nodes that become reachable with an insertion.
+ static void ComputeUnreachableDominators(
+ DomTreeT &DT, const NodePtr Root, const TreeNodePtr Incoming,
+ SmallVectorImpl<std::pair<NodePtr, TreeNodePtr>>
+ &DiscoveredConnectingEdges) {
+ assert(!DT.getNode(Root) && "Root must not be reachable");
+
+ // Visit only previously unreachable nodes.
+ auto UnreachableDescender = [&DT, &DiscoveredConnectingEdges](NodePtr From,
+ NodePtr To) {
+ const TreeNodePtr ToTN = DT.getNode(To);
+ if (!ToTN) return true;
+
+ DiscoveredConnectingEdges.push_back({From, ToTN});
+ return false;
+ };
+
+ SemiNCAInfo SNCA;
+ SNCA.runDFS<IsPostDom>(Root, 0, UnreachableDescender, 0);
+ SNCA.runSemiNCA(DT);
+ SNCA.attachNewSubtree(DT, Incoming);
+
+ DEBUG(dbgs() << "After adding unreachable nodes\n");
+ DEBUG(DT.print(dbgs()));
+ }
+
+ // Checks if the tree contains all reachable nodes in the input graph.
+ bool verifyReachability(const DomTreeT &DT) {
+ clear();
+ doFullDFSWalk(DT, AlwaysDescend);
+
+ for (auto &NodeToTN : DT.DomTreeNodes) {
+ const TreeNodePtr TN = NodeToTN.second.get();
+ const NodePtr BB = TN->getBlock();
+
+ // Virtual root has a corresponding virtual CFG node.
+ if (DT.isVirtualRoot(TN)) continue;
+
+ if (NodeToInfo.count(BB) == 0) {
+ errs() << "DomTree node " << BlockNamePrinter(BB)
+ << " not found by DFS walk!\n";
+ errs().flush();
+
+ return false;
+ }
}
+
+ for (const NodePtr N : NumToNode) {
+ if (N && !DT.getNode(N)) {
+ errs() << "CFG node " << BlockNamePrinter(N)
+ << " not found in the DomTree!\n";
+ errs().flush();
+
+ return false;
+ }
+ }
+
+ return true;
}
- // Step #4: Explicitly define the immediate dominator of each vertex
- for (unsigned i = 2; i <= N; ++i) {
- typename GraphT::NodeRef W = DT.Vertex[i];
- typename GraphT::NodeRef &WIDom = DT.IDoms[W];
- if (WIDom != DT.Vertex[DT.Info[W].Semi])
- WIDom = DT.IDoms[WIDom];
+ static void DeleteEdge(DomTreeT &DT, const NodePtr From, const NodePtr To) {
+ assert(From && To && "Cannot disconnect nullptrs");
+ DEBUG(dbgs() << "Deleting edge " << BlockNamePrinter(From) << " -> "
+ << BlockNamePrinter(To) << "\n");
+
+#ifndef NDEBUG
+ // Ensure that the edge was in fact deleted from the CFG before informing
+ // the DomTree about it.
+ // The check is O(N), so run it only in debug configuration.
+ auto IsSuccessor = [](const NodePtr SuccCandidate, const NodePtr Of) {
+ auto Successors = ChildrenGetter<NodePtr, IsPostDom>::Get(Of);
+ return llvm::find(Successors, SuccCandidate) != Successors.end();
+ };
+ (void)IsSuccessor;
+ assert(!IsSuccessor(To, From) && "Deleted edge still exists in the CFG!");
+#endif
+
+ const TreeNodePtr FromTN = DT.getNode(From);
+ // Deletion in an unreachable subtree -- nothing to do.
+ if (!FromTN) return;
+
+ const TreeNodePtr ToTN = DT.getNode(To);
+ assert(ToTN && "To already unreachable -- there is no edge to delete");
+ const NodePtr NCDBlock = DT.findNearestCommonDominator(From, To);
+ const TreeNodePtr NCD = DT.getNode(NCDBlock);
+
+ // To dominates From -- nothing to do.
+ if (ToTN == NCD) return;
+
+ const TreeNodePtr ToIDom = ToTN->getIDom();
+ DEBUG(dbgs() << "\tNCD " << BlockNamePrinter(NCD) << ", ToIDom "
+ << BlockNamePrinter(ToIDom) << "\n");
+
+ // To remains reachable after deletion.
+ // (Based on the caption under Figure 4. from the second paper.)
+ if (FromTN != ToIDom || HasProperSupport(DT, ToTN))
+ DeleteReachable(DT, FromTN, ToTN);
+ else
+ DeleteUnreachable(DT, ToTN);
+ }
+
+ // Handles deletions that leave destination nodes reachable.
+ static void DeleteReachable(DomTreeT &DT, const TreeNodePtr FromTN,
+ const TreeNodePtr ToTN) {
+ DEBUG(dbgs() << "Deleting reachable " << BlockNamePrinter(FromTN) << " -> "
+ << BlockNamePrinter(ToTN) << "\n");
+ 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.)
+ const NodePtr ToIDom =
+ DT.findNearestCommonDominator(FromTN->getBlock(), ToTN->getBlock());
+ assert(ToIDom || DT.isPostDominator());
+ const TreeNodePtr ToIDomTN = DT.getNode(ToIDom);
+ assert(ToIDomTN);
+ const TreeNodePtr PrevIDomSubTree = ToIDomTN->getIDom();
+ // Top of the subtree to rebuild is the root node. Rebuild the tree from
+ // scratch.
+ if (!PrevIDomSubTree) {
+ DEBUG(dbgs() << "The entire tree needs to be rebuilt\n");
+ DT.recalculate(*DT.Parent);
+ return;
+ }
+
+ // Only visit nodes in the subtree starting at To.
+ const unsigned Level = ToIDomTN->getLevel();
+ auto DescendBelow = [Level, &DT](NodePtr, NodePtr To) {
+ return DT.getNode(To)->getLevel() > Level;
+ };
+
+ DEBUG(dbgs() << "\tTop of subtree: " << BlockNamePrinter(ToIDomTN) << "\n");
+
+ SemiNCAInfo SNCA;
+ SNCA.runDFS<IsPostDom>(ToIDom, 0, DescendBelow, 0);
+ DEBUG(dbgs() << "\tRunning Semi-NCA\n");
+ SNCA.runSemiNCA(DT, Level);
+ SNCA.reattachExistingSubtree(DT, PrevIDomSubTree);
}
- if (DT.Roots.empty()) return;
+ // Checks if a node has proper support, as defined on the page 3 and later
+ // explained on the page 7 of the second paper.
+ static bool HasProperSupport(DomTreeT &DT, const TreeNodePtr TN) {
+ DEBUG(dbgs() << "IsReachableFromIDom " << BlockNamePrinter(TN) << "\n");
+ for (const NodePtr Pred :
+ ChildrenGetter<NodePtr, !IsPostDom>::Get(TN->getBlock())) {
+ DEBUG(dbgs() << "\tPred " << BlockNamePrinter(Pred) << "\n");
+ if (!DT.getNode(Pred)) continue;
+
+ const NodePtr Support =
+ DT.findNearestCommonDominator(TN->getBlock(), Pred);
+ DEBUG(dbgs() << "\tSupport " << BlockNamePrinter(Support) << "\n");
+ if (Support != TN->getBlock()) {
+ DEBUG(dbgs() << "\t" << BlockNamePrinter(TN)
+ << " is reachable from support "
+ << BlockNamePrinter(Support) << "\n");
+ return true;
+ }
+ }
- // Add a node for the root. This node might be the actual root, if there is
- // one exit block, or it may be the virtual exit (denoted by (BasicBlock *)0)
- // which postdominates all real exits if there are multiple exit blocks, or
- // an infinite loop.
- typename GraphT::NodeRef Root = !MultipleRoots ? DT.Roots[0] : nullptr;
+ return false;
+ }
- DT.RootNode =
- (DT.DomTreeNodes[Root] =
- llvm::make_unique<DomTreeNodeBase<NodeType>>(Root, nullptr))
- .get();
+ // Handle deletions that make destination node unreachable.
+ // (Based on the lemma 2.7 from the second paper.)
+ static void DeleteUnreachable(DomTreeT &DT, const TreeNodePtr ToTN) {
+ DEBUG(dbgs() << "Deleting unreachable subtree " << BlockNamePrinter(ToTN)
+ << "\n");
+ assert(ToTN);
+ assert(ToTN->getBlock());
+
+ SmallVector<NodePtr, 16> AffectedQueue;
+ const unsigned Level = ToTN->getLevel();
+
+ // Traverse destination node's descendants with greater level in the tree
+ // and collect visited nodes.
+ auto DescendAndCollect = [Level, &AffectedQueue, &DT](NodePtr, NodePtr To) {
+ const TreeNodePtr TN = DT.getNode(To);
+ assert(TN);
+ if (TN->getLevel() > Level) return true;
+ if (llvm::find(AffectedQueue, To) == AffectedQueue.end())
+ AffectedQueue.push_back(To);
+
+ return false;
+ };
+
+ SemiNCAInfo SNCA;
+ unsigned LastDFSNum =
+ SNCA.runDFS<IsPostDom>(ToTN->getBlock(), 0, DescendAndCollect, 0);
+
+ TreeNodePtr MinNode = ToTN;
+
+ // Identify the top of the subtree to rebuilt by finding the NCD of all
+ // the affected nodes.
+ for (const NodePtr N : AffectedQueue) {
+ const TreeNodePtr TN = DT.getNode(N);
+ const NodePtr NCDBlock =
+ DT.findNearestCommonDominator(TN->getBlock(), ToTN->getBlock());
+ assert(NCDBlock || DT.isPostDominator());
+ const TreeNodePtr NCD = DT.getNode(NCDBlock);
+ assert(NCD);
+
+ DEBUG(dbgs() << "Processing affected node " << BlockNamePrinter(TN)
+ << " with NCD = " << BlockNamePrinter(NCD)
+ << ", MinNode =" << BlockNamePrinter(MinNode) << "\n");
+ if (NCD != TN && NCD->getLevel() < MinNode->getLevel()) MinNode = NCD;
+ }
- // Loop over all of the reachable blocks in the function...
- for (unsigned i = 2; i <= N; ++i) {
- typename GraphT::NodeRef W = DT.Vertex[i];
+ // Root reached, rebuild the whole tree from scratch.
+ if (!MinNode->getIDom()) {
+ DEBUG(dbgs() << "The entire tree needs to be rebuilt\n");
+ DT.recalculate(*DT.Parent);
+ return;
+ }
- // Don't replace this with 'count', the insertion side effect is important
- if (DT.DomTreeNodes[W])
- continue; // Haven't calculated this node yet?
+ // Erase the unreachable subtree in reverse preorder to process all children
+ // before deleting their parent.
+ for (unsigned i = LastDFSNum; i > 0; --i) {
+ const NodePtr N = SNCA.NumToNode[i];
+ const TreeNodePtr TN = DT.getNode(N);
+ DEBUG(dbgs() << "Erasing node " << BlockNamePrinter(TN) << "\n");
- typename GraphT::NodeRef ImmDom = DT.getIDom(W);
+ EraseNode(DT, TN);
+ }
- assert(ImmDom || DT.DomTreeNodes[nullptr]);
+ // The affected subtree start at the To node -- there's no extra work to do.
+ if (MinNode == ToTN) return;
+
+ DEBUG(dbgs() << "DeleteUnreachable: running DFS with MinNode = "
+ << BlockNamePrinter(MinNode) << "\n");
+ const unsigned MinLevel = MinNode->getLevel();
+ const TreeNodePtr PrevIDom = MinNode->getIDom();
+ assert(PrevIDom);
+ SNCA.clear();
+
+ // Identify nodes that remain in the affected subtree.
+ auto DescendBelow = [MinLevel, &DT](NodePtr, NodePtr To) {
+ const TreeNodePtr ToTN = DT.getNode(To);
+ return ToTN && ToTN->getLevel() > MinLevel;
+ };
+ SNCA.runDFS<IsPostDom>(MinNode->getBlock(), 0, DescendBelow, 0);
+
+ DEBUG(dbgs() << "Previous IDom(MinNode) = " << BlockNamePrinter(PrevIDom)
+ << "\nRunning Semi-NCA\n");
+
+ // Rebuild the remaining part of affected subtree.
+ SNCA.runSemiNCA(DT, MinLevel);
+ SNCA.reattachExistingSubtree(DT, PrevIDom);
+ }
- // Get or calculate the node for the immediate dominator
- DomTreeNodeBase<NodeType> *IDomNode = DT.getNodeForBlock(ImmDom);
+ // Removes leaf tree nodes from the dominator tree.
+ static void EraseNode(DomTreeT &DT, const TreeNodePtr TN) {
+ assert(TN);
+ assert(TN->getNumChildren() == 0 && "Not a tree leaf");
- // Add a new tree node for this BasicBlock, and link it as a child of
- // IDomNode
- DT.DomTreeNodes[W] = IDomNode->addChild(
- llvm::make_unique<DomTreeNodeBase<NodeType>>(W, IDomNode));
+ const TreeNodePtr IDom = TN->getIDom();
+ assert(IDom);
+
+ auto ChIt = llvm::find(IDom->Children, TN);
+ assert(ChIt != IDom->Children.end());
+ std::swap(*ChIt, IDom->Children.back());
+ IDom->Children.pop_back();
+
+ DT.DomTreeNodes.erase(TN->getBlock());
}
- // Free temporary memory used to construct idom's
- DT.IDoms.clear();
- DT.Info.clear();
- DT.Vertex.clear();
- DT.Vertex.shrink_to_fit();
+ //~~
+ //===--------------- DomTree correctness verification ---------------------===
+ //~~
+
+ // Check if for every parent with a level L in the tree all of its children
+ // have level L + 1.
+ static bool VerifyLevels(const DomTreeT &DT) {
+ for (auto &NodeToTN : DT.DomTreeNodes) {
+ const TreeNodePtr TN = NodeToTN.second.get();
+ const NodePtr BB = TN->getBlock();
+ if (!BB) continue;
+
+ const TreeNodePtr IDom = TN->getIDom();
+ if (!IDom && TN->getLevel() != 0) {
+ errs() << "Node without an IDom " << BlockNamePrinter(BB)
+ << " has a nonzero level " << TN->getLevel() << "!\n";
+ errs().flush();
+
+ return false;
+ }
+
+ if (IDom && TN->getLevel() != IDom->getLevel() + 1) {
+ errs() << "Node " << BlockNamePrinter(BB) << " has level "
+ << TN->getLevel() << " while its IDom "
+ << BlockNamePrinter(IDom->getBlock()) << " has level "
+ << IDom->getLevel() << "!\n";
+ errs().flush();
+
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ // Checks if for every edge From -> To in the graph
+ // NCD(From, To) == IDom(To) or To.
+ bool verifyNCD(const DomTreeT &DT) {
+ clear();
+ doFullDFSWalk(DT, AlwaysDescend);
+
+ for (auto &BlockToInfo : NodeToInfo) {
+ auto &Info = BlockToInfo.second;
+
+ const NodePtr From = NumToNode[Info.Parent];
+ if (!From) continue;
+
+ const NodePtr To = BlockToInfo.first;
+ const TreeNodePtr ToTN = DT.getNode(To);
+ assert(ToTN);
+
+ const NodePtr NCD = DT.findNearestCommonDominator(From, To);
+ const TreeNodePtr NCDTN = DT.getNode(NCD);
+ const TreeNodePtr ToIDom = ToTN->getIDom();
+ if (NCDTN != ToTN && NCDTN != ToIDom) {
+ errs() << "NearestCommonDominator verification failed:\n\tNCD(From:"
+ << BlockNamePrinter(From) << ", To:" << BlockNamePrinter(To)
+ << ") = " << BlockNamePrinter(NCD)
+ << ",\t (should be To or IDom[To]: " << BlockNamePrinter(ToIDom)
+ << ")\n";
+ errs().flush();
+
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ // The below routines verify the correctness of the dominator tree relative to
+ // the CFG it's coming from. A tree is a dominator tree iff it has two
+ // properties, called the parent property and the sibling property. Tarjan
+ // and Lengauer prove (but don't explicitly name) the properties as part of
+ // the proofs in their 1972 paper, but the proofs are mostly part of proving
+ // things about semidominators and idoms, and some of them are simply asserted
+ // based on even earlier papers (see, e.g., lemma 2). Some papers refer to
+ // these properties as "valid" and "co-valid". See, e.g., "Dominators,
+ // directed bipolar orders, and independent spanning trees" by Loukas
+ // Georgiadis and Robert E. Tarjan, as well as "Dominator Tree Verification
+ // and Vertex-Disjoint Paths " by the same authors.
+
+ // A very simple and direct explanation of these properties can be found in
+ // "An Experimental Study of Dynamic Dominators", found at
+ // https://arxiv.org/abs/1604.02711
+
+ // The easiest way to think of the parent property is that it's a requirement
+ // of being a dominator. Let's just take immediate dominators. For PARENT to
+ // be an immediate dominator of CHILD, all paths in the CFG must go through
+ // PARENT before they hit CHILD. This implies that if you were to cut PARENT
+ // out of the CFG, there should be no paths to CHILD that are reachable. If
+ // there are, then you now have a path from PARENT to CHILD that goes around
+ // PARENT and still reaches CHILD, which by definition, means PARENT can't be
+ // a dominator of CHILD (let alone an immediate one).
+
+ // The sibling property is similar. It says that for each pair of sibling
+ // nodes in the dominator tree (LEFT and RIGHT) , they must not dominate each
+ // other. If sibling LEFT dominated sibling RIGHT, it means there are no
+ // paths in the CFG from sibling LEFT to sibling RIGHT that do not go through
+ // 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.
+
+
+ // 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
+ // an ancestor of V in the tree.
+ //
+ // This means that if a node gets disconnected from the graph, then all of
+ // the nodes it dominated previously will now become unreachable.
+ bool verifyParentProperty(const DomTreeT &DT) {
+ for (auto &NodeToTN : DT.DomTreeNodes) {
+ const TreeNodePtr TN = NodeToTN.second.get();
+ const NodePtr BB = TN->getBlock();
+ if (!BB || TN->getChildren().empty()) continue;
+
+ clear();
+ doFullDFSWalk(DT, [BB](NodePtr From, NodePtr To) {
+ return From != BB && To != BB;
+ });
+
+ for (TreeNodePtr Child : TN->getChildren())
+ if (NodeToInfo.count(Child->getBlock()) != 0) {
+ errs() << "Child " << BlockNamePrinter(Child)
+ << " reachable after its parent " << BlockNamePrinter(BB)
+ << " is removed!\n";
+ errs().flush();
+
+ return false;
+ }
+ }
- DT.updateDFSNumbers();
+ return true;
+ }
+
+ // Check if the tree has sibling property: if a node V does not dominate a
+ // node W for all siblings V and W in the tree.
+ //
+ // This means that if a node gets disconnected from the graph, then all of its
+ // siblings will now still be reachable.
+ bool verifySiblingProperty(const DomTreeT &DT) {
+ for (auto &NodeToTN : DT.DomTreeNodes) {
+ const TreeNodePtr TN = NodeToTN.second.get();
+ const NodePtr BB = TN->getBlock();
+ if (!BB || TN->getChildren().empty()) continue;
+
+ const auto &Siblings = TN->getChildren();
+ for (const TreeNodePtr N : Siblings) {
+ clear();
+ NodePtr BBN = N->getBlock();
+ doFullDFSWalk(DT, [BBN](NodePtr From, NodePtr To) {
+ return From != BBN && To != BBN;
+ });
+
+ for (const TreeNodePtr S : Siblings) {
+ if (S == N) continue;
+
+ if (NodeToInfo.count(S->getBlock()) == 0) {
+ errs() << "Node " << BlockNamePrinter(S)
+ << " not reachable when its sibling " << BlockNamePrinter(N)
+ << " is removed!\n";
+ errs().flush();
+
+ return false;
+ }
+ }
+ }
+ }
+
+ return true;
+ }
+};
+
+
+template <class DomTreeT, class FuncT>
+void Calculate(DomTreeT &DT, FuncT &F) {
+ SemiNCAInfo<DomTreeT> SNCA;
+ SNCA.calculateFromScratch(DT, GraphTraits<FuncT *>::size(&F));
+}
+
+template <class DomTreeT>
+void InsertEdge(DomTreeT &DT, typename DomTreeT::NodePtr From,
+ typename DomTreeT::NodePtr To) {
+ if (DT.isPostDominator()) std::swap(From, To);
+ SemiNCAInfo<DomTreeT>::InsertEdge(DT, From, To);
+}
+
+template <class DomTreeT>
+void DeleteEdge(DomTreeT &DT, typename DomTreeT::NodePtr From,
+ typename DomTreeT::NodePtr To) {
+ if (DT.isPostDominator()) std::swap(From, To);
+ SemiNCAInfo<DomTreeT>::DeleteEdge(DT, From, To);
}
+
+template <class DomTreeT>
+bool Verify(const DomTreeT &DT) {
+ SemiNCAInfo<DomTreeT> SNCA;
+ return SNCA.verifyReachability(DT) && SNCA.VerifyLevels(DT) &&
+ SNCA.verifyNCD(DT) && SNCA.verifyParentProperty(DT) &&
+ SNCA.verifySiblingProperty(DT);
}
+} // namespace DomTreeBuilder
+} // namespace llvm
+
+#undef DEBUG_TYPE
+
#endif
diff --git a/contrib/llvm/include/llvm/Support/GraphWriter.h b/contrib/llvm/include/llvm/Support/GraphWriter.h
index 7555d5b..3df5c86 100644
--- a/contrib/llvm/include/llvm/Support/GraphWriter.h
+++ b/contrib/llvm/include/llvm/Support/GraphWriter.h
@@ -1,4 +1,4 @@
-//===-- llvm/Support/GraphWriter.h - Write graph to a .dot file -*- C++ -*-===//
+//===- llvm/Support/GraphWriter.h - Write graph to a .dot file --*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -24,30 +24,40 @@
#define LLVM_SUPPORT_GRAPHWRITER_H
#include "llvm/ADT/GraphTraits.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/DOTGraphTraits.h"
#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+#include <cstddef>
+#include <iterator>
+#include <string>
+#include <type_traits>
#include <vector>
namespace llvm {
namespace DOT { // Private functions...
- std::string EscapeString(const std::string &Label);
- /// \brief Get a color string for this node number. Simply round-robin selects
- /// from a reasonable number of colors.
- StringRef getColorString(unsigned NodeNumber);
-}
+std::string EscapeString(const std::string &Label);
+
+/// \brief Get a color string for this node number. Simply round-robin selects
+/// from a reasonable number of colors.
+StringRef getColorString(unsigned NodeNumber);
+
+} // end namespace DOT
namespace GraphProgram {
- enum Name {
- DOT,
- FDP,
- NEATO,
- TWOPI,
- CIRCO
- };
-}
+
+enum Name {
+ DOT,
+ FDP,
+ NEATO,
+ TWOPI,
+ CIRCO
+};
+
+} // end namespace GraphProgram
bool DisplayGraph(StringRef Filename, bool wait = true,
GraphProgram::Name program = GraphProgram::DOT);
@@ -57,11 +67,11 @@ class GraphWriter {
raw_ostream &O;
const GraphType &G;
- typedef DOTGraphTraits<GraphType> DOTTraits;
- typedef GraphTraits<GraphType> GTraits;
- typedef typename GTraits::NodeRef NodeRef;
- typedef typename GTraits::nodes_iterator node_iterator;
- typedef typename GTraits::ChildIteratorType child_iterator;
+ using DOTTraits = DOTGraphTraits<GraphType>;
+ using GTraits = GraphTraits<GraphType>;
+ using NodeRef = typename GTraits::NodeRef;
+ using node_iterator = typename GTraits::nodes_iterator;
+ using child_iterator = typename GTraits::ChildIteratorType;
DOTTraits DTraits;
static_assert(std::is_pointer<NodeRef>::value,
@@ -143,10 +153,9 @@ public:
void writeNodes() {
// Loop over the graph, printing it out...
- for (node_iterator I = GTraits::nodes_begin(G), E = GTraits::nodes_end(G);
- I != E; ++I)
- if (!isNodeHidden(*I))
- writeNode(*I);
+ for (const auto Node : nodes<GraphType>(G))
+ if (!isNodeHidden(Node))
+ writeNode(Node);
}
bool isNodeHidden(NodeRef Node) {
@@ -347,6 +356,6 @@ void ViewGraph(const GraphType &G, const Twine &Name,
DisplayGraph(Filename, false, Program);
}
-} // End llvm namespace
+} // end namespace llvm
-#endif
+#endif // LLVM_SUPPORT_GRAPHWRITER_H
diff --git a/contrib/llvm/include/llvm/Support/Host.h b/contrib/llvm/include/llvm/Support/Host.h
index 9df584c..be93dd9 100644
--- a/contrib/llvm/include/llvm/Support/Host.h
+++ b/contrib/llvm/include/llvm/Support/Host.h
@@ -15,11 +15,22 @@
#define LLVM_SUPPORT_HOST_H
#include "llvm/ADT/StringMap.h"
+#include "llvm/Support/MemoryBuffer.h"
#if defined(__linux__) || defined(__GNU__) || defined(__HAIKU__)
#include <endian.h>
#elif defined(_AIX)
#include <sys/machine.h>
+#elif defined(__sun)
+/* Solaris provides _BIG_ENDIAN/_LITTLE_ENDIAN selector in sys/types.h */
+#include <sys/types.h>
+#define BIG_ENDIAN 4321
+#define LITTLE_ENDIAN 1234
+#if defined(_BIG_ENDIAN)
+#define BYTE_ORDER BIG_ENDIAN
+#else
+#define BYTE_ORDER LITTLE_ENDIAN
+#endif
#else
#if !defined(BYTE_ORDER) && !defined(LLVM_ON_WIN32)
#include <machine/endian.h>
@@ -32,9 +43,9 @@ namespace llvm {
namespace sys {
#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && BYTE_ORDER == BIG_ENDIAN
- static const bool IsBigEndianHost = true;
+constexpr bool IsBigEndianHost = true;
#else
- static const bool IsBigEndianHost = false;
+constexpr bool IsBigEndianHost = false;
#endif
static const bool IsLittleEndianHost = !IsBigEndianHost;
@@ -75,6 +86,13 @@ namespace sys {
/// from thread::hardware_concurrency(), which includes hyperthreads).
/// Returns -1 if unknown for the current host system.
int getHostNumPhysicalCores();
+
+ namespace detail {
+ /// Helper functions to extract HostCPUName from /proc/cpuinfo on linux.
+ StringRef getHostCPUNameForPowerPC(const StringRef &ProcCpuinfoContent);
+ StringRef getHostCPUNameForARM(const StringRef &ProcCpuinfoContent);
+ StringRef getHostCPUNameForS390x(const StringRef &ProcCpuinfoContent);
+ }
}
}
diff --git a/contrib/llvm/include/llvm/Support/KnownBits.h b/contrib/llvm/include/llvm/Support/KnownBits.h
new file mode 100644
index 0000000..2c77d40
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/KnownBits.h
@@ -0,0 +1,200 @@
+//===- llvm/Support/KnownBits.h - Stores known zeros/ones -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains a class for representing known zeros and ones used by
+// computeKnownBits.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_KNOWNBITS_H
+#define LLVM_SUPPORT_KNOWNBITS_H
+
+#include "llvm/ADT/APInt.h"
+
+namespace llvm {
+
+// Struct for tracking the known zeros and ones of a value.
+struct KnownBits {
+ APInt Zero;
+ APInt One;
+
+private:
+ // Internal constructor for creating a ConstantRange from two APInts.
+ KnownBits(APInt Zero, APInt One)
+ : Zero(std::move(Zero)), One(std::move(One)) {}
+
+public:
+ // Default construct Zero and One.
+ KnownBits() {}
+
+ /// Create a known bits object of BitWidth bits initialized to unknown.
+ KnownBits(unsigned BitWidth) : Zero(BitWidth, 0), One(BitWidth, 0) {}
+
+ /// Get the bit width of this value.
+ unsigned getBitWidth() const {
+ assert(Zero.getBitWidth() == One.getBitWidth() &&
+ "Zero and One should have the same width!");
+ return Zero.getBitWidth();
+ }
+
+ /// Returns true if there is conflicting information.
+ bool hasConflict() const { return Zero.intersects(One); }
+
+ /// Returns true if we know the value of all bits.
+ bool isConstant() const {
+ assert(!hasConflict() && "KnownBits conflict!");
+ return Zero.countPopulation() + One.countPopulation() == getBitWidth();
+ }
+
+ /// Returns the value when all bits have a known value. This just returns One
+ /// with a protective assertion.
+ const APInt &getConstant() const {
+ assert(isConstant() && "Can only get value when all bits are known");
+ return One;
+ }
+
+ /// Returns true if we don't know any bits.
+ bool isUnknown() const { return Zero.isNullValue() && One.isNullValue(); }
+
+ /// Resets the known state of all bits.
+ void resetAll() {
+ Zero.clearAllBits();
+ One.clearAllBits();
+ }
+
+ /// Returns true if value is all zero.
+ bool isZero() const {
+ assert(!hasConflict() && "KnownBits conflict!");
+ return Zero.isAllOnesValue();
+ }
+
+ /// Returns true if value is all one bits.
+ bool isAllOnes() const {
+ assert(!hasConflict() && "KnownBits conflict!");
+ return One.isAllOnesValue();
+ }
+
+ /// Make all bits known to be zero and discard any previous information.
+ void setAllZero() {
+ Zero.setAllBits();
+ One.clearAllBits();
+ }
+
+ /// Make all bits known to be one and discard any previous information.
+ void setAllOnes() {
+ Zero.clearAllBits();
+ One.setAllBits();
+ }
+
+ /// Returns true if this value is known to be negative.
+ bool isNegative() const { return One.isSignBitSet(); }
+
+ /// Returns true if this value is known to be non-negative.
+ bool isNonNegative() const { return Zero.isSignBitSet(); }
+
+ /// Make this value negative.
+ void makeNegative() {
+ assert(!isNonNegative() && "Can't make a non-negative value negative");
+ One.setSignBit();
+ }
+
+ /// Make this value negative.
+ void makeNonNegative() {
+ assert(!isNegative() && "Can't make a negative value non-negative");
+ Zero.setSignBit();
+ }
+
+ /// Truncate the underlying known Zero and One bits. This is equivalent
+ /// to truncating the value we're tracking.
+ KnownBits trunc(unsigned BitWidth) {
+ return KnownBits(Zero.trunc(BitWidth), One.trunc(BitWidth));
+ }
+
+ /// Zero extends the underlying known Zero and One bits. This is equivalent
+ /// to zero extending the value we're tracking.
+ KnownBits zext(unsigned BitWidth) {
+ return KnownBits(Zero.zext(BitWidth), One.zext(BitWidth));
+ }
+
+ /// Sign extends the underlying known Zero and One bits. This is equivalent
+ /// to sign extending the value we're tracking.
+ KnownBits sext(unsigned BitWidth) {
+ return KnownBits(Zero.sext(BitWidth), One.sext(BitWidth));
+ }
+
+ /// Zero extends or truncates the underlying known Zero and One bits. This is
+ /// equivalent to zero extending or truncating the value we're tracking.
+ KnownBits zextOrTrunc(unsigned BitWidth) {
+ return KnownBits(Zero.zextOrTrunc(BitWidth), One.zextOrTrunc(BitWidth));
+ }
+
+ /// Returns the minimum number of trailing zero bits.
+ unsigned countMinTrailingZeros() const {
+ return Zero.countTrailingOnes();
+ }
+
+ /// Returns the minimum number of trailing one bits.
+ unsigned countMinTrailingOnes() const {
+ return One.countTrailingOnes();
+ }
+
+ /// Returns the minimum number of leading zero bits.
+ unsigned countMinLeadingZeros() const {
+ return Zero.countLeadingOnes();
+ }
+
+ /// Returns the minimum number of leading one bits.
+ unsigned countMinLeadingOnes() const {
+ return One.countLeadingOnes();
+ }
+
+ /// Returns the number of times the sign bit is replicated into the other
+ /// bits.
+ unsigned countMinSignBits() const {
+ if (isNonNegative())
+ return countMinLeadingZeros();
+ if (isNegative())
+ return countMinLeadingOnes();
+ return 0;
+ }
+
+ /// Returns the maximum number of trailing zero bits possible.
+ unsigned countMaxTrailingZeros() const {
+ return One.countTrailingZeros();
+ }
+
+ /// Returns the maximum number of trailing one bits possible.
+ unsigned countMaxTrailingOnes() const {
+ return Zero.countTrailingZeros();
+ }
+
+ /// Returns the maximum number of leading zero bits possible.
+ unsigned countMaxLeadingZeros() const {
+ return One.countLeadingZeros();
+ }
+
+ /// Returns the maximum number of leading one bits possible.
+ unsigned countMaxLeadingOnes() const {
+ return Zero.countLeadingZeros();
+ }
+
+ /// Returns the number of bits known to be one.
+ unsigned countMinPopulation() const {
+ return One.countPopulation();
+ }
+
+ /// Returns the maximum number of bits that could be one.
+ unsigned countMaxPopulation() const {
+ return getBitWidth() - Zero.countPopulation();
+ }
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/LEB128.h b/contrib/llvm/include/llvm/Support/LEB128.h
index 6a95432..29640db 100644
--- a/contrib/llvm/include/llvm/Support/LEB128.h
+++ b/contrib/llvm/include/llvm/Support/LEB128.h
@@ -20,7 +20,8 @@
namespace llvm {
/// Utility function to encode a SLEB128 value to an output stream.
-inline void encodeSLEB128(int64_t Value, raw_ostream &OS) {
+inline void encodeSLEB128(int64_t Value, raw_ostream &OS,
+ unsigned Padding = 0) {
bool More;
do {
uint8_t Byte = Value & 0x7f;
@@ -28,10 +29,44 @@ inline void encodeSLEB128(int64_t Value, raw_ostream &OS) {
Value >>= 7;
More = !((((Value == 0 ) && ((Byte & 0x40) == 0)) ||
((Value == -1) && ((Byte & 0x40) != 0))));
- if (More)
+ if (More || Padding != 0)
Byte |= 0x80; // Mark this byte to show that more bytes will follow.
OS << char(Byte);
} while (More);
+
+ // Pad with 0x80 and emit a terminating byte at the end.
+ if (Padding != 0) {
+ uint8_t PadValue = Value < 0 ? 0x7f : 0x00;
+ for (; Padding != 1; --Padding)
+ OS << char(PadValue | 0x80);
+ OS << char(PadValue);
+ }
+}
+
+/// Utility function to encode a SLEB128 value to a buffer. Returns
+/// the length in bytes of the encoded value.
+inline unsigned encodeSLEB128(int64_t Value, uint8_t *p, unsigned Padding = 0) {
+ uint8_t *orig_p = p;
+ bool More;
+ do {
+ uint8_t Byte = Value & 0x7f;
+ // NOTE: this assumes that this signed shift is an arithmetic right shift.
+ Value >>= 7;
+ More = !((((Value == 0 ) && ((Byte & 0x40) == 0)) ||
+ ((Value == -1) && ((Byte & 0x40) != 0))));
+ if (More || Padding != 0)
+ Byte |= 0x80; // Mark this byte to show that more bytes will follow.
+ *p++ = Byte;
+ } while (More);
+
+ // Pad with 0x80 and emit a terminating byte at the end.
+ if (Padding != 0) {
+ uint8_t PadValue = Value < 0 ? 0x7f : 0x00;
+ for (; Padding != 1; --Padding)
+ *p++ = (PadValue | 0x80);
+ *p++ = PadValue;
+ }
+ return (unsigned)(p - orig_p);
}
/// Utility function to encode a ULEB128 value to an output stream.
@@ -75,13 +110,31 @@ inline unsigned encodeULEB128(uint64_t Value, uint8_t *p,
return (unsigned)(p - orig_p);
}
-
/// Utility function to decode a ULEB128 value.
-inline uint64_t decodeULEB128(const uint8_t *p, unsigned *n = nullptr) {
+inline uint64_t decodeULEB128(const uint8_t *p, unsigned *n = nullptr,
+ const uint8_t *end = nullptr,
+ const char **error = nullptr) {
const uint8_t *orig_p = p;
uint64_t Value = 0;
unsigned Shift = 0;
+ if (error)
+ *error = nullptr;
do {
+ if (end && p == end) {
+ if (error)
+ *error = "malformed uleb128, extends past end";
+ if (n)
+ *n = (unsigned)(p - orig_p);
+ return 0;
+ }
+ uint64_t Slice = *p & 0x7f;
+ if (Shift >= 64 || Slice << Shift >> Shift != Slice) {
+ if (error)
+ *error = "uleb128 too big for uint64";
+ if (n)
+ *n = (unsigned)(p - orig_p);
+ return 0;
+ }
Value += uint64_t(*p & 0x7f) << Shift;
Shift += 7;
} while (*p++ >= 128);
@@ -91,14 +144,23 @@ inline uint64_t decodeULEB128(const uint8_t *p, unsigned *n = nullptr) {
}
/// Utility function to decode a SLEB128 value.
-inline int64_t decodeSLEB128(const uint8_t *p, unsigned *n = nullptr) {
+inline int64_t decodeSLEB128(const uint8_t *p, unsigned *n = nullptr,
+ const uint8_t *end = nullptr,
+ const char **error = nullptr) {
const uint8_t *orig_p = p;
int64_t Value = 0;
unsigned Shift = 0;
uint8_t Byte;
do {
+ if (end && p == end) {
+ if (error)
+ *error = "malformed sleb128, extends past end";
+ if (n)
+ *n = (unsigned)(p - orig_p);
+ return 0;
+ }
Byte = *p++;
- Value |= ((Byte & 0x7f) << Shift);
+ Value |= (int64_t(Byte & 0x7f) << Shift);
Shift += 7;
} while (Byte >= 128);
// Sign extend negative numbers.
@@ -109,13 +171,12 @@ inline int64_t decodeSLEB128(const uint8_t *p, unsigned *n = nullptr) {
return Value;
}
-
/// Utility function to get the size of the ULEB128-encoded value.
extern unsigned getULEB128Size(uint64_t Value);
/// Utility function to get the size of the SLEB128-encoded value.
extern unsigned getSLEB128Size(int64_t Value);
-} // namespace llvm
+} // namespace llvm
-#endif // LLVM_SYSTEM_LEB128_H
+#endif // LLVM_SYSTEM_LEB128_H
diff --git a/contrib/llvm/include/llvm/Support/LowLevelTypeImpl.h b/contrib/llvm/include/llvm/Support/LowLevelTypeImpl.h
new file mode 100644
index 0000000..c79dd0c
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/LowLevelTypeImpl.h
@@ -0,0 +1,309 @@
+//== llvm/Support/LowLevelTypeImpl.h --------------------------- -*- C++ -*-==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+/// Implement a low-level type suitable for MachineInstr level instruction
+/// selection.
+///
+/// For a type attached to a MachineInstr, we only care about 2 details: total
+/// size and the number of vector lanes (if any). Accordingly, there are 4
+/// possible valid type-kinds:
+///
+/// * `sN` for scalars and aggregates
+/// * `<N x sM>` for vectors, which must have at least 2 elements.
+/// * `pN` for pointers
+///
+/// Other information required for correct selection is expected to be carried
+/// by the opcode, or non-type flags. For example the distinction between G_ADD
+/// and G_FADD for int/float or fast-math flags.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_LOWLEVELTYPEIMPL_H
+#define LLVM_SUPPORT_LOWLEVELTYPEIMPL_H
+
+#include "llvm/ADT/DenseMapInfo.h"
+#include "llvm/CodeGen/MachineValueType.h"
+#include <cassert>
+
+namespace llvm {
+
+class DataLayout;
+class Type;
+class raw_ostream;
+
+class LLT {
+public:
+ /// Get a low-level scalar or aggregate "bag of bits".
+ static LLT scalar(unsigned SizeInBits) {
+ assert(SizeInBits > 0 && "invalid scalar size");
+ return LLT{/*isPointer=*/false, /*isVector=*/false, /*NumElements=*/0,
+ SizeInBits, /*AddressSpace=*/0};
+ }
+
+ /// Get a low-level pointer in the given address space (defaulting to 0).
+ static LLT pointer(uint16_t AddressSpace, unsigned SizeInBits) {
+ assert(SizeInBits > 0 && "invalid pointer size");
+ return LLT{/*isPointer=*/true, /*isVector=*/false, /*NumElements=*/0,
+ SizeInBits, AddressSpace};
+ }
+
+ /// Get a low-level vector of some number of elements and element width.
+ /// \p NumElements must be at least 2.
+ static LLT vector(uint16_t NumElements, unsigned ScalarSizeInBits) {
+ assert(NumElements > 1 && "invalid number of vector elements");
+ assert(ScalarSizeInBits > 0 && "invalid vector element size");
+ return LLT{/*isPointer=*/false, /*isVector=*/true, NumElements,
+ ScalarSizeInBits, /*AddressSpace=*/0};
+ }
+
+ /// Get a low-level vector of some number of elements and element type.
+ static LLT vector(uint16_t NumElements, LLT ScalarTy) {
+ assert(NumElements > 1 && "invalid number of vector elements");
+ assert(!ScalarTy.isVector() && "invalid vector element type");
+ return LLT{ScalarTy.isPointer(), /*isVector=*/true, NumElements,
+ ScalarTy.getSizeInBits(),
+ ScalarTy.isPointer() ? ScalarTy.getAddressSpace() : 0};
+ }
+
+ explicit LLT(bool isPointer, bool isVector, uint16_t NumElements,
+ unsigned SizeInBits, unsigned AddressSpace) {
+ init(isPointer, isVector, NumElements, SizeInBits, AddressSpace);
+ }
+ explicit LLT() : IsPointer(false), IsVector(false), RawData(0) {}
+
+ explicit LLT(MVT VT);
+
+ bool isValid() const { return RawData != 0; }
+
+ bool isScalar() const { return isValid() && !IsPointer && !IsVector; }
+
+ bool isPointer() const { return isValid() && IsPointer && !IsVector; }
+
+ bool isVector() const { return isValid() && IsVector; }
+
+ /// Returns the number of elements in a vector LLT. Must only be called on
+ /// vector types.
+ uint16_t getNumElements() const {
+ assert(IsVector && "cannot get number of elements on scalar/aggregate");
+ if (!IsPointer)
+ return getFieldValue(VectorElementsFieldInfo);
+ else
+ return getFieldValue(PointerVectorElementsFieldInfo);
+ }
+
+ /// Returns the total size of the type. Must only be called on sized types.
+ unsigned getSizeInBits() const {
+ if (isPointer() || isScalar())
+ return getScalarSizeInBits();
+ return getScalarSizeInBits() * getNumElements();
+ }
+
+ unsigned getScalarSizeInBits() const {
+ assert(RawData != 0 && "Invalid Type");
+ if (!IsVector) {
+ if (!IsPointer)
+ return getFieldValue(ScalarSizeFieldInfo);
+ else
+ return getFieldValue(PointerSizeFieldInfo);
+ } else {
+ if (!IsPointer)
+ return getFieldValue(VectorSizeFieldInfo);
+ else
+ return getFieldValue(PointerVectorSizeFieldInfo);
+ }
+ }
+
+ unsigned getAddressSpace() const {
+ assert(RawData != 0 && "Invalid Type");
+ assert(IsPointer && "cannot get address space of non-pointer type");
+ if (!IsVector)
+ return getFieldValue(PointerAddressSpaceFieldInfo);
+ else
+ return getFieldValue(PointerVectorAddressSpaceFieldInfo);
+ }
+
+ /// Returns the vector's element type. Only valid for vector types.
+ LLT getElementType() const {
+ assert(isVector() && "cannot get element type of scalar/aggregate");
+ if (IsPointer)
+ return pointer(getAddressSpace(), getScalarSizeInBits());
+ else
+ return scalar(getScalarSizeInBits());
+ }
+
+ /// Get a low-level type with half the size of the original, by halving the
+ /// size of the scalar type involved. For example `s32` will become `s16`,
+ /// `<2 x s32>` will become `<2 x s16>`.
+ LLT halfScalarSize() const {
+ assert(!IsPointer && getScalarSizeInBits() > 1 &&
+ getScalarSizeInBits() % 2 == 0 && "cannot half size of this type");
+ return LLT{/*isPointer=*/false, IsVector ? true : false,
+ IsVector ? getNumElements() : (uint16_t)0,
+ getScalarSizeInBits() / 2, /*AddressSpace=*/0};
+ }
+
+ /// Get a low-level type with twice the size of the original, by doubling the
+ /// size of the scalar type involved. For example `s32` will become `s64`,
+ /// `<2 x s32>` will become `<2 x s64>`.
+ LLT doubleScalarSize() const {
+ assert(!IsPointer && "cannot change size of this type");
+ return LLT{/*isPointer=*/false, IsVector ? true : false,
+ IsVector ? getNumElements() : (uint16_t)0,
+ getScalarSizeInBits() * 2, /*AddressSpace=*/0};
+ }
+
+ /// Get a low-level type with half the size of the original, by halving the
+ /// number of vector elements of the scalar type involved. The source must be
+ /// a vector type with an even number of elements. For example `<4 x s32>`
+ /// will become `<2 x s32>`, `<2 x s32>` will become `s32`.
+ LLT halfElements() const {
+ assert(isVector() && getNumElements() % 2 == 0 && "cannot half odd vector");
+ if (getNumElements() == 2)
+ return scalar(getScalarSizeInBits());
+
+ return LLT{/*isPointer=*/false, /*isVector=*/true,
+ (uint16_t)(getNumElements() / 2), getScalarSizeInBits(),
+ /*AddressSpace=*/0};
+ }
+
+ /// Get a low-level type with twice the size of the original, by doubling the
+ /// number of vector elements of the scalar type involved. The source must be
+ /// a vector type. For example `<2 x s32>` will become `<4 x s32>`. Doubling
+ /// the number of elements in sN produces <2 x sN>.
+ LLT doubleElements() const {
+ return LLT{IsPointer ? true : false, /*isVector=*/true,
+ (uint16_t)(getNumElements() * 2), getScalarSizeInBits(),
+ IsPointer ? getAddressSpace() : 0};
+ }
+
+ void print(raw_ostream &OS) const;
+
+ bool operator==(const LLT &RHS) const {
+ return IsPointer == RHS.IsPointer && IsVector == RHS.IsVector &&
+ RHS.RawData == RawData;
+ }
+
+ bool operator!=(const LLT &RHS) const { return !(*this == RHS); }
+
+ friend struct DenseMapInfo<LLT>;
+
+private:
+ /// LLT is packed into 64 bits as follows:
+ /// isPointer : 1
+ /// isVector : 1
+ /// with 62 bits remaining for Kind-specific data, packed in bitfields
+ /// as described below. As there isn't a simple portable way to pack bits
+ /// into bitfields, here the different fields in the packed structure is
+ /// described in static const *Field variables. Each of these variables
+ /// is a 2-element array, with the first element describing the bitfield size
+ /// and the second element describing the bitfield offset.
+ typedef int BitFieldInfo[2];
+ ///
+ /// This is how the bitfields are packed per Kind:
+ /// * Invalid:
+ /// gets encoded as RawData == 0, as that is an invalid encoding, since for
+ /// valid encodings, SizeInBits/SizeOfElement must be larger than 0.
+ /// * Non-pointer scalar (isPointer == 0 && isVector == 0):
+ /// SizeInBits: 32;
+ static const constexpr BitFieldInfo ScalarSizeFieldInfo{32, 0};
+ /// * Pointer (isPointer == 1 && isVector == 0):
+ /// SizeInBits: 16;
+ /// AddressSpace: 23;
+ static const constexpr BitFieldInfo PointerSizeFieldInfo{16, 0};
+ static const constexpr BitFieldInfo PointerAddressSpaceFieldInfo{
+ 23, PointerSizeFieldInfo[0] + PointerSizeFieldInfo[1]};
+ /// * Vector-of-non-pointer (isPointer == 0 && isVector == 1):
+ /// NumElements: 16;
+ /// SizeOfElement: 32;
+ static const constexpr BitFieldInfo VectorElementsFieldInfo{16, 0};
+ static const constexpr BitFieldInfo VectorSizeFieldInfo{
+ 32, VectorElementsFieldInfo[0] + VectorElementsFieldInfo[1]};
+ /// * Vector-of-pointer (isPointer == 1 && isVector == 1):
+ /// NumElements: 16;
+ /// SizeOfElement: 16;
+ /// AddressSpace: 23;
+ static const constexpr BitFieldInfo PointerVectorElementsFieldInfo{16, 0};
+ static const constexpr BitFieldInfo PointerVectorSizeFieldInfo{
+ 16,
+ PointerVectorElementsFieldInfo[1] + PointerVectorElementsFieldInfo[0]};
+ static const constexpr BitFieldInfo PointerVectorAddressSpaceFieldInfo{
+ 23, PointerVectorSizeFieldInfo[1] + PointerVectorSizeFieldInfo[0]};
+
+ uint64_t IsPointer : 1;
+ uint64_t IsVector : 1;
+ uint64_t RawData : 62;
+
+ static uint64_t getMask(const BitFieldInfo FieldInfo) {
+ const int FieldSizeInBits = FieldInfo[0];
+ return (((uint64_t)1) << FieldSizeInBits) - 1;
+ }
+ static uint64_t maskAndShift(uint64_t Val, uint64_t Mask, uint8_t Shift) {
+ assert(Val <= Mask && "Value too large for field");
+ return (Val & Mask) << Shift;
+ }
+ static uint64_t maskAndShift(uint64_t Val, const BitFieldInfo FieldInfo) {
+ return maskAndShift(Val, getMask(FieldInfo), FieldInfo[1]);
+ }
+ uint64_t getFieldValue(const BitFieldInfo FieldInfo) const {
+ return getMask(FieldInfo) & (RawData >> FieldInfo[1]);
+ }
+
+ void init(bool IsPointer, bool IsVector, uint16_t NumElements,
+ unsigned SizeInBits, unsigned AddressSpace) {
+ this->IsPointer = IsPointer;
+ this->IsVector = IsVector;
+ if (!IsVector) {
+ if (!IsPointer)
+ RawData = maskAndShift(SizeInBits, ScalarSizeFieldInfo);
+ else
+ RawData = maskAndShift(SizeInBits, PointerSizeFieldInfo) |
+ maskAndShift(AddressSpace, PointerAddressSpaceFieldInfo);
+ } else {
+ assert(NumElements > 1 && "invalid number of vector elements");
+ if (!IsPointer)
+ RawData = maskAndShift(NumElements, VectorElementsFieldInfo) |
+ maskAndShift(SizeInBits, VectorSizeFieldInfo);
+ else
+ RawData =
+ maskAndShift(NumElements, PointerVectorElementsFieldInfo) |
+ maskAndShift(SizeInBits, PointerVectorSizeFieldInfo) |
+ maskAndShift(AddressSpace, PointerVectorAddressSpaceFieldInfo);
+ }
+ }
+};
+
+inline raw_ostream& operator<<(raw_ostream &OS, const LLT &Ty) {
+ Ty.print(OS);
+ return OS;
+}
+
+template<> struct DenseMapInfo<LLT> {
+ static inline LLT getEmptyKey() {
+ LLT Invalid;
+ Invalid.IsPointer = true;
+ return Invalid;
+ }
+ static inline LLT getTombstoneKey() {
+ LLT Invalid;
+ Invalid.IsVector = true;
+ return Invalid;
+ }
+ static inline unsigned getHashValue(const LLT &Ty) {
+ uint64_t Val = ((uint64_t)Ty.RawData) << 2 | ((uint64_t)Ty.IsPointer) << 1 |
+ ((uint64_t)Ty.IsVector);
+ return DenseMapInfo<uint64_t>::getHashValue(Val);
+ }
+ static bool isEqual(const LLT &LHS, const LLT &RHS) {
+ return LHS == RHS;
+ }
+};
+
+}
+
+#endif // LLVM_SUPPORT_LOWLEVELTYPEIMPL_H
diff --git a/contrib/llvm/include/llvm/Support/MD5.h b/contrib/llvm/include/llvm/Support/MD5.h
index eb181bf..2c0dc76 100644
--- a/contrib/llvm/include/llvm/Support/MD5.h
+++ b/contrib/llvm/include/llvm/Support/MD5.h
@@ -1,4 +1,4 @@
-/*
+/* -*- C++ -*-
* This code is derived from (original license follows):
*
* This is an OpenSSL-compatible implementation of the RSA Data Security, Inc.
@@ -29,24 +29,55 @@
#define LLVM_SUPPORT_MD5_H
#include "llvm/ADT/SmallString.h"
-#include "llvm/Support/DataTypes.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Endian.h"
#include <array>
+#include <cstdint>
namespace llvm {
+
template <typename T> class ArrayRef;
class MD5 {
// Any 32-bit or wider unsigned integer data type will do.
typedef uint32_t MD5_u32plus;
- MD5_u32plus a, b, c, d;
- MD5_u32plus hi, lo;
+ MD5_u32plus a = 0x67452301;
+ MD5_u32plus b = 0xefcdab89;
+ MD5_u32plus c = 0x98badcfe;
+ MD5_u32plus d = 0x10325476;
+ MD5_u32plus hi = 0;
+ MD5_u32plus lo = 0;
uint8_t buffer[64];
MD5_u32plus block[16];
public:
- typedef uint8_t MD5Result[16];
+ struct MD5Result {
+ std::array<uint8_t, 16> Bytes;
+
+ operator std::array<uint8_t, 16>() const { return Bytes; }
+
+ const uint8_t &operator[](size_t I) const { return Bytes[I]; }
+ uint8_t &operator[](size_t I) { return Bytes[I]; }
+
+ SmallString<32> digest() const;
+
+ uint64_t low() const {
+ // Our MD5 implementation returns the result in little endian, so the low
+ // word is first.
+ using namespace support;
+ return endian::read<uint64_t, little, unaligned>(Bytes.data());
+ }
+
+ uint64_t high() const {
+ using namespace support;
+ return endian::read<uint64_t, little, unaligned>(Bytes.data() + 8);
+ }
+ std::pair<uint64_t, uint64_t> words() const {
+ using namespace support;
+ return std::make_pair(high(), low());
+ }
+ };
MD5();
@@ -70,18 +101,22 @@ private:
const uint8_t *body(ArrayRef<uint8_t> Data);
};
+inline bool operator==(const MD5::MD5Result &LHS, const MD5::MD5Result &RHS) {
+ return LHS.Bytes == RHS.Bytes;
+}
+
/// Helper to compute and return lower 64 bits of the given string's MD5 hash.
inline uint64_t MD5Hash(StringRef Str) {
+ using namespace support;
+
MD5 Hash;
Hash.update(Str);
- llvm::MD5::MD5Result Result;
+ MD5::MD5Result Result;
Hash.final(Result);
- // Return the least significant 8 bytes. Our MD5 implementation returns the
- // result in little endian, so we may need to swap bytes.
- using namespace llvm::support;
- return endian::read<uint64_t, little, unaligned>(Result);
+ // Return the least significant word.
+ return Result.low();
}
-}
+} // end namespace llvm
-#endif
+#endif // LLVM_SUPPORT_MD5_H
diff --git a/contrib/llvm/include/llvm/Support/MachO.h b/contrib/llvm/include/llvm/Support/MachO.h
deleted file mode 100644
index 2b23c0f..0000000
--- a/contrib/llvm/include/llvm/Support/MachO.h
+++ /dev/null
@@ -1,1936 +0,0 @@
-//===-- llvm/Support/MachO.h - The MachO file format ------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines manifest constants for the MachO object file format.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SUPPORT_MACHO_H
-#define LLVM_SUPPORT_MACHO_H
-
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/DataTypes.h"
-#include "llvm/Support/Host.h"
-
-namespace llvm {
- namespace MachO {
- // Enums from <mach-o/loader.h>
- enum : uint32_t {
- // Constants for the "magic" field in llvm::MachO::mach_header and
- // llvm::MachO::mach_header_64
- MH_MAGIC = 0xFEEDFACEu,
- MH_CIGAM = 0xCEFAEDFEu,
- MH_MAGIC_64 = 0xFEEDFACFu,
- MH_CIGAM_64 = 0xCFFAEDFEu,
- FAT_MAGIC = 0xCAFEBABEu,
- FAT_CIGAM = 0xBEBAFECAu,
- FAT_MAGIC_64 = 0xCAFEBABFu,
- FAT_CIGAM_64 = 0xBFBAFECAu
- };
-
- enum HeaderFileType {
- // Constants for the "filetype" field in llvm::MachO::mach_header and
- // llvm::MachO::mach_header_64
- MH_OBJECT = 0x1u,
- MH_EXECUTE = 0x2u,
- MH_FVMLIB = 0x3u,
- MH_CORE = 0x4u,
- MH_PRELOAD = 0x5u,
- MH_DYLIB = 0x6u,
- MH_DYLINKER = 0x7u,
- MH_BUNDLE = 0x8u,
- MH_DYLIB_STUB = 0x9u,
- MH_DSYM = 0xAu,
- MH_KEXT_BUNDLE = 0xBu
- };
-
- enum {
- // Constant bits for the "flags" field in llvm::MachO::mach_header and
- // llvm::MachO::mach_header_64
- MH_NOUNDEFS = 0x00000001u,
- MH_INCRLINK = 0x00000002u,
- MH_DYLDLINK = 0x00000004u,
- MH_BINDATLOAD = 0x00000008u,
- MH_PREBOUND = 0x00000010u,
- MH_SPLIT_SEGS = 0x00000020u,
- MH_LAZY_INIT = 0x00000040u,
- MH_TWOLEVEL = 0x00000080u,
- MH_FORCE_FLAT = 0x00000100u,
- MH_NOMULTIDEFS = 0x00000200u,
- MH_NOFIXPREBINDING = 0x00000400u,
- MH_PREBINDABLE = 0x00000800u,
- MH_ALLMODSBOUND = 0x00001000u,
- MH_SUBSECTIONS_VIA_SYMBOLS = 0x00002000u,
- MH_CANONICAL = 0x00004000u,
- MH_WEAK_DEFINES = 0x00008000u,
- MH_BINDS_TO_WEAK = 0x00010000u,
- MH_ALLOW_STACK_EXECUTION = 0x00020000u,
- MH_ROOT_SAFE = 0x00040000u,
- MH_SETUID_SAFE = 0x00080000u,
- MH_NO_REEXPORTED_DYLIBS = 0x00100000u,
- MH_PIE = 0x00200000u,
- MH_DEAD_STRIPPABLE_DYLIB = 0x00400000u,
- MH_HAS_TLV_DESCRIPTORS = 0x00800000u,
- MH_NO_HEAP_EXECUTION = 0x01000000u,
- MH_APP_EXTENSION_SAFE = 0x02000000u
- };
-
- enum : uint32_t {
- // Flags for the "cmd" field in llvm::MachO::load_command
- LC_REQ_DYLD = 0x80000000u
- };
-
-#define HANDLE_LOAD_COMMAND(LCName, LCValue, LCStruct) \
- LCName = LCValue,
-
- enum LoadCommandType : uint32_t {
- #include "llvm/Support/MachO.def"
- };
-
-#undef HANDLE_LOAD_COMMAND
-
- enum : uint32_t {
- // Constant bits for the "flags" field in llvm::MachO::segment_command
- SG_HIGHVM = 0x1u,
- SG_FVMLIB = 0x2u,
- SG_NORELOC = 0x4u,
- SG_PROTECTED_VERSION_1 = 0x8u,
-
- // Constant masks for the "flags" field in llvm::MachO::section and
- // llvm::MachO::section_64
- SECTION_TYPE = 0x000000ffu, // SECTION_TYPE
- SECTION_ATTRIBUTES = 0xffffff00u, // SECTION_ATTRIBUTES
- SECTION_ATTRIBUTES_USR = 0xff000000u, // SECTION_ATTRIBUTES_USR
- SECTION_ATTRIBUTES_SYS = 0x00ffff00u // SECTION_ATTRIBUTES_SYS
- };
-
- /// These are the section type and attributes fields. A MachO section can
- /// have only one Type, but can have any of the attributes specified.
- enum SectionType : uint32_t {
- // Constant masks for the "flags[7:0]" field in llvm::MachO::section and
- // llvm::MachO::section_64 (mask "flags" with SECTION_TYPE)
-
- /// S_REGULAR - Regular section.
- S_REGULAR = 0x00u,
- /// S_ZEROFILL - Zero fill on demand section.
- S_ZEROFILL = 0x01u,
- /// S_CSTRING_LITERALS - Section with literal C strings.
- S_CSTRING_LITERALS = 0x02u,
- /// S_4BYTE_LITERALS - Section with 4 byte literals.
- S_4BYTE_LITERALS = 0x03u,
- /// S_8BYTE_LITERALS - Section with 8 byte literals.
- S_8BYTE_LITERALS = 0x04u,
- /// S_LITERAL_POINTERS - Section with pointers to literals.
- S_LITERAL_POINTERS = 0x05u,
- /// S_NON_LAZY_SYMBOL_POINTERS - Section with non-lazy symbol pointers.
- S_NON_LAZY_SYMBOL_POINTERS = 0x06u,
- /// S_LAZY_SYMBOL_POINTERS - Section with lazy symbol pointers.
- S_LAZY_SYMBOL_POINTERS = 0x07u,
- /// S_SYMBOL_STUBS - Section with symbol stubs, byte size of stub in
- /// the Reserved2 field.
- S_SYMBOL_STUBS = 0x08u,
- /// S_MOD_INIT_FUNC_POINTERS - Section with only function pointers for
- /// initialization.
- S_MOD_INIT_FUNC_POINTERS = 0x09u,
- /// S_MOD_TERM_FUNC_POINTERS - Section with only function pointers for
- /// termination.
- S_MOD_TERM_FUNC_POINTERS = 0x0au,
- /// S_COALESCED - Section contains symbols that are to be coalesced.
- S_COALESCED = 0x0bu,
- /// S_GB_ZEROFILL - Zero fill on demand section (that can be larger than 4
- /// gigabytes).
- S_GB_ZEROFILL = 0x0cu,
- /// S_INTERPOSING - Section with only pairs of function pointers for
- /// interposing.
- S_INTERPOSING = 0x0du,
- /// S_16BYTE_LITERALS - Section with only 16 byte literals.
- S_16BYTE_LITERALS = 0x0eu,
- /// S_DTRACE_DOF - Section contains DTrace Object Format.
- S_DTRACE_DOF = 0x0fu,
- /// S_LAZY_DYLIB_SYMBOL_POINTERS - Section with lazy symbol pointers to
- /// lazy loaded dylibs.
- S_LAZY_DYLIB_SYMBOL_POINTERS = 0x10u,
- /// S_THREAD_LOCAL_REGULAR - Thread local data section.
- S_THREAD_LOCAL_REGULAR = 0x11u,
- /// S_THREAD_LOCAL_ZEROFILL - Thread local zerofill section.
- S_THREAD_LOCAL_ZEROFILL = 0x12u,
- /// S_THREAD_LOCAL_VARIABLES - Section with thread local variable
- /// structure data.
- S_THREAD_LOCAL_VARIABLES = 0x13u,
- /// S_THREAD_LOCAL_VARIABLE_POINTERS - Section with pointers to thread
- /// local structures.
- S_THREAD_LOCAL_VARIABLE_POINTERS = 0x14u,
- /// S_THREAD_LOCAL_INIT_FUNCTION_POINTERS - Section with thread local
- /// variable initialization pointers to functions.
- S_THREAD_LOCAL_INIT_FUNCTION_POINTERS = 0x15u,
-
- LAST_KNOWN_SECTION_TYPE = S_THREAD_LOCAL_INIT_FUNCTION_POINTERS
- };
-
- enum : uint32_t {
- // Constant masks for the "flags[31:24]" field in llvm::MachO::section and
- // llvm::MachO::section_64 (mask "flags" with SECTION_ATTRIBUTES_USR)
-
- /// S_ATTR_PURE_INSTRUCTIONS - Section contains only true machine
- /// instructions.
- S_ATTR_PURE_INSTRUCTIONS = 0x80000000u,
- /// S_ATTR_NO_TOC - Section contains coalesced symbols that are not to be
- /// in a ranlib table of contents.
- S_ATTR_NO_TOC = 0x40000000u,
- /// S_ATTR_STRIP_STATIC_SYMS - Ok to strip static symbols in this section
- /// in files with the MY_DYLDLINK flag.
- S_ATTR_STRIP_STATIC_SYMS = 0x20000000u,
- /// S_ATTR_NO_DEAD_STRIP - No dead stripping.
- S_ATTR_NO_DEAD_STRIP = 0x10000000u,
- /// S_ATTR_LIVE_SUPPORT - Blocks are live if they reference live blocks.
- S_ATTR_LIVE_SUPPORT = 0x08000000u,
- /// S_ATTR_SELF_MODIFYING_CODE - Used with i386 code stubs written on by
- /// dyld.
- S_ATTR_SELF_MODIFYING_CODE = 0x04000000u,
- /// S_ATTR_DEBUG - A debug section.
- S_ATTR_DEBUG = 0x02000000u,
-
- // Constant masks for the "flags[23:8]" field in llvm::MachO::section and
- // llvm::MachO::section_64 (mask "flags" with SECTION_ATTRIBUTES_SYS)
-
- /// S_ATTR_SOME_INSTRUCTIONS - Section contains some machine instructions.
- S_ATTR_SOME_INSTRUCTIONS = 0x00000400u,
- /// S_ATTR_EXT_RELOC - Section has external relocation entries.
- S_ATTR_EXT_RELOC = 0x00000200u,
- /// S_ATTR_LOC_RELOC - Section has local relocation entries.
- S_ATTR_LOC_RELOC = 0x00000100u,
-
- // Constant masks for the value of an indirect symbol in an indirect
- // symbol table
- INDIRECT_SYMBOL_LOCAL = 0x80000000u,
- INDIRECT_SYMBOL_ABS = 0x40000000u
- };
-
- enum DataRegionType {
- // Constants for the "kind" field in a data_in_code_entry structure
- DICE_KIND_DATA = 1u,
- DICE_KIND_JUMP_TABLE8 = 2u,
- DICE_KIND_JUMP_TABLE16 = 3u,
- DICE_KIND_JUMP_TABLE32 = 4u,
- DICE_KIND_ABS_JUMP_TABLE32 = 5u
- };
-
- enum RebaseType {
- REBASE_TYPE_POINTER = 1u,
- REBASE_TYPE_TEXT_ABSOLUTE32 = 2u,
- REBASE_TYPE_TEXT_PCREL32 = 3u
- };
-
- enum {
- REBASE_OPCODE_MASK = 0xF0u,
- REBASE_IMMEDIATE_MASK = 0x0Fu
- };
-
- enum RebaseOpcode {
- REBASE_OPCODE_DONE = 0x00u,
- REBASE_OPCODE_SET_TYPE_IMM = 0x10u,
- REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB = 0x20u,
- REBASE_OPCODE_ADD_ADDR_ULEB = 0x30u,
- REBASE_OPCODE_ADD_ADDR_IMM_SCALED = 0x40u,
- REBASE_OPCODE_DO_REBASE_IMM_TIMES = 0x50u,
- REBASE_OPCODE_DO_REBASE_ULEB_TIMES = 0x60u,
- REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB = 0x70u,
- REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB = 0x80u
- };
-
- enum BindType {
- BIND_TYPE_POINTER = 1u,
- BIND_TYPE_TEXT_ABSOLUTE32 = 2u,
- BIND_TYPE_TEXT_PCREL32 = 3u
- };
-
- enum BindSpecialDylib {
- BIND_SPECIAL_DYLIB_SELF = 0,
- BIND_SPECIAL_DYLIB_MAIN_EXECUTABLE = -1,
- BIND_SPECIAL_DYLIB_FLAT_LOOKUP = -2
- };
-
- enum {
- BIND_SYMBOL_FLAGS_WEAK_IMPORT = 0x1u,
- BIND_SYMBOL_FLAGS_NON_WEAK_DEFINITION = 0x8u,
-
- BIND_OPCODE_MASK = 0xF0u,
- BIND_IMMEDIATE_MASK = 0x0Fu
- };
-
- enum BindOpcode {
- BIND_OPCODE_DONE = 0x00u,
- BIND_OPCODE_SET_DYLIB_ORDINAL_IMM = 0x10u,
- BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB = 0x20u,
- BIND_OPCODE_SET_DYLIB_SPECIAL_IMM = 0x30u,
- BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM = 0x40u,
- BIND_OPCODE_SET_TYPE_IMM = 0x50u,
- BIND_OPCODE_SET_ADDEND_SLEB = 0x60u,
- BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB = 0x70u,
- BIND_OPCODE_ADD_ADDR_ULEB = 0x80u,
- BIND_OPCODE_DO_BIND = 0x90u,
- BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB = 0xA0u,
- BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED = 0xB0u,
- BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB = 0xC0u
- };
-
- enum {
- EXPORT_SYMBOL_FLAGS_KIND_MASK = 0x03u,
- EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION = 0x04u,
- EXPORT_SYMBOL_FLAGS_REEXPORT = 0x08u,
- EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER = 0x10u
- };
-
- enum ExportSymbolKind {
- EXPORT_SYMBOL_FLAGS_KIND_REGULAR = 0x00u,
- EXPORT_SYMBOL_FLAGS_KIND_THREAD_LOCAL = 0x01u,
- EXPORT_SYMBOL_FLAGS_KIND_ABSOLUTE = 0x02u
- };
-
- enum {
- // Constant masks for the "n_type" field in llvm::MachO::nlist and
- // llvm::MachO::nlist_64
- N_STAB = 0xe0,
- N_PEXT = 0x10,
- N_TYPE = 0x0e,
- N_EXT = 0x01
- };
-
- enum NListType : uint8_t {
- // Constants for the "n_type & N_TYPE" llvm::MachO::nlist and
- // llvm::MachO::nlist_64
- N_UNDF = 0x0u,
- N_ABS = 0x2u,
- N_SECT = 0xeu,
- N_PBUD = 0xcu,
- N_INDR = 0xau
- };
-
- enum SectionOrdinal {
- // Constants for the "n_sect" field in llvm::MachO::nlist and
- // llvm::MachO::nlist_64
- NO_SECT = 0u,
- MAX_SECT = 0xffu
- };
-
- enum {
- // Constant masks for the "n_desc" field in llvm::MachO::nlist and
- // llvm::MachO::nlist_64
- // The low 3 bits are the for the REFERENCE_TYPE.
- REFERENCE_TYPE = 0x7,
- REFERENCE_FLAG_UNDEFINED_NON_LAZY = 0,
- REFERENCE_FLAG_UNDEFINED_LAZY = 1,
- REFERENCE_FLAG_DEFINED = 2,
- REFERENCE_FLAG_PRIVATE_DEFINED = 3,
- REFERENCE_FLAG_PRIVATE_UNDEFINED_NON_LAZY = 4,
- REFERENCE_FLAG_PRIVATE_UNDEFINED_LAZY = 5,
- // Flag bits (some overlap with the library ordinal bits).
- N_ARM_THUMB_DEF = 0x0008u,
- REFERENCED_DYNAMICALLY = 0x0010u,
- N_NO_DEAD_STRIP = 0x0020u,
- N_WEAK_REF = 0x0040u,
- N_WEAK_DEF = 0x0080u,
- N_SYMBOL_RESOLVER = 0x0100u,
- N_ALT_ENTRY = 0x0200u,
- // For undefined symbols coming from libraries, see GET_LIBRARY_ORDINAL()
- // as these are in the top 8 bits.
- SELF_LIBRARY_ORDINAL = 0x0,
- MAX_LIBRARY_ORDINAL = 0xfd,
- DYNAMIC_LOOKUP_ORDINAL = 0xfe,
- EXECUTABLE_ORDINAL = 0xff
- };
-
- enum StabType {
- // Constant values for the "n_type" field in llvm::MachO::nlist and
- // llvm::MachO::nlist_64 when "(n_type & N_STAB) != 0"
- N_GSYM = 0x20u,
- N_FNAME = 0x22u,
- N_FUN = 0x24u,
- N_STSYM = 0x26u,
- N_LCSYM = 0x28u,
- N_BNSYM = 0x2Eu,
- N_PC = 0x30u,
- N_AST = 0x32u,
- N_OPT = 0x3Cu,
- N_RSYM = 0x40u,
- N_SLINE = 0x44u,
- N_ENSYM = 0x4Eu,
- N_SSYM = 0x60u,
- N_SO = 0x64u,
- N_OSO = 0x66u,
- N_LSYM = 0x80u,
- N_BINCL = 0x82u,
- N_SOL = 0x84u,
- N_PARAMS = 0x86u,
- N_VERSION = 0x88u,
- N_OLEVEL = 0x8Au,
- N_PSYM = 0xA0u,
- N_EINCL = 0xA2u,
- N_ENTRY = 0xA4u,
- N_LBRAC = 0xC0u,
- N_EXCL = 0xC2u,
- N_RBRAC = 0xE0u,
- N_BCOMM = 0xE2u,
- N_ECOMM = 0xE4u,
- N_ECOML = 0xE8u,
- N_LENG = 0xFEu
- };
-
- enum : uint32_t {
- // Constant values for the r_symbolnum field in an
- // llvm::MachO::relocation_info structure when r_extern is 0.
- R_ABS = 0,
-
- // Constant bits for the r_address field in an
- // llvm::MachO::relocation_info structure.
- R_SCATTERED = 0x80000000
- };
-
- enum RelocationInfoType {
- // Constant values for the r_type field in an
- // llvm::MachO::relocation_info or llvm::MachO::scattered_relocation_info
- // structure.
- GENERIC_RELOC_VANILLA = 0,
- GENERIC_RELOC_PAIR = 1,
- GENERIC_RELOC_SECTDIFF = 2,
- GENERIC_RELOC_PB_LA_PTR = 3,
- GENERIC_RELOC_LOCAL_SECTDIFF = 4,
- GENERIC_RELOC_TLV = 5,
-
- // Constant values for the r_type field in a PowerPC architecture
- // llvm::MachO::relocation_info or llvm::MachO::scattered_relocation_info
- // structure.
- PPC_RELOC_VANILLA = GENERIC_RELOC_VANILLA,
- PPC_RELOC_PAIR = GENERIC_RELOC_PAIR,
- PPC_RELOC_BR14 = 2,
- PPC_RELOC_BR24 = 3,
- PPC_RELOC_HI16 = 4,
- PPC_RELOC_LO16 = 5,
- PPC_RELOC_HA16 = 6,
- PPC_RELOC_LO14 = 7,
- PPC_RELOC_SECTDIFF = 8,
- PPC_RELOC_PB_LA_PTR = 9,
- PPC_RELOC_HI16_SECTDIFF = 10,
- PPC_RELOC_LO16_SECTDIFF = 11,
- PPC_RELOC_HA16_SECTDIFF = 12,
- PPC_RELOC_JBSR = 13,
- PPC_RELOC_LO14_SECTDIFF = 14,
- PPC_RELOC_LOCAL_SECTDIFF = 15,
-
- // Constant values for the r_type field in an ARM architecture
- // llvm::MachO::relocation_info or llvm::MachO::scattered_relocation_info
- // structure.
- ARM_RELOC_VANILLA = GENERIC_RELOC_VANILLA,
- ARM_RELOC_PAIR = GENERIC_RELOC_PAIR,
- ARM_RELOC_SECTDIFF = GENERIC_RELOC_SECTDIFF,
- ARM_RELOC_LOCAL_SECTDIFF = 3,
- ARM_RELOC_PB_LA_PTR = 4,
- ARM_RELOC_BR24 = 5,
- ARM_THUMB_RELOC_BR22 = 6,
- ARM_THUMB_32BIT_BRANCH = 7, // obsolete
- ARM_RELOC_HALF = 8,
- ARM_RELOC_HALF_SECTDIFF = 9,
-
- // Constant values for the r_type field in an ARM64 architecture
- // llvm::MachO::relocation_info or llvm::MachO::scattered_relocation_info
- // structure.
-
- // For pointers.
- ARM64_RELOC_UNSIGNED = 0,
- // Must be followed by an ARM64_RELOC_UNSIGNED
- ARM64_RELOC_SUBTRACTOR = 1,
- // A B/BL instruction with 26-bit displacement.
- ARM64_RELOC_BRANCH26 = 2,
- // PC-rel distance to page of target.
- ARM64_RELOC_PAGE21 = 3,
- // Offset within page, scaled by r_length.
- ARM64_RELOC_PAGEOFF12 = 4,
- // PC-rel distance to page of GOT slot.
- ARM64_RELOC_GOT_LOAD_PAGE21 = 5,
- // Offset within page of GOT slot, scaled by r_length.
- ARM64_RELOC_GOT_LOAD_PAGEOFF12 = 6,
- // For pointers to GOT slots.
- ARM64_RELOC_POINTER_TO_GOT = 7,
- // PC-rel distance to page of TLVP slot.
- ARM64_RELOC_TLVP_LOAD_PAGE21 = 8,
- // Offset within page of TLVP slot, scaled by r_length.
- ARM64_RELOC_TLVP_LOAD_PAGEOFF12 = 9,
- // Must be followed by ARM64_RELOC_PAGE21 or ARM64_RELOC_PAGEOFF12.
- ARM64_RELOC_ADDEND = 10,
-
- // Constant values for the r_type field in an x86_64 architecture
- // llvm::MachO::relocation_info or llvm::MachO::scattered_relocation_info
- // structure
- X86_64_RELOC_UNSIGNED = 0,
- X86_64_RELOC_SIGNED = 1,
- X86_64_RELOC_BRANCH = 2,
- X86_64_RELOC_GOT_LOAD = 3,
- X86_64_RELOC_GOT = 4,
- X86_64_RELOC_SUBTRACTOR = 5,
- X86_64_RELOC_SIGNED_1 = 6,
- X86_64_RELOC_SIGNED_2 = 7,
- X86_64_RELOC_SIGNED_4 = 8,
- X86_64_RELOC_TLV = 9
- };
-
- // Values for segment_command.initprot.
- // From <mach/vm_prot.h>
- enum {
- VM_PROT_READ = 0x1,
- VM_PROT_WRITE = 0x2,
- VM_PROT_EXECUTE = 0x4
- };
-
- // Structs from <mach-o/loader.h>
-
- struct mach_header {
- uint32_t magic;
- uint32_t cputype;
- uint32_t cpusubtype;
- uint32_t filetype;
- uint32_t ncmds;
- uint32_t sizeofcmds;
- uint32_t flags;
- };
-
- struct mach_header_64 {
- uint32_t magic;
- uint32_t cputype;
- uint32_t cpusubtype;
- uint32_t filetype;
- uint32_t ncmds;
- uint32_t sizeofcmds;
- uint32_t flags;
- uint32_t reserved;
- };
-
- struct load_command {
- uint32_t cmd;
- uint32_t cmdsize;
- };
-
- struct segment_command {
- uint32_t cmd;
- uint32_t cmdsize;
- char segname[16];
- uint32_t vmaddr;
- uint32_t vmsize;
- uint32_t fileoff;
- uint32_t filesize;
- uint32_t maxprot;
- uint32_t initprot;
- uint32_t nsects;
- uint32_t flags;
- };
-
- struct segment_command_64 {
- uint32_t cmd;
- uint32_t cmdsize;
- char segname[16];
- uint64_t vmaddr;
- uint64_t vmsize;
- uint64_t fileoff;
- uint64_t filesize;
- uint32_t maxprot;
- uint32_t initprot;
- uint32_t nsects;
- uint32_t flags;
- };
-
- struct section {
- char sectname[16];
- char segname[16];
- uint32_t addr;
- uint32_t size;
- uint32_t offset;
- uint32_t align;
- uint32_t reloff;
- uint32_t nreloc;
- uint32_t flags;
- uint32_t reserved1;
- uint32_t reserved2;
- };
-
- struct section_64 {
- char sectname[16];
- char segname[16];
- uint64_t addr;
- uint64_t size;
- uint32_t offset;
- uint32_t align;
- uint32_t reloff;
- uint32_t nreloc;
- uint32_t flags;
- uint32_t reserved1;
- uint32_t reserved2;
- uint32_t reserved3;
- };
-
- struct fvmlib {
- uint32_t name;
- uint32_t minor_version;
- uint32_t header_addr;
- };
-
- // The fvmlib_command is obsolete and no longer supported.
- struct fvmlib_command {
- uint32_t cmd;
- uint32_t cmdsize;
- struct fvmlib fvmlib;
- };
-
- struct dylib {
- uint32_t name;
- uint32_t timestamp;
- uint32_t current_version;
- uint32_t compatibility_version;
- };
-
- struct dylib_command {
- uint32_t cmd;
- uint32_t cmdsize;
- struct dylib dylib;
- };
-
- struct sub_framework_command {
- uint32_t cmd;
- uint32_t cmdsize;
- uint32_t umbrella;
- };
-
- struct sub_client_command {
- uint32_t cmd;
- uint32_t cmdsize;
- uint32_t client;
- };
-
- struct sub_umbrella_command {
- uint32_t cmd;
- uint32_t cmdsize;
- uint32_t sub_umbrella;
- };
-
- struct sub_library_command {
- uint32_t cmd;
- uint32_t cmdsize;
- uint32_t sub_library;
- };
-
- // The prebound_dylib_command is obsolete and no longer supported.
- struct prebound_dylib_command {
- uint32_t cmd;
- uint32_t cmdsize;
- uint32_t name;
- uint32_t nmodules;
- uint32_t linked_modules;
- };
-
- struct dylinker_command {
- uint32_t cmd;
- uint32_t cmdsize;
- uint32_t name;
- };
-
- struct thread_command {
- uint32_t cmd;
- uint32_t cmdsize;
- };
-
- struct routines_command {
- uint32_t cmd;
- uint32_t cmdsize;
- uint32_t init_address;
- uint32_t init_module;
- uint32_t reserved1;
- uint32_t reserved2;
- uint32_t reserved3;
- uint32_t reserved4;
- uint32_t reserved5;
- uint32_t reserved6;
- };
-
- struct routines_command_64 {
- uint32_t cmd;
- uint32_t cmdsize;
- uint64_t init_address;
- uint64_t init_module;
- uint64_t reserved1;
- uint64_t reserved2;
- uint64_t reserved3;
- uint64_t reserved4;
- uint64_t reserved5;
- uint64_t reserved6;
- };
-
- struct symtab_command {
- uint32_t cmd;
- uint32_t cmdsize;
- uint32_t symoff;
- uint32_t nsyms;
- uint32_t stroff;
- uint32_t strsize;
- };
-
- struct dysymtab_command {
- uint32_t cmd;
- uint32_t cmdsize;
- uint32_t ilocalsym;
- uint32_t nlocalsym;
- uint32_t iextdefsym;
- uint32_t nextdefsym;
- uint32_t iundefsym;
- uint32_t nundefsym;
- uint32_t tocoff;
- uint32_t ntoc;
- uint32_t modtaboff;
- uint32_t nmodtab;
- uint32_t extrefsymoff;
- uint32_t nextrefsyms;
- uint32_t indirectsymoff;
- uint32_t nindirectsyms;
- uint32_t extreloff;
- uint32_t nextrel;
- uint32_t locreloff;
- uint32_t nlocrel;
- };
-
- struct dylib_table_of_contents {
- uint32_t symbol_index;
- uint32_t module_index;
- };
-
- struct dylib_module {
- uint32_t module_name;
- uint32_t iextdefsym;
- uint32_t nextdefsym;
- uint32_t irefsym;
- uint32_t nrefsym;
- uint32_t ilocalsym;
- uint32_t nlocalsym;
- uint32_t iextrel;
- uint32_t nextrel;
- uint32_t iinit_iterm;
- uint32_t ninit_nterm;
- uint32_t objc_module_info_addr;
- uint32_t objc_module_info_size;
- };
-
- struct dylib_module_64 {
- uint32_t module_name;
- uint32_t iextdefsym;
- uint32_t nextdefsym;
- uint32_t irefsym;
- uint32_t nrefsym;
- uint32_t ilocalsym;
- uint32_t nlocalsym;
- uint32_t iextrel;
- uint32_t nextrel;
- uint32_t iinit_iterm;
- uint32_t ninit_nterm;
- uint32_t objc_module_info_size;
- uint64_t objc_module_info_addr;
- };
-
- struct dylib_reference {
- uint32_t isym:24,
- flags:8;
- };
-
- // The twolevel_hints_command is obsolete and no longer supported.
- struct twolevel_hints_command {
- uint32_t cmd;
- uint32_t cmdsize;
- uint32_t offset;
- uint32_t nhints;
- };
-
- // The twolevel_hints_command is obsolete and no longer supported.
- struct twolevel_hint {
- uint32_t isub_image:8,
- itoc:24;
- };
-
- // The prebind_cksum_command is obsolete and no longer supported.
- struct prebind_cksum_command {
- uint32_t cmd;
- uint32_t cmdsize;
- uint32_t cksum;
- };
-
- struct uuid_command {
- uint32_t cmd;
- uint32_t cmdsize;
- uint8_t uuid[16];
- };
-
- struct rpath_command {
- uint32_t cmd;
- uint32_t cmdsize;
- uint32_t path;
- };
-
- struct linkedit_data_command {
- uint32_t cmd;
- uint32_t cmdsize;
- uint32_t dataoff;
- uint32_t datasize;
- };
-
- struct data_in_code_entry {
- uint32_t offset;
- uint16_t length;
- uint16_t kind;
- };
-
- struct source_version_command {
- uint32_t cmd;
- uint32_t cmdsize;
- uint64_t version;
- };
-
- struct encryption_info_command {
- uint32_t cmd;
- uint32_t cmdsize;
- uint32_t cryptoff;
- uint32_t cryptsize;
- uint32_t cryptid;
- };
-
- struct encryption_info_command_64 {
- uint32_t cmd;
- uint32_t cmdsize;
- uint32_t cryptoff;
- uint32_t cryptsize;
- uint32_t cryptid;
- uint32_t pad;
- };
-
- struct version_min_command {
- uint32_t cmd; // LC_VERSION_MIN_MACOSX or
- // LC_VERSION_MIN_IPHONEOS
- uint32_t cmdsize; // sizeof(struct version_min_command)
- uint32_t version; // X.Y.Z is encoded in nibbles xxxx.yy.zz
- uint32_t sdk; // X.Y.Z is encoded in nibbles xxxx.yy.zz
- };
-
- struct dyld_info_command {
- uint32_t cmd;
- uint32_t cmdsize;
- uint32_t rebase_off;
- uint32_t rebase_size;
- uint32_t bind_off;
- uint32_t bind_size;
- uint32_t weak_bind_off;
- uint32_t weak_bind_size;
- uint32_t lazy_bind_off;
- uint32_t lazy_bind_size;
- uint32_t export_off;
- uint32_t export_size;
- };
-
- struct linker_option_command {
- uint32_t cmd;
- uint32_t cmdsize;
- uint32_t count;
- };
-
- // The symseg_command is obsolete and no longer supported.
- struct symseg_command {
- uint32_t cmd;
- uint32_t cmdsize;
- uint32_t offset;
- uint32_t size;
- };
-
- // The ident_command is obsolete and no longer supported.
- struct ident_command {
- uint32_t cmd;
- uint32_t cmdsize;
- };
-
- // The fvmfile_command is obsolete and no longer supported.
- struct fvmfile_command {
- uint32_t cmd;
- uint32_t cmdsize;
- uint32_t name;
- uint32_t header_addr;
- };
-
- struct tlv_descriptor_32 {
- uint32_t thunk;
- uint32_t key;
- uint32_t offset;
- };
-
- struct tlv_descriptor_64 {
- uint64_t thunk;
- uint64_t key;
- uint64_t offset;
- };
-
- struct tlv_descriptor {
- uintptr_t thunk;
- uintptr_t key;
- uintptr_t offset;
- };
-
- struct entry_point_command {
- uint32_t cmd;
- uint32_t cmdsize;
- uint64_t entryoff;
- uint64_t stacksize;
- };
-
- // Structs from <mach-o/fat.h>
- struct fat_header {
- uint32_t magic;
- uint32_t nfat_arch;
- };
-
- struct fat_arch {
- uint32_t cputype;
- uint32_t cpusubtype;
- uint32_t offset;
- uint32_t size;
- uint32_t align;
- };
-
- struct fat_arch_64 {
- uint32_t cputype;
- uint32_t cpusubtype;
- uint64_t offset;
- uint64_t size;
- uint32_t align;
- uint32_t reserved;
- };
-
- // Structs from <mach-o/reloc.h>
- struct relocation_info {
- int32_t r_address;
- uint32_t r_symbolnum:24,
- r_pcrel:1,
- r_length:2,
- r_extern:1,
- r_type:4;
- };
-
- struct scattered_relocation_info {
-#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && (BYTE_ORDER == BIG_ENDIAN)
- uint32_t r_scattered:1,
- r_pcrel:1,
- r_length:2,
- r_type:4,
- r_address:24;
-#else
- uint32_t r_address:24,
- r_type:4,
- r_length:2,
- r_pcrel:1,
- r_scattered:1;
-#endif
- int32_t r_value;
- };
-
- // Structs NOT from <mach-o/reloc.h>, but that make LLVM's life easier
- struct any_relocation_info {
- uint32_t r_word0, r_word1;
- };
-
- // Structs from <mach-o/nlist.h>
- struct nlist_base {
- uint32_t n_strx;
- uint8_t n_type;
- uint8_t n_sect;
- uint16_t n_desc;
- };
-
- struct nlist {
- uint32_t n_strx;
- uint8_t n_type;
- uint8_t n_sect;
- int16_t n_desc;
- uint32_t n_value;
- };
-
- struct nlist_64 {
- uint32_t n_strx;
- uint8_t n_type;
- uint8_t n_sect;
- uint16_t n_desc;
- uint64_t n_value;
- };
-
- // Byte order swapping functions for MachO structs
-
- inline void swapStruct(fat_header &mh) {
- sys::swapByteOrder(mh.magic);
- sys::swapByteOrder(mh.nfat_arch);
- }
-
- inline void swapStruct(fat_arch &mh) {
- sys::swapByteOrder(mh.cputype);
- sys::swapByteOrder(mh.cpusubtype);
- sys::swapByteOrder(mh.offset);
- sys::swapByteOrder(mh.size);
- sys::swapByteOrder(mh.align);
- }
-
- inline void swapStruct(fat_arch_64 &mh) {
- sys::swapByteOrder(mh.cputype);
- sys::swapByteOrder(mh.cpusubtype);
- sys::swapByteOrder(mh.offset);
- sys::swapByteOrder(mh.size);
- sys::swapByteOrder(mh.align);
- sys::swapByteOrder(mh.reserved);
- }
-
- inline void swapStruct(mach_header &mh) {
- sys::swapByteOrder(mh.magic);
- sys::swapByteOrder(mh.cputype);
- sys::swapByteOrder(mh.cpusubtype);
- sys::swapByteOrder(mh.filetype);
- sys::swapByteOrder(mh.ncmds);
- sys::swapByteOrder(mh.sizeofcmds);
- sys::swapByteOrder(mh.flags);
- }
-
- inline void swapStruct(mach_header_64 &H) {
- sys::swapByteOrder(H.magic);
- sys::swapByteOrder(H.cputype);
- sys::swapByteOrder(H.cpusubtype);
- sys::swapByteOrder(H.filetype);
- sys::swapByteOrder(H.ncmds);
- sys::swapByteOrder(H.sizeofcmds);
- sys::swapByteOrder(H.flags);
- sys::swapByteOrder(H.reserved);
- }
-
- inline void swapStruct(load_command &lc) {
- sys::swapByteOrder(lc.cmd);
- sys::swapByteOrder(lc.cmdsize);
- }
-
- inline void swapStruct(symtab_command &lc) {
- sys::swapByteOrder(lc.cmd);
- sys::swapByteOrder(lc.cmdsize);
- sys::swapByteOrder(lc.symoff);
- sys::swapByteOrder(lc.nsyms);
- sys::swapByteOrder(lc.stroff);
- sys::swapByteOrder(lc.strsize);
- }
-
- inline void swapStruct(segment_command_64 &seg) {
- sys::swapByteOrder(seg.cmd);
- sys::swapByteOrder(seg.cmdsize);
- sys::swapByteOrder(seg.vmaddr);
- sys::swapByteOrder(seg.vmsize);
- sys::swapByteOrder(seg.fileoff);
- sys::swapByteOrder(seg.filesize);
- sys::swapByteOrder(seg.maxprot);
- sys::swapByteOrder(seg.initprot);
- sys::swapByteOrder(seg.nsects);
- sys::swapByteOrder(seg.flags);
- }
-
- inline void swapStruct(segment_command &seg) {
- sys::swapByteOrder(seg.cmd);
- sys::swapByteOrder(seg.cmdsize);
- sys::swapByteOrder(seg.vmaddr);
- sys::swapByteOrder(seg.vmsize);
- sys::swapByteOrder(seg.fileoff);
- sys::swapByteOrder(seg.filesize);
- sys::swapByteOrder(seg.maxprot);
- sys::swapByteOrder(seg.initprot);
- sys::swapByteOrder(seg.nsects);
- sys::swapByteOrder(seg.flags);
- }
-
- inline void swapStruct(section_64 &sect) {
- sys::swapByteOrder(sect.addr);
- sys::swapByteOrder(sect.size);
- sys::swapByteOrder(sect.offset);
- sys::swapByteOrder(sect.align);
- sys::swapByteOrder(sect.reloff);
- sys::swapByteOrder(sect.nreloc);
- sys::swapByteOrder(sect.flags);
- sys::swapByteOrder(sect.reserved1);
- sys::swapByteOrder(sect.reserved2);
- }
-
- inline void swapStruct(section &sect) {
- sys::swapByteOrder(sect.addr);
- sys::swapByteOrder(sect.size);
- sys::swapByteOrder(sect.offset);
- sys::swapByteOrder(sect.align);
- sys::swapByteOrder(sect.reloff);
- sys::swapByteOrder(sect.nreloc);
- sys::swapByteOrder(sect.flags);
- sys::swapByteOrder(sect.reserved1);
- sys::swapByteOrder(sect.reserved2);
- }
-
- inline void swapStruct(dyld_info_command &info) {
- sys::swapByteOrder(info.cmd);
- sys::swapByteOrder(info.cmdsize);
- sys::swapByteOrder(info.rebase_off);
- sys::swapByteOrder(info.rebase_size);
- sys::swapByteOrder(info.bind_off);
- sys::swapByteOrder(info.bind_size);
- sys::swapByteOrder(info.weak_bind_off);
- sys::swapByteOrder(info.weak_bind_size);
- sys::swapByteOrder(info.lazy_bind_off);
- sys::swapByteOrder(info.lazy_bind_size);
- sys::swapByteOrder(info.export_off);
- sys::swapByteOrder(info.export_size);
- }
-
- inline void swapStruct(dylib_command &d) {
- sys::swapByteOrder(d.cmd);
- sys::swapByteOrder(d.cmdsize);
- sys::swapByteOrder(d.dylib.name);
- sys::swapByteOrder(d.dylib.timestamp);
- sys::swapByteOrder(d.dylib.current_version);
- sys::swapByteOrder(d.dylib.compatibility_version);
- }
-
- inline void swapStruct(sub_framework_command &s) {
- sys::swapByteOrder(s.cmd);
- sys::swapByteOrder(s.cmdsize);
- sys::swapByteOrder(s.umbrella);
- }
-
- inline void swapStruct(sub_umbrella_command &s) {
- sys::swapByteOrder(s.cmd);
- sys::swapByteOrder(s.cmdsize);
- sys::swapByteOrder(s.sub_umbrella);
- }
-
- inline void swapStruct(sub_library_command &s) {
- sys::swapByteOrder(s.cmd);
- sys::swapByteOrder(s.cmdsize);
- sys::swapByteOrder(s.sub_library);
- }
-
- inline void swapStruct(sub_client_command &s) {
- sys::swapByteOrder(s.cmd);
- sys::swapByteOrder(s.cmdsize);
- sys::swapByteOrder(s.client);
- }
-
- inline void swapStruct(routines_command &r) {
- sys::swapByteOrder(r.cmd);
- sys::swapByteOrder(r.cmdsize);
- sys::swapByteOrder(r.init_address);
- sys::swapByteOrder(r.init_module);
- sys::swapByteOrder(r.reserved1);
- sys::swapByteOrder(r.reserved2);
- sys::swapByteOrder(r.reserved3);
- sys::swapByteOrder(r.reserved4);
- sys::swapByteOrder(r.reserved5);
- sys::swapByteOrder(r.reserved6);
- }
-
- inline void swapStruct(routines_command_64 &r) {
- sys::swapByteOrder(r.cmd);
- sys::swapByteOrder(r.cmdsize);
- sys::swapByteOrder(r.init_address);
- sys::swapByteOrder(r.init_module);
- sys::swapByteOrder(r.reserved1);
- sys::swapByteOrder(r.reserved2);
- sys::swapByteOrder(r.reserved3);
- sys::swapByteOrder(r.reserved4);
- sys::swapByteOrder(r.reserved5);
- sys::swapByteOrder(r.reserved6);
- }
-
- inline void swapStruct(thread_command &t) {
- sys::swapByteOrder(t.cmd);
- sys::swapByteOrder(t.cmdsize);
- }
-
- inline void swapStruct(dylinker_command &d) {
- sys::swapByteOrder(d.cmd);
- sys::swapByteOrder(d.cmdsize);
- sys::swapByteOrder(d.name);
- }
-
- inline void swapStruct(uuid_command &u) {
- sys::swapByteOrder(u.cmd);
- sys::swapByteOrder(u.cmdsize);
- }
-
- inline void swapStruct(rpath_command &r) {
- sys::swapByteOrder(r.cmd);
- sys::swapByteOrder(r.cmdsize);
- sys::swapByteOrder(r.path);
- }
-
- inline void swapStruct(source_version_command &s) {
- sys::swapByteOrder(s.cmd);
- sys::swapByteOrder(s.cmdsize);
- sys::swapByteOrder(s.version);
- }
-
- inline void swapStruct(entry_point_command &e) {
- sys::swapByteOrder(e.cmd);
- sys::swapByteOrder(e.cmdsize);
- sys::swapByteOrder(e.entryoff);
- sys::swapByteOrder(e.stacksize);
- }
-
- inline void swapStruct(encryption_info_command &e) {
- sys::swapByteOrder(e.cmd);
- sys::swapByteOrder(e.cmdsize);
- sys::swapByteOrder(e.cryptoff);
- sys::swapByteOrder(e.cryptsize);
- sys::swapByteOrder(e.cryptid);
- }
-
- inline void swapStruct(encryption_info_command_64 &e) {
- sys::swapByteOrder(e.cmd);
- sys::swapByteOrder(e.cmdsize);
- sys::swapByteOrder(e.cryptoff);
- sys::swapByteOrder(e.cryptsize);
- sys::swapByteOrder(e.cryptid);
- sys::swapByteOrder(e.pad);
- }
-
- inline void swapStruct(dysymtab_command &dst) {
- sys::swapByteOrder(dst.cmd);
- sys::swapByteOrder(dst.cmdsize);
- sys::swapByteOrder(dst.ilocalsym);
- sys::swapByteOrder(dst.nlocalsym);
- sys::swapByteOrder(dst.iextdefsym);
- sys::swapByteOrder(dst.nextdefsym);
- sys::swapByteOrder(dst.iundefsym);
- sys::swapByteOrder(dst.nundefsym);
- sys::swapByteOrder(dst.tocoff);
- sys::swapByteOrder(dst.ntoc);
- sys::swapByteOrder(dst.modtaboff);
- sys::swapByteOrder(dst.nmodtab);
- sys::swapByteOrder(dst.extrefsymoff);
- sys::swapByteOrder(dst.nextrefsyms);
- sys::swapByteOrder(dst.indirectsymoff);
- sys::swapByteOrder(dst.nindirectsyms);
- sys::swapByteOrder(dst.extreloff);
- sys::swapByteOrder(dst.nextrel);
- sys::swapByteOrder(dst.locreloff);
- sys::swapByteOrder(dst.nlocrel);
- }
-
- inline void swapStruct(any_relocation_info &reloc) {
- sys::swapByteOrder(reloc.r_word0);
- sys::swapByteOrder(reloc.r_word1);
- }
-
- inline void swapStruct(nlist_base &S) {
- sys::swapByteOrder(S.n_strx);
- sys::swapByteOrder(S.n_desc);
- }
-
- inline void swapStruct(nlist &sym) {
- sys::swapByteOrder(sym.n_strx);
- sys::swapByteOrder(sym.n_desc);
- sys::swapByteOrder(sym.n_value);
- }
-
- inline void swapStruct(nlist_64 &sym) {
- sys::swapByteOrder(sym.n_strx);
- sys::swapByteOrder(sym.n_desc);
- sys::swapByteOrder(sym.n_value);
- }
-
- inline void swapStruct(linkedit_data_command &C) {
- sys::swapByteOrder(C.cmd);
- sys::swapByteOrder(C.cmdsize);
- sys::swapByteOrder(C.dataoff);
- sys::swapByteOrder(C.datasize);
- }
-
- inline void swapStruct(linker_option_command &C) {
- sys::swapByteOrder(C.cmd);
- sys::swapByteOrder(C.cmdsize);
- sys::swapByteOrder(C.count);
- }
-
- inline void swapStruct(version_min_command&C) {
- sys::swapByteOrder(C.cmd);
- sys::swapByteOrder(C.cmdsize);
- sys::swapByteOrder(C.version);
- sys::swapByteOrder(C.sdk);
- }
-
- inline void swapStruct(data_in_code_entry &C) {
- sys::swapByteOrder(C.offset);
- sys::swapByteOrder(C.length);
- sys::swapByteOrder(C.kind);
- }
-
- inline void swapStruct(uint32_t &C) {
- sys::swapByteOrder(C);
- }
-
- // The prebind_cksum_command is obsolete and no longer supported.
- inline void swapStruct(prebind_cksum_command &C) {
- sys::swapByteOrder(C.cmd);
- sys::swapByteOrder(C.cmdsize);
- sys::swapByteOrder(C.cksum);
- }
-
- // The twolevel_hints_command is obsolete and no longer supported.
- inline void swapStruct(twolevel_hints_command &C) {
- sys::swapByteOrder(C.cmd);
- sys::swapByteOrder(C.cmdsize);
- sys::swapByteOrder(C.offset);
- sys::swapByteOrder(C.nhints);
- }
-
- // The prebound_dylib_command is obsolete and no longer supported.
- inline void swapStruct(prebound_dylib_command &C) {
- sys::swapByteOrder(C.cmd);
- sys::swapByteOrder(C.cmdsize);
- sys::swapByteOrder(C.name);
- sys::swapByteOrder(C.nmodules);
- sys::swapByteOrder(C.linked_modules);
- }
-
- // The fvmfile_command is obsolete and no longer supported.
- inline void swapStruct(fvmfile_command &C) {
- sys::swapByteOrder(C.cmd);
- sys::swapByteOrder(C.cmdsize);
- sys::swapByteOrder(C.name);
- sys::swapByteOrder(C.header_addr);
- }
-
- // The symseg_command is obsolete and no longer supported.
- inline void swapStruct(symseg_command &C) {
- sys::swapByteOrder(C.cmd);
- sys::swapByteOrder(C.cmdsize);
- sys::swapByteOrder(C.offset);
- sys::swapByteOrder(C.size);
- }
-
- // The ident_command is obsolete and no longer supported.
- inline void swapStruct(ident_command &C) {
- sys::swapByteOrder(C.cmd);
- sys::swapByteOrder(C.cmdsize);
- }
-
- inline void swapStruct(fvmlib &C) {
- sys::swapByteOrder(C.name);
- sys::swapByteOrder(C.minor_version);
- sys::swapByteOrder(C.header_addr);
- }
-
- // The fvmlib_command is obsolete and no longer supported.
- inline void swapStruct(fvmlib_command &C) {
- sys::swapByteOrder(C.cmd);
- sys::swapByteOrder(C.cmdsize);
- swapStruct(C.fvmlib);
- }
-
- // Get/Set functions from <mach-o/nlist.h>
-
- static inline uint16_t GET_LIBRARY_ORDINAL(uint16_t n_desc) {
- return (((n_desc) >> 8u) & 0xffu);
- }
-
- static inline void SET_LIBRARY_ORDINAL(uint16_t &n_desc, uint8_t ordinal) {
- n_desc = (((n_desc) & 0x00ff) | (((ordinal) & 0xff) << 8));
- }
-
- static inline uint8_t GET_COMM_ALIGN (uint16_t n_desc) {
- return (n_desc >> 8u) & 0x0fu;
- }
-
- static inline void SET_COMM_ALIGN (uint16_t &n_desc, uint8_t align) {
- n_desc = ((n_desc & 0xf0ffu) | ((align & 0x0fu) << 8u));
- }
-
- // Enums from <mach/machine.h>
- enum : uint32_t {
- // Capability bits used in the definition of cpu_type.
- CPU_ARCH_MASK = 0xff000000, // Mask for architecture bits
- CPU_ARCH_ABI64 = 0x01000000 // 64 bit ABI
- };
-
- // Constants for the cputype field.
- enum CPUType {
- CPU_TYPE_ANY = -1,
- CPU_TYPE_X86 = 7,
- CPU_TYPE_I386 = CPU_TYPE_X86,
- CPU_TYPE_X86_64 = CPU_TYPE_X86 | CPU_ARCH_ABI64,
- /* CPU_TYPE_MIPS = 8, */
- CPU_TYPE_MC98000 = 10, // Old Motorola PowerPC
- CPU_TYPE_ARM = 12,
- CPU_TYPE_ARM64 = CPU_TYPE_ARM | CPU_ARCH_ABI64,
- CPU_TYPE_SPARC = 14,
- CPU_TYPE_POWERPC = 18,
- CPU_TYPE_POWERPC64 = CPU_TYPE_POWERPC | CPU_ARCH_ABI64
- };
-
- enum : uint32_t {
- // Capability bits used in the definition of cpusubtype.
- CPU_SUBTYPE_MASK = 0xff000000, // Mask for architecture bits
- CPU_SUBTYPE_LIB64 = 0x80000000, // 64 bit libraries
-
- // Special CPU subtype constants.
- CPU_SUBTYPE_MULTIPLE = ~0u
- };
-
- // Constants for the cpusubtype field.
- enum CPUSubTypeX86 {
- CPU_SUBTYPE_I386_ALL = 3,
- CPU_SUBTYPE_386 = 3,
- CPU_SUBTYPE_486 = 4,
- CPU_SUBTYPE_486SX = 0x84,
- CPU_SUBTYPE_586 = 5,
- CPU_SUBTYPE_PENT = CPU_SUBTYPE_586,
- CPU_SUBTYPE_PENTPRO = 0x16,
- CPU_SUBTYPE_PENTII_M3 = 0x36,
- CPU_SUBTYPE_PENTII_M5 = 0x56,
- CPU_SUBTYPE_CELERON = 0x67,
- CPU_SUBTYPE_CELERON_MOBILE = 0x77,
- CPU_SUBTYPE_PENTIUM_3 = 0x08,
- CPU_SUBTYPE_PENTIUM_3_M = 0x18,
- CPU_SUBTYPE_PENTIUM_3_XEON = 0x28,
- CPU_SUBTYPE_PENTIUM_M = 0x09,
- CPU_SUBTYPE_PENTIUM_4 = 0x0a,
- CPU_SUBTYPE_PENTIUM_4_M = 0x1a,
- CPU_SUBTYPE_ITANIUM = 0x0b,
- CPU_SUBTYPE_ITANIUM_2 = 0x1b,
- CPU_SUBTYPE_XEON = 0x0c,
- CPU_SUBTYPE_XEON_MP = 0x1c,
-
- CPU_SUBTYPE_X86_ALL = 3,
- CPU_SUBTYPE_X86_64_ALL = 3,
- CPU_SUBTYPE_X86_ARCH1 = 4,
- CPU_SUBTYPE_X86_64_H = 8
- };
- static inline int CPU_SUBTYPE_INTEL(int Family, int Model) {
- return Family | (Model << 4);
- }
- static inline int CPU_SUBTYPE_INTEL_FAMILY(CPUSubTypeX86 ST) {
- return ((int)ST) & 0x0f;
- }
- static inline int CPU_SUBTYPE_INTEL_MODEL(CPUSubTypeX86 ST) {
- return ((int)ST) >> 4;
- }
- enum {
- CPU_SUBTYPE_INTEL_FAMILY_MAX = 15,
- CPU_SUBTYPE_INTEL_MODEL_ALL = 0
- };
-
- enum CPUSubTypeARM {
- CPU_SUBTYPE_ARM_ALL = 0,
- CPU_SUBTYPE_ARM_V4T = 5,
- CPU_SUBTYPE_ARM_V6 = 6,
- CPU_SUBTYPE_ARM_V5 = 7,
- CPU_SUBTYPE_ARM_V5TEJ = 7,
- CPU_SUBTYPE_ARM_XSCALE = 8,
- CPU_SUBTYPE_ARM_V7 = 9,
- // unused ARM_V7F = 10,
- CPU_SUBTYPE_ARM_V7S = 11,
- CPU_SUBTYPE_ARM_V7K = 12,
- CPU_SUBTYPE_ARM_V6M = 14,
- CPU_SUBTYPE_ARM_V7M = 15,
- CPU_SUBTYPE_ARM_V7EM = 16
- };
-
- enum CPUSubTypeARM64 {
- CPU_SUBTYPE_ARM64_ALL = 0
- };
-
- enum CPUSubTypeSPARC {
- CPU_SUBTYPE_SPARC_ALL = 0
- };
-
- enum CPUSubTypePowerPC {
- CPU_SUBTYPE_POWERPC_ALL = 0,
- CPU_SUBTYPE_POWERPC_601 = 1,
- CPU_SUBTYPE_POWERPC_602 = 2,
- CPU_SUBTYPE_POWERPC_603 = 3,
- CPU_SUBTYPE_POWERPC_603e = 4,
- CPU_SUBTYPE_POWERPC_603ev = 5,
- CPU_SUBTYPE_POWERPC_604 = 6,
- CPU_SUBTYPE_POWERPC_604e = 7,
- CPU_SUBTYPE_POWERPC_620 = 8,
- CPU_SUBTYPE_POWERPC_750 = 9,
- CPU_SUBTYPE_POWERPC_7400 = 10,
- CPU_SUBTYPE_POWERPC_7450 = 11,
- CPU_SUBTYPE_POWERPC_970 = 100,
-
- CPU_SUBTYPE_MC980000_ALL = CPU_SUBTYPE_POWERPC_ALL,
- CPU_SUBTYPE_MC98601 = CPU_SUBTYPE_POWERPC_601
- };
-
- struct x86_thread_state64_t {
- uint64_t rax;
- uint64_t rbx;
- uint64_t rcx;
- uint64_t rdx;
- uint64_t rdi;
- uint64_t rsi;
- uint64_t rbp;
- uint64_t rsp;
- uint64_t r8;
- uint64_t r9;
- uint64_t r10;
- uint64_t r11;
- uint64_t r12;
- uint64_t r13;
- uint64_t r14;
- uint64_t r15;
- uint64_t rip;
- uint64_t rflags;
- uint64_t cs;
- uint64_t fs;
- uint64_t gs;
- };
-
- enum x86_fp_control_precis {
- x86_FP_PREC_24B = 0,
- x86_FP_PREC_53B = 2,
- x86_FP_PREC_64B = 3
- };
-
- enum x86_fp_control_rc {
- x86_FP_RND_NEAR = 0,
- x86_FP_RND_DOWN = 1,
- x86_FP_RND_UP = 2,
- x86_FP_CHOP = 3
- };
-
- struct fp_control_t {
- unsigned short
- invalid :1,
- denorm :1,
- zdiv :1,
- ovrfl :1,
- undfl :1,
- precis :1,
- :2,
- pc :2,
- rc :2,
- :1,
- :3;
- };
-
- struct fp_status_t {
- unsigned short
- invalid :1,
- denorm :1,
- zdiv :1,
- ovrfl :1,
- undfl :1,
- precis :1,
- stkflt :1,
- errsumm :1,
- c0 :1,
- c1 :1,
- c2 :1,
- tos :3,
- c3 :1,
- busy :1;
- };
-
- struct mmst_reg_t {
- char mmst_reg[10];
- char mmst_rsrv[6];
- };
-
- struct xmm_reg_t {
- char xmm_reg[16];
- };
-
- struct x86_float_state64_t {
- int32_t fpu_reserved[2];
- fp_control_t fpu_fcw;
- fp_status_t fpu_fsw;
- uint8_t fpu_ftw;
- uint8_t fpu_rsrv1;
- uint16_t fpu_fop;
- uint32_t fpu_ip;
- uint16_t fpu_cs;
- uint16_t fpu_rsrv2;
- uint32_t fpu_dp;
- uint16_t fpu_ds;
- uint16_t fpu_rsrv3;
- uint32_t fpu_mxcsr;
- uint32_t fpu_mxcsrmask;
- mmst_reg_t fpu_stmm0;
- mmst_reg_t fpu_stmm1;
- mmst_reg_t fpu_stmm2;
- mmst_reg_t fpu_stmm3;
- mmst_reg_t fpu_stmm4;
- mmst_reg_t fpu_stmm5;
- mmst_reg_t fpu_stmm6;
- mmst_reg_t fpu_stmm7;
- xmm_reg_t fpu_xmm0;
- xmm_reg_t fpu_xmm1;
- xmm_reg_t fpu_xmm2;
- xmm_reg_t fpu_xmm3;
- xmm_reg_t fpu_xmm4;
- xmm_reg_t fpu_xmm5;
- xmm_reg_t fpu_xmm6;
- xmm_reg_t fpu_xmm7;
- xmm_reg_t fpu_xmm8;
- xmm_reg_t fpu_xmm9;
- xmm_reg_t fpu_xmm10;
- xmm_reg_t fpu_xmm11;
- xmm_reg_t fpu_xmm12;
- xmm_reg_t fpu_xmm13;
- xmm_reg_t fpu_xmm14;
- xmm_reg_t fpu_xmm15;
- char fpu_rsrv4[6*16];
- uint32_t fpu_reserved1;
- };
-
- struct x86_exception_state64_t {
- uint16_t trapno;
- uint16_t cpu;
- uint32_t err;
- uint64_t faultvaddr;
- };
-
- inline void swapStruct(x86_thread_state64_t &x) {
- sys::swapByteOrder(x.rax);
- sys::swapByteOrder(x.rbx);
- sys::swapByteOrder(x.rcx);
- sys::swapByteOrder(x.rdx);
- sys::swapByteOrder(x.rdi);
- sys::swapByteOrder(x.rsi);
- sys::swapByteOrder(x.rbp);
- sys::swapByteOrder(x.rsp);
- sys::swapByteOrder(x.r8);
- sys::swapByteOrder(x.r9);
- sys::swapByteOrder(x.r10);
- sys::swapByteOrder(x.r11);
- sys::swapByteOrder(x.r12);
- sys::swapByteOrder(x.r13);
- sys::swapByteOrder(x.r14);
- sys::swapByteOrder(x.r15);
- sys::swapByteOrder(x.rip);
- sys::swapByteOrder(x.rflags);
- sys::swapByteOrder(x.cs);
- sys::swapByteOrder(x.fs);
- sys::swapByteOrder(x.gs);
- }
-
- inline void swapStruct(x86_float_state64_t &x) {
- sys::swapByteOrder(x.fpu_reserved[0]);
- sys::swapByteOrder(x.fpu_reserved[1]);
- // TODO swap: fp_control_t fpu_fcw;
- // TODO swap: fp_status_t fpu_fsw;
- sys::swapByteOrder(x.fpu_fop);
- sys::swapByteOrder(x.fpu_ip);
- sys::swapByteOrder(x.fpu_cs);
- sys::swapByteOrder(x.fpu_rsrv2);
- sys::swapByteOrder(x.fpu_dp);
- sys::swapByteOrder(x.fpu_ds);
- sys::swapByteOrder(x.fpu_rsrv3);
- sys::swapByteOrder(x.fpu_mxcsr);
- sys::swapByteOrder(x.fpu_mxcsrmask);
- sys::swapByteOrder(x.fpu_reserved1);
- }
-
- inline void swapStruct(x86_exception_state64_t &x) {
- sys::swapByteOrder(x.trapno);
- sys::swapByteOrder(x.cpu);
- sys::swapByteOrder(x.err);
- sys::swapByteOrder(x.faultvaddr);
- }
-
- struct x86_state_hdr_t {
- uint32_t flavor;
- uint32_t count;
- };
-
- struct x86_thread_state_t {
- x86_state_hdr_t tsh;
- union {
- x86_thread_state64_t ts64;
- } uts;
- };
-
- struct x86_float_state_t {
- x86_state_hdr_t fsh;
- union {
- x86_float_state64_t fs64;
- } ufs;
- };
-
- struct x86_exception_state_t {
- x86_state_hdr_t esh;
- union {
- x86_exception_state64_t es64;
- } ues;
- };
-
- inline void swapStruct(x86_state_hdr_t &x) {
- sys::swapByteOrder(x.flavor);
- sys::swapByteOrder(x.count);
- }
-
- enum X86ThreadFlavors {
- x86_THREAD_STATE32 = 1,
- x86_FLOAT_STATE32 = 2,
- x86_EXCEPTION_STATE32 = 3,
- x86_THREAD_STATE64 = 4,
- x86_FLOAT_STATE64 = 5,
- x86_EXCEPTION_STATE64 = 6,
- x86_THREAD_STATE = 7,
- x86_FLOAT_STATE = 8,
- x86_EXCEPTION_STATE = 9,
- x86_DEBUG_STATE32 = 10,
- x86_DEBUG_STATE64 = 11,
- x86_DEBUG_STATE = 12
- };
-
- inline void swapStruct(x86_thread_state_t &x) {
- swapStruct(x.tsh);
- if (x.tsh.flavor == x86_THREAD_STATE64)
- swapStruct(x.uts.ts64);
- }
-
- inline void swapStruct(x86_float_state_t &x) {
- swapStruct(x.fsh);
- if (x.fsh.flavor == x86_FLOAT_STATE64)
- swapStruct(x.ufs.fs64);
- }
-
- inline void swapStruct(x86_exception_state_t &x) {
- swapStruct(x.esh);
- if (x.esh.flavor == x86_EXCEPTION_STATE64)
- swapStruct(x.ues.es64);
- }
-
- const uint32_t x86_THREAD_STATE64_COUNT =
- sizeof(x86_thread_state64_t) / sizeof(uint32_t);
- const uint32_t x86_FLOAT_STATE64_COUNT =
- sizeof(x86_float_state64_t) / sizeof(uint32_t);
- const uint32_t x86_EXCEPTION_STATE64_COUNT =
- sizeof(x86_exception_state64_t) / sizeof(uint32_t);
-
- const uint32_t x86_THREAD_STATE_COUNT =
- sizeof(x86_thread_state_t) / sizeof(uint32_t);
- const uint32_t x86_FLOAT_STATE_COUNT =
- sizeof(x86_float_state_t) / sizeof(uint32_t);
- const uint32_t x86_EXCEPTION_STATE_COUNT =
- sizeof(x86_exception_state_t) / sizeof(uint32_t);
-
- struct arm_thread_state32_t {
- uint32_t r[13];
- uint32_t sp;
- uint32_t lr;
- uint32_t pc;
- uint32_t cpsr;
- };
-
- inline void swapStruct(arm_thread_state32_t &x) {
- for (int i = 0; i < 13; i++)
- sys::swapByteOrder(x.r[i]);
- sys::swapByteOrder(x.sp);
- sys::swapByteOrder(x.lr);
- sys::swapByteOrder(x.pc);
- sys::swapByteOrder(x.cpsr);
- }
-
- struct arm_thread_state64_t {
- uint64_t x[29];
- uint64_t fp;
- uint64_t lr;
- uint64_t sp;
- uint64_t pc;
- uint32_t cpsr;
- uint32_t pad;
- };
-
- inline void swapStruct(arm_thread_state64_t &x) {
- for (int i = 0; i < 29; i++)
- sys::swapByteOrder(x.x[i]);
- sys::swapByteOrder(x.fp);
- sys::swapByteOrder(x.lr);
- sys::swapByteOrder(x.sp);
- sys::swapByteOrder(x.pc);
- sys::swapByteOrder(x.cpsr);
- }
-
- struct arm_state_hdr_t {
- uint32_t flavor;
- uint32_t count;
- };
-
- struct arm_thread_state_t {
- arm_state_hdr_t tsh;
- union {
- arm_thread_state32_t ts32;
- } uts;
- };
-
- inline void swapStruct(arm_state_hdr_t &x) {
- sys::swapByteOrder(x.flavor);
- sys::swapByteOrder(x.count);
- }
-
- enum ARMThreadFlavors {
- ARM_THREAD_STATE = 1,
- ARM_VFP_STATE = 2,
- ARM_EXCEPTION_STATE = 3,
- ARM_DEBUG_STATE = 4,
- ARN_THREAD_STATE_NONE = 5,
- ARM_THREAD_STATE64 = 6,
- ARM_EXCEPTION_STATE64 = 7
- };
-
- inline void swapStruct(arm_thread_state_t &x) {
- swapStruct(x.tsh);
- if (x.tsh.flavor == ARM_THREAD_STATE)
- swapStruct(x.uts.ts32);
- }
-
- const uint32_t ARM_THREAD_STATE_COUNT =
- sizeof(arm_thread_state32_t) / sizeof(uint32_t);
-
- const uint32_t ARM_THREAD_STATE64_COUNT =
- sizeof(arm_thread_state64_t) / sizeof(uint32_t);
-
- struct ppc_thread_state32_t {
- uint32_t srr0;
- uint32_t srr1;
- uint32_t r0;
- uint32_t r1;
- uint32_t r2;
- uint32_t r3;
- uint32_t r4;
- uint32_t r5;
- uint32_t r6;
- uint32_t r7;
- uint32_t r8;
- uint32_t r9;
- uint32_t r10;
- uint32_t r11;
- uint32_t r12;
- uint32_t r13;
- uint32_t r14;
- uint32_t r15;
- uint32_t r16;
- uint32_t r17;
- uint32_t r18;
- uint32_t r19;
- uint32_t r20;
- uint32_t r21;
- uint32_t r22;
- uint32_t r23;
- uint32_t r24;
- uint32_t r25;
- uint32_t r26;
- uint32_t r27;
- uint32_t r28;
- uint32_t r29;
- uint32_t r30;
- uint32_t r31;
- uint32_t ct;
- uint32_t xer;
- uint32_t lr;
- uint32_t ctr;
- uint32_t mq;
- uint32_t vrsave;
- };
-
- inline void swapStruct(ppc_thread_state32_t &x) {
- sys::swapByteOrder(x.srr0);
- sys::swapByteOrder(x.srr1);
- sys::swapByteOrder(x.r0);
- sys::swapByteOrder(x.r1);
- sys::swapByteOrder(x.r2);
- sys::swapByteOrder(x.r3);
- sys::swapByteOrder(x.r4);
- sys::swapByteOrder(x.r5);
- sys::swapByteOrder(x.r6);
- sys::swapByteOrder(x.r7);
- sys::swapByteOrder(x.r8);
- sys::swapByteOrder(x.r9);
- sys::swapByteOrder(x.r10);
- sys::swapByteOrder(x.r11);
- sys::swapByteOrder(x.r12);
- sys::swapByteOrder(x.r13);
- sys::swapByteOrder(x.r14);
- sys::swapByteOrder(x.r15);
- sys::swapByteOrder(x.r16);
- sys::swapByteOrder(x.r17);
- sys::swapByteOrder(x.r18);
- sys::swapByteOrder(x.r19);
- sys::swapByteOrder(x.r20);
- sys::swapByteOrder(x.r21);
- sys::swapByteOrder(x.r22);
- sys::swapByteOrder(x.r23);
- sys::swapByteOrder(x.r24);
- sys::swapByteOrder(x.r25);
- sys::swapByteOrder(x.r26);
- sys::swapByteOrder(x.r27);
- sys::swapByteOrder(x.r28);
- sys::swapByteOrder(x.r29);
- sys::swapByteOrder(x.r30);
- sys::swapByteOrder(x.r31);
- sys::swapByteOrder(x.ct);
- sys::swapByteOrder(x.xer);
- sys::swapByteOrder(x.lr);
- sys::swapByteOrder(x.ctr);
- sys::swapByteOrder(x.mq);
- sys::swapByteOrder(x.vrsave);
- }
-
- struct ppc_state_hdr_t {
- uint32_t flavor;
- uint32_t count;
- };
-
- struct ppc_thread_state_t {
- ppc_state_hdr_t tsh;
- union {
- ppc_thread_state32_t ts32;
- } uts;
- };
-
- inline void swapStruct(ppc_state_hdr_t &x) {
- sys::swapByteOrder(x.flavor);
- sys::swapByteOrder(x.count);
- }
-
- enum PPCThreadFlavors {
- PPC_THREAD_STATE = 1,
- PPC_FLOAT_STATE = 2,
- PPC_EXCEPTION_STATE = 3,
- PPC_VECTOR_STATE = 4,
- PPC_THREAD_STATE64 = 5,
- PPC_EXCEPTION_STATE64 = 6,
- PPC_THREAD_STATE_NONE = 7
- };
-
- inline void swapStruct(ppc_thread_state_t &x) {
- swapStruct(x.tsh);
- if (x.tsh.flavor == PPC_THREAD_STATE)
- swapStruct(x.uts.ts32);
- }
-
- const uint32_t PPC_THREAD_STATE_COUNT =
- sizeof(ppc_thread_state32_t) / sizeof(uint32_t);
-
- // Define a union of all load command structs
- #define LOAD_COMMAND_STRUCT(LCStruct) LCStruct LCStruct##_data;
-
- union macho_load_command {
- #include "llvm/Support/MachO.def"
- };
-
- } // end namespace MachO
-} // end namespace llvm
-
-#endif
diff --git a/contrib/llvm/include/llvm/Support/ManagedStatic.h b/contrib/llvm/include/llvm/Support/ManagedStatic.h
index 7ce86ee..b4bf321 100644
--- a/contrib/llvm/include/llvm/Support/ManagedStatic.h
+++ b/contrib/llvm/include/llvm/Support/ManagedStatic.h
@@ -14,25 +14,22 @@
#ifndef LLVM_SUPPORT_MANAGEDSTATIC_H
#define LLVM_SUPPORT_MANAGEDSTATIC_H
-#include "llvm/Support/Compiler.h"
#include <atomic>
#include <cstddef>
namespace llvm {
/// object_creator - Helper method for ManagedStatic.
-template<class C>
-LLVM_LIBRARY_VISIBILITY void* object_creator() {
- return new C();
-}
+template <class C> struct object_creator {
+ static void *call() { return new C(); }
+};
/// object_deleter - Helper method for ManagedStatic.
///
-template <typename T> struct LLVM_LIBRARY_VISIBILITY object_deleter {
+template <typename T> struct object_deleter {
static void call(void *Ptr) { delete (T *)Ptr; }
};
-template <typename T, size_t N>
-struct LLVM_LIBRARY_VISIBILITY object_deleter<T[N]> {
+template <typename T, size_t N> struct object_deleter<T[N]> {
static void call(void *Ptr) { delete[](T *)Ptr; }
};
@@ -59,14 +56,15 @@ public:
/// libraries that link in LLVM components) and for making destruction be
/// explicit through the llvm_shutdown() function call.
///
-template<class C>
+template <class C, class Creator = object_creator<C>,
+ class Deleter = object_deleter<C>>
class ManagedStatic : public ManagedStaticBase {
public:
// Accessors.
C &operator*() {
void *Tmp = Ptr.load(std::memory_order_acquire);
if (!Tmp)
- RegisterManagedStatic(object_creator<C>, object_deleter<C>::call);
+ RegisterManagedStatic(Creator::call, Deleter::call);
return *static_cast<C *>(Ptr.load(std::memory_order_relaxed));
}
@@ -76,7 +74,7 @@ public:
const C &operator*() const {
void *Tmp = Ptr.load(std::memory_order_acquire);
if (!Tmp)
- RegisterManagedStatic(object_creator<C>, object_deleter<C>::call);
+ RegisterManagedStatic(Creator::call, Deleter::call);
return *static_cast<C *>(Ptr.load(std::memory_order_relaxed));
}
diff --git a/contrib/llvm/include/llvm/Support/MathExtras.h b/contrib/llvm/include/llvm/Support/MathExtras.h
index 77970f4..fd29865 100644
--- a/contrib/llvm/include/llvm/Support/MathExtras.h
+++ b/contrib/llvm/include/llvm/Support/MathExtras.h
@@ -18,9 +18,10 @@
#include "llvm/Support/SwapByteOrder.h"
#include <algorithm>
#include <cassert>
+#include <climits>
#include <cstring>
-#include <type_traits>
#include <limits>
+#include <type_traits>
#ifdef _MSC_VER
#include <intrin.h>
@@ -112,7 +113,7 @@ std::size_t countTrailingZeros(T Val, ZeroBehavior ZB = ZB_Width) {
static_assert(std::numeric_limits<T>::is_integer &&
!std::numeric_limits<T>::is_signed,
"Only unsigned integral types are allowed.");
- return detail::TrailingZerosCounter<T, sizeof(T)>::count(Val, ZB);
+ return llvm::detail::TrailingZerosCounter<T, sizeof(T)>::count(Val, ZB);
}
namespace detail {
@@ -181,7 +182,7 @@ std::size_t countLeadingZeros(T Val, ZeroBehavior ZB = ZB_Width) {
static_assert(std::numeric_limits<T>::is_integer &&
!std::numeric_limits<T>::is_signed,
"Only unsigned integral types are allowed.");
- return detail::LeadingZerosCounter<T, sizeof(T)>::count(Val, ZB);
+ return llvm::detail::LeadingZerosCounter<T, sizeof(T)>::count(Val, ZB);
}
/// \brief Get the index of the first set bit starting from the least
@@ -198,6 +199,33 @@ template <typename T> T findFirstSet(T Val, ZeroBehavior ZB = ZB_Max) {
return countTrailingZeros(Val, ZB_Undefined);
}
+/// \brief Create a bitmask with the N right-most bits set to 1, and all other
+/// bits set to 0. Only unsigned types are allowed.
+template <typename T> T maskTrailingOnes(unsigned N) {
+ static_assert(std::is_unsigned<T>::value, "Invalid type!");
+ const unsigned Bits = CHAR_BIT * sizeof(T);
+ assert(N <= Bits && "Invalid bit index");
+ return N == 0 ? 0 : (T(-1) >> (Bits - N));
+}
+
+/// \brief Create a bitmask with the N left-most bits set to 1, and all other
+/// bits set to 0. Only unsigned types are allowed.
+template <typename T> T maskLeadingOnes(unsigned N) {
+ return ~maskTrailingOnes<T>(CHAR_BIT * sizeof(T) - N);
+}
+
+/// \brief Create a bitmask with the N right-most bits set to 0, and all other
+/// bits set to 1. Only unsigned types are allowed.
+template <typename T> T maskTrailingZeros(unsigned N) {
+ return maskLeadingOnes<T>(CHAR_BIT * sizeof(T) - N);
+}
+
+/// \brief Create a bitmask with the N left-most bits set to 0, and all other
+/// bits set to 1. Only unsigned types are allowed.
+template <typename T> T maskLeadingZeros(unsigned N) {
+ return maskTrailingOnes<T>(CHAR_BIT * sizeof(T) - N);
+}
+
/// \brief Get the index of the last set bit starting from the least
/// significant bit.
///
@@ -244,23 +272,22 @@ T reverseBits(T Val) {
// type overloading so that signed and unsigned integers can be used without
// ambiguity.
-/// Hi_32 - This function returns the high 32 bits of a 64 bit value.
+/// Return the high 32 bits of a 64 bit value.
constexpr inline uint32_t Hi_32(uint64_t Value) {
return static_cast<uint32_t>(Value >> 32);
}
-/// Lo_32 - This function returns the low 32 bits of a 64 bit value.
+/// Return the low 32 bits of a 64 bit value.
constexpr inline uint32_t Lo_32(uint64_t Value) {
return static_cast<uint32_t>(Value);
}
-/// Make_64 - This functions makes a 64-bit integer from a high / low pair of
-/// 32-bit integers.
+/// Make a 64-bit integer from a high / low pair of 32-bit integers.
constexpr inline uint64_t Make_64(uint32_t High, uint32_t Low) {
return ((uint64_t)High << 32) | (uint64_t)Low;
}
-/// isInt - Checks if an integer fits into the given bit width.
+/// Checks if an integer fits into the given bit width.
template <unsigned N> constexpr inline bool isInt(int64_t x) {
return N >= 64 || (-(INT64_C(1)<<(N-1)) <= x && x < (INT64_C(1)<<(N-1)));
}
@@ -275,8 +302,7 @@ template <> constexpr inline bool isInt<32>(int64_t x) {
return static_cast<int32_t>(x) == x;
}
-/// isShiftedInt<N,S> - Checks if a signed integer is an N bit number shifted
-/// left by S.
+/// Checks if a signed integer is an N bit number shifted left by S.
template <unsigned N, unsigned S>
constexpr inline bool isShiftedInt(int64_t x) {
static_assert(
@@ -285,7 +311,7 @@ constexpr inline bool isShiftedInt(int64_t x) {
return isInt<N + S>(x) && (x % (UINT64_C(1) << S) == 0);
}
-/// isUInt - Checks if an unsigned integer fits into the given bit width.
+/// Checks if an unsigned integer fits into the given bit width.
///
/// This is written as two functions rather than as simply
///
@@ -355,71 +381,63 @@ inline int64_t maxIntN(int64_t N) {
return (UINT64_C(1) << (N - 1)) - 1;
}
-/// isUIntN - Checks if an unsigned integer fits into the given (dynamic)
-/// bit width.
+/// Checks if an unsigned integer fits into the given (dynamic) bit width.
inline bool isUIntN(unsigned N, uint64_t x) {
return N >= 64 || x <= maxUIntN(N);
}
-/// isIntN - Checks if an signed integer fits into the given (dynamic)
-/// bit width.
+/// Checks if an signed integer fits into the given (dynamic) bit width.
inline bool isIntN(unsigned N, int64_t x) {
return N >= 64 || (minIntN(N) <= x && x <= maxIntN(N));
}
-/// isMask_32 - This function returns true if the argument is a non-empty
-/// sequence of ones starting at the least significant bit with the remainder
-/// zero (32 bit version). Ex. isMask_32(0x0000FFFFU) == true.
+/// Return true if the argument is a non-empty sequence of ones starting at the
+/// least significant bit with the remainder zero (32 bit version).
+/// Ex. isMask_32(0x0000FFFFU) == true.
constexpr inline bool isMask_32(uint32_t Value) {
return Value && ((Value + 1) & Value) == 0;
}
-/// isMask_64 - This function returns true if the argument is a non-empty
-/// sequence of ones starting at the least significant bit with the remainder
-/// zero (64 bit version).
+/// Return true if the argument is a non-empty sequence of ones starting at the
+/// least significant bit with the remainder zero (64 bit version).
constexpr inline bool isMask_64(uint64_t Value) {
return Value && ((Value + 1) & Value) == 0;
}
-/// isShiftedMask_32 - This function returns true if the argument contains a
-/// non-empty sequence of ones with the remainder zero (32 bit version.)
-/// Ex. isShiftedMask_32(0x0000FF00U) == true.
+/// Return true if the argument contains a non-empty sequence of ones with the
+/// remainder zero (32 bit version.) Ex. isShiftedMask_32(0x0000FF00U) == true.
constexpr inline bool isShiftedMask_32(uint32_t Value) {
return Value && isMask_32((Value - 1) | Value);
}
-/// isShiftedMask_64 - This function returns true if the argument contains a
-/// non-empty sequence of ones with the remainder zero (64 bit version.)
+/// Return true if the argument contains a non-empty sequence of ones with the
+/// remainder zero (64 bit version.)
constexpr inline bool isShiftedMask_64(uint64_t Value) {
return Value && isMask_64((Value - 1) | Value);
}
-/// isPowerOf2_32 - This function returns true if the argument is a power of
-/// two > 0. Ex. isPowerOf2_32(0x00100000U) == true (32 bit edition.)
+/// Return true if the argument is a power of two > 0.
+/// Ex. isPowerOf2_32(0x00100000U) == true (32 bit edition.)
constexpr inline bool isPowerOf2_32(uint32_t Value) {
return Value && !(Value & (Value - 1));
}
-/// isPowerOf2_64 - This function returns true if the argument is a power of two
-/// > 0 (64 bit edition.)
+/// Return true if the argument is a power of two > 0 (64 bit edition.)
constexpr inline bool isPowerOf2_64(uint64_t Value) {
return Value && !(Value & (Value - int64_t(1L)));
}
-/// ByteSwap_16 - This function returns a byte-swapped representation of the
-/// 16-bit argument, Value.
+/// Return a byte-swapped representation of the 16-bit argument.
inline uint16_t ByteSwap_16(uint16_t Value) {
return sys::SwapByteOrder_16(Value);
}
-/// ByteSwap_32 - This function returns a byte-swapped representation of the
-/// 32-bit argument, Value.
+/// Return a byte-swapped representation of the 32-bit argument.
inline uint32_t ByteSwap_32(uint32_t Value) {
return sys::SwapByteOrder_32(Value);
}
-/// ByteSwap_64 - This function returns a byte-swapped representation of the
-/// 64-bit argument, Value.
+/// Return a byte-swapped representation of the 64-bit argument.
inline uint64_t ByteSwap_64(uint64_t Value) {
return sys::SwapByteOrder_64(Value);
}
@@ -427,7 +445,7 @@ inline uint64_t ByteSwap_64(uint64_t Value) {
/// \brief Count the number of ones from the most significant bit to the first
/// zero bit.
///
-/// Ex. CountLeadingOnes(0xFF0FFF00) == 8.
+/// Ex. countLeadingOnes(0xFF0FFF00) == 8.
/// Only unsigned integral types are allowed.
///
/// \param ZB the behavior on an input of all ones. Only ZB_Width and
@@ -498,7 +516,7 @@ inline unsigned countPopulation(T Value) {
return detail::PopulationCounter<T, sizeof(T)>::count(Value);
}
-/// Log2 - This function returns the log base 2 of the specified value
+/// Return the log base 2 of the specified value.
inline double Log2(double Value) {
#if defined(__ANDROID_API__) && __ANDROID_API__ < 18
return __builtin_log(Value) / __builtin_log(2.0);
@@ -507,34 +525,33 @@ inline double Log2(double Value) {
#endif
}
-/// Log2_32 - This function returns the floor log base 2 of the specified value,
-/// -1 if the value is zero. (32 bit edition.)
+/// Return the floor log base 2 of the specified value, -1 if the value is zero.
+/// (32 bit edition.)
/// Ex. Log2_32(32) == 5, Log2_32(1) == 0, Log2_32(0) == -1, Log2_32(6) == 2
inline unsigned Log2_32(uint32_t Value) {
return 31 - countLeadingZeros(Value);
}
-/// Log2_64 - This function returns the floor log base 2 of the specified value,
-/// -1 if the value is zero. (64 bit edition.)
+/// Return the floor log base 2 of the specified value, -1 if the value is zero.
+/// (64 bit edition.)
inline unsigned Log2_64(uint64_t Value) {
return 63 - countLeadingZeros(Value);
}
-/// Log2_32_Ceil - This function returns the ceil log base 2 of the specified
-/// value, 32 if the value is zero. (32 bit edition).
+/// Return the ceil log base 2 of the specified value, 32 if the value is zero.
+/// (32 bit edition).
/// Ex. Log2_32_Ceil(32) == 5, Log2_32_Ceil(1) == 0, Log2_32_Ceil(6) == 3
inline unsigned Log2_32_Ceil(uint32_t Value) {
return 32 - countLeadingZeros(Value - 1);
}
-/// Log2_64_Ceil - This function returns the ceil log base 2 of the specified
-/// value, 64 if the value is zero. (64 bit edition.)
+/// Return the ceil log base 2 of the specified value, 64 if the value is zero.
+/// (64 bit edition.)
inline unsigned Log2_64_Ceil(uint64_t Value) {
return 64 - countLeadingZeros(Value - 1);
}
-/// GreatestCommonDivisor64 - Return the greatest common divisor of the two
-/// values using Euclid's algorithm.
+/// Return the greatest common divisor of the values using Euclid's algorithm.
inline uint64_t GreatestCommonDivisor64(uint64_t A, uint64_t B) {
while (B) {
uint64_t T = B;
@@ -544,8 +561,7 @@ inline uint64_t GreatestCommonDivisor64(uint64_t A, uint64_t B) {
return A;
}
-/// BitsToDouble - This function takes a 64-bit integer and returns the bit
-/// equivalent double.
+/// This function takes a 64-bit integer and returns the bit equivalent double.
inline double BitsToDouble(uint64_t Bits) {
double D;
static_assert(sizeof(uint64_t) == sizeof(double), "Unexpected type sizes");
@@ -553,8 +569,7 @@ inline double BitsToDouble(uint64_t Bits) {
return D;
}
-/// BitsToFloat - This function takes a 32-bit integer and returns the bit
-/// equivalent float.
+/// This function takes a 32-bit integer and returns the bit equivalent float.
inline float BitsToFloat(uint32_t Bits) {
float F;
static_assert(sizeof(uint32_t) == sizeof(float), "Unexpected type sizes");
@@ -562,10 +577,9 @@ inline float BitsToFloat(uint32_t Bits) {
return F;
}
-/// DoubleToBits - This function takes a double and returns the bit
-/// equivalent 64-bit integer. Note that copying doubles around
-/// changes the bits of NaNs on some hosts, notably x86, so this
-/// routine cannot be used if these bits are needed.
+/// This function takes a double and returns the bit equivalent 64-bit integer.
+/// Note that copying doubles around changes the bits of NaNs on some hosts,
+/// notably x86, so this routine cannot be used if these bits are needed.
inline uint64_t DoubleToBits(double Double) {
uint64_t Bits;
static_assert(sizeof(uint64_t) == sizeof(double), "Unexpected type sizes");
@@ -573,10 +587,9 @@ inline uint64_t DoubleToBits(double Double) {
return Bits;
}
-/// FloatToBits - This function takes a float and returns the bit
-/// equivalent 32-bit integer. Note that copying floats around
-/// changes the bits of NaNs on some hosts, notably x86, so this
-/// routine cannot be used if these bits are needed.
+/// This function takes a float and returns the bit equivalent 32-bit integer.
+/// Note that copying floats around changes the bits of NaNs on some hosts,
+/// notably x86, so this routine cannot be used if these bits are needed.
inline uint32_t FloatToBits(float Float) {
uint32_t Bits;
static_assert(sizeof(uint32_t) == sizeof(float), "Unexpected type sizes");
@@ -584,8 +597,8 @@ inline uint32_t FloatToBits(float Float) {
return Bits;
}
-/// MinAlign - A and B are either alignments or offsets. Return the minimum
-/// alignment that may be assumed after adding the two together.
+/// A and B are either alignments or offsets. Return the minimum alignment that
+/// may be assumed after adding the two together.
constexpr inline uint64_t MinAlign(uint64_t A, uint64_t B) {
// The largest power of 2 that divides both A and B.
//
@@ -614,8 +627,8 @@ inline size_t alignmentAdjustment(const void *Ptr, size_t Alignment) {
return alignAddr(Ptr, Alignment) - (uintptr_t)Ptr;
}
-/// NextPowerOf2 - Returns the next power of two (in 64-bits)
-/// that is strictly greater than A. Returns zero on overflow.
+/// Returns the next power of two (in 64-bits) that is strictly greater than A.
+/// Returns zero on overflow.
inline uint64_t NextPowerOf2(uint64_t A) {
A |= (A >> 1);
A |= (A >> 2);
diff --git a/contrib/llvm/include/llvm/Support/MemoryBuffer.h b/contrib/llvm/include/llvm/Support/MemoryBuffer.h
index f739d19..73f0251 100644
--- a/contrib/llvm/include/llvm/Support/MemoryBuffer.h
+++ b/contrib/llvm/include/llvm/Support/MemoryBuffer.h
@@ -14,14 +14,14 @@
#ifndef LLVM_SUPPORT_MEMORYBUFFER_H
#define LLVM_SUPPORT_MEMORYBUFFER_H
+#include "llvm-c/Types.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/CBindingWrapping.h"
#include "llvm/Support/ErrorOr.h"
-#include "llvm-c/Types.h"
-#include <memory>
#include <cstddef>
#include <cstdint>
+#include <memory>
namespace llvm {
@@ -69,12 +69,12 @@ public:
/// means that the client knows that the file exists and that it has the
/// specified size.
///
- /// \param IsVolatileSize Set to true to indicate that the file size may be
- /// changing, e.g. when libclang tries to parse while the user is
- /// editing/updating the file.
+ /// \param IsVolatile Set to true to indicate that the contents of the file
+ /// can change outside the user's control, e.g. when libclang tries to parse
+ /// while the user is editing/updating the file or if the file is on an NFS.
static ErrorOr<std::unique_ptr<MemoryBuffer>>
getFile(const Twine &Filename, int64_t FileSize = -1,
- bool RequiresNullTerminator = true, bool IsVolatileSize = false);
+ bool RequiresNullTerminator = true, bool IsVolatile = false);
/// Read all of the specified file into a MemoryBuffer as a stream
/// (i.e. until EOF reached). This is useful for special files that
@@ -87,17 +87,17 @@ public:
/// Since this is in the middle of a file, the buffer is not null terminated.
static ErrorOr<std::unique_ptr<MemoryBuffer>>
getOpenFileSlice(int FD, const Twine &Filename, uint64_t MapSize,
- int64_t Offset);
+ int64_t Offset, bool IsVolatile = false);
/// Given an already-open file descriptor, read the file and return a
/// MemoryBuffer.
///
- /// \param IsVolatileSize Set to true to indicate that the file size may be
- /// changing, e.g. when libclang tries to parse while the user is
- /// editing/updating the file.
+ /// \param IsVolatile Set to true to indicate that the contents of the file
+ /// can change outside the user's control, e.g. when libclang tries to parse
+ /// while the user is editing/updating the file or if the file is on an NFS.
static ErrorOr<std::unique_ptr<MemoryBuffer>>
getOpenFile(int FD, const Twine &Filename, uint64_t FileSize,
- bool RequiresNullTerminator = true, bool IsVolatileSize = false);
+ bool RequiresNullTerminator = true, bool IsVolatile = false);
/// Open the specified memory range as a MemoryBuffer. Note that InputData
/// must be null terminated if RequiresNullTerminator is true.
@@ -136,7 +136,7 @@ public:
/// Map a subrange of the specified file as a MemoryBuffer.
static ErrorOr<std::unique_ptr<MemoryBuffer>>
- getFileSlice(const Twine &Filename, uint64_t MapSize, uint64_t Offset);
+ getFileSlice(const Twine &Filename, uint64_t MapSize, uint64_t Offset, bool IsVolatile = false);
//===--------------------------------------------------------------------===//
// Provided for performance analysis.
diff --git a/contrib/llvm/include/llvm/Support/Parallel.h b/contrib/llvm/include/llvm/Support/Parallel.h
new file mode 100644
index 0000000..e36e0cc
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/Parallel.h
@@ -0,0 +1,249 @@
+//===- llvm/Support/Parallel.h - Parallel algorithms ----------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_PARALLEL_H
+#define LLVM_SUPPORT_PARALLEL_H
+
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/Config/llvm-config.h"
+#include "llvm/Support/MathExtras.h"
+
+#include <algorithm>
+#include <condition_variable>
+#include <functional>
+#include <mutex>
+
+#if defined(_MSC_VER) && LLVM_ENABLE_THREADS
+#pragma warning(push)
+#pragma warning(disable : 4530)
+#include <concrt.h>
+#include <ppl.h>
+#pragma warning(pop)
+#endif
+
+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{};
+
+namespace detail {
+
+#if LLVM_ENABLE_THREADS
+
+class Latch {
+ uint32_t Count;
+ mutable std::mutex Mutex;
+ mutable std::condition_variable Cond;
+
+public:
+ explicit Latch(uint32_t Count = 0) : Count(Count) {}
+ ~Latch() { sync(); }
+
+ void inc() {
+ std::unique_lock<std::mutex> lock(Mutex);
+ ++Count;
+ }
+
+ void dec() {
+ std::unique_lock<std::mutex> lock(Mutex);
+ if (--Count == 0)
+ Cond.notify_all();
+ }
+
+ void sync() const {
+ std::unique_lock<std::mutex> lock(Mutex);
+ Cond.wait(lock, [&] { return Count == 0; });
+ }
+};
+
+class TaskGroup {
+ Latch L;
+
+public:
+ void spawn(std::function<void()> f);
+
+ void sync() const { L.sync(); }
+};
+
+#if defined(_MSC_VER)
+template <class RandomAccessIterator, class Comparator>
+void parallel_sort(RandomAccessIterator Start, RandomAccessIterator End,
+ const Comparator &Comp) {
+ concurrency::parallel_sort(Start, End, Comp);
+}
+template <class IterTy, class FuncTy>
+void parallel_for_each(IterTy Begin, IterTy End, FuncTy Fn) {
+ concurrency::parallel_for_each(Begin, End, Fn);
+}
+
+template <class IndexTy, class FuncTy>
+void parallel_for_each_n(IndexTy Begin, IndexTy End, FuncTy Fn) {
+ concurrency::parallel_for(Begin, End, Fn);
+}
+
+#else
+const ptrdiff_t MinParallelSize = 1024;
+
+/// \brief Inclusive median.
+template <class RandomAccessIterator, class Comparator>
+RandomAccessIterator medianOf3(RandomAccessIterator Start,
+ RandomAccessIterator End,
+ const Comparator &Comp) {
+ RandomAccessIterator Mid = Start + (std::distance(Start, End) / 2);
+ return Comp(*Start, *(End - 1))
+ ? (Comp(*Mid, *(End - 1)) ? (Comp(*Start, *Mid) ? Mid : Start)
+ : End - 1)
+ : (Comp(*Mid, *Start) ? (Comp(*(End - 1), *Mid) ? Mid : End - 1)
+ : Start);
+}
+
+template <class RandomAccessIterator, class Comparator>
+void parallel_quick_sort(RandomAccessIterator Start, RandomAccessIterator End,
+ const Comparator &Comp, TaskGroup &TG, size_t Depth) {
+ // Do a sequential sort for small inputs.
+ if (std::distance(Start, End) < detail::MinParallelSize || Depth == 0) {
+ std::sort(Start, End, Comp);
+ return;
+ }
+
+ // Partition.
+ auto Pivot = medianOf3(Start, End, Comp);
+ // Move Pivot to End.
+ std::swap(*(End - 1), *Pivot);
+ Pivot = std::partition(Start, End - 1, [&Comp, End](decltype(*Start) V) {
+ return Comp(V, *(End - 1));
+ });
+ // Move Pivot to middle of partition.
+ std::swap(*Pivot, *(End - 1));
+
+ // Recurse.
+ TG.spawn([=, &Comp, &TG] {
+ parallel_quick_sort(Start, Pivot, Comp, TG, Depth - 1);
+ });
+ parallel_quick_sort(Pivot + 1, End, Comp, TG, Depth - 1);
+}
+
+template <class RandomAccessIterator, class Comparator>
+void parallel_sort(RandomAccessIterator Start, RandomAccessIterator End,
+ const Comparator &Comp) {
+ TaskGroup TG;
+ parallel_quick_sort(Start, End, Comp, TG,
+ llvm::Log2_64(std::distance(Start, End)) + 1);
+}
+
+template <class IterTy, class FuncTy>
+void parallel_for_each(IterTy Begin, IterTy End, FuncTy Fn) {
+ // TaskGroup has a relatively high overhead, so we want to reduce
+ // the number of spawn() calls. We'll create up to 1024 tasks here.
+ // (Note that 1024 is an arbitrary number. This code probably needs
+ // improving to take the number of available cores into account.)
+ ptrdiff_t TaskSize = std::distance(Begin, End) / 1024;
+ if (TaskSize == 0)
+ TaskSize = 1;
+
+ TaskGroup TG;
+ while (TaskSize <= std::distance(Begin, End)) {
+ TG.spawn([=, &Fn] { std::for_each(Begin, Begin + TaskSize, Fn); });
+ Begin += TaskSize;
+ }
+ TG.spawn([=, &Fn] { std::for_each(Begin, End, Fn); });
+}
+
+template <class IndexTy, class FuncTy>
+void parallel_for_each_n(IndexTy Begin, IndexTy End, FuncTy Fn) {
+ ptrdiff_t TaskSize = (End - Begin) / 1024;
+ if (TaskSize == 0)
+ TaskSize = 1;
+
+ TaskGroup TG;
+ IndexTy I = Begin;
+ for (; I + TaskSize < End; I += TaskSize) {
+ TG.spawn([=, &Fn] {
+ for (IndexTy J = I, E = I + TaskSize; J != E; ++J)
+ Fn(J);
+ });
+ }
+ TG.spawn([=, &Fn] {
+ for (IndexTy J = I; J < End; ++J)
+ Fn(J);
+ });
+}
+
+#endif
+
+#endif
+
+template <typename Iter>
+using DefComparator =
+ std::less<typename std::iterator_traits<Iter>::value_type>;
+
+} // namespace detail
+
+// 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!");
+ std::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!");
+ 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.
+#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);
+}
+
+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);
+}
+
+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);
+}
+#endif
+
+} // namespace parallel
+} // namespace llvm
+
+#endif // LLVM_SUPPORT_PARALLEL_H
diff --git a/contrib/llvm/include/llvm/Support/Path.h b/contrib/llvm/include/llvm/Support/Path.h
index 2bbcef0..e597967 100644
--- a/contrib/llvm/include/llvm/Support/Path.h
+++ b/contrib/llvm/include/llvm/Support/Path.h
@@ -17,6 +17,7 @@
#define LLVM_SUPPORT_PATH_H
#include "llvm/ADT/Twine.h"
+#include "llvm/ADT/iterator.h"
#include "llvm/Support/DataTypes.h"
#include <iterator>
@@ -24,6 +25,8 @@ namespace llvm {
namespace sys {
namespace path {
+enum class Style { windows, posix, native };
+
/// @name Lexical Component Iterator
/// @{
@@ -47,21 +50,21 @@ namespace path {
/// C:\foo\bar => C:,/,foo,bar
/// @endcode
class const_iterator
- : public std::iterator<std::input_iterator_tag, const StringRef> {
+ : public iterator_facade_base<const_iterator, std::input_iterator_tag,
+ const StringRef> {
StringRef Path; ///< The entire path.
StringRef Component; ///< The current component. Not necessarily in Path.
size_t Position; ///< The iterators current position within Path.
+ Style S; ///< The path style to use.
// An end iterator has Position = Path.size() + 1.
- friend const_iterator begin(StringRef path);
+ friend const_iterator begin(StringRef path, Style style);
friend const_iterator end(StringRef path);
public:
reference operator*() const { return Component; }
- pointer operator->() const { return &Component; }
const_iterator &operator++(); // preincrement
bool operator==(const const_iterator &RHS) const;
- bool operator!=(const const_iterator &RHS) const { return !(*this == RHS); }
/// @brief Difference in bytes between this and RHS.
ptrdiff_t operator-(const const_iterator &RHS) const;
@@ -73,20 +76,20 @@ public:
/// \a path in reverse order. The traversal order is exactly reversed from that
/// of \a const_iterator
class reverse_iterator
- : public std::iterator<std::input_iterator_tag, const StringRef> {
+ : public iterator_facade_base<reverse_iterator, std::input_iterator_tag,
+ const StringRef> {
StringRef Path; ///< The entire path.
StringRef Component; ///< The current component. Not necessarily in Path.
size_t Position; ///< The iterators current position within Path.
+ Style S; ///< The path style to use.
- friend reverse_iterator rbegin(StringRef path);
+ friend reverse_iterator rbegin(StringRef path, Style style);
friend reverse_iterator rend(StringRef path);
public:
reference operator*() const { return Component; }
- pointer operator->() const { return &Component; }
reverse_iterator &operator++(); // preincrement
bool operator==(const reverse_iterator &RHS) const;
- bool operator!=(const reverse_iterator &RHS) const { return !(*this == RHS); }
/// @brief Difference in bytes between this and RHS.
ptrdiff_t operator-(const reverse_iterator &RHS) const;
@@ -95,7 +98,7 @@ public:
/// @brief Get begin iterator over \a path.
/// @param path Input path.
/// @returns Iterator initialized with the first component of \a path.
-const_iterator begin(StringRef path);
+const_iterator begin(StringRef path, Style style = Style::native);
/// @brief Get end iterator over \a path.
/// @param path Input path.
@@ -105,7 +108,7 @@ const_iterator end(StringRef path);
/// @brief Get reverse begin iterator over \a path.
/// @param path Input path.
/// @returns Iterator initialized with the first reverse component of \a path.
-reverse_iterator rbegin(StringRef path);
+reverse_iterator rbegin(StringRef path, Style style = Style::native);
/// @brief Get reverse end iterator over \a path.
/// @param path Input path.
@@ -126,7 +129,7 @@ reverse_iterator rend(StringRef path);
/// @endcode
///
/// @param path A path that is modified to not have a file component.
-void remove_filename(SmallVectorImpl<char> &path);
+void remove_filename(SmallVectorImpl<char> &path, Style style = Style::native);
/// @brief Replace the file extension of \a path with \a extension.
///
@@ -140,7 +143,8 @@ void remove_filename(SmallVectorImpl<char> &path);
/// @param extension The extension to be added. It may be empty. It may also
/// optionally start with a '.', if it does not, one will be
/// prepended.
-void replace_extension(SmallVectorImpl<char> &path, const Twine &extension);
+void replace_extension(SmallVectorImpl<char> &path, const Twine &extension,
+ Style style = Style::native);
/// @brief Replace matching path prefix with another path.
///
@@ -156,8 +160,8 @@ void replace_extension(SmallVectorImpl<char> &path, const Twine &extension);
/// @param OldPrefix The path prefix to strip from \a Path.
/// @param NewPrefix The path prefix to replace \a NewPrefix with.
void replace_path_prefix(SmallVectorImpl<char> &Path,
- const StringRef &OldPrefix,
- const StringRef &NewPrefix);
+ const StringRef &OldPrefix, const StringRef &NewPrefix,
+ Style style = Style::native);
/// @brief Append to path.
///
@@ -174,6 +178,9 @@ void append(SmallVectorImpl<char> &path, const Twine &a,
const Twine &c = "",
const Twine &d = "");
+void append(SmallVectorImpl<char> &path, Style style, const Twine &a,
+ const Twine &b = "", const Twine &c = "", const Twine &d = "");
+
/// @brief Append to path.
///
/// @code
@@ -185,8 +192,8 @@ void append(SmallVectorImpl<char> &path, const Twine &a,
/// @param path Set to \a path + [\a begin, \a end).
/// @param begin Start of components to append.
/// @param end One past the end of components to append.
-void append(SmallVectorImpl<char> &path,
- const_iterator begin, const_iterator end);
+void append(SmallVectorImpl<char> &path, const_iterator begin,
+ const_iterator end, Style style = Style::native);
/// @}
/// @name Transforms (or some other better name)
@@ -198,14 +205,15 @@ void append(SmallVectorImpl<char> &path,
///
/// @param path A path that is transformed to native format.
/// @param result Holds the result of the transformation.
-void native(const Twine &path, SmallVectorImpl<char> &result);
+void native(const Twine &path, SmallVectorImpl<char> &result,
+ Style style = Style::native);
/// Convert path to the native form in place. This is used to give paths to
/// users and operating system calls in the platform's normal way. For example,
/// on Windows all '/' are converted to '\'.
///
/// @param path A path that is transformed to native format.
-void native(SmallVectorImpl<char> &path);
+void native(SmallVectorImpl<char> &path, Style style = Style::native);
/// @brief Replaces backslashes with slashes if Windows.
///
@@ -213,7 +221,7 @@ void native(SmallVectorImpl<char> &path);
/// @result The result of replacing backslashes with forward slashes if Windows.
/// On Unix, this function is a no-op because backslashes are valid path
/// chracters.
-std::string convert_to_slash(StringRef path);
+std::string convert_to_slash(StringRef path, Style style = Style::native);
/// @}
/// @name Lexical Observers
@@ -229,7 +237,7 @@ std::string convert_to_slash(StringRef path);
///
/// @param path Input path.
/// @result The root name of \a path if it has one, otherwise "".
-StringRef root_name(StringRef path);
+StringRef root_name(StringRef path, Style style = Style::native);
/// @brief Get root directory.
///
@@ -242,7 +250,7 @@ StringRef root_name(StringRef path);
/// @param path Input path.
/// @result The root directory of \a path if it has one, otherwise
/// "".
-StringRef root_directory(StringRef path);
+StringRef root_directory(StringRef path, Style style = Style::native);
/// @brief Get root path.
///
@@ -250,7 +258,7 @@ StringRef root_directory(StringRef path);
///
/// @param path Input path.
/// @result The root path of \a path if it has one, otherwise "".
-StringRef root_path(StringRef path);
+StringRef root_path(StringRef path, Style style = Style::native);
/// @brief Get relative path.
///
@@ -262,7 +270,7 @@ StringRef root_path(StringRef path);
///
/// @param path Input path.
/// @result The path starting after root_path if one exists, otherwise "".
-StringRef relative_path(StringRef path);
+StringRef relative_path(StringRef path, Style style = Style::native);
/// @brief Get parent path.
///
@@ -274,7 +282,7 @@ StringRef relative_path(StringRef path);
///
/// @param path Input path.
/// @result The parent path of \a path if one exists, otherwise "".
-StringRef parent_path(StringRef path);
+StringRef parent_path(StringRef path, Style style = Style::native);
/// @brief Get filename.
///
@@ -288,7 +296,7 @@ StringRef parent_path(StringRef path);
/// @param path Input path.
/// @result The filename part of \a path. This is defined as the last component
/// of \a path.
-StringRef filename(StringRef path);
+StringRef filename(StringRef path, Style style = Style::native);
/// @brief Get stem.
///
@@ -306,7 +314,7 @@ StringRef filename(StringRef path);
///
/// @param path Input path.
/// @result The stem of \a path.
-StringRef stem(StringRef path);
+StringRef stem(StringRef path, Style style = Style::native);
/// @brief Get extension.
///
@@ -322,18 +330,18 @@ StringRef stem(StringRef path);
///
/// @param path Input path.
/// @result The extension of \a path.
-StringRef extension(StringRef path);
+StringRef extension(StringRef path, Style style = Style::native);
/// @brief Check whether the given char is a path separator on the host OS.
///
/// @param value a character
/// @result true if \a value is a path separator character on the host OS
-bool is_separator(char value);
+bool is_separator(char value, Style style = Style::native);
/// @brief Return the preferred separator for this platform.
///
/// @result StringRef of the preferred separator, null-terminated.
-StringRef get_separator();
+StringRef get_separator(Style style = Style::native);
/// @brief Get the typical temporary directory for the system, e.g.,
/// "/var/tmp" or "C:/TEMP"
@@ -374,7 +382,7 @@ bool user_cache_directory(SmallVectorImpl<char> &Result, const Twine &Path1,
///
/// @param path Input path.
/// @result True if the path has a root name, false otherwise.
-bool has_root_name(const Twine &path);
+bool has_root_name(const Twine &path, Style style = Style::native);
/// @brief Has root directory?
///
@@ -382,7 +390,7 @@ bool has_root_name(const Twine &path);
///
/// @param path Input path.
/// @result True if the path has a root directory, false otherwise.
-bool has_root_directory(const Twine &path);
+bool has_root_directory(const Twine &path, Style style = Style::native);
/// @brief Has root path?
///
@@ -390,7 +398,7 @@ bool has_root_directory(const Twine &path);
///
/// @param path Input path.
/// @result True if the path has a root path, false otherwise.
-bool has_root_path(const Twine &path);
+bool has_root_path(const Twine &path, Style style = Style::native);
/// @brief Has relative path?
///
@@ -398,7 +406,7 @@ bool has_root_path(const Twine &path);
///
/// @param path Input path.
/// @result True if the path has a relative path, false otherwise.
-bool has_relative_path(const Twine &path);
+bool has_relative_path(const Twine &path, Style style = Style::native);
/// @brief Has parent path?
///
@@ -406,7 +414,7 @@ bool has_relative_path(const Twine &path);
///
/// @param path Input path.
/// @result True if the path has a parent path, false otherwise.
-bool has_parent_path(const Twine &path);
+bool has_parent_path(const Twine &path, Style style = Style::native);
/// @brief Has filename?
///
@@ -414,7 +422,7 @@ bool has_parent_path(const Twine &path);
///
/// @param path Input path.
/// @result True if the path has a filename, false otherwise.
-bool has_filename(const Twine &path);
+bool has_filename(const Twine &path, Style style = Style::native);
/// @brief Has stem?
///
@@ -422,7 +430,7 @@ bool has_filename(const Twine &path);
///
/// @param path Input path.
/// @result True if the path has a stem, false otherwise.
-bool has_stem(const Twine &path);
+bool has_stem(const Twine &path, Style style = Style::native);
/// @brief Has extension?
///
@@ -430,25 +438,25 @@ bool has_stem(const Twine &path);
///
/// @param path Input path.
/// @result True if the path has a extension, false otherwise.
-bool has_extension(const Twine &path);
+bool has_extension(const Twine &path, Style style = Style::native);
/// @brief Is path absolute?
///
/// @param path Input path.
/// @result True if the path is absolute, false if it is not.
-bool is_absolute(const Twine &path);
+bool is_absolute(const Twine &path, Style style = Style::native);
/// @brief Is path relative?
///
/// @param path Input path.
/// @result True if the path is relative, false if it is not.
-bool is_relative(const Twine &path);
+bool is_relative(const Twine &path, Style style = Style::native);
/// @brief Remove redundant leading "./" pieces and consecutive separators.
///
/// @param path Input path.
/// @result The cleaned-up \a path.
-StringRef remove_leading_dotslash(StringRef path);
+StringRef remove_leading_dotslash(StringRef path, Style style = Style::native);
/// @brief In-place remove any './' and optionally '../' components from a path.
///
@@ -456,7 +464,8 @@ StringRef remove_leading_dotslash(StringRef path);
/// @param remove_dot_dot specify if '../' (except for leading "../") should be
/// removed
/// @result True if path was changed
-bool remove_dots(SmallVectorImpl<char> &path, bool remove_dot_dot = false);
+bool remove_dots(SmallVectorImpl<char> &path, bool remove_dot_dot = false,
+ Style style = Style::native);
} // end namespace path
} // end namespace sys
diff --git a/contrib/llvm/include/llvm/Support/PointerLikeTypeTraits.h b/contrib/llvm/include/llvm/Support/PointerLikeTypeTraits.h
index 9ff894e..521a496 100644
--- a/contrib/llvm/include/llvm/Support/PointerLikeTypeTraits.h
+++ b/contrib/llvm/include/llvm/Support/PointerLikeTypeTraits.h
@@ -60,6 +60,20 @@ public:
enum { NumLowBitsAvailable = 2 };
};
+// Provide PointerLikeTypeTraits for const things.
+template <typename T> class PointerLikeTypeTraits<const T> {
+ typedef PointerLikeTypeTraits<T> NonConst;
+
+public:
+ static inline const void *getAsVoidPointer(const T P) {
+ return NonConst::getAsVoidPointer(P);
+ }
+ static inline const T getFromVoidPointer(const void *P) {
+ return NonConst::getFromVoidPointer(const_cast<void *>(P));
+ }
+ enum { NumLowBitsAvailable = NonConst::NumLowBitsAvailable };
+};
+
// Provide PointerLikeTypeTraits for const pointers.
template <typename T> class PointerLikeTypeTraits<const T *> {
typedef PointerLikeTypeTraits<T *> NonConst;
diff --git a/contrib/llvm/include/llvm/Support/RWMutex.h b/contrib/llvm/include/llvm/Support/RWMutex.h
index e4736b8..85f4fc0 100644
--- a/contrib/llvm/include/llvm/Support/RWMutex.h
+++ b/contrib/llvm/include/llvm/Support/RWMutex.h
@@ -14,7 +14,7 @@
#ifndef LLVM_SUPPORT_RWMUTEX_H
#define LLVM_SUPPORT_RWMUTEX_H
-#include "llvm/Support/Compiler.h"
+#include "llvm/Config/llvm-config.h"
#include "llvm/Support/Threading.h"
#include <cassert>
@@ -32,6 +32,13 @@ namespace sys {
/// @brief Default Constructor.
explicit RWMutexImpl();
+ /// @}
+ /// @name Do Not Implement
+ /// @{
+ RWMutexImpl(const RWMutexImpl & original) = delete;
+ RWMutexImpl &operator=(const RWMutexImpl &) = delete;
+ /// @}
+
/// Releases and removes the lock
/// @brief Destructor
~RWMutexImpl();
@@ -70,16 +77,8 @@ namespace sys {
/// @{
private:
#if defined(LLVM_ENABLE_THREADS) && LLVM_ENABLE_THREADS != 0
- void* data_; ///< We don't know what the data will be
+ void* data_ = nullptr; ///< We don't know what the data will be
#endif
-
- /// @}
- /// @name Do Not Implement
- /// @{
- private:
- RWMutexImpl(const RWMutexImpl & original) = delete;
- void operator=(const RWMutexImpl &) = delete;
- /// @}
};
/// SmartMutex - An R/W mutex with a compile time constant parameter that
@@ -93,6 +92,8 @@ namespace sys {
public:
explicit SmartRWMutex() = default;
+ SmartRWMutex(const SmartRWMutex<mt_only> & original) = delete;
+ SmartRWMutex<mt_only> &operator=(const SmartRWMutex<mt_only> &) = delete;
bool lock_shared() {
if (!mt_only || llvm_is_multithreaded())
@@ -136,10 +137,6 @@ namespace sys {
--writers;
return true;
}
-
- private:
- SmartRWMutex(const SmartRWMutex<mt_only> & original);
- void operator=(const SmartRWMutex<mt_only> &);
};
typedef SmartRWMutex<false> RWMutex;
diff --git a/contrib/llvm/include/llvm/Support/Recycler.h b/contrib/llvm/include/llvm/Support/Recycler.h
index 1523aad..53db2e8 100644
--- a/contrib/llvm/include/llvm/Support/Recycler.h
+++ b/contrib/llvm/include/llvm/Support/Recycler.h
@@ -42,13 +42,16 @@ class Recycler {
FreeNode *pop_val() {
auto *Val = FreeList;
+ __asan_unpoison_memory_region(Val, Size);
FreeList = FreeList->Next;
+ __msan_allocated_memory(Val, Size);
return Val;
}
void push(FreeNode *N) {
N->Next = FreeList;
FreeList = N;
+ __asan_poison_memory_region(N, Size);
}
public:
diff --git a/contrib/llvm/include/llvm/Support/Regex.h b/contrib/llvm/include/llvm/Support/Regex.h
index 83db803..f498835 100644
--- a/contrib/llvm/include/llvm/Support/Regex.h
+++ b/contrib/llvm/include/llvm/Support/Regex.h
@@ -57,7 +57,7 @@ namespace llvm {
/// isValid - returns the error encountered during regex compilation, or
/// matching, if any.
- bool isValid(std::string &Error);
+ bool isValid(std::string &Error) const;
/// getNumMatches - In a valid regex, return the number of parenthesized
/// matches it contains. The number filled in by match will include this
diff --git a/contrib/llvm/include/llvm/Support/ReverseIteration.h b/contrib/llvm/include/llvm/Support/ReverseIteration.h
new file mode 100644
index 0000000..cb97b60
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/ReverseIteration.h
@@ -0,0 +1,17 @@
+#ifndef LLVM_SUPPORT_REVERSEITERATION_H
+#define LLVM_SUPPORT_REVERSEITERATION_H
+
+#include "llvm/Config/abi-breaking.h"
+
+namespace llvm {
+#if LLVM_ENABLE_ABI_BREAKING_CHECKS
+template <class T = void> struct ReverseIterate { static bool value; };
+#if LLVM_ENABLE_REVERSE_ITERATION
+template <class T> bool ReverseIterate<T>::value = true;
+#else
+template <class T> bool ReverseIterate<T>::value = false;
+#endif
+#endif
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/SMLoc.h b/contrib/llvm/include/llvm/Support/SMLoc.h
index eb3a1ba..5b8be55 100644
--- a/contrib/llvm/include/llvm/Support/SMLoc.h
+++ b/contrib/llvm/include/llvm/Support/SMLoc.h
@@ -22,10 +22,10 @@ namespace llvm {
/// Represents a location in source code.
class SMLoc {
- const char *Ptr;
+ const char *Ptr = nullptr;
public:
- SMLoc() : Ptr(nullptr) {}
+ SMLoc() = default;
bool isValid() const { return Ptr != nullptr; }
diff --git a/contrib/llvm/include/llvm/Support/ScopedPrinter.h b/contrib/llvm/include/llvm/Support/ScopedPrinter.h
index a2f2e09..1b66519 100644
--- a/contrib/llvm/include/llvm/Support/ScopedPrinter.h
+++ b/contrib/llvm/include/llvm/Support/ScopedPrinter.h
@@ -295,6 +295,11 @@ public:
printBinaryImpl(Label, StringRef(), V, false);
}
+ void printBinaryBlock(StringRef Label, ArrayRef<uint8_t> Value,
+ uint32_t StartOffset) {
+ printBinaryImpl(Label, StringRef(), Value, true, StartOffset);
+ }
+
void printBinaryBlock(StringRef Label, ArrayRef<uint8_t> Value) {
printBinaryImpl(Label, StringRef(), Value, true);
}
@@ -333,7 +338,7 @@ private:
}
void printBinaryImpl(StringRef Label, StringRef Str, ArrayRef<uint8_t> Value,
- bool Block);
+ bool Block, uint32_t StartOffset = 0);
raw_ostream &OS;
int IndentLevel;
diff --git a/contrib/llvm/include/llvm/Support/Solaris.h b/contrib/llvm/include/llvm/Support/Solaris/sys/regset.h
index b082285..6a69ebe 100644
--- a/contrib/llvm/include/llvm/Support/Solaris.h
+++ b/contrib/llvm/include/llvm/Support/Solaris/sys/regset.h
@@ -1,4 +1,4 @@
-/*===- llvm/Support/Solaris.h ------------------------------------*- C++ -*-===*
+/*===- llvm/Support/Solaris/sys/regset.h ------------------------*- C++ -*-===*
*
* The LLVM Compiler Infrastructure
*
@@ -7,24 +7,14 @@
*
*===----------------------------------------------------------------------===*
*
- * This file contains portability fixes for Solaris hosts.
+ * This file works around excessive name space pollution from the system header
+ * on Solaris hosts.
*
*===----------------------------------------------------------------------===*/
-#ifndef LLVM_SUPPORT_SOLARIS_H
-#define LLVM_SUPPORT_SOLARIS_H
+#ifndef LLVM_SUPPORT_SOLARIS_SYS_REGSET_H
-#include <sys/types.h>
-#include <sys/regset.h>
-
-/* Solaris doesn't have endian.h. SPARC is the only supported big-endian ISA. */
-#define BIG_ENDIAN 4321
-#define LITTLE_ENDIAN 1234
-#if defined(__sparc) || defined(__sparc__)
-#define BYTE_ORDER BIG_ENDIAN
-#else
-#define BYTE_ORDER LITTLE_ENDIAN
-#endif
+#include_next <sys/regset.h>
#undef CS
#undef DS
diff --git a/contrib/llvm/include/llvm/Support/SourceMgr.h b/contrib/llvm/include/llvm/Support/SourceMgr.h
index bc7478e..399f8dc 100644
--- a/contrib/llvm/include/llvm/Support/SourceMgr.h
+++ b/contrib/llvm/include/llvm/Support/SourceMgr.h
@@ -17,18 +17,24 @@
#define LLVM_SUPPORT_SOURCEMGR_H
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/None.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 {
- class SourceMgr;
- class SMDiagnostic;
- class SMFixIt;
- class Twine;
- class raw_ostream;
+
+class raw_ostream;
+class SMDiagnostic;
+class SMFixIt;
/// This owns the files read by a parser, handles include stacks,
/// and handles diagnostic wrangling.
@@ -43,7 +49,8 @@ public:
/// Clients that want to handle their own diagnostics in a custom way can
/// register a function pointer+context as a diagnostic handler.
/// It gets called each time PrintMessage is invoked.
- typedef void (*DiagHandlerTy)(const SMDiagnostic &, void *Context);
+ using DiagHandlerTy = void (*)(const SMDiagnostic &, void *Context);
+
private:
struct SrcBuffer {
/// The memory buffer for the file.
@@ -61,18 +68,17 @@ private:
/// This is a cache for line number queries, its implementation is really
/// private to SourceMgr.cpp.
- mutable void *LineNoCache;
+ mutable void *LineNoCache = nullptr;
- DiagHandlerTy DiagHandler;
- void *DiagContext;
+ DiagHandlerTy DiagHandler = nullptr;
+ void *DiagContext = nullptr;
bool isValidBufferID(unsigned i) const { return i && i <= Buffers.size(); }
- SourceMgr(const SourceMgr&) = delete;
- void operator=(const SourceMgr&) = delete;
public:
- SourceMgr()
- : LineNoCache(nullptr), DiagHandler(nullptr), DiagContext(nullptr) {}
+ SourceMgr() = default;
+ SourceMgr(const SourceMgr &) = delete;
+ SourceMgr &operator=(const SourceMgr &) = delete;
~SourceMgr();
void setIncludeDirs(const std::vector<std::string> &Dirs) {
@@ -190,7 +196,6 @@ public:
void PrintIncludeStack(SMLoc IncludeLoc, raw_ostream &OS) const;
};
-
/// Represents a single fixit, a replacement of one range of text with another.
class SMFixIt {
SMRange Range;
@@ -222,33 +227,31 @@ public:
}
};
-
/// Instances of this class encapsulate one diagnostic report, allowing
/// printing to a raw_ostream as a caret diagnostic.
class SMDiagnostic {
- const SourceMgr *SM;
+ const SourceMgr *SM = nullptr;
SMLoc Loc;
std::string Filename;
- int LineNo, ColumnNo;
- SourceMgr::DiagKind Kind;
+ int LineNo = 0;
+ int ColumnNo = 0;
+ SourceMgr::DiagKind Kind = SourceMgr::DK_Error;
std::string Message, LineContents;
- std::vector<std::pair<unsigned, unsigned> > Ranges;
+ std::vector<std::pair<unsigned, unsigned>> Ranges;
SmallVector<SMFixIt, 4> FixIts;
public:
// Null diagnostic.
- SMDiagnostic()
- : SM(nullptr), LineNo(0), ColumnNo(0), Kind(SourceMgr::DK_Error) {}
+ SMDiagnostic() = default;
// Diagnostic with no location (e.g. file not found, command line arg error).
SMDiagnostic(StringRef filename, SourceMgr::DiagKind Knd, StringRef Msg)
- : SM(nullptr), 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<std::pair<unsigned,unsigned>> Ranges,
ArrayRef<SMFixIt> FixIts = None);
const SourceMgr *getSourceMgr() const { return SM; }
@@ -259,9 +262,7 @@ public:
SourceMgr::DiagKind getKind() const { return Kind; }
StringRef getMessage() const { return Message; }
StringRef getLineContents() const { return LineContents; }
- ArrayRef<std::pair<unsigned, unsigned> > getRanges() const {
- return Ranges;
- }
+ ArrayRef<std::pair<unsigned, unsigned>> getRanges() const { return Ranges; }
void addFixIt(const SMFixIt &Hint) {
FixIts.push_back(Hint);
@@ -275,6 +276,6 @@ public:
bool ShowKindLabel = true) const;
};
-} // end llvm namespace
+} // end namespace llvm
-#endif
+#endif // LLVM_SUPPORT_SOURCEMGR_H
diff --git a/contrib/llvm/include/llvm/Support/StringPool.h b/contrib/llvm/include/llvm/Support/StringPool.h
index 2ec0c3b..bb5fd07 100644
--- a/contrib/llvm/include/llvm/Support/StringPool.h
+++ b/contrib/llvm/include/llvm/Support/StringPool.h
@@ -1,4 +1,4 @@
-//===-- StringPool.h - Interned string pool ---------------------*- C++ -*-===//
+//===- StringPool.h - Interned string pool ----------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -30,6 +30,7 @@
#define LLVM_SUPPORT_STRINGPOOL_H
#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
#include <cassert>
namespace llvm {
@@ -43,17 +44,17 @@ namespace llvm {
/// PooledString - This is the value of an entry in the pool's interning
/// table.
struct PooledString {
- StringPool *Pool; ///< So the string can remove itself.
- unsigned Refcount; ///< Number of referencing PooledStringPtrs.
+ StringPool *Pool = nullptr; ///< So the string can remove itself.
+ unsigned Refcount = 0; ///< Number of referencing PooledStringPtrs.
public:
- PooledString() : Pool(nullptr), Refcount(0) { }
+ PooledString() = default;
};
friend class PooledStringPtr;
- typedef StringMap<PooledString> table_t;
- typedef StringMapEntry<PooledString> entry_t;
+ using table_t = StringMap<PooledString>;
+ using entry_t = StringMapEntry<PooledString>;
table_t InternTable;
public:
@@ -76,11 +77,12 @@ namespace llvm {
/// a single pointer, but it does have reference-counting overhead when
/// copied.
class PooledStringPtr {
- typedef StringPool::entry_t entry_t;
- entry_t *S;
+ using entry_t = StringPool::entry_t;
+
+ entry_t *S = nullptr;
public:
- PooledStringPtr() : S(nullptr) {}
+ PooledStringPtr() = default;
explicit PooledStringPtr(entry_t *E) : S(E) {
if (S) ++S->getValue().Refcount;
@@ -133,6 +135,6 @@ namespace llvm {
inline bool operator!=(const PooledStringPtr &That) const { return S != That.S; }
};
-} // End llvm namespace
+} // end namespace llvm
-#endif
+#endif // LLVM_SUPPORT_STRINGPOOL_H
diff --git a/contrib/llvm/include/llvm/Support/StringSaver.h b/contrib/llvm/include/llvm/Support/StringSaver.h
index fcddd4c..e85b289 100644
--- a/contrib/llvm/include/llvm/Support/StringSaver.h
+++ b/contrib/llvm/include/llvm/Support/StringSaver.h
@@ -26,7 +26,7 @@ public:
StringRef save(const char *S) { return save(StringRef(S)); }
StringRef save(StringRef S);
StringRef save(const Twine &S) { return save(StringRef(S.str())); }
- StringRef save(std::string &S) { return save(StringRef(S)); }
+ StringRef save(const std::string &S) { return save(StringRef(S)); }
};
}
#endif
diff --git a/contrib/llvm/include/llvm/Support/TargetParser.h b/contrib/llvm/include/llvm/Support/TargetParser.h
index 63aeca7..e13582f 100644
--- a/contrib/llvm/include/llvm/Support/TargetParser.h
+++ b/contrib/llvm/include/llvm/Support/TargetParser.h
@@ -17,6 +17,7 @@
// FIXME: vector is used because that's what clang uses for subtarget feature
// lists, but SmallVector would probably be better
+#include "llvm/ADT/Triple.h"
#include <vector>
namespace llvm {
@@ -75,7 +76,7 @@ enum ArchExtKind : unsigned {
AEK_CRC = 0x2,
AEK_CRYPTO = 0x4,
AEK_FP = 0x8,
- AEK_HWDIV = 0x10,
+ AEK_HWDIVTHUMB = 0x10,
AEK_HWDIVARM = 0x20,
AEK_MP = 0x40,
AEK_SIMD = 0x80,
@@ -84,6 +85,7 @@ enum ArchExtKind : unsigned {
AEK_DSP = 0x400,
AEK_FP16 = 0x800,
AEK_RAS = 0x1000,
+ AEK_SVE = 0x2000,
// Unsupported extensions.
AEK_OS = 0x8000000,
AEK_IWMMXT = 0x10000000,
@@ -140,9 +142,11 @@ unsigned parseArchEndian(StringRef Arch);
unsigned parseArchProfile(StringRef Arch);
unsigned parseArchVersion(StringRef Arch);
+StringRef computeDefaultTargetABI(const Triple &TT, StringRef CPU);
+
} // namespace ARM
-// FIXME:This should be made into class design,to avoid dupplication.
+// FIXME:This should be made into class design,to avoid dupplication.
namespace AArch64 {
// Arch names.
@@ -163,7 +167,8 @@ enum ArchExtKind : unsigned {
AEK_FP16 = 0x20,
AEK_PROFILE = 0x40,
AEK_RAS = 0x80,
- AEK_LSE = 0x100
+ AEK_LSE = 0x100,
+ AEK_SVE = 0x200
};
StringRef getCanonicalArchName(StringRef Arch);
diff --git a/contrib/llvm/include/llvm/Support/TargetRegistry.h b/contrib/llvm/include/llvm/Support/TargetRegistry.h
index 954cdb1..8454b27 100644
--- a/contrib/llvm/include/llvm/Support/TargetRegistry.h
+++ b/contrib/llvm/include/llvm/Support/TargetRegistry.h
@@ -1,4 +1,4 @@
-//===-- Support/TargetRegistry.h - Target Registration ----------*- C++ -*-===//
+//===- Support/TargetRegistry.h - Target Registration -----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -21,14 +21,21 @@
#include "llvm-c/Disassembler.h"
#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Triple.h"
+#include "llvm/ADT/iterator_range.h"
#include "llvm/Support/CodeGen.h"
+#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FormattedStream.h"
+#include <algorithm>
#include <cassert>
+#include <cstddef>
+#include <iterator>
#include <memory>
#include <string>
namespace llvm {
+
class AsmPrinter;
class MCAsmBackend;
class MCAsmInfo;
@@ -36,22 +43,21 @@ class MCAsmParser;
class MCCodeEmitter;
class MCContext;
class MCDisassembler;
-class MCInstrAnalysis;
class MCInstPrinter;
+class MCInstrAnalysis;
class MCInstrInfo;
class MCRegisterInfo;
+class MCRelocationInfo;
class MCStreamer;
class MCSubtargetInfo;
class MCSymbolizer;
-class MCRelocationInfo;
class MCTargetAsmParser;
class MCTargetOptions;
class MCTargetStreamer;
-class TargetMachine;
-class TargetOptions;
class raw_ostream;
class raw_pwrite_stream;
-class formatted_raw_ostream;
+class TargetMachine;
+class TargetOptions;
MCStreamer *createNullStreamer(MCContext &Ctx);
MCStreamer *createAsmStreamer(MCContext &Ctx,
@@ -68,6 +74,9 @@ MCStreamer *createMachOStreamer(MCContext &Ctx, MCAsmBackend &TAB,
raw_pwrite_stream &OS, MCCodeEmitter *CE,
bool RelaxAll, bool DWARFMustBeAtTheEnd,
bool LabelSections = false);
+MCStreamer *createWasmStreamer(MCContext &Ctx, MCAsmBackend &TAB,
+ raw_pwrite_stream &OS, MCCodeEmitter *CE,
+ bool RelaxAll);
MCRelocationInfo *createMCRelocationInfo(const Triple &TT, MCContext &Ctx);
@@ -88,70 +97,75 @@ class Target {
public:
friend struct TargetRegistry;
- typedef bool (*ArchMatchFnTy)(Triple::ArchType Arch);
+ using ArchMatchFnTy = bool (*)(Triple::ArchType Arch);
- typedef MCAsmInfo *(*MCAsmInfoCtorFnTy)(const MCRegisterInfo &MRI,
- const Triple &TT);
- typedef void (*MCAdjustCodeGenOptsFnTy)(const Triple &TT, Reloc::Model RM,
- CodeModel::Model &CM);
+ using MCAsmInfoCtorFnTy = MCAsmInfo *(*)(const MCRegisterInfo &MRI,
+ const Triple &TT);
+ using MCAdjustCodeGenOptsFnTy = void (*)(const Triple &TT, Reloc::Model RM,
+ CodeModel::Model &CM);
- typedef MCInstrInfo *(*MCInstrInfoCtorFnTy)(void);
- typedef MCInstrAnalysis *(*MCInstrAnalysisCtorFnTy)(const MCInstrInfo *Info);
- typedef MCRegisterInfo *(*MCRegInfoCtorFnTy)(const Triple &TT);
- typedef MCSubtargetInfo *(*MCSubtargetInfoCtorFnTy)(const Triple &TT,
- StringRef CPU,
- StringRef Features);
- typedef TargetMachine *(*TargetMachineCtorTy)(
+ using MCInstrInfoCtorFnTy = MCInstrInfo *(*)();
+ using MCInstrAnalysisCtorFnTy = MCInstrAnalysis *(*)(const MCInstrInfo *Info);
+ using MCRegInfoCtorFnTy = MCRegisterInfo *(*)(const Triple &TT);
+ using MCSubtargetInfoCtorFnTy = MCSubtargetInfo *(*)(const Triple &TT,
+ StringRef CPU,
+ StringRef Features);
+ using TargetMachineCtorTy = TargetMachine *(*)(
const Target &T, const Triple &TT, StringRef CPU, StringRef Features,
const TargetOptions &Options, Optional<Reloc::Model> RM,
CodeModel::Model CM, CodeGenOpt::Level OL);
// If it weren't for layering issues (this header is in llvm/Support, but
// depends on MC?) this should take the Streamer by value rather than rvalue
// reference.
- typedef AsmPrinter *(*AsmPrinterCtorTy)(
+ using AsmPrinterCtorTy = AsmPrinter *(*)(
TargetMachine &TM, std::unique_ptr<MCStreamer> &&Streamer);
- typedef MCAsmBackend *(*MCAsmBackendCtorTy)(const Target &T,
- const MCRegisterInfo &MRI,
- const Triple &TT, StringRef CPU,
- const MCTargetOptions &Options);
- typedef MCTargetAsmParser *(*MCAsmParserCtorTy)(
+ using MCAsmBackendCtorTy = MCAsmBackend *(*)(const Target &T,
+ const MCRegisterInfo &MRI,
+ const Triple &TT, StringRef CPU,
+ const MCTargetOptions &Options);
+ using MCAsmParserCtorTy = MCTargetAsmParser *(*)(
const MCSubtargetInfo &STI, MCAsmParser &P, const MCInstrInfo &MII,
const MCTargetOptions &Options);
- typedef MCDisassembler *(*MCDisassemblerCtorTy)(const Target &T,
- const MCSubtargetInfo &STI,
- MCContext &Ctx);
- typedef MCInstPrinter *(*MCInstPrinterCtorTy)(const Triple &T,
- unsigned SyntaxVariant,
- const MCAsmInfo &MAI,
- const MCInstrInfo &MII,
- const MCRegisterInfo &MRI);
- typedef MCCodeEmitter *(*MCCodeEmitterCtorTy)(const MCInstrInfo &II,
- const MCRegisterInfo &MRI,
- MCContext &Ctx);
- typedef MCStreamer *(*ELFStreamerCtorTy)(const Triple &T, MCContext &Ctx,
- MCAsmBackend &TAB,
- raw_pwrite_stream &OS,
- MCCodeEmitter *Emitter,
- bool RelaxAll);
- typedef MCStreamer *(*MachOStreamerCtorTy)(MCContext &Ctx, MCAsmBackend &TAB,
+ using MCDisassemblerCtorTy = MCDisassembler *(*)(const Target &T,
+ const MCSubtargetInfo &STI,
+ MCContext &Ctx);
+ using MCInstPrinterCtorTy = MCInstPrinter *(*)(const Triple &T,
+ unsigned SyntaxVariant,
+ const MCAsmInfo &MAI,
+ const MCInstrInfo &MII,
+ const MCRegisterInfo &MRI);
+ using MCCodeEmitterCtorTy = MCCodeEmitter *(*)(const MCInstrInfo &II,
+ const MCRegisterInfo &MRI,
+ MCContext &Ctx);
+ using ELFStreamerCtorTy = MCStreamer *(*)(const Triple &T, MCContext &Ctx,
+ MCAsmBackend &TAB,
+ raw_pwrite_stream &OS,
+ MCCodeEmitter *Emitter,
+ bool RelaxAll);
+ using MachOStreamerCtorTy = MCStreamer *(*)(MCContext &Ctx, MCAsmBackend &TAB,
+ raw_pwrite_stream &OS,
+ MCCodeEmitter *Emitter,
+ bool RelaxAll,
+ bool DWARFMustBeAtTheEnd);
+ using COFFStreamerCtorTy = MCStreamer *(*)(MCContext &Ctx, MCAsmBackend &TAB,
raw_pwrite_stream &OS,
MCCodeEmitter *Emitter,
bool RelaxAll,
- bool DWARFMustBeAtTheEnd);
- typedef MCStreamer *(*COFFStreamerCtorTy)(MCContext &Ctx, MCAsmBackend &TAB,
- raw_pwrite_stream &OS,
- MCCodeEmitter *Emitter,
- bool RelaxAll,
- bool IncrementalLinkerCompatible);
- typedef MCTargetStreamer *(*NullTargetStreamerCtorTy)(MCStreamer &S);
- typedef MCTargetStreamer *(*AsmTargetStreamerCtorTy)(
+ bool IncrementalLinkerCompatible);
+ using WasmStreamerCtorTy = MCStreamer *(*)(const Triple &T, MCContext &Ctx,
+ MCAsmBackend &TAB,
+ raw_pwrite_stream &OS,
+ MCCodeEmitter *Emitter,
+ bool RelaxAll);
+ using NullTargetStreamerCtorTy = MCTargetStreamer *(*)(MCStreamer &S);
+ using AsmTargetStreamerCtorTy = MCTargetStreamer *(*)(
MCStreamer &S, formatted_raw_ostream &OS, MCInstPrinter *InstPrint,
bool IsVerboseAsm);
- typedef MCTargetStreamer *(*ObjectTargetStreamerCtorTy)(
+ using ObjectTargetStreamerCtorTy = MCTargetStreamer *(*)(
MCStreamer &S, const MCSubtargetInfo &STI);
- typedef MCRelocationInfo *(*MCRelocationInfoCtorTy)(const Triple &TT,
- MCContext &Ctx);
- typedef MCSymbolizer *(*MCSymbolizerCtorTy)(
+ using MCRelocationInfoCtorTy = MCRelocationInfo *(*)(const Triple &TT,
+ MCContext &Ctx);
+ using MCSymbolizerCtorTy = MCSymbolizer *(*)(
const Triple &TT, LLVMOpInfoCallback GetOpInfo,
LLVMSymbolLookupCallback SymbolLookUp, void *DisInfo, MCContext *Ctx,
std::unique_ptr<MCRelocationInfo> &&RelInfo);
@@ -224,36 +238,33 @@ private:
MCCodeEmitterCtorTy MCCodeEmitterCtorFn;
// Construction functions for the various object formats, if registered.
- COFFStreamerCtorTy COFFStreamerCtorFn;
- MachOStreamerCtorTy MachOStreamerCtorFn;
- ELFStreamerCtorTy ELFStreamerCtorFn;
+ COFFStreamerCtorTy COFFStreamerCtorFn = nullptr;
+ MachOStreamerCtorTy MachOStreamerCtorFn = nullptr;
+ ELFStreamerCtorTy ELFStreamerCtorFn = nullptr;
+ WasmStreamerCtorTy WasmStreamerCtorFn = nullptr;
/// Construction function for this target's null TargetStreamer, if
/// registered (default = nullptr).
- NullTargetStreamerCtorTy NullTargetStreamerCtorFn;
+ NullTargetStreamerCtorTy NullTargetStreamerCtorFn = nullptr;
/// Construction function for this target's asm TargetStreamer, if
/// registered (default = nullptr).
- AsmTargetStreamerCtorTy AsmTargetStreamerCtorFn;
+ AsmTargetStreamerCtorTy AsmTargetStreamerCtorFn = nullptr;
/// Construction function for this target's obj TargetStreamer, if
/// registered (default = nullptr).
- ObjectTargetStreamerCtorTy ObjectTargetStreamerCtorFn;
+ ObjectTargetStreamerCtorTy ObjectTargetStreamerCtorFn = nullptr;
/// MCRelocationInfoCtorFn - Construction function for this target's
/// MCRelocationInfo, if registered (default = llvm::createMCRelocationInfo)
- MCRelocationInfoCtorTy MCRelocationInfoCtorFn;
+ MCRelocationInfoCtorTy MCRelocationInfoCtorFn = nullptr;
/// MCSymbolizerCtorFn - Construction function for this target's
/// MCSymbolizer, if registered (default = llvm::createMCSymbolizer)
- MCSymbolizerCtorTy MCSymbolizerCtorFn;
+ MCSymbolizerCtorTy MCSymbolizerCtorFn = nullptr;
public:
- Target()
- : COFFStreamerCtorFn(nullptr), MachOStreamerCtorFn(nullptr),
- ELFStreamerCtorFn(nullptr), NullTargetStreamerCtorFn(nullptr),
- AsmTargetStreamerCtorFn(nullptr), ObjectTargetStreamerCtorFn(nullptr),
- MCRelocationInfoCtorFn(nullptr), MCSymbolizerCtorFn(nullptr) {}
+ Target() = default;
/// @name Target Information
/// @{
@@ -461,6 +472,12 @@ public:
else
S = createELFStreamer(Ctx, TAB, OS, Emitter, RelaxAll);
break;
+ case Triple::Wasm:
+ if (WasmStreamerCtorFn)
+ S = WasmStreamerCtorFn(T, Ctx, TAB, OS, Emitter, RelaxAll);
+ else
+ S = createWasmStreamer(Ctx, TAB, OS, Emitter, RelaxAll);
+ break;
}
if (ObjectTargetStreamerCtorFn)
ObjectTargetStreamerCtorFn(*S, STI);
@@ -548,12 +565,14 @@ struct TargetRegistry {
class iterator
: public std::iterator<std::forward_iterator_tag, Target, ptrdiff_t> {
- const Target *Current;
- explicit iterator(Target *T) : Current(T) {}
friend struct TargetRegistry;
+ const Target *Current = nullptr;
+
+ explicit iterator(Target *T) : Current(T) {}
+
public:
- iterator() : Current(nullptr) {}
+ iterator() = default;
bool operator==(const iterator &x) const { return Current == x.Current; }
bool operator!=(const iterator &x) const { return !operator==(x); }
@@ -800,6 +819,10 @@ struct TargetRegistry {
T.ELFStreamerCtorFn = Fn;
}
+ static void RegisterWasmStreamer(Target &T, Target::WasmStreamerCtorTy Fn) {
+ T.WasmStreamerCtorFn = Fn;
+ }
+
static void RegisterNullTargetStreamer(Target &T,
Target::NullTargetStreamerCtorTy Fn) {
T.NullTargetStreamerCtorFn = Fn;
@@ -1147,6 +1170,7 @@ private:
return new MCCodeEmitterImpl();
}
};
-}
-#endif
+} // end namespace llvm
+
+#endif // LLVM_SUPPORT_TARGETREGISTRY_H
diff --git a/contrib/llvm/include/llvm/Support/ThreadPool.h b/contrib/llvm/include/llvm/Support/ThreadPool.h
index 665cec2..9ada946 100644
--- a/contrib/llvm/include/llvm/Support/ThreadPool.h
+++ b/contrib/llvm/include/llvm/Support/ThreadPool.h
@@ -16,23 +16,8 @@
#include "llvm/Support/thread.h"
-#ifdef _MSC_VER
-// concrt.h depends on eh.h for __uncaught_exception declaration
-// even if we disable exceptions.
-#include <eh.h>
-
-// Disable warnings from ppltasks.h transitively included by <future>.
-#pragma warning(push)
-#pragma warning(disable:4530)
-#pragma warning(disable:4062)
-#endif
-
#include <future>
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
-
#include <atomic>
#include <condition_variable>
#include <functional>
@@ -50,17 +35,8 @@ namespace llvm {
/// for some work to become available.
class ThreadPool {
public:
-#ifndef _MSC_VER
- using VoidTy = void;
using TaskTy = std::function<void()>;
using PackagedTaskTy = std::packaged_task<void()>;
-#else
- // MSVC 2013 has a bug and can't use std::packaged_task<void()>;
- // We force it to use bool(bool) instead.
- using VoidTy = bool;
- using TaskTy = std::function<bool(bool)>;
- using PackagedTaskTy = std::packaged_task<bool(bool)>;
-#endif
/// Construct a pool with the number of core available on the system (or
/// whatever the value returned by std::thread::hardware_concurrency() is).
@@ -75,30 +51,17 @@ public:
/// 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.
template <typename Function, typename... Args>
- inline std::shared_future<VoidTy> async(Function &&F, Args &&... ArgList) {
+ inline std::shared_future<void> async(Function &&F, Args &&... ArgList) {
auto Task =
std::bind(std::forward<Function>(F), std::forward<Args>(ArgList)...);
-#ifndef _MSC_VER
return asyncImpl(std::move(Task));
-#else
- // This lambda has to be marked mutable because MSVC 2013's std::bind call
- // operator isn't const qualified.
- return asyncImpl([Task](VoidTy) mutable -> VoidTy {
- Task();
- return VoidTy();
- });
-#endif
}
/// 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.
template <typename Function>
- inline std::shared_future<VoidTy> async(Function &&F) {
-#ifndef _MSC_VER
+ inline std::shared_future<void> async(Function &&F) {
return asyncImpl(std::forward<Function>(F));
-#else
- return asyncImpl([F] (VoidTy) -> VoidTy { F(); return VoidTy(); });
-#endif
}
/// Blocking wait for all the threads to complete and the queue to be empty.
@@ -108,7 +71,7 @@ public:
private:
/// 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<VoidTy> asyncImpl(TaskTy F);
+ std::shared_future<void> asyncImpl(TaskTy F);
/// Threads in flight
std::vector<llvm::thread> Threads;
diff --git a/contrib/llvm/include/llvm/Support/Threading.h b/contrib/llvm/include/llvm/Support/Threading.h
index 4bef7ec..03963a2 100644
--- a/contrib/llvm/include/llvm/Support/Threading.h
+++ b/contrib/llvm/include/llvm/Support/Threading.h
@@ -15,16 +15,22 @@
#ifndef LLVM_SUPPORT_THREADING_H
#define LLVM_SUPPORT_THREADING_H
+#include "llvm/ADT/SmallVector.h"
#include "llvm/Config/llvm-config.h" // for LLVM_ON_UNIX
#include "llvm/Support/Compiler.h"
#include <ciso646> // So we can check the C++ standard lib macros.
#include <functional>
+#if defined(_MSC_VER)
+// MSVC's call_once implementation worked since VS 2015, which is the minimum
+// supported version as of this writing.
+#define LLVM_THREADING_USE_STD_CALL_ONCE 1
+#elif defined(LLVM_ON_UNIX) && \
+ (defined(_LIBCPP_VERSION) || \
+ !(defined(__NetBSD__) || defined(__OpenBSD__) || defined(__ppc__)))
// std::call_once from libc++ is used on all Unix platforms. Other
// implementations like libstdc++ are known to have problems on NetBSD,
// OpenBSD and PowerPC.
-#if defined(LLVM_ON_UNIX) && (defined(_LIBCPP_VERSION) || \
- !(defined(__NetBSD__) || defined(__OpenBSD__) || defined(__ppc__)))
#define LLVM_THREADING_USE_STD_CALL_ONCE 1
#else
#define LLVM_THREADING_USE_STD_CALL_ONCE 0
@@ -37,41 +43,43 @@
#endif
namespace llvm {
- /// Returns true if LLVM is compiled with support for multi-threading, and
- /// false otherwise.
- bool llvm_is_multithreaded();
-
- /// llvm_execute_on_thread - Execute the given \p UserFn on a separate
- /// thread, passing it the provided \p UserData and waits for thread
- /// completion.
- ///
- /// This function does not guarantee that the code will actually be executed
- /// on a separate thread or honoring the requested stack size, but tries to do
- /// so where system support is available.
- ///
- /// \param UserFn - The callback to execute.
- /// \param UserData - An argument to pass to the callback function.
- /// \param RequestedStackSize - If non-zero, a requested size (in bytes) for
- /// the thread stack.
- void llvm_execute_on_thread(void (*UserFn)(void*), void *UserData,
- unsigned RequestedStackSize = 0);
+class Twine;
+
+/// Returns true if LLVM is compiled with support for multi-threading, and
+/// false otherwise.
+bool llvm_is_multithreaded();
+
+/// llvm_execute_on_thread - Execute the given \p UserFn on a separate
+/// thread, passing it the provided \p UserData and waits for thread
+/// completion.
+///
+/// This function does not guarantee that the code will actually be executed
+/// on a separate thread or honoring the requested stack size, but tries to do
+/// so where system support is available.
+///
+/// \param UserFn - The callback to execute.
+/// \param UserData - An argument to pass to the callback function.
+/// \param RequestedStackSize - If non-zero, a requested size (in bytes) for
+/// the thread stack.
+void llvm_execute_on_thread(void (*UserFn)(void *), void *UserData,
+ unsigned RequestedStackSize = 0);
#if LLVM_THREADING_USE_STD_CALL_ONCE
typedef std::once_flag once_flag;
- /// This macro is the only way you should define your once flag for LLVM's
- /// call_once.
-#define LLVM_DEFINE_ONCE_FLAG(flag) static once_flag flag
-
#else
enum InitStatus { Uninitialized = 0, Wait = 1, Done = 2 };
- typedef volatile sys::cas_flag once_flag;
- /// This macro is the only way you should define your once flag for LLVM's
- /// call_once.
-#define LLVM_DEFINE_ONCE_FLAG(flag) static once_flag flag = Uninitialized
+ /// \brief The llvm::once_flag structure
+ ///
+ /// This type is modeled after std::once_flag to use with llvm::call_once.
+ /// This structure must be used as an opaque object. It is a struct to force
+ /// autoinitialization and behave like std::once_flag.
+ struct once_flag {
+ volatile sys::cas_flag status = Uninitialized;
+ };
#endif
@@ -81,7 +89,7 @@ namespace llvm {
/// \code
/// void foo() {...};
/// ...
- /// LLVM_DEFINE_ONCE_FLAG(flag);
+ /// static once_flag flag;
/// call_once(flag, foo);
/// \endcode
///
@@ -95,24 +103,24 @@ namespace llvm {
#else
// For other platforms we use a generic (if brittle) version based on our
// atomics.
- sys::cas_flag old_val = sys::CompareAndSwap(&flag, Wait, Uninitialized);
+ sys::cas_flag old_val = sys::CompareAndSwap(&flag.status, Wait, Uninitialized);
if (old_val == Uninitialized) {
std::forward<Function>(F)(std::forward<Args>(ArgList)...);
sys::MemoryFence();
TsanIgnoreWritesBegin();
- TsanHappensBefore(&flag);
- flag = Done;
+ TsanHappensBefore(&flag.status);
+ flag.status = Done;
TsanIgnoreWritesEnd();
} else {
// Wait until any thread doing the call has finished.
- sys::cas_flag tmp = flag;
+ sys::cas_flag tmp = flag.status;
sys::MemoryFence();
while (tmp != Done) {
- tmp = flag;
+ tmp = flag.status;
sys::MemoryFence();
}
}
- TsanHappensAfter(&flag);
+ TsanHappensAfter(&flag.status);
#endif
}
@@ -122,6 +130,32 @@ namespace llvm {
/// thread::hardware_concurrency().
/// Returns 1 when LLVM is configured with LLVM_ENABLE_THREADS=OFF
unsigned heavyweight_hardware_concurrency();
+
+ /// \brief Return the current thread id, as used in various OS system calls.
+ /// Note that not all platforms guarantee that the value returned will be
+ /// unique across the entire system, so portable code should not assume
+ /// this.
+ uint64_t get_threadid();
+
+ /// \brief Get the maximum length of a thread name on this platform.
+ /// A value of 0 means there is no limit.
+ uint32_t get_max_thread_name_length();
+
+ /// \brief Set the name of the current thread. Setting a thread's name can
+ /// be helpful for enabling useful diagnostics under a debugger or when
+ /// logging. The level of support for setting a thread's name varies
+ /// wildly across operating systems, and we only make a best effort to
+ /// perform the operation on supported platforms. No indication of success
+ /// or failure is returned.
+ void set_thread_name(const Twine &Name);
+
+ /// \brief Get the name of the current thread. The level of support for
+ /// getting a thread's name varies wildly across operating systems, and it
+ /// is not even guaranteed that if you can successfully set a thread's name
+ /// that you can later get it back. This function is intended for diagnostic
+ /// purposes, and as with setting a thread's name no indication of whether
+ /// the operation succeeded or failed is returned.
+ void get_thread_name(SmallVectorImpl<char> &Name);
}
#endif
diff --git a/contrib/llvm/include/llvm/Support/Timer.h b/contrib/llvm/include/llvm/Support/Timer.h
index 80e8f13..198855a 100644
--- a/contrib/llvm/include/llvm/Support/Timer.h
+++ b/contrib/llvm/include/llvm/Support/Timer.h
@@ -207,6 +207,9 @@ public:
/// This static method prints all timers and clears them all out.
static void printAll(raw_ostream &OS);
+ /// Prints all timers as JSON key/value pairs, and clears them all out.
+ static const char *printAllJSONValues(raw_ostream &OS, const char *delim);
+
/// Ensure global timer group lists are initialized. This function is mostly
/// used by the Statistic code to influence the construction and destruction
/// order of the global timer lists.
@@ -221,7 +224,6 @@ private:
void printJSONValue(raw_ostream &OS, const PrintRecord &R,
const char *suffix, double Value);
const char *printJSONValues(raw_ostream &OS, const char *delim);
- static const char *printAllJSONValues(raw_ostream &OS, const char *delim);
};
} // end namespace llvm
diff --git a/contrib/llvm/include/llvm/Support/TrailingObjects.h b/contrib/llvm/include/llvm/Support/TrailingObjects.h
index 4d35572..cb5a52b 100644
--- a/contrib/llvm/include/llvm/Support/TrailingObjects.h
+++ b/contrib/llvm/include/llvm/Support/TrailingObjects.h
@@ -294,7 +294,14 @@ class TrailingObjects : private trailing_objects_internal::TrailingObjectsImpl<
public:
// Make this (privately inherited) member public.
+#ifndef _MSC_VER
using ParentType::OverloadToken;
+#else
+ // MSVC bug prevents the above from working, at least up through CL
+ // 19.10.24629.
+ template <typename T>
+ using OverloadToken = typename ParentType::template OverloadToken<T>;
+#endif
/// Returns a pointer to the trailing object array of the given type
/// (which must be one of those specified in the class template). The
diff --git a/contrib/llvm/include/llvm/Support/UnicodeCharRanges.h b/contrib/llvm/include/llvm/Support/UnicodeCharRanges.h
index d4d4d8e..4c65583 100644
--- a/contrib/llvm/include/llvm/Support/UnicodeCharRanges.h
+++ b/contrib/llvm/include/llvm/Support/UnicodeCharRanges.h
@@ -18,11 +18,11 @@
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
+#define DEBUG_TYPE "unicode"
+
namespace llvm {
namespace sys {
-#define DEBUG_TYPE "unicode"
-
/// \brief Represents a closed range of Unicode code points [Lower, Upper].
struct UnicodeCharRange {
uint32_t Lower;
@@ -99,10 +99,9 @@ private:
const CharRanges Ranges;
};
-#undef DEBUG_TYPE // "unicode"
-
} // namespace sys
} // namespace llvm
+#undef DEBUG_TYPE // "unicode"
#endif // LLVM_SUPPORT_UNICODECHARRANGES_H
diff --git a/contrib/llvm/include/llvm/Support/UniqueLock.h b/contrib/llvm/include/llvm/Support/UniqueLock.h
index 529284d..b4675f4 100644
--- a/contrib/llvm/include/llvm/Support/UniqueLock.h
+++ b/contrib/llvm/include/llvm/Support/UniqueLock.h
@@ -1,4 +1,4 @@
-//===-- Support/UniqueLock.h - Acquire/Release Mutex In Scope ---*- C++ -*-===//
+//===- Support/UniqueLock.h - Acquire/Release Mutex In Scope ----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -15,9 +15,10 @@
#ifndef LLVM_SUPPORT_UNIQUE_LOCK_H
#define LLVM_SUPPORT_UNIQUE_LOCK_H
-#include "llvm/Support/Mutex.h"
+#include <cassert>
namespace llvm {
+
/// A pared-down imitation of std::unique_lock from C++11. Contrary to the
/// name, it's really more of a wrapper for a lock. It may or may not have
/// an associated mutex, which is guaranteed to be locked upon creation
@@ -26,14 +27,14 @@ namespace llvm {
/// @brief Guard a section of code with a mutex.
template<typename MutexT>
class unique_lock {
- MutexT *M;
- bool locked;
+ MutexT *M = nullptr;
+ bool locked = false;
- unique_lock(const unique_lock &) = delete;
- void operator=(const unique_lock &) = delete;
public:
- unique_lock() : M(nullptr), locked(false) {}
+ unique_lock() = default;
explicit unique_lock(MutexT &m) : M(&m), locked(true) { M->lock(); }
+ unique_lock(const unique_lock &) = delete;
+ unique_lock &operator=(const unique_lock &) = delete;
void operator=(unique_lock &&o) {
if (owns_lock())
@@ -62,6 +63,7 @@ namespace llvm {
bool owns_lock() { return locked; }
};
-}
+
+} // end namespace llvm
#endif // LLVM_SUPPORT_UNIQUE_LOCK_H
diff --git a/contrib/llvm/include/llvm/Support/Wasm.h b/contrib/llvm/include/llvm/Support/Wasm.h
deleted file mode 100644
index 8ac6b90..0000000
--- a/contrib/llvm/include/llvm/Support/Wasm.h
+++ /dev/null
@@ -1,87 +0,0 @@
-//===- Wasm.h - Wasm object file format -------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines manifest constants for the wasm object file format.
-// See: https://github.com/WebAssembly/design/blob/master/BinaryEncoding.md
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SUPPORT_WASM_H
-#define LLVM_SUPPORT_WASM_H
-
-#include "llvm/ADT/ArrayRef.h"
-
-namespace llvm {
-namespace wasm {
-
-// Object file magic string.
-const char WasmMagic[] = {'\0', 'a', 's', 'm'};
-// Wasm binary format version
-const uint32_t WasmVersion = 0xd;
-
-struct WasmObjectHeader {
- StringRef Magic;
- uint32_t Version;
-};
-
-struct WasmSection {
- uint32_t Type; // Section type (See below)
- uint32_t Offset; // Offset with in the file
- StringRef Name; // Section name (User-defined sections only)
- ArrayRef<uint8_t> Content; // Section content
-};
-
-enum : unsigned {
- WASM_SEC_USER = 0, // User-defined section
- WASM_SEC_TYPE = 1, // Function signature declarations
- WASM_SEC_IMPORT = 2, // Import declarations
- WASM_SEC_FUNCTION = 3, // Function declarations
- WASM_SEC_TABLE = 4, // Indirect function table and other tables
- WASM_SEC_MEMORY = 5, // Memory attributes
- WASM_SEC_GLOBAL = 6, // Global declarations
- WASM_SEC_EXPORT = 7, // Exports
- WASM_SEC_START = 8, // Start function declaration
- WASM_SEC_ELEM = 9, // Elements section
- WASM_SEC_CODE = 10, // Function bodies (code)
- WASM_SEC_DATA = 11 // Data segments
-};
-
-// Type immediate encodings used in various contexts.
-enum : unsigned {
- WASM_TYPE_I32 = 0x7f,
- WASM_TYPE_I64 = 0x7e,
- WASM_TYPE_F32 = 0x7d,
- WASM_TYPE_F64 = 0x7c,
- WASM_TYPE_ANYFUNC = 0x70,
- WASM_TYPE_FUNC = 0x60,
- WASM_TYPE_NORESULT = 0x40, // for blocks with no result values
-};
-
-// Kinds of externals (for imports and exports).
-enum : unsigned {
- WASM_EXTERNAL_FUNCTION = 0x0,
- WASM_EXTERNAL_TABLE = 0x1,
- WASM_EXTERNAL_MEMORY = 0x2,
- WASM_EXTERNAL_GLOBAL = 0x3,
-};
-
-// Opcodes used in initializer expressions.
-enum : unsigned {
- WASM_OPCODE_END = 0x0b,
- WASM_OPCODE_GET_GLOBAL = 0x23,
- WASM_OPCODE_I32_CONST = 0x41,
- WASM_OPCODE_I64_CONST = 0x42,
- WASM_OPCODE_F32_CONST = 0x43,
- WASM_OPCODE_F64_CONST = 0x44,
-};
-
-} // end namespace wasm
-} // end namespace llvm
-
-#endif
diff --git a/contrib/llvm/include/llvm/Support/YAMLParser.h b/contrib/llvm/include/llvm/Support/YAMLParser.h
index b9e3fa4..549da3c 100644
--- a/contrib/llvm/include/llvm/Support/YAMLParser.h
+++ b/contrib/llvm/include/llvm/Support/YAMLParser.h
@@ -1,4 +1,4 @@
-//===--- YAMLParser.h - Simple YAML parser --------------------------------===//
+//===- YAMLParser.h - Simple YAML parser ------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -41,20 +41,25 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/SMLoc.h"
+#include <cassert>
+#include <cstddef>
+#include <iterator>
#include <map>
+#include <memory>
+#include <string>
#include <system_error>
-#include <utility>
namespace llvm {
+
class MemoryBufferRef;
class SourceMgr;
-class Twine;
class raw_ostream;
+class Twine;
namespace yaml {
-class document_iterator;
class Document;
+class document_iterator;
class Node;
class Scanner;
struct Token;
@@ -87,6 +92,7 @@ public:
document_iterator end();
void skip();
bool failed();
+
bool validate() {
skip();
return !failed();
@@ -95,10 +101,10 @@ public:
void printError(Node *N, const Twine &Msg);
private:
+ friend class Document;
+
std::unique_ptr<Scanner> scanner;
std::unique_ptr<Document> CurrentDoc;
-
- friend class Document;
};
/// \brief Abstract base class for all Nodes.
@@ -119,6 +125,18 @@ public:
Node(unsigned int Type, std::unique_ptr<Document> &, StringRef Anchor,
StringRef Tag);
+ void *operator new(size_t Size, BumpPtrAllocator &Alloc,
+ size_t Alignment = 16) noexcept {
+ return Alloc.Allocate(Size, Alignment);
+ }
+
+ void operator delete(void *Ptr, BumpPtrAllocator &Alloc,
+ size_t Size) noexcept {
+ Alloc.Deallocate(Ptr, Size);
+ }
+
+ void operator delete(void *) noexcept = delete;
+
/// \brief Get the value of the anchor attached to this node. If it does not
/// have one, getAnchor().size() will be 0.
StringRef getAnchor() const { return Anchor; }
@@ -146,22 +164,10 @@ public:
unsigned int getType() const { return TypeID; }
- void *operator new(size_t Size, BumpPtrAllocator &Alloc,
- size_t Alignment = 16) noexcept {
- return Alloc.Allocate(Size, Alignment);
- }
-
- void operator delete(void *Ptr, BumpPtrAllocator &Alloc,
- size_t Size) noexcept {
- Alloc.Deallocate(Ptr, Size);
- }
-
protected:
std::unique_ptr<Document> &Doc;
SMRange SourceRange;
- void operator delete(void *) noexcept = delete;
-
~Node() = default;
private:
@@ -182,7 +188,7 @@ public:
NullNode(std::unique_ptr<Document> &D)
: Node(NK_Null, D, StringRef(), StringRef()) {}
- static inline bool classof(const Node *N) { return N->getType() == NK_Null; }
+ static bool classof(const Node *N) { return N->getType() == NK_Null; }
};
/// \brief A scalar node is an opaque datum that can be presented as a
@@ -214,7 +220,7 @@ public:
/// This happens with escaped characters and multi-line literals.
StringRef getValue(SmallVectorImpl<char> &Storage) const;
- static inline bool classof(const Node *N) {
+ static bool classof(const Node *N) {
return N->getType() == NK_Scalar;
}
@@ -248,7 +254,7 @@ public:
/// \brief Gets the value of this node as a StringRef.
StringRef getValue() const { return Value; }
- static inline bool classof(const Node *N) {
+ static bool classof(const Node *N) {
return N->getType() == NK_BlockScalar;
}
@@ -268,8 +274,7 @@ class KeyValueNode final : public Node {
public:
KeyValueNode(std::unique_ptr<Document> &D)
- : Node(NK_KeyValue, D, StringRef(), StringRef()), Key(nullptr),
- Value(nullptr) {}
+ : Node(NK_KeyValue, D, StringRef(), StringRef()) {}
/// \brief Parse and return the key.
///
@@ -291,13 +296,13 @@ public:
Val->skip();
}
- static inline bool classof(const Node *N) {
+ static bool classof(const Node *N) {
return N->getType() == NK_KeyValue;
}
private:
- Node *Key;
- Node *Value;
+ Node *Key = nullptr;
+ Node *Value = nullptr;
};
/// \brief This is an iterator abstraction over YAML collections shared by both
@@ -309,7 +314,7 @@ template <class BaseT, class ValueT>
class basic_collection_iterator
: public std::iterator<std::input_iterator_tag, ValueT> {
public:
- basic_collection_iterator() : Base(nullptr) {}
+ basic_collection_iterator() = default;
basic_collection_iterator(BaseT *B) : Base(B) {}
ValueT *operator->() const {
@@ -358,7 +363,7 @@ public:
}
private:
- BaseT *Base;
+ BaseT *Base = nullptr;
};
// The following two templates are used for both MappingNode and Sequence Node.
@@ -399,11 +404,12 @@ public:
MappingNode(std::unique_ptr<Document> &D, StringRef Anchor, StringRef Tag,
MappingType MT)
- : Node(NK_Mapping, D, Anchor, Tag), Type(MT), IsAtBeginning(true),
- IsAtEnd(false), CurrentEntry(nullptr) {}
+ : Node(NK_Mapping, D, Anchor, Tag), Type(MT) {}
friend class basic_collection_iterator<MappingNode, KeyValueNode>;
- typedef basic_collection_iterator<MappingNode, KeyValueNode> iterator;
+
+ using iterator = basic_collection_iterator<MappingNode, KeyValueNode>;
+
template <class T> friend typename T::iterator yaml::begin(T &);
template <class T> friend void yaml::skip(T &);
@@ -413,15 +419,15 @@ public:
void skip() override { yaml::skip(*this); }
- static inline bool classof(const Node *N) {
+ static bool classof(const Node *N) {
return N->getType() == NK_Mapping;
}
private:
MappingType Type;
- bool IsAtBeginning;
- bool IsAtEnd;
- KeyValueNode *CurrentEntry;
+ bool IsAtBeginning = true;
+ bool IsAtEnd = false;
+ KeyValueNode *CurrentEntry = nullptr;
void increment();
};
@@ -453,13 +459,12 @@ public:
SequenceNode(std::unique_ptr<Document> &D, StringRef Anchor, StringRef Tag,
SequenceType ST)
- : Node(NK_Sequence, D, Anchor, Tag), SeqType(ST), IsAtBeginning(true),
- IsAtEnd(false),
- WasPreviousTokenFlowEntry(true), // Start with an imaginary ','.
- CurrentEntry(nullptr) {}
+ : Node(NK_Sequence, D, Anchor, Tag), SeqType(ST) {}
friend class basic_collection_iterator<SequenceNode, Node>;
- typedef basic_collection_iterator<SequenceNode, Node> iterator;
+
+ using iterator = basic_collection_iterator<SequenceNode, Node>;
+
template <class T> friend typename T::iterator yaml::begin(T &);
template <class T> friend void yaml::skip(T &);
@@ -471,16 +476,16 @@ public:
void skip() override { yaml::skip(*this); }
- static inline bool classof(const Node *N) {
+ static bool classof(const Node *N) {
return N->getType() == NK_Sequence;
}
private:
SequenceType SeqType;
- bool IsAtBeginning;
- bool IsAtEnd;
- bool WasPreviousTokenFlowEntry;
- Node *CurrentEntry;
+ bool IsAtBeginning = true;
+ bool IsAtEnd = false;
+ bool WasPreviousTokenFlowEntry = true; // Start with an imaginary ','.
+ Node *CurrentEntry = nullptr;
};
/// \brief Represents an alias to a Node with an anchor.
@@ -497,7 +502,7 @@ public:
StringRef getName() const { return Name; }
Node *getTarget();
- static inline bool classof(const Node *N) { return N->getType() == NK_Alias; }
+ static bool classof(const Node *N) { return N->getType() == NK_Alias; }
private:
StringRef Name;
@@ -507,11 +512,11 @@ private:
/// node.
class Document {
public:
+ Document(Stream &ParentStream);
+
/// \brief Root for parsing a node. Returns a single node.
Node *parseBlockNode();
- Document(Stream &ParentStream);
-
/// \brief Finish parsing the current document and return true if there are
/// more. Return false otherwise.
bool skip();
@@ -564,7 +569,7 @@ private:
/// \brief Iterator abstraction for Documents over a Stream.
class document_iterator {
public:
- document_iterator() : Doc(nullptr) {}
+ document_iterator() = default;
document_iterator(std::unique_ptr<Document> &D) : Doc(&D) {}
bool operator==(const document_iterator &Other) {
@@ -593,11 +598,11 @@ public:
private:
bool isAtEnd() const { return !Doc || !*Doc; }
- std::unique_ptr<Document> *Doc;
+ std::unique_ptr<Document> *Doc = nullptr;
};
-} // End namespace yaml.
+} // end namespace yaml
-} // End namespace llvm.
+} // end namespace llvm
-#endif
+#endif // LLVM_SUPPORT_YAMLPARSER_H
diff --git a/contrib/llvm/include/llvm/Support/YAMLTraits.h b/contrib/llvm/include/llvm/Support/YAMLTraits.h
index cbba9c0..71fdf47 100644
--- a/contrib/llvm/include/llvm/Support/YAMLTraits.h
+++ b/contrib/llvm/include/llvm/Support/YAMLTraits.h
@@ -26,6 +26,7 @@
#include <cctype>
#include <cstddef>
#include <cstdint>
+#include <map>
#include <memory>
#include <new>
#include <string>
@@ -179,17 +180,17 @@ struct BlockScalarTraits {
/// to/from a YAML sequence. For example:
///
/// template<>
-/// struct SequenceTraits< std::vector<MyType>> {
-/// static size_t size(IO &io, std::vector<MyType> &seq) {
+/// struct SequenceTraits<MyContainer> {
+/// static size_t size(IO &io, MyContainer &seq) {
/// return seq.size();
/// }
-/// static MyType& element(IO &, std::vector<MyType> &seq, size_t index) {
+/// static MyType& element(IO &, MyContainer &seq, size_t index) {
/// if ( index >= seq.size() )
/// seq.resize(index+1);
/// return seq[index];
/// }
/// };
-template<typename T>
+template<typename T, typename EnableIf = void>
struct SequenceTraits {
// Must provide:
// static size_t size(IO &io, T &seq);
@@ -200,6 +201,14 @@ struct SequenceTraits {
// static const bool flow = true;
};
+/// This class should be specialized by any type for which vectors of that
+/// type need to be converted to/from a YAML sequence.
+template<typename T, typename EnableIf = void>
+struct SequenceElementTraits {
+ // Must provide:
+ // static const bool flow;
+};
+
/// This class should be specialized by any type that needs to be converted
/// to/from a list of YAML documents.
template<typename T>
@@ -226,7 +235,7 @@ struct MissingTrait;
template <class T>
struct has_ScalarEnumerationTraits
{
- typedef void (*Signature_enumeration)(class IO&, T&);
+ using Signature_enumeration = void (*)(class IO&, T&);
template <typename U>
static char test(SameType<Signature_enumeration, &U::enumeration>*);
@@ -243,7 +252,7 @@ public:
template <class T>
struct has_ScalarBitSetTraits
{
- typedef void (*Signature_bitset)(class IO&, T&);
+ using Signature_bitset = void (*)(class IO&, T&);
template <typename U>
static char test(SameType<Signature_bitset, &U::bitset>*);
@@ -259,9 +268,9 @@ public:
template <class T>
struct has_ScalarTraits
{
- typedef StringRef (*Signature_input)(StringRef, void*, T&);
- typedef void (*Signature_output)(const T&, void*, llvm::raw_ostream&);
- typedef bool (*Signature_mustQuote)(StringRef);
+ using Signature_input = StringRef (*)(StringRef, void*, T&);
+ using Signature_output = void (*)(const T&, void*, raw_ostream&);
+ using Signature_mustQuote = bool (*)(StringRef);
template <typename U>
static char test(SameType<Signature_input, &U::input> *,
@@ -280,8 +289,8 @@ public:
template <class T>
struct has_BlockScalarTraits
{
- typedef StringRef (*Signature_input)(StringRef, void *, T &);
- typedef void (*Signature_output)(const T &, void *, llvm::raw_ostream &);
+ using Signature_input = StringRef (*)(StringRef, void *, T &);
+ using Signature_output = void (*)(const T &, void *, raw_ostream &);
template <typename U>
static char test(SameType<Signature_input, &U::input> *,
@@ -297,7 +306,7 @@ public:
// Test if MappingContextTraits<T> is defined on type T.
template <class T, class Context> struct has_MappingTraits {
- typedef void (*Signature_mapping)(class IO &, T &, Context &);
+ using Signature_mapping = void (*)(class IO &, T &, Context &);
template <typename U>
static char test(SameType<Signature_mapping, &U::mapping>*);
@@ -312,7 +321,7 @@ public:
// Test if MappingTraits<T> is defined on type T.
template <class T> struct has_MappingTraits<T, EmptyContext> {
- typedef void (*Signature_mapping)(class IO &, T &);
+ using Signature_mapping = void (*)(class IO &, T &);
template <typename U>
static char test(SameType<Signature_mapping, &U::mapping> *);
@@ -325,7 +334,7 @@ public:
// Test if MappingContextTraits<T>::validate() is defined on type T.
template <class T, class Context> struct has_MappingValidateTraits {
- typedef StringRef (*Signature_validate)(class IO &, T &, Context &);
+ using Signature_validate = StringRef (*)(class IO &, T &, Context &);
template <typename U>
static char test(SameType<Signature_validate, &U::validate>*);
@@ -340,7 +349,7 @@ public:
// Test if MappingTraits<T>::validate() is defined on type T.
template <class T> struct has_MappingValidateTraits<T, EmptyContext> {
- typedef StringRef (*Signature_validate)(class IO &, T &);
+ using Signature_validate = StringRef (*)(class IO &, T &);
template <typename U>
static char test(SameType<Signature_validate, &U::validate> *);
@@ -355,7 +364,7 @@ public:
template <class T>
struct has_SequenceMethodTraits
{
- typedef size_t (*Signature_size)(class IO&, T&);
+ using Signature_size = size_t (*)(class IO&, T&);
template <typename U>
static char test(SameType<Signature_size, &U::size>*);
@@ -371,7 +380,7 @@ public:
template <class T>
struct has_CustomMappingTraits
{
- typedef void (*Signature_input)(IO &io, StringRef key, T &v);
+ using Signature_input = void (*)(IO &io, StringRef key, T &v);
template <typename U>
static char test(SameType<Signature_input, &U::inputOne>*);
@@ -422,7 +431,7 @@ struct has_SequenceTraits : public std::integral_constant<bool,
template <class T>
struct has_DocumentListTraits
{
- typedef size_t (*Signature_size)(class IO&, T&);
+ using Signature_size = size_t (*)(class IO &, T &);
template <typename U>
static char test(SameType<Signature_size, &U::size>*);
@@ -537,7 +546,7 @@ struct unvalidatedMappingTraits
// Base class for Input and Output.
class IO {
public:
- IO(void *Ctxt=nullptr);
+ IO(void *Ctxt = nullptr);
virtual ~IO();
virtual bool outputting() = 0;
@@ -606,7 +615,7 @@ public:
template <typename T>
void bitSetCase(T &Val, const char* Str, const T ConstVal) {
if ( bitSetMatch(Str, outputting() && (Val & ConstVal) == ConstVal) ) {
- Val = Val | ConstVal;
+ Val = static_cast<T>(Val | ConstVal);
}
}
@@ -614,7 +623,7 @@ public:
template <typename T>
void bitSetCase(T &Val, const char* Str, const uint32_t ConstVal) {
if ( bitSetMatch(Str, outputting() && (Val & ConstVal) == ConstVal) ) {
- Val = Val | ConstVal;
+ Val = static_cast<T>(Val | ConstVal);
}
}
@@ -638,6 +647,7 @@ public:
EmptyContext Ctx;
this->processKey(Key, Val, true, Ctx);
}
+
template <typename T, typename Context>
void mapRequired(const char *Key, T &Val, Context &Ctx) {
this->processKey(Key, Val, true, Ctx);
@@ -689,11 +699,12 @@ private:
assert(DefaultValue.hasValue() == false &&
"Optional<T> shouldn't have a value!");
void *SaveInfo;
- bool UseDefault;
+ bool UseDefault = true;
const bool sameAsDefault = outputting() && !Val.hasValue();
if (!outputting() && !Val.hasValue())
Val = T();
- if (this->preflightKey(Key, Required, sameAsDefault, UseDefault,
+ if (Val.hasValue() &&
+ this->preflightKey(Key, Required, sameAsDefault, UseDefault,
SaveInfo)) {
yamlize(*this, Val.getValue(), Required, Ctx);
this->postflightKey(SaveInfo);
@@ -731,7 +742,7 @@ private:
}
private:
- void *Ctxt;
+ void *Ctxt;
};
namespace detail {
@@ -772,7 +783,7 @@ typename std::enable_if<has_ScalarTraits<T>::value, void>::type
yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
if ( io.outputting() ) {
std::string Storage;
- llvm::raw_string_ostream Buffer(Storage);
+ raw_string_ostream Buffer(Storage);
ScalarTraits<T>::output(Val, io.getContext(), Buffer);
StringRef Str = Buffer.str();
io.scalarString(Str, ScalarTraits<T>::mustQuote(Str));
@@ -782,7 +793,7 @@ yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
io.scalarString(Str, ScalarTraits<T>::mustQuote(Str));
StringRef Result = ScalarTraits<T>::input(Str, io.getContext(), Val);
if ( !Result.empty() ) {
- io.setError(llvm::Twine(Result));
+ io.setError(Twine(Result));
}
}
}
@@ -792,7 +803,7 @@ typename std::enable_if<has_BlockScalarTraits<T>::value, void>::type
yamlize(IO &YamlIO, T &Val, bool, EmptyContext &Ctx) {
if (YamlIO.outputting()) {
std::string Storage;
- llvm::raw_string_ostream Buffer(Storage);
+ raw_string_ostream Buffer(Storage);
BlockScalarTraits<T>::output(Val, YamlIO.getContext(), Buffer);
StringRef Str = Buffer.str();
YamlIO.blockScalarString(Str);
@@ -802,7 +813,7 @@ yamlize(IO &YamlIO, T &Val, bool, EmptyContext &Ctx) {
StringRef Result =
BlockScalarTraits<T>::input(Str, YamlIO.getContext(), Val);
if (!Result.empty())
- YamlIO.setError(llvm::Twine(Result));
+ YamlIO.setError(Twine(Result));
}
}
@@ -816,7 +827,7 @@ yamlize(IO &io, T &Val, bool, Context &Ctx) {
if (io.outputting()) {
StringRef Err = MappingTraits<T>::validate(io, Val);
if (!Err.empty()) {
- llvm::errs() << Err << "\n";
+ errs() << Err << "\n";
assert(Err.empty() && "invalid struct trying to be written as yaml");
}
}
@@ -870,7 +881,7 @@ yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
template <typename T, typename Context>
typename std::enable_if<has_SequenceTraits<T>::value, void>::type
yamlize(IO &io, T &Seq, bool, Context &Ctx) {
- if ( has_FlowTraits< SequenceTraits<T> >::value ) {
+ if ( has_FlowTraits< SequenceTraits<T>>::value ) {
unsigned incnt = io.beginFlowSequence();
unsigned count = io.outputting() ? SequenceTraits<T>::size(io, Seq) : incnt;
for(unsigned i=0; i < count; ++i) {
@@ -898,92 +909,92 @@ yamlize(IO &io, T &Seq, bool, Context &Ctx) {
template<>
struct ScalarTraits<bool> {
- static void output(const bool &, void*, llvm::raw_ostream &);
- static StringRef input(StringRef, void*, bool &);
+ static void output(const bool &, void* , raw_ostream &);
+ static StringRef input(StringRef, void *, bool &);
static bool mustQuote(StringRef) { return false; }
};
template<>
struct ScalarTraits<StringRef> {
- static void output(const StringRef &, void*, llvm::raw_ostream &);
- static StringRef input(StringRef, void*, StringRef &);
+ static void output(const StringRef &, void *, raw_ostream &);
+ static StringRef input(StringRef, void *, StringRef &);
static bool mustQuote(StringRef S) { return needsQuotes(S); }
};
template<>
struct ScalarTraits<std::string> {
- static void output(const std::string &, void*, llvm::raw_ostream &);
- static StringRef input(StringRef, void*, std::string &);
+ static void output(const std::string &, void *, raw_ostream &);
+ static StringRef input(StringRef, void *, std::string &);
static bool mustQuote(StringRef S) { return needsQuotes(S); }
};
template<>
struct ScalarTraits<uint8_t> {
- static void output(const uint8_t &, void*, llvm::raw_ostream &);
- static StringRef input(StringRef, void*, uint8_t &);
+ static void output(const uint8_t &, void *, raw_ostream &);
+ static StringRef input(StringRef, void *, uint8_t &);
static bool mustQuote(StringRef) { return false; }
};
template<>
struct ScalarTraits<uint16_t> {
- static void output(const uint16_t &, void*, llvm::raw_ostream &);
- static StringRef input(StringRef, void*, uint16_t &);
+ static void output(const uint16_t &, void *, raw_ostream &);
+ static StringRef input(StringRef, void *, uint16_t &);
static bool mustQuote(StringRef) { return false; }
};
template<>
struct ScalarTraits<uint32_t> {
- static void output(const uint32_t &, void*, llvm::raw_ostream &);
- static StringRef input(StringRef, void*, uint32_t &);
+ static void output(const uint32_t &, void *, raw_ostream &);
+ static StringRef input(StringRef, void *, uint32_t &);
static bool mustQuote(StringRef) { return false; }
};
template<>
struct ScalarTraits<uint64_t> {
- static void output(const uint64_t &, void*, llvm::raw_ostream &);
- static StringRef input(StringRef, void*, uint64_t &);
+ static void output(const uint64_t &, void *, raw_ostream &);
+ static StringRef input(StringRef, void *, uint64_t &);
static bool mustQuote(StringRef) { return false; }
};
template<>
struct ScalarTraits<int8_t> {
- static void output(const int8_t &, void*, llvm::raw_ostream &);
- static StringRef input(StringRef, void*, int8_t &);
+ static void output(const int8_t &, void *, raw_ostream &);
+ static StringRef input(StringRef, void *, int8_t &);
static bool mustQuote(StringRef) { return false; }
};
template<>
struct ScalarTraits<int16_t> {
- static void output(const int16_t &, void*, llvm::raw_ostream &);
- static StringRef input(StringRef, void*, int16_t &);
+ static void output(const int16_t &, void *, raw_ostream &);
+ static StringRef input(StringRef, void *, int16_t &);
static bool mustQuote(StringRef) { return false; }
};
template<>
struct ScalarTraits<int32_t> {
- static void output(const int32_t &, void*, llvm::raw_ostream &);
- static StringRef input(StringRef, void*, int32_t &);
+ static void output(const int32_t &, void *, raw_ostream &);
+ static StringRef input(StringRef, void *, int32_t &);
static bool mustQuote(StringRef) { return false; }
};
template<>
struct ScalarTraits<int64_t> {
- static void output(const int64_t &, void*, llvm::raw_ostream &);
- static StringRef input(StringRef, void*, int64_t &);
+ static void output(const int64_t &, void *, raw_ostream &);
+ static StringRef input(StringRef, void *, int64_t &);
static bool mustQuote(StringRef) { return false; }
};
template<>
struct ScalarTraits<float> {
- static void output(const float &, void*, llvm::raw_ostream &);
- static StringRef input(StringRef, void*, float &);
+ static void output(const float &, void *, raw_ostream &);
+ static StringRef input(StringRef, void *, float &);
static bool mustQuote(StringRef) { return false; }
};
template<>
struct ScalarTraits<double> {
- static void output(const double &, void*, llvm::raw_ostream &);
- static StringRef input(StringRef, void*, double &);
+ static void output(const double &, void *, raw_ostream &);
+ static StringRef input(StringRef, void *, double &);
static bool mustQuote(StringRef) { return false; }
};
@@ -993,12 +1004,11 @@ struct ScalarTraits<double> {
template <typename value_type, support::endianness endian, size_t alignment>
struct ScalarTraits<support::detail::packed_endian_specific_integral<
value_type, endian, alignment>> {
- typedef support::detail::packed_endian_specific_integral<value_type, endian,
- alignment>
- endian_type;
+ using endian_type =
+ support::detail::packed_endian_specific_integral<value_type, endian,
+ alignment>;
- static void output(const endian_type &E, void *Ctx,
- llvm::raw_ostream &Stream) {
+ static void output(const endian_type &E, void *Ctx, raw_ostream &Stream) {
ScalarTraits<value_type>::output(static_cast<value_type>(E), Ctx, Stream);
}
@@ -1038,7 +1048,7 @@ struct MappingNormalization {
TNorm* operator->() { return BufPtr; }
private:
- typedef llvm::AlignedCharArrayUnion<TNorm> Storage;
+ using Storage = AlignedCharArrayUnion<TNorm>;
Storage Buffer;
IO &io;
@@ -1050,9 +1060,8 @@ private:
// to [de]normalize an object for use with YAML conversion.
template <typename TNorm, typename TFinal>
struct MappingNormalizationHeap {
- MappingNormalizationHeap(IO &i_o, TFinal &Obj,
- llvm::BumpPtrAllocator *allocator)
- : io(i_o), BufPtr(nullptr), Result(Obj) {
+ MappingNormalizationHeap(IO &i_o, TFinal &Obj, BumpPtrAllocator *allocator)
+ : io(i_o), Result(Obj) {
if ( io.outputting() ) {
BufPtr = new (&Buffer) TNorm(io, Obj);
}
@@ -1076,11 +1085,11 @@ struct MappingNormalizationHeap {
TNorm* operator->() { return BufPtr; }
private:
- typedef llvm::AlignedCharArrayUnion<TNorm> Storage;
+ using Storage = AlignedCharArrayUnion<TNorm>;
Storage Buffer;
IO &io;
- TNorm *BufPtr;
+ TNorm *BufPtr = nullptr;
TFinal &Result;
};
@@ -1105,6 +1114,10 @@ public:
void *Ctxt = nullptr,
SourceMgr::DiagHandlerTy DiagHandler = nullptr,
void *DiagHandlerCtxt = nullptr);
+ Input(MemoryBufferRef Input,
+ void *Ctxt = nullptr,
+ SourceMgr::DiagHandlerTy DiagHandler = nullptr,
+ void *DiagHandlerCtxt = nullptr);
~Input() override;
// Check if there was an syntax or semantic error during parsing.
@@ -1147,7 +1160,7 @@ private:
HNode(Node *n) : _node(n) { }
virtual ~HNode() = default;
- static inline bool classof(const HNode *) { return true; }
+ static bool classof(const HNode *) { return true; }
Node *_node;
};
@@ -1158,11 +1171,9 @@ private:
public:
EmptyHNode(Node *n) : HNode(n) { }
- static inline bool classof(const HNode *n) {
- return NullNode::classof(n->_node);
- }
+ static bool classof(const HNode *n) { return NullNode::classof(n->_node); }
- static inline bool classof(const EmptyHNode *) { return true; }
+ static bool classof(const EmptyHNode *) { return true; }
};
class ScalarHNode : public HNode {
@@ -1173,12 +1184,12 @@ private:
StringRef value() const { return _value; }
- static inline bool classof(const HNode *n) {
+ static bool classof(const HNode *n) {
return ScalarNode::classof(n->_node) ||
BlockScalarNode::classof(n->_node);
}
- static inline bool classof(const ScalarHNode *) { return true; }
+ static bool classof(const ScalarHNode *) { return true; }
protected:
StringRef _value;
@@ -1190,16 +1201,16 @@ private:
public:
MapHNode(Node *n) : HNode(n) { }
- static inline bool classof(const HNode *n) {
+ static bool classof(const HNode *n) {
return MappingNode::classof(n->_node);
}
- static inline bool classof(const MapHNode *) { return true; }
+ static bool classof(const MapHNode *) { return true; }
- typedef llvm::StringMap<std::unique_ptr<HNode>> NameToNode;
+ using NameToNode = StringMap<std::unique_ptr<HNode>>;
- NameToNode Mapping;
- llvm::SmallVector<std::string, 6> ValidKeys;
+ NameToNode Mapping;
+ SmallVector<std::string, 6> ValidKeys;
};
class SequenceHNode : public HNode {
@@ -1208,11 +1219,11 @@ private:
public:
SequenceHNode(Node *n) : HNode(n) { }
- static inline bool classof(const HNode *n) {
+ static bool classof(const HNode *n) {
return SequenceNode::classof(n->_node);
}
- static inline bool classof(const SequenceHNode *) { return true; }
+ static bool classof(const SequenceHNode *) { return true; }
std::vector<std::unique_ptr<HNode>> Entries;
};
@@ -1231,14 +1242,14 @@ public:
const Node *getCurrentNode() const;
private:
- llvm::SourceMgr SrcMgr; // must be before Strm
+ SourceMgr SrcMgr; // must be before Strm
std::unique_ptr<llvm::yaml::Stream> Strm;
std::unique_ptr<HNode> TopNode;
std::error_code EC;
- llvm::BumpPtrAllocator StringAllocator;
- llvm::yaml::document_iterator DocIterator;
+ BumpPtrAllocator StringAllocator;
+ document_iterator DocIterator;
std::vector<bool> BitValuesUsed;
- HNode *CurrentNode;
+ HNode *CurrentNode = nullptr;
bool ScalarMatchFound;
};
@@ -1248,9 +1259,16 @@ private:
///
class Output : public IO {
public:
- Output(llvm::raw_ostream &, void *Ctxt = nullptr, int WrapColumn = 70);
+ Output(raw_ostream &, void *Ctxt = nullptr, int WrapColumn = 70);
~Output() override;
+ /// \brief Set whether or not to output optional values which are equal
+ /// to the default value. By default, when outputting if you attempt
+ /// to write a value that is equal to the default, the value gets ignored.
+ /// Sometimes, it is useful to be able to see these in the resulting YAML
+ /// anyway.
+ void setWriteDefaultValues(bool Write) { WriteDefaultValues = Write; }
+
bool outputting() override;
bool mapTag(StringRef, bool) override;
void beginMapping() override;
@@ -1304,16 +1322,17 @@ private:
inFlowMapOtherKey
};
- llvm::raw_ostream &Out;
- int WrapColumn;
- SmallVector<InState, 8> StateStack;
- int Column;
- int ColumnAtFlowStart;
- int ColumnAtMapFlowStart;
- bool NeedBitValueComma;
- bool NeedFlowSequenceComma;
- bool EnumerationMatchFound;
- bool NeedsNewLine;
+ raw_ostream &Out;
+ int WrapColumn;
+ SmallVector<InState, 8> StateStack;
+ int Column = 0;
+ int ColumnAtFlowStart = 0;
+ int ColumnAtMapFlowStart = 0;
+ bool NeedBitValueComma = false;
+ bool NeedFlowSequenceComma = false;
+ bool EnumerationMatchFound = false;
+ bool NeedsNewLine = false;
+ bool WriteDefaultValues = false;
};
/// YAML I/O does conversion based on types. But often native data types
@@ -1336,7 +1355,7 @@ private:
bool operator==(const _base &rhs) const { return value == rhs; } \
bool operator<(const _type &rhs) const { return value < rhs.value; } \
_base value; \
- typedef _base BaseType; \
+ using BaseType = _base; \
};
///
@@ -1350,29 +1369,29 @@ LLVM_YAML_STRONG_TYPEDEF(uint64_t, Hex64)
template<>
struct ScalarTraits<Hex8> {
- static void output(const Hex8 &, void*, llvm::raw_ostream &);
- static StringRef input(StringRef, void*, Hex8 &);
+ static void output(const Hex8 &, void *, raw_ostream &);
+ static StringRef input(StringRef, void *, Hex8 &);
static bool mustQuote(StringRef) { return false; }
};
template<>
struct ScalarTraits<Hex16> {
- static void output(const Hex16 &, void*, llvm::raw_ostream &);
- static StringRef input(StringRef, void*, Hex16 &);
+ static void output(const Hex16 &, void *, raw_ostream &);
+ static StringRef input(StringRef, void *, Hex16 &);
static bool mustQuote(StringRef) { return false; }
};
template<>
struct ScalarTraits<Hex32> {
- static void output(const Hex32 &, void*, llvm::raw_ostream &);
- static StringRef input(StringRef, void*, Hex32 &);
+ static void output(const Hex32 &, void *, raw_ostream &);
+ static StringRef input(StringRef, void *, Hex32 &);
static bool mustQuote(StringRef) { return false; }
};
template<>
struct ScalarTraits<Hex64> {
- static void output(const Hex64 &, void*, llvm::raw_ostream &);
- static StringRef input(StringRef, void*, Hex64 &);
+ static void output(const Hex64 &, void *, raw_ostream &);
+ static StringRef input(StringRef, void *, Hex64 &);
static bool mustQuote(StringRef) { return false; }
};
@@ -1535,22 +1554,67 @@ operator<<(Output &yout, T &seq) {
return yout;
}
-template <typename T> struct SequenceTraitsImpl {
- typedef typename T::value_type _type;
+template <bool B> struct IsFlowSequenceBase {};
+template <> struct IsFlowSequenceBase<true> { static const bool flow = true; };
+
+template <typename T, bool Flow>
+struct SequenceTraitsImpl : IsFlowSequenceBase<Flow> {
+private:
+ using type = typename T::value_type;
+
+public:
static size_t size(IO &io, T &seq) { return seq.size(); }
- static _type &element(IO &io, T &seq, size_t index) {
+
+ static type &element(IO &io, T &seq, size_t index) {
if (index >= seq.size())
seq.resize(index + 1);
return seq[index];
}
};
+// Simple helper to check an expression can be used as a bool-valued template
+// argument.
+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>
+ : 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>
+ : SequenceTraitsImpl<SmallVector<T, N>, 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> {
+ static const bool flow = true;
+};
+
+// Sequences of strings use block formatting.
+template<> struct SequenceElementTraits<std::string> {
+ static const bool flow = false;
+};
+template<> struct SequenceElementTraits<StringRef> {
+ static const bool flow = false;
+};
+template<> struct SequenceElementTraits<std::pair<std::string, std::string>> {
+ static const bool flow = false;
+};
+
/// Implementation of CustomMappingTraits for std::map<std::string, T>.
template <typename T> struct StdMapStringCustomMappingTraitsImpl {
- typedef std::map<std::string, T> map_type;
+ 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]);
}
+
static void output(IO &io, map_type &v) {
for (auto &p : v)
io.mapRequired(p.first.c_str(), p.second);
@@ -1560,39 +1624,64 @@ template <typename T> struct StdMapStringCustomMappingTraitsImpl {
} // end namespace yaml
} // end namespace llvm
-/// Utility for declaring that a std::vector of a particular type
-/// should be considered a YAML sequence.
-#define LLVM_YAML_IS_SEQUENCE_VECTOR(_type) \
+#define LLVM_YAML_IS_SEQUENCE_VECTOR_IMPL(TYPE, FLOW) \
namespace llvm { \
namespace yaml { \
- template <> \
- struct SequenceTraits<std::vector<_type>> \
- : public SequenceTraitsImpl<std::vector<_type>> {}; \
- template <unsigned N> \
- struct SequenceTraits<SmallVector<_type, N>> \
- : public SequenceTraitsImpl<SmallVector<_type, N>> {}; \
+ static_assert( \
+ !std::is_fundamental<TYPE>::value && \
+ !std::is_same<TYPE, std::string>::value && \
+ !std::is_same<TYPE, llvm::StringRef>::value, \
+ "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"); \
+ template <> struct SequenceElementTraits<TYPE> { \
+ static const bool flow = FLOW; \
+ }; \
} \
}
/// Utility for declaring that a std::vector of a particular type
+/// should be considered a YAML sequence.
+#define LLVM_YAML_IS_SEQUENCE_VECTOR(type) \
+ LLVM_YAML_IS_SEQUENCE_VECTOR_IMPL(type, false)
+
+/// Utility for declaring that a std::vector of a particular type
/// should be considered a YAML flow sequence.
-/// We need to do a partial specialization on the vector version, not a full.
-/// If this is a full specialization, the compiler is a bit too "smart" and
-/// decides to warn on -Wunused-const-variable. This workaround can be
-/// removed and we can do a full specialization on std::vector<T> once
-/// PR28878 is fixed.
-#define LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(_type) \
+#define LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(type) \
+ LLVM_YAML_IS_SEQUENCE_VECTOR_IMPL(type, true)
+
+#define LLVM_YAML_DECLARE_MAPPING_TRAITS(Type) \
namespace llvm { \
namespace yaml { \
- template <unsigned N> \
- struct SequenceTraits<SmallVector<_type, N>> \
- : public SequenceTraitsImpl<SmallVector<_type, N>> { \
- static const bool flow = true; \
+ template <> struct MappingTraits<Type> { \
+ static void mapping(IO &IO, Type &Obj); \
+ }; \
+ } \
+ }
+
+#define LLVM_YAML_DECLARE_ENUM_TRAITS(Type) \
+ namespace llvm { \
+ namespace yaml { \
+ template <> struct ScalarEnumerationTraits<Type> { \
+ static void enumeration(IO &io, Type &Value); \
+ }; \
+ } \
+ }
+
+#define LLVM_YAML_DECLARE_BITSET_TRAITS(Type) \
+ namespace llvm { \
+ namespace yaml { \
+ template <> struct ScalarBitSetTraits<Type> { \
+ static void bitset(IO &IO, Type &Options); \
}; \
- template <typename Allocator> \
- struct SequenceTraits<std::vector<_type, Allocator>> \
- : public SequenceTraitsImpl<std::vector<_type, Allocator>> { \
- static const bool flow = true; \
+ } \
+ }
+
+#define LLVM_YAML_DECLARE_SCALAR_TRAITS(Type, MustQuote) \
+ namespace llvm { \
+ namespace yaml { \
+ template <> struct ScalarTraits<Type> { \
+ static void output(const Type &Value, void *ctx, raw_ostream &Out); \
+ static StringRef input(StringRef Scalar, void *ctxt, Type &Value); \
+ static bool mustQuote(StringRef) { return MustQuote; } \
}; \
} \
}
@@ -1604,10 +1693,10 @@ template <typename T> struct StdMapStringCustomMappingTraitsImpl {
namespace yaml { \
template <unsigned N> \
struct DocumentListTraits<SmallVector<_type, N>> \
- : public SequenceTraitsImpl<SmallVector<_type, N>> {}; \
+ : public SequenceTraitsImpl<SmallVector<_type, N>, false> {}; \
template <> \
struct DocumentListTraits<std::vector<_type>> \
- : public SequenceTraitsImpl<std::vector<_type>> {}; \
+ : public SequenceTraitsImpl<std::vector<_type>, false> {}; \
} \
}
diff --git a/contrib/llvm/include/llvm/Support/raw_sha1_ostream.h b/contrib/llvm/include/llvm/Support/raw_sha1_ostream.h
index 329ef9f..bd55d98 100644
--- a/contrib/llvm/include/llvm/Support/raw_sha1_ostream.h
+++ b/contrib/llvm/include/llvm/Support/raw_sha1_ostream.h
@@ -14,9 +14,9 @@
#ifndef LLVM_SUPPORT_RAW_SHA1_OSTREAM_H
#define LLVM_SUPPORT_RAW_SHA1_OSTREAM_H
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/Support/SHA1.h"
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/Support/SHA1.h"
+#include "llvm/Support/raw_ostream.h"
namespace llvm {
diff --git a/contrib/llvm/include/llvm/Support/thread.h b/contrib/llvm/include/llvm/Support/thread.h
index 9c45418..787a513 100644
--- a/contrib/llvm/include/llvm/Support/thread.h
+++ b/contrib/llvm/include/llvm/Support/thread.h
@@ -21,22 +21,8 @@
#if LLVM_ENABLE_THREADS
-#ifdef _MSC_VER
-// concrt.h depends on eh.h for __uncaught_exception declaration
-// even if we disable exceptions.
-#include <eh.h>
-
-// Suppress 'C++ exception handler used, but unwind semantics are not enabled.'
-#pragma warning(push)
-#pragma warning(disable:4530)
-#endif
-
#include <thread>
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
-
namespace llvm {
typedef std::thread thread;
}
diff --git a/contrib/llvm/include/llvm/Support/type_traits.h b/contrib/llvm/include/llvm/Support/type_traits.h
index 7706ff5..cc08783 100644
--- a/contrib/llvm/include/llvm/Support/type_traits.h
+++ b/contrib/llvm/include/llvm/Support/type_traits.h
@@ -14,11 +14,10 @@
#ifndef LLVM_SUPPORT_TYPE_TRAITS_H
#define LLVM_SUPPORT_TYPE_TRAITS_H
+#include "llvm/Support/Compiler.h"
#include <type_traits>
#include <utility>
-#include "llvm/Support/Compiler.h"
-
#ifndef __has_feature
#define LLVM_DEFINED_HAS_FEATURE
#define __has_feature(x) 0
@@ -51,7 +50,7 @@ struct isPodLike {
// std::pair's are pod-like if their elements are.
template<typename T, typename U>
-struct isPodLike<std::pair<T, U> > {
+struct isPodLike<std::pair<T, U>> {
static const bool value = isPodLike<T>::value && isPodLike<U>::value;
};
@@ -63,7 +62,7 @@ struct isPodLike<std::pair<T, U> > {
/// 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 {
- typedef typename std::remove_reference<T>::type UnderlyingT;
+ using UnderlyingT = typename std::remove_reference<T>::type;
public:
static const bool value =
@@ -76,26 +75,36 @@ public:
/// \brief If T is a pointer, just return it. If it is not, return T&.
template<typename T, typename Enable = void>
-struct add_lvalue_reference_if_not_pointer { typedef T &type; };
+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> {
- typedef T type;
+ using type = T;
};
/// \brief If T is a pointer to X, return a pointer to const X. If it is not,
/// return const T.
template<typename T, typename Enable = void>
-struct add_const_past_pointer { typedef const T type; };
+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> {
- typedef const typename std::remove_pointer<T>::type *type;
+ using type = const typename std::remove_pointer<T>::type *;
};
-}
+template <typename T, typename Enable = void>
+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> {
+ using type = typename add_const_past_pointer<T>::type;
+};
+
+} // end namespace llvm
// If the compiler supports detecting whether a class is final, define
// an LLVM_IS_FINAL macro. If it cannot be defined properly, this
@@ -110,4 +119,4 @@ struct add_const_past_pointer<
#undef __has_feature
#endif
-#endif
+#endif // LLVM_SUPPORT_TYPE_TRAITS_H
diff --git a/contrib/llvm/include/llvm/TableGen/Main.h b/contrib/llvm/include/llvm/TableGen/Main.h
index 866b986..670572d 100644
--- a/contrib/llvm/include/llvm/TableGen/Main.h
+++ b/contrib/llvm/include/llvm/TableGen/Main.h
@@ -16,13 +16,15 @@
namespace llvm {
-class RecordKeeper;
class raw_ostream;
-/// \brief Perform the action using Records, and write output to OS.
-/// \returns true on error, false otherwise
-typedef bool TableGenMainFn(raw_ostream &OS, RecordKeeper &Records);
+class RecordKeeper;
+
+/// Perform the action using Records, and write output to OS.
+/// Returns true on error, false otherwise.
+using TableGenMainFn = bool (raw_ostream &OS, RecordKeeper &Records);
int TableGenMain(char *argv0, TableGenMainFn *MainFn);
-}
-#endif
+} // end namespace llvm
+
+#endif // LLVM_TABLEGEN_MAIN_H
diff --git a/contrib/llvm/include/llvm/TableGen/Record.h b/contrib/llvm/include/llvm/TableGen/Record.h
index 5a100f0..fa9ca28 100644
--- a/contrib/llvm/include/llvm/TableGen/Record.h
+++ b/contrib/llvm/include/llvm/TableGen/Record.h
@@ -38,11 +38,11 @@
namespace llvm {
class ListRecTy;
+struct MultiClass;
class Record;
class RecordKeeper;
class RecordVal;
class StringInit;
-struct MultiClass;
//===----------------------------------------------------------------------===//
// Type Classes
@@ -90,7 +90,6 @@ inline raw_ostream &operator<<(raw_ostream &OS, const RecTy &Ty) {
}
/// 'bit' - Represent a single bit
-///
class BitRecTy : public RecTy {
static BitRecTy Shared;
@@ -109,7 +108,6 @@ public:
};
/// 'bits<n>' - Represent a fixed number of bits
-///
class BitsRecTy : public RecTy {
unsigned Size;
@@ -130,7 +128,6 @@ public:
};
/// 'code' - Represent a code fragment
-///
class CodeRecTy : public RecTy {
static CodeRecTy Shared;
@@ -147,7 +144,6 @@ public:
};
/// 'int' - Represent an integer value of no particular size
-///
class IntRecTy : public RecTy {
static IntRecTy Shared;
@@ -166,7 +162,6 @@ public:
};
/// 'string' - Represent an string value
-///
class StringRecTy : public RecTy {
static StringRecTy Shared;
@@ -185,14 +180,13 @@ public:
/// 'list<Ty>' - Represent a list of values, all of which must be of
/// the specified type.
-///
class ListRecTy : public RecTy {
+ friend ListRecTy *RecTy::getListTy();
+
RecTy *Ty;
explicit ListRecTy(RecTy *T) : RecTy(ListRecTyKind), Ty(T) {}
- friend ListRecTy *RecTy::getListTy();
-
public:
static bool classof(const RecTy *RT) {
return RT->getRecTyKind() == ListRecTyKind;
@@ -207,7 +201,6 @@ public:
};
/// 'dag' - Represent a dag fragment
-///
class DagRecTy : public RecTy {
static DagRecTy Shared;
@@ -225,14 +218,13 @@ public:
/// '[classname]' - Represent an instance of a class, such as:
/// (R32 X = EAX).
-///
class RecordRecTy : public RecTy {
+ friend class Record;
+
Record *Rec;
explicit RecordRecTy(Record *R) : RecTy(RecordRecTyKind), Rec(R) {}
- friend class Record;
-
public:
static bool classof(const RecTy *RT) {
return RT->getRecTyKind() == RecordRecTyKind;
@@ -249,7 +241,6 @@ public:
/// Find a common type that T1 and T2 convert to.
/// Return 0 if no such type exists.
-///
RecTy *resolveTypes(RecTy *T1, RecTy *T2);
//===----------------------------------------------------------------------===//
@@ -341,7 +332,6 @@ public:
/// selection operator. Given an initializer, it selects the specified bits
/// out, returning them as a new init of bits type. If it is not legal to use
/// the bit subscript operator on this initializer, return null.
- ///
virtual Init *convertInitializerBitRange(ArrayRef<unsigned> Bits) const {
return nullptr;
}
@@ -350,7 +340,6 @@ public:
/// selection operator. Given an initializer, it selects the specified list
/// elements, returning them as a new init of list type. If it is not legal
/// to take a slice of this, return null.
- ///
virtual Init *convertInitListSlice(ArrayRef<unsigned> Elements) const {
return nullptr;
}
@@ -358,7 +347,6 @@ public:
/// This method is used to implement the FieldInit class.
/// Implementors of this method should return the type of the named field if
/// they are of record type.
- ///
virtual RecTy *getFieldType(StringInit *FieldName) const {
return nullptr;
}
@@ -366,7 +354,6 @@ public:
/// This method complements getFieldType to return the
/// initializer for the specified field. If getFieldType returns non-null
/// this method should return non-null, otherwise it returns null.
- ///
virtual Init *getFieldInit(Record &R, const RecordVal *RV,
StringInit *FieldName) const {
return nullptr;
@@ -376,7 +363,6 @@ public:
/// variables which may not be defined at the time the expression is formed.
/// If a value is set for the variable later, this method will be called on
/// users of the value to allow the value to propagate out.
- ///
virtual Init *resolveReferences(Record &R, const RecordVal *RV) const {
return const_cast<Init *>(this);
}
@@ -400,7 +386,6 @@ inline raw_ostream &operator<<(raw_ostream &OS, const Init &I) {
/// This is the common super-class of types that have a specific,
/// explicit, type.
-///
class TypedInit : public Init {
RecTy *Ty;
@@ -409,8 +394,8 @@ protected:
: Init(K, Opc), Ty(T) {}
public:
- TypedInit(const TypedInit &Other) = delete;
- TypedInit &operator=(const TypedInit &Other) = delete;
+ TypedInit(const TypedInit &) = delete;
+ TypedInit &operator=(const TypedInit &) = delete;
static bool classof(const Init *I) {
return I->getKind() >= IK_FirstTypedInit &&
@@ -438,13 +423,12 @@ public:
};
/// '?' - Represents an uninitialized value
-///
class UnsetInit : public Init {
UnsetInit() : Init(IK_UnsetInit) {}
public:
UnsetInit(const UnsetInit &) = delete;
- UnsetInit &operator=(const UnsetInit &Other) = delete;
+ UnsetInit &operator=(const UnsetInit &) = delete;
static bool classof(const Init *I) {
return I->getKind() == IK_UnsetInit;
@@ -463,15 +447,14 @@ public:
};
/// 'true'/'false' - Represent a concrete initializer for a bit.
-///
class BitInit : public Init {
bool Value;
explicit BitInit(bool V) : Init(IK_BitInit), Value(V) {}
public:
- BitInit(const BitInit &Other) = delete;
- BitInit &operator=(BitInit &Other) = delete;
+ BitInit(const BitInit &) = delete;
+ BitInit &operator=(BitInit &) = delete;
static bool classof(const Init *I) {
return I->getKind() == IK_BitInit;
@@ -493,7 +476,6 @@ public:
/// '{ a, b, c }' - Represents an initializer for a BitsRecTy value.
/// It contains a vector of bits, whose size is determined by the type.
-///
class BitsInit final : public TypedInit, public FoldingSetNode,
public TrailingObjects<BitsInit, Init *> {
unsigned NumBits;
@@ -502,8 +484,8 @@ class BitsInit final : public TypedInit, public FoldingSetNode,
: TypedInit(IK_BitsInit, BitsRecTy::get(N)), NumBits(N) {}
public:
- BitsInit(const BitsInit &Other) = delete;
- BitsInit &operator=(const BitsInit &Other) = delete;
+ BitsInit(const BitsInit &) = delete;
+ BitsInit &operator=(const BitsInit &) = delete;
// Do not use sized deallocation due to trailing objects.
void operator delete(void *p) { ::operator delete(p); }
@@ -552,7 +534,6 @@ public:
};
/// '7' - Represent an initialization by a literal integer value.
-///
class IntInit : public TypedInit {
int64_t Value;
@@ -560,8 +541,8 @@ class IntInit : public TypedInit {
: TypedInit(IK_IntInit, IntRecTy::get()), Value(V) {}
public:
- IntInit(const IntInit &Other) = delete;
- IntInit &operator=(const IntInit &Other) = delete;
+ IntInit(const IntInit &) = delete;
+ IntInit &operator=(const IntInit &) = delete;
static bool classof(const Init *I) {
return I->getKind() == IK_IntInit;
@@ -590,7 +571,6 @@ public:
};
/// "foo" - Represent an initialization by a string value.
-///
class StringInit : public TypedInit {
StringRef Value;
@@ -598,8 +578,8 @@ class StringInit : public TypedInit {
: TypedInit(IK_StringInit, StringRecTy::get()), Value(V) {}
public:
- StringInit(const StringInit &Other) = delete;
- StringInit &operator=(const StringInit &Other) = delete;
+ StringInit(const StringInit &) = delete;
+ StringInit &operator=(const StringInit &) = delete;
static bool classof(const Init *I) {
return I->getKind() == IK_StringInit;
@@ -636,8 +616,8 @@ class CodeInit : public TypedInit {
Value(V) {}
public:
- CodeInit(const StringInit &Other) = delete;
- CodeInit &operator=(const StringInit &Other) = delete;
+ CodeInit(const StringInit &) = delete;
+ CodeInit &operator=(const StringInit &) = delete;
static bool classof(const Init *I) {
return I->getKind() == IK_CodeInit;
@@ -671,19 +651,19 @@ public:
/// [AL, AH, CL] - Represent a list of defs
///
class ListInit final : public TypedInit, public FoldingSetNode,
- public TrailingObjects<BitsInit, Init *> {
+ public TrailingObjects<ListInit, Init *> {
unsigned NumValues;
public:
- typedef Init *const *const_iterator;
+ using const_iterator = Init *const *;
private:
explicit ListInit(unsigned N, RecTy *EltTy)
: TypedInit(IK_ListInit, ListRecTy::get(EltTy)), NumValues(N) {}
public:
- ListInit(const ListInit &Other) = delete;
- ListInit &operator=(const ListInit &Other) = delete;
+ ListInit(const ListInit &) = delete;
+ ListInit &operator=(const ListInit &) = delete;
// Do not use sized deallocation due to trailing objects.
void operator delete(void *p) { ::operator delete(p); }
@@ -744,8 +724,8 @@ protected:
: TypedInit(K, Type, Opc) {}
public:
- OpInit(const OpInit &Other) = delete;
- OpInit &operator=(OpInit &Other) = delete;
+ OpInit(const OpInit &) = delete;
+ OpInit &operator=(OpInit &) = delete;
static bool classof(const Init *I) {
return I->getKind() >= IK_FirstOpInit &&
@@ -781,8 +761,8 @@ private:
: OpInit(IK_UnOpInit, Type, opc), LHS(lhs) {}
public:
- UnOpInit(const UnOpInit &Other) = delete;
- UnOpInit &operator=(const UnOpInit &Other) = delete;
+ UnOpInit(const UnOpInit &) = delete;
+ UnOpInit &operator=(const UnOpInit &) = delete;
static bool classof(const Init *I) {
return I->getKind() == IK_UnOpInit;
@@ -819,7 +799,6 @@ public:
};
/// !op (X, Y) - Combine two inits.
-///
class BinOpInit : public OpInit, public FoldingSetNode {
public:
enum BinaryOp : uint8_t { ADD, AND, OR, SHL, SRA, SRL, LISTCONCAT,
@@ -832,8 +811,8 @@ private:
OpInit(IK_BinOpInit, Type, opc), LHS(lhs), RHS(rhs) {}
public:
- BinOpInit(const BinOpInit &Other) = delete;
- BinOpInit &operator=(const BinOpInit &Other) = delete;
+ BinOpInit(const BinOpInit &) = delete;
+ BinOpInit &operator=(const BinOpInit &) = delete;
static bool classof(const Init *I) {
return I->getKind() == IK_BinOpInit;
@@ -874,7 +853,6 @@ public:
};
/// !op (X, Y, Z) - Combine two inits.
-///
class TernOpInit : public OpInit, public FoldingSetNode {
public:
enum TernaryOp : uint8_t { SUBST, FOREACH, IF };
@@ -887,8 +865,8 @@ private:
OpInit(IK_TernOpInit, Type, opc), LHS(lhs), MHS(mhs), RHS(rhs) {}
public:
- TernOpInit(const TernOpInit &Other) = delete;
- TernOpInit &operator=(const TernOpInit &Other) = delete;
+ TernOpInit(const TernOpInit &) = delete;
+ TernOpInit &operator=(const TernOpInit &) = delete;
static bool classof(const Init *I) {
return I->getKind() == IK_TernOpInit;
@@ -935,7 +913,6 @@ public:
};
/// 'Opcode' - Represent a reference to an entire variable object.
-///
class VarInit : public TypedInit {
Init *VarName;
@@ -943,8 +920,8 @@ class VarInit : public TypedInit {
: TypedInit(IK_VarInit, T), VarName(VN) {}
public:
- VarInit(const VarInit &Other) = delete;
- VarInit &operator=(const VarInit &Other) = delete;
+ VarInit(const VarInit &) = delete;
+ VarInit &operator=(const VarInit &) = delete;
static bool classof(const Init *I) {
return I->getKind() == IK_VarInit;
@@ -980,7 +957,6 @@ public:
};
/// Opcode{0} - Represent access to one bit of a variable or field.
-///
class VarBitInit : public Init {
TypedInit *TI;
unsigned Bit;
@@ -994,8 +970,8 @@ class VarBitInit : public Init {
}
public:
- VarBitInit(const VarBitInit &Other) = delete;
- VarBitInit &operator=(const VarBitInit &Other) = delete;
+ VarBitInit(const VarBitInit &) = delete;
+ VarBitInit &operator=(const VarBitInit &) = delete;
static bool classof(const Init *I) {
return I->getKind() == IK_VarBitInit;
@@ -1032,8 +1008,8 @@ class VarListElementInit : public TypedInit {
}
public:
- VarListElementInit(const VarListElementInit &Other) = delete;
- void operator=(const VarListElementInit &Other) = delete;
+ VarListElementInit(const VarListElementInit &) = delete;
+ VarListElementInit &operator=(const VarListElementInit &) = delete;
static bool classof(const Init *I) {
return I->getKind() == IK_VarListElementInit;
@@ -1057,17 +1033,16 @@ public:
};
/// AL - Represent a reference to a 'def' in the description
-///
class DefInit : public TypedInit {
+ friend class Record;
+
Record *Def;
DefInit(Record *D, RecordRecTy *T) : TypedInit(IK_DefInit, T), Def(D) {}
- friend class Record;
-
public:
- DefInit(const DefInit &Other) = delete;
- DefInit &operator=(const DefInit &Other) = delete;
+ DefInit(const DefInit &) = delete;
+ DefInit &operator=(const DefInit &) = delete;
static bool classof(const Init *I) {
return I->getKind() == IK_DefInit;
@@ -1101,7 +1076,6 @@ public:
};
/// X.Y - Represent a reference to a subfield of a variable
-///
class FieldInit : public TypedInit {
Init *Rec; // Record we are referring to
StringInit *FieldName; // Field we are accessing
@@ -1112,8 +1086,8 @@ class FieldInit : public TypedInit {
}
public:
- FieldInit(const FieldInit &Other) = delete;
- FieldInit &operator=(const FieldInit &Other) = delete;
+ FieldInit(const FieldInit &) = delete;
+ FieldInit &operator=(const FieldInit &) = delete;
static bool classof(const Init *I) {
return I->getKind() == IK_FieldInit;
@@ -1136,22 +1110,24 @@ public:
/// (v a, b) - Represent a DAG tree value. DAG inits are required
/// to have at least one value then a (possibly empty) list of arguments. Each
/// argument can have a name associated with it.
-///
-class DagInit : public TypedInit, public FoldingSetNode {
+class DagInit final : public TypedInit, public FoldingSetNode,
+ public TrailingObjects<DagInit, Init *, StringInit *> {
+ friend TrailingObjects;
+
Init *Val;
StringInit *ValName;
- SmallVector<Init*, 4> Args;
- SmallVector<StringInit*, 4> ArgNames;
+ unsigned NumArgs;
+ unsigned NumArgNames;
- DagInit(Init *V, StringInit *VN, ArrayRef<Init *> ArgRange,
- ArrayRef<StringInit *> NameRange)
+ DagInit(Init *V, StringInit *VN, unsigned NumArgs, unsigned NumArgNames)
: TypedInit(IK_DagInit, DagRecTy::get()), Val(V), ValName(VN),
- Args(ArgRange.begin(), ArgRange.end()),
- ArgNames(NameRange.begin(), NameRange.end()) {}
+ NumArgs(NumArgs), NumArgNames(NumArgNames) {}
+
+ size_t numTrailingObjects(OverloadToken<Init *>) const { return NumArgs; }
public:
- DagInit(const DagInit &Other) = delete;
- DagInit &operator=(const DagInit &Other) = delete;
+ DagInit(const DagInit &) = delete;
+ DagInit &operator=(const DagInit &) = delete;
static bool classof(const Init *I) {
return I->getKind() == IK_DagInit;
@@ -1169,42 +1145,54 @@ public:
Init *getOperator() const { return Val; }
StringInit *getName() const { return ValName; }
+
StringRef getNameStr() const {
return ValName ? ValName->getValue() : StringRef();
}
- unsigned getNumArgs() const { return Args.size(); }
+ unsigned getNumArgs() const { return NumArgs; }
+
Init *getArg(unsigned Num) const {
- assert(Num < Args.size() && "Arg number out of range!");
- return Args[Num];
+ assert(Num < NumArgs && "Arg number out of range!");
+ return getTrailingObjects<Init *>()[Num];
}
+
StringInit *getArgName(unsigned Num) const {
- assert(Num < ArgNames.size() && "Arg number out of range!");
- return ArgNames[Num];
+ assert(Num < NumArgNames && "Arg number out of range!");
+ return getTrailingObjects<StringInit *>()[Num];
}
+
StringRef getArgNameStr(unsigned Num) const {
StringInit *Init = getArgName(Num);
return Init ? Init->getValue() : StringRef();
}
+ ArrayRef<Init *> getArgs() const {
+ return makeArrayRef(getTrailingObjects<Init *>(), NumArgs);
+ }
+
+ ArrayRef<StringInit *> getArgNames() const {
+ return makeArrayRef(getTrailingObjects<StringInit *>(), NumArgNames);
+ }
+
Init *resolveReferences(Record &R, const RecordVal *RV) const override;
std::string getAsString() const override;
- typedef SmallVectorImpl<Init*>::const_iterator const_arg_iterator;
- typedef SmallVectorImpl<StringInit*>::const_iterator const_name_iterator;
+ using const_arg_iterator = SmallVectorImpl<Init*>::const_iterator;
+ using const_name_iterator = SmallVectorImpl<StringInit*>::const_iterator;
- inline const_arg_iterator arg_begin() const { return Args.begin(); }
- inline const_arg_iterator arg_end () const { return Args.end(); }
+ inline const_arg_iterator arg_begin() const { return getArgs().begin(); }
+ inline const_arg_iterator arg_end () const { return getArgs().end(); }
- inline size_t arg_size () const { return Args.size(); }
- inline bool arg_empty() const { return Args.empty(); }
+ inline size_t arg_size () const { return NumArgs; }
+ inline bool arg_empty() const { return NumArgs == 0; }
- inline const_name_iterator name_begin() const { return ArgNames.begin(); }
- inline const_name_iterator name_end () const { return ArgNames.end(); }
+ inline const_name_iterator name_begin() const { return getArgNames().begin();}
+ inline const_name_iterator name_end () const { return getArgNames().end(); }
- inline size_t name_size () const { return ArgNames.size(); }
- inline bool name_empty() const { return ArgNames.empty(); }
+ inline size_t name_size () const { return NumArgNames; }
+ inline bool name_empty() const { return NumArgNames == 0; }
Init *getBit(unsigned Bit) const override {
llvm_unreachable("Illegal bit reference off dag");
@@ -1222,13 +1210,13 @@ public:
class RecordVal {
friend class Record;
+
Init *Name;
PointerIntPair<RecTy *, 1, bool> TyAndPrefix;
Init *Value;
public:
RecordVal(Init *N, RecTy *T, bool P);
- RecordVal(StringRef N, RecTy *T, bool P);
StringRef getName() const;
Init *getNameInit() const { return Name; }
@@ -1290,7 +1278,7 @@ class Record {
// definitions that use them (e.g. Def). However, inside a multiclass they
// can't be immediately resolved so we mark them ResolveFirst to fully
// resolve them later as soon as the multiclass is instantiated.
- bool ResolveFirst;
+ bool ResolveFirst = false;
void init();
void checkName();
@@ -1300,7 +1288,7 @@ public:
explicit Record(Init *N, ArrayRef<SMLoc> locs, RecordKeeper &records,
bool Anonymous = false) :
Name(N), Locs(locs.begin(), locs.end()), TrackedRecords(records),
- ID(LastID++), IsAnonymous(Anonymous), ResolveFirst(false) {
+ ID(LastID++), IsAnonymous(Anonymous) {
init();
}
@@ -1322,6 +1310,7 @@ public:
unsigned getID() const { return ID; }
StringRef getName() const;
+
Init *getNameInit() const {
return Name;
}
@@ -1331,7 +1320,6 @@ public:
}
void setName(Init *Name); // Also updates RecordKeeper.
- void setName(StringRef Name); // Also updates RecordKeeper.
ArrayRef<SMLoc> getLoc() const { return Locs; }
@@ -1354,10 +1342,6 @@ public:
return false;
}
- bool isTemplateArg(StringRef Name) const {
- return isTemplateArg(StringInit::get(Name));
- }
-
const RecordVal *getValue(const Init *Name) const {
for (const RecordVal &Val : Values)
if (Val.Name == Name) return &Val;
@@ -1369,13 +1353,11 @@ public:
}
RecordVal *getValue(const Init *Name) {
- for (RecordVal &Val : Values)
- if (Val.Name == Name) return &Val;
- return nullptr;
+ return const_cast<RecordVal *>(static_cast<const Record *>(this)->getValue(Name));
}
RecordVal *getValue(StringRef Name) {
- return getValue(StringInit::get(Name));
+ return const_cast<RecordVal *>(static_cast<const Record *>(this)->getValue(Name));
}
void addTemplateArg(Init *Name) {
@@ -1383,10 +1365,6 @@ public:
TemplateArgs.push_back(Name);
}
- void addTemplateArg(StringRef Name) {
- addTemplateArg(StringInit::get(Name));
- }
-
void addValue(const RecordVal &RV) {
assert(getValue(RV.getNameInit()) == nullptr && "Value already added!");
Values.push_back(RV);
@@ -1438,7 +1416,6 @@ public:
/// If there are any field references that refer to fields
/// that have been filled in, we can propagate the values now.
- ///
void resolveReferences() { resolveReferencesTo(nullptr); }
/// If anything in this record refers to RV, replace the
@@ -1462,6 +1439,7 @@ public:
ResolveFirst = b;
}
+ void print(raw_ostream &OS) const;
void dump() const;
//===--------------------------------------------------------------------===//
@@ -1470,7 +1448,6 @@ public:
/// Return the initializer for a value with the specified name,
/// or throw an exception if the field does not exist.
- ///
Init *getValueInit(StringRef FieldName) const;
/// Return true if the named field is unset.
@@ -1481,67 +1458,56 @@ public:
/// This method looks up the specified field and returns
/// its value as a string, throwing an exception if the field does not exist
/// or if the value is not a string.
- ///
- std::string getValueAsString(StringRef FieldName) const;
+ StringRef getValueAsString(StringRef FieldName) const;
/// This method looks up the specified field and returns
/// its value as a BitsInit, throwing an exception if the field does not exist
/// or if the value is not the right type.
- ///
BitsInit *getValueAsBitsInit(StringRef FieldName) const;
/// This method looks up the specified field and returns
/// its value as a ListInit, throwing an exception if the field does not exist
/// or if the value is not the right type.
- ///
ListInit *getValueAsListInit(StringRef FieldName) const;
/// This method looks up the specified field and
/// returns its value as a vector of records, throwing an exception if the
/// field does not exist or if the value is not the right type.
- ///
std::vector<Record*> getValueAsListOfDefs(StringRef FieldName) const;
/// This method looks up the specified field and
/// returns its value as a vector of integers, throwing an exception if the
/// field does not exist or if the value is not the right type.
- ///
std::vector<int64_t> getValueAsListOfInts(StringRef FieldName) const;
/// This method looks up the specified field and
/// returns its value as a vector of strings, throwing an exception if the
/// field does not exist or if the value is not the right type.
- ///
- std::vector<std::string> getValueAsListOfStrings(StringRef FieldName) const;
+ std::vector<StringRef> getValueAsListOfStrings(StringRef FieldName) const;
/// This method looks up the specified field and returns its
/// value as a Record, throwing an exception if the field does not exist or if
/// the value is not the right type.
- ///
Record *getValueAsDef(StringRef FieldName) const;
/// This method looks up the specified field and returns its
/// value as a bit, throwing an exception if the field does not exist or if
/// the value is not the right type.
- ///
bool getValueAsBit(StringRef FieldName) const;
/// This method looks up the specified field and
/// returns its value as a bit. If the field is unset, sets Unset to true and
/// returns false.
- ///
bool getValueAsBitOrUnset(StringRef FieldName, bool &Unset) const;
/// This method looks up the specified field and returns its
/// value as an int64_t, throwing an exception if the field does not exist or
/// if the value is not the right type.
- ///
int64_t getValueAsInt(StringRef FieldName) const;
/// This method looks up the specified field and returns its
/// value as an Dag, throwing an exception if the field does not exist or if
/// the value is not the right type.
- ///
DagInit *getValueAsDag(StringRef FieldName) const;
};
@@ -1549,7 +1515,7 @@ raw_ostream &operator<<(raw_ostream &OS, const Record &R);
struct MultiClass {
Record Rec; // Placeholder for template args and Name.
- typedef std::vector<std::unique_ptr<Record>> RecordVector;
+ using RecordVector = std::vector<std::unique_ptr<Record>>;
RecordVector DefPrototypes;
void dump() const;
@@ -1559,7 +1525,7 @@ struct MultiClass {
};
class RecordKeeper {
- typedef std::map<std::string, std::unique_ptr<Record>> RecordMap;
+ using RecordMap = std::map<std::string, std::unique_ptr<Record>>;
RecordMap Classes, Defs;
public:
@@ -1602,7 +1568,6 @@ public:
};
/// Sorting predicate to sort record pointers by name.
-///
struct LessRecord {
bool operator()(const Record *Rec1, const Record *Rec2) const {
return StringRef(Rec1->getName()).compare_numeric(Rec2->getName()) < 0;
@@ -1621,7 +1586,6 @@ struct LessRecordByID {
/// Sorting predicate to sort record pointers by their
/// name field.
-///
struct LessRecordFieldName {
bool operator()(const Record *Rec1, const Record *Rec2) const {
return Rec1->getValueAsString("Name") < Rec2->getValueAsString("Name");
diff --git a/contrib/llvm/include/llvm/TableGen/SetTheory.h b/contrib/llvm/include/llvm/TableGen/SetTheory.h
index 818b054..4b32f9e 100644
--- a/contrib/llvm/include/llvm/TableGen/SetTheory.h
+++ b/contrib/llvm/include/llvm/TableGen/SetTheory.h
@@ -64,8 +64,8 @@ class Record;
class SetTheory {
public:
- typedef std::vector<Record*> RecVec;
- typedef SmallSetVector<Record*, 16> RecSet;
+ using RecVec = std::vector<Record *>;
+ using RecSet = SmallSetVector<Record *, 16>;
/// Operator - A callback representing a DAG operator.
class Operator {
@@ -95,7 +95,7 @@ public:
private:
// Map set defs to their fully expanded contents. This serves as a memoization
// cache and it makes it possible to return const references on queries.
- typedef std::map<Record*, RecVec> ExpandMap;
+ using ExpandMap = std::map<Record *, RecVec>;
ExpandMap Expansions;
// Known DAG operators by name.
diff --git a/contrib/llvm/include/llvm/TableGen/StringMatcher.h b/contrib/llvm/include/llvm/TableGen/StringMatcher.h
index b438779..7c919ff 100644
--- a/contrib/llvm/include/llvm/TableGen/StringMatcher.h
+++ b/contrib/llvm/include/llvm/TableGen/StringMatcher.h
@@ -20,7 +20,8 @@
#include <vector>
namespace llvm {
- class raw_ostream;
+
+class raw_ostream;
/// StringMatcher - Given a list of strings and code to execute when they match,
/// output a simple switch tree to classify the input string.
@@ -30,7 +31,7 @@ namespace llvm {
///
class StringMatcher {
public:
- typedef std::pair<std::string, std::string> StringPair;
+ using StringPair = std::pair<std::string, std::string>;
private:
StringRef StrVariableName;
@@ -38,7 +39,7 @@ private:
raw_ostream &OS;
public:
- StringMatcher(StringRef strVariableName,
+ StringMatcher(StringRef strVariableName,
const std::vector<StringPair> &matches, raw_ostream &os)
: StrVariableName(strVariableName), Matches(matches), OS(os) {}
@@ -49,6 +50,6 @@ private:
unsigned CharNo, unsigned IndentCount) const;
};
-} // end llvm namespace.
+} // end namespace llvm
-#endif
+#endif // LLVM_TABLEGEN_STRINGMATCHER_H
diff --git a/contrib/llvm/include/llvm/TableGen/StringToOffsetTable.h b/contrib/llvm/include/llvm/TableGen/StringToOffsetTable.h
index e5b61ed..4b11e88 100644
--- a/contrib/llvm/include/llvm/TableGen/StringToOffsetTable.h
+++ b/contrib/llvm/include/llvm/TableGen/StringToOffsetTable.h
@@ -27,6 +27,8 @@ class StringToOffsetTable {
std::string AggregateString;
public:
+ bool Empty() const { return StringOffset.empty(); }
+
unsigned GetOrAddStringOffset(StringRef Str, bool appendZero = true) {
auto IterBool =
StringOffset.insert(std::make_pair(Str, AggregateString.size()));
@@ -60,10 +62,10 @@ public:
if (AggregateString[i] != '\\')
continue;
- assert(i+1 < AggregateString.size() && "Incomplete escape sequence!");
- if (isdigit(AggregateString[i+1])) {
- assert(isdigit(AggregateString[i+2]) &&
- isdigit(AggregateString[i+3]) &&
+ assert(i + 1 < AggregateString.size() && "Incomplete escape sequence!");
+ if (isdigit(AggregateString[i + 1])) {
+ assert(isdigit(AggregateString[i + 2]) &&
+ isdigit(AggregateString[i + 3]) &&
"Expected 3 digit octal escape!");
O << AggregateString[++i];
O << AggregateString[++i];
diff --git a/contrib/llvm/include/llvm/Target/GenericOpcodes.td b/contrib/llvm/include/llvm/Target/GenericOpcodes.td
index 8694eb5..e35bcb0 100644
--- a/contrib/llvm/include/llvm/Target/GenericOpcodes.td
+++ b/contrib/llvm/include/llvm/Target/GenericOpcodes.td
@@ -49,6 +49,12 @@ def G_TRUNC : Instruction {
let hasSideEffects = 0;
}
+def G_IMPLICIT_DEF : Instruction {
+ let OutOperandList = (outs type0:$dst);
+ let InOperandList = (ins);
+ let hasSideEffects = 0;
+}
+
def G_FRAME_INDEX : Instruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins unknown:$src2);
@@ -91,6 +97,21 @@ def G_FCONSTANT : Instruction {
let hasSideEffects = 0;
}
+def G_VASTART : Instruction {
+ let OutOperandList = (outs);
+ let InOperandList = (ins type0:$list);
+ let hasSideEffects = 0;
+ let mayStore = 1;
+}
+
+def G_VAARG : Instruction {
+ let OutOperandList = (outs type0:$val);
+ let InOperandList = (ins type1:$list, unknown:$align);
+ let hasSideEffects = 0;
+ let mayLoad = 1;
+ let mayStore = 1;
+}
+
//------------------------------------------------------------------------------
// Binary ops.
//------------------------------------------------------------------------------
@@ -103,13 +124,6 @@ def G_ADD : Instruction {
let isCommutable = 1;
}
-// Generic pointer offset.
-def G_GEP : Instruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src1, type1:$src2);
- let hasSideEffects = 0;
-}
-
// Generic subtraction.
def G_SUB : Instruction {
let OutOperandList = (outs type0:$dst);
@@ -224,6 +238,19 @@ def G_SELECT : Instruction {
let hasSideEffects = 0;
}
+// Generic pointer offset.
+def G_GEP : Instruction {
+ let OutOperandList = (outs type0:$dst);
+ let InOperandList = (ins type0:$src1, type1:$src2);
+ let hasSideEffects = 0;
+}
+
+def G_PTR_MASK : Instruction {
+ let OutOperandList = (outs type0:$dst);
+ let InOperandList = (ins type0:$src, unknown:$bits);
+ let hasSideEffects = 0;
+}
+
//------------------------------------------------------------------------------
// Overflow ops
//------------------------------------------------------------------------------
@@ -273,10 +300,34 @@ def G_SMULO : Instruction {
let isCommutable = 1;
}
+// Multiply two numbers at twice the incoming bit width (unsigned) and return
+// the high half of the result.
+def G_UMULH : Instruction {
+ let OutOperandList = (outs type0:$dst);
+ let InOperandList = (ins type0:$src1, type0:$src2);
+ let hasSideEffects = 0;
+ let isCommutable = 1;
+}
+
+// Multiply two numbers at twice the incoming bit width (signed) and return
+// the high half of the result.
+def G_SMULH : Instruction {
+ let OutOperandList = (outs type0:$dst);
+ let InOperandList = (ins type0:$src1, type0:$src2);
+ let hasSideEffects = 0;
+ let isCommutable = 1;
+}
+
//------------------------------------------------------------------------------
// Floating Point Unary Ops.
//------------------------------------------------------------------------------
+def G_FNEG : Instruction {
+ let OutOperandList = (outs type0:$dst);
+ let InOperandList = (ins type0:$src);
+ let hasSideEffects = 0;
+}
+
def G_FPEXT : Instruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type1:$src);
@@ -341,6 +392,15 @@ def G_FMUL : Instruction {
let isCommutable = 1;
}
+// Generic fused multiply-add instruction.
+// Behaves like llvm fma intrinsic ie src1 * src2 + src3
+def G_FMA : Instruction {
+ let OutOperandList = (outs type0:$dst);
+ let InOperandList = (ins type0:$src1, type0:$src2, type0:$src3);
+ let hasSideEffects = 0;
+ let isCommutable = 0;
+}
+
// Generic FP division.
def G_FDIV : Instruction {
let OutOperandList = (outs type0:$dst);
@@ -355,6 +415,41 @@ def G_FREM : Instruction {
let hasSideEffects = 0;
}
+// Floating point exponentiation.
+def G_FPOW : Instruction {
+ let OutOperandList = (outs type0:$dst);
+ let InOperandList = (ins type0:$src1, type0:$src2);
+ let hasSideEffects = 0;
+}
+
+// Floating point base-e exponential of a value.
+def G_FEXP : Instruction {
+ let OutOperandList = (outs type0:$dst);
+ let InOperandList = (ins type0:$src1);
+ let hasSideEffects = 0;
+}
+
+// Floating point base-2 exponential of a value.
+def G_FEXP2 : Instruction {
+ let OutOperandList = (outs type0:$dst);
+ let InOperandList = (ins type0:$src1);
+ let hasSideEffects = 0;
+}
+
+// Floating point base-2 logarithm of a value.
+def G_FLOG : Instruction {
+ let OutOperandList = (outs type0:$dst);
+ let InOperandList = (ins type0:$src1);
+ let hasSideEffects = 0;
+}
+
+// Floating point base-2 logarithm of a value.
+def G_FLOG2 : Instruction {
+ let OutOperandList = (outs type0:$dst);
+ let InOperandList = (ins type0:$src1);
+ let hasSideEffects = 0;
+}
+
//------------------------------------------------------------------------------
// Memory ops
//------------------------------------------------------------------------------
@@ -383,24 +478,28 @@ def G_STORE : Instruction {
// indexes. This will almost certainly be mapped to sub-register COPYs after
// register banks have been selected.
def G_EXTRACT : Instruction {
+ let OutOperandList = (outs type0:$res);
+ let InOperandList = (ins type1:$src, unknown:$offset);
+ let hasSideEffects = 0;
+}
+
+// Extract multiple registers specified size, starting from blocks given by
+// indexes. This will almost certainly be mapped to sub-register COPYs after
+// register banks have been selected.
+def G_UNMERGE_VALUES : Instruction {
let OutOperandList = (outs);
let InOperandList = (ins variable_ops);
let hasSideEffects = 0;
}
-// Insert a sequence of smaller registers into a larger one at the specified
-// indices (interleaved with the values in the operand list "op0, bit0, op1,
-// bit1, ...")).
+// Insert a smaller register into a larger one at the specified bit-index.
def G_INSERT : Instruction {
let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src, variable_ops);
+ let InOperandList = (ins type0:$src, type1:$op, unknown:$offset);
let hasSideEffects = 0;
}
-// Combine a sequence of generic vregs into a single larger value (starting at
-// bit 0). Essentially a G_INSERT where $src is an IMPLICIT_DEF, but it's so
-// important to legalization it probably deserves its own instruction.
-def G_SEQUENCE : Instruction {
+def G_MERGE_VALUES : Instruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins variable_ops);
let hasSideEffects = 0;
@@ -445,4 +544,38 @@ def G_BRCOND : Instruction {
let isTerminator = 1;
}
+// Generic indirect branch.
+def G_BRINDIRECT : Instruction {
+ let OutOperandList = (outs);
+ let InOperandList = (ins type0:$src1);
+ let hasSideEffects = 0;
+ let isBranch = 1;
+ let isTerminator = 1;
+}
+
+//------------------------------------------------------------------------------
+// Vector ops
+//------------------------------------------------------------------------------
+
+// Generic insertelement.
+def G_INSERT_VECTOR_ELT : Instruction {
+ let OutOperandList = (outs type0:$dst);
+ let InOperandList = (ins type0:$src, type1:$elt, type2:$idx);
+ let hasSideEffects = 0;
+}
+
+// Generic extractelement.
+def G_EXTRACT_VECTOR_ELT : Instruction {
+ let OutOperandList = (outs type0:$dst);
+ let InOperandList = (ins type1:$src, type2:$idx);
+ let hasSideEffects = 0;
+}
+
+// Generic shufflevector.
+def G_SHUFFLE_VECTOR: Instruction {
+ let OutOperandList = (outs type0:$dst);
+ let InOperandList = (ins type1:$v1, type1:$v2, type2:$mask);
+ let hasSideEffects = 0;
+}
+
// TODO: Add the other generic opcodes.
diff --git a/contrib/llvm/include/llvm/Target/GlobalISel/RegisterBank.td b/contrib/llvm/include/llvm/Target/GlobalISel/RegisterBank.td
new file mode 100644
index 0000000..4dfd139
--- /dev/null
+++ b/contrib/llvm/include/llvm/Target/GlobalISel/RegisterBank.td
@@ -0,0 +1,16 @@
+//===- RegisterBank.td - Register bank definitions ---------*- tablegen -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//
+//===----------------------------------------------------------------------===//
+
+class RegisterBank<string name, list<RegisterClass> classes> {
+ string Name = name;
+ list<RegisterClass> RegisterClasses = classes;
+}
diff --git a/contrib/llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td b/contrib/llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td
new file mode 100644
index 0000000..50de41f
--- /dev/null
+++ b/contrib/llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td
@@ -0,0 +1,75 @@
+//===- TargetGlobalISel.td - Common code for GlobalISel ----*- tablegen -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the target-independent interfaces used to support
+// SelectionDAG instruction selection patterns (specified in
+// TargetSelectionDAG.td) when generating GlobalISel instruction selectors.
+//
+// This is intended as a compatibility layer, to enable reuse of target
+// descriptions written for SelectionDAG without requiring explicit GlobalISel
+// support. It will eventually supersede SelectionDAG patterns.
+//
+//===----------------------------------------------------------------------===//
+
+// Declare that a generic Instruction is 'equivalent' to an SDNode, that is,
+// SelectionDAG patterns involving the SDNode can be transformed to match the
+// Instruction instead.
+class GINodeEquiv<Instruction i, SDNode node> {
+ Instruction I = i;
+ SDNode Node = node;
+}
+
+// These are defined in the same order as the G_* instructions.
+def : GINodeEquiv<G_ANYEXT, anyext>;
+def : GINodeEquiv<G_SEXT, sext>;
+def : GINodeEquiv<G_ZEXT, zext>;
+def : GINodeEquiv<G_TRUNC, trunc>;
+def : GINodeEquiv<G_BITCAST, bitconvert>;
+// G_INTTOPTR - SelectionDAG has no equivalent.
+// G_PTRTOINT - SelectionDAG has no equivalent.
+// G_CONSTANT - Not needed since constants aren't operators.
+// G_FCONSTANT - Not needed since constants aren't operators.
+def : GINodeEquiv<G_ADD, add>;
+def : GINodeEquiv<G_SUB, sub>;
+def : GINodeEquiv<G_MUL, mul>;
+def : GINodeEquiv<G_SDIV, sdiv>;
+def : GINodeEquiv<G_UDIV, udiv>;
+def : GINodeEquiv<G_SREM, srem>;
+def : GINodeEquiv<G_UREM, urem>;
+def : GINodeEquiv<G_AND, and>;
+def : GINodeEquiv<G_OR, or>;
+def : GINodeEquiv<G_XOR, xor>;
+def : GINodeEquiv<G_SHL, shl>;
+def : GINodeEquiv<G_LSHR, srl>;
+def : GINodeEquiv<G_ASHR, sra>;
+def : GINodeEquiv<G_SELECT, select>;
+def : GINodeEquiv<G_FNEG, fneg>;
+def : GINodeEquiv<G_FPEXT, fpextend>;
+def : GINodeEquiv<G_FPTRUNC, ftrunc>;
+def : GINodeEquiv<G_FPTOSI, fp_to_sint>;
+def : GINodeEquiv<G_FPTOUI, fp_to_uint>;
+def : GINodeEquiv<G_SITOFP, sint_to_fp>;
+def : GINodeEquiv<G_UITOFP, uint_to_fp>;
+def : GINodeEquiv<G_FADD, fadd>;
+def : GINodeEquiv<G_FSUB, fsub>;
+def : GINodeEquiv<G_FMA, fma>;
+def : GINodeEquiv<G_FMUL, fmul>;
+def : GINodeEquiv<G_FDIV, fdiv>;
+def : GINodeEquiv<G_FREM, frem>;
+def : GINodeEquiv<G_FPOW, fpow>;
+def : GINodeEquiv<G_FEXP2, fexp2>;
+def : GINodeEquiv<G_FLOG2, flog2>;
+def : GINodeEquiv<G_INTRINSIC, intrinsic_wo_chain>;
+def : GINodeEquiv<G_BR, br>;
+
+// Specifies the GlobalISel equivalents for SelectionDAG's ComplexPattern.
+// Should be used on defs that subclass GIComplexOperandMatcher<>.
+class GIComplexPatternEquiv<ComplexPattern seldag> {
+ ComplexPattern SelDAGEquivalent = seldag;
+}
diff --git a/contrib/llvm/include/llvm/Target/GlobalISel/Target.td b/contrib/llvm/include/llvm/Target/GlobalISel/Target.td
new file mode 100644
index 0000000..fd2ebca
--- /dev/null
+++ b/contrib/llvm/include/llvm/Target/GlobalISel/Target.td
@@ -0,0 +1,48 @@
+//===- Target.td - Define GlobalISel rules -----------------*- tablegen -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the target-independent interfaces used to support
+// SelectionDAG instruction selection patterns (specified in
+// TargetSelectionDAG.td) when generating GlobalISel instruction selectors.
+//
+// This is intended as a compatibility layer, to enable reuse of target
+// descriptions written for SelectionDAG without requiring explicit GlobalISel
+// support. It will eventually supersede SelectionDAG patterns.
+//
+//===----------------------------------------------------------------------===//
+
+// Definitions that inherit from LLT define types that will be used in the
+// GlobalISel matcher.
+class LLT;
+
+def s32 : LLT;
+def s64 : LLT;
+
+// Defines a matcher for complex operands. This is analogous to ComplexPattern
+// from SelectionDAG.
+//
+// Definitions that inherit from this may also inherit from
+// GIComplexPatternEquiv to enable the import of SelectionDAG patterns involving
+// those ComplexPatterns.
+class GIComplexOperandMatcher<LLT type, string matcherfn> {
+ // The expected type of the root of the match.
+ //
+ // TODO: We should probably support, any-type, any-scalar, and multiple types
+ // in the future.
+ LLT Type = type;
+
+ // 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.
+ string MatcherFn = matcherfn;
+}
diff --git a/contrib/llvm/include/llvm/Target/Target.td b/contrib/llvm/include/llvm/Target/Target.td
index 729d766..6f44292 100644
--- a/contrib/llvm/include/llvm/Target/Target.td
+++ b/contrib/llvm/include/llvm/Target/Target.td
@@ -402,11 +402,8 @@ class Instruction {
// If so, make sure to override
// TargetInstrInfo::getInsertSubregLikeInputs.
- // Side effect flags - When set, the flags have these meanings:
- //
- // hasSideEffects - The instruction has side effects that are not
- // captured by any operands of the instruction or other flags.
- //
+ // Does the instruction have side effects that are not captured by any
+ // operands of the instruction or other flags?
bit hasSideEffects = ?;
// Is this instruction a "real" instruction (with a distinct machine
@@ -533,6 +530,12 @@ class Predicate<string cond> {
/// PredicateName - User-level name to use for the predicate. Mainly for use
/// in diagnostics such as missing feature errors in the asm matcher.
string PredicateName = "";
+
+ /// Setting this to '1' indicates that the predicate must be recomputed on
+ /// every function change. Most predicates can leave this at '0'.
+ ///
+ /// Ignored by SelectionDAG, it always recomputes the predicate on every use.
+ bit RecomputePerFunction = 0;
}
/// NoHonorSignDependentRounding - This predicate is true if support for
@@ -677,6 +680,11 @@ class RegisterOperand<RegisterClass regclass, string pm = "printOperand">
// this type. The method normally will just use an alt-name index to look
// up the name to print. Default to the generic printOperand().
string PrintMethod = pm;
+
+ // EncoderMethod - The target method name to call to encode this register
+ // operand.
+ string EncoderMethod = "";
+
// ParserMatchClass - The "match class" that operands of this type fit
// in. Match classes are used to define the order in which instructions are
// match, to ensure that which instructions gets matched is deterministic.
@@ -951,11 +959,12 @@ def LOCAL_ESCAPE : Instruction {
let hasSideEffects = 0;
let hasCtrlDep = 1;
}
-def FAULTING_LOAD_OP : Instruction {
+def FAULTING_OP : Instruction {
let OutOperandList = (outs unknown:$dst);
let InOperandList = (ins variable_ops);
let usesCustomInserter = 1;
let mayLoad = 1;
+ let mayStore = 1;
let isTerminator = 1;
let isBranch = 1;
}
@@ -998,6 +1007,25 @@ def PATCHABLE_TAIL_CALL : Instruction {
let hasSideEffects = 1;
let isReturn = 1;
}
+def PATCHABLE_EVENT_CALL : Instruction {
+ let OutOperandList = (outs);
+ let InOperandList = (ins ptr_rc:$event, i8imm:$size);
+ let AsmString = "# XRay Custom Event Log.";
+ let usesCustomInserter = 1;
+ let isCall = 1;
+ let mayLoad = 1;
+ let mayStore = 1;
+ let hasSideEffects = 1;
+}
+def FENTRY_CALL : Instruction {
+ let OutOperandList = (outs unknown:$dst);
+ let InOperandList = (ins variable_ops);
+ let AsmString = "# FEntry call";
+ let usesCustomInserter = 1;
+ let mayLoad = 1;
+ let mayStore = 1;
+ let hasSideEffects = 1;
+}
// Generic opcodes used in GlobalISel.
include "llvm/Target/GenericOpcodes.td"
@@ -1342,6 +1370,16 @@ include "llvm/Target/TargetCallingConv.td"
include "llvm/Target/TargetSelectionDAG.td"
//===----------------------------------------------------------------------===//
-// Pull in the common support for Global ISel generation.
+// Pull in the common support for Global ISel register bank info generation.
+//
+include "llvm/Target/GlobalISel/RegisterBank.td"
+
+//===----------------------------------------------------------------------===//
+// Pull in the common support for DAG isel generation.
+//
+include "llvm/Target/GlobalISel/Target.td"
+
+//===----------------------------------------------------------------------===//
+// Pull in the common support for the Global ISel DAG-based selector generation.
//
-include "llvm/Target/TargetGlobalISel.td"
+include "llvm/Target/GlobalISel/SelectionDAGCompat.td"
diff --git a/contrib/llvm/include/llvm/Target/TargetCallingConv.h b/contrib/llvm/include/llvm/Target/TargetCallingConv.h
index be09236..4f750b8 100644
--- a/contrib/llvm/include/llvm/Target/TargetCallingConv.h
+++ b/contrib/llvm/include/llvm/Target/TargetCallingConv.h
@@ -14,146 +14,120 @@
#ifndef LLVM_TARGET_TARGETCALLINGCONV_H
#define LLVM_TARGET_TARGETCALLINGCONV_H
+#include "llvm/CodeGen/MachineValueType.h"
#include "llvm/CodeGen/ValueTypes.h"
-#include "llvm/Support/DataTypes.h"
#include "llvm/Support/MathExtras.h"
+#include <cassert>
#include <climits>
+#include <cstdint>
namespace llvm {
-
namespace ISD {
+
struct ArgFlagsTy {
private:
- static const uint64_t NoFlagSet = 0ULL;
- static const uint64_t ZExt = 1ULL<<0; ///< Zero extended
- static const uint64_t ZExtOffs = 0;
- static const uint64_t SExt = 1ULL<<1; ///< Sign extended
- static const uint64_t SExtOffs = 1;
- static const uint64_t InReg = 1ULL<<2; ///< Passed in register
- static const uint64_t InRegOffs = 2;
- static const uint64_t SRet = 1ULL<<3; ///< Hidden struct-ret ptr
- static const uint64_t SRetOffs = 3;
- static const uint64_t ByVal = 1ULL<<4; ///< Struct passed by value
- static const uint64_t ByValOffs = 4;
- static const uint64_t Nest = 1ULL<<5; ///< Nested fn static chain
- static const uint64_t NestOffs = 5;
- static const uint64_t Returned = 1ULL<<6; ///< Always returned
- static const uint64_t ReturnedOffs = 6;
- static const uint64_t ByValAlign = 0xFULL<<7; ///< Struct alignment
- static const uint64_t ByValAlignOffs = 7;
- static const uint64_t Split = 1ULL<<11;
- static const uint64_t SplitOffs = 11;
- static const uint64_t InAlloca = 1ULL<<12; ///< Passed with inalloca
- static const uint64_t InAllocaOffs = 12;
- static const uint64_t SplitEnd = 1ULL<<13; ///< Last part of a split
- static const uint64_t SplitEndOffs = 13;
- static const uint64_t SwiftSelf = 1ULL<<14; ///< Swift self parameter
- static const uint64_t SwiftSelfOffs = 14;
- static const uint64_t SwiftError = 1ULL<<15; ///< Swift error parameter
- static const uint64_t SwiftErrorOffs = 15;
- static const uint64_t Hva = 1ULL << 16; ///< HVA field for
- ///< vectorcall
- static const uint64_t HvaOffs = 16;
- static const uint64_t HvaStart = 1ULL << 17; ///< HVA structure start
- ///< for vectorcall
- static const uint64_t HvaStartOffs = 17;
- static const uint64_t SecArgPass = 1ULL << 18; ///< Second argument
- ///< pass for vectorcall
- static const uint64_t SecArgPassOffs = 18;
- static const uint64_t OrigAlign = 0x1FULL<<27;
- static const uint64_t OrigAlignOffs = 27;
- static const uint64_t ByValSize = 0x3fffffffULL<<32; ///< Struct size
- static const uint64_t ByValSizeOffs = 32;
- static const uint64_t InConsecutiveRegsLast = 0x1ULL<<62; ///< Struct size
- static const uint64_t InConsecutiveRegsLastOffs = 62;
- static const uint64_t InConsecutiveRegs = 0x1ULL<<63; ///< Struct size
- static const uint64_t InConsecutiveRegsOffs = 63;
-
- static const uint64_t One = 1ULL; ///< 1 of this type, for shifts
-
- uint64_t Flags;
+ unsigned IsZExt : 1; ///< Zero extended
+ unsigned IsSExt : 1; ///< Sign extended
+ unsigned IsInReg : 1; ///< Passed in register
+ unsigned IsSRet : 1; ///< Hidden struct-ret ptr
+ unsigned IsByVal : 1; ///< Struct passed by value
+ unsigned IsNest : 1; ///< Nested fn static chain
+ unsigned IsReturned : 1; ///< Always returned
+ unsigned IsSplit : 1;
+ unsigned IsInAlloca : 1; ///< Passed with inalloca
+ unsigned IsSplitEnd : 1; ///< Last part of a split
+ unsigned IsSwiftSelf : 1; ///< Swift self parameter
+ unsigned IsSwiftError : 1; ///< Swift error parameter
+ unsigned IsHva : 1; ///< HVA field for
+ unsigned IsHvaStart : 1; ///< HVA structure start
+ unsigned IsSecArgPass : 1; ///< Second argument
+ unsigned ByValAlign : 4; ///< Log 2 of byval alignment
+ unsigned OrigAlign : 5; ///< Log 2 of original alignment
+ unsigned IsInConsecutiveRegsLast : 1;
+ unsigned IsInConsecutiveRegs : 1;
+ unsigned IsCopyElisionCandidate : 1; ///< Argument copy elision candidate
+
+ unsigned ByValSize; ///< Byval struct size
public:
- ArgFlagsTy() : Flags(0) { }
+ 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), IsHva(0), IsHvaStart(0),
+ IsSecArgPass(0), ByValAlign(0), OrigAlign(0),
+ IsInConsecutiveRegsLast(0), IsInConsecutiveRegs(0),
+ IsCopyElisionCandidate(0), ByValSize(0) {
+ static_assert(sizeof(*this) == 2 * sizeof(unsigned), "flags are too big");
+ }
- bool isZExt() const { return Flags & ZExt; }
- void setZExt() { Flags |= One << ZExtOffs; }
+ bool isZExt() const { return IsZExt; }
+ void setZExt() { IsZExt = 1; }
- bool isSExt() const { return Flags & SExt; }
- void setSExt() { Flags |= One << SExtOffs; }
+ bool isSExt() const { return IsSExt; }
+ void setSExt() { IsSExt = 1; }
- bool isInReg() const { return Flags & InReg; }
- void setInReg() { Flags |= One << InRegOffs; }
+ bool isInReg() const { return IsInReg; }
+ void setInReg() { IsInReg = 1; }
- bool isSRet() const { return Flags & SRet; }
- void setSRet() { Flags |= One << SRetOffs; }
+ bool isSRet() const { return IsSRet; }
+ void setSRet() { IsSRet = 1; }
- bool isByVal() const { return Flags & ByVal; }
- void setByVal() { Flags |= One << ByValOffs; }
+ bool isByVal() const { return IsByVal; }
+ void setByVal() { IsByVal = 1; }
- bool isInAlloca() const { return Flags & InAlloca; }
- void setInAlloca() { Flags |= One << InAllocaOffs; }
+ bool isInAlloca() const { return IsInAlloca; }
+ void setInAlloca() { IsInAlloca = 1; }
- bool isSwiftSelf() const { return Flags & SwiftSelf; }
- void setSwiftSelf() { Flags |= One << SwiftSelfOffs; }
+ bool isSwiftSelf() const { return IsSwiftSelf; }
+ void setSwiftSelf() { IsSwiftSelf = 1; }
- bool isSwiftError() const { return Flags & SwiftError; }
- void setSwiftError() { Flags |= One << SwiftErrorOffs; }
+ bool isSwiftError() const { return IsSwiftError; }
+ void setSwiftError() { IsSwiftError = 1; }
- bool isHva() const { return Flags & Hva; }
- void setHva() { Flags |= One << HvaOffs; }
+ bool isHva() const { return IsHva; }
+ void setHva() { IsHva = 1; }
- bool isHvaStart() const { return Flags & HvaStart; }
- void setHvaStart() { Flags |= One << HvaStartOffs; }
+ bool isHvaStart() const { return IsHvaStart; }
+ void setHvaStart() { IsHvaStart = 1; }
- bool isSecArgPass() const { return Flags & SecArgPass; }
- void setSecArgPass() { Flags |= One << SecArgPassOffs; }
+ bool isSecArgPass() const { return IsSecArgPass; }
+ void setSecArgPass() { IsSecArgPass = 1; }
- bool isNest() const { return Flags & Nest; }
- void setNest() { Flags |= One << NestOffs; }
+ bool isNest() const { return IsNest; }
+ void setNest() { IsNest = 1; }
- bool isReturned() const { return Flags & Returned; }
- void setReturned() { Flags |= One << ReturnedOffs; }
+ bool isReturned() const { return IsReturned; }
+ void setReturned() { IsReturned = 1; }
- bool isInConsecutiveRegs() const { return Flags & InConsecutiveRegs; }
- void setInConsecutiveRegs() { Flags |= One << InConsecutiveRegsOffs; }
+ bool isInConsecutiveRegs() const { return IsInConsecutiveRegs; }
+ void setInConsecutiveRegs() { IsInConsecutiveRegs = 1; }
- bool isInConsecutiveRegsLast() const { return Flags & InConsecutiveRegsLast; }
- void setInConsecutiveRegsLast() { Flags |= One << InConsecutiveRegsLastOffs; }
+ bool isInConsecutiveRegsLast() const { return IsInConsecutiveRegsLast; }
+ void setInConsecutiveRegsLast() { IsInConsecutiveRegsLast = 1; }
- unsigned getByValAlign() const {
- return (unsigned)
- ((One << ((Flags & ByValAlign) >> ByValAlignOffs)) / 2);
- }
- void setByValAlign(unsigned A) {
- Flags = (Flags & ~ByValAlign) |
- (uint64_t(Log2_32(A) + 1) << ByValAlignOffs);
- }
+ bool isSplit() const { return IsSplit; }
+ void setSplit() { IsSplit = 1; }
- bool isSplit() const { return Flags & Split; }
- void setSplit() { Flags |= One << SplitOffs; }
+ bool isSplitEnd() const { return IsSplitEnd; }
+ void setSplitEnd() { IsSplitEnd = 1; }
- bool isSplitEnd() const { return Flags & SplitEnd; }
- void setSplitEnd() { Flags |= One << SplitEndOffs; }
+ bool isCopyElisionCandidate() const { return IsCopyElisionCandidate; }
+ void setCopyElisionCandidate() { IsCopyElisionCandidate = 1; }
- unsigned getOrigAlign() const {
- return (unsigned)
- ((One << ((Flags & OrigAlign) >> OrigAlignOffs)) / 2);
- }
- void setOrigAlign(unsigned A) {
- Flags = (Flags & ~OrigAlign) |
- (uint64_t(Log2_32(A) + 1) << OrigAlignOffs);
+ unsigned getByValAlign() const { return (1U << ByValAlign) / 2; }
+ void setByValAlign(unsigned A) {
+ ByValAlign = Log2_32(A) + 1;
+ assert(getByValAlign() == A && "bitfield overflow");
}
- unsigned getByValSize() const {
- return (unsigned)((Flags & ByValSize) >> ByValSizeOffs);
- }
- void setByValSize(unsigned S) {
- Flags = (Flags & ~ByValSize) | (uint64_t(S) << ByValSizeOffs);
+ unsigned getOrigAlign() const { return (1U << OrigAlign) / 2; }
+ void setOrigAlign(unsigned A) {
+ OrigAlign = Log2_32(A) + 1;
+ assert(getOrigAlign() == A && "bitfield overflow");
}
- /// getRawBits - Represent the flags as a bunch of bits.
- uint64_t getRawBits() const { return Flags; }
+ unsigned getByValSize() const { return ByValSize; }
+ void setByValSize(unsigned S) { ByValSize = S; }
};
/// InputArg - This struct carries flags and type information about a
@@ -162,9 +136,9 @@ namespace ISD {
///
struct InputArg {
ArgFlagsTy Flags;
- MVT VT;
+ MVT VT = MVT::Other;
EVT ArgVT;
- bool Used;
+ bool Used = false;
/// Index original Function's argument.
unsigned OrigArgIndex;
@@ -176,7 +150,7 @@ namespace ISD {
/// registers, we got 4 InputArgs with PartOffsets 0, 4, 8 and 12.
unsigned PartOffset;
- InputArg() : VT(MVT::Other), Used(false) {}
+ InputArg() = default;
InputArg(ArgFlagsTy flags, EVT vt, EVT argvt, bool used,
unsigned origIdx, unsigned partOffs)
: Flags(flags), Used(used), OrigArgIndex(origIdx), PartOffset(partOffs) {
@@ -204,7 +178,7 @@ namespace ISD {
EVT ArgVT;
/// IsFixed - Is this a "fixed" value, ie not passed through a vararg "...".
- bool IsFixed;
+ bool IsFixed = false;
/// Index original Function's argument.
unsigned OrigArgIndex;
@@ -214,7 +188,7 @@ namespace ISD {
/// registers, we got 4 OutputArgs with PartOffsets 0, 4, 8 and 12.
unsigned PartOffset;
- OutputArg() : IsFixed(false) {}
+ OutputArg() = default;
OutputArg(ArgFlagsTy flags, EVT vt, EVT argvt, bool isfixed,
unsigned origIdx, unsigned partOffs)
: Flags(flags), IsFixed(isfixed), OrigArgIndex(origIdx),
@@ -223,8 +197,8 @@ namespace ISD {
ArgVT = argvt;
}
};
-} // end namespace ISD
-} // end llvm namespace
+} // end namespace ISD
+} // end namespace llvm
#endif // LLVM_TARGET_TARGETCALLINGCONV_H
diff --git a/contrib/llvm/include/llvm/Target/TargetGlobalISel.td b/contrib/llvm/include/llvm/Target/TargetGlobalISel.td
deleted file mode 100644
index 0727c98..0000000
--- a/contrib/llvm/include/llvm/Target/TargetGlobalISel.td
+++ /dev/null
@@ -1,29 +0,0 @@
-//===- TargetGlobalISel.td - Common code for GlobalISel ----*- tablegen -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the target-independent interfaces used to support
-// SelectionDAG instruction selection patterns (specified in
-// TargetSelectionDAG.td) when generating GlobalISel instruction selectors.
-//
-// This is intended as a compatibility layer, to enable reuse of target
-// descriptions written for SelectionDAG without requiring explicit GlobalISel
-// support. It will eventually supersede SelectionDAG patterns.
-//
-//===----------------------------------------------------------------------===//
-
-// Declare that a generic Instruction is 'equivalent' to an SDNode, that is,
-// SelectionDAG patterns involving the SDNode can be transformed to match the
-// Instruction instead.
-class GINodeEquiv<Instruction i, SDNode node> {
- Instruction I = i;
- SDNode Node = node;
-}
-
-def : GINodeEquiv<G_ADD, add>;
-def : GINodeEquiv<G_BR, br>;
diff --git a/contrib/llvm/include/llvm/Target/TargetInstrInfo.h b/contrib/llvm/include/llvm/Target/TargetInstrInfo.h
index 247d694..1843a2e 100644
--- a/contrib/llvm/include/llvm/Target/TargetInstrInfo.h
+++ b/contrib/llvm/include/llvm/Target/TargetInstrInfo.h
@@ -1,4 +1,4 @@
-//===-- llvm/Target/TargetInstrInfo.h - Instruction Info --------*- C++ -*-===//
+//===- llvm/Target/TargetInstrInfo.h - Instruction Info ---------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,36 +14,46 @@
#ifndef LLVM_TARGET_TARGETINSTRINFO_H
#define LLVM_TARGET_TARGETINSTRINFO_H
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/DenseMapInfo.h"
+#include "llvm/ADT/None.h"
+#include "llvm/CodeGen/LiveIntervalAnalysis.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineCombinerPattern.h"
#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineLoopInfo.h"
+#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/Support/BranchProbability.h"
-#include "llvm/Target/TargetRegisterInfo.h"
-#include "llvm/CodeGen/LiveIntervalAnalysis.h"
+#include "llvm/Support/ErrorHandling.h"
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
+#include <utility>
+#include <vector>
namespace llvm {
+class DFAPacketizer;
class InstrItineraryData;
class LiveVariables;
-class MCAsmInfo;
class MachineMemOperand;
class MachineRegisterInfo;
-class MDNode;
+class MCAsmInfo;
class MCInst;
struct MCSchedModel;
-class MCSymbolRefExpr;
-class SDNode;
+class Module;
+class ScheduleDAG;
class ScheduleHazardRecognizer;
+class SDNode;
class SelectionDAG;
-class ScheduleDAG;
+class RegScavenger;
class TargetRegisterClass;
class TargetRegisterInfo;
-class TargetSubtargetInfo;
class TargetSchedModel;
-class DFAPacketizer;
+class TargetSubtargetInfo;
template<class T> class SmallVectorImpl;
@@ -52,8 +62,6 @@ template<class T> class SmallVectorImpl;
/// TargetInstrInfo - Interface to description of machine instruction set
///
class TargetInstrInfo : public MCInstrInfo {
- TargetInstrInfo(const TargetInstrInfo &) = delete;
- void operator=(const TargetInstrInfo &) = delete;
public:
TargetInstrInfo(unsigned CFSetupOpcode = ~0u, unsigned CFDestroyOpcode = ~0u,
unsigned CatchRetOpcode = ~0u, unsigned ReturnOpcode = ~0u)
@@ -61,7 +69,8 @@ public:
CallFrameDestroyOpcode(CFDestroyOpcode),
CatchRetOpcode(CatchRetOpcode),
ReturnOpcode(ReturnOpcode) {}
-
+ TargetInstrInfo(const TargetInstrInfo &) = delete;
+ TargetInstrInfo &operator=(const TargetInstrInfo &) = delete;
virtual ~TargetInstrInfo();
static bool isGenericOpcode(unsigned Opc) {
@@ -152,6 +161,42 @@ public:
unsigned getCallFrameSetupOpcode() const { return CallFrameSetupOpcode; }
unsigned getCallFrameDestroyOpcode() const { return CallFrameDestroyOpcode; }
+ /// Returns true if the argument is a frame pseudo instruction.
+ bool isFrameInstr(const MachineInstr &I) const {
+ return I.getOpcode() == getCallFrameSetupOpcode() ||
+ I.getOpcode() == getCallFrameDestroyOpcode();
+ }
+
+ /// Returns true if the argument is a frame setup pseudo instruction.
+ bool isFrameSetup(const MachineInstr &I) const {
+ return I.getOpcode() == getCallFrameSetupOpcode();
+ }
+
+ /// Returns size of the frame associated with the given frame instruction.
+ /// For frame setup instruction this is frame that is set up space set up
+ /// after the instruction. For frame destroy instruction this is the frame
+ /// freed by the caller.
+ /// Note, in some cases a call frame (or a part of it) may be prepared prior
+ /// to the frame setup instruction. It occurs in the calls that involve
+ /// inalloca arguments. This function reports only the size of the frame part
+ /// that is set up between the frame setup and destroy pseudo instructions.
+ int64_t getFrameSize(const MachineInstr &I) const {
+ assert(isFrameInstr(I) && "Not a frame instruction");
+ assert(I.getOperand(0).getImm() >= 0);
+ return I.getOperand(0).getImm();
+ }
+
+ /// Returns the total frame size, which is made up of the space set up inside
+ /// the pair of frame start-stop instructions and the space that is set up
+ /// prior to the pair.
+ int64_t getFrameTotalSize(const MachineInstr &I) const {
+ if (isFrameSetup(I)) {
+ assert(I.getOperand(1).getImm() >= 0 && "Frame size must not be negative");
+ return getFrameSize(I) + I.getOperand(1).getImm();
+ }
+ return getFrameSize(I);
+ }
+
unsigned getCatchReturnOpcode() const { return CatchRetOpcode; }
unsigned getReturnOpcode() const { return ReturnOpcode; }
@@ -360,14 +405,17 @@ public:
struct RegSubRegPair {
unsigned Reg;
unsigned SubReg;
+
RegSubRegPair(unsigned Reg = 0, unsigned SubReg = 0)
: Reg(Reg), SubReg(SubReg) {}
};
+
/// A pair composed of a pair of a register and a sub-register index,
/// and another sub-register index.
/// Used to give some type checking when modeling Reg:SubReg1, SubReg2.
struct RegSubRegPairAndIdx : RegSubRegPair {
unsigned SubIdx;
+
RegSubRegPairAndIdx(unsigned Reg = 0, unsigned SubReg = 0,
unsigned SubIdx = 0)
: RegSubRegPair(Reg, SubReg), SubIdx(SubIdx) {}
@@ -433,7 +481,6 @@ public:
RegSubRegPair &BaseReg,
RegSubRegPairAndIdx &InsertedReg) const;
-
/// Return true if two machine instructions would produce identical values.
/// By default, this is only true when the two instructions
/// are deemed identical except for defs. If this function is called when the
@@ -515,23 +562,19 @@ public:
PRED_INVALID // Sentinel value
};
- ComparePredicate Predicate;
- MachineOperand LHS;
- MachineOperand RHS;
- MachineBasicBlock *TrueDest;
- MachineBasicBlock *FalseDest;
- MachineInstr *ConditionDef;
+ ComparePredicate Predicate = PRED_INVALID;
+ MachineOperand LHS = MachineOperand::CreateImm(0);
+ MachineOperand RHS = MachineOperand::CreateImm(0);
+ MachineBasicBlock *TrueDest = nullptr;
+ MachineBasicBlock *FalseDest = nullptr;
+ MachineInstr *ConditionDef = nullptr;
/// SingleUseCondition is true if ConditionDef is dead except for the
/// branch(es) at the end of the basic block.
///
- bool SingleUseCondition;
+ bool SingleUseCondition = false;
- explicit MachineBranchPredicate()
- : Predicate(PRED_INVALID), LHS(MachineOperand::CreateImm(0)),
- RHS(MachineOperand::CreateImm(0)), TrueDest(nullptr),
- FalseDest(nullptr), ConditionDef(nullptr), SingleUseCondition(false) {
- }
+ explicit MachineBranchPredicate() = default;
};
/// Analyze the branching code at the end of MBB and parse it into the
@@ -1070,15 +1113,6 @@ public:
llvm_unreachable("target did not implement shouldClusterMemOps()");
}
- /// Can this target fuse the given instructions if they are scheduled
- /// adjacent. Note that you have to add:
- /// DAG.addMutation(createMacroFusionDAGMutation());
- /// to TargetPassConfig::createMachineScheduler() to have an effect.
- virtual bool shouldScheduleAdjacent(const MachineInstr &First,
- const MachineInstr &Second) const {
- llvm_unreachable("target did not implement shouldScheduleAdjacent()");
- }
-
/// Reverses the branch condition of the specified condition list,
/// returning false on success and true if it cannot be reversed.
virtual
@@ -1090,9 +1124,8 @@ public:
virtual void insertNoop(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI) const;
-
/// Return the noop instruction to use for a noop.
- virtual void getNoopForMachoTarget(MCInst &NopInst) const;
+ virtual void getNoop(MCInst &NopInst) const;
/// Return true for post-incremented instructions.
virtual bool isPostIncrement(const MachineInstr &MI) const {
@@ -1108,6 +1141,25 @@ public:
/// terminator instruction that has not been predicated.
virtual bool isUnpredicatedTerminator(const MachineInstr &MI) const;
+ /// Returns true if MI is an unconditional tail call.
+ virtual bool isUnconditionalTailCall(const MachineInstr &MI) const {
+ return false;
+ }
+
+ /// Returns true if the tail call can be made conditional on BranchCond.
+ virtual bool
+ canMakeTailCallConditional(SmallVectorImpl<MachineOperand> &Cond,
+ const MachineInstr &TailCall) const {
+ return false;
+ }
+
+ /// Replace the conditional branch in MBB with a conditional tail call.
+ virtual void replaceBranchWithTailCall(MachineBasicBlock &MBB,
+ SmallVectorImpl<MachineOperand> &Cond,
+ const MachineInstr &TailCall) const {
+ llvm_unreachable("Target didn't implement replaceBranchWithTailCall!");
+ }
+
/// Convert the instruction into a predicated instruction.
/// It returns true if the operation was successful.
virtual bool PredicateInstruction(MachineInstr &MI,
@@ -1132,7 +1184,7 @@ public:
/// Return true if the specified instruction can be predicated.
/// By default, this returns true for every instruction with a
/// PredicateOperand.
- virtual bool isPredicable(MachineInstr &MI) const {
+ virtual bool isPredicable(const MachineInstr &MI) const {
return MI.getDesc().isPredicable();
}
@@ -1427,10 +1479,17 @@ public:
return nullptr;
}
- // Sometimes, it is possible for the target
- // to tell, even without aliasing information, that two MIs access different
- // memory addresses. This function returns true if two MIs access different
- // memory addresses and false otherwise.
+ /// Sometimes, it is possible for the target
+ /// to tell, even without aliasing information, that two MIs access different
+ /// memory addresses. This function returns true if two MIs access different
+ /// memory addresses and false otherwise.
+ ///
+ /// Assumes any physical registers used to compute addresses have the same
+ /// value for both instructions. (This is the most useful assumption for
+ /// post-RA scheduling.)
+ ///
+ /// See also MachineInstr::mayAlias, which is implemented on top of this
+ /// function.
virtual bool
areMemAccessesTriviallyDisjoint(MachineInstr &MIa, MachineInstr &MIb,
AliasAnalysis *AA = nullptr) const {
@@ -1486,11 +1545,89 @@ public:
return None;
}
- /// Determines whether |Inst| is a tail call instruction.
+ /// Return an array that contains the MMO target flag values and their
+ /// names.
+ ///
+ /// MIR Serialization is able to serialize only the MMO target flags that are
+ /// defined by this method.
+ virtual ArrayRef<std::pair<MachineMemOperand::Flags, const char *>>
+ getSerializableMachineMemOperandTargetFlags() const {
+ return None;
+ }
+
+ /// Determines whether \p Inst is a tail call instruction. Override this
+ /// method on targets that do not properly set MCID::Return and MCID::Call on
+ /// tail call instructions."
virtual bool isTailCall(const MachineInstr &Inst) const {
+ return Inst.isReturn() && Inst.isCall();
+ }
+
+ /// True if the instruction is bound to the top of its basic block and no
+ /// other instructions shall be inserted before it. This can be implemented
+ /// to prevent register allocator to insert spills before such instructions.
+ virtual bool isBasicBlockPrologue(const MachineInstr &MI) const {
return false;
}
+ /// \brief Return how many instructions would be saved by outlining a
+ /// sequence containing \p SequenceSize instructions that appears
+ /// \p Occurrences times in a module.
+ virtual unsigned getOutliningBenefit(size_t SequenceSize, size_t Occurrences,
+ bool CanBeTailCall) const {
+ llvm_unreachable(
+ "Target didn't implement TargetInstrInfo::getOutliningBenefit!");
+ }
+
+ /// Represents how an instruction should be mapped by the outliner.
+ /// \p Legal instructions are those which are safe to outline.
+ /// \p Illegal instructions are those which cannot be outlined.
+ /// \p Invisible instructions are instructions which can be outlined, but
+ /// shouldn't actually impact the outlining result.
+ enum MachineOutlinerInstrType {Legal, Illegal, Invisible};
+
+ /// Returns how or if \p MI should be outlined.
+ virtual MachineOutlinerInstrType getOutliningType(MachineInstr &MI) const {
+ llvm_unreachable(
+ "Target didn't implement TargetInstrInfo::getOutliningType!");
+ }
+
+ /// Insert a custom epilogue for outlined functions.
+ /// This may be empty, in which case no epilogue or return statement will be
+ /// emitted.
+ virtual void insertOutlinerEpilogue(MachineBasicBlock &MBB,
+ MachineFunction &MF,
+ bool IsTailCall) const {
+ llvm_unreachable(
+ "Target didn't implement TargetInstrInfo::insertOutlinerEpilogue!");
+ }
+
+ /// Insert a call to an outlined function into the program.
+ /// Returns an iterator to the spot where we inserted the call. This must be
+ /// implemented by the target.
+ virtual MachineBasicBlock::iterator
+ insertOutlinedCall(Module &M, MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator &It, MachineFunction &MF,
+ bool IsTailCall) const {
+ llvm_unreachable(
+ "Target didn't implement TargetInstrInfo::insertOutlinedCall!");
+ }
+
+ /// Insert a custom prologue for outlined functions.
+ /// This may be empty, in which case no prologue will be emitted.
+ virtual void insertOutlinerPrologue(MachineBasicBlock &MBB,
+ MachineFunction &MF,
+ bool IsTailCall) const {
+ llvm_unreachable(
+ "Target didn't implement TargetInstrInfo::insertOutlinerPrologue!");
+ }
+
+ /// Return true if the function can safely be outlined from.
+ /// By default, this means that the function has no red zone.
+ virtual bool isFunctionSafeToOutlineFrom(MachineFunction &MF) const {
+ llvm_unreachable("Target didn't implement "
+ "TargetInstrInfo::isFunctionSafeToOutlineFrom!");
+ }
+
private:
unsigned CallFrameSetupOpcode, CallFrameDestroyOpcode;
unsigned CatchRetOpcode;
@@ -1500,16 +1637,18 @@ private:
/// \brief Provide DenseMapInfo for TargetInstrInfo::RegSubRegPair.
template<>
struct DenseMapInfo<TargetInstrInfo::RegSubRegPair> {
- typedef DenseMapInfo<unsigned> RegInfo;
+ using RegInfo = DenseMapInfo<unsigned>;
static inline TargetInstrInfo::RegSubRegPair getEmptyKey() {
return TargetInstrInfo::RegSubRegPair(RegInfo::getEmptyKey(),
RegInfo::getEmptyKey());
}
+
static inline TargetInstrInfo::RegSubRegPair getTombstoneKey() {
return TargetInstrInfo::RegSubRegPair(RegInfo::getTombstoneKey(),
RegInfo::getTombstoneKey());
}
+
/// \brief Reuse getHashValue implementation from
/// std::pair<unsigned, unsigned>.
static unsigned getHashValue(const TargetInstrInfo::RegSubRegPair &Val) {
@@ -1517,6 +1656,7 @@ struct DenseMapInfo<TargetInstrInfo::RegSubRegPair> {
std::make_pair(Val.Reg, Val.SubReg);
return DenseMapInfo<std::pair<unsigned, unsigned>>::getHashValue(PairVal);
}
+
static bool isEqual(const TargetInstrInfo::RegSubRegPair &LHS,
const TargetInstrInfo::RegSubRegPair &RHS) {
return RegInfo::isEqual(LHS.Reg, RHS.Reg) &&
diff --git a/contrib/llvm/include/llvm/Target/TargetLowering.h b/contrib/llvm/include/llvm/Target/TargetLowering.h
index 3728a7a..23711d6 100644
--- a/contrib/llvm/include/llvm/Target/TargetLowering.h
+++ b/contrib/llvm/include/llvm/Target/TargetLowering.h
@@ -1,4 +1,4 @@
-//===-- llvm/Target/TargetLowering.h - Target Lowering Info -----*- C++ -*-===//
+//===- llvm/Target/TargetLowering.h - Target Lowering Info ------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -23,15 +23,17 @@
#ifndef LLVM_TARGET_TARGETLOWERING_H
#define LLVM_TARGET_TARGETLOWERING_H
+#include "llvm/ADT/APInt.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/CodeGen/DAGCombine.h"
#include "llvm/CodeGen/ISDOpcodes.h"
#include "llvm/CodeGen/MachineValueType.h"
#include "llvm/CodeGen/RuntimeLibcalls.h"
+#include "llvm/CodeGen/SelectionDAG.h"
#include "llvm/CodeGen/SelectionDAGNodes.h"
#include "llvm/CodeGen/ValueTypes.h"
#include "llvm/IR/Attributes.h"
@@ -39,6 +41,7 @@
#include "llvm/IR/CallingConv.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Function.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/InlineAsm.h"
#include "llvm/IR/Instruction.h"
@@ -65,9 +68,13 @@ namespace llvm {
class BranchProbability;
class CCState;
class CCValAssign;
+class Constant;
class FastISel;
class FunctionLoweringInfo;
+class GlobalValue;
class IntrinsicInst;
+struct KnownBits;
+class LLVMContext;
class MachineBasicBlock;
class MachineFunction;
class MachineInstr;
@@ -76,6 +83,7 @@ class MachineLoop;
class MachineRegisterInfo;
class MCContext;
class MCExpr;
+class Module;
class TargetRegisterClass;
class TargetLibraryInfo;
class TargetRegisterInfo;
@@ -125,7 +133,7 @@ public:
/// LegalizeKind holds the legalization kind that needs to happen to EVT
/// in order to type-legalize it.
- typedef std::pair<LegalizeTypeAction, EVT> LegalizeKind;
+ using LegalizeKind = std::pair<LegalizeTypeAction, EVT>;
/// Enum that describes how the target represents true/false values.
enum BooleanContent {
@@ -163,6 +171,35 @@ public:
// or custom.
};
+ class ArgListEntry {
+ public:
+ Value *Val = nullptr;
+ SDValue Node = SDValue();
+ Type *Ty = nullptr;
+ bool IsSExt : 1;
+ bool IsZExt : 1;
+ bool IsInReg : 1;
+ bool IsSRet : 1;
+ bool IsNest : 1;
+ bool IsByVal : 1;
+ bool IsInAlloca : 1;
+ bool IsReturned : 1;
+ bool IsSwiftSelf : 1;
+ bool IsSwiftError : 1;
+ uint16_t Alignment = 0;
+
+ ArgListEntry()
+ : IsSExt(false), IsZExt(false), IsInReg(false), IsSRet(false),
+ IsNest(false), IsByVal(false), IsInAlloca(false), IsReturned(false),
+ IsSwiftSelf(false), IsSwiftError(false) {}
+
+ void setAttributes(ImmutableCallSite *CS, unsigned ArgIdx);
+ };
+ using ArgListTy = std::vector<ArgListEntry>;
+
+ virtual void markLibCallAttributes(MachineFunction *MF, unsigned CC,
+ ArgListTy &Args) const {};
+
static ISD::NodeType getExtendForContent(BooleanContent Content) {
switch (Content) {
case UndefinedBooleanContent:
@@ -180,8 +217,8 @@ public:
/// NOTE: The TargetMachine owns TLOF.
explicit TargetLoweringBase(const TargetMachine &TM);
- TargetLoweringBase(const TargetLoweringBase&) = delete;
- void operator=(const TargetLoweringBase&) = delete;
+ TargetLoweringBase(const TargetLoweringBase &) = delete;
+ TargetLoweringBase &operator=(const TargetLoweringBase &) = delete;
virtual ~TargetLoweringBase() = default;
protected:
@@ -200,6 +237,18 @@ public:
return MVT::getIntegerVT(DL.getPointerSizeInBits(AS));
}
+ /// Return the type for frame index, which is determined by
+ /// the alloca address space specified through the data layout.
+ MVT getFrameIndexTy(const DataLayout &DL) const {
+ return getPointerTy(DL, DL.getAllocaAddrSpace());
+ }
+
+ /// 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 {
+ return getPointerTy(DL);
+ }
+
/// EVT is not used in-tree, but is used by out-of-tree target.
/// A documentation for this function would be nice...
virtual MVT getScalarShiftAmountTy(const DataLayout &, EVT) const;
@@ -254,9 +303,7 @@ public:
/// several shifts, adds, and multiplies for this target.
/// The definition of "cheaper" may depend on whether we're optimizing
/// for speed or for size.
- virtual bool isIntDivCheap(EVT VT, AttributeSet Attr) const {
- return false;
- }
+ virtual bool isIntDivCheap(EVT VT, AttributeList Attr) const { return false; }
/// Return true if the target can handle a standalone remainder operation.
virtual bool hasStandaloneRem(EVT VT) const {
@@ -363,6 +410,16 @@ public:
return false;
}
+ /// Should we merge stores after Legalization (generally
+ /// better quality) or before (simpler)
+ virtual bool mergeStoresAfterLegalization() const { return false; }
+
+ /// Returns if it's reasonable to merge stores to MemVT size.
+ virtual bool canMergeStoresTo(unsigned AS, EVT MemVT,
+ const SelectionDAG &DAG) const {
+ return true;
+ }
+
/// \brief Return true if it is cheap to speculate a call to intrinsic cttz.
virtual bool isCheapToSpeculateCttz() const {
return false;
@@ -395,16 +452,33 @@ public:
/// \brief Return if the target supports combining a
/// chain like:
/// \code
- /// %andResult = and %val1, #imm-with-one-bit-set;
+ /// %andResult = and %val1, #mask
/// %icmpResult = icmp %andResult, 0
- /// br i1 %icmpResult, label %dest1, label %dest2
/// \endcode
/// into a single machine instruction of a form like:
/// \code
- /// brOnBitSet %register, #bitNumber, dest
+ /// cc = test %register, #mask
/// \endcode
- bool isMaskAndBranchFoldingLegal() const {
- return MaskAndBranchFoldingIsLegal;
+ virtual bool isMaskAndCmp0FoldingBeneficial(const Instruction &AndI) const {
+ return false;
+ }
+
+ /// Use bitwise logic to make pairs of compares more efficient. For example:
+ /// and (seteq A, B), (seteq C, D) --> seteq (or (xor A, B), (xor C, D)), 0
+ /// This should be true when it takes more than one instruction to lower
+ /// setcc (cmp+set on x86 scalar), when bitwise ops are faster than logic on
+ /// condition bits (crand on PowerPC), and/or when reducing cmp+br is a win.
+ virtual bool convertSetCCLogicToBitwiseLogic(EVT VT) const {
+ return false;
+ }
+
+ /// Return the preferred operand type if the target has a quick way to compare
+ /// integer values of the given size. Assume that any legal integer type can
+ /// be compared efficiently. Targets may override this to allow illegal wide
+ /// types to return a vector type if there is support to compare that type.
+ virtual MVT hasFastEqualityCompare(unsigned NumBits) const {
+ MVT VT = MVT::getIntegerVT(NumBits);
+ return isTypeLegal(VT) ? VT : MVT::INVALID_SIMPLE_VALUE_TYPE;
}
/// Return true if the target should transform:
@@ -614,6 +688,16 @@ public:
unsigned &NumIntermediates,
MVT &RegisterVT) const;
+ /// Certain targets such as MIPS require that some types such as vectors are
+ /// always broken down into scalars in some contexts. This occurs even if the
+ /// vector type is legal.
+ virtual unsigned getVectorTypeBreakdownForCallingConv(
+ LLVMContext &Context, EVT VT, EVT &IntermediateVT,
+ unsigned &NumIntermediates, MVT &RegisterVT) const {
+ return getVectorTypeBreakdown(Context, VT, IntermediateVT, NumIntermediates,
+ RegisterVT);
+ }
+
struct IntrinsicInfo {
unsigned opc = 0; // target opcode
EVT memVT; // memory VT
@@ -675,7 +759,7 @@ public:
if (VT.isExtended()) return Expand;
// If a target-specific SDNode requires legalization, require the target
// to provide custom legalization for it.
- if (Op > array_lengthof(OpActions[0])) return Custom;
+ if (Op >= array_lengthof(OpActions[0])) return Custom;
return OpActions[(unsigned)VT.getSimpleVT().SimpleTy][Op];
}
@@ -714,6 +798,74 @@ public:
return (!isTypeLegal(VT) && getOperationAction(Op, VT) == Custom);
}
+ /// Return true if lowering to a jump table is allowed.
+ bool areJTsAllowed(const Function *Fn) const {
+ if (Fn->getFnAttribute("no-jump-tables").getValueAsString() == "true")
+ return false;
+
+ return isOperationLegalOrCustom(ISD::BR_JT, MVT::Other) ||
+ isOperationLegalOrCustom(ISD::BRIND, MVT::Other);
+ }
+
+ /// Check whether the range [Low,High] fits in a machine word.
+ bool rangeFitsInWord(const APInt &Low, const APInt &High,
+ const DataLayout &DL) const {
+ // FIXME: Using the pointer type doesn't seem ideal.
+ uint64_t BW = DL.getPointerSizeInBits();
+ uint64_t Range = (High - Low).getLimitedValue(UINT64_MAX - 1) + 1;
+ return Range <= BW;
+ }
+
+ /// Return true if lowering to a jump table is suitable for a set of case
+ /// clusters which may contain \p NumCases cases, \p Range range of values.
+ /// FIXME: This function check the maximum table size and density, but the
+ /// minimum size is not checked. It would be nice if the the minimum size is
+ /// also combined within this function. Currently, the minimum size check is
+ /// performed in findJumpTable() in SelectionDAGBuiler and
+ /// getEstimatedNumberOfCaseClusters() in BasicTTIImpl.
+ bool isSuitableForJumpTable(const SwitchInst *SI, uint64_t NumCases,
+ uint64_t Range) const {
+ const bool OptForSize = SI->getParent()->getParent()->optForSize();
+ const unsigned MinDensity = getMinimumJumpTableDensity(OptForSize);
+ const unsigned MaxJumpTableSize =
+ OptForSize || getMaximumJumpTableSize() == 0
+ ? UINT_MAX
+ : getMaximumJumpTableSize();
+ // Check whether a range of clusters is dense enough for a jump table.
+ if (Range <= MaxJumpTableSize &&
+ (NumCases * 100 >= Range * MinDensity)) {
+ return true;
+ }
+ return false;
+ }
+
+ /// Return true if lowering to a bit test is suitable for a set of case
+ /// clusters which contains \p NumDests unique destinations, \p Low and
+ /// \p High as its lowest and highest case values, and expects \p NumCmps
+ /// case value comparisons. Check if the number of destinations, comparison
+ /// metric, and range are all suitable.
+ bool isSuitableForBitTests(unsigned NumDests, unsigned NumCmps,
+ const APInt &Low, const APInt &High,
+ const DataLayout &DL) const {
+ // FIXME: I don't think NumCmps is the correct metric: a single case and a
+ // range of cases both require only one branch to lower. Just looking at the
+ // number of clusters and destinations should be enough to decide whether to
+ // build bit tests.
+
+ // To lower a range with bit tests, the range must fit the bitwidth of a
+ // machine word.
+ if (!rangeFitsInWord(Low, High, DL))
+ return false;
+
+ // Decide whether it's profitable to lower this range with bit tests. Each
+ // destination requires a bit test and branch, and there is an overall range
+ // check branch. For a small number of clusters, separate comparisons might
+ // be cheaper, and for many destinations, splitting the range might be
+ // better.
+ return (NumDests == 1 && NumCmps >= 3) || (NumDests == 2 && NumCmps >= 5) ||
+ (NumDests == 3 && NumCmps >= 6);
+ }
+
/// Return true if the specified operation is illegal on this target or
/// unlikely to be made legal with custom lowering. This is used to help guide
/// high-level lowering decisions.
@@ -954,6 +1106,33 @@ public:
llvm_unreachable("Unsupported extended type!");
}
+ /// Certain combinations of ABIs, Targets and features require that types
+ /// are legal for some operations and not for other operations.
+ /// For MIPS all vector types must be passed through the integer register set.
+ virtual MVT getRegisterTypeForCallingConv(MVT VT) const {
+ return getRegisterType(VT);
+ }
+
+ virtual MVT getRegisterTypeForCallingConv(LLVMContext &Context,
+ EVT VT) const {
+ return getRegisterType(Context, VT);
+ }
+
+ /// Certain targets require unusual breakdowns of certain types. For MIPS,
+ /// this occurs when a vector type is used, as vector are passed through the
+ /// integer register set.
+ virtual unsigned getNumRegistersForCallingConv(LLVMContext &Context,
+ EVT VT) const {
+ return getNumRegisters(Context, VT);
+ }
+
+ /// Certain targets have context senstive alignment requirements, where one
+ /// type has the alignment requirement of another type.
+ virtual unsigned getABIAlignmentForCallingConv(Type *ArgTy,
+ DataLayout DL) const {
+ return DL.getABITypeAlignment(ArgTy);
+ }
+
/// If true, then instruction selection should seek to shrink the FP constant
/// of the specified type to a smaller type in order to save space and / or
/// reduce runtime.
@@ -987,6 +1166,11 @@ public:
return GatherAllAliasesMaxDepth;
}
+ /// Returns the size of the platform's va_list object.
+ virtual unsigned getVaListSizeInBits(const DataLayout &DL) const {
+ return getPointerTy(DL).getSizeInBits();
+ }
+
/// \brief Get maximum # of store operations permitted for llvm.memset
///
/// This function returns the maximum number of store operations permitted
@@ -1007,6 +1191,16 @@ public:
return OptSize ? MaxStoresPerMemcpyOptSize : MaxStoresPerMemcpy;
}
+ /// Get maximum # of load operations permitted for memcmp
+ ///
+ /// This function returns the maximum number of load operations permitted
+ /// to replace a call to memcmp. The value is set by the target at the
+ /// performance threshold for such a replacement. If OptSize is true,
+ /// return the limit for functions that have OptSize attribute.
+ unsigned getMaxExpandSizeMemcmp(bool OptSize) const {
+ return OptSize ? MaxLoadsPerMemcmpOptSize : MaxLoadsPerMemcmp;
+ }
+
/// \brief Get maximum # of store operations permitted for llvm.memmove
///
/// This function returns the maximum number of store operations permitted
@@ -1083,6 +1277,9 @@ public:
/// Return lower limit for number of blocks in a jump table.
unsigned getMinimumJumpTableEntries() const;
+ /// Return lower limit of the density in a jump table.
+ unsigned getMinimumJumpTableDensity(bool OptForSize) const;
+
/// Return upper limit for number of entries in a jump table.
/// Zero if no limit.
unsigned getMaximumJumpTableSize() const;
@@ -1178,6 +1375,12 @@ public:
/// Returns the target-specific address of the unsafe stack pointer.
virtual Value *getSafeStackPointerLocation(IRBuilder<> &IRB) const;
+ /// Returns the name of the symbol used to emit stack probes or the empty
+ /// string if not applicable.
+ virtual StringRef getStackProbeSymbolName(MachineFunction &MF) const {
+ return "";
+ }
+
/// Returns true if a cast between SrcAS and DestAS is a noop.
virtual bool isNoopAddrSpaceCast(unsigned SrcAS, unsigned DestAS) const {
return false;
@@ -1259,7 +1462,10 @@ public:
/// It is called by AtomicExpandPass before expanding an
/// AtomicRMW/AtomicCmpXchg/AtomicStore/AtomicLoad
/// if shouldInsertFencesForAtomic returns true.
- /// RMW and CmpXchg set both IsStore and IsLoad to true.
+ ///
+ /// Inst is the original atomic instruction, prior to other expansions that
+ /// may be performed.
+ ///
/// This function should either return a nullptr, or a pointer to an IR-level
/// Instruction*. Even complex fence sequences can be represented by a
/// single Instruction* through an intrinsic to be lowered later.
@@ -1285,18 +1491,17 @@ public:
/// seq_cst. But if they are lowered to monotonic accesses, no amount of
/// IR-level fences can prevent it.
/// @{
- virtual Instruction *emitLeadingFence(IRBuilder<> &Builder,
- AtomicOrdering Ord, bool IsStore,
- bool IsLoad) const {
- if (isReleaseOrStronger(Ord) && IsStore)
+ virtual Instruction *emitLeadingFence(IRBuilder<> &Builder, Instruction *Inst,
+ AtomicOrdering Ord) const {
+ if (isReleaseOrStronger(Ord) && Inst->hasAtomicStore())
return Builder.CreateFence(Ord);
else
return nullptr;
}
virtual Instruction *emitTrailingFence(IRBuilder<> &Builder,
- AtomicOrdering Ord, bool IsStore,
- bool IsLoad) const {
+ Instruction *Inst,
+ AtomicOrdering Ord) const {
if (isAcquireOrStronger(Ord))
return Builder.CreateFence(Ord);
else
@@ -1384,6 +1589,13 @@ public:
Action != TypeSplitVector;
}
+ /// Return true if a select of constants (select Cond, C1, C2) should be
+ /// transformed into simple math ops with the condition value. For example:
+ /// select Cond, C1, C1-1 --> add (zext Cond), C1-1
+ virtual bool convertSelectOfConstantsToMath() const {
+ return false;
+ }
+
//===--------------------------------------------------------------------===//
// TargetLowering Configuration Methods - These methods should be invoked by
// the derived class constructor to configure this object for the target.
@@ -1490,7 +1702,8 @@ protected:
void computeRegisterProperties(const TargetRegisterInfo *TRI);
/// Indicate that the specified operation does not work with the specified
- /// type and indicate what to do about it.
+ /// type and indicate what to do about it. Note that VT may refer to either
+ /// the type of a result or that of an operand of Op.
void setOperationAction(unsigned Op, MVT VT,
LegalizeAction Action) {
assert(Op < array_lengthof(OpActions[0]) && "Table isn't big enough!");
@@ -1642,10 +1855,9 @@ public:
/// possible to be done in the address mode for that operand. This hook lets
/// targets also pass back when this should be done on intrinsics which
/// load/store.
- virtual bool GetAddrModeArguments(IntrinsicInst * /*I*/,
+ virtual bool getAddrModeArguments(IntrinsicInst * /*I*/,
SmallVectorImpl<Value*> &/*Ops*/,
- Type *&/*AccessTy*/,
- unsigned AddrSpace = 0) const {
+ Type *&/*AccessTy*/) const {
return false;
}
@@ -1718,6 +1930,38 @@ public:
return false;
}
+ /// 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.
+ switch (Opcode) {
+ case ISD::ADD:
+ case ISD::SMIN:
+ case ISD::SMAX:
+ case ISD::UMIN:
+ case ISD::UMAX:
+ case ISD::MUL:
+ case ISD::MULHU:
+ case ISD::MULHS:
+ case ISD::SMUL_LOHI:
+ case ISD::UMUL_LOHI:
+ case ISD::FADD:
+ case ISD::FMUL:
+ case ISD::AND:
+ case ISD::OR:
+ case ISD::XOR:
+ case ISD::SADDO:
+ case ISD::UADDO:
+ case ISD::ADDC:
+ case ISD::ADDE:
+ case ISD::FMINNUM:
+ case ISD::FMAXNUM:
+ case ISD::FMINNAN:
+ case ISD::FMAXNAN:
+ return true;
+ default: return false;
+ }
+ }
+
/// Return true if it's free to truncate a value of type FromTy to type
/// ToTy. e.g. On x86 it's free to truncate a i32 value in register EAX to i16
/// by referencing its sub-register AX.
@@ -1768,6 +2012,35 @@ public:
return isExtFreeImpl(I);
}
+ /// Return true if \p Load and \p Ext can form an ExtLoad.
+ /// For example, in AArch64
+ /// %L = load i8, i8* %ptr
+ /// %E = zext i8 %L to i32
+ /// can be lowered into one load instruction
+ /// ldrb w0, [x0]
+ bool isExtLoad(const LoadInst *Load, const Instruction *Ext,
+ const DataLayout &DL) const {
+ EVT VT = getValueType(DL, Ext->getType());
+ EVT LoadVT = getValueType(DL, Load->getType());
+
+ // If the load has other users and the truncate is not free, the ext
+ // probably isn't free.
+ if (!Load->hasOneUse() && (isTypeLegal(LoadVT) || !isTypeLegal(VT)) &&
+ !isTruncateFree(Ext->getType(), Load->getType()))
+ return false;
+
+ // Check whether the target supports casts folded into loads.
+ unsigned LType;
+ if (isa<ZExtInst>(Ext))
+ LType = ISD::ZEXTLOAD;
+ else {
+ assert(isa<SExtInst>(Ext) && "Unexpected ext type!");
+ LType = ISD::SEXTLOAD;
+ }
+
+ return isLoadExtLegal(LType, VT, LoadVT);
+ }
+
/// Return true if any actual instruction that defines a value of type FromTy
/// implicitly zero-extends the value to ToTy in the result register.
///
@@ -1808,7 +2081,7 @@ public:
/// this information should not be provided because it will generate more
/// loads.
virtual bool hasPairedLoad(EVT /*LoadedType*/,
- unsigned & /*RequiredAligment*/) const {
+ unsigned & /*RequiredAlignment*/) const {
return false;
}
@@ -1953,6 +2226,12 @@ public:
return LibcallCallingConvs[Call];
}
+ /// Execute target specific actions to finalize target lowering.
+ /// This is used to set extra flags in MachineFrameInformation and freezing
+ /// the set of reserved registers.
+ /// The default implementation just freezes the set of reserved registers.
+ virtual void finalizeLowering(MachineFunction &MF) const;
+
private:
const TargetMachine &TM;
@@ -2176,6 +2455,8 @@ protected:
/// Maximum number of store operations that may be substituted for a call to
/// memcpy, used for functions with OptSize attribute.
unsigned MaxStoresPerMemcpyOptSize;
+ unsigned MaxLoadsPerMemcmp;
+ unsigned MaxLoadsPerMemcmpOptSize;
/// \brief Specify maximum bytes of store instructions per memmove call.
///
@@ -2197,16 +2478,13 @@ protected:
/// the branch is usually predicted right.
bool PredictableSelectIsExpensive;
- /// MaskAndBranchFoldingIsLegal - Indicates if the target supports folding
- /// a mask of a single bit, a compare, and a branch into a single instruction.
- bool MaskAndBranchFoldingIsLegal;
-
/// \see enableExtLdPromotion.
bool EnableExtLdPromotion;
/// Return true if the value types that can be represented by the specified
/// register class are all legal.
- bool isLegalRC(const TargetRegisterClass *RC) const;
+ bool isLegalRC(const TargetRegisterInfo &TRI,
+ const TargetRegisterClass &RC) const;
/// Replace/modify any TargetFrameIndex operands with a targte-dependent
/// sequence of memory operands that is recognized by PrologEpilogInserter.
@@ -2223,8 +2501,8 @@ class TargetLowering : public TargetLoweringBase {
public:
struct DAGCombinerInfo;
- TargetLowering(const TargetLowering&) = delete;
- void operator=(const TargetLowering&) = delete;
+ TargetLowering(const TargetLowering &) = delete;
+ TargetLowering &operator=(const TargetLowering &) = delete;
/// NOTE: The TargetMachine owns TLOF.
explicit TargetLowering(const TargetMachine &TM);
@@ -2326,30 +2604,39 @@ public:
New = N;
return true;
}
-
- /// 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);
-
- /// Convert x+y to (VT)((SmallVT)x+(SmallVT)y) if the casts are free. This
- /// uses isZExtFree and ZERO_EXTEND for the widening cast, but it could be
- /// generalized for targets with other types of implicit widening casts.
- bool ShrinkDemandedOp(SDValue Op, unsigned BitWidth, const APInt &Demanded,
- const SDLoc &dl);
-
- /// Helper for SimplifyDemandedBits that can simplify an operation with
- /// multiple uses. This function uses TLI.SimplifyDemandedBits to
- /// simplify Operand \p OpIdx of \p User and then updated \p User with
- /// the simplified version. No other uses of \p OpIdx are updated.
- /// If \p User is the only user of \p OpIdx, this function behaves exactly
- /// like TLI.SimplifyDemandedBits except that it also updates the DAG by
- /// calling DCI.CommitTargetLoweringOpt.
- bool SimplifyDemandedBits(SDNode *User, unsigned OpIdx,
- const APInt &Demanded, DAGCombinerInfo &DCI);
};
+ /// 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,
+ 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,
+ TargetLoweringOpt &TLO) const {
+ return false;
+ }
+
+ /// Convert x+y to (VT)((SmallVT)x+(SmallVT)y) if the casts are free. This
+ /// uses isZExtFree and ZERO_EXTEND for the widening cast, but it could be
+ /// generalized for targets with other types of implicit widening casts.
+ bool ShrinkDemandedOp(SDValue Op, unsigned BitWidth, const APInt &Demanded,
+ TargetLoweringOpt &TLO) const;
+
+ /// Helper for SimplifyDemandedBits that can simplify an operation with
+ /// multiple uses. This function simplifies operand \p OpIdx of \p User and
+ /// then updates \p User with the simplified version. No other uses of
+ /// \p OpIdx are updated. If \p User is the only user of \p OpIdx, this
+ /// function behaves exactly like function SimplifyDemandedBits declared
+ /// below except that it also updates the DAG by calling
+ /// DCI.CommitTargetLoweringOpt.
+ bool SimplifyDemandedBits(SDNode *User, unsigned OpIdx, const APInt &Demanded,
+ DAGCombinerInfo &DCI, TargetLoweringOpt &TLO) const;
+
/// Look at Op. At this point, we know that only the DemandedMask bits 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 return true, returning
@@ -2357,29 +2644,38 @@ public:
/// expression and return a mask of KnownOne and KnownZero bits for the
/// expression (used to simplify the caller). The KnownZero/One bits may only
/// be accurate for those bits in the DemandedMask.
- /// \p AssumeSingleUse When this paramater is true, this function will
+ /// \p AssumeSingleUse When this parameter is true, this function will
/// attempt to simplify \p Op even if there are multiple uses.
/// Callers are responsible for correctly updating the DAG based on the
/// results of this function, because simply replacing replacing TLO.Old
- /// with TLO.New will be incorrect when this paramater is true and TLO.Old
+ /// with TLO.New will be incorrect when this parameter is true and TLO.Old
/// has multiple uses.
bool SimplifyDemandedBits(SDValue Op, const APInt &DemandedMask,
- APInt &KnownZero, APInt &KnownOne,
+ KnownBits &Known,
TargetLoweringOpt &TLO,
unsigned Depth = 0,
bool AssumeSingleUse = false) const;
+ /// Helper wrapper around SimplifyDemandedBits
+ bool SimplifyDemandedBits(SDValue Op, APInt &DemandedMask,
+ DAGCombinerInfo &DCI) 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.
+ /// 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
+ /// requested vector elements.
virtual void computeKnownBitsForTargetNode(const SDValue Op,
- APInt &KnownZero,
- APInt &KnownOne,
+ KnownBits &Known,
+ const APInt &DemandedElts,
const SelectionDAG &DAG,
unsigned Depth = 0) const;
/// This method can be implemented by targets that want to expose additional
- /// information about sign bits to the DAG Combiner.
+ /// information about sign bits to the DAG Combiner. The DemandedElts
+ /// argument allows us to only collect the minimum sign bits that are shared
+ /// by the requested vector elements.
virtual unsigned ComputeNumSignBitsForTargetNode(SDValue Op,
+ const APInt &DemandedElts,
const SelectionDAG &DAG,
unsigned Depth = 0) const;
@@ -2456,10 +2752,22 @@ public:
// This transformation may not be desirable if it disrupts a particularly
// auspicious target-specific tree (e.g. bitfield extraction in AArch64).
// By default, it returns true.
- virtual bool isDesirableToCommuteWithShift(const SDNode *N /*Op*/) const {
+ virtual bool isDesirableToCommuteWithShift(const SDNode *N) const {
return true;
}
+ // Return true if it is profitable to combine a BUILD_VECTOR to a TRUNCATE.
+ // Example of such a combine:
+ // v4i32 build_vector((extract_elt V, 0),
+ // (extract_elt V, 2),
+ // (extract_elt V, 4),
+ // (extract_elt V, 6))
+ // -->
+ // v4i32 truncate (bitcast V to v4i64)
+ virtual bool isDesirableToCombineBuildVectorToTruncate() 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
@@ -2496,12 +2804,6 @@ public:
return false;
}
- /// Return true if the MachineFunction contains a COPY which would imply
- /// HasCopyImplyingStackAdjustment.
- virtual bool hasCopyImplyingStackAdjustment(MachineFunction *MF) const {
- return false;
- }
-
/// Perform necessary initialization to handle a subset of CSRs explicitly
/// via copies. This function is called at the beginning of instruction
/// selection.
@@ -2528,7 +2830,6 @@ public:
/// described by the Ins array, into the specified DAG. The implementation
/// should fill in the InVals array with legal-type argument values, and
/// return the resulting token chain value.
- ///
virtual SDValue LowerFormalArguments(
SDValue /*Chain*/, CallingConv::ID /*CallConv*/, bool /*isVarArg*/,
const SmallVectorImpl<ISD::InputArg> & /*Ins*/, const SDLoc & /*dl*/,
@@ -2536,37 +2837,13 @@ public:
llvm_unreachable("Not Implemented");
}
- struct ArgListEntry {
- SDValue Node;
- Type* Ty;
- bool isSExt : 1;
- bool isZExt : 1;
- bool isInReg : 1;
- bool isSRet : 1;
- bool isNest : 1;
- bool isByVal : 1;
- bool isInAlloca : 1;
- bool isReturned : 1;
- bool isSwiftSelf : 1;
- bool isSwiftError : 1;
- uint16_t Alignment;
-
- ArgListEntry() : isSExt(false), isZExt(false), isInReg(false),
- isSRet(false), isNest(false), isByVal(false), isInAlloca(false),
- isReturned(false), isSwiftSelf(false), isSwiftError(false),
- Alignment(0) {}
-
- void setAttributes(ImmutableCallSite *CS, unsigned AttrIdx);
- };
- typedef std::vector<ArgListEntry> ArgListTy;
-
/// This structure contains all information that is necessary for lowering
/// calls. It is passed to TLI::LowerCallTo when the SelectionDAG builder
/// needs to lower a call, and targets will see this struct in their LowerCall
/// implementation.
struct CallLoweringInfo {
SDValue Chain;
- Type *RetTy;
+ Type *RetTy = nullptr;
bool RetSExt : 1;
bool RetZExt : 1;
bool IsVarArg : 1;
@@ -2574,30 +2851,31 @@ public:
bool DoesNotReturn : 1;
bool IsReturnValueUsed : 1;
bool IsConvergent : 1;
+ bool IsPatchPoint : 1;
// IsTailCall should be modified by implementations of
// TargetLowering::LowerCall that perform tail call conversions.
- bool IsTailCall;
+ bool IsTailCall = false;
+
+ // Is Call lowering done post SelectionDAG type legalization.
+ bool IsPostTypeLegalization = false;
- unsigned NumFixedArgs;
- CallingConv::ID CallConv;
+ unsigned NumFixedArgs = -1;
+ CallingConv::ID CallConv = CallingConv::C;
SDValue Callee;
ArgListTy Args;
SelectionDAG &DAG;
SDLoc DL;
- ImmutableCallSite *CS;
- bool IsPatchPoint;
+ ImmutableCallSite *CS = nullptr;
SmallVector<ISD::OutputArg, 32> Outs;
SmallVector<SDValue, 32> OutVals;
SmallVector<ISD::InputArg, 32> Ins;
SmallVector<SDValue, 4> InVals;
CallLoweringInfo(SelectionDAG &DAG)
- : RetTy(nullptr), RetSExt(false), RetZExt(false), IsVarArg(false),
- IsInReg(false), DoesNotReturn(false), IsReturnValueUsed(true),
- IsConvergent(false), IsTailCall(false), NumFixedArgs(-1),
- CallConv(CallingConv::C), DAG(DAG), CS(nullptr), IsPatchPoint(false) {
- }
+ : RetSExt(false), RetZExt(false), IsVarArg(false), IsInReg(false),
+ DoesNotReturn(false), IsReturnValueUsed(true), IsConvergent(false),
+ IsPatchPoint(false), DAG(DAG) {}
CallLoweringInfo &setDebugLoc(const SDLoc &dl) {
DL = dl;
@@ -2609,6 +2887,20 @@ public:
return *this;
}
+ // setCallee with target/module-specific attributes
+ CallLoweringInfo &setLibCallee(CallingConv::ID CC, Type *ResultType,
+ SDValue Target, ArgListTy &&ArgsList) {
+ RetTy = ResultType;
+ Callee = Target;
+ CallConv = CC;
+ NumFixedArgs = Args.size();
+ Args = std::move(ArgsList);
+
+ DAG.getTargetLoweringInfo().markLibCallAttributes(
+ &(DAG.getMachineFunction()), CC, Args);
+ return *this;
+ }
+
CallLoweringInfo &setCallee(CallingConv::ID CC, Type *ResultType,
SDValue Target, ArgListTy &&ArgsList) {
RetTy = ResultType;
@@ -2624,15 +2916,15 @@ public:
ImmutableCallSite &Call) {
RetTy = ResultType;
- IsInReg = Call.paramHasAttr(0, Attribute::InReg);
+ IsInReg = Call.hasRetAttr(Attribute::InReg);
DoesNotReturn =
Call.doesNotReturn() ||
(!Call.isInvoke() &&
isa<UnreachableInst>(Call.getInstruction()->getNextNode()));
IsVarArg = FTy->isVarArg();
IsReturnValueUsed = !Call.getInstruction()->use_empty();
- RetSExt = Call.paramHasAttr(0, Attribute::SExt);
- RetZExt = Call.paramHasAttr(0, Attribute::ZExt);
+ RetSExt = Call.hasRetAttr(Attribute::SExt);
+ RetZExt = Call.hasRetAttr(Attribute::ZExt);
Callee = Target;
@@ -2690,6 +2982,11 @@ public:
return *this;
}
+ CallLoweringInfo &setIsPostTypeLegalization(bool Value=true) {
+ IsPostTypeLegalization = Value;
+ return *this;
+ }
+
ArgListTy &getArgs() {
return Args;
}
@@ -2751,7 +3048,7 @@ public:
/// Return true if the target may be able emit the call instruction as a tail
/// call. This is used by optimization passes to determine if it's profitable
/// to duplicate return instructions to enable tailcall optimization.
- virtual bool mayBeEmittedAsTailCall(CallInst *) const {
+ virtual bool mayBeEmittedAsTailCall(const CallInst *) const {
return false;
}
@@ -2808,6 +3105,13 @@ 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;
+ }
+
/// This callback is invoked by the type legalizer to legalize nodes with an
/// illegal operand type but legal result types. It replaces the
/// LowerOperation callback in the type Legalizer. The reason we can not do
@@ -2857,7 +3161,6 @@ public:
return nullptr;
}
-
bool verifyReturnAddressArgumentIsConstant(SDValue Op,
SelectionDAG &DAG) const;
@@ -2906,15 +3209,19 @@ public:
/// Information about the constraint code, e.g. Register, RegisterClass,
/// Memory, Other, Unknown.
- TargetLowering::ConstraintType ConstraintType;
+ TargetLowering::ConstraintType ConstraintType = TargetLowering::C_Unknown;
/// If this is the result output operand or a clobber, this is null,
/// otherwise it is the incoming operand to the CallInst. This gets
/// modified as the asm is processed.
- Value *CallOperandVal;
+ Value *CallOperandVal = nullptr;
/// The ValueType for the operand value.
- MVT ConstraintVT;
+ MVT ConstraintVT = MVT::Other;
+
+ /// Copy constructor for copying from a ConstraintInfo.
+ AsmOperandInfo(InlineAsm::ConstraintInfo Info)
+ : InlineAsm::ConstraintInfo(std::move(Info)) {}
/// Return true of this is an input operand that is a matching constraint
/// like "4".
@@ -2923,15 +3230,9 @@ public:
/// If this is an input matching constraint, this method returns the output
/// operand it matches.
unsigned getMatchedOperand() const;
-
- /// Copy constructor for copying from a ConstraintInfo.
- AsmOperandInfo(InlineAsm::ConstraintInfo Info)
- : InlineAsm::ConstraintInfo(std::move(Info)),
- ConstraintType(TargetLowering::C_Unknown), CallOperandVal(nullptr),
- ConstraintVT(MVT::Other) {}
};
- typedef std::vector<AsmOperandInfo> AsmOperandInfoVector;
+ using AsmOperandInfoVector = std::vector<AsmOperandInfo>;
/// Split up the constraint string from the inline assembly value into the
/// specific constraints and their prefixes, and also tie in the associated
@@ -3183,7 +3484,7 @@ private:
/// Given an LLVM IR type and return type attributes, compute the return value
/// EVTs and flags, and optionally also the offsets, if the return value is
/// being lowered to memory.
-void GetReturnInfo(Type *ReturnType, AttributeSet attr,
+void GetReturnInfo(Type *ReturnType, AttributeList attr,
SmallVectorImpl<ISD::OutputArg> &Outs,
const TargetLowering &TLI, const DataLayout &DL);
diff --git a/contrib/llvm/include/llvm/Target/TargetLoweringObjectFile.h b/contrib/llvm/include/llvm/Target/TargetLoweringObjectFile.h
index 72bae0a..80d4d8e 100644
--- a/contrib/llvm/include/llvm/Target/TargetLoweringObjectFile.h
+++ b/contrib/llvm/include/llvm/Target/TargetLoweringObjectFile.h
@@ -16,37 +16,35 @@
#define LLVM_TARGET_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 MachineModuleInfo;
- class Mangler;
- class MCContext;
- class MCExpr;
- class MCSection;
- class MCSymbol;
- class MCSymbolRefExpr;
- class MCStreamer;
- class MCValue;
- class ConstantExpr;
- class GlobalValue;
- class TargetMachine;
+
+class GlobalValue;
+class MachineModuleInfo;
+class Mangler;
+class MCContext;
+class MCExpr;
+class MCSection;
+class MCSymbol;
+class MCSymbolRefExpr;
+class MCStreamer;
+class MCValue;
+class TargetMachine;
class TargetLoweringObjectFile : public MCObjectFileInfo {
- MCContext *Ctx;
+ MCContext *Ctx = nullptr;
/// Name-mangler for global names.
Mangler *Mang = nullptr;
- TargetLoweringObjectFile(
- const TargetLoweringObjectFile&) = delete;
- void operator=(const TargetLoweringObjectFile&) = delete;
-
protected:
- bool SupportIndirectSymViaGOTPCRel;
- bool SupportGOTPCRelWithOffset;
+ bool SupportIndirectSymViaGOTPCRel = false;
+ bool SupportGOTPCRelWithOffset = true;
/// This section contains the static constructor pointer list.
MCSection *StaticCtorSection;
@@ -55,15 +53,15 @@ protected:
MCSection *StaticDtorSection;
public:
+ TargetLoweringObjectFile() = default;
+ TargetLoweringObjectFile(const TargetLoweringObjectFile &) = delete;
+ TargetLoweringObjectFile &
+ operator=(const TargetLoweringObjectFile &) = delete;
+ virtual ~TargetLoweringObjectFile();
+
MCContext &getContext() const { return *Ctx; }
Mangler &getMangler() const { return *Mang; }
- TargetLoweringObjectFile()
- : MCObjectFileInfo(), Ctx(nullptr), Mang(nullptr),
- SupportIndirectSymViaGOTPCRel(false), SupportGOTPCRelWithOffset(true) {}
-
- virtual ~TargetLoweringObjectFile();
-
/// This method must be called before any actual lowering is done. This
/// specifies the current context for codegen, and gives the lowering
/// implementations a chance to set up their default sections.
@@ -72,10 +70,9 @@ public:
virtual void emitPersonalityValue(MCStreamer &Streamer, const DataLayout &TM,
const MCSymbol *Sym) const;
- /// Emit the module flags that the platform cares about.
- virtual void emitModuleFlags(MCStreamer &Streamer,
- ArrayRef<Module::ModuleFlagEntry> Flags,
- const TargetMachine &TM) const {}
+ /// Emit the module-level metadata that the platform cares about.
+ virtual void emitModuleMetadata(MCStreamer &Streamer, Module &M,
+ const TargetMachine &TM) const {}
/// Given a constant with the SectionKind, return a section that it should be
/// placed in.
@@ -194,4 +191,4 @@ protected:
} // end namespace llvm
-#endif
+#endif // LLVM_TARGET_TARGETLOWERINGOBJECTFILE_H
diff --git a/contrib/llvm/include/llvm/Target/TargetMachine.h b/contrib/llvm/include/llvm/Target/TargetMachine.h
index b1d8f8f..933c6c8 100644
--- a/contrib/llvm/include/llvm/Target/TargetMachine.h
+++ b/contrib/llvm/include/llvm/Target/TargetMachine.h
@@ -25,7 +25,6 @@
namespace llvm {
class GlobalValue;
-class MachineFunctionInitializer;
class Mangler;
class MCAsmInfo;
class MCContext;
@@ -34,6 +33,7 @@ class MCRegisterInfo;
class MCSubtargetInfo;
class MCSymbol;
class raw_pwrite_stream;
+class PassManagerBuilder;
class Target;
class TargetIntrinsicInfo;
class TargetIRAnalysis;
@@ -205,10 +205,9 @@ public:
/// uses this to answer queries about the IR.
virtual TargetIRAnalysis getTargetIRAnalysis();
- /// Add target-specific function passes that should be run as early as
- /// possible in the optimization pipeline. Most TargetMachines have no such
- /// passes.
- virtual void addEarlyAsPossiblePasses(PassManagerBase &) {}
+ /// Allow the target to modify the pass manager, e.g. by calling
+ /// PassManagerBuilder::addExtension.
+ virtual void adjustPassManager(PassManagerBuilder &) {}
/// These enums are meant to be passed into addPassesToEmitFile to indicate
/// what type of file to emit, and returned by it to indicate what type of
@@ -227,8 +226,7 @@ public:
PassManagerBase &, raw_pwrite_stream &, CodeGenFileType,
bool /*DisableVerify*/ = true, AnalysisID /*StartBefore*/ = nullptr,
AnalysisID /*StartAfter*/ = nullptr, AnalysisID /*StopBefore*/ = nullptr,
- AnalysisID /*StopAfter*/ = nullptr,
- MachineFunctionInitializer * /*MFInitializer*/ = nullptr) {
+ AnalysisID /*StopAfter*/ = nullptr) {
return true;
}
@@ -268,8 +266,8 @@ class LLVMTargetMachine : public TargetMachine {
protected: // Can only create subclasses.
LLVMTargetMachine(const Target &T, StringRef DataLayoutString,
const Triple &TargetTriple, StringRef CPU, StringRef FS,
- TargetOptions Options, Reloc::Model RM, CodeModel::Model CM,
- CodeGenOpt::Level OL);
+ const TargetOptions &Options, Reloc::Model RM,
+ CodeModel::Model CM, CodeGenOpt::Level OL);
void initAsmInfo();
public:
@@ -289,8 +287,7 @@ public:
PassManagerBase &PM, raw_pwrite_stream &Out, CodeGenFileType FileType,
bool DisableVerify = true, AnalysisID StartBefore = nullptr,
AnalysisID StartAfter = nullptr, AnalysisID StopBefore = nullptr,
- AnalysisID StopAfter = nullptr,
- MachineFunctionInitializer *MFInitializer = nullptr) override;
+ AnalysisID StopAfter = nullptr) override;
/// Add passes to the specified pass manager to get machine code emitted with
/// the MCJIT. This method returns true if machine code is not supported. It
@@ -299,6 +296,17 @@ public:
bool addPassesToEmitMC(PassManagerBase &PM, MCContext *&Ctx,
raw_pwrite_stream &OS,
bool DisableVerify = true) override;
+
+ /// Returns true if the target is expected to pass all machine verifier
+ /// checks. This is a stopgap measure to fix targets one by one. We will
+ /// remove this at some point and always enable the verifier when
+ /// EXPENSIVE_CHECKS is enabled.
+ virtual bool isMachineVerifierClean() const { return true; }
+
+ /// \brief Adds an AsmPrinter pass to the pipeline that prints assembly or
+ /// machine code from the MI representation.
+ bool addAsmPrinter(PassManagerBase &PM, raw_pwrite_stream &Out,
+ CodeGenFileType FileTYpe, MCContext &Context);
};
} // end namespace llvm
diff --git a/contrib/llvm/include/llvm/Target/TargetOpcodes.def b/contrib/llvm/include/llvm/Target/TargetOpcodes.def
index edb9b73..cadf860 100644
--- a/contrib/llvm/include/llvm/Target/TargetOpcodes.def
+++ b/contrib/llvm/include/llvm/Target/TargetOpcodes.def
@@ -107,6 +107,9 @@ HANDLE_TARGET_OPCODE(LIFETIME_END)
/// that must lie within the function and not contain another stackmap.
HANDLE_TARGET_OPCODE(STACKMAP)
+/// FEntry all - This is a marker instruction which gets translated into a raw fentry call.
+HANDLE_TARGET_OPCODE(FENTRY_CALL)
+
/// Patchable call instruction - this instruction represents a call to a
/// constant address, followed by a series of NOPs. It is intended to
/// support optimizations for dynamic languages (such as javascript) that
@@ -131,11 +134,13 @@ HANDLE_TARGET_OPCODE(STATEPOINT)
/// frame index of the local stack allocation.
HANDLE_TARGET_OPCODE(LOCAL_ESCAPE)
-/// Loading instruction that may page fault, bundled with associated
+/// Wraps a machine instruction which can fault, bundled with associated
+/// information on how to handle such a fault.
+/// For example loading instruction that may page fault, bundled with associated
/// information on how to handle such a page fault. It is intended to support
/// "zero cost" null checks in managed languages by allowing LLVM to fold
/// comparisons into existing memory operations.
-HANDLE_TARGET_OPCODE(FAULTING_LOAD_OP)
+HANDLE_TARGET_OPCODE(FAULTING_OP)
/// Wraps a machine instruction to add patchability constraints. An
/// instruction wrapped in PATCHABLE_OP has to either have a minimum
@@ -177,6 +182,10 @@ HANDLE_TARGET_OPCODE(PATCHABLE_FUNCTION_EXIT)
/// PATCHABLE_RET which specifically only works for return instructions.
HANDLE_TARGET_OPCODE(PATCHABLE_TAIL_CALL)
+/// Wraps a logging call and its arguments with nop sleds. At runtime, this can be
+/// patched to insert instrumentation instructions.
+HANDLE_TARGET_OPCODE(PATCHABLE_EVENT_CALL)
+
/// The following generic opcodes are not supposed to appear after ISel.
/// This is something we might want to relax, but for now, this is convenient
/// to produce diagnostics.
@@ -213,6 +222,8 @@ HANDLE_TARGET_OPCODE(G_OR)
HANDLE_TARGET_OPCODE(G_XOR)
+HANDLE_TARGET_OPCODE(G_IMPLICIT_DEF)
+
/// Generic instruction to materialize the address of an alloca or other
/// stack-based object.
HANDLE_TARGET_OPCODE(G_FRAME_INDEX)
@@ -224,13 +235,15 @@ HANDLE_TARGET_OPCODE(G_GLOBAL_VALUE)
/// (typically a sub-register COPY after instruction selection).
HANDLE_TARGET_OPCODE(G_EXTRACT)
+HANDLE_TARGET_OPCODE(G_UNMERGE_VALUES)
+
/// Generic instruction to insert blocks of bits from the registers given into
/// the source.
HANDLE_TARGET_OPCODE(G_INSERT)
/// Generic instruction to paste a variable number of components together into a
/// larger register.
-HANDLE_TARGET_OPCODE(G_SEQUENCE)
+HANDLE_TARGET_OPCODE(G_MERGE_VALUES)
/// Generic pointer to int conversion.
HANDLE_TARGET_OPCODE(G_PTRTOINT)
@@ -251,6 +264,9 @@ HANDLE_TARGET_OPCODE(G_STORE)
/// Generic conditional branch instruction.
HANDLE_TARGET_OPCODE(G_BRCOND)
+/// Generic indirect branch instruction.
+HANDLE_TARGET_OPCODE(G_BRINDIRECT)
+
/// Generic intrinsic use (without side effects).
HANDLE_TARGET_OPCODE(G_INTRINSIC)
@@ -272,6 +288,12 @@ HANDLE_TARGET_OPCODE(G_CONSTANT)
/// Generic floating constant.
HANDLE_TARGET_OPCODE(G_FCONSTANT)
+/// Generic va_start instruction. Stores to its one pointer operand.
+HANDLE_TARGET_OPCODE(G_VASTART)
+
+/// Generic va_start instruction. Stores to its one pointer operand.
+HANDLE_TARGET_OPCODE(G_VAARG)
+
// Generic sign extend
HANDLE_TARGET_OPCODE(G_SEXT)
@@ -320,6 +342,14 @@ HANDLE_TARGET_OPCODE(G_UMULO)
/// overflow flag.
HANDLE_TARGET_OPCODE(G_SMULO)
+// Multiply two numbers at twice the incoming bit width (unsigned) and return
+// the high half of the result.
+HANDLE_TARGET_OPCODE(G_UMULH)
+
+// Multiply two numbers at twice the incoming bit width (signed) and return
+// the high half of the result.
+HANDLE_TARGET_OPCODE(G_SMULH)
+
/// Generic FP addition.
HANDLE_TARGET_OPCODE(G_FADD)
@@ -329,13 +359,34 @@ HANDLE_TARGET_OPCODE(G_FSUB)
/// Generic FP multiplication.
HANDLE_TARGET_OPCODE(G_FMUL)
+/// Generic FMA multiplication. Behaves like llvm fma intrinsic
+HANDLE_TARGET_OPCODE(G_FMA)
+
/// Generic FP division.
HANDLE_TARGET_OPCODE(G_FDIV)
/// Generic FP remainder.
HANDLE_TARGET_OPCODE(G_FREM)
-/// Generic float to signed-int conversion
+/// Generic FP exponentiation.
+HANDLE_TARGET_OPCODE(G_FPOW)
+
+/// Generic base-e exponential of a value.
+HANDLE_TARGET_OPCODE(G_FEXP)
+
+/// Generic base-2 exponential of a value.
+HANDLE_TARGET_OPCODE(G_FEXP2)
+
+/// Floating point base-e logarithm of a value.
+HANDLE_TARGET_OPCODE(G_FLOG)
+
+/// Floating point base-2 logarithm of a value.
+HANDLE_TARGET_OPCODE(G_FLOG2)
+
+/// Generic FP negation.
+HANDLE_TARGET_OPCODE(G_FNEG)
+
+/// Generic FP extension.
HANDLE_TARGET_OPCODE(G_FPEXT)
/// Generic float to signed-int conversion
@@ -353,18 +404,31 @@ HANDLE_TARGET_OPCODE(G_SITOFP)
/// Generic unsigned-int to float conversion
HANDLE_TARGET_OPCODE(G_UITOFP)
-/// Generic unsigned-int to float conversion
+/// Generic pointer offset
HANDLE_TARGET_OPCODE(G_GEP)
+/// 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)
+
/// Generic BRANCH instruction. This is an unconditional branch.
HANDLE_TARGET_OPCODE(G_BR)
+/// Generic insertelement.
+HANDLE_TARGET_OPCODE(G_INSERT_VECTOR_ELT)
+
+/// Generic extractelement.
+HANDLE_TARGET_OPCODE(G_EXTRACT_VECTOR_ELT)
+
+/// Generic shufflevector.
+HANDLE_TARGET_OPCODE(G_SHUFFLE_VECTOR)
+
// TODO: Add more generic opcodes as we move along.
/// Marker for the end of the generic opcode.
/// This is used to check if an opcode is in the range of the
/// generic opcodes.
-HANDLE_TARGET_OPCODE_MARKER(PRE_ISEL_GENERIC_OPCODE_END, G_BR)
+HANDLE_TARGET_OPCODE_MARKER(PRE_ISEL_GENERIC_OPCODE_END, G_SHUFFLE_VECTOR)
/// BUILTIN_OP_END - This must be the last enum value in this list.
/// The target-specific post-isel opcode values start here.
diff --git a/contrib/llvm/include/llvm/Target/TargetOptions.h b/contrib/llvm/include/llvm/Target/TargetOptions.h
index f5134d9..5c20638 100644
--- a/contrib/llvm/include/llvm/Target/TargetOptions.h
+++ b/contrib/llvm/include/llvm/Target/TargetOptions.h
@@ -99,22 +99,16 @@ namespace llvm {
class TargetOptions {
public:
TargetOptions()
- : PrintMachineCode(false), LessPreciseFPMADOption(false),
- UnsafeFPMath(false), NoInfsFPMath(false), NoNaNsFPMath(false),
- NoTrappingFPMath(false),
+ : PrintMachineCode(false), UnsafeFPMath(false), NoInfsFPMath(false),
+ NoNaNsFPMath(false), NoTrappingFPMath(false),
+ NoSignedZerosFPMath(false),
HonorSignDependentRoundingFPMathOption(false), NoZerosInBSS(false),
- GuaranteedTailCallOpt(false), StackAlignmentOverride(0),
- StackSymbolOrdering(true), EnableFastISel(false), UseInitArray(false),
- DisableIntegratedAS(false), CompressDebugSections(false),
- RelaxELFRelocations(false), FunctionSections(false),
- DataSections(false), UniqueSectionNames(true), TrapUnreachable(false),
- EmulatedTLS(false), EnableIPRA(false),
- FloatABIType(FloatABI::Default),
- AllowFPOpFusion(FPOpFusion::Standard),
- ThreadModel(ThreadModel::POSIX),
- EABIVersion(EABI::Default), DebuggerTuning(DebuggerKind::Default),
- FPDenormalMode(FPDenormal::IEEE),
- ExceptionModel(ExceptionHandling::None) {}
+ GuaranteedTailCallOpt(false), StackSymbolOrdering(true),
+ EnableFastISel(false), UseInitArray(false),
+ DisableIntegratedAS(false), RelaxELFRelocations(false),
+ FunctionSections(false), DataSections(false),
+ UniqueSectionNames(true), TrapUnreachable(false), EmulatedTLS(false),
+ EnableIPRA(false) {}
/// PrintMachineCode - This flag is enabled when the -print-machineinstrs
/// option is specified on the command line, and should enable debugging
@@ -125,20 +119,11 @@ namespace llvm {
/// optimization should be disabled for the given machine function.
bool DisableFramePointerElim(const MachineFunction &MF) const;
- /// LessPreciseFPMAD - This flag is enabled when the
- /// -enable-fp-mad is specified on the command line. When this flag is off
- /// (the default), the code generator is not allowed to generate mad
- /// (multiply add) if the result is "less precise" than doing those
- /// operations individually.
- unsigned LessPreciseFPMADOption : 1;
- bool LessPreciseFPMAD() const;
-
/// UnsafeFPMath - This flag is enabled when the
/// -enable-unsafe-fp-math flag is specified on the command line. When
/// this flag is off (the default), the code generator is not allowed to
/// produce results that are "less precise" than IEEE allows. This includes
/// use of X86 instructions like FSIN and FCOS instead of libcalls.
- /// UnsafeFPMath implies LessPreciseFPMAD.
unsigned UnsafeFPMath : 1;
/// NoInfsFPMath - This flag is enabled when the
@@ -153,11 +138,17 @@ namespace llvm {
/// assume the FP arithmetic arguments and results are never NaNs.
unsigned NoNaNsFPMath : 1;
- /// NoTrappingFPMath - This flag is enabled when the
- /// -enable-no-trapping-fp-math is specified on the command line. This
+ /// NoTrappingFPMath - This flag is enabled when the
+ /// -enable-no-trapping-fp-math is specified on the command line. This
/// specifies that there are no trap handlers to handle exceptions.
unsigned NoTrappingFPMath : 1;
+ /// NoSignedZerosFPMath - This flag is enabled when the
+ /// -enable-no-signed-zeros-fp-math is specified on the command line. This
+ /// specifies that optimizations are allowed to treat the sign of a zero
+ /// argument or result as insignificant.
+ unsigned NoSignedZerosFPMath : 1;
+
/// HonorSignDependentRoundingFPMath - This returns true when the
/// -enable-sign-dependent-rounding-fp-math is specified. If this returns
/// false (the default), the code generator is allowed to assume that the
@@ -182,7 +173,7 @@ namespace llvm {
unsigned GuaranteedTailCallOpt : 1;
/// StackAlignmentOverride - Override default stack alignment for target.
- unsigned StackAlignmentOverride;
+ unsigned StackAlignmentOverride = 0;
/// StackSymbolOrdering - When true, this will allow CodeGen to order
/// the local stack symbols (for code size, code locality, or any other
@@ -203,7 +194,7 @@ namespace llvm {
unsigned DisableIntegratedAS : 1;
/// Compress DWARF debug sections.
- unsigned CompressDebugSections : 1;
+ DebugCompressionType CompressDebugSections = DebugCompressionType::None;
unsigned RelaxELFRelocations : 1;
@@ -231,7 +222,7 @@ namespace llvm {
/// software floating point, but does not indicate that FP hardware may not
/// be used. Such a combination is unfortunately popular (e.g.
/// arm-apple-darwin). Hard presumes that the normal FP ABI is used.
- FloatABI::ABIType FloatABIType;
+ FloatABI::ABIType FloatABIType = FloatABI::Default;
/// AllowFPOpFusion - This flag is set by the -fuse-fp-ops=xxx option.
/// This controls the creation of fused FP ops that store intermediate
@@ -249,65 +240,29 @@ namespace llvm {
/// optimizers. Fused operations that are explicitly specified (e.g. FMA
/// via the llvm.fma.* intrinsic) will always be honored, regardless of
/// the value of this option.
- FPOpFusion::FPOpFusionMode AllowFPOpFusion;
+ FPOpFusion::FPOpFusionMode AllowFPOpFusion = FPOpFusion::Standard;
/// ThreadModel - This flag specifies the type of threading model to assume
/// for things like atomics
- ThreadModel::Model ThreadModel;
+ ThreadModel::Model ThreadModel = ThreadModel::POSIX;
/// EABIVersion - This flag specifies the EABI version
- EABI EABIVersion;
+ EABI EABIVersion = EABI::Default;
/// Which debugger to tune for.
- DebuggerKind DebuggerTuning;
+ DebuggerKind DebuggerTuning = DebuggerKind::Default;
/// FPDenormalMode - This flags specificies which denormal numbers the code
/// is permitted to require.
- FPDenormal::DenormalMode FPDenormalMode;
+ FPDenormal::DenormalMode FPDenormalMode = FPDenormal::IEEE;
/// What exception model to use
- ExceptionHandling ExceptionModel;
+ ExceptionHandling ExceptionModel = ExceptionHandling::None;
/// Machine level options.
MCTargetOptions MCOptions;
};
-// Comparison operators:
-
-
-inline bool operator==(const TargetOptions &LHS,
- const TargetOptions &RHS) {
-#define ARE_EQUAL(X) LHS.X == RHS.X
- return
- ARE_EQUAL(UnsafeFPMath) &&
- ARE_EQUAL(NoInfsFPMath) &&
- ARE_EQUAL(NoNaNsFPMath) &&
- ARE_EQUAL(NoTrappingFPMath) &&
- ARE_EQUAL(HonorSignDependentRoundingFPMathOption) &&
- ARE_EQUAL(NoZerosInBSS) &&
- ARE_EQUAL(GuaranteedTailCallOpt) &&
- ARE_EQUAL(StackAlignmentOverride) &&
- ARE_EQUAL(EnableFastISel) &&
- ARE_EQUAL(UseInitArray) &&
- ARE_EQUAL(TrapUnreachable) &&
- ARE_EQUAL(EmulatedTLS) &&
- ARE_EQUAL(FloatABIType) &&
- ARE_EQUAL(AllowFPOpFusion) &&
- ARE_EQUAL(ThreadModel) &&
- ARE_EQUAL(EABIVersion) &&
- ARE_EQUAL(DebuggerTuning) &&
- ARE_EQUAL(FPDenormalMode) &&
- ARE_EQUAL(ExceptionModel) &&
- ARE_EQUAL(MCOptions) &&
- ARE_EQUAL(EnableIPRA);
-#undef ARE_EQUAL
-}
-
-inline bool operator!=(const TargetOptions &LHS,
- const TargetOptions &RHS) {
- return !(LHS == RHS);
-}
-
} // End llvm namespace
#endif
diff --git a/contrib/llvm/include/llvm/Target/TargetRegisterInfo.h b/contrib/llvm/include/llvm/Target/TargetRegisterInfo.h
index 3080e9a..b6839da 100644
--- a/contrib/llvm/include/llvm/Target/TargetRegisterInfo.h
+++ b/contrib/llvm/include/llvm/Target/TargetRegisterInfo.h
@@ -1,4 +1,4 @@
-//=== Target/TargetRegisterInfo.h - Target Register Information -*- C++ -*-===//
+//==- Target/TargetRegisterInfo.h - Target Register Information --*- C++ -*-==//
//
// The LLVM Compiler Infrastructure
//
@@ -17,35 +17,40 @@
#define LLVM_TARGET_TARGETREGISTERINFO_H
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineValueType.h"
#include "llvm/IR/CallingConv.h"
+#include "llvm/MC/LaneBitmask.h"
#include "llvm/MC/MCRegisterInfo.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/MathExtras.h"
#include "llvm/Support/Printable.h"
#include <cassert>
+#include <cstdint>
#include <functional>
namespace llvm {
class BitVector;
+class LiveRegMatrix;
class MachineFunction;
+class MachineInstr;
class RegScavenger;
-template<class T> class SmallVectorImpl;
class VirtRegMap;
-class raw_ostream;
-class LiveRegMatrix;
class TargetRegisterClass {
public:
- typedef const MCPhysReg* iterator;
- typedef const MCPhysReg* const_iterator;
- typedef const MVT::SimpleValueType* vt_iterator;
- typedef const TargetRegisterClass* const * sc_iterator;
+ using iterator = const MCPhysReg *;
+ using const_iterator = const MCPhysReg *;
+ using sc_iterator = const TargetRegisterClass* const *;
// Instance variables filled by tablegen, do not use!
const MCRegisterClass *MC;
- const vt_iterator VTs;
+ const uint16_t SpillSize, SpillAlignment;
+ const MVT::SimpleValueType *VTs;
const uint32_t *SubClassMask;
const uint16_t *SuperRegIndices;
const LaneBitmask LaneMask;
@@ -92,13 +97,6 @@ public:
return MC->contains(Reg1, Reg2);
}
- /// Return the size of the register in bytes, which is also the size
- /// of a stack slot allocated to hold a spilled copy of this register.
- unsigned getSize() const { return MC->getSize(); }
-
- /// Return the minimum required alignment for a register of this class.
- unsigned getAlignment() const { return MC->getAlignment(); }
-
/// Return the cost of copying a value between two registers in this class.
/// A negative number means the register class is very expensive
/// to copy e.g. status flag register classes.
@@ -108,26 +106,6 @@ public:
/// registers.
bool isAllocatable() const { return MC->isAllocatable(); }
- /// Return true if this TargetRegisterClass has the ValueType vt.
- bool hasType(MVT vt) const {
- for(int i = 0; VTs[i] != MVT::Other; ++i)
- if (MVT(VTs[i]) == vt)
- return true;
- return false;
- }
-
- /// vt_begin / vt_end - Loop over all of the value types that can be
- /// represented by values in this register class.
- vt_iterator vt_begin() const {
- return VTs;
- }
-
- vt_iterator vt_end() const {
- vt_iterator I = VTs;
- while (*I != MVT::Other) ++I;
- return I;
- }
-
/// Return true if the specified TargetRegisterClass
/// is a proper sub-class of this TargetRegisterClass.
bool hasSubClass(const TargetRegisterClass *RC) const {
@@ -178,7 +156,6 @@ public:
/// There exists SuperRC where:
/// For all Reg in SuperRC:
/// this->contains(Reg:Idx)
- ///
const uint16_t *getSuperRegIndices() const {
return SuperRegIndices;
}
@@ -209,7 +186,6 @@ public:
/// other criteria.
///
/// By default, this method returns all registers in the class.
- ///
ArrayRef<MCPhysReg> getRawAllocationOrder(const MachineFunction &MF) const {
return OrderFunc ? OrderFunc(MF) : makeArrayRef(begin(), getNumRegs());
}
@@ -244,7 +220,9 @@ struct RegClassWeight {
///
class TargetRegisterInfo : public MCRegisterInfo {
public:
- typedef const TargetRegisterClass * const * regclass_iterator;
+ using regclass_iterator = const TargetRegisterClass * const *;
+ using vt_iterator = const MVT::SimpleValueType *;
+
private:
const TargetRegisterInfoDesc *InfoDesc; // Extra desc array for codegen
const char *const *SubRegIndexNames; // Names of subreg indexes.
@@ -262,8 +240,8 @@ protected:
const LaneBitmask *SRILaneMasks,
LaneBitmask CoveringLanes);
virtual ~TargetRegisterInfo();
-public:
+public:
// Register numbers can represent physical registers, virtual registers, and
// sometimes stack slots. The unsigned values are divided into these ranges:
//
@@ -326,6 +304,44 @@ public:
return Index | (1u << 31);
}
+ /// Return the size in bits of a register from class RC.
+ unsigned getRegSizeInBits(const TargetRegisterClass &RC) const {
+ return RC.SpillSize * 8;
+ }
+
+ /// Return the size in bytes of the stack slot allocated to hold a spilled
+ /// copy of a register from class RC.
+ unsigned getSpillSize(const TargetRegisterClass &RC) const {
+ return RC.SpillSize;
+ }
+
+ /// Return the minimum required alignment for a spill slot for a register
+ /// of this class.
+ unsigned getSpillAlignment(const TargetRegisterClass &RC) const {
+ return RC.SpillAlignment;
+ }
+
+ /// Return true if the given TargetRegisterClass has the ValueType T.
+ bool isTypeLegalForClass(const TargetRegisterClass &RC, MVT T) const {
+ for (int i = 0; RC.VTs[i] != MVT::Other; ++i)
+ if (MVT(RC.VTs[i]) == T)
+ return true;
+ return false;
+ }
+
+ /// Loop over all of the value types that can be represented by values
+ // in the given register class.
+ vt_iterator legalclasstypes_begin(const TargetRegisterClass &RC) const {
+ return RC.VTs;
+ }
+
+ vt_iterator legalclasstypes_end(const TargetRegisterClass &RC) const {
+ vt_iterator I = RC.VTs;
+ while (*I != MVT::Other)
+ ++I;
+ return I;
+ }
+
/// 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.
@@ -426,7 +442,9 @@ public:
/// this target. The register should be in the order of desired callee-save
/// stack frame offset. The first register is closest to the incoming stack
/// pointer if stack grows down, and vice versa.
- ///
+ /// Notice: This function does not take into account disabled CSRs.
+ /// In most cases you will want to use instead the function
+ /// getCalleeSavedRegs that is implemented in MachineRegisterInfo.
virtual const MCPhysReg*
getCalleeSavedRegs(const MachineFunction *MF) const = 0;
@@ -483,10 +501,20 @@ public:
/// function. Used by MachineRegisterInfo::isConstantPhysReg().
virtual bool isConstantPhysReg(unsigned PhysReg) const { return false; }
+ /// Physical registers that may be modified within a function but are
+ /// guaranteed to be restored before any uses. This is useful for targets that
+ /// 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,
+ const MachineFunction &MF) const {
+ return false;
+ }
+
/// Prior to adding the live-out mask to a stackmap or patchpoint
/// instruction, provide the target the opportunity to adjust it (mainly to
/// remove pseudo-registers that should be ignored).
- virtual void adjustStackMapLiveOutMask(uint32_t *Mask) const { }
+ virtual void adjustStackMapLiveOutMask(uint32_t *Mask) const {}
/// Return a super-register of the specified register
/// Reg so its sub-register of index SubIdx is Reg.
@@ -544,7 +572,6 @@ public:
/// The ARM register Q0 has two D subregs dsub_0:D0 and dsub_1:D1. It also has
/// ssub_0:S0 - ssub_3:S3 subregs.
/// If you compose subreg indices dsub_1, ssub_0 you get ssub_2.
- ///
unsigned composeSubRegIndices(unsigned a, unsigned b) const {
if (!a) return b;
if (!b) return a;
@@ -619,7 +646,6 @@ public:
/// corresponding argument register class.
///
/// The function returns NULL if no register class can be found.
- ///
const TargetRegisterClass*
getCommonSuperRegClass(const TargetRegisterClass *RCA, unsigned SubA,
const TargetRegisterClass *RCB, unsigned SubB,
@@ -630,9 +656,11 @@ public:
//
/// Register class iterators
- ///
regclass_iterator regclass_begin() const { return RegClassBegin; }
regclass_iterator regclass_end() const { return RegClassEnd; }
+ iterator_range<regclass_iterator> regclasses() const {
+ return make_range(regclass_begin(), regclass_end());
+ }
unsigned getNumRegClasses() const {
return (unsigned)(regclass_end()-regclass_begin());
@@ -882,7 +910,6 @@ public:
/// Return true if the register was spilled, false otherwise.
/// If this function does not spill the register, the scavenger
/// will instead spill it to the emergency spill slot.
- ///
virtual bool saveScavengerRegister(MachineBasicBlock &MBB,
MachineBasicBlock::iterator I,
MachineBasicBlock::iterator &UseMI,
@@ -941,7 +968,6 @@ public:
ArrayRef<MCPhysReg> Exceptions = ArrayRef<MCPhysReg>()) const;
};
-
//===----------------------------------------------------------------------===//
// SuperRegClassIterator
//===----------------------------------------------------------------------===//
@@ -960,7 +986,7 @@ public:
//
class SuperRegClassIterator {
const unsigned RCMaskWords;
- unsigned SubReg;
+ unsigned SubReg = 0;
const uint16_t *Idx;
const uint32_t *Mask;
@@ -971,9 +997,7 @@ public:
const TargetRegisterInfo *TRI,
bool IncludeSelf = false)
: RCMaskWords((TRI->getNumRegClasses() + 31) / 32),
- SubReg(0),
- Idx(RC->getSuperRegIndices()),
- Mask(RC->getSubClassMask()) {
+ Idx(RC->getSuperRegIndices()), Mask(RC->getSubClassMask()) {
if (!IncludeSelf)
++*this;
}
@@ -1012,12 +1036,12 @@ class BitMaskClassIterator {
/// Base index of CurrentChunk.
/// In other words, the number of bit we read to get at the
/// beginning of that chunck.
- unsigned Base;
+ unsigned Base = 0;
/// Adjust base index of CurrentChunk.
/// Base index + how many bit we read within CurrentChunk.
- unsigned Idx;
+ unsigned Idx = 0;
/// Current register class ID.
- unsigned ID;
+ unsigned ID = 0;
/// Mask we are iterating over.
const uint32_t *Mask;
/// Current chunk of the Mask we are traversing.
@@ -1071,8 +1095,7 @@ public:
///
/// \pre \p Mask != nullptr
BitMaskClassIterator(const uint32_t *Mask, const TargetRegisterInfo &TRI)
- : NumRegClasses(TRI.getNumRegClasses()), Base(0), Idx(0), ID(0),
- Mask(Mask), CurrentChunk(*Mask) {
+ : NumRegClasses(TRI.getNumRegClasses()), Mask(Mask), CurrentChunk(*Mask) {
// Move to the first ID.
moveToNextID();
}
@@ -1124,6 +1147,6 @@ Printable PrintRegUnit(unsigned Unit, const TargetRegisterInfo *TRI);
/// registers on a \ref raw_ostream.
Printable PrintVRegOrUnit(unsigned VRegOrUnit, const TargetRegisterInfo *TRI);
-} // End llvm namespace
+} // end namespace llvm
-#endif
+#endif // LLVM_TARGET_TARGETREGISTERINFO_H
diff --git a/contrib/llvm/include/llvm/Target/TargetSchedule.td b/contrib/llvm/include/llvm/Target/TargetSchedule.td
index 74b98ac..7b00c94 100644
--- a/contrib/llvm/include/llvm/Target/TargetSchedule.td
+++ b/contrib/llvm/include/llvm/Target/TargetSchedule.td
@@ -139,7 +139,7 @@ class ProcResourceKind;
// changes this to an in-order issue/dispatch resource. In this case,
// the scheduler counts down from the cycle that the instruction
// issues in-order, forcing a stall whenever a subsequent instruction
-// requires the same resource until the number of ResourceCyles
+// requires the same resource until the number of ResourceCycles
// specified in WriteRes expire. Setting BufferSize=1 changes this to
// an in-order latency resource. In this case, the scheduler models
// producer/consumer stalls between instructions that use the
@@ -255,6 +255,9 @@ class ProcWriteResources<list<ProcResourceKind> resources> {
// Allow a processor to mark some scheduling classes as unsupported
// for stronger verification.
bit Unsupported = 0;
+ // Allow a processor to mark some scheduling classes as single-issue.
+ // SingleIssue is an alias for Begin/End Group.
+ bit SingleIssue = 0;
SchedMachineModel SchedModel = ?;
}
@@ -331,7 +334,7 @@ class ReadAdvance<SchedRead read, int cycles, list<SchedWrite> writes = []>
}
// Directly associate a new SchedRead type with a delay and optional
-// pipeline bypess. For use with InstRW or ItinRW.
+// pipeline bypass. For use with InstRW or ItinRW.
class SchedReadAdvance<int cycles, list<SchedWrite> writes = []> : SchedRead,
ProcReadAdvance<cycles, writes>;
diff --git a/contrib/llvm/include/llvm/Target/TargetSelectionDAG.td b/contrib/llvm/include/llvm/Target/TargetSelectionDAG.td
index 55e2c2bc..9ed614c 100644
--- a/contrib/llvm/include/llvm/Target/TargetSelectionDAG.td
+++ b/contrib/llvm/include/llvm/Target/TargetSelectionDAG.td
@@ -136,30 +136,34 @@ def SDTIntUnaryOp : SDTypeProfile<1, 1, [ // ctlz
SDTCisSameAs<0, 1>, SDTCisInt<0>
]>;
def SDTIntExtendOp : SDTypeProfile<1, 1, [ // sext, zext, anyext
- SDTCisInt<0>, SDTCisInt<1>, SDTCisOpSmallerThanOp<1, 0>
+ SDTCisInt<0>, SDTCisInt<1>, SDTCisOpSmallerThanOp<1, 0>, SDTCisSameNumEltsAs<0, 1>
]>;
def SDTIntTruncOp : SDTypeProfile<1, 1, [ // trunc
- SDTCisInt<0>, SDTCisInt<1>, SDTCisOpSmallerThanOp<0, 1>
+ SDTCisInt<0>, SDTCisInt<1>, SDTCisOpSmallerThanOp<0, 1>, SDTCisSameNumEltsAs<0, 1>
]>;
def SDTFPUnaryOp : SDTypeProfile<1, 1, [ // fneg, fsqrt, etc
SDTCisSameAs<0, 1>, SDTCisFP<0>
]>;
def SDTFPRoundOp : SDTypeProfile<1, 1, [ // fround
- SDTCisFP<0>, SDTCisFP<1>, SDTCisOpSmallerThanOp<0, 1>
+ SDTCisFP<0>, SDTCisFP<1>, SDTCisOpSmallerThanOp<0, 1>, SDTCisSameNumEltsAs<0, 1>
]>;
def SDTFPExtendOp : SDTypeProfile<1, 1, [ // fextend
- SDTCisFP<0>, SDTCisFP<1>, SDTCisOpSmallerThanOp<1, 0>
+ SDTCisFP<0>, SDTCisFP<1>, SDTCisOpSmallerThanOp<1, 0>, SDTCisSameNumEltsAs<0, 1>
]>;
def SDTIntToFPOp : SDTypeProfile<1, 1, [ // [su]int_to_fp
- SDTCisFP<0>, SDTCisInt<1>
+ SDTCisFP<0>, SDTCisInt<1>, SDTCisSameNumEltsAs<0, 1>
]>;
def SDTFPToIntOp : SDTypeProfile<1, 1, [ // fp_to_[su]int
- SDTCisInt<0>, SDTCisFP<1>
+ SDTCisInt<0>, SDTCisFP<1>, SDTCisSameNumEltsAs<0, 1>
]>;
def SDTExtInreg : SDTypeProfile<1, 2, [ // sext_inreg
SDTCisSameAs<0, 1>, SDTCisInt<0>, SDTCisVT<2, OtherVT>,
SDTCisVTSmallerThanOp<2, 1>
]>;
+def SDTExtInvec : SDTypeProfile<1, 1, [ // sext_invec
+ SDTCisInt<0>, SDTCisVec<0>, SDTCisInt<1>, SDTCisVec<1>,
+ SDTCisOpSmallerThanOp<1, 0>, SDTCisSameSizeAs<0,1>
+]>;
def SDTSetCC : SDTypeProfile<1, 3, [ // setcc
SDTCisInt<0>, SDTCisSameAs<1, 2>, SDTCisVT<3, OtherVT>
@@ -170,7 +174,7 @@ def SDTSelect : SDTypeProfile<1, 3, [ // select
]>;
def SDTVSelect : SDTypeProfile<1, 3, [ // vselect
- SDTCisInt<1>, SDTCisSameAs<0, 2>, SDTCisSameAs<2, 3>, SDTCisSameNumEltsAs<0, 1>
+ SDTCisVec<0>, SDTCisInt<1>, SDTCisSameAs<0, 2>, SDTCisSameAs<2, 3>, SDTCisSameNumEltsAs<0, 1>
]>;
def SDTSelectCC : SDTypeProfile<1, 5, [ // select_cc
@@ -277,7 +281,7 @@ def SDTConvertOp : SDTypeProfile<1, 5, [ //cvtss, su, us, uu, ff, fs, fu, sf, su
]>;
class SDCallSeqStart<list<SDTypeConstraint> constraints> :
- SDTypeProfile<0, 1, constraints>;
+ SDTypeProfile<0, 2, constraints>;
class SDCallSeqEnd<list<SDTypeConstraint> constraints> :
SDTypeProfile<0, 2, constraints>;
@@ -406,6 +410,10 @@ def umax : SDNode<"ISD::UMAX" , SDTIntBinOp,
[SDNPCommutative, SDNPAssociative]>;
def sext_inreg : SDNode<"ISD::SIGN_EXTEND_INREG", SDTExtInreg>;
+def sext_invec : SDNode<"ISD::SIGN_EXTEND_VECTOR_INREG", SDTExtInvec>;
+def zext_invec : SDNode<"ISD::ZERO_EXTEND_VECTOR_INREG", SDTExtInvec>;
+
+def abs : SDNode<"ISD::ABS" , SDTIntUnaryOp>;
def bitreverse : SDNode<"ISD::BITREVERSE" , SDTIntUnaryOp>;
def bswap : SDNode<"ISD::BSWAP" , SDTIntUnaryOp>;
def ctlz : SDNode<"ISD::CTLZ" , SDTIntUnaryOp>;
diff --git a/contrib/llvm/include/llvm/Target/TargetSubtargetInfo.h b/contrib/llvm/include/llvm/Target/TargetSubtargetInfo.h
index 0b43515..9440c56 100644
--- a/contrib/llvm/include/llvm/Target/TargetSubtargetInfo.h
+++ b/contrib/llvm/include/llvm/Target/TargetSubtargetInfo.h
@@ -1,4 +1,4 @@
-//==-- llvm/Target/TargetSubtargetInfo.h - Target Information ----*- C++ -*-==//
+//===- llvm/Target/TargetSubtargetInfo.h - Target Information ---*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -18,22 +18,31 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/CodeGen/PBQPRAConstraint.h"
-#include "llvm/CodeGen/SchedulerRegistry.h"
#include "llvm/CodeGen/ScheduleDAGMutation.h"
+#include "llvm/CodeGen/SchedulerRegistry.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/Support/CodeGen.h"
#include <memory>
#include <vector>
+
namespace llvm {
class CallLowering;
+class InstrItineraryData;
+struct InstrStage;
class InstructionSelector;
class LegalizerInfo;
class MachineInstr;
+struct MachineSchedPolicy;
+struct MCReadAdvanceEntry;
+struct MCWriteLatencyEntry;
+struct MCWriteProcResEntry;
class RegisterBankInfo;
class SDep;
class SelectionDAGTargetInfo;
+struct SubtargetFeatureKV;
+struct SubtargetInfoKV;
class SUnit;
class TargetFrameLowering;
class TargetInstrInfo;
@@ -41,7 +50,7 @@ class TargetLowering;
class TargetRegisterClass;
class TargetRegisterInfo;
class TargetSchedModel;
-struct MachineSchedPolicy;
+class Triple;
//===----------------------------------------------------------------------===//
///
@@ -63,13 +72,13 @@ protected: // Can only create subclasses...
public:
// AntiDepBreakMode - Type of anti-dependence breaking that should
// be performed before post-RA scheduling.
- typedef enum { ANTIDEP_NONE, ANTIDEP_CRITICAL, ANTIDEP_ALL } AntiDepBreakMode;
- typedef SmallVectorImpl<const TargetRegisterClass *> RegClassVector;
+ using AntiDepBreakMode = enum { ANTIDEP_NONE, ANTIDEP_CRITICAL, ANTIDEP_ALL };
+ using RegClassVector = SmallVectorImpl<const TargetRegisterClass *>;
TargetSubtargetInfo() = delete;
TargetSubtargetInfo(const TargetSubtargetInfo &) = delete;
- void operator=(const TargetSubtargetInfo &) = delete;
- virtual ~TargetSubtargetInfo();
+ TargetSubtargetInfo &operator=(const TargetSubtargetInfo &) = delete;
+ ~TargetSubtargetInfo() override;
virtual bool isXRaySupported() const { return false; }
@@ -111,7 +120,6 @@ public:
/// getRegisterInfo - If register information is available, return it. If
/// not, return null.
- ///
virtual const TargetRegisterInfo *getRegisterInfo() const { return nullptr; }
/// If the information for the register banks is available, return it.
@@ -120,7 +128,6 @@ public:
/// getInstrItineraryData - Returns instruction itinerary data for the target
/// or specific subtarget.
- ///
virtual const InstrItineraryData *getInstrItineraryData() const {
return nullptr;
}
@@ -143,6 +150,9 @@ public:
/// TargetLowering preference). It does not yet disable the postRA scheduler.
virtual bool enableMachineScheduler() const;
+ /// \brief Support printing of [latency:throughput] comment in output .S file.
+ virtual bool supportPrintSchedInfo() const { return false; }
+
/// \brief True if the machine scheduler should disable the TLI preference
/// for preRA scheduling with the source level scheduler.
virtual bool enableMachineSchedDefaultSched() const { return true; }
@@ -227,6 +237,10 @@ public:
/// Please use MachineRegisterInfo::subRegLivenessEnabled() instead where
/// possible.
virtual bool enableSubRegLiveness() const { return false; }
+
+ /// Returns string representation of scheduler comment
+ std::string getSchedInfoStr(const MachineInstr &MI) const override;
+ std::string getSchedInfoStr(MCInst const &MCI) const override;
};
} // end namespace llvm
diff --git a/contrib/llvm/include/llvm/Testing/Support/Error.h b/contrib/llvm/include/llvm/Testing/Support/Error.h
new file mode 100644
index 0000000..f23d289
--- /dev/null
+++ b/contrib/llvm/include/llvm/Testing/Support/Error.h
@@ -0,0 +1,69 @@
+//===- llvm/Testing/Support/Error.h ---------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TESTING_SUPPORT_ERROR_H
+#define LLVM_TESTING_SUPPORT_ERROR_H
+
+#include "llvm/ADT/Optional.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Testing/Support/SupportHelpers.h"
+
+#include "gmock/gmock.h"
+#include <ostream>
+
+namespace llvm {
+namespace detail {
+ErrorHolder TakeError(Error Err);
+
+template <typename T> ExpectedHolder<T> TakeExpected(Expected<T> &Exp) {
+ llvm::detail::ExpectedHolder<T> Result;
+ auto &EH = static_cast<llvm::detail::ErrorHolder &>(Result);
+ EH = TakeError(Exp.takeError());
+ if (Result.Success)
+ Result.Value = &(*Exp);
+ return Result;
+}
+
+template <typename T> ExpectedHolder<T> TakeExpected(Expected<T> &&Exp) {
+ return TakeExpected(Exp);
+}
+} // namespace detail
+
+#define EXPECT_THAT_ERROR(Err, Matcher) \
+ EXPECT_THAT(llvm::detail::TakeError(Err), Matcher)
+#define ASSERT_THAT_ERROR(Err, Matcher) \
+ ASSERT_THAT(llvm::detail::TakeError(Err), Matcher)
+
+#define EXPECT_THAT_EXPECTED(Err, Matcher) \
+ EXPECT_THAT(llvm::detail::TakeExpected(Err), Matcher)
+#define ASSERT_THAT_EXPECTED(Err, Matcher) \
+ ASSERT_THAT(llvm::detail::TakeExpected(Err), Matcher)
+
+MATCHER(Succeeded, "") { return arg.Success; }
+MATCHER(Failed, "") { return !arg.Success; }
+
+MATCHER_P(HasValue, value,
+ "succeeded with value " + testing::PrintToString(value)) {
+ if (!arg.Success) {
+ *result_listener << "operation failed";
+ return false;
+ }
+
+ assert(arg.Value.hasValue());
+ if (**arg.Value != value) {
+ *result_listener << "but \"" + testing::PrintToString(**arg.Value) +
+ "\" != " + testing::PrintToString(value);
+ return false;
+ }
+
+ return true;
+}
+} // namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/Testing/Support/SupportHelpers.h b/contrib/llvm/include/llvm/Testing/Support/SupportHelpers.h
new file mode 100644
index 0000000..c4dd414
--- /dev/null
+++ b/contrib/llvm/include/llvm/Testing/Support/SupportHelpers.h
@@ -0,0 +1,47 @@
+//===- Testing/Support/SupportHelpers.h -----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TESTING_SUPPORT_SUPPORTHELPERS_H
+#define LLVM_TESTING_SUPPORT_SUPPORTHELPERS_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Error.h"
+#include "gtest/gtest-printers.h"
+
+namespace llvm {
+namespace detail {
+struct ErrorHolder {
+ bool Success;
+ std::string Message;
+};
+
+template <typename T> struct ExpectedHolder : public ErrorHolder {
+ Optional<T *> Value;
+};
+
+inline void PrintTo(const ErrorHolder &Err, std::ostream *Out) {
+ *Out << (Err.Success ? "succeeded" : "failed");
+ if (!Err.Success) {
+ *Out << " (" << StringRef(Err.Message).trim().str() << ")";
+ }
+}
+
+template <typename T>
+void PrintTo(const ExpectedHolder<T> &Item, std::ostream *Out) {
+ if (Item.Success) {
+ *Out << "succeeded with value \"" << ::testing::PrintToString(**Item.Value)
+ << "\"";
+ } else {
+ PrintTo(static_cast<const ErrorHolder &>(Item), Out);
+ }
+}
+} // namespace detail
+} // namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/ToolDrivers/llvm-dlltool/DlltoolDriver.h b/contrib/llvm/include/llvm/ToolDrivers/llvm-dlltool/DlltoolDriver.h
new file mode 100644
index 0000000..964b0f7
--- /dev/null
+++ b/contrib/llvm/include/llvm/ToolDrivers/llvm-dlltool/DlltoolDriver.h
@@ -0,0 +1,24 @@
+//===- DlltoolDriver.h - dlltool.exe-compatible driver ----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Defines an interface to a dlltool.exe-compatible driver.
+// Used by llvm-dlltool.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TOOLDRIVERS_LLVM_DLLTOOL_DLLTOOLDRIVER_H
+#define LLVM_TOOLDRIVERS_LLVM_DLLTOOL_DLLTOOLDRIVER_H
+
+namespace llvm {
+template <typename T> class ArrayRef;
+
+int dlltoolDriverMain(ArrayRef<const char *> ArgsArr);
+} // namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/LibDriver/LibDriver.h b/contrib/llvm/include/llvm/ToolDrivers/llvm-lib/LibDriver.h
index 95feb60..a4806ac 100644
--- a/contrib/llvm/include/llvm/LibDriver/LibDriver.h
+++ b/contrib/llvm/include/llvm/ToolDrivers/llvm-lib/LibDriver.h
@@ -1,4 +1,4 @@
-//===- llvm/LibDriver/LibDriver.h - lib.exe-compatible driver ---*- C++ -*-===//
+//===- llvm-lib/LibDriver.h - lib.exe-compatible driver ---------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIBDRIVER_LIBDRIVER_H
-#define LLVM_LIBDRIVER_LIBDRIVER_H
+#ifndef LLVM_TOOLDRIVERS_LLVM_LIB_LIBDRIVER_H
+#define LLVM_TOOLDRIVERS_LLVM_LIB_LIBDRIVER_H
namespace llvm {
template <typename T> class ArrayRef;
diff --git a/contrib/llvm/include/llvm/Transforms/IPO.h b/contrib/llvm/include/llvm/Transforms/IPO.h
index dd55062..39ceb19 100644
--- a/contrib/llvm/include/llvm/Transforms/IPO.h
+++ b/contrib/llvm/include/llvm/Transforms/IPO.h
@@ -50,12 +50,12 @@ ModulePass *createStripNonLineTableDebugInfoPass();
//===----------------------------------------------------------------------===//
//
-// These pass removes llvm.dbg.declare intrinsics.
+// This pass removes llvm.dbg.declare intrinsics.
ModulePass *createStripDebugDeclarePass();
//===----------------------------------------------------------------------===//
//
-// These pass removes unused symbols' debug info.
+// This pass removes unused symbols' debug info.
ModulePass *createStripDeadDebugInfoPass();
//===----------------------------------------------------------------------===//
@@ -108,7 +108,8 @@ Pass *createFunctionImportPass();
/// threshold given here.
Pass *createFunctionInliningPass();
Pass *createFunctionInliningPass(int Threshold);
-Pass *createFunctionInliningPass(unsigned OptLevel, unsigned SizeOptLevel);
+Pass *createFunctionInliningPass(unsigned OptLevel, unsigned SizeOptLevel,
+ bool DisableInlineHotCallSite);
Pass *createFunctionInliningPass(InlineParams &Params);
//===----------------------------------------------------------------------===//
@@ -215,27 +216,42 @@ ModulePass *createMetaRenamerPass();
/// manager.
ModulePass *createBarrierNoopPass();
-/// What to do with the summary when running the LowerTypeTests pass.
-enum class LowerTypeTestsSummaryAction {
+/// What to do with the summary when running passes that operate on it.
+enum class PassSummaryAction {
None, ///< Do nothing.
- Import, ///< Import typeid resolutions from summary and globals.
- Export, ///< Export typeid resolutions to summary and globals.
+ Import, ///< Import information from summary.
+ Export, ///< Export information to summary.
};
/// \brief This pass lowers type metadata and the llvm.type.test intrinsic to
/// bitsets.
-/// \param Action What to do with the summary passed as Index.
-/// \param Index The summary to use for importing or exporting, this can be null
-/// when Action is None.
-ModulePass *createLowerTypeTestsPass(LowerTypeTestsSummaryAction Action,
- ModuleSummaryIndex *Index);
+///
+/// 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.
+ModulePass *createLowerTypeTestsPass(ModuleSummaryIndex *ExportSummary,
+ const ModuleSummaryIndex *ImportSummary);
/// \brief This pass export CFI checks for use by external modules.
ModulePass *createCrossDSOCFIPass();
/// \brief This pass implements whole-program devirtualization using type
/// metadata.
-ModulePass *createWholeProgramDevirtPass();
+///
+/// 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.
+ModulePass *
+createWholeProgramDevirtPass(ModuleSummaryIndex *ExportSummary,
+ const ModuleSummaryIndex *ImportSummary);
/// This pass splits globals into pieces for the benefit of whole-program
/// devirtualization and control-flow integrity.
@@ -248,7 +264,8 @@ ModulePass *createSampleProfileLoaderPass();
ModulePass *createSampleProfileLoaderPass(StringRef Name);
/// Write ThinLTO-ready bitcode to Str.
-ModulePass *createWriteThinLTOBitcodePass(raw_ostream &Str);
+ModulePass *createWriteThinLTOBitcodePass(raw_ostream &Str,
+ raw_ostream *ThinLinkOS = nullptr);
} // End llvm namespace
diff --git a/contrib/llvm/include/llvm/Transforms/IPO/ArgumentPromotion.h b/contrib/llvm/include/llvm/Transforms/IPO/ArgumentPromotion.h
new file mode 100644
index 0000000..724ff72
--- /dev/null
+++ b/contrib/llvm/include/llvm/Transforms/IPO/ArgumentPromotion.h
@@ -0,0 +1,31 @@
+//===- ArgumentPromotion.h - Promote by-reference arguments -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_IPO_ARGUMENTPROMOTION_H
+#define LLVM_TRANSFORMS_IPO_ARGUMENTPROMOTION_H
+
+#include "llvm/Analysis/CGSCCPassManager.h"
+#include "llvm/Analysis/LazyCallGraph.h"
+
+namespace llvm {
+
+/// Argument promotion pass.
+///
+/// This pass walks the functions in each SCC and for each one tries to
+/// transform it and all of its callers to replace indirect arguments with
+/// direct (by-value) arguments.
+class ArgumentPromotionPass : public PassInfoMixin<ArgumentPromotionPass> {
+public:
+ PreservedAnalyses run(LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM,
+ LazyCallGraph &CG, CGSCCUpdateResult &UR);
+};
+
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/Transforms/IPO/FunctionAttrs.h b/contrib/llvm/include/llvm/Transforms/IPO/FunctionAttrs.h
index ee45f35..36dd06b 100644
--- a/contrib/llvm/include/llvm/Transforms/IPO/FunctionAttrs.h
+++ b/contrib/llvm/include/llvm/Transforms/IPO/FunctionAttrs.h
@@ -14,12 +14,25 @@
#ifndef LLVM_TRANSFORMS_IPO_FUNCTIONATTRS_H
#define LLVM_TRANSFORMS_IPO_FUNCTIONATTRS_H
-#include "llvm/Analysis/LazyCallGraph.h"
#include "llvm/Analysis/CGSCCPassManager.h"
+#include "llvm/Analysis/LazyCallGraph.h"
#include "llvm/IR/PassManager.h"
namespace llvm {
+class AAResults;
+
+/// The three kinds of memory access relevant to 'readonly' and
+/// 'readnone' attributes.
+enum MemoryAccessKind {
+ MAK_ReadNone = 0,
+ MAK_ReadOnly = 1,
+ MAK_MayWrite = 2
+};
+
+/// Returns the memory access properties of this copy of the function.
+MemoryAccessKind computeFunctionBodyMemoryAccess(Function &F, AAResults &AAR);
+
/// Computes function attributes in post-order over the call graph.
///
/// By operating in post-order, this pass computes precise attributes for
@@ -43,7 +56,7 @@ Pass *createPostOrderFunctionAttrsLegacyPass();
/// This pass provides a general RPO or "top down" propagation of
/// function attributes. For a few (rare) cases, we can deduce significantly
/// more about function attributes by working in RPO, so this pass
-/// provides the compliment to the post-order pass above where the majority of
+/// provides the complement to the post-order pass above where the majority of
/// deduction is performed.
// FIXME: Currently there is no RPO CGSCC pass structure to slide into and so
// this is a boring module pass, but eventually it should be an RPO CGSCC pass
diff --git a/contrib/llvm/include/llvm/Transforms/IPO/FunctionImport.h b/contrib/llvm/include/llvm/Transforms/IPO/FunctionImport.h
index eaea092..de35cdf 100644
--- a/contrib/llvm/include/llvm/Transforms/IPO/FunctionImport.h
+++ b/contrib/llvm/include/llvm/Transforms/IPO/FunctionImport.h
@@ -53,12 +53,7 @@ public:
: Index(Index), ModuleLoader(std::move(ModuleLoader)) {}
/// Import functions in Module \p M based on the supplied import list.
- /// \p ForceImportReferencedDiscardableSymbols will set the ModuleLinker in
- /// a mode where referenced discarable symbols in the source modules will be
- /// imported as well even if they are not present in the ImportList.
- Expected<bool>
- importFunctions(Module &M, const ImportMapTy &ImportList,
- bool ForceImportReferencedDiscardableSymbols = false);
+ Expected<bool> importFunctions(Module &M, const ImportMapTy &ImportList);
private:
/// The summaries index used to trigger importing.
@@ -86,15 +81,11 @@ public:
/// \p ExportLists contains for each Module the set of globals (GUID) that will
/// be imported by another module, or referenced by such a function. I.e. this
/// is the set of globals that need to be promoted/renamed appropriately.
-///
-/// \p DeadSymbols (optional) contains a list of GUID that are deemed "dead" and
-/// will be ignored for the purpose of importing.
void ComputeCrossModuleImport(
const ModuleSummaryIndex &Index,
const StringMap<GVSummaryMapTy> &ModuleToDefinedGVSummaries,
StringMap<FunctionImporter::ImportMapTy> &ImportLists,
- StringMap<FunctionImporter::ExportSetTy> &ExportLists,
- const DenseSet<GlobalValue::GUID> *DeadSymbols = nullptr);
+ StringMap<FunctionImporter::ExportSetTy> &ExportLists);
/// Compute all the imports for the given module using the Index.
///
@@ -107,9 +98,9 @@ void ComputeCrossModuleImportForModule(
/// Compute all the symbols that are "dead": i.e these that can't be reached
/// in the graph from any of the given symbols listed in
/// \p GUIDPreservedSymbols.
-DenseSet<GlobalValue::GUID>
-computeDeadSymbols(const ModuleSummaryIndex &Index,
- const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols);
+void computeDeadSymbols(
+ ModuleSummaryIndex &Index,
+ const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols);
/// Compute the set of summaries needed for a ThinLTO backend compilation of
/// \p ModulePath.
diff --git a/contrib/llvm/include/llvm/Transforms/IPO/GlobalDCE.h b/contrib/llvm/include/llvm/Transforms/IPO/GlobalDCE.h
index 57e174c..9ca939c 100644
--- a/contrib/llvm/include/llvm/Transforms/IPO/GlobalDCE.h
+++ b/contrib/llvm/include/llvm/Transforms/IPO/GlobalDCE.h
@@ -18,6 +18,8 @@
#ifndef LLVM_TRANSFORMS_IPO_GLOBALDCE_H
#define LLVM_TRANSFORMS_IPO_GLOBALDCE_H
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallSet.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/PassManager.h"
#include <unordered_map>
@@ -31,14 +33,23 @@ public:
private:
SmallPtrSet<GlobalValue*, 32> AliveGlobals;
- SmallPtrSet<Constant *, 8> SeenConstants;
+
+ /// Global -> Global that uses this global.
+ std::unordered_multimap<GlobalValue *, GlobalValue *> GVDependencies;
+
+ /// Constant -> Globals that use this global cache.
+ std::unordered_map<Constant *, SmallPtrSet<GlobalValue *, 8>>
+ ConstantDependenciesCache;
+
+ /// Comdat -> Globals in that Comdat section.
std::unordered_multimap<Comdat *, GlobalValue *> ComdatMembers;
- /// Mark the specific global value as needed, and
- /// recursively mark anything that it uses as also needed.
- void GlobalIsNeeded(GlobalValue *GV);
- void MarkUsedGlobalsAsNeeded(Constant *C);
+ void UpdateGVDependencies(GlobalValue &GV);
+ void MarkLive(GlobalValue &GV,
+ SmallVectorImpl<GlobalValue *> *Updates = nullptr);
bool RemoveUnusedGlobalValue(GlobalValue &GV);
+
+ void ComputeDependencies(Value *V, SmallPtrSetImpl<GlobalValue *> &U);
};
}
diff --git a/contrib/llvm/include/llvm/Transforms/IPO/LowerTypeTests.h b/contrib/llvm/include/llvm/Transforms/IPO/LowerTypeTests.h
index ca6e1b8..a2b888c 100644
--- a/contrib/llvm/include/llvm/Transforms/IPO/LowerTypeTests.h
+++ b/contrib/llvm/include/llvm/Transforms/IPO/LowerTypeTests.h
@@ -15,11 +15,9 @@
#ifndef LLVM_TRANSFORMS_IPO_LOWERTYPETESTS_H
#define LLVM_TRANSFORMS_IPO_LOWERTYPETESTS_H
-#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/PassManager.h"
-
#include <cstdint>
#include <cstring>
#include <limits>
@@ -28,9 +26,6 @@
namespace llvm {
-class DataLayout;
-class GlobalObject;
-class Value;
class raw_ostream;
namespace lowertypetests {
@@ -65,9 +60,10 @@ struct BitSetInfo {
struct BitSetBuilder {
SmallVector<uint64_t, 16> Offsets;
- uint64_t Min, Max;
+ uint64_t Min = std::numeric_limits<uint64_t>::max();
+ uint64_t Max = 0;
- BitSetBuilder() : Min(std::numeric_limits<uint64_t>::max()), Max(0) {}
+ BitSetBuilder() = default;
void addOffset(uint64_t Offset) {
if (Min > Offset)
diff --git a/contrib/llvm/include/llvm/Transforms/IPO/PassManagerBuilder.h b/contrib/llvm/include/llvm/Transforms/IPO/PassManagerBuilder.h
index abfb24f..276306f 100644
--- a/contrib/llvm/include/llvm/Transforms/IPO/PassManagerBuilder.h
+++ b/contrib/llvm/include/llvm/Transforms/IPO/PassManagerBuilder.h
@@ -21,6 +21,7 @@
#include <vector>
namespace llvm {
+class ModuleSummaryIndex;
class Pass;
class TargetLibraryInfoImpl;
class TargetMachine;
@@ -100,6 +101,14 @@ public:
/// will be inserted after each instance of the instruction combiner pass.
EP_Peephole,
+ /// EP_LateLoopOptimizations - This extension point allows adding late loop
+ /// canonicalization and simplification passes. This is the last point in
+ /// the loop optimization pipeline before loop deletion. Each pass added
+ /// here must be an instance of LoopPass.
+ /// This is the place to add passes that can remove loops, such as target-
+ /// specific loop idiom recognition.
+ EP_LateLoopOptimizations,
+
/// EP_CGSCCOptimizerLate - This extension point allows adding CallGraphSCC
/// passes at the end of the main CallGraphSCC passes and before any
/// function simplification passes run by CGPassManager.
@@ -123,14 +132,22 @@ public:
/// added to the per-module passes.
Pass *Inliner;
+ /// The module summary index to use for exporting information from the
+ /// regular LTO phase, for example for the CFI and devirtualization type
+ /// tests.
+ ModuleSummaryIndex *ExportSummary = nullptr;
+
+ /// The module summary index to use for importing information to the
+ /// thin LTO backends, for example for the CFI and devirtualization type
+ /// tests.
+ const ModuleSummaryIndex *ImportSummary = nullptr;
+
bool DisableTailCalls;
bool DisableUnitAtATime;
bool DisableUnrollLoops;
- bool BBVectorize;
bool SLPVectorize;
bool LoopVectorize;
bool RerollLoops;
- bool LoadCombine;
bool NewGVN;
bool DisableGVNLoadPRE;
bool VerifyInput;
@@ -139,6 +156,7 @@ public:
bool PrepareForLTO;
bool PrepareForThinLTO;
bool PerformThinLTO;
+ bool DivergentTarget;
/// Enable profile instrumentation pass.
bool EnablePGOInstrGen;
diff --git a/contrib/llvm/include/llvm/Transforms/IPO/ThinLTOBitcodeWriter.h b/contrib/llvm/include/llvm/Transforms/IPO/ThinLTOBitcodeWriter.h
new file mode 100644
index 0000000..bf04bbf
--- /dev/null
+++ b/contrib/llvm/include/llvm/Transforms/IPO/ThinLTOBitcodeWriter.h
@@ -0,0 +1,41 @@
+//===- ThinLTOBitcodeWriter.h - Bitcode writing pass for ThinLTO ----------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This pass prepares a module containing type metadata for ThinLTO by splitting
+// it into regular and thin LTO parts if possible, and writing both parts to
+// a multi-module bitcode file. Modules that do not contain type metadata are
+// written unmodified as a single module.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_IPO_THINLTOBITCODEWRITER_H
+#define LLVM_TRANSFORMS_IPO_THINLTOBITCODEWRITER_H
+
+#include <llvm/IR/PassManager.h>
+#include <llvm/Support/raw_ostream.h>
+
+namespace llvm {
+
+class ThinLTOBitcodeWriterPass
+ : public PassInfoMixin<ThinLTOBitcodeWriterPass> {
+ raw_ostream &OS;
+ raw_ostream *ThinLinkOS;
+
+public:
+ // Writes bitcode to OS. Also write thin link file to ThinLinkOS, if
+ // it's not nullptr.
+ ThinLTOBitcodeWriterPass(raw_ostream &OS, raw_ostream *ThinLinkOS)
+ : OS(OS), ThinLinkOS(ThinLinkOS) {}
+
+ PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
+};
+
+} // namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/Transforms/InstrProfiling.h b/contrib/llvm/include/llvm/Transforms/InstrProfiling.h
index b7c2935..0fe6ad5 100644
--- a/contrib/llvm/include/llvm/Transforms/InstrProfiling.h
+++ b/contrib/llvm/include/llvm/Transforms/InstrProfiling.h
@@ -1,4 +1,4 @@
-//===- Transforms/InstrProfiling.h - Instrumentation passes ---*- C++ -*-===//
+//===- Transforms/InstrProfiling.h - Instrumentation passes -----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,21 +14,28 @@
#ifndef LLVM_TRANSFORMS_INSTRPROFILING_H
#define LLVM_TRANSFORMS_INSTRPROFILING_H
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/PassManager.h"
#include "llvm/ProfileData/InstrProf.h"
#include "llvm/Transforms/Instrumentation.h"
+#include <cstddef>
+#include <cstdint>
+#include <cstring>
+#include <vector>
namespace llvm {
class TargetLibraryInfo;
+using LoadStorePair = std::pair<Instruction *, Instruction *>;
/// Instrumentation based profiling lowering pass. This pass lowers
/// the profile instrumented code generated by FE or the IR based
/// instrumentation pass.
class InstrProfiling : public PassInfoMixin<InstrProfiling> {
public:
- InstrProfiling() {}
+ InstrProfiling() = default;
InstrProfiling(const InstrProfOptions &Options) : Options(Options) {}
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
@@ -37,12 +44,14 @@ public:
private:
InstrProfOptions Options;
Module *M;
+ Triple TT;
const TargetLibraryInfo *TLI;
struct PerFunctionProfileData {
uint32_t NumValueSites[IPVK_Last + 1];
- GlobalVariable *RegionCounters;
- GlobalVariable *DataVar;
- PerFunctionProfileData() : RegionCounters(nullptr), DataVar(nullptr) {
+ GlobalVariable *RegionCounters = nullptr;
+ GlobalVariable *DataVar = nullptr;
+
+ PerFunctionProfileData() {
memset(NumValueSites, 0, sizeof(uint32_t) * (IPVK_Last + 1));
}
};
@@ -52,19 +61,25 @@ private:
GlobalVariable *NamesVar;
size_t NamesSize;
- bool isMachO() const;
+ // vector of counter load/store pairs to be register promoted.
+ std::vector<LoadStorePair> PromotionCandidates;
+
+ // The start value of precise value profile range for memory intrinsic sizes.
+ int64_t MemOPSizeRangeStart;
+ // The end value of precise value profile range for memory intrinsic sizes.
+ int64_t MemOPSizeRangeLast;
- /// Get the section name for the counter variables.
- StringRef getCountersSection() const;
+ int64_t TotalCountersPromoted = 0;
- /// Get the section name for the name variables.
- StringRef getNameSection() const;
+ /// Lower instrumentation intrinsics in the function. Returns true if there
+ /// any lowering.
+ bool lowerIntrinsics(Function *F);
- /// Get the section name for the profile data variables.
- StringRef getDataSection() const;
+ /// Register-promote counter loads and stores in loops.
+ void promoteCounterLoadStores(Function *F);
- /// Get the section name for the coverage mapping data.
- StringRef getCoverageSection() const;
+ /// Returns true if profile counter update register promotion is enabled.
+ bool isCounterPromotionEnabled() const;
/// Count the number of instrumented value sites for the function.
void computeNumValueSiteCounts(InstrProfValueProfileInst *Ins);
@@ -104,5 +119,6 @@ private:
void emitInitialization();
};
-} // End llvm namespace
-#endif
+} // end namespace llvm
+
+#endif // LLVM_TRANSFORMS_INSTRPROFILING_H
diff --git a/contrib/llvm/include/llvm/Transforms/Instrumentation.h b/contrib/llvm/include/llvm/Transforms/Instrumentation.h
index 7fb9a54..f2fc6dc 100644
--- a/contrib/llvm/include/llvm/Transforms/Instrumentation.h
+++ b/contrib/llvm/include/llvm/Transforms/Instrumentation.h
@@ -16,6 +16,10 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/IR/BasicBlock.h"
+#include <cassert>
+#include <cstdint>
+#include <limits>
+#include <string>
#include <vector>
#if defined(__GNUC__) && defined(__linux__) && !defined(ANDROID)
@@ -34,7 +38,8 @@ inline void *getDFSanRetValTLSPtrForJIT() {
namespace llvm {
-class TargetMachine;
+class FunctionPass;
+class ModulePass;
/// Instrumentation passes often insert conditional checks into entry blocks.
/// Call this function before splitting the entry block to move instructions
@@ -44,9 +49,6 @@ class TargetMachine;
BasicBlock::iterator PrepareToSplitEntryBlock(BasicBlock &BB,
BasicBlock::iterator IP);
-class ModulePass;
-class FunctionPass;
-
// Insert GCOV profiling instrumentation
struct GCOVOptions {
static GCOVOptions getDefault();
@@ -76,6 +78,7 @@ struct GCOVOptions {
// all of the function body's blocks.
bool ExitBlockBeforeBody;
};
+
ModulePass *createGCOVProfilerPass(const GCOVOptions &Options =
GCOVOptions::getDefault());
@@ -83,17 +86,43 @@ ModulePass *createGCOVProfilerPass(const GCOVOptions &Options =
ModulePass *createPGOInstrumentationGenLegacyPass();
ModulePass *
createPGOInstrumentationUseLegacyPass(StringRef Filename = StringRef(""));
-ModulePass *createPGOIndirectCallPromotionLegacyPass(bool InLTO = false);
+ModulePass *createPGOIndirectCallPromotionLegacyPass(bool InLTO = false,
+ bool SamplePGO = false);
+FunctionPass *createPGOMemOPSizeOptLegacyPass();
+
+// Helper function to check if it is legal to promote indirect call \p Inst
+// to a direct call of function \p F. Stores the reason in \p Reason.
+bool isLegalToPromote(Instruction *Inst, Function *F, const char **Reason);
+
+// Helper function that transforms Inst (either an indirect-call instruction, or
+// an invoke instruction , to a conditional call to F. This is like:
+// if (Inst.CalledValue == F)
+// F(...);
+// else
+// Inst(...);
+// end
+// TotalCount is the profile count value that the instruction executes.
+// Count is the profile count value that F is the target function.
+// These two values are used to update the branch weight.
+// 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);
/// Options for the frontend instrumentation based profiling pass.
struct InstrProfOptions {
- InstrProfOptions() : NoRedZone(false) {}
-
// Add the 'noredzone' attribute to added runtime library calls.
- bool NoRedZone;
+ bool NoRedZone = false;
+
+ // Do counter register promotion
+ bool DoCounterPromotion = false;
// Name of the profile file to use as output
std::string InstrProfileOutput;
+
+ InstrProfOptions() = default;
};
/// Insert frontend instrumentation based profiling.
@@ -105,7 +134,8 @@ FunctionPass *createAddressSanitizerFunctionPass(bool CompileKernel = false,
bool Recover = false,
bool UseAfterScope = false);
ModulePass *createAddressSanitizerModulePass(bool CompileKernel = false,
- bool Recover = false);
+ bool Recover = false,
+ bool UseGlobalsGC = true);
// Insert MemorySanitizer instrumentation (detection of uninitialized reads)
FunctionPass *createMemorySanitizerPass(int TrackOrigins = 0,
@@ -121,12 +151,13 @@ ModulePass *createDataFlowSanitizerPass(
// Options for EfficiencySanitizer sub-tools.
struct EfficiencySanitizerOptions {
- EfficiencySanitizerOptions() : ToolType(ESAN_None) {}
enum Type {
ESAN_None = 0,
ESAN_CacheFrag,
ESAN_WorkingSet,
- } ToolType;
+ } ToolType = ESAN_None;
+
+ EfficiencySanitizerOptions() = default;
};
// Insert EfficiencySanitizer instrumentation.
@@ -135,25 +166,24 @@ ModulePass *createEfficiencySanitizerPass(
// Options for sanitizer coverage instrumentation.
struct SanitizerCoverageOptions {
- SanitizerCoverageOptions()
- : CoverageType(SCK_None), IndirectCalls(false), TraceBB(false),
- TraceCmp(false), TraceDiv(false), TraceGep(false),
- Use8bitCounters(false), TracePC(false), TracePCGuard(false) {}
-
enum Type {
SCK_None = 0,
SCK_Function,
SCK_BB,
SCK_Edge
- } CoverageType;
- bool IndirectCalls;
- bool TraceBB;
- bool TraceCmp;
- bool TraceDiv;
- bool TraceGep;
- bool Use8bitCounters;
- bool TracePC;
- bool TracePCGuard;
+ } CoverageType = SCK_None;
+ bool IndirectCalls = false;
+ bool TraceBB = false;
+ bool TraceCmp = false;
+ bool TraceDiv = false;
+ bool TraceGep = false;
+ bool Use8bitCounters = false;
+ bool TracePC = false;
+ bool TracePCGuard = false;
+ bool Inline8bitCounters = false;
+ bool NoPrune = false;
+
+ SanitizerCoverageOptions() = default;
};
// Insert SanitizerCoverage instrumentation.
@@ -175,9 +205,11 @@ FunctionPass *createBoundsCheckingPass();
/// \brief Calculate what to divide by to scale counts.
///
/// Given the maximum count, calculate a divisor that will scale all the
-/// weights to strictly less than UINT32_MAX.
+/// weights to strictly less than std::numeric_limits<uint32_t>::max().
static inline uint64_t calculateCountScale(uint64_t MaxCount) {
- return MaxCount < UINT32_MAX ? 1 : MaxCount / UINT32_MAX + 1;
+ return MaxCount < std::numeric_limits<uint32_t>::max()
+ ? 1
+ : MaxCount / std::numeric_limits<uint32_t>::max() + 1;
}
/// \brief Scale an individual branch count.
@@ -186,10 +218,10 @@ static inline uint64_t calculateCountScale(uint64_t MaxCount) {
///
static inline uint32_t scaleBranchCount(uint64_t Count, uint64_t Scale) {
uint64_t Scaled = Count / Scale;
- assert(Scaled <= UINT32_MAX && "overflow 32-bits");
+ assert(Scaled <= std::numeric_limits<uint32_t>::max() && "overflow 32-bits");
return Scaled;
}
-} // End llvm namespace
+} // end namespace llvm
-#endif
+#endif // LLVM_TRANSFORMS_INSTRUMENTATION_H
diff --git a/contrib/llvm/include/llvm/Transforms/PGOInstrumentation.h b/contrib/llvm/include/llvm/Transforms/PGOInstrumentation.h
index 1b449c9..19263f0 100644
--- a/contrib/llvm/include/llvm/Transforms/PGOInstrumentation.h
+++ b/contrib/llvm/include/llvm/Transforms/PGOInstrumentation.h
@@ -38,11 +38,24 @@ private:
/// The indirect function call promotion pass.
class PGOIndirectCallPromotion : public PassInfoMixin<PGOIndirectCallPromotion> {
public:
- PGOIndirectCallPromotion(bool IsInLTO = false) : InLTO(IsInLTO) {}
+ PGOIndirectCallPromotion(bool IsInLTO = false, bool SamplePGO = false)
+ : InLTO(IsInLTO), SamplePGO(SamplePGO) {}
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
+
private:
bool InLTO;
+ bool SamplePGO;
};
+/// The profile size based optimization pass for memory intrinsics.
+class PGOMemOPSizeOpt : public PassInfoMixin<PGOMemOPSizeOpt> {
+public:
+ PGOMemOPSizeOpt() {}
+ PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
+};
+
+void setProfMetadata(Module *M, Instruction *TI, ArrayRef<uint64_t> EdgeCounts,
+ uint64_t MaxCount);
+
} // End llvm namespace
#endif
diff --git a/contrib/llvm/include/llvm/Transforms/SampleProfile.h b/contrib/llvm/include/llvm/Transforms/SampleProfile.h
index 93fa953..c984fe7 100644
--- a/contrib/llvm/include/llvm/Transforms/SampleProfile.h
+++ b/contrib/llvm/include/llvm/Transforms/SampleProfile.h
@@ -21,6 +21,10 @@ namespace llvm {
class SampleProfileLoaderPass : public PassInfoMixin<SampleProfileLoaderPass> {
public:
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
+ SampleProfileLoaderPass(std::string File = "") : ProfileFileName(File) {}
+
+private:
+ std::string ProfileFileName;
};
} // End llvm namespace
diff --git a/contrib/llvm/include/llvm/Transforms/Scalar.h b/contrib/llvm/include/llvm/Transforms/Scalar.h
index 9255893..1913a9d 100644
--- a/contrib/llvm/include/llvm/Transforms/Scalar.h
+++ b/contrib/llvm/include/llvm/Transforms/Scalar.h
@@ -147,6 +147,12 @@ Pass *createLoopSinkPass();
//===----------------------------------------------------------------------===//
//
+// LoopPredication - This pass does loop predication on guards.
+//
+Pass *createLoopPredicationPass();
+
+//===----------------------------------------------------------------------===//
+//
// LoopInterchange - This pass interchanges loops to provide a more
// cache-friendly memory access patterns.
//
@@ -163,7 +169,8 @@ Pass *createLoopStrengthReducePass();
//
// LoopUnswitch - This pass is a simple loop unswitching pass.
//
-Pass *createLoopUnswitchPass(bool OptimizeForSize = false);
+Pass *createLoopUnswitchPass(bool OptimizeForSize = false,
+ bool hasBranchDivergence = false);
//===----------------------------------------------------------------------===//
//
@@ -175,11 +182,11 @@ Pass *createLoopInstSimplifyPass();
//
// LoopUnroll - This pass is a simple loop unrolling pass.
//
-Pass *createLoopUnrollPass(int Threshold = -1, int Count = -1,
+Pass *createLoopUnrollPass(int OptLevel = 2, int Threshold = -1, int Count = -1,
int AllowPartial = -1, int Runtime = -1,
int UpperBound = -1);
// Create an unrolling pass for full unrolling that uses exact trip count only.
-Pass *createSimpleLoopUnrollPass();
+Pass *createSimpleLoopUnrollPass(int OptLevel = 2);
//===----------------------------------------------------------------------===//
//
@@ -255,6 +262,14 @@ FunctionPass *createCFGSimplificationPass(
//===----------------------------------------------------------------------===//
//
+// LateCFGSimplification - Like CFGSimplification, but may also
+// convert switches to lookup tables.
+//
+FunctionPass *createLateCFGSimplificationPass(
+ int Threshold = -1, std::function<bool(const Function &)> Ftor = nullptr);
+
+//===----------------------------------------------------------------------===//
+//
// FlattenCFG - flatten CFG, reduce number of conditional branches by using
// parallel-and and parallel-or mode, etc...
//
@@ -341,6 +356,13 @@ FunctionPass *createGVNHoistPass();
//===----------------------------------------------------------------------===//
//
+// GVNSink - This pass uses an "inverted" value numbering to decide the
+// similarity of expressions and sinks similar expressions into successors.
+//
+FunctionPass *createGVNSinkPass();
+
+//===----------------------------------------------------------------------===//
+//
// MergedLoadStoreMotion - This pass merges loads and stores in diamonds. Loads
// are hoisted into the header, while stores sink into the footer.
//
@@ -406,6 +428,15 @@ Pass *createCorrelatedValuePropagationPass();
//===----------------------------------------------------------------------===//
//
+// InferAddressSpaces - Modify users of addrspacecast instructions with values
+// in the source address space if using the destination address space is slower
+// on the target.
+//
+FunctionPass *createInferAddressSpacesPass();
+extern char &InferAddressSpacesID;
+
+//===----------------------------------------------------------------------===//
+//
// InstructionSimplifier - Remove redundant instructions.
//
FunctionPass *createInstructionSimplifierPass();
@@ -456,12 +487,6 @@ FunctionPass *createSpeculativeExecutionIfHasBranchDivergencePass();
//===----------------------------------------------------------------------===//
//
-// LoadCombine - Combine loads into bigger loads.
-//
-BasicBlockPass *createLoadCombinePass();
-
-//===----------------------------------------------------------------------===//
-//
// StraightLineStrengthReduce - This pass strength-reduces some certain
// instruction patterns in straight-line code.
//
diff --git a/contrib/llvm/include/llvm/Transforms/Scalar/ConstantHoisting.h b/contrib/llvm/include/llvm/Transforms/Scalar/ConstantHoisting.h
index 3e2b332..a2a9afc 100644
--- a/contrib/llvm/include/llvm/Transforms/Scalar/ConstantHoisting.h
+++ b/contrib/llvm/include/llvm/Transforms/Scalar/ConstantHoisting.h
@@ -36,6 +36,7 @@
#ifndef LLVM_TRANSFORMS_SCALAR_CONSTANTHOISTING_H
#define LLVM_TRANSFORMS_SCALAR_CONSTANTHOISTING_H
+#include "llvm/Analysis/BlockFrequencyInfo.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/PassManager.h"
@@ -98,7 +99,7 @@ public:
// Glue for old PM.
bool runImpl(Function &F, TargetTransformInfo &TTI, DominatorTree &DT,
- BasicBlock &Entry);
+ BlockFrequencyInfo *BFI, BasicBlock &Entry);
void releaseMemory() {
ConstantVec.clear();
@@ -112,6 +113,7 @@ private:
const TargetTransformInfo *TTI;
DominatorTree *DT;
+ BlockFrequencyInfo *BFI;
BasicBlock *Entry;
/// Keeps track of constant candidates found in the function.
@@ -124,12 +126,14 @@ private:
SmallVector<consthoist::ConstantInfo, 8> ConstantVec;
Instruction *findMatInsertPt(Instruction *Inst, unsigned Idx = ~0U) const;
- Instruction *findConstantInsertionPoint(
- const consthoist::ConstantInfo &ConstInfo) const;
+ SmallPtrSet<Instruction *, 8>
+ findConstantInsertionPoint(const consthoist::ConstantInfo &ConstInfo) const;
void collectConstantCandidates(ConstCandMapType &ConstCandMap,
Instruction *Inst, unsigned Idx,
ConstantInt *ConstInt);
void collectConstantCandidates(ConstCandMapType &ConstCandMap,
+ Instruction *Inst, unsigned Idx);
+ void collectConstantCandidates(ConstCandMapType &ConstCandMap,
Instruction *Inst);
void collectConstantCandidates(Function &Fn);
void findAndMakeBaseConstant(ConstCandVecType::iterator S,
diff --git a/contrib/llvm/include/llvm/Transforms/Scalar/Float2Int.h b/contrib/llvm/include/llvm/Transforms/Scalar/Float2Int.h
index a804239..206ee98 100644
--- a/contrib/llvm/include/llvm/Transforms/Scalar/Float2Int.h
+++ b/contrib/llvm/include/llvm/Transforms/Scalar/Float2Int.h
@@ -31,7 +31,7 @@ public:
private:
void findRoots(Function &F, SmallPtrSet<Instruction *, 8> &Roots);
- ConstantRange seen(Instruction *I, ConstantRange R);
+ void seen(Instruction *I, ConstantRange R);
ConstantRange badRange();
ConstantRange unknownRange();
ConstantRange validateRange(ConstantRange R);
diff --git a/contrib/llvm/include/llvm/Transforms/Scalar/GVN.h b/contrib/llvm/include/llvm/Transforms/Scalar/GVN.h
index 8f05e8c..f25ab40 100644
--- a/contrib/llvm/include/llvm/Transforms/Scalar/GVN.h
+++ b/contrib/llvm/include/llvm/Transforms/Scalar/GVN.h
@@ -209,7 +209,7 @@ private:
// Other helper routines
bool processInstruction(Instruction *I);
bool processBlock(BasicBlock *BB);
- void dump(DenseMap<uint32_t, Value *> &d);
+ void dump(DenseMap<uint32_t, Value *> &d) const;
bool iterateOnFunction(Function &F);
bool performPRE(Function &F);
bool performScalarPRE(Instruction *I);
@@ -238,7 +238,12 @@ struct GVNHoistPass : PassInfoMixin<GVNHoistPass> {
/// \brief Run the pass over the function.
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
};
-
+/// \brief Uses an "inverted" value numbering to decide the similarity of
+/// expressions and sinks similar expressions into successors.
+struct GVNSinkPass : PassInfoMixin<GVNSinkPass> {
+ /// \brief Run the pass over the function.
+ PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
+};
}
#endif
diff --git a/contrib/llvm/include/llvm/Transforms/Scalar/GVNExpression.h b/contrib/llvm/include/llvm/Transforms/Scalar/GVNExpression.h
index 3458696..f603ebc 100644
--- a/contrib/llvm/include/llvm/Transforms/Scalar/GVNExpression.h
+++ b/contrib/llvm/include/llvm/Transforms/Scalar/GVNExpression.h
@@ -1,4 +1,4 @@
-//======- GVNExpression.h - GVN Expression classes -------*- C++ -*-==-------=//
+//======- GVNExpression.h - GVN Expression classes --------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -17,18 +17,22 @@
#define LLVM_TRANSFORMS_SCALAR_GVNEXPRESSION_H
#include "llvm/ADT/Hashing.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/Analysis/MemorySSA.h"
#include "llvm/IR/Constant.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Value.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/ArrayRecycler.h"
+#include "llvm/Support/Casting.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/Transforms/Utils/MemorySSA.h"
#include <algorithm>
+#include <cassert>
+#include <iterator>
+#include <utility>
namespace llvm {
-class MemoryAccess;
namespace GVNExpression {
@@ -36,14 +40,17 @@ enum ExpressionType {
ET_Base,
ET_Constant,
ET_Variable,
+ ET_Dead,
ET_Unknown,
ET_BasicStart,
ET_Basic,
- ET_Call,
ET_AggregateValue,
ET_Phi,
+ ET_MemoryStart,
+ ET_Call,
ET_Load,
ET_Store,
+ ET_MemoryEnd,
ET_BasicEnd
};
@@ -51,41 +58,53 @@ class Expression {
private:
ExpressionType EType;
unsigned Opcode;
+ mutable hash_code HashVal;
public:
- Expression(const Expression &) = delete;
Expression(ExpressionType ET = ET_Base, unsigned O = ~2U)
- : EType(ET), Opcode(O) {}
- void operator=(const Expression &) = delete;
+ : EType(ET), Opcode(O), HashVal(0) {}
+ Expression(const Expression &) = delete;
+ Expression &operator=(const Expression &) = delete;
virtual ~Expression();
static unsigned getEmptyKey() { return ~0U; }
static unsigned getTombstoneKey() { return ~1U; }
-
+ bool operator!=(const Expression &Other) const { return !(*this == Other); }
bool operator==(const Expression &Other) const {
if (getOpcode() != Other.getOpcode())
return false;
if (getOpcode() == getEmptyKey() || getOpcode() == getTombstoneKey())
return true;
// Compare the expression type for anything but load and store.
- // For load and store we set the opcode to zero.
- // This is needed for load coercion.
+ // For load and store we set the opcode to zero to make them equal.
if (getExpressionType() != ET_Load && getExpressionType() != ET_Store &&
getExpressionType() != Other.getExpressionType())
return false;
return equals(Other);
}
+ hash_code getComputedHash() const {
+ // It's theoretically possible for a thing to hash to zero. In that case,
+ // we will just compute the hash a few extra times, which is no worse that
+ // we did before, which was to compute it always.
+ if (static_cast<unsigned>(HashVal) == 0)
+ HashVal = getHashValue();
+ return HashVal;
+ }
virtual bool equals(const Expression &Other) const { return true; }
+ // Return true if the two expressions are exactly the same, including the
+ // normally ignored fields.
+ virtual bool exactlyEquals(const Expression &Other) const {
+ return getExpressionType() == Other.getExpressionType() && equals(Other);
+ }
unsigned getOpcode() const { return Opcode; }
void setOpcode(unsigned opcode) { Opcode = opcode; }
ExpressionType getExpressionType() const { return EType; }
- virtual hash_code getHashValue() const {
- return hash_combine(getExpressionType(), getOpcode());
- }
+ // We deliberately leave the expression type out of the hash value.
+ virtual hash_code getHashValue() const { return getOpcode(); }
//
// Debugging support
@@ -101,7 +120,8 @@ public:
printInternal(OS, true);
OS << "}";
}
- void dump() const { print(dbgs()); }
+
+ LLVM_DUMP_METHOD void dump() const;
};
inline raw_ostream &operator<<(raw_ostream &OS, const Expression &E) {
@@ -119,20 +139,20 @@ private:
Type *ValueType;
public:
- static bool classof(const Expression *EB) {
- ExpressionType ET = EB->getExpressionType();
- return ET > ET_BasicStart && ET < ET_BasicEnd;
- }
-
BasicExpression(unsigned NumOperands)
: BasicExpression(NumOperands, ET_Basic) {}
BasicExpression(unsigned NumOperands, ExpressionType ET)
: Expression(ET), Operands(nullptr), MaxOperands(NumOperands),
NumOperands(0), ValueType(nullptr) {}
- virtual ~BasicExpression() override;
- void operator=(const BasicExpression &) = delete;
- BasicExpression(const BasicExpression &) = delete;
BasicExpression() = delete;
+ BasicExpression(const BasicExpression &) = delete;
+ BasicExpression &operator=(const BasicExpression &) = delete;
+ ~BasicExpression() override;
+
+ static bool classof(const Expression *EB) {
+ ExpressionType ET = EB->getExpressionType();
+ return ET > ET_BasicStart && ET < ET_BasicEnd;
+ }
/// \brief Swap two operands. Used during GVN to put commutative operands in
/// order.
@@ -185,7 +205,7 @@ public:
void setType(Type *T) { ValueType = T; }
Type *getType() const { return ValueType; }
- virtual bool equals(const Expression &Other) const override {
+ bool equals(const Expression &Other) const override {
if (getOpcode() != Other.getOpcode())
return false;
@@ -194,15 +214,15 @@ public:
std::equal(op_begin(), op_end(), OE.op_begin());
}
- virtual hash_code getHashValue() const override {
- return hash_combine(getExpressionType(), getOpcode(), ValueType,
+ hash_code getHashValue() const override {
+ return hash_combine(this->Expression::getHashValue(), ValueType,
hash_combine_range(op_begin(), op_end()));
}
//
// Debugging support
//
- virtual void printInternal(raw_ostream &OS, bool PrintEType) const override {
+ void printInternal(raw_ostream &OS, bool PrintEType) const override {
if (PrintEType)
OS << "ExpressionTypeBasic, ";
@@ -216,6 +236,7 @@ public:
OS << "} ";
}
};
+
class op_inserter
: public std::iterator<std::output_iterator_tag, void, void, void, void> {
private:
@@ -235,131 +256,153 @@ public:
op_inserter &operator++(int) { return *this; }
};
-class CallExpression final : public BasicExpression {
+class MemoryExpression : public BasicExpression {
private:
- CallInst *Call;
- MemoryAccess *DefiningAccess;
+ const MemoryAccess *MemoryLeader;
public:
+ MemoryExpression(unsigned NumOperands, enum ExpressionType EType,
+ const MemoryAccess *MemoryLeader)
+ : BasicExpression(NumOperands, EType), MemoryLeader(MemoryLeader){};
+
+ MemoryExpression() = delete;
+ MemoryExpression(const MemoryExpression &) = delete;
+ MemoryExpression &operator=(const MemoryExpression &) = delete;
static bool classof(const Expression *EB) {
- return EB->getExpressionType() == ET_Call;
+ return EB->getExpressionType() > ET_MemoryStart &&
+ EB->getExpressionType() < ET_MemoryEnd;
+ }
+ hash_code getHashValue() const override {
+ return hash_combine(this->BasicExpression::getHashValue(), MemoryLeader);
}
- CallExpression(unsigned NumOperands, CallInst *C, MemoryAccess *DA)
- : BasicExpression(NumOperands, ET_Call), Call(C), DefiningAccess(DA) {}
- void operator=(const CallExpression &) = delete;
- CallExpression(const CallExpression &) = delete;
- CallExpression() = delete;
- virtual ~CallExpression() override;
-
- virtual bool equals(const Expression &Other) const override {
+ bool equals(const Expression &Other) const override {
if (!this->BasicExpression::equals(Other))
return false;
- const auto &OE = cast<CallExpression>(Other);
- return DefiningAccess == OE.DefiningAccess;
+ const MemoryExpression &OtherMCE = cast<MemoryExpression>(Other);
+
+ return MemoryLeader == OtherMCE.MemoryLeader;
}
- virtual hash_code getHashValue() const override {
- return hash_combine(this->BasicExpression::getHashValue(), DefiningAccess);
+ const MemoryAccess *getMemoryLeader() const { return MemoryLeader; }
+ void setMemoryLeader(const MemoryAccess *ML) { MemoryLeader = ML; }
+};
+
+class CallExpression final : public MemoryExpression {
+private:
+ CallInst *Call;
+
+public:
+ CallExpression(unsigned NumOperands, CallInst *C,
+ const MemoryAccess *MemoryLeader)
+ : MemoryExpression(NumOperands, ET_Call, MemoryLeader), Call(C) {}
+ CallExpression() = delete;
+ CallExpression(const CallExpression &) = delete;
+ CallExpression &operator=(const CallExpression &) = delete;
+ ~CallExpression() override;
+
+ static bool classof(const Expression *EB) {
+ return EB->getExpressionType() == ET_Call;
}
//
// Debugging support
//
- virtual void printInternal(raw_ostream &OS, bool PrintEType) const override {
+ void printInternal(raw_ostream &OS, bool PrintEType) const override {
if (PrintEType)
OS << "ExpressionTypeCall, ";
this->BasicExpression::printInternal(OS, false);
- OS << " represents call at " << Call;
+ OS << " represents call at ";
+ Call->printAsOperand(OS);
}
};
-class LoadExpression final : public BasicExpression {
+class LoadExpression final : public MemoryExpression {
private:
LoadInst *Load;
- MemoryAccess *DefiningAccess;
unsigned Alignment;
public:
- static bool classof(const Expression *EB) {
- return EB->getExpressionType() == ET_Load;
- }
-
- LoadExpression(unsigned NumOperands, LoadInst *L, MemoryAccess *DA)
- : LoadExpression(ET_Load, NumOperands, L, DA) {}
+ LoadExpression(unsigned NumOperands, LoadInst *L,
+ const MemoryAccess *MemoryLeader)
+ : LoadExpression(ET_Load, NumOperands, L, MemoryLeader) {}
LoadExpression(enum ExpressionType EType, unsigned NumOperands, LoadInst *L,
- MemoryAccess *DA)
- : BasicExpression(NumOperands, EType), Load(L), DefiningAccess(DA) {
+ const MemoryAccess *MemoryLeader)
+ : MemoryExpression(NumOperands, EType, MemoryLeader), Load(L) {
Alignment = L ? L->getAlignment() : 0;
}
- void operator=(const LoadExpression &) = delete;
- LoadExpression(const LoadExpression &) = delete;
LoadExpression() = delete;
- virtual ~LoadExpression() override;
+ LoadExpression(const LoadExpression &) = delete;
+ LoadExpression &operator=(const LoadExpression &) = delete;
+ ~LoadExpression() override;
+
+ static bool classof(const Expression *EB) {
+ return EB->getExpressionType() == ET_Load;
+ }
LoadInst *getLoadInst() const { return Load; }
void setLoadInst(LoadInst *L) { Load = L; }
- MemoryAccess *getDefiningAccess() const { return DefiningAccess; }
- void setDefiningAccess(MemoryAccess *MA) { DefiningAccess = MA; }
unsigned getAlignment() const { return Alignment; }
void setAlignment(unsigned Align) { Alignment = Align; }
- virtual bool equals(const Expression &Other) const override;
-
- virtual hash_code getHashValue() const override {
- return hash_combine(getOpcode(), getType(), DefiningAccess,
- hash_combine_range(op_begin(), op_end()));
+ bool equals(const Expression &Other) const override;
+ bool exactlyEquals(const Expression &Other) const override {
+ return Expression::exactlyEquals(Other) &&
+ cast<LoadExpression>(Other).getLoadInst() == getLoadInst();
}
//
// Debugging support
//
- virtual void printInternal(raw_ostream &OS, bool PrintEType) const override {
+ void printInternal(raw_ostream &OS, bool PrintEType) const override {
if (PrintEType)
OS << "ExpressionTypeLoad, ";
this->BasicExpression::printInternal(OS, false);
- OS << " represents Load at " << Load;
- OS << " with DefiningAccess " << *DefiningAccess;
+ OS << " represents Load at ";
+ Load->printAsOperand(OS);
+ OS << " with MemoryLeader " << *getMemoryLeader();
}
};
-class StoreExpression final : public BasicExpression {
+class StoreExpression final : public MemoryExpression {
private:
StoreInst *Store;
- MemoryAccess *DefiningAccess;
+ Value *StoredValue;
public:
+ StoreExpression(unsigned NumOperands, StoreInst *S, Value *StoredValue,
+ const MemoryAccess *MemoryLeader)
+ : MemoryExpression(NumOperands, ET_Store, MemoryLeader), Store(S),
+ StoredValue(StoredValue) {}
+ StoreExpression() = delete;
+ StoreExpression(const StoreExpression &) = delete;
+ StoreExpression &operator=(const StoreExpression &) = delete;
+ ~StoreExpression() override;
+
static bool classof(const Expression *EB) {
return EB->getExpressionType() == ET_Store;
}
- StoreExpression(unsigned NumOperands, StoreInst *S, MemoryAccess *DA)
- : BasicExpression(NumOperands, ET_Store), Store(S), DefiningAccess(DA) {}
- void operator=(const StoreExpression &) = delete;
- StoreExpression(const StoreExpression &) = delete;
- StoreExpression() = delete;
- virtual ~StoreExpression() override;
-
StoreInst *getStoreInst() const { return Store; }
- MemoryAccess *getDefiningAccess() const { return DefiningAccess; }
-
- virtual bool equals(const Expression &Other) const override;
+ Value *getStoredValue() const { return StoredValue; }
- virtual hash_code getHashValue() const override {
- return hash_combine(getOpcode(), getType(), DefiningAccess,
- hash_combine_range(op_begin(), op_end()));
+ bool equals(const Expression &Other) const override;
+ bool exactlyEquals(const Expression &Other) const override {
+ return Expression::exactlyEquals(Other) &&
+ cast<StoreExpression>(Other).getStoreInst() == getStoreInst();
}
- //
// Debugging support
//
- virtual void printInternal(raw_ostream &OS, bool PrintEType) const override {
+ void printInternal(raw_ostream &OS, bool PrintEType) const override {
if (PrintEType)
OS << "ExpressionTypeStore, ";
this->BasicExpression::printInternal(OS, false);
- OS << " represents Store at " << Store;
- OS << " with DefiningAccess " << *DefiningAccess;
+ OS << " represents Store " << *Store;
+ OS << " with StoredValue ";
+ StoredValue->printAsOperand(OS);
+ OS << " and MemoryLeader " << *getMemoryLeader();
}
};
@@ -370,19 +413,19 @@ private:
unsigned *IntOperands;
public:
- static bool classof(const Expression *EB) {
- return EB->getExpressionType() == ET_AggregateValue;
- }
-
AggregateValueExpression(unsigned NumOperands, unsigned NumIntOperands)
: BasicExpression(NumOperands, ET_AggregateValue),
MaxIntOperands(NumIntOperands), NumIntOperands(0),
IntOperands(nullptr) {}
-
- void operator=(const AggregateValueExpression &) = delete;
- AggregateValueExpression(const AggregateValueExpression &) = delete;
AggregateValueExpression() = delete;
- virtual ~AggregateValueExpression() override;
+ AggregateValueExpression(const AggregateValueExpression &) = delete;
+ AggregateValueExpression &
+ operator=(const AggregateValueExpression &) = delete;
+ ~AggregateValueExpression() override;
+
+ static bool classof(const Expression *EB) {
+ return EB->getExpressionType() == ET_AggregateValue;
+ }
typedef unsigned *int_arg_iterator;
typedef const unsigned *const_int_arg_iterator;
@@ -407,7 +450,7 @@ public:
IntOperands = Allocator.Allocate<unsigned>(MaxIntOperands);
}
- virtual bool equals(const Expression &Other) const override {
+ bool equals(const Expression &Other) const override {
if (!this->BasicExpression::equals(Other))
return false;
const AggregateValueExpression &OE = cast<AggregateValueExpression>(Other);
@@ -415,7 +458,7 @@ public:
std::equal(int_op_begin(), int_op_end(), OE.int_op_begin());
}
- virtual hash_code getHashValue() const override {
+ hash_code getHashValue() const override {
return hash_combine(this->BasicExpression::getHashValue(),
hash_combine_range(int_op_begin(), int_op_end()));
}
@@ -423,7 +466,7 @@ public:
//
// Debugging support
//
- virtual void printInternal(raw_ostream &OS, bool PrintEType) const override {
+ void printInternal(raw_ostream &OS, bool PrintEType) const override {
if (PrintEType)
OS << "ExpressionTypeAggregateValue, ";
this->BasicExpression::printInternal(OS, false);
@@ -434,6 +477,7 @@ public:
OS << "}";
}
};
+
class int_op_inserter
: public std::iterator<std::output_iterator_tag, void, void, void, void> {
private:
@@ -443,6 +487,7 @@ private:
public:
explicit int_op_inserter(AggregateValueExpression &E) : AVE(&E) {}
explicit int_op_inserter(AggregateValueExpression *E) : AVE(E) {}
+
int_op_inserter &operator=(unsigned int val) {
AVE->int_op_push_back(val);
return *this;
@@ -457,32 +502,32 @@ private:
BasicBlock *BB;
public:
- static bool classof(const Expression *EB) {
- return EB->getExpressionType() == ET_Phi;
- }
-
PHIExpression(unsigned NumOperands, BasicBlock *B)
: BasicExpression(NumOperands, ET_Phi), BB(B) {}
- void operator=(const PHIExpression &) = delete;
- PHIExpression(const PHIExpression &) = delete;
PHIExpression() = delete;
- virtual ~PHIExpression() override;
+ PHIExpression(const PHIExpression &) = delete;
+ PHIExpression &operator=(const PHIExpression &) = delete;
+ ~PHIExpression() override;
+
+ static bool classof(const Expression *EB) {
+ return EB->getExpressionType() == ET_Phi;
+ }
- virtual bool equals(const Expression &Other) const override {
+ bool equals(const Expression &Other) const override {
if (!this->BasicExpression::equals(Other))
return false;
const PHIExpression &OE = cast<PHIExpression>(Other);
return BB == OE.BB;
}
- virtual hash_code getHashValue() const override {
+ hash_code getHashValue() const override {
return hash_combine(this->BasicExpression::getHashValue(), BB);
}
//
// Debugging support
//
- virtual void printInternal(raw_ostream &OS, bool PrintEType) const override {
+ void printInternal(raw_ostream &OS, bool PrintEType) const override {
if (PrintEType)
OS << "ExpressionTypePhi, ";
this->BasicExpression::printInternal(OS, false);
@@ -490,36 +535,48 @@ public:
}
};
+class DeadExpression final : public Expression {
+public:
+ DeadExpression() : Expression(ET_Dead) {}
+ DeadExpression(const DeadExpression &) = delete;
+ DeadExpression &operator=(const DeadExpression &) = delete;
+
+ static bool classof(const Expression *E) {
+ return E->getExpressionType() == ET_Dead;
+ }
+};
+
class VariableExpression final : public Expression {
private:
Value *VariableValue;
public:
+ VariableExpression(Value *V) : Expression(ET_Variable), VariableValue(V) {}
+ VariableExpression() = delete;
+ VariableExpression(const VariableExpression &) = delete;
+ VariableExpression &operator=(const VariableExpression &) = delete;
+
static bool classof(const Expression *EB) {
return EB->getExpressionType() == ET_Variable;
}
- VariableExpression(Value *V) : Expression(ET_Variable), VariableValue(V) {}
- void operator=(const VariableExpression &) = delete;
- VariableExpression(const VariableExpression &) = delete;
- VariableExpression() = delete;
-
Value *getVariableValue() const { return VariableValue; }
void setVariableValue(Value *V) { VariableValue = V; }
- virtual bool equals(const Expression &Other) const override {
+
+ bool equals(const Expression &Other) const override {
const VariableExpression &OC = cast<VariableExpression>(Other);
return VariableValue == OC.VariableValue;
}
- virtual hash_code getHashValue() const override {
- return hash_combine(getExpressionType(), VariableValue->getType(),
- VariableValue);
+ hash_code getHashValue() const override {
+ return hash_combine(this->Expression::getHashValue(),
+ VariableValue->getType(), VariableValue);
}
//
// Debugging support
//
- virtual void printInternal(raw_ostream &OS, bool PrintEType) const override {
+ void printInternal(raw_ostream &OS, bool PrintEType) const override {
if (PrintEType)
OS << "ExpressionTypeVariable, ";
this->Expression::printInternal(OS, false);
@@ -529,36 +586,36 @@ public:
class ConstantExpression final : public Expression {
private:
- Constant *ConstantValue;
+ Constant *ConstantValue = nullptr;
public:
- static bool classof(const Expression *EB) {
- return EB->getExpressionType() == ET_Constant;
- }
-
- ConstantExpression() : Expression(ET_Constant), ConstantValue(NULL) {}
+ ConstantExpression() : Expression(ET_Constant) {}
ConstantExpression(Constant *constantValue)
: Expression(ET_Constant), ConstantValue(constantValue) {}
- void operator=(const ConstantExpression &) = delete;
ConstantExpression(const ConstantExpression &) = delete;
+ ConstantExpression &operator=(const ConstantExpression &) = delete;
+
+ static bool classof(const Expression *EB) {
+ return EB->getExpressionType() == ET_Constant;
+ }
Constant *getConstantValue() const { return ConstantValue; }
void setConstantValue(Constant *V) { ConstantValue = V; }
- virtual bool equals(const Expression &Other) const override {
+ bool equals(const Expression &Other) const override {
const ConstantExpression &OC = cast<ConstantExpression>(Other);
return ConstantValue == OC.ConstantValue;
}
- virtual hash_code getHashValue() const override {
- return hash_combine(getExpressionType(), ConstantValue->getType(),
- ConstantValue);
+ hash_code getHashValue() const override {
+ return hash_combine(this->Expression::getHashValue(),
+ ConstantValue->getType(), ConstantValue);
}
//
// Debugging support
//
- virtual void printInternal(raw_ostream &OS, bool PrintEType) const override {
+ void printInternal(raw_ostream &OS, bool PrintEType) const override {
if (PrintEType)
OS << "ExpressionTypeConstant, ";
this->Expression::printInternal(OS, false);
@@ -571,35 +628,40 @@ private:
Instruction *Inst;
public:
+ UnknownExpression(Instruction *I) : Expression(ET_Unknown), Inst(I) {}
+ UnknownExpression() = delete;
+ UnknownExpression(const UnknownExpression &) = delete;
+ UnknownExpression &operator=(const UnknownExpression &) = delete;
+
static bool classof(const Expression *EB) {
return EB->getExpressionType() == ET_Unknown;
}
- UnknownExpression(Instruction *I) : Expression(ET_Unknown), Inst(I) {}
- void operator=(const UnknownExpression &) = delete;
- UnknownExpression(const UnknownExpression &) = delete;
- UnknownExpression() = delete;
-
Instruction *getInstruction() const { return Inst; }
void setInstruction(Instruction *I) { Inst = I; }
- virtual bool equals(const Expression &Other) const override {
+
+ bool equals(const Expression &Other) const override {
const auto &OU = cast<UnknownExpression>(Other);
return Inst == OU.Inst;
}
- virtual hash_code getHashValue() const override {
- return hash_combine(getExpressionType(), Inst);
+
+ hash_code getHashValue() const override {
+ return hash_combine(this->Expression::getHashValue(), Inst);
}
+
//
// Debugging support
//
- virtual void printInternal(raw_ostream &OS, bool PrintEType) const override {
+ void printInternal(raw_ostream &OS, bool PrintEType) const override {
if (PrintEType)
OS << "ExpressionTypeUnknown, ";
this->Expression::printInternal(OS, false);
OS << " inst = " << *Inst;
}
};
-}
-}
-#endif
+} // end namespace GVNExpression
+
+} // end namespace llvm
+
+#endif // LLVM_TRANSFORMS_SCALAR_GVNEXPRESSION_H
diff --git a/contrib/llvm/include/llvm/Transforms/Scalar/JumpThreading.h b/contrib/llvm/include/llvm/Transforms/Scalar/JumpThreading.h
index f96741c..1da8613 100644
--- a/contrib/llvm/include/llvm/Transforms/Scalar/JumpThreading.h
+++ b/contrib/llvm/include/llvm/Transforms/Scalar/JumpThreading.h
@@ -17,12 +17,14 @@
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallSet.h"
+#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/BlockFrequencyInfo.h"
#include "llvm/Analysis/BlockFrequencyInfoImpl.h"
#include "llvm/Analysis/BranchProbabilityInfo.h"
#include "llvm/Analysis/LazyValueInfo.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/IR/Instructions.h"
+#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/ValueHandle.h"
namespace llvm {
@@ -59,9 +61,11 @@ enum ConstantPreference { WantInteger, WantBlockAddress };
class JumpThreadingPass : public PassInfoMixin<JumpThreadingPass> {
TargetLibraryInfo *TLI;
LazyValueInfo *LVI;
+ AliasAnalysis *AA;
std::unique_ptr<BlockFrequencyInfo> BFI;
std::unique_ptr<BranchProbabilityInfo> BPI;
bool HasProfileData = false;
+ bool HasGuards = false;
#ifdef NDEBUG
SmallPtrSet<const BasicBlock *, 16> LoopHeaders;
#else
@@ -88,7 +92,8 @@ public:
// Glue for old PM.
bool runImpl(Function &F, TargetLibraryInfo *TLI_, LazyValueInfo *LVI_,
- bool HasProfileData_, std::unique_ptr<BlockFrequencyInfo> BFI_,
+ AliasAnalysis *AA_, bool HasProfileData_,
+ std::unique_ptr<BlockFrequencyInfo> BFI_,
std::unique_ptr<BranchProbabilityInfo> BPI_);
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
@@ -122,6 +127,9 @@ public:
bool TryToUnfoldSelect(CmpInst *CondCmp, BasicBlock *BB);
bool TryToUnfoldSelectInCurrBB(BasicBlock *BB);
+ bool ProcessGuards(BasicBlock *BB);
+ bool ThreadGuard(BasicBlock *BB, IntrinsicInst *Guard, BranchInst *BI);
+
private:
BasicBlock *SplitBlockPreds(BasicBlock *BB, ArrayRef<BasicBlock *> Preds,
const char *Suffix);
diff --git a/contrib/llvm/include/llvm/Transforms/Scalar/LoopDataPrefetch.h b/contrib/llvm/include/llvm/Transforms/Scalar/LoopDataPrefetch.h
index 114d1ba..12c7a03 100644
--- a/contrib/llvm/include/llvm/Transforms/Scalar/LoopDataPrefetch.h
+++ b/contrib/llvm/include/llvm/Transforms/Scalar/LoopDataPrefetch.h
@@ -22,10 +22,12 @@ namespace llvm {
/// An optimization pass inserting data prefetches in loops.
class LoopDataPrefetchPass : public PassInfoMixin<LoopDataPrefetchPass> {
public:
- LoopDataPrefetchPass() {}
+ LoopDataPrefetchPass() = default;
+
/// \brief Run the pass over the function.
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
};
-}
-#endif
+} // end namespace llvm
+
+#endif // LLVM_TRANSFORMS_SCALAR_LOOPDATAPREFETCH_H
diff --git a/contrib/llvm/include/llvm/Transforms/Scalar/LoopDeletion.h b/contrib/llvm/include/llvm/Transforms/Scalar/LoopDeletion.h
index b44f823..7b8cb1e 100644
--- a/contrib/llvm/include/llvm/Transforms/Scalar/LoopDeletion.h
+++ b/contrib/llvm/include/llvm/Transforms/Scalar/LoopDeletion.h
@@ -1,4 +1,4 @@
-//===- LoopDeletion.h - Loop Deletion -------------------------------------===//
+//===- LoopDeletion.h - Loop Deletion ---------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,6 +14,7 @@
#ifndef LLVM_TRANSFORMS_SCALAR_LOOPDELETION_H
#define LLVM_TRANSFORMS_SCALAR_LOOPDELETION_H
+#include "llvm/Analysis/LoopAnalysisManager.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/ScalarEvolution.h"
#include "llvm/IR/PassManager.h"
@@ -23,18 +24,12 @@ namespace llvm {
class LoopDeletionPass : public PassInfoMixin<LoopDeletionPass> {
public:
- LoopDeletionPass() {}
+ LoopDeletionPass() = default;
+
PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM,
LoopStandardAnalysisResults &AR, LPMUpdater &U);
- bool runImpl(Loop *L, DominatorTree &DT, ScalarEvolution &SE,
- LoopInfo &loopInfo);
-
-private:
- bool isLoopDead(Loop *L, ScalarEvolution &SE,
- SmallVectorImpl<BasicBlock *> &exitingBlocks,
- SmallVectorImpl<BasicBlock *> &exitBlocks, bool &Changed,
- BasicBlock *Preheader);
};
-}
+
+} // end namespace llvm
#endif // LLVM_TRANSFORMS_SCALAR_LOOPDELETION_H
diff --git a/contrib/llvm/include/llvm/Transforms/Scalar/LoopLoadElimination.h b/contrib/llvm/include/llvm/Transforms/Scalar/LoopLoadElimination.h
new file mode 100644
index 0000000..7a007a7
--- /dev/null
+++ b/contrib/llvm/include/llvm/Transforms/Scalar/LoopLoadElimination.h
@@ -0,0 +1,30 @@
+//===---- LoopLoadElimination.h ---------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+/// \file
+/// This header defines the LoopLoadEliminationPass object. This pass forwards
+/// loaded values around loop backedges to allow their use in subsequent
+/// iterations.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_SCALAR_LOOPLOADELIMINATION_H
+#define LLVM_TRANSFORMS_SCALAR_LOOPLOADELIMINATION_H
+
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+
+/// Pass to forward loads in a loop around the backedge to subsequent
+/// iterations.
+struct LoopLoadEliminationPass : public PassInfoMixin<LoopLoadEliminationPass> {
+ PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
+};
+}
+
+#endif // LLVM_TRANSFORMS_SCALAR_LOOPLOADELIMINATION_H
diff --git a/contrib/llvm/include/llvm/Transforms/Scalar/LoopPassManager.h b/contrib/llvm/include/llvm/Transforms/Scalar/LoopPassManager.h
index b0e6dd6..715b11d 100644
--- a/contrib/llvm/include/llvm/Transforms/Scalar/LoopPassManager.h
+++ b/contrib/llvm/include/llvm/Transforms/Scalar/LoopPassManager.h
@@ -51,6 +51,8 @@
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/PassManager.h"
+#include "llvm/Transforms/Utils/LCSSA.h"
+#include "llvm/Transforms/Utils/LoopSimplify.h"
namespace llvm {
@@ -248,19 +250,25 @@ template <typename LoopPassT>
class FunctionToLoopPassAdaptor
: public PassInfoMixin<FunctionToLoopPassAdaptor<LoopPassT>> {
public:
- explicit FunctionToLoopPassAdaptor(LoopPassT Pass) : Pass(std::move(Pass)) {}
+ explicit FunctionToLoopPassAdaptor(LoopPassT Pass) : Pass(std::move(Pass)) {
+ LoopCanonicalizationFPM.addPass(LoopSimplifyPass());
+ LoopCanonicalizationFPM.addPass(LCSSAPass());
+ }
/// \brief Runs the loop passes across every loop in the function.
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM) {
- // Setup the loop analysis manager from its proxy.
- LoopAnalysisManager &LAM =
- AM.getResult<LoopAnalysisManagerFunctionProxy>(F).getManager();
+ // Before we even compute any loop analyses, first run a miniature function
+ // pass pipeline to put loops into their canonical form. Note that we can
+ // directly build up function analyses after this as the function pass
+ // manager handles all the invalidation at that layer.
+ PreservedAnalyses PA = LoopCanonicalizationFPM.run(F, AM);
+
// Get the loop structure for this function
LoopInfo &LI = AM.getResult<LoopAnalysis>(F);
// If there are no loops, there is nothing to do here.
if (LI.empty())
- return PreservedAnalyses::all();
+ return PA;
// Get the analysis results needed by loop passes.
LoopStandardAnalysisResults LAR = {AM.getResult<AAManager>(F),
@@ -271,7 +279,13 @@ public:
AM.getResult<TargetLibraryAnalysis>(F),
AM.getResult<TargetIRAnalysis>(F)};
- PreservedAnalyses PA = PreservedAnalyses::all();
+ // Setup the loop analysis manager from its proxy. It is important that
+ // this is only done when there are loops to process and we have built the
+ // LoopStandardAnalysisResults object. The loop analyses cached in this
+ // manager have access to those analysis results and so it must invalidate
+ // itself when they go away.
+ LoopAnalysisManager &LAM =
+ AM.getResult<LoopAnalysisManagerFunctionProxy>(F).getManager();
// A postorder worklist of loops to process.
SmallPriorityWorklist<Loop *, 4> Worklist;
@@ -294,8 +308,15 @@ public:
// Reset the update structure for this loop.
Updater.CurrentL = L;
Updater.SkipCurrentLoop = false;
+
#ifndef NDEBUG
+ // Save a parent loop pointer for asserts.
Updater.ParentL = L->getParentLoop();
+
+ // Verify the loop structure and LCSSA form before visiting the loop.
+ L->verifyLoop();
+ assert(L->isRecursivelyLCSSAForm(LAR.DT, LI) &&
+ "Loops must remain in LCSSA form!");
#endif
PreservedAnalyses PassPA = Pass.run(*L, LAM, LAR, Updater);
@@ -321,7 +342,6 @@ public:
PA.preserveSet<AllAnalysesOn<Loop>>();
PA.preserve<LoopAnalysisManagerFunctionProxy>();
// We also preserve the set of standard analyses.
- PA.preserve<AssumptionAnalysis>();
PA.preserve<DominatorTreeAnalysis>();
PA.preserve<LoopAnalysis>();
PA.preserve<ScalarEvolutionAnalysis>();
@@ -336,6 +356,8 @@ public:
private:
LoopPassT Pass;
+
+ FunctionPassManager LoopCanonicalizationFPM;
};
/// \brief A function to deduce a loop pass type and wrap it in the templated
diff --git a/contrib/llvm/include/llvm/Transforms/Scalar/LoopPredication.h b/contrib/llvm/include/llvm/Transforms/Scalar/LoopPredication.h
new file mode 100644
index 0000000..57398bd
--- /dev/null
+++ b/contrib/llvm/include/llvm/Transforms/Scalar/LoopPredication.h
@@ -0,0 +1,32 @@
+//===- LoopPredication.h - Guard based loop predication pass ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This pass tries to convert loop variant range checks to loop invariant by
+// widening checks across loop iterations.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_SCALAR_LOOPPREDICATION_H
+#define LLVM_TRANSFORMS_SCALAR_LOOPPREDICATION_H
+
+#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/Transforms/Scalar/LoopPassManager.h"
+
+namespace llvm {
+
+/// Performs Loop Predication Pass.
+class LoopPredicationPass : public PassInfoMixin<LoopPredicationPass> {
+public:
+ PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM,
+ LoopStandardAnalysisResults &AR, LPMUpdater &U);
+};
+} // end namespace llvm
+
+#endif // LLVM_TRANSFORMS_SCALAR_LOOPPREDICATION_H
diff --git a/contrib/llvm/include/llvm/Transforms/Scalar/LoopSink.h b/contrib/llvm/include/llvm/Transforms/Scalar/LoopSink.h
new file mode 100644
index 0000000..371a7c8
--- /dev/null
+++ b/contrib/llvm/include/llvm/Transforms/Scalar/LoopSink.h
@@ -0,0 +1,40 @@
+//===- LoopSink.h - Loop Sink Pass ------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides the interface for the Loop Sink pass.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_SCALAR_LOOPSINK_H
+#define LLVM_TRANSFORMS_SCALAR_LOOPSINK_H
+
+#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/Transforms/Scalar/LoopPassManager.h"
+
+namespace llvm {
+
+/// A pass that does profile-guided sinking of instructions into loops.
+///
+/// This is a function pass as it shouldn't be composed into any kind of
+/// unified loop pass pipeline. The goal of it is to sink code into loops that
+/// is loop invariant but only required within the loop body when doing so
+/// reduces the global expected dynamic frequency with which it executes.
+/// A classic example is an extremely cold branch within a loop body.
+///
+/// We do this as a separate pass so that during normal optimization all
+/// invariant operations can be held outside the loop body to simplify
+/// fundamental analyses and transforms of the loop.
+class LoopSinkPass : public PassInfoMixin<LoopSinkPass> {
+public:
+ PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM);
+};
+}
+
+#endif // LLVM_TRANSFORMS_SCALAR_LOOPSINK_H
diff --git a/contrib/llvm/include/llvm/Transforms/Scalar/LoopUnrollPass.h b/contrib/llvm/include/llvm/Transforms/Scalar/LoopUnrollPass.h
index 9da95ef..7253bd0 100644
--- a/contrib/llvm/include/llvm/Transforms/Scalar/LoopUnrollPass.h
+++ b/contrib/llvm/include/llvm/Transforms/Scalar/LoopUnrollPass.h
@@ -16,12 +16,30 @@
namespace llvm {
-struct LoopUnrollPass : public PassInfoMixin<LoopUnrollPass> {
- Optional<unsigned> ProvidedCount;
- Optional<unsigned> ProvidedThreshold;
- Optional<bool> ProvidedAllowPartial;
- Optional<bool> ProvidedRuntime;
- Optional<bool> ProvidedUpperBound;
+class LoopUnrollPass : public PassInfoMixin<LoopUnrollPass> {
+ const bool AllowPartialUnrolling;
+ const int OptLevel;
+
+ explicit LoopUnrollPass(bool AllowPartialUnrolling, int OptLevel)
+ : AllowPartialUnrolling(AllowPartialUnrolling), OptLevel(OptLevel) {}
+
+public:
+ /// Create an instance of the loop unroll pass that will support both full
+ /// and partial unrolling.
+ ///
+ /// This uses the target information (or flags) to control the thresholds for
+ /// different unrolling stategies but supports all of them.
+ static LoopUnrollPass create(int OptLevel = 2) {
+ return LoopUnrollPass(/*AllowPartialUnrolling*/ true, OptLevel);
+ }
+
+ /// Create an instance of the loop unroll pass that only does full loop
+ /// unrolling.
+ ///
+ /// This will disable any runtime or partial unrolling.
+ static LoopUnrollPass createFull(int OptLevel = 2) {
+ return LoopUnrollPass(/*AllowPartialUnrolling*/ false, OptLevel);
+ }
PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM,
LoopStandardAnalysisResults &AR, LPMUpdater &U);
diff --git a/contrib/llvm/include/llvm/Transforms/Scalar/MemCpyOptimizer.h b/contrib/llvm/include/llvm/Transforms/Scalar/MemCpyOptimizer.h
index 4308e44..f52872d 100644
--- a/contrib/llvm/include/llvm/Transforms/Scalar/MemCpyOptimizer.h
+++ b/contrib/llvm/include/llvm/Transforms/Scalar/MemCpyOptimizer.h
@@ -15,17 +15,18 @@
#ifndef LLVM_TRANSFORMS_SCALAR_MEMCPYOPTIMIZER_H
#define LLVM_TRANSFORMS_SCALAR_MEMCPYOPTIMIZER_H
-#include "llvm/ADT/STLExtras.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/AssumptionCache.h"
-#include "llvm/Analysis/GlobalsModRef.h"
#include "llvm/Analysis/MemoryDependenceAnalysis.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
+#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/PassManager.h"
+#include <cstdint>
+#include <functional>
namespace llvm {
@@ -37,7 +38,8 @@ class MemCpyOptPass : public PassInfoMixin<MemCpyOptPass> {
std::function<DominatorTree &()> LookupDomTree;
public:
- MemCpyOptPass() {}
+ MemCpyOptPass() = default;
+
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
// Glue for the old PM.
bool runImpl(Function &F, MemoryDependenceResults *MD_,
@@ -63,6 +65,7 @@ private:
bool iterateOnFunction(Function &F);
};
-}
+
+} // end namespace llvm
#endif // LLVM_TRANSFORMS_SCALAR_MEMCPYOPTIMIZER_H
diff --git a/contrib/llvm/include/llvm/Transforms/Scalar/NaryReassociate.h b/contrib/llvm/include/llvm/Transforms/Scalar/NaryReassociate.h
index a74bb6c..f35707e 100644
--- a/contrib/llvm/include/llvm/Transforms/Scalar/NaryReassociate.h
+++ b/contrib/llvm/include/llvm/Transforms/Scalar/NaryReassociate.h
@@ -167,7 +167,7 @@ private:
// foo(a + b);
// if (p2)
// bar(a + b);
- DenseMap<const SCEV *, SmallVector<WeakVH, 2>> SeenExprs;
+ DenseMap<const SCEV *, SmallVector<WeakTrackingVH, 2>> SeenExprs;
};
} // namespace llvm
diff --git a/contrib/llvm/include/llvm/Transforms/Scalar/Reassociate.h b/contrib/llvm/include/llvm/Transforms/Scalar/Reassociate.h
index 7b68b44..a30a717 100644
--- a/contrib/llvm/include/llvm/Transforms/Scalar/Reassociate.h
+++ b/contrib/llvm/include/llvm/Transforms/Scalar/Reassociate.h
@@ -82,8 +82,6 @@ private:
bool CombineXorOpnd(Instruction *I, reassociate::XorOpnd *Opnd1,
reassociate::XorOpnd *Opnd2, APInt &ConstOpnd,
Value *&Res);
- bool collectMultiplyFactors(SmallVectorImpl<reassociate::ValueEntry> &Ops,
- SmallVectorImpl<reassociate::Factor> &Factors);
Value *buildMinimalMultiplyDAG(IRBuilder<> &Builder,
SmallVectorImpl<reassociate::Factor> &Factors);
Value *OptimizeMul(BinaryOperator *I,
diff --git a/contrib/llvm/include/llvm/Transforms/Scalar/SROA.h b/contrib/llvm/include/llvm/Transforms/Scalar/SROA.h
index 3e93f46..3080b75 100644
--- a/contrib/llvm/include/llvm/Transforms/Scalar/SROA.h
+++ b/contrib/llvm/include/llvm/Transforms/Scalar/SROA.h
@@ -21,17 +21,21 @@
#include "llvm/IR/Dominators.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/PassManager.h"
+#include "llvm/Support/Compiler.h"
+#include <vector>
namespace llvm {
/// A private "module" namespace for types and utilities used by SROA. These
/// are implementation details and should not be used by clients.
namespace sroa LLVM_LIBRARY_VISIBILITY {
+
class AllocaSliceRewriter;
class AllocaSlices;
class Partition;
class SROALegacyPass;
-}
+
+} // end namespace sroa
/// \brief An optimization pass providing Scalar Replacement of Aggregates.
///
@@ -52,9 +56,9 @@ class SROALegacyPass;
/// this form. By doing so, it will enable promotion of vector aggregates to
/// SSA vector values.
class SROA : public PassInfoMixin<SROA> {
- LLVMContext *C;
- DominatorTree *DT;
- AssumptionCache *AC;
+ LLVMContext *C = nullptr;
+ DominatorTree *DT = nullptr;
+ AssumptionCache *AC = nullptr;
/// \brief Worklist of alloca instructions to simplify.
///
@@ -99,7 +103,7 @@ class SROA : public PassInfoMixin<SROA> {
SetVector<SelectInst *, SmallVector<SelectInst *, 2>> SpeculatableSelects;
public:
- SROA() : C(nullptr), DT(nullptr), AC(nullptr) {}
+ SROA() = default;
/// \brief Run the pass over the function.
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
@@ -122,6 +126,6 @@ private:
bool promoteAllocas(Function &F);
};
-}
+} // end namespace llvm
-#endif
+#endif // LLVM_TRANSFORMS_SCALAR_SROA_H
diff --git a/contrib/llvm/include/llvm/Transforms/Scalar/SimpleLoopUnswitch.h b/contrib/llvm/include/llvm/Transforms/Scalar/SimpleLoopUnswitch.h
new file mode 100644
index 0000000..d7282ac
--- /dev/null
+++ b/contrib/llvm/include/llvm/Transforms/Scalar/SimpleLoopUnswitch.h
@@ -0,0 +1,53 @@
+//===- SimpleLoopUnswitch.h - Hoist loop-invariant control flow -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_SCALAR_SIMPLELOOPUNSWITCH_H
+#define LLVM_TRANSFORMS_SCALAR_SIMPLELOOPUNSWITCH_H
+
+#include "llvm/Analysis/LoopAnalysisManager.h"
+#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/Transforms/Scalar/LoopPassManager.h"
+
+namespace llvm {
+
+/// This pass transforms loops that contain branches on loop-invariant
+/// conditions to have multiple loops. For example, it turns the left into the
+/// right code:
+///
+/// for (...) if (lic)
+/// A for (...)
+/// if (lic) A; B; C
+/// B else
+/// C for (...)
+/// A; C
+///
+/// This can increase the size of the code exponentially (doubling it every time
+/// a loop is unswitched) so we only unswitch if the resultant code will be
+/// smaller than a threshold.
+///
+/// This pass expects LICM to be run before it to hoist invariant conditions out
+/// of the loop, to make the unswitching opportunity obvious.
+///
+class SimpleLoopUnswitchPass : public PassInfoMixin<SimpleLoopUnswitchPass> {
+public:
+ SimpleLoopUnswitchPass() = default;
+
+ PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM,
+ LoopStandardAnalysisResults &AR, LPMUpdater &U);
+};
+
+/// Create the legacy pass object for the simple loop unswitcher.
+///
+/// See the documentaion for `SimpleLoopUnswitchPass` for details.
+Pass *createSimpleLoopUnswitchLegacyPass();
+
+} // end namespace llvm
+
+#endif // LLVM_TRANSFORMS_SCALAR_SIMPLELOOPUNSWITCH_H
diff --git a/contrib/llvm/include/llvm/Transforms/Scalar/SimplifyCFG.h b/contrib/llvm/include/llvm/Transforms/Scalar/SimplifyCFG.h
index 96e1658..54b51c4 100644
--- a/contrib/llvm/include/llvm/Transforms/Scalar/SimplifyCFG.h
+++ b/contrib/llvm/include/llvm/Transforms/Scalar/SimplifyCFG.h
@@ -27,13 +27,16 @@ namespace llvm {
/// by the rest of the mid-level optimizer.
class SimplifyCFGPass : public PassInfoMixin<SimplifyCFGPass> {
int BonusInstThreshold;
+ bool LateSimplifyCFG;
public:
- /// \brief Construct a pass with the default thresholds.
+ /// \brief Construct a pass with the default thresholds
+ /// and switch optimizations.
SimplifyCFGPass();
- /// \brief Construct a pass with a specific bonus threshold.
- SimplifyCFGPass(int BonusInstThreshold);
+ /// \brief Construct a pass with a specific bonus threshold
+ /// and optional switch optimizations.
+ SimplifyCFGPass(int BonusInstThreshold, bool LateSimplifyCFG);
/// \brief Run the pass over the function.
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
diff --git a/contrib/llvm/include/llvm/Transforms/Utils/BasicBlockUtils.h b/contrib/llvm/include/llvm/Transforms/Utils/BasicBlockUtils.h
index 3d41dbe..85bb053 100644
--- a/contrib/llvm/include/llvm/Transforms/Utils/BasicBlockUtils.h
+++ b/contrib/llvm/include/llvm/Transforms/Utils/BasicBlockUtils.h
@@ -78,14 +78,13 @@ void ReplaceInstWithInst(Instruction *From, Instruction *To);
struct CriticalEdgeSplittingOptions {
DominatorTree *DT;
LoopInfo *LI;
- bool MergeIdenticalEdges;
- bool DontDeleteUselessPHIs;
- bool PreserveLCSSA;
+ bool MergeIdenticalEdges = false;
+ bool DontDeleteUselessPHIs = false;
+ bool PreserveLCSSA = false;
CriticalEdgeSplittingOptions(DominatorTree *DT = nullptr,
LoopInfo *LI = nullptr)
- : DT(DT), LI(LI), MergeIdenticalEdges(false),
- DontDeleteUselessPHIs(false), PreserveLCSSA(false) {}
+ : DT(DT), LI(LI) {}
CriticalEdgeSplittingOptions &setMergeIdenticalEdges() {
MergeIdenticalEdges = true;
diff --git a/contrib/llvm/include/llvm/Transforms/Utils/BuildLibCalls.h b/contrib/llvm/include/llvm/Transforms/Utils/BuildLibCalls.h
index 2d2a859..a067a68 100644
--- a/contrib/llvm/include/llvm/Transforms/Utils/BuildLibCalls.h
+++ b/contrib/llvm/include/llvm/Transforms/Utils/BuildLibCalls.h
@@ -84,14 +84,14 @@ namespace llvm {
/// 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,
- const AttributeSet &Attrs);
+ const AttributeList &Attrs);
/// Emit a call to the binary function named 'Name' (e.g. 'fmin'). This
/// function is known to take type matching 'Op1' and 'Op2' and return one
/// 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 AttributeSet &Attrs);
+ IRBuilder<> &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);
diff --git a/contrib/llvm/include/llvm/Transforms/Utils/Cloning.h b/contrib/llvm/include/llvm/Transforms/Utils/Cloning.h
index 5eeb8cf..2a8b89d 100644
--- a/contrib/llvm/include/llvm/Transforms/Utils/Cloning.h
+++ b/contrib/llvm/include/llvm/Transforms/Utils/Cloning.h
@@ -22,32 +22,30 @@
#include "llvm/ADT/Twine.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/AssumptionCache.h"
+#include "llvm/IR/CallSite.h"
#include "llvm/IR/ValueHandle.h"
-#include "llvm/IR/ValueMap.h"
#include "llvm/Transforms/Utils/ValueMapper.h"
#include <functional>
+#include <memory>
+#include <vector>
namespace llvm {
-class Module;
-class Function;
-class Instruction;
-class Pass;
-class LPPassManager;
+class AllocaInst;
class BasicBlock;
-class Value;
+class BlockFrequencyInfo;
class CallInst;
-class InvokeInst;
-class ReturnInst;
-class CallSite;
-class Trace;
class CallGraph;
-class DataLayout;
+class DebugInfoFinder;
+class DominatorTree;
+class Function;
+class Instruction;
+class InvokeInst;
class Loop;
class LoopInfo;
-class AllocaInst;
-class AssumptionCacheTracker;
-class DominatorTree;
+class Module;
+class ProfileSummaryInfo;
+class ReturnInst;
/// Return an exact copy of the specified module
///
@@ -67,20 +65,20 @@ CloneModule(const Module *M, ValueToValueMapTy &VMap,
struct ClonedCodeInfo {
/// ContainsCalls - This is set to true if the cloned code contains a normal
/// call instruction.
- bool ContainsCalls;
+ bool ContainsCalls = false;
/// ContainsDynamicAllocas - This is set to true if the cloned code contains
/// a 'dynamic' alloca. Dynamic allocas are allocas that are either not in
/// the entry block or they are in the entry block but are not a constant
/// size.
- bool ContainsDynamicAllocas;
+ bool ContainsDynamicAllocas = false;
/// All cloned call sites that have operand bundles attached are appended to
/// this vector. This vector may contain nulls or undefs if some of the
/// originally inserted callsites were DCE'ed after they were cloned.
- std::vector<WeakVH> OperandBundleCallSites;
+ std::vector<WeakTrackingVH> OperandBundleCallSites;
- ClonedCodeInfo() : ContainsCalls(false), ContainsDynamicAllocas(false) {}
+ ClonedCodeInfo() = default;
};
/// CloneBasicBlock - Return a copy of the specified basic block, but without
@@ -113,7 +111,8 @@ struct ClonedCodeInfo {
///
BasicBlock *CloneBasicBlock(const BasicBlock *BB, ValueToValueMapTy &VMap,
const Twine &NameSuffix = "", Function *F = nullptr,
- ClonedCodeInfo *CodeInfo = nullptr);
+ ClonedCodeInfo *CodeInfo = nullptr,
+ DebugInfoFinder *DIFinder = nullptr);
/// CloneFunction - Return a copy of the specified function and add it to that
/// function's module. Also, any references specified in the VMap are changed
@@ -178,13 +177,19 @@ class InlineFunctionInfo {
public:
explicit InlineFunctionInfo(CallGraph *cg = nullptr,
std::function<AssumptionCache &(Function &)>
- *GetAssumptionCache = nullptr)
- : CG(cg), GetAssumptionCache(GetAssumptionCache) {}
+ *GetAssumptionCache = nullptr,
+ ProfileSummaryInfo *PSI = nullptr,
+ BlockFrequencyInfo *CallerBFI = nullptr,
+ BlockFrequencyInfo *CalleeBFI = nullptr)
+ : CG(cg), GetAssumptionCache(GetAssumptionCache), PSI(PSI),
+ CallerBFI(CallerBFI), CalleeBFI(CalleeBFI) {}
/// CG - If non-null, InlineFunction will update the callgraph to reflect the
/// changes it makes.
CallGraph *CG;
std::function<AssumptionCache &(Function &)> *GetAssumptionCache;
+ ProfileSummaryInfo *PSI;
+ BlockFrequencyInfo *CallerBFI, *CalleeBFI;
/// StaticAllocas - InlineFunction fills this in with all static allocas that
/// get copied into the caller.
@@ -192,7 +197,7 @@ public:
/// InlinedCalls - InlineFunction fills this in with callsites that were
/// inlined from the callee. This is only filled in if CG is non-null.
- SmallVector<WeakVH, 8> InlinedCalls;
+ SmallVector<WeakTrackingVH, 8> InlinedCalls;
/// All of the new call sites inlined into the caller.
///
@@ -245,6 +250,16 @@ Loop *cloneLoopWithPreheader(BasicBlock *Before, BasicBlock *LoopDomBB,
void remapInstructionsInBlocks(const SmallVectorImpl<BasicBlock *> &Blocks,
ValueToValueMapTy &VMap);
-} // End llvm namespace
+/// Split edge between BB and PredBB and duplicate all non-Phi instructions
+/// from BB between its beginning and the StopAt instruction into the split
+/// block. Phi nodes are not duplicated, but their uses are handled correctly:
+/// we replace them with the uses of corresponding Phi inputs. ValueMapping
+/// is used to map the original instructions from BB to their newly-created
+/// copies. Returns the split block.
+BasicBlock *
+DuplicateInstructionsInSplitBetween(BasicBlock *BB, BasicBlock *PredBB,
+ Instruction *StopAt,
+ ValueToValueMapTy &ValueMapping);
+} // end namespace llvm
-#endif
+#endif // LLVM_TRANSFORMS_UTILS_CLONING_H
diff --git a/contrib/llvm/include/llvm/Transforms/Utils/CodeExtractor.h b/contrib/llvm/include/llvm/Transforms/Utils/CodeExtractor.h
index a297866..682b353 100644
--- a/contrib/llvm/include/llvm/Transforms/Utils/CodeExtractor.h
+++ b/contrib/llvm/include/llvm/Transforms/Utils/CodeExtractor.h
@@ -25,6 +25,7 @@ template <typename T> class ArrayRef;
class BranchProbabilityInfo;
class DominatorTree;
class Function;
+ class Instruction;
class Loop;
class Module;
class RegionNode;
@@ -65,14 +66,6 @@ template <typename T> class ArrayRef;
/// Blocks containing EHPads, allocas, invokes, or vastarts are not valid.
static bool isBlockValidForExtraction(const BasicBlock &BB);
- /// \brief Create a code extractor for a single basic block.
- ///
- /// In this formation, we don't require a dominator tree. The given basic
- /// block is set up for extraction.
- CodeExtractor(BasicBlock *BB, bool AggregateArgs = false,
- BlockFrequencyInfo *BFI = nullptr,
- BranchProbabilityInfo *BPI = nullptr);
-
/// \brief Create a code extractor for a sequence of blocks.
///
/// Given a sequence of basic blocks where the first block in the sequence
@@ -91,14 +84,6 @@ template <typename T> class ArrayRef;
BlockFrequencyInfo *BFI = nullptr,
BranchProbabilityInfo *BPI = nullptr);
- /// \brief Create a code extractor for a region node.
- ///
- /// Behaves just like the generic code sequence constructor, but uses the
- /// block sequence of the region node passed in.
- CodeExtractor(DominatorTree &DT, const RegionNode &RN,
- bool AggregateArgs = false, BlockFrequencyInfo *BFI = nullptr,
- BranchProbabilityInfo *BPI = nullptr);
-
/// \brief Perform the extraction, returning the new function.
///
/// Returns zero when called on a CodeExtractor instance where isEligible
@@ -119,7 +104,34 @@ template <typename T> class ArrayRef;
/// a code sequence, that sequence is modified, including changing these
/// sets, before extraction occurs. These modifications won't have any
/// significant impact on the cost however.
- void findInputsOutputs(ValueSet &Inputs, ValueSet &Outputs) const;
+ void findInputsOutputs(ValueSet &Inputs, ValueSet &Outputs,
+ const ValueSet &Allocas) const;
+
+ /// Check if life time marker nodes can be hoisted/sunk into the outline
+ /// region.
+ ///
+ /// Returns true if it is safe to do the code motion.
+ bool isLegalToShrinkwrapLifetimeMarkers(Instruction *AllocaAddr) const;
+ /// Find the set of allocas whose life ranges are contained within the
+ /// outlined region.
+ ///
+ /// Allocas which have life_time markers contained in the outlined region
+ /// should be pushed to the outlined function. The address bitcasts that
+ /// are used by the lifetime markers are also candidates for shrink-
+ /// wrapping. The instructions that need to be sunk are collected in
+ /// 'Allocas'.
+ void findAllocas(ValueSet &SinkCands, ValueSet &HoistCands,
+ BasicBlock *&ExitBlock) const;
+
+ /// Find or create a block within the outline region for placing hoisted
+ /// code.
+ ///
+ /// CommonExitBlock is block outside the outline region. It is the common
+ /// successor of blocks inside the region. If there exists a single block
+ /// inside the region that is the predecessor of CommonExitBlock, that block
+ /// will be returned. Otherwise CommonExitBlock will be split and the
+ /// original block will be added to the outline region.
+ BasicBlock *findOrCreateBlockForHoisting(BasicBlock *CommonExitBlock);
private:
void severSplitPHINodes(BasicBlock *&Header);
diff --git a/contrib/llvm/include/llvm/Transforms/Utils/EscapeEnumerator.h b/contrib/llvm/include/llvm/Transforms/Utils/EscapeEnumerator.h
index 80d16ed..1256dfd 100644
--- a/contrib/llvm/include/llvm/Transforms/Utils/EscapeEnumerator.h
+++ b/contrib/llvm/include/llvm/Transforms/Utils/EscapeEnumerator.h
@@ -15,8 +15,8 @@
#ifndef LLVM_TRANSFORMS_UTILS_ESCAPEENUMERATOR_H
#define LLVM_TRANSFORMS_UTILS_ESCAPEENUMERATOR_H
-#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Function.h"
+#include "llvm/IR/IRBuilder.h"
namespace llvm {
diff --git a/contrib/llvm/include/llvm/Transforms/Utils/FunctionComparator.h b/contrib/llvm/include/llvm/Transforms/Utils/FunctionComparator.h
index a613fc3..b0f10ea 100644
--- a/contrib/llvm/include/llvm/Transforms/Utils/FunctionComparator.h
+++ b/contrib/llvm/include/llvm/Transforms/Utils/FunctionComparator.h
@@ -19,8 +19,8 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/IR/Function.h"
-#include "llvm/IR/ValueMap.h"
#include "llvm/IR/Operator.h"
+#include "llvm/IR/ValueMap.h"
#include "llvm/Support/AtomicOrdering.h"
#include "llvm/Support/Casting.h"
#include <cstdint>
@@ -314,7 +314,7 @@ protected:
private:
int cmpOrderings(AtomicOrdering L, AtomicOrdering R) const;
int cmpInlineAsm(const InlineAsm *L, const InlineAsm *R) const;
- int cmpAttrs(const AttributeSet L, const AttributeSet 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;
diff --git a/contrib/llvm/include/llvm/Transforms/Utils/FunctionImportUtils.h b/contrib/llvm/include/llvm/Transforms/Utils/FunctionImportUtils.h
index f18cd92..b9fbef0 100644
--- a/contrib/llvm/include/llvm/Transforms/Utils/FunctionImportUtils.h
+++ b/contrib/llvm/include/llvm/Transforms/Utils/FunctionImportUtils.h
@@ -32,7 +32,7 @@ class FunctionImportGlobalProcessing {
/// Globals to import from this module, all other functions will be
/// imported as declarations instead of definitions.
- DenseSet<const GlobalValue *> *GlobalsToImport;
+ SetVector<GlobalValue *> *GlobalsToImport;
/// Set to true if the given ModuleSummaryIndex contains any functions
/// from this source module, in which case we must conservatively assume
@@ -85,7 +85,7 @@ class FunctionImportGlobalProcessing {
public:
FunctionImportGlobalProcessing(
Module &M, const ModuleSummaryIndex &Index,
- DenseSet<const GlobalValue *> *GlobalsToImport = nullptr)
+ SetVector<GlobalValue *> *GlobalsToImport = nullptr)
: M(M), ImportIndex(Index), GlobalsToImport(GlobalsToImport) {
// If we have a ModuleSummaryIndex but no function to import,
// then this is the primary module being compiled in a ThinLTO
@@ -104,16 +104,15 @@ public:
bool run();
- static bool
- doImportAsDefinition(const GlobalValue *SGV,
- DenseSet<const GlobalValue *> *GlobalsToImport);
+ static bool doImportAsDefinition(const GlobalValue *SGV,
+ SetVector<GlobalValue *> *GlobalsToImport);
};
/// Perform in-place global value handling on the given Module for
/// exported local functions renamed and promoted for ThinLTO.
bool renameModuleForThinLTO(
Module &M, const ModuleSummaryIndex &Index,
- DenseSet<const GlobalValue *> *GlobalsToImport = nullptr);
+ SetVector<GlobalValue *> *GlobalsToImport = nullptr);
} // End llvm namespace
diff --git a/contrib/llvm/include/llvm/Transforms/Utils/GlobalStatus.h b/contrib/llvm/include/llvm/Transforms/Utils/GlobalStatus.h
index c366095..8cc265b 100644
--- a/contrib/llvm/include/llvm/Transforms/Utils/GlobalStatus.h
+++ b/contrib/llvm/include/llvm/Transforms/Utils/GlobalStatus.h
@@ -10,11 +10,13 @@
#ifndef LLVM_TRANSFORMS_UTILS_GLOBALSTATUS_H
#define LLVM_TRANSFORMS_UTILS_GLOBALSTATUS_H
-#include "llvm/IR/Instructions.h"
+#include "llvm/Support/AtomicOrdering.h"
namespace llvm {
-class Value;
+
+class Constant;
class Function;
+class Value;
/// It is safe to destroy a constant iff it is only used by constants itself.
/// Note that constants cannot be cyclic, so this test is pretty easy to
@@ -27,11 +29,11 @@ bool isSafeToDestroyConstant(const Constant *C);
/// accurate.
struct GlobalStatus {
/// True if the global's address is used in a comparison.
- bool IsCompared;
+ bool IsCompared = false;
/// True if the global is ever loaded. If the global isn't ever loaded it
/// can be deleted.
- bool IsLoaded;
+ bool IsLoaded = false;
/// Keep track of what stores to the global look like.
enum StoredType {
@@ -51,32 +53,33 @@ struct GlobalStatus {
/// This global is stored to by multiple values or something else that we
/// cannot track.
Stored
- } StoredType;
+ } StoredType = NotStored;
/// If only one value (besides the initializer constant) is ever stored to
/// this global, keep track of what value it is.
- Value *StoredOnceValue;
+ Value *StoredOnceValue = nullptr;
/// These start out null/false. When the first accessing function is noticed,
/// it is recorded. When a second different accessing function is noticed,
/// HasMultipleAccessingFunctions is set to true.
- const Function *AccessingFunction;
- bool HasMultipleAccessingFunctions;
+ const Function *AccessingFunction = nullptr;
+ bool HasMultipleAccessingFunctions = false;
/// Set to true if this global has a user that is not an instruction (e.g. a
/// constant expr or GV initializer).
- bool HasNonInstructionUser;
+ bool HasNonInstructionUser = false;
/// Set to the strongest atomic ordering requirement.
- AtomicOrdering Ordering;
+ AtomicOrdering Ordering = AtomicOrdering::NotAtomic;
+
+ GlobalStatus();
/// Look at all uses of the global and fill in the GlobalStatus structure. If
/// the global has its address taken, return true to indicate we can't do
/// anything with it.
static bool analyzeGlobal(const Value *V, GlobalStatus &GS);
-
- GlobalStatus();
};
-}
-#endif
+} // end namespace llvm
+
+#endif // LLVM_TRANSFORMS_UTILS_GLOBALSTATUS_H
diff --git a/contrib/llvm/include/llvm/Transforms/Utils/ImportedFunctionsInliningStatistics.h b/contrib/llvm/include/llvm/Transforms/Utils/ImportedFunctionsInliningStatistics.h
index bb7fa52..b7a3d13 100644
--- a/contrib/llvm/include/llvm/Transforms/Utils/ImportedFunctionsInliningStatistics.h
+++ b/contrib/llvm/include/llvm/Transforms/Utils/ImportedFunctionsInliningStatistics.h
@@ -14,8 +14,8 @@
#define LLVM_TRANSFORMS_UTILS_IMPORTEDFUNCTIONSINLININGSTATISTICS_H
#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
#include <string>
#include <vector>
diff --git a/contrib/llvm/include/llvm/Transforms/Utils/Local.h b/contrib/llvm/include/llvm/Transforms/Utils/Local.h
index 490a765..30b27616 100644
--- a/contrib/llvm/include/llvm/Transforms/Utils/Local.h
+++ b/contrib/llvm/include/llvm/Transforms/Utils/Local.h
@@ -15,13 +15,13 @@
#ifndef LLVM_TRANSFORMS_UTILS_LOCAL_H
#define LLVM_TRANSFORMS_UTILS_LOCAL_H
+#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/GetElementPtrTypeIterator.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Operator.h"
-#include "llvm/ADT/SmallPtrSet.h"
namespace llvm {
@@ -49,8 +49,6 @@ class LazyValueInfo;
template<typename T> class SmallVectorImpl;
-typedef SmallVector<DbgValueInst *, 1> DbgValueList;
-
//===----------------------------------------------------------------------===//
// Local constant propagation.
//
@@ -74,6 +72,12 @@ bool ConstantFoldTerminator(BasicBlock *BB, bool DeleteDeadConditions = false,
bool isInstructionTriviallyDead(Instruction *I,
const TargetLibraryInfo *TLI = nullptr);
+/// Return true if the result produced by the instruction would have no side
+/// effects if it was not used. This is equivalent to checking whether
+/// isInstructionTriviallyDead would be true if the use count was 0.
+bool wouldInstructionBeTriviallyDead(Instruction *I,
+ const TargetLibraryInfo *TLI = nullptr);
+
/// If the specified value is a trivially dead instruction, delete it.
/// If that makes any of its operands trivially dead, delete them too,
/// recursively. Return true if any instructions were deleted.
@@ -138,7 +142,8 @@ bool EliminateDuplicatePHINodes(BasicBlock *BB);
/// eliminate.
bool SimplifyCFG(BasicBlock *BB, const TargetTransformInfo &TTI,
unsigned BonusInstThreshold, AssumptionCache *AC = nullptr,
- SmallPtrSetImpl<BasicBlock *> *LoopHeaders = nullptr);
+ SmallPtrSetImpl<BasicBlock *> *LoopHeaders = nullptr,
+ bool LateSimplifyCFG = false);
/// 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
@@ -278,8 +283,8 @@ bool LowerDbgDeclare(Function &F);
/// Finds the llvm.dbg.declare intrinsic corresponding to an alloca, if any.
DbgDeclareInst *FindAllocaDbgDeclare(Value *V);
-/// Finds the llvm.dbg.value intrinsics corresponding to an alloca, if any.
-void FindAllocaDbgValues(DbgValueList &DbgValues, Value *V);
+/// Finds the llvm.dbg.value intrinsics describing a value.
+void findDbgValues(SmallVectorImpl<DbgValueInst *> &DbgValues, Value *V);
/// Replaces llvm.dbg.declare instruction when the address it describes
/// is replaced with a new value. If Deref is true, an additional DW_OP_deref is
@@ -306,6 +311,11 @@ bool replaceDbgDeclareForAlloca(AllocaInst *AI, Value *NewAllocaAddress,
void replaceDbgValueForAlloca(AllocaInst *AI, Value *NewAllocaAddress,
DIBuilder &Builder, int Offset = 0);
+/// Assuming the instruction \p I is going to be deleted, attempt to salvage any
+/// dbg.value intrinsics referring to \p I by rewriting its effect into a
+/// DIExpression.
+void salvageDebugInfo(Instruction &I);
+
/// Remove all instructions from a basic block other than it's terminator
/// and any present EH pad instructions.
unsigned removeAllNonTerminatorAndEHPadInstructions(BasicBlock *BB);
@@ -346,6 +356,10 @@ void combineMetadata(Instruction *K, const Instruction *J, ArrayRef<unsigned> Kn
/// Unknown metadata is removed.
void combineMetadataForCSE(Instruction *K, const Instruction *J);
+// Replace each use of 'From' with 'To', if that use does not belong to basic
+// block where 'From' is defined. Returns the number of replacements made.
+unsigned replaceNonLocalUsesWith(Instruction *From, Value *To);
+
/// Replace each use of 'From' with 'To' if that use is dominated by
/// the given edge. Returns the number of replacements made.
unsigned replaceDominatedUsesWith(Value *From, Value *To, DominatorTree &DT,
@@ -366,6 +380,19 @@ unsigned replaceDominatedUsesWith(Value *From, Value *To, DominatorTree &DT,
/// during lowering by the GC infrastructure.
bool callsGCLeafFunction(ImmutableCallSite CS);
+/// Copy a nonnull metadata node to a new load instruction.
+///
+/// This handles mapping it to range metadata if the new load is an integer
+/// load instead of a pointer load.
+void copyNonnullMetadata(const LoadInst &OldLI, MDNode *N, LoadInst &NewLI);
+
+/// Copy a range metadata node to a new load instruction.
+///
+/// This handles mapping it to nonnull metadata if the new load is a pointer
+/// load instead of an integer load and the range doesn't cover null.
+void copyRangeMetadata(const DataLayout &DL, const LoadInst &OldLI, MDNode *N,
+ LoadInst &NewLI);
+
//===----------------------------------------------------------------------===//
// Intrinsic pattern matching
//
@@ -396,6 +423,14 @@ bool recognizeBSwapOrBitReverseIdiom(
void maybeMarkSanitizerLibraryCallNoBuiltin(CallInst *CI,
const TargetLibraryInfo *TLI);
+//===----------------------------------------------------------------------===//
+// Transform predicates
+//
+
+/// Given an instruction, is it legal to set operand OpIdx to a non-constant
+/// value?
+bool canReplaceOperandWithVariable(const Instruction *I, unsigned OpIdx);
+
} // End llvm namespace
#endif
diff --git a/contrib/llvm/include/llvm/Transforms/Utils/LoopUtils.h b/contrib/llvm/include/llvm/Transforms/Utils/LoopUtils.h
index 27b45c4..94e20b8 100644
--- a/contrib/llvm/include/llvm/Transforms/Utils/LoopUtils.h
+++ b/contrib/llvm/include/llvm/Transforms/Utils/LoopUtils.h
@@ -1,4 +1,4 @@
-//===- llvm/Transforms/Utils/LoopUtils.h - Loop utilities -*- C++ -*-=========//
+//===- llvm/Transforms/Utils/LoopUtils.h - Loop utilities -------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,38 +14,47 @@
#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/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/EHPersonalities.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"
namespace llvm {
+
class AliasSet;
class AliasSetTracker;
-class AssumptionCache;
class BasicBlock;
class DataLayout;
-class DominatorTree;
class Loop;
class LoopInfo;
class OptimizationRemarkEmitter;
-class Pass;
class PredicatedScalarEvolution;
class PredIteratorCache;
class ScalarEvolution;
class SCEV;
class TargetLibraryInfo;
+class TargetTransformInfo;
/// \brief Captures loop safety information.
/// It keep information for loop & its header may throw exception.
struct LoopSafetyInfo {
- bool MayThrow; // The current loop contains an instruction which
- // may throw.
- bool HeaderMayThrow; // Same as previous, but specific to loop header
+ bool MayThrow = false; // The current loop contains an instruction which
+ // may throw.
+ bool HeaderMayThrow = false; // Same as previous, but specific to loop header
// Used to update funclet bundle operands.
DenseMap<BasicBlock *, ColorVector> BlockColors;
- LoopSafetyInfo() : MayThrow(false), HeaderMayThrow(false) {}
+
+ LoopSafetyInfo() = default;
};
/// The RecurrenceDescriptor is used to identify recurrences variables in a
@@ -61,7 +70,6 @@ struct LoopSafetyInfo {
/// This struct holds information about recurrence variables.
class RecurrenceDescriptor {
-
public:
/// This enum represents the kinds of recurrences that we support.
enum RecurrenceKind {
@@ -88,10 +96,7 @@ public:
MRK_FloatMax
};
- RecurrenceDescriptor()
- : StartValue(nullptr), LoopExitInstr(nullptr), Kind(RK_NoRecurrence),
- MinMaxKind(MRK_Invalid), UnsafeAlgebraInst(nullptr),
- RecurrenceType(nullptr), IsSigned(false) {}
+ RecurrenceDescriptor() = default;
RecurrenceDescriptor(Value *Start, Instruction *Exit, RecurrenceKind K,
MinMaxRecurrenceKind MK, Instruction *UAI, Type *RT,
@@ -103,7 +108,6 @@ public:
/// This POD struct holds information about a potential recurrence operation.
class InstDesc {
-
public:
InstDesc(bool IsRecur, Instruction *I, Instruction *UAI = nullptr)
: IsRecurrence(IsRecur), PatternLastInst(I), MinMaxKind(MRK_Invalid),
@@ -180,9 +184,14 @@ public:
/// Returns true if Phi is a first-order recurrence. A first-order recurrence
/// is a non-reduction recurrence relation in which the value of the
/// recurrence in the current loop iteration equals a value defined in the
- /// previous iteration.
- static bool isFirstOrderRecurrence(PHINode *Phi, Loop *TheLoop,
- DominatorTree *DT);
+ /// previous iteration. \p SinkAfter includes pairs of instructions where the
+ /// first will be rescheduled to appear after the second if/when the loop is
+ /// vectorized. It may be augmented with additional pairs if needed in order
+ /// to handle Phi as a first-order recurrence.
+ static bool
+ isFirstOrderRecurrence(PHINode *Phi, Loop *TheLoop,
+ DenseMap<Instruction *, Instruction *> &SinkAfter,
+ DominatorTree *DT);
RecurrenceKind getRecurrenceKind() { return Kind; }
@@ -242,17 +251,17 @@ private:
// It does not have to be zero!
TrackingVH<Value> StartValue;
// The instruction who's value is used outside the loop.
- Instruction *LoopExitInstr;
+ Instruction *LoopExitInstr = nullptr;
// The kind of the recurrence.
- RecurrenceKind Kind;
+ RecurrenceKind Kind = RK_NoRecurrence;
// If this a min/max recurrence the kind of recurrence.
- MinMaxRecurrenceKind MinMaxKind;
+ MinMaxRecurrenceKind MinMaxKind = MRK_Invalid;
// First occurrence of unasfe algebra in the PHI's use-chain.
- Instruction *UnsafeAlgebraInst;
+ Instruction *UnsafeAlgebraInst = nullptr;
// The type of the recurrence.
- Type *RecurrenceType;
+ Type *RecurrenceType = nullptr;
// True if all source operands of the recurrence are SExtInsts.
- bool IsSigned;
+ bool IsSigned = false;
// Instructions used for type-promoting the recurrence.
SmallPtrSet<Instruction *, 8> CastInsts;
};
@@ -270,9 +279,7 @@ public:
public:
/// Default constructor - creates an invalid induction.
- InductionDescriptor()
- : StartValue(nullptr), IK(IK_NoInduction), Step(nullptr),
- InductionBinOp(nullptr) {}
+ InductionDescriptor() = default;
/// Get the consecutive direction. Returns:
/// 0 - unknown or non-consecutive.
@@ -350,16 +357,24 @@ private:
/// Start value.
TrackingVH<Value> StartValue;
/// Induction kind.
- InductionKind IK;
+ InductionKind IK = IK_NoInduction;
/// Step value.
- const SCEV *Step;
+ const SCEV *Step = nullptr;
// Instruction that advances induction variable.
- BinaryOperator *InductionBinOp;
+ BinaryOperator *InductionBinOp = nullptr;
};
BasicBlock *InsertPreheaderForLoop(Loop *L, DominatorTree *DT, LoopInfo *LI,
bool PreserveLCSSA);
+/// Ensure that all exit blocks of the loop are dedicated exits.
+///
+/// For any loop exit block with non-loop predecessors, we split the loop
+/// predecessors to use a dedicated loop exit block. We update the dominator
+/// tree and loop info if provided, and will preserve LCSSA if requested.
+bool formDedicatedExitBlocks(Loop *L, DominatorTree *DT, LoopInfo *LI,
+ bool PreserveLCSSA);
+
/// Ensures LCSSA form for every instruction from the Worklist in the scope of
/// innermost containing loop.
///
@@ -488,6 +503,39 @@ bool canSinkOrHoistInst(Instruction &I, AAResults *AA, DominatorTree *DT,
Loop *CurLoop, AliasSetTracker *CurAST,
LoopSafetyInfo *SafetyInfo,
OptimizationRemarkEmitter *ORE = nullptr);
-}
-#endif
+/// Generates a vector reduction using shufflevectors to reduce the value.
+Value *getShuffleReduction(IRBuilder<> &Builder, Value *Src, unsigned Op,
+ RecurrenceDescriptor::MinMaxRecurrenceKind
+ MinMaxKind = RecurrenceDescriptor::MRK_Invalid,
+ ArrayRef<Value *> RedOps = ArrayRef<Value *>());
+
+/// Create a target reduction of the given vector. The reduction operation
+/// is described by the \p Opcode parameter. min/max reductions require
+/// additional information supplied in \p Flags.
+/// The target is queried to determine if intrinsics or shuffle sequences are
+/// required to implement the reduction.
+Value *
+createSimpleTargetReduction(IRBuilder<> &B, const TargetTransformInfo *TTI,
+ unsigned Opcode, Value *Src,
+ TargetTransformInfo::ReductionFlags Flags =
+ TargetTransformInfo::ReductionFlags(),
+ ArrayRef<Value *> RedOps = ArrayRef<Value *>());
+
+/// Create a generic target reduction using a recurrence descriptor \p Desc
+/// The target is queried to determine if intrinsics or shuffle sequences are
+/// required to implement the reduction.
+Value *createTargetReduction(IRBuilder<> &B, const TargetTransformInfo *TTI,
+ RecurrenceDescriptor &Desc, Value *Src,
+ bool NoNaN = false);
+
+/// Get the intersection (logical and) of all of the potential IR flags
+/// of each scalar operation (VL) that will be converted into a vector (I).
+/// If OpValue is non-null, we only consider operations similar to OpValue
+/// when intersecting.
+/// Flag set: NSW, NUW, exact, and all of fast-math.
+void propagateIRFlags(Value *I, ArrayRef<Value *> VL, Value *OpValue = nullptr);
+
+} // end namespace llvm
+
+#endif // LLVM_TRANSFORMS_UTILS_LOOPUTILS_H
diff --git a/contrib/llvm/include/llvm/Transforms/Utils/LoopVersioning.h b/contrib/llvm/include/llvm/Transforms/Utils/LoopVersioning.h
index 0d345a9..fa5d784 100644
--- a/contrib/llvm/include/llvm/Transforms/Utils/LoopVersioning.h
+++ b/contrib/llvm/include/llvm/Transforms/Utils/LoopVersioning.h
@@ -18,8 +18,8 @@
#include "llvm/Analysis/LoopAccessAnalysis.h"
#include "llvm/Analysis/ScalarEvolution.h"
-#include "llvm/Transforms/Utils/ValueMapper.h"
#include "llvm/Transforms/Utils/LoopUtils.h"
+#include "llvm/Transforms/Utils/ValueMapper.h"
namespace llvm {
diff --git a/contrib/llvm/include/llvm/Transforms/Utils/LowerMemIntrinsics.h b/contrib/llvm/include/llvm/Transforms/Utils/LowerMemIntrinsics.h
new file mode 100644
index 0000000..4554b5c
--- /dev/null
+++ b/contrib/llvm/include/llvm/Transforms/Utils/LowerMemIntrinsics.h
@@ -0,0 +1,62 @@
+//===- llvm/Transforms/Utils/LowerMemintrinsics.h ---------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Lower memset, memcpy, memmov intrinsics to loops (e.g. for targets without
+// library support).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_UTILS_LOWERMEMINTRINSICS_H
+#define LLVM_TRANSFORMS_UTILS_LOWERMEMINTRINSICS_H
+
+namespace llvm {
+
+class ConstantInt;
+class Instruction;
+class MemCpyInst;
+class MemMoveInst;
+class MemSetInst;
+class TargetTransformInfo;
+class Value;
+
+/// Emit a loop implementing the semantics of llvm.memcpy with the equivalent
+/// arguments at \p InsertBefore.
+void createMemCpyLoop(Instruction *InsertBefore, Value *SrcAddr, Value *DstAddr,
+ Value *CopyLen, unsigned SrcAlign, unsigned DestAlign,
+ bool SrcIsVolatile, bool DstIsVolatile);
+
+/// 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,
+ bool SrcIsVolatile, bool DstIsVolatile,
+ const TargetTransformInfo &TTI);
+
+/// Emit a loop implementing the semantics of an llvm.memcpy whose size is a
+/// compile time constant. Loop is inserted at \p InsertBefore.
+void createMemCpyLoopKnownSize(Instruction *InsertBefore, Value *SrcAddr,
+ Value *DstAddr, ConstantInt *CopyLen,
+ unsigned SrcAlign, unsigned 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);
+
+/// Expand \p MemMove as a loop. \p MemMove is not deleted.
+void expandMemMoveAsLoop(MemMoveInst *MemMove);
+
+/// Expand \p MemSet as a loop. \p MemSet is not deleted.
+void expandMemSetAsLoop(MemSetInst *MemSet);
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Transforms/Utils/Mem2Reg.h b/contrib/llvm/include/llvm/Transforms/Utils/Mem2Reg.h
index 456876b..1fe186d 100644
--- a/contrib/llvm/include/llvm/Transforms/Utils/Mem2Reg.h
+++ b/contrib/llvm/include/llvm/Transforms/Utils/Mem2Reg.h
@@ -25,4 +25,4 @@ public:
};
}
-#endif // LLVM_TRANSFORMS_UTILS_MEM2REG_H \ No newline at end of file
+#endif // LLVM_TRANSFORMS_UTILS_MEM2REG_H
diff --git a/contrib/llvm/include/llvm/Transforms/Utils/ModuleUtils.h b/contrib/llvm/include/llvm/Transforms/Utils/ModuleUtils.h
index 2750879..e9793fe 100644
--- a/contrib/llvm/include/llvm/Transforms/Utils/ModuleUtils.h
+++ b/contrib/llvm/include/llvm/Transforms/Utils/ModuleUtils.h
@@ -46,6 +46,9 @@ void appendToGlobalDtors(Module &M, Function *F, int Priority,
// getOrInsertFunction returns a bitcast.
Function *checkSanitizerInterfaceFunction(Constant *FuncOrBitcast);
+Function *declareSanitizerInitFunction(Module &M, StringRef InitName,
+ ArrayRef<Type *> InitArgTypes);
+
/// \brief Creates sanitizer constructor function, and calls sanitizer's init
/// function from it.
/// \return Returns pair of pointers to constructor, and init functions
@@ -81,6 +84,17 @@ void appendToCompilerUsed(Module &M, ArrayRef<GlobalValue *> Values);
void filterDeadComdatFunctions(
Module &M, SmallVectorImpl<Function *> &DeadComdatFunctions);
+/// \brief Produce a unique identifier for this module by taking the MD5 sum of
+/// the names of the module's strong external symbols.
+///
+/// This identifier is normally guaranteed to be unique, or the program would
+/// fail to link due to multiply defined symbols.
+///
+/// If the module has no strong external symbols (such a module may still have a
+/// semantic effect if it performs global initialization), we cannot produce a
+/// unique identifier for this module, so we return the empty string.
+std::string getUniqueModuleId(Module *M);
+
} // End llvm namespace
#endif // LLVM_TRANSFORMS_UTILS_MODULEUTILS_H
diff --git a/contrib/llvm/include/llvm/Transforms/Utils/NameAnonGlobals.h b/contrib/llvm/include/llvm/Transforms/Utils/NameAnonGlobals.h
index 4bec361..17fc902 100644
--- a/contrib/llvm/include/llvm/Transforms/Utils/NameAnonGlobals.h
+++ b/contrib/llvm/include/llvm/Transforms/Utils/NameAnonGlobals.h
@@ -1,4 +1,4 @@
-//===-- NameAnonGlobals.h - Anonymous Global Naming Pass ----*- C++ -*-=======//
+//===-- NameAnonGlobals.h - Anonymous Global Naming Pass --------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -23,9 +23,11 @@ namespace llvm {
/// Simple pass that provides a name to every anonymous globals.
class NameAnonGlobalPass : public PassInfoMixin<NameAnonGlobalPass> {
public:
- NameAnonGlobalPass() {}
+ NameAnonGlobalPass() = default;
+
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
};
-}
+
+} // end namespace llvm
#endif // LLVM_TRANSFORMS_UTILS_NAMEANONGLOBALS_H
diff --git a/contrib/llvm/include/llvm/Transforms/Utils/OrderedInstructions.h b/contrib/llvm/include/llvm/Transforms/Utils/OrderedInstructions.h
new file mode 100644
index 0000000..165d4bd
--- /dev/null
+++ b/contrib/llvm/include/llvm/Transforms/Utils/OrderedInstructions.h
@@ -0,0 +1,54 @@
+//===- llvm/Transforms/Utils/OrderedInstructions.h -------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// 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_TRANSFORMS_UTILS_ORDEREDINSTRUCTIONS_H
+#define LLVM_TRANSFORMS_UTILS_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;
+
+public:
+ /// Constructor.
+ OrderedInstructions(DominatorTree *DT) : DT(DT) {}
+
+ /// Return true if first instruction dominates the second.
+ bool dominates(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_TRANSFORMS_UTILS_ORDEREDINSTRUCTIONS_H
diff --git a/contrib/llvm/include/llvm/Transforms/Utils/PredicateInfo.h b/contrib/llvm/include/llvm/Transforms/Utils/PredicateInfo.h
new file mode 100644
index 0000000..8150f15
--- /dev/null
+++ b/contrib/llvm/include/llvm/Transforms/Utils/PredicateInfo.h
@@ -0,0 +1,295 @@
+//===- PredicateInfo.h - Build PredicateInfo ----------------------*-C++-*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief This file implements the PredicateInfo analysis, which creates an Extended
+/// SSA form for operations used in branch comparisons and llvm.assume
+/// comparisons.
+///
+/// Copies of these operations are inserted into the true/false edge (and after
+/// assumes), and information attached to the copies. All uses of the original
+/// operation in blocks dominated by the true/false edge (and assume), are
+/// replaced with uses of the copies. This enables passes to easily and sparsely
+/// propagate condition based info into the operations that may be affected.
+///
+/// Example:
+/// %cmp = icmp eq i32 %x, 50
+/// br i1 %cmp, label %true, label %false
+/// true:
+/// ret i32 %x
+/// false:
+/// ret i32 1
+///
+/// will become
+///
+/// %cmp = icmp eq i32, %x, 50
+/// br i1 %cmp, label %true, label %false
+/// true:
+/// %x.0 = call @llvm.ssa_copy.i32(i32 %x)
+/// ret i32 %x.0
+/// false:
+/// ret i32 1
+///
+/// Using getPredicateInfoFor on x.0 will give you the comparison it is
+/// dominated by (the icmp), and that you are located in the true edge of that
+/// comparison, which tells you x.0 is 50.
+///
+/// In order to reduce the number of copies inserted, predicateinfo is only
+/// inserted where it would actually be live. This means if there are no uses of
+/// an operation dominated by the branch edges, or by an assume, the associated
+/// predicate info is never inserted.
+///
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_UTILS_PREDICATEINFO_H
+#define LLVM_TRANSFORMS_UTILS_PREDICATEINFO_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/SmallPtrSet.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/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/Value.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 "llvm/Transforms/Utils/OrderedInstructions.h"
+#include <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <iterator>
+#include <memory>
+#include <utility>
+
+namespace llvm {
+
+class DominatorTree;
+class Function;
+class Instruction;
+class MemoryAccess;
+class LLVMContext;
+class raw_ostream;
+
+enum PredicateType { PT_Branch, PT_Assume, PT_Switch };
+
+// Base class for all predicate information we provide.
+// All of our predicate information has at least a comparison.
+class PredicateBase : public ilist_node<PredicateBase> {
+public:
+ PredicateType Type;
+ // The original operand before we renamed it.
+ // 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;
+ PredicateBase(const PredicateBase &) = delete;
+ PredicateBase &operator=(const PredicateBase &) = delete;
+ PredicateBase() = delete;
+ virtual ~PredicateBase() = default;
+
+protected:
+ PredicateBase(PredicateType PT, Value *Op) : Type(PT), OriginalOp(Op) {}
+};
+
+class PredicateWithCondition : public PredicateBase {
+public:
+ Value *Condition;
+ static bool classof(const PredicateBase *PB) {
+ return PB->Type == PT_Assume || PB->Type == PT_Branch ||
+ PB->Type == PT_Switch;
+ }
+
+protected:
+ PredicateWithCondition(PredicateType PT, Value *Op, Value *Condition)
+ : PredicateBase(PT, Op), Condition(Condition) {}
+};
+
+// Provides predicate information for assumes. Since assumes are always true,
+// we simply provide the assume instruction, so you can tell your relative
+// position to it.
+class PredicateAssume : public PredicateWithCondition {
+public:
+ IntrinsicInst *AssumeInst;
+ PredicateAssume(Value *Op, IntrinsicInst *AssumeInst, Value *Condition)
+ : PredicateWithCondition(PT_Assume, Op, Condition),
+ AssumeInst(AssumeInst) {}
+ PredicateAssume() = delete;
+ static bool classof(const PredicateBase *PB) {
+ return PB->Type == PT_Assume;
+ }
+};
+
+// Mixin class for edge predicates. The FROM block is the block where the
+// predicate originates, and the TO block is the block where the predicate is
+// valid.
+class PredicateWithEdge : public PredicateWithCondition {
+public:
+ BasicBlock *From;
+ BasicBlock *To;
+ PredicateWithEdge() = delete;
+ static bool classof(const PredicateBase *PB) {
+ return PB->Type == PT_Branch || PB->Type == PT_Switch;
+ }
+
+protected:
+ PredicateWithEdge(PredicateType PType, Value *Op, BasicBlock *From,
+ BasicBlock *To, Value *Cond)
+ : PredicateWithCondition(PType, Op, Cond), From(From), To(To) {}
+};
+
+// Provides predicate information for branches.
+class PredicateBranch : public PredicateWithEdge {
+public:
+ // If true, SplitBB is the true successor, otherwise it's the false successor.
+ bool TrueEdge;
+ PredicateBranch(Value *Op, BasicBlock *BranchBB, BasicBlock *SplitBB,
+ Value *Condition, bool TakenEdge)
+ : PredicateWithEdge(PT_Branch, Op, BranchBB, SplitBB, Condition),
+ TrueEdge(TakenEdge) {}
+ PredicateBranch() = delete;
+ static bool classof(const PredicateBase *PB) {
+ return PB->Type == PT_Branch;
+ }
+};
+
+class PredicateSwitch : public PredicateWithEdge {
+public:
+ Value *CaseValue;
+ // This is the switch instruction.
+ SwitchInst *Switch;
+ PredicateSwitch(Value *Op, BasicBlock *SwitchBB, BasicBlock *TargetBB,
+ Value *CaseValue, SwitchInst *SI)
+ : PredicateWithEdge(PT_Switch, Op, SwitchBB, TargetBB,
+ SI->getCondition()),
+ CaseValue(CaseValue), Switch(SI) {}
+ PredicateSwitch() = delete;
+ static bool classof(const PredicateBase *PB) {
+ return PB->Type == PT_Switch;
+ }
+};
+
+// This name is used in a few places, so kick it into their own namespace
+namespace PredicateInfoClasses {
+struct ValueDFS;
+}
+
+/// \brief 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();
+
+ void verifyPredicateInfo() const;
+
+ void dump() const;
+ void print(raw_ostream &) const;
+
+ const PredicateBase *getPredicateInfoFor(const Value *V) const {
+ return PredicateMap.lookup(V);
+ }
+
+protected:
+ // Used by PredicateInfo annotater, dumpers, and wrapper pass.
+ friend class PredicateInfoAnnotatedWriter;
+ friend class PredicateInfoPrinterLegacyPass;
+
+private:
+ void buildPredicateInfo();
+ void processAssume(IntrinsicInst *, BasicBlock *, SmallPtrSetImpl<Value *> &);
+ void processBranch(BranchInst *, BasicBlock *, SmallPtrSetImpl<Value *> &);
+ void processSwitch(SwitchInst *, BasicBlock *, SmallPtrSetImpl<Value *> &);
+ void renameUses(SmallPtrSetImpl<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(SmallPtrSetImpl<Value *> &OpsToRename, Value *Op,
+ PredicateBase *PB);
+ const ValueInfo &getValueInfo(Value *) const;
+ Function &F;
+ DominatorTree &DT;
+ AssumptionCache &AC;
+ OrderedInstructions OI;
+ // 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;
+};
+
+// This pass does eager building and then printing of PredicateInfo. It is used
+// by
+// the tests to be able to build, dump, and verify PredicateInfo.
+class PredicateInfoPrinterLegacyPass : public FunctionPass {
+public:
+ PredicateInfoPrinterLegacyPass();
+
+ static char ID;
+ bool runOnFunction(Function &) override;
+ void getAnalysisUsage(AnalysisUsage &AU) const override;
+};
+
+/// \brief Printer pass for \c PredicateInfo.
+class PredicateInfoPrinterPass
+ : public PassInfoMixin<PredicateInfoPrinterPass> {
+ raw_ostream &OS;
+
+public:
+ explicit PredicateInfoPrinterPass(raw_ostream &OS) : OS(OS) {}
+ PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
+};
+
+/// \brief Verifier pass for \c PredicateInfo.
+struct PredicateInfoVerifierPass : PassInfoMixin<PredicateInfoVerifierPass> {
+ PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
+};
+
+} // end namespace llvm
+
+#endif // LLVM_TRANSFORMS_UTILS_PREDICATEINFO_H
diff --git a/contrib/llvm/include/llvm/Transforms/Utils/PromoteMemToReg.h b/contrib/llvm/include/llvm/Transforms/Utils/PromoteMemToReg.h
index b548072..bb8a61a 100644
--- a/contrib/llvm/include/llvm/Transforms/Utils/PromoteMemToReg.h
+++ b/contrib/llvm/include/llvm/Transforms/Utils/PromoteMemToReg.h
@@ -38,10 +38,7 @@ bool isAllocaPromotable(const AllocaInst *AI);
/// does not modify the CFG of the function at all. All allocas must be from
/// the same function.
///
-/// If AST is specified, the specified tracker is updated to reflect changes
-/// made to the IR.
void PromoteMemToReg(ArrayRef<AllocaInst *> Allocas, DominatorTree &DT,
- AliasSetTracker *AST = nullptr,
AssumptionCache *AC = nullptr);
} // End llvm namespace
diff --git a/contrib/llvm/include/llvm/Transforms/Utils/SSAUpdater.h b/contrib/llvm/include/llvm/Transforms/Utils/SSAUpdater.h
index 9f98bac..8cbcdf4 100644
--- a/contrib/llvm/include/llvm/Transforms/Utils/SSAUpdater.h
+++ b/contrib/llvm/include/llvm/Transforms/Utils/SSAUpdater.h
@@ -15,19 +15,20 @@
#define LLVM_TRANSFORMS_UTILS_SSAUPDATER_H
#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/Compiler.h"
+#include <string>
namespace llvm {
- class BasicBlock;
- class Instruction;
- class LoadInst;
- template <typename T> class ArrayRef;
- template <typename T> class SmallVectorImpl;
- template <typename T> class SSAUpdaterTraits;
- class PHINode;
- class Type;
- class Use;
- class Value;
+
+class BasicBlock;
+class Instruction;
+class LoadInst;
+template <typename T> class ArrayRef;
+template <typename T> class SmallVectorImpl;
+template <typename T> class SSAUpdaterTraits;
+class PHINode;
+class Type;
+class Use;
+class Value;
/// \brief Helper class for SSA formation on a set of values defined in
/// multiple blocks.
@@ -42,10 +43,10 @@ private:
/// 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<BasicBlock*, Value*> AvailableValsTy;
- void *AV;
+ void *AV = nullptr;
/// ProtoType holds the type of the values being rewritten.
- Type *ProtoType;
+ Type *ProtoType = nullptr;
/// PHI nodes are given a name based on ProtoName.
std::string ProtoName;
@@ -58,6 +59,8 @@ public:
/// If InsertedPHIs is specified, it will be filled
/// in with all PHI Nodes created by rewriting.
explicit SSAUpdater(SmallVectorImpl<PHINode*> *InsertedPHIs = nullptr);
+ SSAUpdater(const SSAUpdater &) = delete;
+ SSAUpdater &operator=(const SSAUpdater &) = delete;
~SSAUpdater();
/// \brief Reset this object to get ready for a new set of SSA updates with
@@ -118,9 +121,6 @@ public:
private:
Value *GetValueAtEndOfBlockInternal(BasicBlock *BB);
-
- void operator=(const SSAUpdater&) = delete;
- SSAUpdater(const SSAUpdater&) = delete;
};
/// \brief Helper class for promoting a collection of loads and stores into SSA
@@ -138,7 +138,7 @@ protected:
public:
LoadAndStorePromoter(ArrayRef<const Instruction*> Insts,
SSAUpdater &S, StringRef Name = StringRef());
- virtual ~LoadAndStorePromoter() {}
+ virtual ~LoadAndStorePromoter() = default;
/// \brief This does the promotion.
///
@@ -173,6 +173,6 @@ public:
}
};
-} // End llvm namespace
+} // end namespace llvm
-#endif
+#endif // LLVM_TRANSFORMS_UTILS_SSAUPDATER_H
diff --git a/contrib/llvm/include/llvm/Transforms/Utils/SSAUpdaterImpl.h b/contrib/llvm/include/llvm/Transforms/Utils/SSAUpdaterImpl.h
index b0448fe..2dd205d 100644
--- a/contrib/llvm/include/llvm/Transforms/Utils/SSAUpdaterImpl.h
+++ b/contrib/llvm/include/llvm/Transforms/Utils/SSAUpdaterImpl.h
@@ -22,10 +22,10 @@
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Debug.h"
-namespace llvm {
-
#define DEBUG_TYPE "ssaupdater"
+namespace llvm {
+
class CastInst;
class PHINode;
template<typename T> class SSAUpdaterTraits;
@@ -453,8 +453,8 @@ public:
}
};
-#undef DEBUG_TYPE // "ssaupdater"
+} // end llvm namespace
-} // End llvm namespace
+#undef DEBUG_TYPE // "ssaupdater"
-#endif
+#endif // LLVM_TRANSFORMS_UTILS_SSAUPDATERIMPL_H
diff --git a/contrib/llvm/include/llvm/Transforms/Utils/SimplifyIndVar.h b/contrib/llvm/include/llvm/Transforms/Utils/SimplifyIndVar.h
index 90438ee..8d50aeb 100644
--- a/contrib/llvm/include/llvm/Transforms/Utils/SimplifyIndVar.h
+++ b/contrib/llvm/include/llvm/Transforms/Utils/SimplifyIndVar.h
@@ -22,7 +22,6 @@ namespace llvm {
class CastInst;
class DominatorTree;
-class IVUsers;
class Loop;
class LoopInfo;
class PHINode;
@@ -32,13 +31,13 @@ class ScalarEvolution;
/// simplified by this utility.
class IVVisitor {
protected:
- const DominatorTree *DT;
+ const DominatorTree *DT = nullptr;
virtual void anchor();
public:
- IVVisitor() : DT(nullptr) {}
- virtual ~IVVisitor() {}
+ IVVisitor() = default;
+ virtual ~IVVisitor() = default;
const DominatorTree *getDomTree() const { return DT; }
virtual void visitCast(CastInst *Cast) = 0;
@@ -47,14 +46,14 @@ 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<WeakVH> &Dead,
+ LoopInfo *LI, SmallVectorImpl<WeakTrackingVH> &Dead,
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<WeakVH> &Dead);
+ LoopInfo *LI, SmallVectorImpl<WeakTrackingVH> &Dead);
-} // namespace llvm
+} // end namespace llvm
-#endif
+#endif // LLVM_TRANSFORMS_UTILS_SIMPLIFYINDVAR_H
diff --git a/contrib/llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h b/contrib/llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h
index 5e217ad..6aba9b2 100644
--- a/contrib/llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h
+++ b/contrib/llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h
@@ -56,8 +56,8 @@ private:
Value *optimizeMemSetChk(CallInst *CI, IRBuilder<> &B);
// Str/Stp cpy are similar enough to be handled in the same functions.
- Value *optimizeStrpCpyChk(CallInst *CI, IRBuilder<> &B, LibFunc::Func Func);
- Value *optimizeStrpNCpyChk(CallInst *CI, IRBuilder<> &B, LibFunc::Func Func);
+ Value *optimizeStrpCpyChk(CallInst *CI, IRBuilder<> &B, LibFunc Func);
+ Value *optimizeStrpNCpyChk(CallInst *CI, IRBuilder<> &B, LibFunc Func);
/// \brief Checks whether the call \p CI to a fortified libcall is foldable
/// to the non-fortified version.
@@ -121,6 +121,7 @@ private:
Value *optimizeMemCpy(CallInst *CI, IRBuilder<> &B);
Value *optimizeMemMove(CallInst *CI, IRBuilder<> &B);
Value *optimizeMemSet(CallInst *CI, IRBuilder<> &B);
+ Value *optimizeWcslen(CallInst *CI, IRBuilder<> &B);
// Wrapper for all String/Memory Library Call Optimizations
Value *optimizeStringMemoryLibCall(CallInst *CI, IRBuilder<> &B);
@@ -128,7 +129,6 @@ private:
Value *optimizeCos(CallInst *CI, IRBuilder<> &B);
Value *optimizePow(CallInst *CI, IRBuilder<> &B);
Value *optimizeExp2(CallInst *CI, IRBuilder<> &B);
- Value *optimizeFabs(CallInst *CI, IRBuilder<> &B);
Value *optimizeFMinFMax(CallInst *CI, IRBuilder<> &B);
Value *optimizeLog(CallInst *CI, IRBuilder<> &B);
Value *optimizeSqrt(CallInst *CI, IRBuilder<> &B);
@@ -166,6 +166,9 @@ private:
/// 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);
};
} // End llvm namespace
diff --git a/contrib/llvm/include/llvm/Transforms/Utils/SymbolRewriter.h b/contrib/llvm/include/llvm/Transforms/Utils/SymbolRewriter.h
index ff99517..9365898 100644
--- a/contrib/llvm/include/llvm/Transforms/Utils/SymbolRewriter.h
+++ b/contrib/llvm/include/llvm/Transforms/Utils/SymbolRewriter.h
@@ -36,18 +36,24 @@
#include "llvm/IR/Module.h"
#include "llvm/IR/PassManager.h"
#include <list>
+#include <memory>
+#include <string>
namespace llvm {
+
class MemoryBuffer;
namespace yaml {
+
class KeyValueNode;
class MappingNode;
class ScalarNode;
class Stream;
-}
+
+} // end namespace yaml
namespace SymbolRewriter {
+
/// The basic entity representing a rewrite operation. It serves as the base
/// class for any rewrite descriptor. It has a certain set of specializations
/// which describe a particular rewrite.
@@ -60,11 +66,6 @@ namespace SymbolRewriter {
/// select the symbols to rewrite. This descriptor list is passed to the
/// SymbolRewriter pass.
class RewriteDescriptor {
- RewriteDescriptor(const RewriteDescriptor &) = delete;
-
- const RewriteDescriptor &
- operator=(const RewriteDescriptor &) = delete;
-
public:
enum class Type {
Invalid, /// invalid
@@ -73,7 +74,9 @@ public:
NamedAlias, /// named alias - descriptor rewrites a global alias
};
- virtual ~RewriteDescriptor() {}
+ RewriteDescriptor(const RewriteDescriptor &) = delete;
+ RewriteDescriptor &operator=(const RewriteDescriptor &) = delete;
+ virtual ~RewriteDescriptor() = default;
Type getType() const { return Kind; }
@@ -108,7 +111,8 @@ private:
yaml::MappingNode *V,
RewriteDescriptorList *DL);
};
-}
+
+} // end namespace SymbolRewriter
ModulePass *createRewriteSymbolsPass();
ModulePass *createRewriteSymbolsPass(SymbolRewriter::RewriteDescriptorList &);
@@ -130,6 +134,7 @@ private:
SymbolRewriter::RewriteDescriptorList Descriptors;
};
-}
+
+} // end namespace llvm
#endif //LLVM_TRANSFORMS_UTILS_SYMBOLREWRITER_H
diff --git a/contrib/llvm/include/llvm/Transforms/Utils/UnifyFunctionExitNodes.h b/contrib/llvm/include/llvm/Transforms/Utils/UnifyFunctionExitNodes.h
index 550292f..222c601 100644
--- a/contrib/llvm/include/llvm/Transforms/Utils/UnifyFunctionExitNodes.h
+++ b/contrib/llvm/include/llvm/Transforms/Utils/UnifyFunctionExitNodes.h
@@ -19,16 +19,18 @@
#define LLVM_TRANSFORMS_UTILS_UNIFYFUNCTIONEXITNODES_H
#include "llvm/Pass.h"
+#include "llvm/PassRegistry.h"
namespace llvm {
struct UnifyFunctionExitNodes : public FunctionPass {
- BasicBlock *ReturnBlock, *UnwindBlock, *UnreachableBlock;
+ BasicBlock *ReturnBlock = nullptr;
+ BasicBlock *UnwindBlock = nullptr;
+ BasicBlock *UnreachableBlock;
public:
static char ID; // Pass identification, replacement for typeid
- UnifyFunctionExitNodes() : FunctionPass(ID),
- ReturnBlock(nullptr), UnwindBlock(nullptr) {
+ UnifyFunctionExitNodes() : FunctionPass(ID) {
initializeUnifyFunctionExitNodesPass(*PassRegistry::getPassRegistry());
}
@@ -47,6 +49,6 @@ public:
Pass *createUnifyFunctionExitNodesPass();
-} // End llvm namespace
+} // end namespace llvm
-#endif
+#endif // LLVM_TRANSFORMS_UTILS_UNIFYFUNCTIONEXITNODES_H
diff --git a/contrib/llvm/include/llvm/Transforms/Utils/UnrollLoop.h b/contrib/llvm/include/llvm/Transforms/Utils/UnrollLoop.h
index f322bea..a3115ad 100644
--- a/contrib/llvm/include/llvm/Transforms/Utils/UnrollLoop.h
+++ b/contrib/llvm/include/llvm/Transforms/Utils/UnrollLoop.h
@@ -53,10 +53,11 @@ bool UnrollRuntimeLoopRemainder(Loop *L, unsigned Count,
bool PreserveLCSSA);
void computePeelCount(Loop *L, unsigned LoopSize,
- TargetTransformInfo::UnrollingPreferences &UP);
+ TargetTransformInfo::UnrollingPreferences &UP,
+ unsigned &TripCount);
bool peelLoop(Loop *L, unsigned PeelCount, LoopInfo *LI, ScalarEvolution *SE,
- DominatorTree *DT, bool PreserveLCSSA);
+ DominatorTree *DT, AssumptionCache *AC, bool PreserveLCSSA);
MDNode *GetUnrollMetadata(MDNode *LoopID, StringRef Name);
}
diff --git a/contrib/llvm/include/llvm/Transforms/Utils/VNCoercion.h b/contrib/llvm/include/llvm/Transforms/Utils/VNCoercion.h
new file mode 100644
index 0000000..1baa9b6
--- /dev/null
+++ b/contrib/llvm/include/llvm/Transforms/Utils/VNCoercion.h
@@ -0,0 +1,108 @@
+//===- VNCoercion.h - Value Numbering Coercion Utilities --------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+/// \file / This file provides routines used by LLVM's value numbering passes to
+/// perform various forms of value extraction from memory when the types are not
+/// identical. For example, given
+///
+/// store i32 8, i32 *%foo
+/// %a = bitcast i32 *%foo to i16
+/// %val = load i16, i16 *%a
+///
+/// It possible to extract the value of the load of %a from the store to %foo.
+/// These routines know how to tell whether they can do that (the analyze*
+/// routines), and can also insert the necessary IR to do it (the get*
+/// routines).
+
+#ifndef LLVM_TRANSFORMS_UTILS_VNCOERCION_H
+#define LLVM_TRANSFORMS_UTILS_VNCOERCION_H
+#include "llvm/IR/IRBuilder.h"
+
+namespace llvm {
+class Function;
+class StoreInst;
+class LoadInst;
+class MemIntrinsic;
+class Instruction;
+class Value;
+class Type;
+class DataLayout;
+namespace VNCoercion {
+/// Return true if CoerceAvailableValueToLoadType would succeed if it was
+/// called.
+bool canCoerceMustAliasedValueToLoad(Value *StoredVal, Type *LoadTy,
+ const DataLayout &DL);
+
+/// If we saw a store of a value to memory, and then a load from a must-aliased
+/// pointer of a different type, try to coerce the stored value to the loaded
+/// type. LoadedTy is the type of the load we want to replace. IRB is
+/// IRBuilder used to insert new instructions.
+///
+/// If we can't do it, return null.
+Value *coerceAvailableValueToLoadType(Value *StoredVal, Type *LoadedTy,
+ IRBuilder<> &IRB, const DataLayout &DL);
+
+/// This function determines whether a value for the pointer LoadPtr can be
+/// extracted from the store at DepSI.
+///
+/// On success, it returns the offset into DepSI that extraction would start.
+/// On failure, it returns -1.
+int analyzeLoadFromClobberingStore(Type *LoadTy, Value *LoadPtr,
+ StoreInst *DepSI, const DataLayout &DL);
+
+/// This function determines whether a value for the pointer LoadPtr can be
+/// extracted from the load at DepLI.
+///
+/// On success, it returns the offset into DepLI that extraction would start.
+/// On failure, it returns -1.
+int analyzeLoadFromClobberingLoad(Type *LoadTy, Value *LoadPtr, LoadInst *DepLI,
+ const DataLayout &DL);
+
+/// This function determines whether a value for the pointer LoadPtr can be
+/// extracted from the memory intrinsic at DepMI.
+///
+/// On success, it returns the offset into DepMI that extraction would start.
+/// On failure, it returns -1.
+int analyzeLoadFromClobberingMemInst(Type *LoadTy, Value *LoadPtr,
+ MemIntrinsic *DepMI, const DataLayout &DL);
+
+/// If analyzeLoadFromClobberingStore returned an offset, this function can be
+/// used to actually perform the extraction of the bits from the store. It
+/// inserts instructions to do so at InsertPt, and returns the extracted value.
+Value *getStoreValueForLoad(Value *SrcVal, unsigned Offset, Type *LoadTy,
+ Instruction *InsertPt, const DataLayout &DL);
+// This is the same as getStoreValueForLoad, except it performs no insertion
+// It only allows constant inputs.
+Constant *getConstantStoreValueForLoad(Constant *SrcVal, unsigned Offset,
+ Type *LoadTy, const DataLayout &DL);
+
+/// If analyzeLoadFromClobberingLoad returned an offset, this function can be
+/// used to actually perform the extraction of the bits from the load, including
+/// any necessary load widening. It inserts instructions to do so at InsertPt,
+/// and returns the extracted value.
+Value *getLoadValueForLoad(LoadInst *SrcVal, unsigned Offset, Type *LoadTy,
+ Instruction *InsertPt, const DataLayout &DL);
+// This is the same as getLoadValueForLoad, except it is given the load value as
+// a constant. It returns nullptr if it would require widening the load.
+Constant *getConstantLoadValueForLoad(Constant *SrcVal, unsigned Offset,
+ Type *LoadTy, const DataLayout &DL);
+
+/// If analyzeLoadFromClobberingMemInst returned an offset, this function can be
+/// used to actually perform the extraction of the bits from the memory
+/// intrinsic. It inserts instructions to do so at InsertPt, and returns the
+/// extracted value.
+Value *getMemInstValueForLoad(MemIntrinsic *SrcInst, unsigned Offset,
+ Type *LoadTy, Instruction *InsertPt,
+ const DataLayout &DL);
+// This is the same as getStoreValueForLoad, except it performs no insertion.
+// It returns nullptr if it cannot produce a constant.
+Constant *getConstantMemInstValueForLoad(MemIntrinsic *SrcInst, unsigned Offset,
+ Type *LoadTy, const DataLayout &DL);
+}
+}
+#endif
diff --git a/contrib/llvm/include/llvm/Transforms/Utils/ValueMapper.h b/contrib/llvm/include/llvm/Transforms/Utils/ValueMapper.h
index de64900..45ef824 100644
--- a/contrib/llvm/include/llvm/Transforms/Utils/ValueMapper.h
+++ b/contrib/llvm/include/llvm/Transforms/Utils/ValueMapper.h
@@ -15,20 +15,23 @@
#ifndef LLVM_TRANSFORMS_UTILS_VALUEMAPPER_H
#define LLVM_TRANSFORMS_UTILS_VALUEMAPPER_H
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/IR/ValueHandle.h"
#include "llvm/IR/ValueMap.h"
namespace llvm {
class Value;
class Instruction;
-typedef ValueMap<const Value *, WeakVH> ValueToValueMapTy;
+typedef ValueMap<const Value *, WeakTrackingVH> ValueToValueMapTy;
/// This is a class that can be implemented by clients to remap types when
/// cloning constants and instructions.
class ValueMapTypeRemapper {
virtual void anchor(); // Out of line method.
+
public:
- virtual ~ValueMapTypeRemapper() {}
+ virtual ~ValueMapTypeRemapper() = default;
/// The client should implement this method if they want to remap types while
/// mapping values.
@@ -92,8 +95,6 @@ static inline RemapFlags operator|(RemapFlags LHS, RemapFlags RHS) {
return RemapFlags(unsigned(LHS) | unsigned(RHS));
}
-class ValueMapperImpl;
-
/// Context for (re-)mapping values (and metadata).
///
/// A shared context used for mapping and remapping of Value and Metadata
@@ -115,7 +116,7 @@ class ValueMapperImpl;
/// - \a scheduleMapGlobalAliasee()
/// - \a scheduleRemapFunction()
///
-/// Sometimes a callback needs a diferent mapping context. Such a context can
+/// Sometimes a callback needs a different mapping context. Such a context can
/// be registered using \a registerAlternateMappingContext(), which takes an
/// alternate \a ValueToValueMapTy and \a ValueMaterializer and returns a ID to
/// pass into the schedule*() functions.
@@ -133,15 +134,14 @@ class ValueMapperImpl;
class ValueMapper {
void *pImpl;
- ValueMapper(ValueMapper &&) = delete;
- ValueMapper(const ValueMapper &) = delete;
- ValueMapper &operator=(ValueMapper &&) = delete;
- ValueMapper &operator=(const ValueMapper &) = delete;
-
public:
ValueMapper(ValueToValueMapTy &VM, RemapFlags Flags = RF_None,
ValueMapTypeRemapper *TypeMapper = nullptr,
ValueMaterializer *Materializer = nullptr);
+ ValueMapper(ValueMapper &&) = delete;
+ ValueMapper(const ValueMapper &) = delete;
+ ValueMapper &operator=(ValueMapper &&) = delete;
+ ValueMapper &operator=(const ValueMapper &) = delete;
~ValueMapper();
/// Register an alternate mapping context.
@@ -268,6 +268,6 @@ inline Constant *MapValue(const Constant *V, ValueToValueMapTy &VM,
return ValueMapper(VM, Flags, TypeMapper, Materializer).mapConstant(*V);
}
-} // End llvm namespace
+} // end namespace llvm
-#endif
+#endif // LLVM_TRANSFORMS_UTILS_VALUEMAPPER_H
diff --git a/contrib/llvm/include/llvm/Transforms/Vectorize.h b/contrib/llvm/include/llvm/Transforms/Vectorize.h
index f734e29..19845e4 100644
--- a/contrib/llvm/include/llvm/Transforms/Vectorize.h
+++ b/contrib/llvm/include/llvm/Transforms/Vectorize.h
@@ -108,13 +108,6 @@ struct VectorizeConfig {
//===----------------------------------------------------------------------===//
//
-// BBVectorize - A basic-block vectorization pass.
-//
-BasicBlockPass *
-createBBVectorizePass(const VectorizeConfig &C = VectorizeConfig());
-
-//===----------------------------------------------------------------------===//
-//
// LoopVectorize - Create a loop vectorization pass.
//
Pass *createLoopVectorizePass(bool NoUnrolling = false,
diff --git a/contrib/llvm/include/llvm/Transforms/Vectorize/LoopVectorize.h b/contrib/llvm/include/llvm/Transforms/Vectorize/LoopVectorize.h
index 73d1f26..57d10c4 100644
--- a/contrib/llvm/include/llvm/Transforms/Vectorize/LoopVectorize.h
+++ b/contrib/llvm/include/llvm/Transforms/Vectorize/LoopVectorize.h
@@ -87,8 +87,6 @@ struct LoopVectorizePass : public PassInfoMixin<LoopVectorizePass> {
std::function<const LoopAccessInfo &(Loop &)> *GetLAA;
OptimizationRemarkEmitter *ORE;
- BlockFrequency ColdEntryFreq;
-
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
// Shim for old PM.
diff --git a/contrib/llvm/include/llvm/Transforms/Vectorize/SLPVectorizer.h b/contrib/llvm/include/llvm/Transforms/Vectorize/SLPVectorizer.h
index 4886700..6f25819 100644
--- a/contrib/llvm/include/llvm/Transforms/Vectorize/SLPVectorizer.h
+++ b/contrib/llvm/include/llvm/Transforms/Vectorize/SLPVectorizer.h
@@ -24,6 +24,7 @@
#include "llvm/Analysis/AssumptionCache.h"
#include "llvm/Analysis/DemandedBits.h"
#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/Analysis/OptimizationDiagnosticInfo.h"
#include "llvm/Analysis/ScalarEvolution.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/IR/Function.h"
@@ -40,8 +41,8 @@ class BoUpSLP;
struct SLPVectorizerPass : public PassInfoMixin<SLPVectorizerPass> {
typedef SmallVector<StoreInst *, 8> StoreList;
typedef MapVector<Value *, StoreList> StoreListMap;
- typedef SmallVector<WeakVH, 8> WeakVHList;
- typedef MapVector<Value *, WeakVHList> WeakVHListMap;
+ typedef SmallVector<WeakTrackingVH, 8> WeakTrackingVHList;
+ typedef MapVector<Value *, WeakTrackingVHList> WeakTrackingVHListMap;
ScalarEvolution *SE = nullptr;
TargetTransformInfo *TTI = nullptr;
@@ -59,7 +60,8 @@ public:
// Glue for old PM.
bool runImpl(Function &F, ScalarEvolution *SE_, TargetTransformInfo *TTI_,
TargetLibraryInfo *TLI_, AliasAnalysis *AA_, LoopInfo *LI_,
- DominatorTree *DT_, AssumptionCache *AC_, DemandedBits *DB_);
+ DominatorTree *DT_, AssumptionCache *AC_, DemandedBits *DB_,
+ OptimizationRemarkEmitter *ORE_);
private:
/// \brief Collect store and getelementptr instructions and organize them
@@ -82,7 +84,7 @@ private:
ArrayRef<Value *> BuildVector = None,
bool AllowReorder = false);
- /// \brief Try to vectorize a chain that may start at the operands of \V;
+ /// \brief Try to vectorize a chain that may start at the operands of \p V.
bool tryToVectorize(BinaryOperator *V, slpvectorizer::BoUpSLP &R);
/// \brief Vectorize the store instructions collected in Stores.
@@ -92,6 +94,12 @@ private:
/// collected in GEPs.
bool vectorizeGEPIndices(BasicBlock *BB, slpvectorizer::BoUpSLP &R);
+ /// Try to find horizontal reduction or otherwise vectorize a chain of binary
+ /// operators.
+ bool vectorizeRootInstruction(PHINode *P, Value *V, BasicBlock *BB,
+ slpvectorizer::BoUpSLP &R,
+ TargetTransformInfo *TTI);
+
/// \brief Scan the basic block and look for patterns that are likely to start
/// a vectorization chain.
bool vectorizeChainsInBlock(BasicBlock *BB, slpvectorizer::BoUpSLP &R);
@@ -105,7 +113,7 @@ private:
StoreListMap Stores;
/// The getelementptr instructions in a basic block organized by base pointer.
- WeakVHListMap GEPs;
+ WeakTrackingVHListMap GEPs;
};
}
diff --git a/contrib/llvm/include/llvm/XRay/Graph.h b/contrib/llvm/include/llvm/XRay/Graph.h
new file mode 100644
index 0000000..a4d34a8
--- /dev/null
+++ b/contrib/llvm/include/llvm/XRay/Graph.h
@@ -0,0 +1,494 @@
+//===-- Graph.h - XRay Graph Class ------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// A Graph Datatype for XRay.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_XRAY_GRAPH_T_H
+#define LLVM_XRAY_GRAPH_T_H
+
+#include <initializer_list>
+#include <stdint.h>
+#include <type_traits>
+#include <utility>
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/iterator.h"
+#include "llvm/Support/Error.h"
+
+namespace llvm {
+namespace xray {
+
+/// A Graph object represents a Directed Graph and is used in XRay to compute
+/// and store function call graphs and associated statistical information.
+///
+/// The graph takes in four template parameters, these are:
+/// - VertexAttribute, this is a structure which is stored for each vertex.
+/// Must be DefaultConstructible, CopyConstructible, CopyAssignable and
+/// Destructible.
+/// - EdgeAttribute, this is a structure which is stored for each edge
+/// Must be DefaultConstructible, CopyConstructible, CopyAssignable and
+/// Destructible.
+/// - EdgeAttribute, this is a structure which is stored for each variable
+/// - VI, this is a type over which DenseMapInfo is defined and is the type
+/// used look up strings, available as VertexIdentifier.
+/// - If the built in DenseMapInfo is not defined, provide a specialization
+/// class type here.
+///
+/// Graph is CopyConstructible, CopyAssignable, MoveConstructible and
+/// MoveAssignable but is not EqualityComparible or LessThanComparible.
+///
+/// Usage Example Graph with weighted edges and vertices:
+/// Graph<int, int, int> G;
+///
+/// G[1] = 0;
+/// G[2] = 2;
+/// G[{1,2}] = 1;
+/// G[{2,1}] = -1;
+/// for(const auto &v : G.vertices()){
+/// // Do something with the vertices in the graph;
+/// }
+/// for(const auto &e : G.edges()){
+/// // Do something with the edges in the graph;
+/// }
+///
+/// Usage Example with StrRef keys.
+/// Graph<int, double, StrRef> StrG;
+/// char va[] = "Vertex A";
+/// char vaa[] = "Vertex A";
+/// char vb[] = "Vertex B"; // Vertices are referenced by String Refs.
+/// G[va] = 0;
+/// G[vb] = 1;
+/// G[{va, vb}] = 1.0;
+/// cout() << G[vaa] << " " << G[{vaa, vb}]; //prints "0 1.0".
+///
+template <typename VertexAttribute, typename EdgeAttribute,
+ typename VI = int32_t>
+class Graph {
+public:
+ /// These objects are used to name edges and vertices in the graph.
+ typedef VI VertexIdentifier;
+ typedef std::pair<VI, VI> EdgeIdentifier;
+
+ /// This type is the value_type of all iterators which range over vertices,
+ /// Determined by the Vertices DenseMap
+ using VertexValueType =
+ detail::DenseMapPair<VertexIdentifier, VertexAttribute>;
+
+ /// This type is the value_type of all iterators which range over edges,
+ /// Determined by the Edges DenseMap.
+ using EdgeValueType = detail::DenseMapPair<EdgeIdentifier, EdgeAttribute>;
+
+ using size_type = std::size_t;
+
+private:
+ /// The type used for storing the EdgeAttribute for each edge in the graph
+ using EdgeMapT = DenseMap<EdgeIdentifier, EdgeAttribute>;
+
+ /// The type used for storing the VertexAttribute for each vertex in
+ /// the graph.
+ using VertexMapT = DenseMap<VertexIdentifier, VertexAttribute>;
+
+ /// The type used for storing the edges entering a vertex. Indexed by
+ /// the VertexIdentifier of the start of the edge. Only used to determine
+ /// where the incoming edges are, the EdgeIdentifiers are stored in an
+ /// InnerEdgeMapT.
+ using NeighborSetT = DenseSet<VertexIdentifier>;
+
+ /// The type storing the InnerInvGraphT corresponding to each vertex in
+ /// the graph (When a vertex has an incoming edge incident to it)
+ using NeighborLookupT = DenseMap<VertexIdentifier, NeighborSetT>;
+
+private:
+ /// Stores the map from the start and end vertex of an edge to it's
+ /// EdgeAttribute
+ EdgeMapT Edges;
+
+ /// Stores the map from VertexIdentifier to VertexAttribute
+ VertexMapT Vertices;
+
+ /// Allows fast lookup for the incoming edge set of any given vertex.
+ NeighborLookupT InNeighbors;
+
+ /// Allows fast lookup for the outgoing edge set of any given vertex.
+ NeighborLookupT OutNeighbors;
+
+ /// An Iterator adapter using an InnerInvGraphT::iterator as a base iterator,
+ /// and storing the VertexIdentifier the iterator range comes from. The
+ /// dereference operator is then performed using a pointer to the graph's edge
+ /// set.
+ template <bool IsConst, bool IsOut,
+ typename BaseIt = typename NeighborSetT::const_iterator,
+ typename T = typename std::conditional<IsConst, const EdgeValueType,
+ EdgeValueType>::type>
+ 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;
+
+ friend class NeighborEdgeIteratorT<false, IsOut, BaseIt, EdgeValueType>;
+ friend class NeighborEdgeIteratorT<true, IsOut, BaseIt,
+ const EdgeValueType>;
+
+ InternalEdgeMapT *MP;
+ VertexIdentifier SI;
+
+ public:
+ template <bool IsConstDest,
+ typename = typename std::enable_if<IsConstDest && !IsConst>::type>
+ operator NeighborEdgeIteratorT<IsConstDest, IsOut, BaseIt,
+ const EdgeValueType>() const {
+ return NeighborEdgeIteratorT<IsConstDest, IsOut, BaseIt,
+ const EdgeValueType>(this->I, MP, SI);
+ }
+
+ NeighborEdgeIteratorT() = default;
+ NeighborEdgeIteratorT(BaseIt _I, InternalEdgeMapT *_MP,
+ VertexIdentifier _SI)
+ : iterator_adaptor_base<
+ NeighborEdgeIteratorT<IsConst, IsOut>, BaseIt,
+ typename std::iterator_traits<BaseIt>::iterator_category, T>(_I),
+ MP(_MP), SI(_SI) {}
+
+ T &operator*() const {
+ if (!IsOut)
+ return *(MP->find({*(this->I), SI}));
+ else
+ return *(MP->find({SI, *(this->I)}));
+ }
+ };
+
+public:
+ /// A const iterator type for iterating through the set of edges entering a
+ /// vertex.
+ ///
+ /// Has a const EdgeValueType as its value_type
+ using ConstInEdgeIterator = NeighborEdgeIteratorT<true, false>;
+
+ /// An iterator type for iterating through the set of edges leaving a vertex.
+ ///
+ /// Has an EdgeValueType as its value_type
+ using InEdgeIterator = NeighborEdgeIteratorT<false, false>;
+
+ /// A const iterator type for iterating through the set of edges entering a
+ /// vertex.
+ ///
+ /// Has a const EdgeValueType as its value_type
+ using ConstOutEdgeIterator = NeighborEdgeIteratorT<true, true>;
+
+ /// An iterator type for iterating through the set of edges leaving a vertex.
+ ///
+ /// Has an EdgeValueType as its value_type
+ using OutEdgeIterator = NeighborEdgeIteratorT<false, true>;
+
+ /// A class for ranging over the incoming edges incident to a vertex.
+ ///
+ /// Like all views in this class it provides methods to get the beginning and
+ /// past the range iterators for the range, as well as methods to determine
+ /// the number of elements in the range and whether the range is empty.
+ template <bool isConst, bool isOut> class InOutEdgeView {
+ public:
+ using iterator = NeighborEdgeIteratorT<isConst, isOut>;
+ using const_iterator = NeighborEdgeIteratorT<true, isOut>;
+ using GraphT = typename std::conditional<isConst, const Graph, Graph>::type;
+ using InternalEdgeMapT =
+ typename std::conditional<isConst, const EdgeMapT, EdgeMapT>::type;
+
+ private:
+ InternalEdgeMapT &M;
+ const VertexIdentifier A;
+ const NeighborLookupT &NL;
+
+ public:
+ iterator begin() {
+ auto It = NL.find(A);
+ if (It == NL.end())
+ return iterator();
+ return iterator(It->second.begin(), &M, A);
+ }
+
+ const_iterator cbegin() const {
+ auto It = NL.find(A);
+ if (It == NL.end())
+ return const_iterator();
+ return const_iterator(It->second.begin(), &M, A);
+ }
+
+ const_iterator begin() const { return cbegin(); }
+
+ iterator end() {
+ auto It = NL.find(A);
+ if (It == NL.end())
+ return iterator();
+ return iterator(It->second.end(), &M, A);
+ }
+ const_iterator cend() const {
+ auto It = NL.find(A);
+ if (It == NL.end())
+ return const_iterator();
+ return const_iterator(It->second.end(), &M, A);
+ }
+
+ const_iterator end() const { return cend(); }
+
+ size_type size() const {
+ auto I = NL.find(A);
+ if (I == NL.end())
+ return 0;
+ else
+ return I->second.size();
+ }
+
+ bool empty() const { return NL.count(A) == 0; };
+
+ InOutEdgeView(GraphT &G, VertexIdentifier A)
+ : M(G.Edges), A(A), NL(isOut ? G.OutNeighbors : G.InNeighbors) {}
+ };
+
+ /// A const iterator type for iterating through the whole vertex set of the
+ /// graph.
+ ///
+ /// Has a const VertexValueType as its value_type
+ using ConstVertexIterator = typename VertexMapT::const_iterator;
+
+ /// An iterator type for iterating through the whole vertex set of the graph.
+ ///
+ /// Has a VertexValueType as its value_type
+ using VertexIterator = typename VertexMapT::iterator;
+
+ /// A class for ranging over the vertices in the graph.
+ ///
+ /// Like all views in this class it provides methods to get the beginning and
+ /// past the range iterators for the range, as well as methods to determine
+ /// 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 const_iterator = ConstVertexIterator;
+ using GraphT = typename std::conditional<isConst, const Graph, Graph>::type;
+
+ private:
+ GraphT &G;
+
+ public:
+ iterator begin() { return G.Vertices.begin(); }
+ iterator end() { return G.Vertices.end(); }
+ const_iterator cbegin() const { return G.Vertices.cbegin(); }
+ const_iterator cend() const { return G.Vertices.cend(); }
+ const_iterator begin() const { return G.Vertices.begin(); }
+ const_iterator end() const { return G.Vertices.end(); }
+ size_type size() const { return G.Vertices.size(); }
+ bool empty() const { return G.Vertices.empty(); }
+ VertexView(GraphT &_G) : G(_G) {}
+ };
+
+ /// A const iterator for iterating through the entire edge set of the graph.
+ ///
+ /// Has a const EdgeValueType as its value_type
+ using ConstEdgeIterator = typename EdgeMapT::const_iterator;
+
+ /// An iterator for iterating through the entire edge set of the graph.
+ ///
+ /// Has an EdgeValueType as its value_type
+ using EdgeIterator = typename EdgeMapT::iterator;
+
+ /// A class for ranging over all the edges in the graph.
+ ///
+ /// Like all views in this class it provides methods to get the beginning and
+ /// past the range iterators for the range, as well as methods to determine
+ /// 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 const_iterator = ConstEdgeIterator;
+ using GraphT = typename std::conditional<isConst, const Graph, Graph>::type;
+
+ private:
+ GraphT &G;
+
+ public:
+ iterator begin() { return G.Edges.begin(); }
+ iterator end() { return G.Edges.end(); }
+ const_iterator cbegin() const { return G.Edges.cbegin(); }
+ const_iterator cend() const { return G.Edges.cend(); }
+ const_iterator begin() const { return G.Edges.begin(); }
+ const_iterator end() const { return G.Edges.end(); }
+ size_type size() const { return G.Edges.size(); }
+ bool empty() const { return G.Edges.empty(); }
+ EdgeView(GraphT &_G) : G(_G) {}
+ };
+
+public:
+ // TODO: implement constructor to enable Graph Initialisation.\
+ // Something like:
+ // Graph<int, int, int> G(
+ // {1, 2, 3, 4, 5},
+ // {{1, 2}, {2, 3}, {3, 4}});
+
+ /// Empty the Graph
+ void clear() {
+ Edges.clear();
+ Vertices.clear();
+ InNeighbors.clear();
+ OutNeighbors.clear();
+ }
+
+ /// Returns a view object allowing iteration over the vertices of the graph.
+ /// also allows access to the size of the vertex set.
+ VertexView<false> vertices() { return VertexView<false>(*this); }
+
+ VertexView<true> vertices() const { return VertexView<true>(*this); }
+
+ /// Returns a view object allowing iteration over the edges of the graph.
+ /// also allows access to the size of the edge set.
+ EdgeView<false> edges() { return EdgeView<false>(*this); }
+
+ EdgeView<true> edges() const { return EdgeView<true>(*this); }
+
+ /// Returns a view object allowing iteration over the edges which start at
+ /// a vertex I.
+ InOutEdgeView<false, true> outEdges(const VertexIdentifier I) {
+ return InOutEdgeView<false, true>(*this, I);
+ }
+
+ InOutEdgeView<true, true> outEdges(const VertexIdentifier I) const {
+ return InOutEdgeView<true, true>(*this, I);
+ }
+
+ /// Returns a view object allowing iteration over the edges which point to
+ /// a vertex I.
+ InOutEdgeView<false, false> inEdges(const VertexIdentifier I) {
+ return InOutEdgeView<false, false>(*this, I);
+ }
+
+ InOutEdgeView<true, false> inEdges(const VertexIdentifier I) const {
+ return InOutEdgeView<true, false>(*this, I);
+ }
+
+ /// Looks up the vertex with identifier I, if it does not exist it default
+ /// constructs it.
+ VertexAttribute &operator[](const VertexIdentifier &I) {
+ return Vertices.FindAndConstruct(I).second;
+ }
+
+ /// Looks up the edge with identifier I, if it does not exist it default
+ /// constructs it, if it's endpoints do not exist it also default constructs
+ /// them.
+ EdgeAttribute &operator[](const EdgeIdentifier &I) {
+ auto &P = Edges.FindAndConstruct(I);
+ Vertices.FindAndConstruct(I.first);
+ Vertices.FindAndConstruct(I.second);
+ InNeighbors[I.second].insert(I.first);
+ OutNeighbors[I.first].insert(I.second);
+ return P.second;
+ }
+
+ /// Looks up a vertex with Identifier I, or an error if it does not exist.
+ Expected<VertexAttribute &> at(const VertexIdentifier &I) {
+ auto It = Vertices.find(I);
+ if (It == Vertices.end())
+ return make_error<StringError>(
+ "Vertex Identifier Does Not Exist",
+ std::make_error_code(std::errc::invalid_argument));
+ return It->second;
+ }
+
+ Expected<const VertexAttribute &> at(const VertexIdentifier &I) const {
+ auto It = Vertices.find(I);
+ if (It == Vertices.end())
+ return make_error<StringError>(
+ "Vertex Identifier Does Not Exist",
+ std::make_error_code(std::errc::invalid_argument));
+ return It->second;
+ }
+
+ /// Looks up an edge with Identifier I, or an error if it does not exist.
+ Expected<EdgeAttribute &> at(const EdgeIdentifier &I) {
+ auto It = Edges.find(I);
+ if (It == Edges.end())
+ return make_error<StringError>(
+ "Edge Identifier Does Not Exist",
+ std::make_error_code(std::errc::invalid_argument));
+ return It->second;
+ }
+
+ Expected<const EdgeAttribute &> at(const EdgeIdentifier &I) const {
+ auto It = Edges.find(I);
+ if (It == Edges.end())
+ return make_error<StringError>(
+ "Edge Identifier Does Not Exist",
+ std::make_error_code(std::errc::invalid_argument));
+ return It->second;
+ }
+
+ /// Looks for a vertex with identifier I, returns 1 if one exists, and
+ /// 0 otherwise
+ size_type count(const VertexIdentifier &I) const {
+ return Vertices.count(I);
+ }
+
+ /// Looks for an edge with Identifier I, returns 1 if one exists and 0
+ /// otherwise
+ size_type count(const EdgeIdentifier &I) const { return Edges.count(I); }
+
+ /// Inserts a vertex into the graph with Identifier Val.first, and
+ /// Attribute Val.second.
+ std::pair<VertexIterator, bool>
+ insert(const std::pair<VertexIdentifier, VertexAttribute> &Val) {
+ return Vertices.insert(Val);
+ }
+
+ std::pair<VertexIterator, bool>
+ insert(std::pair<VertexIdentifier, VertexAttribute> &&Val) {
+ return Vertices.insert(std::move(Val));
+ }
+
+ /// Inserts an edge into the graph with Identifier Val.first, and
+ /// Attribute Val.second. If the key is already in the map, it returns false
+ /// and doesn't update the value.
+ std::pair<EdgeIterator, bool>
+ insert(const std::pair<EdgeIdentifier, EdgeAttribute> &Val) {
+ const auto &p = Edges.insert(Val);
+ if (p.second) {
+ const auto &EI = Val.first;
+ Vertices.FindAndConstruct(EI.first);
+ Vertices.FindAndConstruct(EI.second);
+ InNeighbors[EI.second].insert(EI.first);
+ OutNeighbors[EI.first].insert(EI.second);
+ };
+
+ return p;
+ }
+
+ /// Inserts an edge into the graph with Identifier Val.first, and
+ /// Attribute Val.second. If the key is already in the map, it returns false
+ /// and doesn't update the value.
+ std::pair<EdgeIterator, bool>
+ insert(std::pair<EdgeIdentifier, EdgeAttribute> &&Val) {
+ auto EI = Val.first;
+ const auto &p = Edges.insert(std::move(Val));
+ if (p.second) {
+ Vertices.FindAndConstruct(EI.first);
+ Vertices.FindAndConstruct(EI.second);
+ InNeighbors[EI.second].insert(EI.first);
+ OutNeighbors[EI.first].insert(EI.second);
+ };
+
+ return p;
+ }
+};
+}
+}
+#endif
diff --git a/contrib/llvm/include/llvm/XRay/InstrumentationMap.h b/contrib/llvm/include/llvm/XRay/InstrumentationMap.h
new file mode 100644
index 0000000..0342da0
--- /dev/null
+++ b/contrib/llvm/include/llvm/XRay/InstrumentationMap.h
@@ -0,0 +1,131 @@
+//===- InstrumentationMap.h - XRay Instrumentation Map ----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Defines the interface for extracting the instrumentation map from an
+// XRay-instrumented binary.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_XRAY_INSTRUMENTATION_MAP_H
+#define LLVM_XRAY_INSTRUMENTATION_MAP_H
+
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/YAMLTraits.h"
+#include <cstdint>
+#include <unordered_map>
+#include <vector>
+
+namespace llvm {
+
+namespace xray {
+
+// Forward declare to make a friend.
+class InstrumentationMap;
+
+/// Loads the instrumentation map from |Filename|. This auto-deduces the type of
+/// the instrumentation map.
+Expected<InstrumentationMap> loadInstrumentationMap(StringRef Filename);
+
+/// Represents an XRay instrumentation sled entry from an object file.
+struct SledEntry {
+ /// Each entry here represents the kinds of supported instrumentation map
+ /// entries.
+ enum class FunctionKinds { ENTRY, EXIT, TAIL };
+
+ /// The address of the sled.
+ uint64_t Address;
+
+ /// The address of the function.
+ uint64_t Function;
+
+ /// The kind of sled.
+ FunctionKinds Kind;
+
+ /// Whether the sled was annotated to always be instrumented.
+ bool AlwaysInstrument;
+};
+
+struct YAMLXRaySledEntry {
+ int32_t FuncId;
+ yaml::Hex64 Address;
+ yaml::Hex64 Function;
+ SledEntry::FunctionKinds Kind;
+ bool AlwaysInstrument;
+ std::string FunctionName;
+};
+
+/// The InstrumentationMap represents the computed function id's and indicated
+/// function addresses from an object file (or a YAML file). This provides an
+/// interface to just the mapping between the function id, and the function
+/// address.
+///
+/// We also provide raw access to the actual instrumentation map entries we find
+/// associated with a particular object file.
+///
+class InstrumentationMap {
+public:
+ using FunctionAddressMap = std::unordered_map<int32_t, uint64_t>;
+ using FunctionAddressReverseMap = std::unordered_map<uint64_t, int32_t>;
+ using SledContainer = std::vector<SledEntry>;
+
+private:
+ SledContainer Sleds;
+ FunctionAddressMap FunctionAddresses;
+ FunctionAddressReverseMap FunctionIds;
+
+ friend Expected<InstrumentationMap> loadInstrumentationMap(StringRef);
+
+public:
+ /// Provides a raw accessor to the unordered map of function addresses.
+ const FunctionAddressMap &getFunctionAddresses() { return FunctionAddresses; }
+
+ /// Returns an XRay computed function id, provided a function address.
+ Optional<int32_t> getFunctionId(uint64_t Addr) const;
+
+ /// Returns the function address for a function id.
+ Optional<uint64_t> getFunctionAddr(int32_t FuncId) const;
+
+ /// Provide read-only access to the entries of the instrumentation map.
+ const SledContainer &sleds() const { return Sleds; };
+};
+
+} // end namespace xray
+
+namespace yaml {
+
+template <> struct ScalarEnumerationTraits<xray::SledEntry::FunctionKinds> {
+ static void enumeration(IO &IO, xray::SledEntry::FunctionKinds &Kind) {
+ IO.enumCase(Kind, "function-enter", xray::SledEntry::FunctionKinds::ENTRY);
+ IO.enumCase(Kind, "function-exit", xray::SledEntry::FunctionKinds::EXIT);
+ IO.enumCase(Kind, "tail-exit", xray::SledEntry::FunctionKinds::TAIL);
+ }
+};
+
+template <> struct MappingTraits<xray::YAMLXRaySledEntry> {
+ static void mapping(IO &IO, xray::YAMLXRaySledEntry &Entry) {
+ IO.mapRequired("id", Entry.FuncId);
+ IO.mapRequired("address", Entry.Address);
+ IO.mapRequired("function", Entry.Function);
+ IO.mapRequired("kind", Entry.Kind);
+ IO.mapRequired("always-instrument", Entry.AlwaysInstrument);
+ IO.mapOptional("function-name", Entry.FunctionName);
+ }
+
+ static constexpr bool flow = true;
+};
+
+} // end namespace yaml
+
+} // end namespace llvm
+
+LLVM_YAML_IS_SEQUENCE_VECTOR(xray::YAMLXRaySledEntry)
+
+#endif // LLVM_XRAY_INSTRUMENTATION_MAP_H
diff --git a/contrib/llvm/include/llvm/XRay/XRayRecord.h b/contrib/llvm/include/llvm/XRay/XRayRecord.h
index a968461..68c91a4 100644
--- a/contrib/llvm/include/llvm/XRay/XRayRecord.h
+++ b/contrib/llvm/include/llvm/XRay/XRayRecord.h
@@ -42,6 +42,11 @@ struct XRayFileHeader {
/// counter (TSC) values. Useful for estimating the amount of time that
/// elapsed between two TSCs on some platforms.
uint64_t CycleFrequency = 0;
+
+ // This is different depending on the type of xray record. The naive format
+ // stores a Wallclock timespec. FDR logging stores the size of a thread
+ // buffer.
+ char FreeFormData[16];
};
/// Determines the supported types of records that could be seen in XRay traces.
@@ -54,8 +59,8 @@ struct XRayRecord {
/// The type of record.
uint16_t RecordType;
- /// The CPU where the thread is running. We assume number of CPUs <= 256.
- uint8_t CPU;
+ /// The CPU where the thread is running. We assume number of CPUs <= 65536.
+ uint16_t CPU;
/// Identifies the type of record.
RecordTypes Type;
diff --git a/contrib/llvm/include/llvm/XRay/YAMLXRayRecord.h b/contrib/llvm/include/llvm/XRay/YAMLXRayRecord.h
index f5836b3..7e1a411 100644
--- a/contrib/llvm/include/llvm/XRay/YAMLXRayRecord.h
+++ b/contrib/llvm/include/llvm/XRay/YAMLXRayRecord.h
@@ -31,7 +31,7 @@ struct YAMLXRayFileHeader {
struct YAMLXRayRecord {
uint16_t RecordType;
- uint8_t CPU;
+ uint16_t CPU;
RecordTypes Type;
int32_t FuncId;
std::string Function;
diff --git a/contrib/llvm/include/llvm/module.modulemap b/contrib/llvm/include/llvm/module.modulemap
index 29e6d66..766198b 100644
--- a/contrib/llvm/include/llvm/module.modulemap
+++ b/contrib/llvm/include/llvm/module.modulemap
@@ -23,6 +23,7 @@ module LLVM_Backend {
exclude header "CodeGen/CommandFlags.h"
exclude header "CodeGen/LinkAllAsmWriterComponents.h"
exclude header "CodeGen/LinkAllCodegenComponents.h"
+ exclude header "CodeGen/GlobalISel/InstructionSelectorImpl.h"
// These are intended for (repeated) textual inclusion.
textual header "CodeGen/DIEValue.def"
@@ -38,6 +39,31 @@ module LLVM_Backend {
}
module LLVM_Bitcode { requires cplusplus umbrella "Bitcode" module * { export * } }
+
+module LLVM_BinaryFormat {
+ requires cplusplus
+ umbrella "BinaryFormat" module * { export * }
+ textual header "BinaryFormat/Dwarf.def"
+ textual header "BinaryFormat/MachO.def"
+ textual header "BinaryFormat/ELFRelocs/AArch64.def"
+ textual header "BinaryFormat/ELFRelocs/AMDGPU.def"
+ textual header "BinaryFormat/ELFRelocs/ARM.def"
+ textual header "BinaryFormat/ELFRelocs/AVR.def"
+ textual header "BinaryFormat/ELFRelocs/BPF.def"
+ textual header "BinaryFormat/ELFRelocs/Hexagon.def"
+ textual header "BinaryFormat/ELFRelocs/i386.def"
+ textual header "BinaryFormat/ELFRelocs/Lanai.def"
+ textual header "BinaryFormat/ELFRelocs/Mips.def"
+ textual header "BinaryFormat/ELFRelocs/PowerPC64.def"
+ textual header "BinaryFormat/ELFRelocs/PowerPC.def"
+ textual header "BinaryFormat/ELFRelocs/RISCV.def"
+ textual header "BinaryFormat/ELFRelocs/Sparc.def"
+ textual header "BinaryFormat/ELFRelocs/SystemZ.def"
+ textual header "BinaryFormat/ELFRelocs/x86_64.def"
+ textual header "BinaryFormat/ELFRelocs/WebAssembly.def"
+ textual header "BinaryFormat/WasmRelocs/WebAssembly.def"
+}
+
module LLVM_Config { requires cplusplus umbrella "Config" module * { export * } }
module LLVM_DebugInfo {
@@ -95,8 +121,8 @@ module LLVM_DebugInfo_CodeView {
module * { export * }
// These are intended for (repeated) textual inclusion.
- textual header "DebugInfo/CodeView/TypeRecords.def"
- textual header "DebugInfo/CodeView/CVSymbolTypes.def"
+ textual header "DebugInfo/CodeView/CodeViewTypes.def"
+ textual header "DebugInfo/CodeView/CodeViewSymbols.def"
}
module LLVM_ExecutionEngine {
@@ -148,6 +174,7 @@ module LLVM_intrinsic_gen {
module IR_Attributes { header "IR/Attributes.h" export * }
module IR_CallSite { header "IR/CallSite.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 IR_Module { header "IR/Module.h" export * }
module IR_ModuleSummaryIndex { header "IR/ModuleSummaryIndex.h" export * }
@@ -249,33 +276,13 @@ module LLVM_Utils {
umbrella "Support"
module * { export * }
- // Exclude this; it's only included on Solaris.
- exclude header "Support/Solaris.h"
-
- // Exclude this; it's fundamentally non-modular.
+ // Exclude these; they are fundamentally non-modular.
exclude header "Support/PluginLoader.h"
+ exclude header "Support/Solaris/sys/regset.h"
// These are intended for textual inclusion.
textual header "Support/ARMTargetParser.def"
textual header "Support/AArch64TargetParser.def"
- textual header "Support/Dwarf.def"
- textual header "Support/MachO.def"
- textual header "Support/ELFRelocs/AArch64.def"
- textual header "Support/ELFRelocs/AMDGPU.def"
- textual header "Support/ELFRelocs/ARM.def"
- textual header "Support/ELFRelocs/AVR.def"
- textual header "Support/ELFRelocs/BPF.def"
- textual header "Support/ELFRelocs/Hexagon.def"
- textual header "Support/ELFRelocs/i386.def"
- textual header "Support/ELFRelocs/Lanai.def"
- textual header "Support/ELFRelocs/Mips.def"
- textual header "Support/ELFRelocs/PowerPC64.def"
- textual header "Support/ELFRelocs/PowerPC.def"
- textual header "Support/ELFRelocs/RISCV.def"
- textual header "Support/ELFRelocs/Sparc.def"
- textual header "Support/ELFRelocs/SystemZ.def"
- textual header "Support/ELFRelocs/x86_64.def"
- textual header "Support/ELFRelocs/WebAssembly.def"
}
// This part of the module is usable from both C and C++ code.
@@ -283,12 +290,12 @@ module LLVM_Utils {
header "Support/ConvertUTF.h"
export *
}
-}
-module LLVM_CodeGen_MachineValueType {
- requires cplusplus
- header "CodeGen/MachineValueType.h"
- export *
+ module LLVM_CodeGen_MachineValueType {
+ requires cplusplus
+ header "CodeGen/MachineValueType.h"
+ export *
+ }
}
// This is used for a $src == $build compilation. Otherwise we use
OpenPOWER on IntegriCloud