aboutsummaryrefslogtreecommitdiff
path: root/contrib
diff options
context:
space:
mode:
Diffstat (limited to 'contrib')
-rw-r--r--contrib/compiler-rt/include/sanitizer/coverage_interface.h3
-rw-r--r--contrib/compiler-rt/lib/asan/asan_allocator.cc4
-rw-r--r--contrib/compiler-rt/lib/asan/asan_allocator.h2
-rw-r--r--contrib/compiler-rt/lib/asan/asan_flags.cc4
-rw-r--r--contrib/compiler-rt/lib/asan/asan_interceptors.cc17
-rw-r--r--contrib/compiler-rt/lib/dfsan/done_abilist.txt2
-rw-r--r--contrib/compiler-rt/lib/lsan/lsan_interceptors.cc24
-rw-r--r--contrib/compiler-rt/lib/msan/msan_allocator.cc96
-rw-r--r--contrib/compiler-rt/lib/msan/msan_allocator.h97
-rw-r--r--contrib/compiler-rt/lib/msan/msan_interceptors.cc38
-rw-r--r--contrib/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc42
-rw-r--r--contrib/compiler-rt/lib/sanitizer_common/sanitizer_coverage_interface.inc5
-rw-r--r--contrib/compiler-rt/lib/sanitizer_common/sanitizer_coverage_libcdep.cc47
-rw-r--r--contrib/compiler-rt/lib/sanitizer_common/sanitizer_coverage_libcdep_new.cc4
-rw-r--r--contrib/compiler-rt/lib/sanitizer_common/sanitizer_flags.inc3
-rw-r--r--contrib/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h14
-rw-r--r--contrib/compiler-rt/lib/sanitizer_common/symbolizer/scripts/global_symbols.txt1
-rw-r--r--contrib/compiler-rt/lib/ubsan/ubsan_type_hash_itanium.cc2
-rw-r--r--contrib/libc++/include/__bit_reference8
-rw-r--r--contrib/libc++/include/__config34
-rw-r--r--contrib/libc++/include/__hash_table10
-rw-r--r--contrib/libc++/include/__locale4
-rw-r--r--contrib/libc++/include/__mutex_base8
-rw-r--r--contrib/libc++/include/__split_buffer9
-rw-r--r--contrib/libc++/include/__std_stream8
-rw-r--r--contrib/libc++/include/__string8
-rw-r--r--contrib/libc++/include/__threading_support7
-rw-r--r--contrib/libc++/include/__tree8
-rw-r--r--contrib/libc++/include/__undef_macros (renamed from contrib/libc++/include/__undef_min_max)7
-rw-r--r--contrib/libc++/include/algorithm12
-rw-r--r--contrib/libc++/include/array2
-rw-r--r--contrib/libc++/include/bitset14
-rw-r--r--contrib/libc++/include/chrono8
-rw-r--r--contrib/libc++/include/deque14
-rw-r--r--contrib/libc++/include/experimental/algorithm9
-rw-r--r--contrib/libc++/include/experimental/dynarray5
-rw-r--r--contrib/libc++/include/experimental/functional9
-rw-r--r--contrib/libc++/include/experimental/memory_resource5
-rw-r--r--contrib/libc++/include/experimental/numeric6
-rw-r--r--contrib/libc++/include/experimental/optional28
-rw-r--r--contrib/libc++/include/experimental/string_view5
-rw-r--r--contrib/libc++/include/forward_list9
-rw-r--r--contrib/libc++/include/fstream8
-rw-r--r--contrib/libc++/include/istream8
-rw-r--r--contrib/libc++/include/limits25
-rw-r--r--contrib/libc++/include/list8
-rw-r--r--contrib/libc++/include/locale25
-rw-r--r--contrib/libc++/include/memory30
-rw-r--r--contrib/libc++/include/module.modulemap2
-rw-r--r--contrib/libc++/include/mutex8
-rw-r--r--contrib/libc++/include/numeric5
-rw-r--r--contrib/libc++/include/optional7
-rw-r--r--contrib/libc++/include/random226
-rw-r--r--contrib/libc++/include/ratio8
-rw-r--r--contrib/libc++/include/regex8
-rw-r--r--contrib/libc++/include/shared_mutex8
-rw-r--r--contrib/libc++/include/sstream8
-rw-r--r--contrib/libc++/include/stdexcept6
-rw-r--r--contrib/libc++/include/stdio.h3
-rw-r--r--contrib/libc++/include/streambuf5
-rw-r--r--contrib/libc++/include/string16
-rw-r--r--contrib/libc++/include/string_view11
-rw-r--r--contrib/libc++/include/thread5
-rw-r--r--contrib/libc++/include/tuple80
-rw-r--r--contrib/libc++/include/valarray8
-rw-r--r--contrib/libc++/include/vector8
-rw-r--r--contrib/libc++/include/wchar.h2
-rw-r--r--contrib/libc++/src/chrono.cpp2
-rw-r--r--contrib/libc++/src/condition_variable.cpp1
-rw-r--r--contrib/libc++/src/ios.cpp1
-rw-r--r--contrib/libc++/src/locale.cpp1
-rw-r--r--contrib/libc++/src/mutex.cpp1
-rw-r--r--contrib/libc++/src/new.cpp4
-rw-r--r--contrib/libc++/src/strstream.cpp1
-rw-r--r--contrib/libc++/src/system_error.cpp2
-rw-r--r--contrib/libc++/src/thread.cpp2
-rw-r--r--contrib/llvm/include/llvm/Analysis/TargetTransformInfo.h7
-rw-r--r--contrib/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h2
-rw-r--r--contrib/llvm/include/llvm/Analysis/ValueTracking.h2
-rw-r--r--contrib/llvm/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h2
-rw-r--r--contrib/llvm/include/llvm/CodeGen/ISDOpcodes.h12
-rw-r--r--contrib/llvm/include/llvm/CodeGen/MIRYamlMapping.h2
-rw-r--r--contrib/llvm/include/llvm/CodeGen/MachineBasicBlock.h3
-rw-r--r--contrib/llvm/include/llvm/CodeGen/MachineConstantPool.h17
-rw-r--r--contrib/llvm/include/llvm/CodeGen/MachineFunction.h116
-rw-r--r--contrib/llvm/include/llvm/CodeGen/MachineFunctionInitializer.h6
-rw-r--r--contrib/llvm/include/llvm/CodeGen/MachineInstr.h75
-rw-r--r--contrib/llvm/include/llvm/CodeGen/MachineInstrBundleIterator.h72
-rw-r--r--contrib/llvm/include/llvm/CodeGen/MachineLoopInfo.h24
-rw-r--r--contrib/llvm/include/llvm/CodeGen/MachineModuleInfo.h36
-rw-r--r--contrib/llvm/include/llvm/CodeGen/Passes.h4
-rw-r--r--contrib/llvm/include/llvm/CodeGen/TargetPassConfig.h6
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/CodeView.h14
-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)0
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolDeserializer.h13
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolRecord.h2
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolRecordMapping.h2
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolSerializer.h13
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolVisitorCallbackPipeline.h2
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h2
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/TypeDatabaseVisitor.h2
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/TypeDeserializer.h5
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/TypeDumpVisitor.h2
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/TypeRecord.h36
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/TypeRecordMapping.h2
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/TypeSerializer.h2
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/TypeTableBuilder.h2
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h2
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h6
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/DIContext.h11
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h3
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/Native/RawConstants.h1
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/Native/TpiHashing.h2
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/PDB/PDBContext.h3
-rw-r--r--contrib/llvm/include/llvm/IR/Attributes.h197
-rw-r--r--contrib/llvm/include/llvm/IR/Function.h47
-rw-r--r--contrib/llvm/include/llvm/IR/Instructions.h18
-rw-r--r--contrib/llvm/include/llvm/InitializePasses.h1
-rw-r--r--contrib/llvm/include/llvm/Object/WindowsResource.h64
-rw-r--r--contrib/llvm/include/llvm/ObjectYAML/CodeViewYAMLDebugSections.h91
-rw-r--r--contrib/llvm/include/llvm/ObjectYAML/CodeViewYAMLSymbols.h41
-rw-r--r--contrib/llvm/include/llvm/ObjectYAML/CodeViewYAMLTypes.h48
-rw-r--r--contrib/llvm/include/llvm/Passes/PassBuilder.h63
-rw-r--r--contrib/llvm/include/llvm/Support/ARMTargetParser.def4
-rw-r--r--contrib/llvm/include/llvm/Support/BinaryStreamReader.h8
-rw-r--r--contrib/llvm/include/llvm/Support/YAMLTraits.h38
-rw-r--r--contrib/llvm/include/llvm/TableGen/Record.h12
-rw-r--r--contrib/llvm/include/llvm/Target/TargetLowering.h12
-rw-r--r--contrib/llvm/include/llvm/Target/TargetMachine.h6
-rw-r--r--contrib/llvm/include/llvm/Transforms/IPO/ThinLTOBitcodeWriter.h41
-rw-r--r--contrib/llvm/include/llvm/Transforms/Scalar/GVN.h27
-rw-r--r--contrib/llvm/include/llvm/Transforms/Utils/CodeExtractor.h13
-rw-r--r--contrib/llvm/include/llvm/module.modulemap4
-rw-r--r--contrib/llvm/lib/Analysis/CFLGraph.h6
-rw-r--r--contrib/llvm/lib/Analysis/ConstantFolding.cpp2
-rw-r--r--contrib/llvm/lib/Analysis/EHPersonalities.cpp2
-rw-r--r--contrib/llvm/lib/Analysis/InstructionSimplify.cpp7
-rw-r--r--contrib/llvm/lib/Analysis/MemoryDependenceAnalysis.cpp1
-rw-r--r--contrib/llvm/lib/Analysis/ScalarEvolution.cpp4
-rw-r--r--contrib/llvm/lib/Analysis/TargetTransformInfo.cpp4
-rw-r--r--contrib/llvm/lib/Analysis/ValueTracking.cpp13
-rw-r--r--contrib/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp56
-rw-r--r--contrib/llvm/lib/CodeGen/AggressiveAntiDepBreaker.cpp2
-rw-r--r--contrib/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp20
-rw-r--r--contrib/llvm/lib/CodeGen/AsmPrinter/EHStreamer.cpp2
-rw-r--r--contrib/llvm/lib/CodeGen/CodeGen.cpp1
-rw-r--r--contrib/llvm/lib/CodeGen/CodeGenPrepare.cpp612
-rw-r--r--contrib/llvm/lib/CodeGen/CriticalAntiDepBreaker.cpp2
-rw-r--r--contrib/llvm/lib/CodeGen/GlobalISel/Localizer.cpp10
-rw-r--r--contrib/llvm/lib/CodeGen/ImplicitNullChecks.cpp16
-rw-r--r--contrib/llvm/lib/CodeGen/LiveRangeShrink.cpp231
-rw-r--r--contrib/llvm/lib/CodeGen/MIRParser/MIRParser.cpp2
-rw-r--r--contrib/llvm/lib/CodeGen/MIRPrinter.cpp2
-rw-r--r--contrib/llvm/lib/CodeGen/MachineBasicBlock.cpp7
-rw-r--r--contrib/llvm/lib/CodeGen/MachineInstr.cpp86
-rw-r--r--contrib/llvm/lib/CodeGen/MachineModuleInfo.cpp65
-rw-r--r--contrib/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp132
-rw-r--r--contrib/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp70
-rw-r--r--contrib/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h1
-rw-r--r--contrib/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp278
-rw-r--r--contrib/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp1
-rw-r--r--contrib/llvm/lib/CodeGen/TargetLoweringBase.cpp8
-rw-r--r--contrib/llvm/lib/CodeGen/TargetPassConfig.cpp17
-rw-r--r--contrib/llvm/lib/DebugInfo/CodeView/CVSymbolVisitor.cpp2
-rw-r--r--contrib/llvm/lib/DebugInfo/CodeView/CVTypeVisitor.cpp4
-rw-r--r--contrib/llvm/lib/DebugInfo/CodeView/EnumTables.cpp4
-rw-r--r--contrib/llvm/lib/DebugInfo/CodeView/SymbolDumper.cpp2
-rw-r--r--contrib/llvm/lib/DebugInfo/CodeView/TypeDumpVisitor.cpp4
-rw-r--r--contrib/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp8
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/Native/InfoStream.cpp1
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/PDBContext.cpp3
-rw-r--r--contrib/llvm/lib/IR/Attributes.cpp45
-rw-r--r--contrib/llvm/lib/IR/Function.cpp64
-rw-r--r--contrib/llvm/lib/IR/Instructions.cpp32
-rw-r--r--contrib/llvm/lib/LTO/LTOBackend.cpp15
-rw-r--r--contrib/llvm/lib/MC/MCCodeView.cpp2
-rw-r--r--contrib/llvm/lib/Object/MachOObjectFile.cpp2
-rw-r--r--contrib/llvm/lib/Object/WindowsResource.cpp156
-rw-r--r--contrib/llvm/lib/ObjectYAML/CodeViewYAMLDebugSections.cpp127
-rw-r--r--contrib/llvm/lib/ObjectYAML/CodeViewYAMLSymbols.cpp496
-rw-r--r--contrib/llvm/lib/ObjectYAML/CodeViewYAMLTypes.cpp712
-rw-r--r--contrib/llvm/lib/Passes/PassBuilder.cpp141
-rw-r--r--contrib/llvm/lib/Support/BinaryStreamReader.cpp20
-rw-r--r--contrib/llvm/lib/Support/Unix/Path.inc5
-rw-r--r--contrib/llvm/lib/TableGen/Record.cpp19
-rw-r--r--contrib/llvm/lib/TableGen/TGParser.cpp8
-rw-r--r--contrib/llvm/lib/TableGen/TGParser.h2
-rw-r--r--contrib/llvm/lib/Target/AArch64/AArch64.td2
-rw-r--r--contrib/llvm/lib/Target/AArch64/AArch64SchedM1.td340
-rw-r--r--contrib/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp6
-rw-r--r--contrib/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp55
-rw-r--r--contrib/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp10
-rw-r--r--contrib/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.h5
-rw-r--r--contrib/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp324
-rw-r--r--contrib/llvm/lib/Target/AMDGPU/DSInstructions.td6
-rw-r--r--contrib/llvm/lib/Target/AMDGPU/InstPrinter/AMDGPUInstPrinter.cpp106
-rw-r--r--contrib/llvm/lib/Target/AMDGPU/InstPrinter/AMDGPUInstPrinter.h2
-rw-r--r--contrib/llvm/lib/Target/AMDGPU/SIDefines.h40
-rw-r--r--contrib/llvm/lib/Target/AMDGPU/SIInsertWaitcnts.cpp26
-rw-r--r--contrib/llvm/lib/Target/AMDGPU/SIInstrInfo.td13
-rw-r--r--contrib/llvm/lib/Target/AMDGPU/SIRegisterInfo.h6
-rw-r--r--contrib/llvm/lib/Target/AMDGPU/Utils/AMDGPUAsmUtils.cpp13
-rw-r--r--contrib/llvm/lib/Target/AMDGPU/Utils/AMDGPUAsmUtils.h6
-rw-r--r--contrib/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp132
-rw-r--r--contrib/llvm/lib/Target/ARM/ARMFrameLowering.cpp5
-rw-r--r--contrib/llvm/lib/Target/ARM/ARMInstrThumb.td3
-rw-r--r--contrib/llvm/lib/Target/ARM/ARMInstrThumb2.td3
-rw-r--r--contrib/llvm/lib/Target/ARM/ARMTargetMachine.cpp4
-rw-r--r--contrib/llvm/lib/Target/ARM/ARMTargetMachine.h4
-rw-r--r--contrib/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp9
-rw-r--r--contrib/llvm/lib/Target/ARM/Thumb1FrameLowering.cpp9
-rw-r--r--contrib/llvm/lib/Target/AVR/AVRISelLowering.cpp4
-rw-r--r--contrib/llvm/lib/Target/AVR/AVRInstrInfo.td2
-rw-r--r--contrib/llvm/lib/Target/AVR/AVRTargetMachine.cpp4
-rw-r--r--contrib/llvm/lib/Target/AVR/AVRTargetMachine.h4
-rw-r--r--contrib/llvm/lib/Target/BPF/BPFTargetMachine.cpp4
-rw-r--r--contrib/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp189
-rw-r--r--contrib/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp6
-rw-r--r--contrib/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp170
-rw-r--r--contrib/llvm/lib/Target/Hexagon/HexagonInstrInfo.h5
-rw-r--r--contrib/llvm/lib/Target/Hexagon/HexagonLoopIdiomRecognition.cpp8
-rw-r--r--contrib/llvm/lib/Target/Hexagon/HexagonPatterns.td59
-rw-r--r--contrib/llvm/lib/Target/Hexagon/HexagonTargetMachine.cpp4
-rw-r--r--contrib/llvm/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp49
-rw-r--r--contrib/llvm/lib/Target/Lanai/LanaiTargetMachine.cpp4
-rw-r--r--contrib/llvm/lib/Target/Lanai/LanaiTargetMachine.h4
-rw-r--r--contrib/llvm/lib/Target/MSP430/MSP430TargetMachine.cpp4
-rw-r--r--contrib/llvm/lib/Target/Mips/Mips16FrameLowering.cpp24
-rw-r--r--contrib/llvm/lib/Target/Mips/MipsTargetMachine.cpp4
-rw-r--r--contrib/llvm/lib/Target/Mips/MipsTargetMachine.h4
-rw-r--r--contrib/llvm/lib/Target/NVPTX/NVPTXTargetMachine.cpp4
-rw-r--r--contrib/llvm/lib/Target/NVPTX/NVPTXTargetMachine.h3
-rw-r--r--contrib/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp298
-rw-r--r--contrib/llvm/lib/Target/PowerPC/PPCISelLowering.cpp110
-rw-r--r--contrib/llvm/lib/Target/PowerPC/PPCISelLowering.h8
-rw-r--r--contrib/llvm/lib/Target/PowerPC/PPCInstr64Bit.td12
-rw-r--r--contrib/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp4
-rw-r--r--contrib/llvm/lib/Target/PowerPC/PPCInstrInfo.h1
-rw-r--r--contrib/llvm/lib/Target/PowerPC/PPCInstrInfo.td5
-rw-r--r--contrib/llvm/lib/Target/PowerPC/PPCInstrVSX.td4
-rw-r--r--contrib/llvm/lib/Target/PowerPC/PPCTargetMachine.cpp4
-rw-r--r--contrib/llvm/lib/Target/PowerPC/PPCTargetMachine.h4
-rw-r--r--contrib/llvm/lib/Target/PowerPC/PPCTargetTransformInfo.cpp20
-rw-r--r--contrib/llvm/lib/Target/PowerPC/PPCTargetTransformInfo.h1
-rw-r--r--contrib/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp2
-rw-r--r--contrib/llvm/lib/Target/Sparc/SparcTargetMachine.cpp4
-rw-r--r--contrib/llvm/lib/Target/Sparc/SparcTargetMachine.h4
-rw-r--r--contrib/llvm/lib/Target/SystemZ/SystemZTargetMachine.cpp4
-rw-r--r--contrib/llvm/lib/Target/SystemZ/SystemZTargetMachine.h2
-rw-r--r--contrib/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp4
-rw-r--r--contrib/llvm/lib/Target/X86/InstPrinter/X86InstComments.cpp4
-rw-r--r--contrib/llvm/lib/Target/X86/X86FloatingPoint.cpp34
-rw-r--r--contrib/llvm/lib/Target/X86/X86FrameLowering.cpp9
-rw-r--r--contrib/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp2
-rw-r--r--contrib/llvm/lib/Target/X86/X86ISelLowering.cpp266
-rw-r--r--contrib/llvm/lib/Target/X86/X86ISelLowering.h2
-rw-r--r--contrib/llvm/lib/Target/X86/X86InstrInfo.cpp1
-rw-r--r--contrib/llvm/lib/Target/X86/X86TargetMachine.cpp5
-rw-r--r--contrib/llvm/lib/Target/X86/X86TargetMachine.h4
-rw-r--r--contrib/llvm/lib/Target/XCore/XCoreTargetMachine.cpp4
-rw-r--r--contrib/llvm/lib/Transforms/Coroutines/CoroCleanup.cpp4
-rw-r--r--contrib/llvm/lib/Transforms/Coroutines/CoroEarly.cpp4
-rw-r--r--contrib/llvm/lib/Transforms/Coroutines/CoroElide.cpp4
-rw-r--r--contrib/llvm/lib/Transforms/Coroutines/CoroSplit.cpp4
-rw-r--r--contrib/llvm/lib/Transforms/IPO/PartialInlining.cpp23
-rw-r--r--contrib/llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp20
-rw-r--r--contrib/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp10
-rw-r--r--contrib/llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp64
-rw-r--r--contrib/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp140
-rw-r--r--contrib/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp9
-rw-r--r--contrib/llvm/lib/Transforms/Scalar/GVN.cpp164
-rw-r--r--contrib/llvm/lib/Transforms/Scalar/LowerExpectIntrinsic.cpp16
-rw-r--r--contrib/llvm/lib/Transforms/Scalar/NewGVN.cpp38
-rw-r--r--contrib/llvm/lib/Transforms/Utils/CodeExtractor.cpp83
-rw-r--r--contrib/llvm/lib/Transforms/Utils/PredicateInfo.cpp35
-rw-r--r--contrib/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp14
-rw-r--r--contrib/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp29
-rw-r--r--contrib/llvm/tools/bugpoint/OptimizerDriver.cpp11
-rw-r--r--contrib/llvm/tools/clang/include/clang/AST/VTableBuilder.h22
-rw-r--r--contrib/llvm/tools/clang/include/clang/Basic/DiagnosticGroups.td1
-rw-r--r--contrib/llvm/tools/clang/include/clang/Basic/DiagnosticIDs.h2
-rw-r--r--contrib/llvm/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td4
-rw-r--r--contrib/llvm/tools/clang/include/clang/Basic/Module.h4
-rw-r--r--contrib/llvm/tools/clang/include/clang/Basic/Sanitizers.def7
-rw-r--r--contrib/llvm/tools/clang/include/clang/Basic/TokenKinds.def2
-rw-r--r--contrib/llvm/tools/clang/include/clang/Basic/TypeTraits.h1
-rw-r--r--contrib/llvm/tools/clang/include/clang/Driver/CLCompatOptions.td7
-rw-r--r--contrib/llvm/tools/clang/include/clang/Driver/Options.td4
-rw-r--r--contrib/llvm/tools/clang/include/clang/Lex/HeaderSearch.h7
-rw-r--r--contrib/llvm/tools/clang/lib/AST/ODRHash.cpp28
-rw-r--r--contrib/llvm/tools/clang/lib/Basic/Targets.cpp16
-rw-r--r--contrib/llvm/tools/clang/lib/CodeGen/ABIInfo.h1
-rw-r--r--contrib/llvm/tools/clang/lib/CodeGen/CGCall.cpp18
-rw-r--r--contrib/llvm/tools/clang/lib/CodeGen/CGCleanup.cpp7
-rw-r--r--contrib/llvm/tools/clang/lib/CodeGen/CGExpr.cpp60
-rw-r--r--contrib/llvm/tools/clang/lib/CodeGen/CGExprScalar.cpp210
-rw-r--r--contrib/llvm/tools/clang/lib/CodeGen/CGObjCRuntime.cpp6
-rw-r--r--contrib/llvm/tools/clang/lib/CodeGen/CGVTables.cpp2
-rw-r--r--contrib/llvm/tools/clang/lib/CodeGen/CodeGenFunction.h8
-rw-r--r--contrib/llvm/tools/clang/lib/CodeGen/CodeGenModule.cpp31
-rw-r--r--contrib/llvm/tools/clang/lib/CodeGen/CodeGenModule.h11
-rw-r--r--contrib/llvm/tools/clang/lib/CodeGen/ItaniumCXXABI.cpp47
-rw-r--r--contrib/llvm/tools/clang/lib/CodeGen/MicrosoftCXXABI.cpp3
-rw-r--r--contrib/llvm/tools/clang/lib/CodeGen/TargetInfo.cpp22
-rw-r--r--contrib/llvm/tools/clang/lib/Driver/ToolChains/Clang.cpp63
-rw-r--r--contrib/llvm/tools/clang/lib/Driver/ToolChains/Gnu.cpp12
-rw-r--r--contrib/llvm/tools/clang/lib/Format/UnwrappedLineParser.cpp25
-rw-r--r--contrib/llvm/tools/clang/lib/Frontend/CompilerInvocation.cpp4
-rw-r--r--contrib/llvm/tools/clang/lib/Frontend/FrontendAction.cpp20
-rw-r--r--contrib/llvm/tools/clang/lib/Lex/HeaderSearch.cpp17
-rw-r--r--contrib/llvm/tools/clang/lib/Sema/SemaCoroutine.cpp8
-rw-r--r--contrib/llvm/tools/clang/lib/Sema/SemaDecl.cpp11
-rw-r--r--contrib/llvm/tools/clang/lib/Sema/SemaDeclObjC.cpp4
-rw-r--r--contrib/llvm/tools/clang/lib/Sema/SemaExprCXX.cpp33
-rw-r--r--contrib/llvm/tools/clang/lib/Sema/SemaOverload.cpp298
-rw-r--r--contrib/llvm/tools/clang/lib/Sema/SemaType.cpp6
-rw-r--r--contrib/llvm/tools/clang/lib/Serialization/ASTWriter.cpp9
-rw-r--r--contrib/llvm/tools/clang/utils/TableGen/ClangAttrEmitter.cpp50
-rw-r--r--contrib/llvm/tools/clang/utils/TableGen/ClangDiagnosticsEmitter.cpp4
-rw-r--r--contrib/llvm/tools/clang/utils/TableGen/ClangOptionDocEmitter.cpp13
-rw-r--r--contrib/llvm/tools/clang/utils/TableGen/ClangSACheckersEmitter.cpp3
-rw-r--r--contrib/llvm/tools/lld/ELF/InputSection.cpp50
-rw-r--r--contrib/llvm/tools/lld/ELF/InputSection.h19
-rw-r--r--contrib/llvm/tools/lld/ELF/LinkerScript.cpp127
-rw-r--r--contrib/llvm/tools/lld/ELF/LinkerScript.h14
-rw-r--r--contrib/llvm/tools/lld/ELF/MarkLive.cpp3
-rw-r--r--contrib/llvm/tools/lld/ELF/OutputSections.cpp53
-rw-r--r--contrib/llvm/tools/lld/ELF/OutputSections.h2
-rw-r--r--contrib/llvm/tools/lld/ELF/Relocations.cpp8
-rw-r--r--contrib/llvm/tools/lld/ELF/ScriptParser.cpp32
-rw-r--r--contrib/llvm/tools/lld/ELF/Symbols.cpp8
-rw-r--r--contrib/llvm/tools/lld/ELF/SyntheticSections.cpp97
-rw-r--r--contrib/llvm/tools/lld/ELF/SyntheticSections.h2
-rw-r--r--contrib/llvm/tools/lld/ELF/Target.cpp4
-rw-r--r--contrib/llvm/tools/lld/ELF/Writer.cpp82
-rw-r--r--contrib/llvm/tools/lldb/tools/lldb-mi/MICmdCmdVar.cpp28
-rw-r--r--contrib/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp6
-rw-r--r--contrib/llvm/tools/llvm-objdump/MachODump.cpp5
-rw-r--r--contrib/llvm/tools/llvm-objdump/llvm-objdump.cpp5
-rw-r--r--contrib/llvm/tools/llvm-pdbdump/Analyze.cpp2
-rw-r--r--contrib/llvm/tools/llvm-pdbdump/CompactTypeDumpVisitor.cpp2
-rw-r--r--contrib/llvm/tools/llvm-pdbdump/PdbYaml.cpp200
-rw-r--r--contrib/llvm/tools/llvm-pdbdump/PdbYaml.h207
-rw-r--r--contrib/llvm/tools/llvm-pdbdump/YAMLOutputStyle.cpp43
-rw-r--r--contrib/llvm/tools/llvm-pdbdump/YAMLOutputStyle.h2
-rw-r--r--contrib/llvm/tools/llvm-pdbdump/YamlSerializationContext.h39
-rw-r--r--contrib/llvm/tools/llvm-pdbdump/YamlSymbolDumper.cpp413
-rw-r--r--contrib/llvm/tools/llvm-pdbdump/YamlSymbolDumper.h66
-rw-r--r--contrib/llvm/tools/llvm-pdbdump/YamlTypeDumper.cpp589
-rw-r--r--contrib/llvm/tools/llvm-pdbdump/YamlTypeDumper.h116
-rw-r--r--contrib/llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp17
-rw-r--r--contrib/llvm/tools/llvm-readobj/ELFDumper.cpp1
-rw-r--r--contrib/llvm/tools/opt/NewPMDriver.cpp15
-rw-r--r--contrib/llvm/tools/opt/NewPMDriver.h10
-rw-r--r--contrib/llvm/tools/opt/opt.cpp6
-rw-r--r--contrib/llvm/utils/TableGen/AsmMatcherEmitter.cpp45
-rw-r--r--contrib/llvm/utils/TableGen/AsmWriterEmitter.cpp46
-rw-r--r--contrib/llvm/utils/TableGen/Attributes.cpp4
-rw-r--r--contrib/llvm/utils/TableGen/CodeEmitterGen.cpp14
-rw-r--r--contrib/llvm/utils/TableGen/CodeGenDAGPatterns.cpp6
-rw-r--r--contrib/llvm/utils/TableGen/CodeGenDAGPatterns.h8
-rw-r--r--contrib/llvm/utils/TableGen/CodeGenRegisters.cpp7
-rw-r--r--contrib/llvm/utils/TableGen/CodeGenRegisters.h4
-rw-r--r--contrib/llvm/utils/TableGen/CodeGenSchedule.cpp2
-rw-r--r--contrib/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp15
-rw-r--r--contrib/llvm/utils/TableGen/GlobalISelEmitter.cpp2
-rw-r--r--contrib/llvm/utils/TableGen/OptParserEmitter.cpp34
-rw-r--r--contrib/llvm/utils/TableGen/RegisterBankEmitter.cpp2
-rw-r--r--contrib/llvm/utils/TableGen/RegisterInfoEmitter.cpp7
-rw-r--r--contrib/llvm/utils/TableGen/SearchableTableEmitter.cpp4
-rw-r--r--contrib/llvm/utils/TableGen/SubtargetEmitter.cpp16
-rw-r--r--contrib/llvm/utils/TableGen/X86FoldTablesEmitter.cpp4
373 files changed, 8221 insertions, 4532 deletions
diff --git a/contrib/compiler-rt/include/sanitizer/coverage_interface.h b/contrib/compiler-rt/include/sanitizer/coverage_interface.h
index 911a3e854b77..bdb113728b95 100644
--- a/contrib/compiler-rt/include/sanitizer/coverage_interface.h
+++ b/contrib/compiler-rt/include/sanitizer/coverage_interface.h
@@ -32,9 +32,6 @@ extern "C" {
// descriptor. Returns -1 on failure, or if coverage dumping is disabled.
// This is intended for use by sandboxing code.
intptr_t __sanitizer_maybe_open_cov_file(const char *name);
- // Get the number of unique covered blocks (or edges).
- // This can be useful for coverage-directed in-process fuzzers.
- uintptr_t __sanitizer_get_total_unique_coverage();
#ifdef __cplusplus
} // extern "C"
#endif
diff --git a/contrib/compiler-rt/lib/asan/asan_allocator.cc b/contrib/compiler-rt/lib/asan/asan_allocator.cc
index 7010b6023614..db5a683e283d 100644
--- a/contrib/compiler-rt/lib/asan/asan_allocator.cc
+++ b/contrib/compiler-rt/lib/asan/asan_allocator.cc
@@ -47,8 +47,6 @@ static u32 RZSize2Log(u32 rz_size) {
return res;
}
-static AsanAllocator &get_allocator();
-
// The memory chunk allocated from the underlying allocator looks like this:
// L L L L L L H H U U U U U U R R
// L -- left redzone words (0 or more bytes)
@@ -719,7 +717,7 @@ struct Allocator {
static Allocator instance(LINKER_INITIALIZED);
-static AsanAllocator &get_allocator() {
+AsanAllocator &get_allocator() {
return instance.allocator;
}
diff --git a/contrib/compiler-rt/lib/asan/asan_allocator.h b/contrib/compiler-rt/lib/asan/asan_allocator.h
index ad1aeb58a86b..ce3e25dc5094 100644
--- a/contrib/compiler-rt/lib/asan/asan_allocator.h
+++ b/contrib/compiler-rt/lib/asan/asan_allocator.h
@@ -213,5 +213,7 @@ void asan_mz_force_unlock();
void PrintInternalAllocatorStats();
void AsanSoftRssLimitExceededCallback(bool exceeded);
+AsanAllocator &get_allocator();
+
} // namespace __asan
#endif // ASAN_ALLOCATOR_H
diff --git a/contrib/compiler-rt/lib/asan/asan_flags.cc b/contrib/compiler-rt/lib/asan/asan_flags.cc
index c8ae3faed7c2..6be0d6e94b9a 100644
--- a/contrib/compiler-rt/lib/asan/asan_flags.cc
+++ b/contrib/compiler-rt/lib/asan/asan_flags.cc
@@ -194,6 +194,10 @@ void InitializeFlags() {
Report("WARNING: strchr* interceptors are enabled even though "
"replace_str=0. Use intercept_strchr=0 to disable them.");
}
+ if (!f->replace_str && common_flags()->intercept_strndup) {
+ Report("WARNING: strndup* interceptors are enabled even though "
+ "replace_str=0. Use intercept_strndup=0 to disable them.");
+ }
}
} // namespace __asan
diff --git a/contrib/compiler-rt/lib/asan/asan_interceptors.cc b/contrib/compiler-rt/lib/asan/asan_interceptors.cc
index cb2214f966ea..e82a5a4a7e96 100644
--- a/contrib/compiler-rt/lib/asan/asan_interceptors.cc
+++ b/contrib/compiler-rt/lib/asan/asan_interceptors.cc
@@ -22,6 +22,7 @@
#include "asan_stats.h"
#include "asan_suppressions.h"
#include "lsan/lsan_common.h"
+#include "sanitizer_common/sanitizer_stackdepot.h"
#include "sanitizer_common/sanitizer_libc.h"
#if SANITIZER_POSIX
@@ -705,11 +706,27 @@ INTERCEPTOR(int, __cxa_atexit, void (*func)(void *), void *arg,
#endif // ASAN_INTERCEPT___CXA_ATEXIT
#if ASAN_INTERCEPT_FORK
+static void BeforeFork() {
+ if (SANITIZER_LINUX) {
+ get_allocator().ForceLock();
+ StackDepotLockAll();
+ }
+}
+
+static void AfterFork() {
+ if (SANITIZER_LINUX) {
+ StackDepotUnlockAll();
+ get_allocator().ForceUnlock();
+ }
+}
+
INTERCEPTOR(int, fork, void) {
ENSURE_ASAN_INITED();
+ BeforeFork();
if (common_flags()->coverage) CovBeforeFork();
int pid = REAL(fork)();
if (common_flags()->coverage) CovAfterFork(pid);
+ AfterFork();
return pid;
}
#endif // ASAN_INTERCEPT_FORK
diff --git a/contrib/compiler-rt/lib/dfsan/done_abilist.txt b/contrib/compiler-rt/lib/dfsan/done_abilist.txt
index cbbedbc33601..a560cd7b477c 100644
--- a/contrib/compiler-rt/lib/dfsan/done_abilist.txt
+++ b/contrib/compiler-rt/lib/dfsan/done_abilist.txt
@@ -287,8 +287,6 @@ fun:__sanitizer_cov_with_check=uninstrumented
fun:__sanitizer_cov_with_check=discard
fun:__sanitizer_set_death_callback=uninstrumented
fun:__sanitizer_set_death_callback=discard
-fun:__sanitizer_get_total_unique_coverage=uninstrumented
-fun:__sanitizer_get_total_unique_coverage=discard
fun:__sanitizer_update_counter_bitset_and_clear_counters=uninstrumented
fun:__sanitizer_update_counter_bitset_and_clear_counters=discard
diff --git a/contrib/compiler-rt/lib/lsan/lsan_interceptors.cc b/contrib/compiler-rt/lib/lsan/lsan_interceptors.cc
index 9e39a7d1944d..a0a59daa07ae 100644
--- a/contrib/compiler-rt/lib/lsan/lsan_interceptors.cc
+++ b/contrib/compiler-rt/lib/lsan/lsan_interceptors.cc
@@ -22,6 +22,7 @@
#include "sanitizer_common/sanitizer_platform_interceptors.h"
#include "sanitizer_common/sanitizer_platform_limits_posix.h"
#include "sanitizer_common/sanitizer_posix.h"
+#include "sanitizer_common/sanitizer_stackdepot.h"
#include "sanitizer_common/sanitizer_tls_get_addr.h"
#include "lsan.h"
#include "lsan_allocator.h"
@@ -97,6 +98,28 @@ INTERCEPTOR(void*, valloc, uptr size) {
}
#endif
+static void BeforeFork() {
+ if (SANITIZER_LINUX) {
+ LockAllocator();
+ StackDepotLockAll();
+ }
+}
+
+static void AfterFork() {
+ if (SANITIZER_LINUX) {
+ StackDepotUnlockAll();
+ UnlockAllocator();
+ }
+}
+
+INTERCEPTOR(int, fork, void) {
+ ENSURE_LSAN_INITED;
+ BeforeFork();
+ int pid = REAL(fork)();
+ AfterFork();
+ return pid;
+}
+
#if SANITIZER_INTERCEPT_MEMALIGN
INTERCEPTOR(void*, memalign, uptr alignment, uptr size) {
ENSURE_LSAN_INITED;
@@ -336,6 +359,7 @@ void InitializeInterceptors() {
LSAN_MAYBE_INTERCEPT_MALLOPT;
INTERCEPT_FUNCTION(pthread_create);
INTERCEPT_FUNCTION(pthread_join);
+ INTERCEPT_FUNCTION(fork);
if (pthread_key_create(&g_thread_finalize_key, &thread_finalize)) {
Report("LeakSanitizer: failed to create thread key.\n");
diff --git a/contrib/compiler-rt/lib/msan/msan_allocator.cc b/contrib/compiler-rt/lib/msan/msan_allocator.cc
index 1be573faa412..f76b01de0924 100644
--- a/contrib/compiler-rt/lib/msan/msan_allocator.cc
+++ b/contrib/compiler-rt/lib/msan/msan_allocator.cc
@@ -12,8 +12,6 @@
// MemorySanitizer allocator.
//===----------------------------------------------------------------------===//
-#include "sanitizer_common/sanitizer_allocator.h"
-#include "sanitizer_common/sanitizer_allocator_interface.h"
#include "msan.h"
#include "msan_allocator.h"
#include "msan_origin.h"
@@ -22,102 +20,12 @@
namespace __msan {
-struct Metadata {
- uptr requested_size;
-};
-
-struct MsanMapUnmapCallback {
- void OnMap(uptr p, uptr size) const {}
- void OnUnmap(uptr p, uptr size) const {
- __msan_unpoison((void *)p, size);
-
- // We are about to unmap a chunk of user memory.
- // Mark the corresponding shadow memory as not needed.
- uptr shadow_p = MEM_TO_SHADOW(p);
- ReleaseMemoryPagesToOS(shadow_p, shadow_p + size);
- if (__msan_get_track_origins()) {
- uptr origin_p = MEM_TO_ORIGIN(p);
- ReleaseMemoryPagesToOS(origin_p, origin_p + size);
- }
- }
-};
-
-#if defined(__mips64)
- static const uptr kMaxAllowedMallocSize = 2UL << 30;
- static const uptr kRegionSizeLog = 20;
- static const uptr kNumRegions = SANITIZER_MMAP_RANGE_SIZE >> kRegionSizeLog;
- typedef TwoLevelByteMap<(kNumRegions >> 12), 1 << 12> ByteMap;
-
- struct AP32 {
- static const uptr kSpaceBeg = 0;
- static const u64 kSpaceSize = SANITIZER_MMAP_RANGE_SIZE;
- static const uptr kMetadataSize = sizeof(Metadata);
- typedef __sanitizer::CompactSizeClassMap SizeClassMap;
- static const uptr kRegionSizeLog = __msan::kRegionSizeLog;
- typedef __msan::ByteMap ByteMap;
- typedef MsanMapUnmapCallback MapUnmapCallback;
- static const uptr kFlags = 0;
- };
- typedef SizeClassAllocator32<AP32> PrimaryAllocator;
-#elif defined(__x86_64__)
-#if SANITIZER_LINUX && !defined(MSAN_LINUX_X86_64_OLD_MAPPING)
- static const uptr kAllocatorSpace = 0x700000000000ULL;
-#else
- static const uptr kAllocatorSpace = 0x600000000000ULL;
-#endif
- static const uptr kMaxAllowedMallocSize = 8UL << 30;
-
- struct AP64 { // Allocator64 parameters. Deliberately using a short name.
- static const uptr kSpaceBeg = kAllocatorSpace;
- static const uptr kSpaceSize = 0x40000000000; // 4T.
- static const uptr kMetadataSize = sizeof(Metadata);
- typedef DefaultSizeClassMap SizeClassMap;
- typedef MsanMapUnmapCallback MapUnmapCallback;
- static const uptr kFlags = 0;
- };
-
- typedef SizeClassAllocator64<AP64> PrimaryAllocator;
-
-#elif defined(__powerpc64__)
- static const uptr kMaxAllowedMallocSize = 2UL << 30; // 2G
-
- struct AP64 { // Allocator64 parameters. Deliberately using a short name.
- static const uptr kSpaceBeg = 0x300000000000;
- static const uptr kSpaceSize = 0x020000000000; // 2T.
- static const uptr kMetadataSize = sizeof(Metadata);
- typedef DefaultSizeClassMap SizeClassMap;
- typedef MsanMapUnmapCallback MapUnmapCallback;
- static const uptr kFlags = 0;
- };
-
- typedef SizeClassAllocator64<AP64> PrimaryAllocator;
-#elif defined(__aarch64__)
- static const uptr kMaxAllowedMallocSize = 2UL << 30; // 2G
- static const uptr kRegionSizeLog = 20;
- static const uptr kNumRegions = SANITIZER_MMAP_RANGE_SIZE >> kRegionSizeLog;
- typedef TwoLevelByteMap<(kNumRegions >> 12), 1 << 12> ByteMap;
-
- struct AP32 {
- static const uptr kSpaceBeg = 0;
- static const u64 kSpaceSize = SANITIZER_MMAP_RANGE_SIZE;
- static const uptr kMetadataSize = sizeof(Metadata);
- typedef __sanitizer::CompactSizeClassMap SizeClassMap;
- static const uptr kRegionSizeLog = __msan::kRegionSizeLog;
- typedef __msan::ByteMap ByteMap;
- typedef MsanMapUnmapCallback MapUnmapCallback;
- static const uptr kFlags = 0;
- };
- typedef SizeClassAllocator32<AP32> PrimaryAllocator;
-#endif
-typedef SizeClassAllocatorLocalCache<PrimaryAllocator> AllocatorCache;
-typedef LargeMmapAllocator<MsanMapUnmapCallback> SecondaryAllocator;
-typedef CombinedAllocator<PrimaryAllocator, AllocatorCache,
- SecondaryAllocator> Allocator;
-
static Allocator allocator;
static AllocatorCache fallback_allocator_cache;
static SpinMutex fallback_mutex;
+Allocator &get_allocator() { return allocator; }
+
void MsanAllocatorInit() {
allocator.Init(
common_flags()->allocator_may_return_null,
diff --git a/contrib/compiler-rt/lib/msan/msan_allocator.h b/contrib/compiler-rt/lib/msan/msan_allocator.h
index 407942e54c1a..abd4ea678523 100644
--- a/contrib/compiler-rt/lib/msan/msan_allocator.h
+++ b/contrib/compiler-rt/lib/msan/msan_allocator.h
@@ -15,9 +15,106 @@
#define MSAN_ALLOCATOR_H
#include "sanitizer_common/sanitizer_common.h"
+#include "sanitizer_common/sanitizer_allocator.h"
+#include "sanitizer_common/sanitizer_allocator_interface.h"
namespace __msan {
+struct Metadata {
+ uptr requested_size;
+};
+
+struct MsanMapUnmapCallback {
+ void OnMap(uptr p, uptr size) const {}
+ void OnUnmap(uptr p, uptr size) const {
+ __msan_unpoison((void *)p, size);
+
+ // We are about to unmap a chunk of user memory.
+ // Mark the corresponding shadow memory as not needed.
+ uptr shadow_p = MEM_TO_SHADOW(p);
+ ReleaseMemoryPagesToOS(shadow_p, shadow_p + size);
+ if (__msan_get_track_origins()) {
+ uptr origin_p = MEM_TO_ORIGIN(p);
+ ReleaseMemoryPagesToOS(origin_p, origin_p + size);
+ }
+ }
+};
+
+#if defined(__mips64)
+ static const uptr kMaxAllowedMallocSize = 2UL << 30;
+ static const uptr kRegionSizeLog = 20;
+ static const uptr kNumRegions = SANITIZER_MMAP_RANGE_SIZE >> kRegionSizeLog;
+ typedef TwoLevelByteMap<(kNumRegions >> 12), 1 << 12> ByteMap;
+
+ struct AP32 {
+ static const uptr kSpaceBeg = 0;
+ static const u64 kSpaceSize = SANITIZER_MMAP_RANGE_SIZE;
+ static const uptr kMetadataSize = sizeof(Metadata);
+ typedef __sanitizer::CompactSizeClassMap SizeClassMap;
+ static const uptr kRegionSizeLog = __msan::kRegionSizeLog;
+ typedef __msan::ByteMap ByteMap;
+ typedef MsanMapUnmapCallback MapUnmapCallback;
+ static const uptr kFlags = 0;
+ };
+ typedef SizeClassAllocator32<AP32> PrimaryAllocator;
+#elif defined(__x86_64__)
+#if SANITIZER_LINUX && !defined(MSAN_LINUX_X86_64_OLD_MAPPING)
+ static const uptr kAllocatorSpace = 0x700000000000ULL;
+#else
+ static const uptr kAllocatorSpace = 0x600000000000ULL;
+#endif
+ static const uptr kMaxAllowedMallocSize = 8UL << 30;
+
+ struct AP64 { // Allocator64 parameters. Deliberately using a short name.
+ static const uptr kSpaceBeg = kAllocatorSpace;
+ static const uptr kSpaceSize = 0x40000000000; // 4T.
+ static const uptr kMetadataSize = sizeof(Metadata);
+ typedef DefaultSizeClassMap SizeClassMap;
+ typedef MsanMapUnmapCallback MapUnmapCallback;
+ static const uptr kFlags = 0;
+ };
+
+ typedef SizeClassAllocator64<AP64> PrimaryAllocator;
+
+#elif defined(__powerpc64__)
+ static const uptr kMaxAllowedMallocSize = 2UL << 30; // 2G
+
+ struct AP64 { // Allocator64 parameters. Deliberately using a short name.
+ static const uptr kSpaceBeg = 0x300000000000;
+ static const uptr kSpaceSize = 0x020000000000; // 2T.
+ static const uptr kMetadataSize = sizeof(Metadata);
+ typedef DefaultSizeClassMap SizeClassMap;
+ typedef MsanMapUnmapCallback MapUnmapCallback;
+ static const uptr kFlags = 0;
+ };
+
+ typedef SizeClassAllocator64<AP64> PrimaryAllocator;
+#elif defined(__aarch64__)
+ static const uptr kMaxAllowedMallocSize = 2UL << 30; // 2G
+ static const uptr kRegionSizeLog = 20;
+ static const uptr kNumRegions = SANITIZER_MMAP_RANGE_SIZE >> kRegionSizeLog;
+ typedef TwoLevelByteMap<(kNumRegions >> 12), 1 << 12> ByteMap;
+
+ struct AP32 {
+ static const uptr kSpaceBeg = 0;
+ static const u64 kSpaceSize = SANITIZER_MMAP_RANGE_SIZE;
+ static const uptr kMetadataSize = sizeof(Metadata);
+ typedef __sanitizer::CompactSizeClassMap SizeClassMap;
+ static const uptr kRegionSizeLog = __msan::kRegionSizeLog;
+ typedef __msan::ByteMap ByteMap;
+ typedef MsanMapUnmapCallback MapUnmapCallback;
+ static const uptr kFlags = 0;
+ };
+ typedef SizeClassAllocator32<AP32> PrimaryAllocator;
+#endif
+typedef SizeClassAllocatorLocalCache<PrimaryAllocator> AllocatorCache;
+typedef LargeMmapAllocator<MsanMapUnmapCallback> SecondaryAllocator;
+typedef CombinedAllocator<PrimaryAllocator, AllocatorCache,
+ SecondaryAllocator> Allocator;
+
+
+Allocator &get_allocator();
+
struct MsanThreadLocalMallocStorage {
uptr quarantine_cache[16];
// Allocator cache contains atomic_uint64_t which must be 8-byte aligned.
diff --git a/contrib/compiler-rt/lib/msan/msan_interceptors.cc b/contrib/compiler-rt/lib/msan/msan_interceptors.cc
index 15543bd912d6..fbc2ea4fec9d 100644
--- a/contrib/compiler-rt/lib/msan/msan_interceptors.cc
+++ b/contrib/compiler-rt/lib/msan/msan_interceptors.cc
@@ -341,33 +341,6 @@ INTERCEPTOR(char *, __strdup, char *src) {
#define MSAN_MAYBE_INTERCEPT___STRDUP
#endif
-INTERCEPTOR(char *, strndup, char *src, SIZE_T n) {
- ENSURE_MSAN_INITED();
- GET_STORE_STACK_TRACE;
- // On FreeBSD strndup() leverages strnlen().
- InterceptorScope interceptor_scope;
- SIZE_T copy_size = REAL(strnlen)(src, n);
- char *res = REAL(strndup)(src, n);
- CopyShadowAndOrigin(res, src, copy_size, &stack);
- __msan_unpoison(res + copy_size, 1); // \0
- return res;
-}
-
-#if !SANITIZER_FREEBSD
-INTERCEPTOR(char *, __strndup, char *src, SIZE_T n) {
- ENSURE_MSAN_INITED();
- GET_STORE_STACK_TRACE;
- SIZE_T copy_size = REAL(strnlen)(src, n);
- char *res = REAL(__strndup)(src, n);
- CopyShadowAndOrigin(res, src, copy_size, &stack);
- __msan_unpoison(res + copy_size, 1); // \0
- return res;
-}
-#define MSAN_MAYBE_INTERCEPT___STRNDUP INTERCEPT_FUNCTION(__strndup)
-#else
-#define MSAN_MAYBE_INTERCEPT___STRNDUP
-#endif
-
INTERCEPTOR(char *, gcvt, double number, SIZE_T ndigit, char *buf) {
ENSURE_MSAN_INITED();
char *res = REAL(gcvt)(number, ndigit, buf);
@@ -1228,6 +1201,7 @@ INTERCEPTOR(void *, shmat, int shmid, const void *shmaddr, int shmflg) {
}
static void BeforeFork() {
+ get_allocator().ForceLock();
StackDepotLockAll();
ChainedOriginDepotLockAll();
}
@@ -1235,6 +1209,7 @@ static void BeforeFork() {
static void AfterFork() {
ChainedOriginDepotUnlockAll();
StackDepotUnlockAll();
+ get_allocator().ForceUnlock();
}
INTERCEPTOR(int, fork, void) {
@@ -1371,6 +1346,13 @@ int OnExit() {
return __msan_memcpy(to, from, size); \
}
+#define COMMON_INTERCEPTOR_COPY_STRING(ctx, to, from, size) \
+ do { \
+ GET_STORE_STACK_TRACE; \
+ CopyShadowAndOrigin(to, from, size, &stack); \
+ __msan_unpoison(to + size, 1); \
+ } while (false)
+
#include "sanitizer_common/sanitizer_platform_interceptors.h"
#include "sanitizer_common/sanitizer_common_interceptors.inc"
@@ -1538,8 +1520,6 @@ void InitializeInterceptors() {
INTERCEPT_FUNCTION(stpcpy); // NOLINT
INTERCEPT_FUNCTION(strdup);
MSAN_MAYBE_INTERCEPT___STRDUP;
- INTERCEPT_FUNCTION(strndup);
- MSAN_MAYBE_INTERCEPT___STRNDUP;
INTERCEPT_FUNCTION(strncpy); // NOLINT
INTERCEPT_FUNCTION(gcvt);
INTERCEPT_FUNCTION(strcat); // NOLINT
diff --git a/contrib/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/contrib/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
index 53204b48e300..c0c08a031e9b 100644
--- a/contrib/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
+++ b/contrib/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
@@ -34,6 +34,8 @@
// COMMON_INTERCEPTOR_MEMSET_IMPL
// COMMON_INTERCEPTOR_MEMMOVE_IMPL
// COMMON_INTERCEPTOR_MEMCPY_IMPL
+// COMMON_INTERCEPTOR_COPY_STRING
+// COMMON_INTERCEPTOR_STRNDUP_IMPL
//===----------------------------------------------------------------------===//
#include "interception/interception.h"
@@ -217,6 +219,24 @@ bool PlatformHasDifferentMemcpyAndMemmove();
}
#endif
+#ifndef COMMON_INTERCEPTOR_COPY_STRING
+#define COMMON_INTERCEPTOR_COPY_STRING(ctx, to, from, size) {}
+#endif
+
+#ifndef COMMON_INTERCEPTOR_STRNDUP_IMPL
+#define COMMON_INTERCEPTOR_STRNDUP_IMPL(ctx, s, size) \
+ COMMON_INTERCEPTOR_ENTER(ctx, strndup, s, size); \
+ uptr copy_length = internal_strnlen(s, size); \
+ char *new_mem = (char *)WRAP(malloc)(copy_length + 1); \
+ if (common_flags()->intercept_strndup) { \
+ COMMON_INTERCEPTOR_READ_STRING(ctx, s, Min(size, copy_length + 1)); \
+ } \
+ COMMON_INTERCEPTOR_COPY_STRING(ctx, new_mem, s, copy_length); \
+ internal_memcpy(new_mem, s, copy_length); \
+ new_mem[copy_length] = '\0'; \
+ return new_mem;
+#endif
+
struct FileMetadata {
// For open_memstream().
char **addr;
@@ -300,6 +320,26 @@ INTERCEPTOR(SIZE_T, strnlen, const char *s, SIZE_T maxlen) {
#define INIT_STRNLEN
#endif
+#if SANITIZER_INTERCEPT_STRNDUP
+INTERCEPTOR(char*, strndup, const char *s, uptr size) {
+ void *ctx;
+ COMMON_INTERCEPTOR_STRNDUP_IMPL(ctx, s, size);
+}
+#define INIT_STRNDUP COMMON_INTERCEPT_FUNCTION(strndup)
+#else
+#define INIT_STRNDUP
+#endif // SANITIZER_INTERCEPT_STRNDUP
+
+#if SANITIZER_INTERCEPT___STRNDUP
+INTERCEPTOR(char*, __strndup, const char *s, uptr size) {
+ void *ctx;
+ COMMON_INTERCEPTOR_STRNDUP_IMPL(ctx, s, size);
+}
+#define INIT___STRNDUP COMMON_INTERCEPT_FUNCTION(__strndup)
+#else
+#define INIT___STRNDUP
+#endif // SANITIZER_INTERCEPT___STRNDUP
+
#if SANITIZER_INTERCEPT_TEXTDOMAIN
INTERCEPTOR(char*, textdomain, const char *domainname) {
void *ctx;
@@ -6163,6 +6203,8 @@ static void InitializeCommonInterceptors() {
INIT_TEXTDOMAIN;
INIT_STRLEN;
INIT_STRNLEN;
+ INIT_STRNDUP;
+ INIT___STRNDUP;
INIT_STRCMP;
INIT_STRNCMP;
INIT_STRCASECMP;
diff --git a/contrib/compiler-rt/lib/sanitizer_common/sanitizer_coverage_interface.inc b/contrib/compiler-rt/lib/sanitizer_common/sanitizer_coverage_interface.inc
index 42b4d3aba01b..70c10e04b653 100644
--- a/contrib/compiler-rt/lib/sanitizer_common/sanitizer_coverage_interface.inc
+++ b/contrib/compiler-rt/lib/sanitizer_common/sanitizer_coverage_interface.inc
@@ -8,14 +8,9 @@
//===----------------------------------------------------------------------===//
// Sanitizer Coverage interface list.
//===----------------------------------------------------------------------===//
-INTERFACE_FUNCTION(__sanitizer_cov)
INTERFACE_FUNCTION(__sanitizer_cov_dump)
-INTERFACE_FUNCTION(__sanitizer_cov_init)
-INTERFACE_FUNCTION(__sanitizer_cov_module_init)
-INTERFACE_FUNCTION(__sanitizer_cov_with_check)
INTERFACE_FUNCTION(__sanitizer_dump_coverage)
INTERFACE_FUNCTION(__sanitizer_dump_trace_pc_guard_coverage)
-INTERFACE_FUNCTION(__sanitizer_get_total_unique_coverage)
INTERFACE_FUNCTION(__sanitizer_maybe_open_cov_file)
INTERFACE_WEAK_FUNCTION(__sancov_default_options)
INTERFACE_WEAK_FUNCTION(__sanitizer_cov_trace_cmp)
diff --git a/contrib/compiler-rt/lib/sanitizer_common/sanitizer_coverage_libcdep.cc b/contrib/compiler-rt/lib/sanitizer_common/sanitizer_coverage_libcdep.cc
index 754ece9840ef..abfdf3d02088 100644
--- a/contrib/compiler-rt/lib/sanitizer_common/sanitizer_coverage_libcdep.cc
+++ b/contrib/compiler-rt/lib/sanitizer_common/sanitizer_coverage_libcdep.cc
@@ -155,13 +155,6 @@ void CoverageData::DirectOpen() {
void CoverageData::Init() {
pc_fd = kInvalidFd;
-
- if (!common_flags()->coverage) return;
- Printf("**\n***\n***\n");
- Printf("**WARNING: this implementation of SanitizerCoverage is deprecated\n");
- Printf("**WARNING: and will be removed in future versions\n");
- Printf("**WARNING: See https://clang.llvm.org/docs/SanitizerCoverage.html\n");
- Printf("**\n***\n***\n");
}
void CoverageData::Enable() {
@@ -495,6 +488,12 @@ static void GenerateHtmlReport(const InternalMmapVector<char *> &cov_files) {
void CoverageData::DumpOffsets() {
auto sym = Symbolizer::GetOrInit();
if (!common_flags()->coverage_pcs) return;
+ Printf("**\n***\n***\n");
+ Printf("**WARNING: this implementation of SanitizerCoverage is deprecated\n");
+ Printf("**WARNING: and will be removed in future versions\n");
+ Printf("**WARNING: See https://clang.llvm.org/docs/SanitizerCoverage.html\n");
+ Printf("**\n***\n***\n");
+
CHECK_NE(sym, nullptr);
InternalMmapVector<uptr> offsets(0);
InternalScopedString path(kMaxPathLength);
@@ -607,47 +606,13 @@ void CoverageUpdateMapping() {
} // namespace __sanitizer
extern "C" {
-SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_cov(u32 *guard) {
- coverage_data.Add(StackTrace::GetPreviousInstructionPc(GET_CALLER_PC()),
- guard);
-}
-SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_cov_with_check(u32 *guard) {
- atomic_uint32_t *atomic_guard = reinterpret_cast<atomic_uint32_t*>(guard);
- if (static_cast<s32>(
- __sanitizer::atomic_load(atomic_guard, memory_order_relaxed)) < 0)
- coverage_data.Add(StackTrace::GetPreviousInstructionPc(GET_CALLER_PC()),
- guard);
-}
-SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_cov_init() {
- coverage_enabled = true;
- coverage_dir = common_flags()->coverage_dir;
- coverage_data.Init();
-}
SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_cov_dump() {
- coverage_data.DumpAll();
__sanitizer_dump_trace_pc_guard_coverage();
}
-SANITIZER_INTERFACE_ATTRIBUTE void
-__sanitizer_cov_module_init(s32 *guards, uptr npcs, u8 *counters,
- const char *comp_unit_name) {
- coverage_data.InitializeGuards(guards, npcs, comp_unit_name, GET_CALLER_PC());
- if (!common_flags()->coverage_direct) return;
- if (SANITIZER_ANDROID && coverage_enabled) {
- // dlopen/dlclose interceptors do not work on Android, so we rely on
- // Extend() calls to update .sancov.map.
- CovUpdateMapping(coverage_dir, GET_CALLER_PC());
- }
- coverage_data.Extend(npcs);
-}
SANITIZER_INTERFACE_ATTRIBUTE
sptr __sanitizer_maybe_open_cov_file(const char *name) {
return (sptr)MaybeOpenCovFile(name);
}
-SANITIZER_INTERFACE_ATTRIBUTE
-uptr __sanitizer_get_total_unique_coverage() {
- return atomic_load(&coverage_counter, memory_order_relaxed);
-}
-
// Default empty implementations (weak). Users should redefine them.
SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_cov_trace_cmp, void) {}
SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_cov_trace_cmp1, void) {}
diff --git a/contrib/compiler-rt/lib/sanitizer_common/sanitizer_coverage_libcdep_new.cc b/contrib/compiler-rt/lib/sanitizer_common/sanitizer_coverage_libcdep_new.cc
index 6d8e3e041cc0..a98dde76e22a 100644
--- a/contrib/compiler-rt/lib/sanitizer_common/sanitizer_coverage_libcdep_new.cc
+++ b/contrib/compiler-rt/lib/sanitizer_common/sanitizer_coverage_libcdep_new.cc
@@ -49,7 +49,7 @@ static void WriteModuleCoverage(char* file_path, const char* module_name,
WriteToFile(fd, &Magic, sizeof(Magic));
WriteToFile(fd, pcs, len * sizeof(*pcs));
CloseFile(fd);
- Printf("SanitizerCoverage: %s %zd PCs written\n", file_path, len);
+ Printf("SanitizerCoverage: %s: %zd PCs written\n", file_path, len);
}
static void SanitizerDumpCoverage(const uptr* unsorted_pcs, uptr len) {
@@ -71,7 +71,7 @@ static void SanitizerDumpCoverage(const uptr* unsorted_pcs, uptr len) {
if (!pc) continue;
if (!__sanitizer_get_module_and_offset_for_pc(pc, nullptr, 0, &pcs[i])) {
- Printf("ERROR: bad pc %x\n", pc);
+ Printf("ERROR: unknown pc 0x%x (may happen if dlclose is used)\n", pc);
continue;
}
uptr module_base = pc - pcs[i];
diff --git a/contrib/compiler-rt/lib/sanitizer_common/sanitizer_flags.inc b/contrib/compiler-rt/lib/sanitizer_common/sanitizer_flags.inc
index 12c126fa707c..f87d8b6433ac 100644
--- a/contrib/compiler-rt/lib/sanitizer_common/sanitizer_flags.inc
+++ b/contrib/compiler-rt/lib/sanitizer_common/sanitizer_flags.inc
@@ -197,6 +197,9 @@ COMMON_FLAG(bool, intercept_strpbrk, true,
COMMON_FLAG(bool, intercept_strlen, true,
"If set, uses custom wrappers for strlen and strnlen functions "
"to find more errors.")
+COMMON_FLAG(bool, intercept_strndup, true,
+ "If set, uses custom wrappers for strndup functions "
+ "to find more errors.")
COMMON_FLAG(bool, intercept_strchr, true,
"If set, uses custom wrappers for strchr, strchrnul, and strrchr "
"functions to find more errors.")
diff --git a/contrib/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h b/contrib/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h
index e5644ef25e83..a95497467d61 100644
--- a/contrib/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h
+++ b/contrib/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h
@@ -25,6 +25,12 @@
# define SI_NOT_WINDOWS 0
#endif
+#if SANITIZER_POSIX
+# define SI_POSIX 1
+#else
+# define SI_POSIX 0
+#endif
+
#if SANITIZER_LINUX && !SANITIZER_ANDROID
# define SI_LINUX_NOT_ANDROID 1
#else
@@ -69,6 +75,12 @@
# define SI_UNIX_NOT_MAC 0
#endif
+#if SANITIZER_LINUX && !SANITIZER_FREEBSD
+# define SI_LINUX_NOT_FREEBSD 1
+# else
+# define SI_LINUX_NOT_FREEBSD 0
+#endif
+
#define SANITIZER_INTERCEPT_STRLEN 1
#define SANITIZER_INTERCEPT_STRNLEN SI_NOT_MAC
#define SANITIZER_INTERCEPT_STRCMP 1
@@ -86,6 +98,8 @@
#define SANITIZER_INTERCEPT_MEMMOVE 1
#define SANITIZER_INTERCEPT_MEMCPY 1
#define SANITIZER_INTERCEPT_MEMCMP 1
+#define SANITIZER_INTERCEPT_STRNDUP SI_POSIX
+#define SANITIZER_INTERCEPT___STRNDUP SI_LINUX_NOT_FREEBSD
#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && \
__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1070
# define SI_MAC_DEPLOYMENT_BELOW_10_7 1
diff --git a/contrib/compiler-rt/lib/sanitizer_common/symbolizer/scripts/global_symbols.txt b/contrib/compiler-rt/lib/sanitizer_common/symbolizer/scripts/global_symbols.txt
index 737f9459d240..a23c9534701d 100644
--- a/contrib/compiler-rt/lib/sanitizer_common/symbolizer/scripts/global_symbols.txt
+++ b/contrib/compiler-rt/lib/sanitizer_common/symbolizer/scripts/global_symbols.txt
@@ -59,6 +59,7 @@ getpagesize U
getpid U
gettimeofday U
ioctl U
+isalpha U
isatty U
isprint U
isupper U
diff --git a/contrib/compiler-rt/lib/ubsan/ubsan_type_hash_itanium.cc b/contrib/compiler-rt/lib/ubsan/ubsan_type_hash_itanium.cc
index 5ae5ae0dc849..729c4a0f3739 100644
--- a/contrib/compiler-rt/lib/ubsan/ubsan_type_hash_itanium.cc
+++ b/contrib/compiler-rt/lib/ubsan/ubsan_type_hash_itanium.cc
@@ -197,7 +197,7 @@ struct VtablePrefix {
};
VtablePrefix *getVtablePrefix(void *Vtable) {
VtablePrefix *Vptr = reinterpret_cast<VtablePrefix*>(Vtable);
- if (!Vptr)
+ if (!IsAccessibleMemoryRange((uptr)Vptr, sizeof(VtablePrefix)))
return nullptr;
VtablePrefix *Prefix = Vptr - 1;
if (!Prefix->TypeInfo)
diff --git a/contrib/libc++/include/__bit_reference b/contrib/libc++/include/__bit_reference
index 9aea96145284..3e4a21d261ff 100644
--- a/contrib/libc++/include/__bit_reference
+++ b/contrib/libc++/include/__bit_reference
@@ -14,12 +14,14 @@
#include <__config>
#include <algorithm>
-#include <__undef_min_max>
-
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
#endif
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+
_LIBCPP_BEGIN_NAMESPACE_STD
template <class _Cp, bool _IsConst, typename _Cp::__storage_type = 0> class __bit_iterator;
@@ -1273,4 +1275,6 @@ private:
_LIBCPP_END_NAMESPACE_STD
+_LIBCPP_POP_MACROS
+
#endif // _LIBCPP___BIT_REFERENCE
diff --git a/contrib/libc++/include/__config b/contrib/libc++/include/__config
index 32e542bd1fd7..212a2d53136b 100644
--- a/contrib/libc++/include/__config
+++ b/contrib/libc++/include/__config
@@ -220,10 +220,12 @@
#endif // __NetBSD__
#if defined(_WIN32)
-# define _LIBCPP_WIN32API 1
+# define _LIBCPP_WIN32API
# define _LIBCPP_LITTLE_ENDIAN 1
# define _LIBCPP_BIG_ENDIAN 0
# define _LIBCPP_SHORT_WCHAR 1
+// Both MinGW and native MSVC provide a "MSVC"-like enviroment
+# define _LIBCPP_MSVCRT_LIKE
// If mingw not explicitly detected, assume using MS C runtime only.
# ifndef __MINGW32__
# define _LIBCPP_MSVCRT // Using Microsoft's C Runtime library
@@ -1205,4 +1207,34 @@ _LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container(
#define _LIBCPP_AVAILABILITY_NO_STREAMS_EXTERN_TEMPLATE
#endif
+#if defined(_LIBCPP_COMPILER_IBM)
+#define _LIBCPP_HAS_NO_PRAGMA_PUSH_POP_MACRO
+#endif
+
+#if defined(_LIBCPP_HAS_NO_PRAGMA_PUSH_POP_MACRO)
+# define _LIBCPP_PUSH_MACROS
+# define _LIBCPP_POP_MACROS
+#else
+ // Don't warn about macro conflicts when we can restore them at the
+ // end of the header.
+# ifndef _LIBCPP_DISABLE_MACRO_CONFLICT_WARNINGS
+# define _LIBCPP_DISABLE_MACRO_CONFLICT_WARNINGS
+# endif
+# if defined(_LIBCPP_COMPILER_MSVC)
+# define _LIBCPP_PUSH_MACROS \
+ __pragma(push_macro("min")) \
+ __pragma(push_macro("max"))
+# define _LIBCPP_POP_MACROS \
+ __pragma(pop_macro("min")) \
+ __pragma(pop_macro("max"))
+# else
+# define _LIBCPP_PUSH_MACROS \
+ _Pragma("push_macro(\"min\")") \
+ _Pragma("push_macro(\"max\")")
+# define _LIBCPP_POP_MACROS \
+ _Pragma("pop_macro(\"min\")") \
+ _Pragma("pop_macro(\"max\")")
+# endif
+#endif // defined(_LIBCPP_HAS_NO_PRAGMA_PUSH_POP_MACRO)
+
#endif // _LIBCPP_CONFIG
diff --git a/contrib/libc++/include/__hash_table b/contrib/libc++/include/__hash_table
index acdc443a640a..79336ff793ec 100644
--- a/contrib/libc++/include/__hash_table
+++ b/contrib/libc++/include/__hash_table
@@ -20,16 +20,17 @@
#include <utility>
#include <type_traits>
-#include <__undef_min_max>
-
#include <__debug>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
#endif
-_LIBCPP_BEGIN_NAMESPACE_STD
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
#ifndef _LIBCPP_CXX03_LANG
template <class _Key, class _Tp>
@@ -2667,6 +2668,9 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__subscriptable(const const_iterator*,
}
#endif // _LIBCPP_DEBUG_LEVEL >= 2
+
_LIBCPP_END_NAMESPACE_STD
+_LIBCPP_POP_MACROS
+
#endif // _LIBCPP__HASH_TABLE
diff --git a/contrib/libc++/include/__locale b/contrib/libc++/include/__locale
index cf3ba23b9092..766842294ca3 100644
--- a/contrib/libc++/include/__locale
+++ b/contrib/libc++/include/__locale
@@ -19,7 +19,7 @@
#include <cstdint>
#include <cctype>
#include <locale.h>
-#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
+#if defined(_LIBCPP_MSVCRT_LIKE)
# include <support/win32/locale_win32.h>
#elif defined(_AIX)
# include <support/ibm/xlocale.h>
@@ -367,7 +367,7 @@ public:
static const mask punct = _ISpunct;
static const mask xdigit = _ISxdigit;
static const mask blank = _ISblank;
-#elif defined(_LIBCPP_MSVCRT)
+#elif defined(_LIBCPP_MSVCRT_LIKE)
typedef unsigned short mask;
static const mask space = _SPACE;
static const mask print = _BLANK|_PUNCT|_ALPHA|_DIGIT;
diff --git a/contrib/libc++/include/__mutex_base b/contrib/libc++/include/__mutex_base
index 7f5e2ea2810e..159acd626618 100644
--- a/contrib/libc++/include/__mutex_base
+++ b/contrib/libc++/include/__mutex_base
@@ -15,12 +15,16 @@
#include <chrono>
#include <system_error>
#include <__threading_support>
-#include <__undef_min_max>
+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
#endif
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+
_LIBCPP_BEGIN_NAMESPACE_STD
#ifndef _LIBCPP_HAS_NO_THREADS
@@ -428,4 +432,6 @@ condition_variable::wait_for(unique_lock<mutex>& __lk,
_LIBCPP_END_NAMESPACE_STD
+_LIBCPP_POP_MACROS
+
#endif // _LIBCPP___MUTEX_BASE
diff --git a/contrib/libc++/include/__split_buffer b/contrib/libc++/include/__split_buffer
index 72073f024cd2..1daa4e5ada3d 100644
--- a/contrib/libc++/include/__split_buffer
+++ b/contrib/libc++/include/__split_buffer
@@ -6,12 +6,14 @@
#include <type_traits>
#include <algorithm>
-#include <__undef_min_max>
-
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
#endif
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+
_LIBCPP_BEGIN_NAMESPACE_STD
template <bool>
@@ -628,7 +630,8 @@ swap(__split_buffer<_Tp, _Allocator>& __x, __split_buffer<_Tp, _Allocator>& __y)
__x.swap(__y);
}
-
_LIBCPP_END_NAMESPACE_STD
+_LIBCPP_POP_MACROS
+
#endif // _LIBCPP_SPLIT_BUFFER
diff --git a/contrib/libc++/include/__std_stream b/contrib/libc++/include/__std_stream
index fb5a346f10d8..db90795f66fc 100644
--- a/contrib/libc++/include/__std_stream
+++ b/contrib/libc++/include/__std_stream
@@ -17,12 +17,14 @@
#include <__locale>
#include <cstdio>
-#include <__undef_min_max>
-
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
#endif
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+
_LIBCPP_BEGIN_NAMESPACE_STD
static const int __limit = 8;
@@ -355,4 +357,6 @@ __stdoutbuf<_CharT>::imbue(const locale& __loc)
_LIBCPP_END_NAMESPACE_STD
+_LIBCPP_POP_MACROS
+
#endif // _LIBCPP___STD_STREAM
diff --git a/contrib/libc++/include/__string b/contrib/libc++/include/__string
index 75608cea71d9..d30c7fddc8d6 100644
--- a/contrib/libc++/include/__string
+++ b/contrib/libc++/include/__string
@@ -57,14 +57,16 @@ template <> struct char_traits<wchar_t>;
#include <cstdio> // For EOF.
#include <memory> // for __murmur2_or_cityhash
-#include <__undef_min_max>
-
#include <__debug>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
#endif
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+
_LIBCPP_BEGIN_NAMESPACE_STD
// char_traits
@@ -870,4 +872,6 @@ struct __quoted_output_proxy
_LIBCPP_END_NAMESPACE_STD
+_LIBCPP_POP_MACROS
+
#endif // _LIBCPP___STRING
diff --git a/contrib/libc++/include/__threading_support b/contrib/libc++/include/__threading_support
index afd7cb506492..5d4c907966ee 100644
--- a/contrib/libc++/include/__threading_support
+++ b/contrib/libc++/include/__threading_support
@@ -30,9 +30,12 @@
#include <windows.h>
#include <process.h>
#include <fibersapi.h>
-#include <__undef_min_max>
#endif
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+
#if defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \
defined(_LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL)
#define _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_FUNC_VIS
@@ -629,6 +632,8 @@ int __libcpp_tls_set(__libcpp_tls_key __key, void *__p)
_LIBCPP_END_NAMESPACE_STD
+_LIBCPP_POP_MACROS
+
#endif // !_LIBCPP_HAS_NO_THREADS
#endif // _LIBCPP_THREADING_SUPPORT
diff --git a/contrib/libc++/include/__tree b/contrib/libc++/include/__tree
index 6771589bbc68..792870aa6ebc 100644
--- a/contrib/libc++/include/__tree
+++ b/contrib/libc++/include/__tree
@@ -17,12 +17,14 @@
#include <stdexcept>
#include <algorithm>
-#include <__undef_min_max>
-
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
#endif
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+
_LIBCPP_BEGIN_NAMESPACE_STD
template <class _Tp, class _Compare, class _Allocator> class __tree;
@@ -2685,4 +2687,6 @@ swap(__tree<_Tp, _Compare, _Allocator>& __x,
_LIBCPP_END_NAMESPACE_STD
+_LIBCPP_POP_MACROS
+
#endif // _LIBCPP___TREE
diff --git a/contrib/libc++/include/__undef_min_max b/contrib/libc++/include/__undef_macros
index 71db3965e3cd..60ab1dbfb5f7 100644
--- a/contrib/libc++/include/__undef_min_max
+++ b/contrib/libc++/include/__undef_macros
@@ -1,13 +1,14 @@
// -*- C++ -*-
-//===----------------------------------------------------------------------===//
+//===------------------------ __undef_macros ------------------------------===//
//
// The LLVM Compiler Infrastructure
//
-// This file is dual licensed under the MIT and the University of Illinois Open
-// Source Licenses. See LICENSE.TXT for details.
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+
#ifdef min
#if !defined(_LIBCPP_DISABLE_MACRO_CONFLICT_WARNINGS)
#if defined(_LIBCPP_WARNING)
diff --git a/contrib/libc++/include/algorithm b/contrib/libc++/include/algorithm
index 7ea4474a1bb4..9fe0361e577d 100644
--- a/contrib/libc++/include/algorithm
+++ b/contrib/libc++/include/algorithm
@@ -651,14 +651,16 @@ template <class BidirectionalIterator, class Compare>
#include <intrin.h>
#endif
-#include <__undef_min_max>
-
#include <__debug>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
#endif
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+
_LIBCPP_BEGIN_NAMESPACE_STD
// I'd like to replace these with _VSTD::equal_to<void>, but can't because:
@@ -2908,11 +2910,11 @@ struct __log2_imp<0, _Rp>
static const size_t value = _Rp + 1;
};
-template <class _UI, _UI _Xp>
+template <class _UIntType, _UIntType _Xp>
struct __log2
{
static const size_t value = __log2_imp<_Xp,
- sizeof(_UI) * __CHAR_BIT__ - 1>::value;
+ sizeof(_UIntType) * __CHAR_BIT__ - 1>::value;
};
template<class _Engine, class _UIntType>
@@ -5904,4 +5906,6 @@ prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last)
_LIBCPP_END_NAMESPACE_STD
+_LIBCPP_POP_MACROS
+
#endif // _LIBCPP_ALGORITHM
diff --git a/contrib/libc++/include/array b/contrib/libc++/include/array
index 31f5501b9bc4..79f7e0d62c56 100644
--- a/contrib/libc++/include/array
+++ b/contrib/libc++/include/array
@@ -113,6 +113,8 @@ template <size_t I, class T, size_t N> const T&& get(const array<T, N>&&) noexce
#pragma GCC system_header
#endif
+
+
_LIBCPP_BEGIN_NAMESPACE_STD
template <class _Tp, size_t _Size>
diff --git a/contrib/libc++/include/bitset b/contrib/libc++/include/bitset
index b49c93ce2224..583122fbfdab 100644
--- a/contrib/libc++/include/bitset
+++ b/contrib/libc++/include/bitset
@@ -113,10 +113,6 @@ template <size_t N> struct hash<std::bitset<N>>;
*/
-#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
-#endif
-
#include <__config>
#include <__bit_reference>
#include <cstddef>
@@ -126,7 +122,13 @@ template <size_t N> struct hash<std::bitset<N>>;
#include <iosfwd>
#include <__functional_base>
-#include <__undef_min_max>
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -1090,4 +1092,6 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, const bitset<_Size>& __x);
_LIBCPP_END_NAMESPACE_STD
+_LIBCPP_POP_MACROS
+
#endif // _LIBCPP_BITSET
diff --git a/contrib/libc++/include/chrono b/contrib/libc++/include/chrono
index 657808736d09..4b793c760559 100644
--- a/contrib/libc++/include/chrono
+++ b/contrib/libc++/include/chrono
@@ -305,12 +305,14 @@ constexpr chrono::duration<unspecified , nano> operator "" ns(long doub
#include <ratio>
#include <limits>
-#include <__undef_min_max>
-
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
#endif
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+
_LIBCPP_BEGIN_NAMESPACE_STD
namespace chrono
@@ -1160,4 +1162,6 @@ namespace chrono { // hoist the literals into namespace std::chrono
_LIBCPP_END_NAMESPACE_STD
+_LIBCPP_POP_MACROS
+
#endif // _LIBCPP_CHRONO
diff --git a/contrib/libc++/include/deque b/contrib/libc++/include/deque
index bd4316412f60..f795b489edc6 100644
--- a/contrib/libc++/include/deque
+++ b/contrib/libc++/include/deque
@@ -150,10 +150,6 @@ template <class T, class Allocator>
*/
-#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
-#endif
-
#include <__config>
#include <__split_buffer>
#include <type_traits>
@@ -162,7 +158,13 @@ template <class T, class Allocator>
#include <algorithm>
#include <stdexcept>
-#include <__undef_min_max>
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -2900,4 +2902,6 @@ swap(deque<_Tp, _Allocator>& __x, deque<_Tp, _Allocator>& __y)
_LIBCPP_END_NAMESPACE_STD
+_LIBCPP_POP_MACROS
+
#endif // _LIBCPP_DEQUE
diff --git a/contrib/libc++/include/experimental/algorithm b/contrib/libc++/include/experimental/algorithm
index b32d7ca66bd2..3801cae4f16e 100644
--- a/contrib/libc++/include/experimental/algorithm
+++ b/contrib/libc++/include/experimental/algorithm
@@ -39,17 +39,18 @@ SampleIterator sample(PopulationIterator first, PopulationIterator last,
#include <algorithm>
#include <type_traits>
-#include <__undef_min_max>
-
#include <__debug>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
#endif
-_LIBCPP_BEGIN_NAMESPACE_LFTS
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+_LIBCPP_BEGIN_NAMESPACE_LFTS
+
template <class _ForwardIterator, class _Searcher>
_LIBCPP_INLINE_VISIBILITY
_ForwardIterator search(_ForwardIterator __f, _ForwardIterator __l, const _Searcher &__s)
@@ -67,4 +68,6 @@ _SampleIterator sample(_PopulationIterator __first, _PopulationIterator __last,
_LIBCPP_END_NAMESPACE_LFTS
+_LIBCPP_POP_MACROS
+
#endif /* _LIBCPP_EXPERIMENTAL_ALGORITHM */
diff --git a/contrib/libc++/include/experimental/dynarray b/contrib/libc++/include/experimental/dynarray
index f96a0e5fed38..16193317ad20 100644
--- a/contrib/libc++/include/experimental/dynarray
+++ b/contrib/libc++/include/experimental/dynarray
@@ -107,6 +107,9 @@ public:
#pragma GCC system_header
#endif
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
namespace std { namespace experimental { inline namespace __array_extensions_v1 {
template <class _Tp>
@@ -295,5 +298,7 @@ template <class _Tp, class _Alloc>
struct _LIBCPP_TEMPLATE_VIS uses_allocator<std::experimental::dynarray<_Tp>, _Alloc> : true_type {};
_LIBCPP_END_NAMESPACE_STD
+_LIBCPP_POP_MACROS
+
#endif // if _LIBCPP_STD_VER > 11
#endif // _LIBCPP_DYNARRAY
diff --git a/contrib/libc++/include/experimental/functional b/contrib/libc++/include/experimental/functional
index 75fc8e99f352..a136cbb57c85 100644
--- a/contrib/libc++/include/experimental/functional
+++ b/contrib/libc++/include/experimental/functional
@@ -89,21 +89,22 @@ inline namespace fundamentals_v1 {
#include <experimental/__config>
#include <functional>
-
#include <algorithm>
#include <type_traits>
#include <vector>
#include <array>
#include <unordered_map>
-#include <__undef_min_max>
-
#include <__debug>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
#endif
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+
_LIBCPP_BEGIN_NAMESPACE_LFTS
#if _LIBCPP_STD_VER > 11
@@ -456,4 +457,6 @@ make_boyer_moore_horspool_searcher( _RandomAccessIterator __f, _RandomAccessIter
_LIBCPP_END_NAMESPACE_LFTS
+_LIBCPP_POP_MACROS
+
#endif /* _LIBCPP_EXPERIMENTAL_FUNCTIONAL */
diff --git a/contrib/libc++/include/experimental/memory_resource b/contrib/libc++/include/experimental/memory_resource
index 743f9cbe639c..d101f3e08113 100644
--- a/contrib/libc++/include/experimental/memory_resource
+++ b/contrib/libc++/include/experimental/memory_resource
@@ -82,6 +82,9 @@ namespace pmr {
#pragma GCC system_header
#endif
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
_LIBCPP_BEGIN_NAMESPACE_LFTS_PMR
// Round __s up to next multiple of __a.
@@ -419,4 +422,6 @@ using resource_adaptor = __resource_adaptor_imp<
_LIBCPP_END_NAMESPACE_LFTS_PMR
+_LIBCPP_POP_MACROS
+
#endif /* _LIBCPP_EXPERIMENTAL_MEMORY_RESOURCE */
diff --git a/contrib/libc++/include/experimental/numeric b/contrib/libc++/include/experimental/numeric
index 6488a68eca6c..d784c08f0fe8 100644
--- a/contrib/libc++/include/experimental/numeric
+++ b/contrib/libc++/include/experimental/numeric
@@ -41,6 +41,9 @@ inline namespace fundamentals_v2 {
#pragma GCC system_header
#endif
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
#if _LIBCPP_STD_VER > 11
_LIBCPP_BEGIN_NAMESPACE_LFTS_V2
@@ -110,4 +113,7 @@ lcm(_Tp __m, _Up __n)
_LIBCPP_END_NAMESPACE_LFTS_V2
#endif /* _LIBCPP_STD_VER > 11 */
+
+_LIBCPP_POP_MACROS
+
#endif /* _LIBCPP_EXPERIMENTAL_NUMERIC */
diff --git a/contrib/libc++/include/experimental/optional b/contrib/libc++/include/experimental/optional
index 48adfbae5167..b251748fbf37 100644
--- a/contrib/libc++/include/experimental/optional
+++ b/contrib/libc++/include/experimental/optional
@@ -143,6 +143,21 @@ namespace std { namespace experimental { inline namespace fundamentals_v1 {
#include <experimental/__config>
#include <functional>
#include <stdexcept>
+#if _LIBCPP_STD_VER > 11
+#include <initializer_list>
+#include <type_traits>
+#include <new>
+#include <__functional_base>
+#include <__debug>
+#endif
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL
class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS bad_optional_access
@@ -160,17 +175,6 @@ _LIBCPP_END_NAMESPACE_EXPERIMENTAL
#if _LIBCPP_STD_VER > 11
-#include <initializer_list>
-#include <type_traits>
-#include <new>
-#include <__functional_base>
-#include <__undef_min_max>
-#include <__debug>
-
-#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
-#endif
-
_LIBCPP_BEGIN_NAMESPACE_LFTS
struct in_place_t {};
@@ -913,4 +917,6 @@ _LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP_STD_VER > 11
+_LIBCPP_POP_MACROS
+
#endif // _LIBCPP_EXPERIMENTAL_OPTIONAL
diff --git a/contrib/libc++/include/experimental/string_view b/contrib/libc++/include/experimental/string_view
index 41c0d34d3c84..da104f9a1210 100644
--- a/contrib/libc++/include/experimental/string_view
+++ b/contrib/libc++/include/experimental/string_view
@@ -189,6 +189,9 @@ namespace std {
#pragma GCC system_header
#endif
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
_LIBCPP_BEGIN_NAMESPACE_LFTS
template<class _CharT, class _Traits = _VSTD::char_traits<_CharT> >
@@ -810,4 +813,6 @@ quoted ( std::experimental::basic_string_view <_CharT, _Traits> __sv,
_LIBCPP_END_NAMESPACE_STD
+_LIBCPP_POP_MACROS
+
#endif // _LIBCPP_LFTS_STRING_VIEW
diff --git a/contrib/libc++/include/forward_list b/contrib/libc++/include/forward_list
index e4ab41e38b11..8bfa9a084338 100644
--- a/contrib/libc++/include/forward_list
+++ b/contrib/libc++/include/forward_list
@@ -167,19 +167,20 @@ template <class T, class Allocator>
*/
#include <__config>
-
#include <initializer_list>
#include <memory>
#include <limits>
#include <iterator>
#include <algorithm>
-#include <__undef_min_max>
-
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
#endif
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+
_LIBCPP_BEGIN_NAMESPACE_STD
template <class _Tp, class _VoidPtr> struct __forward_list_node;
@@ -1719,4 +1720,6 @@ swap(forward_list<_Tp, _Alloc>& __x, forward_list<_Tp, _Alloc>& __y)
_LIBCPP_END_NAMESPACE_STD
+_LIBCPP_POP_MACROS
+
#endif // _LIBCPP_FORWARD_LIST
diff --git a/contrib/libc++/include/fstream b/contrib/libc++/include/fstream
index 5ec42bd13407..e41a53af4a0c 100644
--- a/contrib/libc++/include/fstream
+++ b/contrib/libc++/include/fstream
@@ -171,12 +171,14 @@ typedef basic_fstream<wchar_t> wfstream;
#include <__locale>
#include <cstdio>
-#include <__undef_min_max>
-
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
#endif
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+
_LIBCPP_BEGIN_NAMESPACE_STD
template <class _CharT, class _Traits>
@@ -1476,4 +1478,6 @@ basic_fstream<_CharT, _Traits>::close()
_LIBCPP_END_NAMESPACE_STD
+_LIBCPP_POP_MACROS
+
#endif // _LIBCPP_FSTREAM
diff --git a/contrib/libc++/include/istream b/contrib/libc++/include/istream
index 530f204cfad9..0b8e05d95bd8 100644
--- a/contrib/libc++/include/istream
+++ b/contrib/libc++/include/istream
@@ -162,12 +162,14 @@ template <class charT, class traits, class T>
#include <__config>
#include <ostream>
-#include <__undef_min_max>
-
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
#endif
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+
_LIBCPP_BEGIN_NAMESPACE_STD
template <class _CharT, class _Traits>
@@ -1683,4 +1685,6 @@ _LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_iostream<ch
_LIBCPP_END_NAMESPACE_STD
+_LIBCPP_POP_MACROS
+
#endif // _LIBCPP_ISTREAM
diff --git a/contrib/libc++/include/limits b/contrib/libc++/include/limits
index 4755c57cf903..f530507f7246 100644
--- a/contrib/libc++/include/limits
+++ b/contrib/libc++/include/limits
@@ -102,15 +102,8 @@ template<> class numeric_limits<cv long double>;
*/
#include <__config>
-
-#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
-#endif
-
#include <type_traits>
-#include <__undef_min_max>
-
#if defined(_LIBCPP_COMPILER_MSVC)
#include "support/win32/limits_msvc_win32.h"
#endif // _LIBCPP_MSVCRT
@@ -119,6 +112,14 @@ template<> class numeric_limits<cv long double>;
#include "support/ibm/limits.h"
#endif // __IBMCPP__
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+
_LIBCPP_BEGIN_NAMESPACE_STD
enum float_round_style
@@ -182,14 +183,14 @@ protected:
static _LIBCPP_CONSTEXPR const float_round_style round_style = round_toward_zero;
};
-template <class _Tp, int digits, bool _IsSigned>
+template <class _Tp, int __digits, bool _IsSigned>
struct __libcpp_compute_min
{
- static _LIBCPP_CONSTEXPR const _Tp value = _Tp(_Tp(1) << digits);
+ static _LIBCPP_CONSTEXPR const _Tp value = _Tp(_Tp(1) << __digits);
};
-template <class _Tp, int digits>
-struct __libcpp_compute_min<_Tp, digits, false>
+template <class _Tp, int __digits>
+struct __libcpp_compute_min<_Tp, __digits, false>
{
static _LIBCPP_CONSTEXPR const _Tp value = _Tp(0);
};
@@ -811,4 +812,6 @@ template <class _Tp>
_LIBCPP_END_NAMESPACE_STD
+_LIBCPP_POP_MACROS
+
#endif // _LIBCPP_LIMITS
diff --git a/contrib/libc++/include/list b/contrib/libc++/include/list
index 5e76d1103371..20a66c36002d 100644
--- a/contrib/libc++/include/list
+++ b/contrib/libc++/include/list
@@ -177,14 +177,16 @@ template <class T, class Alloc>
#include <algorithm>
#include <type_traits>
-#include <__undef_min_max>
-
#include <__debug>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
#endif
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+
_LIBCPP_BEGIN_NAMESPACE_STD
template <class _Tp, class _VoidPtr> struct __list_node;
@@ -2415,4 +2417,6 @@ swap(list<_Tp, _Alloc>& __x, list<_Tp, _Alloc>& __y)
_LIBCPP_END_NAMESPACE_STD
+_LIBCPP_POP_MACROS
+
#endif // _LIBCPP_LIST
diff --git a/contrib/libc++/include/locale b/contrib/libc++/include/locale
index d29a2dc70a5b..6aaa22ccaa15 100644
--- a/contrib/libc++/include/locale
+++ b/contrib/libc++/include/locale
@@ -192,14 +192,7 @@ template <class charT> class messages_byname;
#endif
#include <cstdlib>
#include <ctime>
-#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
-#include <support/win32/locale_win32.h>
-#elif defined(_NEWLIB_VERSION)
-// FIXME: replace all the uses of _NEWLIB_VERSION with __NEWLIB__ preceded by an
-// include of <sys/cdefs.h> once https://sourceware.org/ml/newlib-cvs/2014-q3/msg00038.html
-// has had a chance to bake for a bit
-#include <support/newlib/xlocale.h>
-#endif
+#include <cstdio>
#ifdef _LIBCPP_HAS_CATOPEN
#include <nl_types.h>
#endif
@@ -208,18 +201,20 @@ template <class charT> class messages_byname;
#include <Availability.h>
#endif
-#include <__undef_min_max>
-
-#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
-#endif
-
#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
#include <__bsd_locale_defaults.h>
#else
#include <__bsd_locale_fallbacks.h>
#endif
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+
_LIBCPP_BEGIN_NAMESPACE_STD
#if defined(__APPLE__) || defined(__FreeBSD__)
@@ -4274,4 +4269,6 @@ wbuffer_convert<_Codecvt, _Elem, _Tr>::__close()
_LIBCPP_END_NAMESPACE_STD
+_LIBCPP_POP_MACROS
+
#endif // _LIBCPP_LOCALE
diff --git a/contrib/libc++/include/memory b/contrib/libc++/include/memory
index 31dc73d8b142..711551d5732d 100644
--- a/contrib/libc++/include/memory
+++ b/contrib/libc++/include/memory
@@ -658,12 +658,14 @@ void* align(size_t alignment, size_t size, void*& ptr, size_t& space);
# include <atomic>
#endif
-#include <__undef_min_max>
-
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
#endif
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+
_LIBCPP_BEGIN_NAMESPACE_STD
template <class _ValueType>
@@ -1541,7 +1543,7 @@ struct _LIBCPP_TEMPLATE_VIS allocator_traits
{return __a.allocate(__n);}
_LIBCPP_INLINE_VISIBILITY
static pointer allocate(allocator_type& __a, size_type __n, const_void_pointer __hint)
- {return allocate(__a, __n, __hint,
+ {return __allocate(__a, __n, __hint,
__has_allocate_hint<allocator_type, size_type, const_void_pointer>());}
_LIBCPP_INLINE_VISIBILITY
@@ -1595,7 +1597,7 @@ struct _LIBCPP_TEMPLATE_VIS allocator_traits
_LIBCPP_INLINE_VISIBILITY
static allocator_type
select_on_container_copy_construction(const allocator_type& __a)
- {return select_on_container_copy_construction(
+ {return __select_on_container_copy_construction(
__has_select_on_container_copy_construction<const allocator_type>(),
__a);}
@@ -1694,11 +1696,11 @@ struct _LIBCPP_TEMPLATE_VIS allocator_traits
private:
_LIBCPP_INLINE_VISIBILITY
- static pointer allocate(allocator_type& __a, size_type __n,
+ static pointer __allocate(allocator_type& __a, size_type __n,
const_void_pointer __hint, true_type)
{return __a.allocate(__n, __hint);}
_LIBCPP_INLINE_VISIBILITY
- static pointer allocate(allocator_type& __a, size_type __n,
+ static pointer __allocate(allocator_type& __a, size_type __n,
const_void_pointer, false_type)
{return __a.allocate(__n);}
@@ -1735,11 +1737,11 @@ private:
_LIBCPP_INLINE_VISIBILITY
static allocator_type
- select_on_container_copy_construction(true_type, const allocator_type& __a)
+ __select_on_container_copy_construction(true_type, const allocator_type& __a)
{return __a.select_on_container_copy_construction();}
_LIBCPP_INLINE_VISIBILITY
static allocator_type
- select_on_container_copy_construction(false_type, const allocator_type& __a)
+ __select_on_container_copy_construction(false_type, const allocator_type& __a)
{return __a;}
};
@@ -3101,28 +3103,28 @@ struct _LIBCPP_TEMPLATE_VIS hash<__enable_hash_helper<
struct __destruct_n
{
private:
- size_t size;
+ size_t __size_;
template <class _Tp>
_LIBCPP_INLINE_VISIBILITY void __process(_Tp* __p, false_type) _NOEXCEPT
- {for (size_t __i = 0; __i < size; ++__i, ++__p) __p->~_Tp();}
+ {for (size_t __i = 0; __i < __size_; ++__i, ++__p) __p->~_Tp();}
template <class _Tp>
_LIBCPP_INLINE_VISIBILITY void __process(_Tp*, true_type) _NOEXCEPT
{}
_LIBCPP_INLINE_VISIBILITY void __incr(false_type) _NOEXCEPT
- {++size;}
+ {++__size_;}
_LIBCPP_INLINE_VISIBILITY void __incr(true_type) _NOEXCEPT
{}
_LIBCPP_INLINE_VISIBILITY void __set(size_t __s, false_type) _NOEXCEPT
- {size = __s;}
+ {__size_ = __s;}
_LIBCPP_INLINE_VISIBILITY void __set(size_t, true_type) _NOEXCEPT
{}
public:
_LIBCPP_INLINE_VISIBILITY explicit __destruct_n(size_t __s) _NOEXCEPT
- : size(__s) {}
+ : __size_(__s) {}
template <class _Tp>
_LIBCPP_INLINE_VISIBILITY void __incr(_Tp*) _NOEXCEPT
@@ -5574,4 +5576,6 @@ struct __temp_value {
_LIBCPP_END_NAMESPACE_STD
+_LIBCPP_POP_MACROS
+
#endif // _LIBCPP_MEMORY
diff --git a/contrib/libc++/include/module.modulemap b/contrib/libc++/include/module.modulemap
index 98b1870afcc1..3194b5c9f2a2 100644
--- a/contrib/libc++/include/module.modulemap
+++ b/contrib/libc++/include/module.modulemap
@@ -484,7 +484,7 @@ module std [system] {
module __string { header "__string" export * }
module __tree { header "__tree" export * }
module __tuple { header "__tuple" export * }
- module __undef_min_max { header "__undef_min_max" export * }
+ module __undef_macros { header "__undef_macros" export * }
module experimental {
requires cplusplus11
diff --git a/contrib/libc++/include/mutex b/contrib/libc++/include/mutex
index 0b25614e8ead..55380882044d 100644
--- a/contrib/libc++/include/mutex
+++ b/contrib/libc++/include/mutex
@@ -196,12 +196,14 @@ template<class Callable, class ...Args>
#endif
#include <__threading_support>
-#include <__undef_min_max>
-
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
#endif
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+
_LIBCPP_BEGIN_NAMESPACE_STD
#ifndef _LIBCPP_HAS_NO_THREADS
@@ -696,4 +698,6 @@ call_once(once_flag& __flag, const _Callable& __func)
_LIBCPP_END_NAMESPACE_STD
+_LIBCPP_POP_MACROS
+
#endif // _LIBCPP_MUTEX
diff --git a/contrib/libc++/include/numeric b/contrib/libc++/include/numeric
index 9c98cdbe262e..0e53ba33c3c7 100644
--- a/contrib/libc++/include/numeric
+++ b/contrib/libc++/include/numeric
@@ -71,6 +71,9 @@ template <class M, class N>
#pragma GCC system_header
#endif
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
_LIBCPP_BEGIN_NAMESPACE_STD
template <class _InputIterator, class _Tp>
@@ -267,4 +270,6 @@ lcm(_Tp __m, _Up __n)
_LIBCPP_END_NAMESPACE_STD
+_LIBCPP_POP_MACROS
+
#endif // _LIBCPP_NUMERIC
diff --git a/contrib/libc++/include/optional b/contrib/libc++/include/optional
index 70b6eb44dcd6..8c8ee76b1411 100644
--- a/contrib/libc++/include/optional
+++ b/contrib/libc++/include/optional
@@ -146,7 +146,6 @@ namespace std {
#include <__config>
#include <__debug>
#include <__functional_base>
-#include <__undef_min_max>
#include <functional>
#include <initializer_list>
#include <new>
@@ -158,6 +157,10 @@ namespace std {
#pragma GCC system_header
#endif
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+
namespace std // purposefully not using versioning namespace
{
@@ -1315,4 +1318,6 @@ _LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP_STD_VER > 14
+_LIBCPP_POP_MACROS
+
#endif // _LIBCPP_OPTIONAL
diff --git a/contrib/libc++/include/random b/contrib/libc++/include/random
index 6c36e8c01ae2..ba8a088dfcb1 100644
--- a/contrib/libc++/include/random
+++ b/contrib/libc++/include/random
@@ -1646,12 +1646,14 @@ class piecewise_linear_distribution
#include <istream>
#include <ostream>
-#include <__undef_min_max>
-
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
#endif
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+
_LIBCPP_BEGIN_NAMESPACE_STD
// __is_seed_sequence
@@ -2013,41 +2015,41 @@ template <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,
_UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>
class _LIBCPP_TEMPLATE_VIS mersenne_twister_engine;
-template <class _UI, size_t _Wp, size_t _Np, size_t _Mp, size_t _Rp,
- _UI _Ap, size_t _Up, _UI _Dp, size_t _Sp,
- _UI _Bp, size_t _Tp, _UI _Cp, size_t _Lp, _UI _Fp>
+template <class _UInt, size_t _Wp, size_t _Np, size_t _Mp, size_t _Rp,
+ _UInt _Ap, size_t _Up, _UInt _Dp, size_t _Sp,
+ _UInt _Bp, size_t _Tp, _UInt _Cp, size_t _Lp, _UInt _Fp>
bool
-operator==(const mersenne_twister_engine<_UI, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
+operator==(const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
_Bp, _Tp, _Cp, _Lp, _Fp>& __x,
- const mersenne_twister_engine<_UI, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
+ const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
_Bp, _Tp, _Cp, _Lp, _Fp>& __y);
-template <class _UI, size_t _Wp, size_t _Np, size_t _Mp, size_t _Rp,
- _UI _Ap, size_t _Up, _UI _Dp, size_t _Sp,
- _UI _Bp, size_t _Tp, _UI _Cp, size_t _Lp, _UI _Fp>
+template <class _UInt, size_t _Wp, size_t _Np, size_t _Mp, size_t _Rp,
+ _UInt _Ap, size_t _Up, _UInt _Dp, size_t _Sp,
+ _UInt _Bp, size_t _Tp, _UInt _Cp, size_t _Lp, _UInt _Fp>
_LIBCPP_INLINE_VISIBILITY
bool
-operator!=(const mersenne_twister_engine<_UI, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
+operator!=(const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
_Bp, _Tp, _Cp, _Lp, _Fp>& __x,
- const mersenne_twister_engine<_UI, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
+ const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
_Bp, _Tp, _Cp, _Lp, _Fp>& __y);
template <class _CharT, class _Traits,
- class _UI, size_t _Wp, size_t _Np, size_t _Mp, size_t _Rp,
- _UI _Ap, size_t _Up, _UI _Dp, size_t _Sp,
- _UI _Bp, size_t _Tp, _UI _Cp, size_t _Lp, _UI _Fp>
+ class _UInt, size_t _Wp, size_t _Np, size_t _Mp, size_t _Rp,
+ _UInt _Ap, size_t _Up, _UInt _Dp, size_t _Sp,
+ _UInt _Bp, size_t _Tp, _UInt _Cp, size_t _Lp, _UInt _Fp>
basic_ostream<_CharT, _Traits>&
operator<<(basic_ostream<_CharT, _Traits>& __os,
- const mersenne_twister_engine<_UI, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
+ const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
_Bp, _Tp, _Cp, _Lp, _Fp>& __x);
template <class _CharT, class _Traits,
- class _UI, size_t _Wp, size_t _Np, size_t _Mp, size_t _Rp,
- _UI _Ap, size_t _Up, _UI _Dp, size_t _Sp,
- _UI _Bp, size_t _Tp, _UI _Cp, size_t _Lp, _UI _Fp>
+ class _UInt, size_t _Wp, size_t _Np, size_t _Mp, size_t _Rp,
+ _UInt _Ap, size_t _Up, _UInt _Dp, size_t _Sp,
+ _UInt _Bp, size_t _Tp, _UInt _Cp, size_t _Lp, _UInt _Fp>
basic_istream<_CharT, _Traits>&
operator>>(basic_istream<_CharT, _Traits>& __is,
- mersenne_twister_engine<_UI, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
+ mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
_Bp, _Tp, _Cp, _Lp, _Fp>& __x);
template <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,
@@ -2129,44 +2131,44 @@ public:
_LIBCPP_INLINE_VISIBILITY
void discard(unsigned long long __z) {for (; __z; --__z) operator()();}
- template <class _UI, size_t _Wp, size_t _Np, size_t _Mp, size_t _Rp,
- _UI _Ap, size_t _Up, _UI _Dp, size_t _Sp,
- _UI _Bp, size_t _Tp, _UI _Cp, size_t _Lp, _UI _Fp>
+ template <class _UInt, size_t _Wp, size_t _Np, size_t _Mp, size_t _Rp,
+ _UInt _Ap, size_t _Up, _UInt _Dp, size_t _Sp,
+ _UInt _Bp, size_t _Tp, _UInt _Cp, size_t _Lp, _UInt _Fp>
friend
bool
- operator==(const mersenne_twister_engine<_UI, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
+ operator==(const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
_Bp, _Tp, _Cp, _Lp, _Fp>& __x,
- const mersenne_twister_engine<_UI, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
+ const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
_Bp, _Tp, _Cp, _Lp, _Fp>& __y);
- template <class _UI, size_t _Wp, size_t _Np, size_t _Mp, size_t _Rp,
- _UI _Ap, size_t _Up, _UI _Dp, size_t _Sp,
- _UI _Bp, size_t _Tp, _UI _Cp, size_t _Lp, _UI _Fp>
+ template <class _UInt, size_t _Wp, size_t _Np, size_t _Mp, size_t _Rp,
+ _UInt _Ap, size_t _Up, _UInt _Dp, size_t _Sp,
+ _UInt _Bp, size_t _Tp, _UInt _Cp, size_t _Lp, _UInt _Fp>
friend
bool
- operator!=(const mersenne_twister_engine<_UI, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
+ operator!=(const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
_Bp, _Tp, _Cp, _Lp, _Fp>& __x,
- const mersenne_twister_engine<_UI, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
+ const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
_Bp, _Tp, _Cp, _Lp, _Fp>& __y);
template <class _CharT, class _Traits,
- class _UI, size_t _Wp, size_t _Np, size_t _Mp, size_t _Rp,
- _UI _Ap, size_t _Up, _UI _Dp, size_t _Sp,
- _UI _Bp, size_t _Tp, _UI _Cp, size_t _Lp, _UI _Fp>
+ class _UInt, size_t _Wp, size_t _Np, size_t _Mp, size_t _Rp,
+ _UInt _Ap, size_t _Up, _UInt _Dp, size_t _Sp,
+ _UInt _Bp, size_t _Tp, _UInt _Cp, size_t _Lp, _UInt _Fp>
friend
basic_ostream<_CharT, _Traits>&
operator<<(basic_ostream<_CharT, _Traits>& __os,
- const mersenne_twister_engine<_UI, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
+ const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
_Bp, _Tp, _Cp, _Lp, _Fp>& __x);
template <class _CharT, class _Traits,
- class _UI, size_t _Wp, size_t _Np, size_t _Mp, size_t _Rp,
- _UI _Ap, size_t _Up, _UI _Dp, size_t _Sp,
- _UI _Bp, size_t _Tp, _UI _Cp, size_t _Lp, _UI _Fp>
+ class _UInt, size_t _Wp, size_t _Np, size_t _Mp, size_t _Rp,
+ _UInt _Ap, size_t _Up, _UInt _Dp, size_t _Sp,
+ _UInt _Bp, size_t _Tp, _UInt _Cp, size_t _Lp, _UInt _Fp>
friend
basic_istream<_CharT, _Traits>&
operator>>(basic_istream<_CharT, _Traits>& __is,
- mersenne_twister_engine<_UI, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
+ mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
_Bp, _Tp, _Cp, _Lp, _Fp>& __x);
private:
@@ -2384,13 +2386,13 @@ mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b,
return __z ^ __rshift<__l>(__z);
}
-template <class _UI, size_t _Wp, size_t _Np, size_t _Mp, size_t _Rp,
- _UI _Ap, size_t _Up, _UI _Dp, size_t _Sp,
- _UI _Bp, size_t _Tp, _UI _Cp, size_t _Lp, _UI _Fp>
+template <class _UInt, size_t _Wp, size_t _Np, size_t _Mp, size_t _Rp,
+ _UInt _Ap, size_t _Up, _UInt _Dp, size_t _Sp,
+ _UInt _Bp, size_t _Tp, _UInt _Cp, size_t _Lp, _UInt _Fp>
bool
-operator==(const mersenne_twister_engine<_UI, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
+operator==(const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
_Bp, _Tp, _Cp, _Lp, _Fp>& __x,
- const mersenne_twister_engine<_UI, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
+ const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
_Bp, _Tp, _Cp, _Lp, _Fp>& __y)
{
if (__x.__i_ == __y.__i_)
@@ -2428,26 +2430,26 @@ operator==(const mersenne_twister_engine<_UI, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp,
__x.__x_ + (_Np - (__y.__i_ + __j)));
}
-template <class _UI, size_t _Wp, size_t _Np, size_t _Mp, size_t _Rp,
- _UI _Ap, size_t _Up, _UI _Dp, size_t _Sp,
- _UI _Bp, size_t _Tp, _UI _Cp, size_t _Lp, _UI _Fp>
+template <class _UInt, size_t _Wp, size_t _Np, size_t _Mp, size_t _Rp,
+ _UInt _Ap, size_t _Up, _UInt _Dp, size_t _Sp,
+ _UInt _Bp, size_t _Tp, _UInt _Cp, size_t _Lp, _UInt _Fp>
inline _LIBCPP_INLINE_VISIBILITY
bool
-operator!=(const mersenne_twister_engine<_UI, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
+operator!=(const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
_Bp, _Tp, _Cp, _Lp, _Fp>& __x,
- const mersenne_twister_engine<_UI, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
+ const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
_Bp, _Tp, _Cp, _Lp, _Fp>& __y)
{
return !(__x == __y);
}
template <class _CharT, class _Traits,
- class _UI, size_t _Wp, size_t _Np, size_t _Mp, size_t _Rp,
- _UI _Ap, size_t _Up, _UI _Dp, size_t _Sp,
- _UI _Bp, size_t _Tp, _UI _Cp, size_t _Lp, _UI _Fp>
+ class _UInt, size_t _Wp, size_t _Np, size_t _Mp, size_t _Rp,
+ _UInt _Ap, size_t _Up, _UInt _Dp, size_t _Sp,
+ _UInt _Bp, size_t _Tp, _UInt _Cp, size_t _Lp, _UInt _Fp>
basic_ostream<_CharT, _Traits>&
operator<<(basic_ostream<_CharT, _Traits>& __os,
- const mersenne_twister_engine<_UI, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
+ const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
_Bp, _Tp, _Cp, _Lp, _Fp>& __x)
{
__save_flags<_CharT, _Traits> __lx(__os);
@@ -2463,17 +2465,17 @@ operator<<(basic_ostream<_CharT, _Traits>& __os,
}
template <class _CharT, class _Traits,
- class _UI, size_t _Wp, size_t _Np, size_t _Mp, size_t _Rp,
- _UI _Ap, size_t _Up, _UI _Dp, size_t _Sp,
- _UI _Bp, size_t _Tp, _UI _Cp, size_t _Lp, _UI _Fp>
+ class _UInt, size_t _Wp, size_t _Np, size_t _Mp, size_t _Rp,
+ _UInt _Ap, size_t _Up, _UInt _Dp, size_t _Sp,
+ _UInt _Bp, size_t _Tp, _UInt _Cp, size_t _Lp, _UInt _Fp>
basic_istream<_CharT, _Traits>&
operator>>(basic_istream<_CharT, _Traits>& __is,
- mersenne_twister_engine<_UI, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
+ mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
_Bp, _Tp, _Cp, _Lp, _Fp>& __x)
{
__save_flags<_CharT, _Traits> __lx(__is);
__is.flags(ios_base::dec | ios_base::skipws);
- _UI __t[_Np];
+ _UInt __t[_Np];
for (size_t __i = 0; __i < _Np; ++__i)
__is >> __t[__i];
if (!__is.fail())
@@ -2501,30 +2503,30 @@ typedef mersenne_twister_engine<uint_fast64_t, 64, 312, 156, 31,
template<class _UIntType, size_t __w, size_t __s, size_t __r>
class _LIBCPP_TEMPLATE_VIS subtract_with_carry_engine;
-template<class _UI, size_t _Wp, size_t _Sp, size_t _Rp>
+template<class _UInt, size_t _Wp, size_t _Sp, size_t _Rp>
bool
operator==(
- const subtract_with_carry_engine<_UI, _Wp, _Sp, _Rp>& __x,
- const subtract_with_carry_engine<_UI, _Wp, _Sp, _Rp>& __y);
+ const subtract_with_carry_engine<_UInt, _Wp, _Sp, _Rp>& __x,
+ const subtract_with_carry_engine<_UInt, _Wp, _Sp, _Rp>& __y);
-template<class _UI, size_t _Wp, size_t _Sp, size_t _Rp>
+template<class _UInt, size_t _Wp, size_t _Sp, size_t _Rp>
_LIBCPP_INLINE_VISIBILITY
bool
operator!=(
- const subtract_with_carry_engine<_UI, _Wp, _Sp, _Rp>& __x,
- const subtract_with_carry_engine<_UI, _Wp, _Sp, _Rp>& __y);
+ const subtract_with_carry_engine<_UInt, _Wp, _Sp, _Rp>& __x,
+ const subtract_with_carry_engine<_UInt, _Wp, _Sp, _Rp>& __y);
template <class _CharT, class _Traits,
- class _UI, size_t _Wp, size_t _Sp, size_t _Rp>
+ class _UInt, size_t _Wp, size_t _Sp, size_t _Rp>
basic_ostream<_CharT, _Traits>&
operator<<(basic_ostream<_CharT, _Traits>& __os,
- const subtract_with_carry_engine<_UI, _Wp, _Sp, _Rp>& __x);
+ const subtract_with_carry_engine<_UInt, _Wp, _Sp, _Rp>& __x);
template <class _CharT, class _Traits,
- class _UI, size_t _Wp, size_t _Sp, size_t _Rp>
+ class _UInt, size_t _Wp, size_t _Sp, size_t _Rp>
basic_istream<_CharT, _Traits>&
operator>>(basic_istream<_CharT, _Traits>& __is,
- subtract_with_carry_engine<_UI, _Wp, _Sp, _Rp>& __x);
+ subtract_with_carry_engine<_UInt, _Wp, _Sp, _Rp>& __x);
template<class _UIntType, size_t __w, size_t __s, size_t __r>
class _LIBCPP_TEMPLATE_VIS subtract_with_carry_engine
@@ -2586,33 +2588,33 @@ public:
_LIBCPP_INLINE_VISIBILITY
void discard(unsigned long long __z) {for (; __z; --__z) operator()();}
- template<class _UI, size_t _Wp, size_t _Sp, size_t _Rp>
+ template<class _UInt, size_t _Wp, size_t _Sp, size_t _Rp>
friend
bool
operator==(
- const subtract_with_carry_engine<_UI, _Wp, _Sp, _Rp>& __x,
- const subtract_with_carry_engine<_UI, _Wp, _Sp, _Rp>& __y);
+ const subtract_with_carry_engine<_UInt, _Wp, _Sp, _Rp>& __x,
+ const subtract_with_carry_engine<_UInt, _Wp, _Sp, _Rp>& __y);
- template<class _UI, size_t _Wp, size_t _Sp, size_t _Rp>
+ template<class _UInt, size_t _Wp, size_t _Sp, size_t _Rp>
friend
bool
operator!=(
- const subtract_with_carry_engine<_UI, _Wp, _Sp, _Rp>& __x,
- const subtract_with_carry_engine<_UI, _Wp, _Sp, _Rp>& __y);
+ const subtract_with_carry_engine<_UInt, _Wp, _Sp, _Rp>& __x,
+ const subtract_with_carry_engine<_UInt, _Wp, _Sp, _Rp>& __y);
template <class _CharT, class _Traits,
- class _UI, size_t _Wp, size_t _Sp, size_t _Rp>
+ class _UInt, size_t _Wp, size_t _Sp, size_t _Rp>
friend
basic_ostream<_CharT, _Traits>&
operator<<(basic_ostream<_CharT, _Traits>& __os,
- const subtract_with_carry_engine<_UI, _Wp, _Sp, _Rp>& __x);
+ const subtract_with_carry_engine<_UInt, _Wp, _Sp, _Rp>& __x);
template <class _CharT, class _Traits,
- class _UI, size_t _Wp, size_t _Sp, size_t _Rp>
+ class _UInt, size_t _Wp, size_t _Sp, size_t _Rp>
friend
basic_istream<_CharT, _Traits>&
operator>>(basic_istream<_CharT, _Traits>& __is,
- subtract_with_carry_engine<_UI, _Wp, _Sp, _Rp>& __x);
+ subtract_with_carry_engine<_UInt, _Wp, _Sp, _Rp>& __x);
private:
@@ -2711,11 +2713,11 @@ subtract_with_carry_engine<_UIntType, __w, __s, __r>::operator()()
return __xr;
}
-template<class _UI, size_t _Wp, size_t _Sp, size_t _Rp>
+template<class _UInt, size_t _Wp, size_t _Sp, size_t _Rp>
bool
operator==(
- const subtract_with_carry_engine<_UI, _Wp, _Sp, _Rp>& __x,
- const subtract_with_carry_engine<_UI, _Wp, _Sp, _Rp>& __y)
+ const subtract_with_carry_engine<_UInt, _Wp, _Sp, _Rp>& __x,
+ const subtract_with_carry_engine<_UInt, _Wp, _Sp, _Rp>& __y)
{
if (__x.__c_ != __y.__c_)
return false;
@@ -2754,21 +2756,21 @@ operator==(
__x.__x_ + (_Rp - (__y.__i_ + __j)));
}
-template<class _UI, size_t _Wp, size_t _Sp, size_t _Rp>
+template<class _UInt, size_t _Wp, size_t _Sp, size_t _Rp>
inline _LIBCPP_INLINE_VISIBILITY
bool
operator!=(
- const subtract_with_carry_engine<_UI, _Wp, _Sp, _Rp>& __x,
- const subtract_with_carry_engine<_UI, _Wp, _Sp, _Rp>& __y)
+ const subtract_with_carry_engine<_UInt, _Wp, _Sp, _Rp>& __x,
+ const subtract_with_carry_engine<_UInt, _Wp, _Sp, _Rp>& __y)
{
return !(__x == __y);
}
template <class _CharT, class _Traits,
- class _UI, size_t _Wp, size_t _Sp, size_t _Rp>
+ class _UInt, size_t _Wp, size_t _Sp, size_t _Rp>
basic_ostream<_CharT, _Traits>&
operator<<(basic_ostream<_CharT, _Traits>& __os,
- const subtract_with_carry_engine<_UI, _Wp, _Sp, _Rp>& __x)
+ const subtract_with_carry_engine<_UInt, _Wp, _Sp, _Rp>& __x)
{
__save_flags<_CharT, _Traits> __lx(__os);
__os.flags(ios_base::dec | ios_base::left);
@@ -2784,14 +2786,14 @@ operator<<(basic_ostream<_CharT, _Traits>& __os,
}
template <class _CharT, class _Traits,
- class _UI, size_t _Wp, size_t _Sp, size_t _Rp>
+ class _UInt, size_t _Wp, size_t _Sp, size_t _Rp>
basic_istream<_CharT, _Traits>&
operator>>(basic_istream<_CharT, _Traits>& __is,
- subtract_with_carry_engine<_UI, _Wp, _Sp, _Rp>& __x)
+ subtract_with_carry_engine<_UInt, _Wp, _Sp, _Rp>& __x)
{
__save_flags<_CharT, _Traits> __lx(__is);
__is.flags(ios_base::dec | ios_base::skipws);
- _UI __t[_Rp+1];
+ _UInt __t[_Rp+1];
for (size_t __i = 0; __i < _Rp+1; ++__i)
__is >> __t[__i];
if (!__is.fail())
@@ -2986,13 +2988,13 @@ typedef discard_block_engine<ranlux48_base, 389, 11> ranlux48;
template<class _Engine, size_t __w, class _UIntType>
class _LIBCPP_TEMPLATE_VIS independent_bits_engine
{
- template <class _UI, _UI _R0, size_t _Wp, size_t _Mp>
+ template <class _UInt, _UInt _R0, size_t _Wp, size_t _Mp>
class __get_n
{
- static _LIBCPP_CONSTEXPR const size_t _Dt = numeric_limits<_UI>::digits;
+ static _LIBCPP_CONSTEXPR const size_t _Dt = numeric_limits<_UInt>::digits;
static _LIBCPP_CONSTEXPR const size_t _Np = _Wp / _Mp + (_Wp % _Mp != 0);
static _LIBCPP_CONSTEXPR const size_t _W0 = _Wp / _Np;
- static _LIBCPP_CONSTEXPR const _UI _Y0 = _W0 >= _Dt ? 0 : (_R0 >> _W0) << _W0;
+ static _LIBCPP_CONSTEXPR const _UInt _Y0 = _W0 >= _Dt ? 0 : (_R0 >> _W0) << _W0;
public:
static _LIBCPP_CONSTEXPR const size_t value = _R0 - _Y0 > _Y0 / _Np ? _Np + 1 : _Np;
};
@@ -3091,33 +3093,33 @@ public:
_LIBCPP_INLINE_VISIBILITY
const _Engine& base() const _NOEXCEPT {return __e_;}
- template<class _Eng, size_t _Wp, class _UI>
+ template<class _Eng, size_t _Wp, class _UInt>
friend
bool
operator==(
- const independent_bits_engine<_Eng, _Wp, _UI>& __x,
- const independent_bits_engine<_Eng, _Wp, _UI>& __y);
+ const independent_bits_engine<_Eng, _Wp, _UInt>& __x,
+ const independent_bits_engine<_Eng, _Wp, _UInt>& __y);
- template<class _Eng, size_t _Wp, class _UI>
+ template<class _Eng, size_t _Wp, class _UInt>
friend
bool
operator!=(
- const independent_bits_engine<_Eng, _Wp, _UI>& __x,
- const independent_bits_engine<_Eng, _Wp, _UI>& __y);
+ const independent_bits_engine<_Eng, _Wp, _UInt>& __x,
+ const independent_bits_engine<_Eng, _Wp, _UInt>& __y);
template <class _CharT, class _Traits,
- class _Eng, size_t _Wp, class _UI>
+ class _Eng, size_t _Wp, class _UInt>
friend
basic_ostream<_CharT, _Traits>&
operator<<(basic_ostream<_CharT, _Traits>& __os,
- const independent_bits_engine<_Eng, _Wp, _UI>& __x);
+ const independent_bits_engine<_Eng, _Wp, _UInt>& __x);
template <class _CharT, class _Traits,
- class _Eng, size_t _Wp, class _UI>
+ class _Eng, size_t _Wp, class _UInt>
friend
basic_istream<_CharT, _Traits>&
operator>>(basic_istream<_CharT, _Traits>& __is,
- independent_bits_engine<_Eng, _Wp, _UI>& __x);
+ independent_bits_engine<_Eng, _Wp, _UInt>& __x);
private:
_LIBCPP_INLINE_VISIBILITY
@@ -3179,40 +3181,40 @@ independent_bits_engine<_Engine, __w, _UIntType>::__eval(true_type)
return _Sp;
}
-template<class _Eng, size_t _Wp, class _UI>
+template<class _Eng, size_t _Wp, class _UInt>
inline _LIBCPP_INLINE_VISIBILITY
bool
operator==(
- const independent_bits_engine<_Eng, _Wp, _UI>& __x,
- const independent_bits_engine<_Eng, _Wp, _UI>& __y)
+ const independent_bits_engine<_Eng, _Wp, _UInt>& __x,
+ const independent_bits_engine<_Eng, _Wp, _UInt>& __y)
{
return __x.base() == __y.base();
}
-template<class _Eng, size_t _Wp, class _UI>
+template<class _Eng, size_t _Wp, class _UInt>
inline _LIBCPP_INLINE_VISIBILITY
bool
operator!=(
- const independent_bits_engine<_Eng, _Wp, _UI>& __x,
- const independent_bits_engine<_Eng, _Wp, _UI>& __y)
+ const independent_bits_engine<_Eng, _Wp, _UInt>& __x,
+ const independent_bits_engine<_Eng, _Wp, _UInt>& __y)
{
return !(__x == __y);
}
template <class _CharT, class _Traits,
- class _Eng, size_t _Wp, class _UI>
+ class _Eng, size_t _Wp, class _UInt>
basic_ostream<_CharT, _Traits>&
operator<<(basic_ostream<_CharT, _Traits>& __os,
- const independent_bits_engine<_Eng, _Wp, _UI>& __x)
+ const independent_bits_engine<_Eng, _Wp, _UInt>& __x)
{
return __os << __x.base();
}
template <class _CharT, class _Traits,
- class _Eng, size_t _Wp, class _UI>
+ class _Eng, size_t _Wp, class _UInt>
basic_istream<_CharT, _Traits>&
operator>>(basic_istream<_CharT, _Traits>& __is,
- independent_bits_engine<_Eng, _Wp, _UI>& __x)
+ independent_bits_engine<_Eng, _Wp, _UInt>& __x)
{
_Eng __e;
__is >> __e;
@@ -6736,4 +6738,6 @@ operator>>(basic_istream<_CharT, _Traits>& __is,
_LIBCPP_END_NAMESPACE_STD
+_LIBCPP_POP_MACROS
+
#endif // _LIBCPP_RANDOM
diff --git a/contrib/libc++/include/ratio b/contrib/libc++/include/ratio
index fa893637d51d..27aa0ded32e6 100644
--- a/contrib/libc++/include/ratio
+++ b/contrib/libc++/include/ratio
@@ -83,12 +83,14 @@ typedef ratio<1000000000000000000000000, 1> yotta; // not supported
#include <climits>
#include <type_traits>
-#include <__undef_min_max>
-
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
#endif
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+
_LIBCPP_BEGIN_NAMESPACE_STD
// __static_gcd
@@ -520,4 +522,6 @@ template <class _R1, class _R2> _LIBCPP_CONSTEXPR bool ratio_greater_equal_v
_LIBCPP_END_NAMESPACE_STD
+_LIBCPP_POP_MACROS
+
#endif // _LIBCPP_RATIO
diff --git a/contrib/libc++/include/regex b/contrib/libc++/include/regex
index 0f49b95a6561..443c2e303465 100644
--- a/contrib/libc++/include/regex
+++ b/contrib/libc++/include/regex
@@ -765,12 +765,14 @@ typedef regex_token_iterator<wstring::const_iterator> wsregex_token_iterator;
#include <vector>
#include <deque>
-#include <__undef_min_max>
-
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
#endif
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+
_LIBCPP_BEGIN_NAMESPACE_STD
namespace regex_constants
@@ -6562,4 +6564,6 @@ regex_replace(const _CharT* __s,
_LIBCPP_END_NAMESPACE_STD
+_LIBCPP_POP_MACROS
+
#endif // _LIBCPP_REGEX
diff --git a/contrib/libc++/include/shared_mutex b/contrib/libc++/include/shared_mutex
index ff36ee6ac67d..9cb81528cd9d 100644
--- a/contrib/libc++/include/shared_mutex
+++ b/contrib/libc++/include/shared_mutex
@@ -125,12 +125,14 @@ template <class Mutex>
#include <__config>
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+
#if _LIBCPP_STD_VER > 11 || defined(_LIBCPP_BUILDING_SHARED_MUTEX)
#include <__mutex_base>
-#include <__undef_min_max>
-
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
#endif
@@ -500,4 +502,6 @@ _LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP_STD_VER > 11
+_LIBCPP_POP_MACROS
+
#endif // _LIBCPP_SHARED_MUTEX
diff --git a/contrib/libc++/include/sstream b/contrib/libc++/include/sstream
index 411374207b4a..b9903f961823 100644
--- a/contrib/libc++/include/sstream
+++ b/contrib/libc++/include/sstream
@@ -175,12 +175,14 @@ typedef basic_stringstream<wchar_t> wstringstream;
#include <istream>
#include <string>
-#include <__undef_min_max>
-
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
#endif
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+
_LIBCPP_BEGIN_NAMESPACE_STD
// basic_stringbuf
@@ -970,4 +972,6 @@ basic_stringstream<_CharT, _Traits, _Allocator>::str(const string_type& __s)
_LIBCPP_END_NAMESPACE_STD
+_LIBCPP_POP_MACROS
+
#endif // _LIBCPP_SSTREAM
diff --git a/contrib/libc++/include/stdexcept b/contrib/libc++/include/stdexcept
index d501d0916085..95a96cc07678 100644
--- a/contrib/libc++/include/stdexcept
+++ b/contrib/libc++/include/stdexcept
@@ -61,9 +61,9 @@ class _LIBCPP_HIDDEN __libcpp_refstring
bool __uses_refcount() const;
public:
- explicit __libcpp_refstring(const char* msg);
- __libcpp_refstring(const __libcpp_refstring& s) _NOEXCEPT;
- __libcpp_refstring& operator=(const __libcpp_refstring& s) _NOEXCEPT;
+ explicit __libcpp_refstring(const char* __msg);
+ __libcpp_refstring(const __libcpp_refstring& __s) _NOEXCEPT;
+ __libcpp_refstring& operator=(const __libcpp_refstring& __s) _NOEXCEPT;
~__libcpp_refstring();
const char* c_str() const _NOEXCEPT {return __imp_;}
diff --git a/contrib/libc++/include/stdio.h b/contrib/libc++/include/stdio.h
index dc534970f9d8..f12417640164 100644
--- a/contrib/libc++/include/stdio.h
+++ b/contrib/libc++/include/stdio.h
@@ -110,10 +110,9 @@ void perror(const char* s);
#ifdef __cplusplus
// snprintf
-#if defined(_LIBCPP_MSVCRT)
+#if defined(_LIBCPP_MSVCRT_LIKE)
extern "C" {
int vasprintf(char **sptr, const char *__restrict fmt, va_list ap);
-int asprintf(char **sptr, const char *__restrict fmt, ...);
}
#endif
diff --git a/contrib/libc++/include/streambuf b/contrib/libc++/include/streambuf
index 12eded5c4d31..a10ce1bf5636 100644
--- a/contrib/libc++/include/streambuf
+++ b/contrib/libc++/include/streambuf
@@ -116,6 +116,9 @@ protected:
#pragma GCC system_header
#endif
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
_LIBCPP_BEGIN_NAMESPACE_STD
template <class _CharT, class _Traits>
@@ -486,4 +489,6 @@ _LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ios<wchar_t
_LIBCPP_END_NAMESPACE_STD
+_LIBCPP_POP_MACROS
+
#endif // _LIBCPP_STEAMBUF
diff --git a/contrib/libc++/include/string b/contrib/libc++/include/string
index af028a023c29..accf1ce27716 100644
--- a/contrib/libc++/include/string
+++ b/contrib/libc++/include/string
@@ -484,14 +484,16 @@ basic_string<char32_t> operator "" s( const char32_t *str, size_t len ); // C++1
#include <cstdint>
#endif
-#include <__undef_min_max>
-
#include <__debug>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
#endif
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+
_LIBCPP_BEGIN_NAMESPACE_STD
// fpos
@@ -899,7 +901,7 @@ public:
void resize(size_type __n, value_type __c);
_LIBCPP_INLINE_VISIBILITY void resize(size_type __n) {resize(__n, value_type());}
- void reserve(size_type res_arg = 0);
+ void reserve(size_type __res_arg = 0);
_LIBCPP_INLINE_VISIBILITY
void shrink_to_fit() _NOEXCEPT {reserve();}
_LIBCPP_INLINE_VISIBILITY
@@ -985,9 +987,9 @@ public:
basic_string& assign(const basic_string& __str) { return *this = __str; }
#ifndef _LIBCPP_CXX03_LANG
_LIBCPP_INLINE_VISIBILITY
- basic_string& assign(basic_string&& str)
+ basic_string& assign(basic_string&& __str)
_NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value))
- {*this = _VSTD::move(str); return *this;}
+ {*this = _VSTD::move(__str); return *this;}
#endif
basic_string& assign(const basic_string& __str, size_type __pos, size_type __n=npos);
template <class _Tp>
@@ -997,7 +999,7 @@ public:
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
basic_string&
>::type
- assign(const _Tp & __t, size_type pos, size_type n=npos);
+ assign(const _Tp & __t, size_type __pos, size_type __n=npos);
basic_string& assign(const value_type* __s, size_type __n);
basic_string& assign(const value_type* __s);
basic_string& assign(size_type __n, value_type __c);
@@ -4041,4 +4043,6 @@ _LIBCPP_EXTERN_TEMPLATE(string operator+<char, char_traits<char>, allocator<char
_LIBCPP_END_NAMESPACE_STD
+_LIBCPP_POP_MACROS
+
#endif // _LIBCPP_STRING
diff --git a/contrib/libc++/include/string_view b/contrib/libc++/include/string_view
index e59f099f16e7..4c759ab5daea 100644
--- a/contrib/libc++/include/string_view
+++ b/contrib/libc++/include/string_view
@@ -166,7 +166,6 @@ namespace std {
*/
#include <__config>
-
#include <__string>
#include <algorithm>
#include <iterator>
@@ -178,6 +177,10 @@ namespace std {
#pragma GCC system_header
#endif
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+
_LIBCPP_BEGIN_NAMESPACE_STD
template<class _CharT, class _Traits = char_traits<_CharT> >
@@ -353,9 +356,9 @@ public:
_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
int compare( size_type __pos1, size_type __n1,
- basic_string_view _sv, size_type __pos2, size_type __n2) const
+ basic_string_view __sv, size_type __pos2, size_type __n2) const
{
- return substr(__pos1, __n1).compare(_sv.substr(__pos2, __n2));
+ return substr(__pos1, __n1).compare(__sv.substr(__pos2, __n2));
}
_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
@@ -784,4 +787,6 @@ inline namespace literals
#endif
_LIBCPP_END_NAMESPACE_STD
+_LIBCPP_POP_MACROS
+
#endif // _LIBCPP_STRING_VIEW
diff --git a/contrib/libc++/include/thread b/contrib/libc++/include/thread
index 360b43d5e555..1b8dca394aa4 100644
--- a/contrib/libc++/include/thread
+++ b/contrib/libc++/include/thread
@@ -105,6 +105,9 @@ void sleep_for(const chrono::duration<Rep, Period>& rel_time);
#pragma GCC system_header
#endif
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
#define __STDCPP_THREADS__ __cplusplus
#ifdef _LIBCPP_HAS_NO_THREADS
@@ -476,4 +479,6 @@ _LIBCPP_END_NAMESPACE_STD
#endif // !_LIBCPP_HAS_NO_THREADS
+_LIBCPP_POP_MACROS
+
#endif // _LIBCPP_THREAD
diff --git a/contrib/libc++/include/tuple b/contrib/libc++/include/tuple
index b869b861cce0..aa4713faf06f 100644
--- a/contrib/libc++/include/tuple
+++ b/contrib/libc++/include/tuple
@@ -169,7 +169,7 @@ void swap(__tuple_leaf<_Ip, _Hp, _Ep>& __x, __tuple_leaf<_Ip, _Hp, _Ep>& __y)
template <size_t _Ip, class _Hp, bool>
class __tuple_leaf
{
- _Hp value;
+ _Hp __value_;
template <class _Tp>
static constexpr bool __can_bind_reference() {
@@ -188,28 +188,28 @@ class __tuple_leaf
__tuple_leaf& operator=(const __tuple_leaf&);
public:
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR __tuple_leaf()
- _NOEXCEPT_(is_nothrow_default_constructible<_Hp>::value) : value()
+ _NOEXCEPT_(is_nothrow_default_constructible<_Hp>::value) : __value_()
{static_assert(!is_reference<_Hp>::value,
"Attempted to default construct a reference element in a tuple");}
template <class _Alloc>
_LIBCPP_INLINE_VISIBILITY
__tuple_leaf(integral_constant<int, 0>, const _Alloc&)
- : value()
+ : __value_()
{static_assert(!is_reference<_Hp>::value,
"Attempted to default construct a reference element in a tuple");}
template <class _Alloc>
_LIBCPP_INLINE_VISIBILITY
__tuple_leaf(integral_constant<int, 1>, const _Alloc& __a)
- : value(allocator_arg_t(), __a)
+ : __value_(allocator_arg_t(), __a)
{static_assert(!is_reference<_Hp>::value,
"Attempted to default construct a reference element in a tuple");}
template <class _Alloc>
_LIBCPP_INLINE_VISIBILITY
__tuple_leaf(integral_constant<int, 2>, const _Alloc& __a)
- : value(__a)
+ : __value_(__a)
{static_assert(!is_reference<_Hp>::value,
"Attempted to default construct a reference element in a tuple");}
@@ -223,28 +223,28 @@ public:
>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
explicit __tuple_leaf(_Tp&& __t) _NOEXCEPT_((is_nothrow_constructible<_Hp, _Tp>::value))
- : value(_VSTD::forward<_Tp>(__t))
+ : __value_(_VSTD::forward<_Tp>(__t))
{static_assert(__can_bind_reference<_Tp>(),
"Attempted to construct a reference element in a tuple with an rvalue");}
template <class _Tp, class _Alloc>
_LIBCPP_INLINE_VISIBILITY
explicit __tuple_leaf(integral_constant<int, 0>, const _Alloc&, _Tp&& __t)
- : value(_VSTD::forward<_Tp>(__t))
+ : __value_(_VSTD::forward<_Tp>(__t))
{static_assert(__can_bind_reference<_Tp>(),
"Attempted to construct a reference element in a tuple with an rvalue");}
template <class _Tp, class _Alloc>
_LIBCPP_INLINE_VISIBILITY
explicit __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a, _Tp&& __t)
- : value(allocator_arg_t(), __a, _VSTD::forward<_Tp>(__t))
+ : __value_(allocator_arg_t(), __a, _VSTD::forward<_Tp>(__t))
{static_assert(!is_reference<_Hp>::value,
"Attempted to uses-allocator construct a reference element in a tuple");}
template <class _Tp, class _Alloc>
_LIBCPP_INLINE_VISIBILITY
explicit __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a, _Tp&& __t)
- : value(_VSTD::forward<_Tp>(__t), __a)
+ : __value_(_VSTD::forward<_Tp>(__t), __a)
{static_assert(!is_reference<_Hp>::value,
"Attempted to uses-allocator construct a reference element in a tuple");}
@@ -256,7 +256,7 @@ public:
__tuple_leaf&
operator=(_Tp&& __t) _NOEXCEPT_((is_nothrow_assignable<_Hp&, _Tp>::value))
{
- value = _VSTD::forward<_Tp>(__t);
+ __value_ = _VSTD::forward<_Tp>(__t);
return *this;
}
@@ -267,8 +267,8 @@ public:
return 0;
}
- _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 _Hp& get() _NOEXCEPT {return value;}
- _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const _Hp& get() const _NOEXCEPT {return value;}
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 _Hp& get() _NOEXCEPT {return __value_;}
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const _Hp& get() const _NOEXCEPT {return __value_;}
};
template <size_t _Ip, class _Hp>
@@ -473,9 +473,9 @@ struct _LIBCPP_DECLSPEC_EMPTY_BASES __tuple_impl<__tuple_indices<_Indx...>, _Tp.
template <class ..._Tp>
class _LIBCPP_TEMPLATE_VIS tuple
{
- typedef __tuple_impl<typename __make_tuple_indices<sizeof...(_Tp)>::type, _Tp...> base;
+ typedef __tuple_impl<typename __make_tuple_indices<sizeof...(_Tp)>::type, _Tp...> _BaseT;
- base base_;
+ _BaseT __base_;
#if defined(_LIBCPP_ENABLE_TUPLE_IMPLICIT_REDUCED_ARITY_EXTENSION)
static constexpr bool _EnableImplicitReducedArityExtension = true;
@@ -628,7 +628,7 @@ public:
>::type>
_LIBCPP_INLINE_VISIBILITY
tuple(_AllocArgT, _Alloc const& __a)
- : base_(allocator_arg_t(), __a,
+ : __base_(allocator_arg_t(), __a,
__tuple_indices<>(), __tuple_types<>(),
typename __make_tuple_indices<sizeof...(_Tp), 0>::type(),
__tuple_types<_Tp...>()) {}
@@ -644,7 +644,7 @@ public:
>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
tuple(const _Tp& ... __t) _NOEXCEPT_((__all<is_nothrow_copy_constructible<_Tp>::value...>::value))
- : base_(typename __make_tuple_indices<sizeof...(_Tp)>::type(),
+ : __base_(typename __make_tuple_indices<sizeof...(_Tp)>::type(),
typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
typename __make_tuple_indices<0>::type(),
typename __make_tuple_types<tuple, 0>::type(),
@@ -662,7 +662,7 @@ public:
>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
explicit tuple(const _Tp& ... __t) _NOEXCEPT_((__all<is_nothrow_copy_constructible<_Tp>::value...>::value))
- : base_(typename __make_tuple_indices<sizeof...(_Tp)>::type(),
+ : __base_(typename __make_tuple_indices<sizeof...(_Tp)>::type(),
typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
typename __make_tuple_indices<0>::type(),
typename __make_tuple_types<tuple, 0>::type(),
@@ -680,7 +680,7 @@ public:
>
_LIBCPP_INLINE_VISIBILITY
tuple(allocator_arg_t, const _Alloc& __a, const _Tp& ... __t)
- : base_(allocator_arg_t(), __a,
+ : __base_(allocator_arg_t(), __a,
typename __make_tuple_indices<sizeof...(_Tp)>::type(),
typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
typename __make_tuple_indices<0>::type(),
@@ -700,7 +700,7 @@ public:
_LIBCPP_INLINE_VISIBILITY
explicit
tuple(allocator_arg_t, const _Alloc& __a, const _Tp& ... __t)
- : base_(allocator_arg_t(), __a,
+ : __base_(allocator_arg_t(), __a,
typename __make_tuple_indices<sizeof...(_Tp)>::type(),
typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
typename __make_tuple_indices<0>::type(),
@@ -727,7 +727,7 @@ public:
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
tuple(_Up&&... __u)
_NOEXCEPT_((
- is_nothrow_constructible<base,
+ is_nothrow_constructible<_BaseT,
typename __make_tuple_indices<sizeof...(_Up)>::type,
typename __make_tuple_types<tuple, sizeof...(_Up)>::type,
typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type,
@@ -735,7 +735,7 @@ public:
_Up...
>::value
))
- : base_(typename __make_tuple_indices<sizeof...(_Up)>::type(),
+ : __base_(typename __make_tuple_indices<sizeof...(_Up)>::type(),
typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
@@ -760,7 +760,7 @@ public:
explicit
tuple(_Up&&... __u)
_NOEXCEPT_((
- is_nothrow_constructible<base,
+ is_nothrow_constructible<_BaseT,
typename __make_tuple_indices<sizeof...(_Up)>::type,
typename __make_tuple_types<tuple, sizeof...(_Up)>::type,
typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type,
@@ -768,7 +768,7 @@ public:
_Up...
>::value
))
- : base_(typename __make_tuple_indices<sizeof...(_Up)>::type(),
+ : __base_(typename __make_tuple_indices<sizeof...(_Up)>::type(),
typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
@@ -786,7 +786,7 @@ public:
>
_LIBCPP_INLINE_VISIBILITY
tuple(allocator_arg_t, const _Alloc& __a, _Up&&... __u)
- : base_(allocator_arg_t(), __a,
+ : __base_(allocator_arg_t(), __a,
typename __make_tuple_indices<sizeof...(_Up)>::type(),
typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
@@ -806,7 +806,7 @@ public:
_LIBCPP_INLINE_VISIBILITY
explicit
tuple(allocator_arg_t, const _Alloc& __a, _Up&&... __u)
- : base_(allocator_arg_t(), __a,
+ : __base_(allocator_arg_t(), __a,
typename __make_tuple_indices<sizeof...(_Up)>::type(),
typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
@@ -824,8 +824,8 @@ public:
>::type = false
>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
- tuple(_Tuple&& __t) _NOEXCEPT_((is_nothrow_constructible<base, _Tuple>::value))
- : base_(_VSTD::forward<_Tuple>(__t)) {}
+ tuple(_Tuple&& __t) _NOEXCEPT_((is_nothrow_constructible<_BaseT, _Tuple>::value))
+ : __base_(_VSTD::forward<_Tuple>(__t)) {}
template <class _Tuple,
typename enable_if
@@ -839,8 +839,8 @@ public:
>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
explicit
- tuple(_Tuple&& __t) _NOEXCEPT_((is_nothrow_constructible<base, _Tuple>::value))
- : base_(_VSTD::forward<_Tuple>(__t)) {}
+ tuple(_Tuple&& __t) _NOEXCEPT_((is_nothrow_constructible<_BaseT, _Tuple>::value))
+ : __base_(_VSTD::forward<_Tuple>(__t)) {}
template <class _Alloc, class _Tuple,
typename enable_if
@@ -853,7 +853,7 @@ public:
>
_LIBCPP_INLINE_VISIBILITY
tuple(allocator_arg_t, const _Alloc& __a, _Tuple&& __t)
- : base_(allocator_arg_t(), __a, _VSTD::forward<_Tuple>(__t)) {}
+ : __base_(allocator_arg_t(), __a, _VSTD::forward<_Tuple>(__t)) {}
template <class _Alloc, class _Tuple,
typename enable_if
@@ -867,7 +867,7 @@ public:
_LIBCPP_INLINE_VISIBILITY
explicit
tuple(allocator_arg_t, const _Alloc& __a, _Tuple&& __t)
- : base_(allocator_arg_t(), __a, _VSTD::forward<_Tuple>(__t)) {}
+ : __base_(allocator_arg_t(), __a, _VSTD::forward<_Tuple>(__t)) {}
using _CanCopyAssign = __all<is_copy_assignable<_Tp>::value...>;
using _CanMoveAssign = __all<is_move_assignable<_Tp>::value...>;
@@ -876,7 +876,7 @@ public:
tuple& operator=(typename conditional<_CanCopyAssign::value, tuple, __nat>::type const& __t)
_NOEXCEPT_((__all<is_nothrow_copy_assignable<_Tp>::value...>::value))
{
- base_.operator=(__t.base_);
+ __base_.operator=(__t.__base_);
return *this;
}
@@ -884,7 +884,7 @@ public:
tuple& operator=(typename conditional<_CanMoveAssign::value, tuple, __nat>::type&& __t)
_NOEXCEPT_((__all<is_nothrow_move_assignable<_Tp>::value...>::value))
{
- base_.operator=(static_cast<base&&>(__t.base_));
+ __base_.operator=(static_cast<_BaseT&&>(__t.__base_));
return *this;
}
@@ -896,15 +896,15 @@ public:
>
_LIBCPP_INLINE_VISIBILITY
tuple&
- operator=(_Tuple&& __t) _NOEXCEPT_((is_nothrow_assignable<base&, _Tuple>::value))
+ operator=(_Tuple&& __t) _NOEXCEPT_((is_nothrow_assignable<_BaseT&, _Tuple>::value))
{
- base_.operator=(_VSTD::forward<_Tuple>(__t));
+ __base_.operator=(_VSTD::forward<_Tuple>(__t));
return *this;
}
_LIBCPP_INLINE_VISIBILITY
void swap(tuple& __t) _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
- {base_.swap(__t.base_);}
+ {__base_.swap(__t.__base_);}
};
template <>
@@ -948,7 +948,7 @@ typename tuple_element<_Ip, tuple<_Tp...> >::type&
get(tuple<_Tp...>& __t) _NOEXCEPT
{
typedef typename tuple_element<_Ip, tuple<_Tp...> >::type type;
- return static_cast<__tuple_leaf<_Ip, type>&>(__t.base_).get();
+ return static_cast<__tuple_leaf<_Ip, type>&>(__t.__base_).get();
}
template <size_t _Ip, class ..._Tp>
@@ -957,7 +957,7 @@ const typename tuple_element<_Ip, tuple<_Tp...> >::type&
get(const tuple<_Tp...>& __t) _NOEXCEPT
{
typedef typename tuple_element<_Ip, tuple<_Tp...> >::type type;
- return static_cast<const __tuple_leaf<_Ip, type>&>(__t.base_).get();
+ return static_cast<const __tuple_leaf<_Ip, type>&>(__t.__base_).get();
}
template <size_t _Ip, class ..._Tp>
@@ -967,7 +967,7 @@ get(tuple<_Tp...>&& __t) _NOEXCEPT
{
typedef typename tuple_element<_Ip, tuple<_Tp...> >::type type;
return static_cast<type&&>(
- static_cast<__tuple_leaf<_Ip, type>&&>(__t.base_).get());
+ static_cast<__tuple_leaf<_Ip, type>&&>(__t.__base_).get());
}
template <size_t _Ip, class ..._Tp>
@@ -977,7 +977,7 @@ get(const tuple<_Tp...>&& __t) _NOEXCEPT
{
typedef typename tuple_element<_Ip, tuple<_Tp...> >::type type;
return static_cast<const type&&>(
- static_cast<const __tuple_leaf<_Ip, type>&&>(__t.base_).get());
+ static_cast<const __tuple_leaf<_Ip, type>&&>(__t.__base_).get());
}
#if _LIBCPP_STD_VER > 11
diff --git a/contrib/libc++/include/valarray b/contrib/libc++/include/valarray
index f8e19acdb719..ee61238a932f 100644
--- a/contrib/libc++/include/valarray
+++ b/contrib/libc++/include/valarray
@@ -347,12 +347,14 @@ template <class T> unspecified2 end(const valarray<T>& v);
#include <functional>
#include <new>
-#include <__undef_min_max>
-
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
#endif
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+
_LIBCPP_BEGIN_NAMESPACE_STD
template<class _Tp> class _LIBCPP_TEMPLATE_VIS valarray;
@@ -4865,4 +4867,6 @@ end(const valarray<_Tp>& __v)
_LIBCPP_END_NAMESPACE_STD
+_LIBCPP_POP_MACROS
+
#endif // _LIBCPP_VALARRAY
diff --git a/contrib/libc++/include/vector b/contrib/libc++/include/vector
index 6759dbd8a584..ee19fb7081a2 100644
--- a/contrib/libc++/include/vector
+++ b/contrib/libc++/include/vector
@@ -275,14 +275,16 @@ void swap(vector<T,Allocator>& x, vector<T,Allocator>& y)
#include <__split_buffer>
#include <__functional_base>
-#include <__undef_min_max>
-
#include <__debug>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
#endif
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+
_LIBCPP_BEGIN_NAMESPACE_STD
template <bool>
@@ -3357,4 +3359,6 @@ swap(vector<_Tp, _Allocator>& __x, vector<_Tp, _Allocator>& __y)
_LIBCPP_END_NAMESPACE_STD
+_LIBCPP_POP_MACROS
+
#endif // _LIBCPP_VECTOR
diff --git a/contrib/libc++/include/wchar.h b/contrib/libc++/include/wchar.h
index 25a318faff25..a5666e193a5b 100644
--- a/contrib/libc++/include/wchar.h
+++ b/contrib/libc++/include/wchar.h
@@ -166,7 +166,7 @@ inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_PREFERRED_OVERLOAD
}
#endif
-#if defined(__cplusplus) && defined(_LIBCPP_MSVCRT)
+#if defined(__cplusplus) && defined(_LIBCPP_MSVCRT_LIKE)
extern "C" {
size_t mbsnrtowcs(wchar_t *__restrict dst, const char **__restrict src,
size_t nmc, size_t len, mbstate_t *__restrict ps);
diff --git a/contrib/libc++/src/chrono.cpp b/contrib/libc++/src/chrono.cpp
index 9b277a610cd2..d0e184ad32fb 100644
--- a/contrib/libc++/src/chrono.cpp
+++ b/contrib/libc++/src/chrono.cpp
@@ -37,7 +37,7 @@
#if defined(_LIBCPP_WIN32API)
#define WIN32_LEAN_AND_MEAN
#define VC_EXTRA_LEAN
-#include <Windows.h>
+#include <windows.h>
#if _WIN32_WINNT >= _WIN32_WINNT_WIN8
#include <winapifamily.h>
#endif
diff --git a/contrib/libc++/src/condition_variable.cpp b/contrib/libc++/src/condition_variable.cpp
index 3f607271b9eb..2200aefb804d 100644
--- a/contrib/libc++/src/condition_variable.cpp
+++ b/contrib/libc++/src/condition_variable.cpp
@@ -14,6 +14,7 @@
#include "condition_variable"
#include "thread"
#include "system_error"
+#include "__undef_macros"
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/contrib/libc++/src/ios.cpp b/contrib/libc++/src/ios.cpp
index 7c76ca258b26..0f1d88e378f5 100644
--- a/contrib/libc++/src/ios.cpp
+++ b/contrib/libc++/src/ios.cpp
@@ -22,6 +22,7 @@
#include "new"
#include "streambuf"
#include "string"
+#include "__undef_macros"
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/contrib/libc++/src/locale.cpp b/contrib/libc++/src/locale.cpp
index 4163c2c0af65..3d61fbede58a 100644
--- a/contrib/libc++/src/locale.cpp
+++ b/contrib/libc++/src/locale.cpp
@@ -36,6 +36,7 @@
#endif
#include <stdlib.h>
#include <stdio.h>
+#include "__undef_macros"
// On Linux, wint_t and wchar_t have different signed-ness, and this causes
// lots of noise in the build log, but no bugs that I know of.
diff --git a/contrib/libc++/src/mutex.cpp b/contrib/libc++/src/mutex.cpp
index b858e8877ae5..c36bd5549da8 100644
--- a/contrib/libc++/src/mutex.cpp
+++ b/contrib/libc++/src/mutex.cpp
@@ -12,6 +12,7 @@
#include "limits"
#include "system_error"
#include "include/atomic_support.h"
+#include "__undef_macros"
_LIBCPP_BEGIN_NAMESPACE_STD
#ifndef _LIBCPP_HAS_NO_THREADS
diff --git a/contrib/libc++/src/new.cpp b/contrib/libc++/src/new.cpp
index 21b30740196b..2b2682fa6617 100644
--- a/contrib/libc++/src/new.cpp
+++ b/contrib/libc++/src/new.cpp
@@ -183,7 +183,7 @@ operator new(std::size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC
if (static_cast<size_t>(alignment) < sizeof(void*))
alignment = std::align_val_t(sizeof(void*));
void* p;
-#if defined(_LIBCPP_MSVCRT)
+#if defined(_LIBCPP_MSVCRT_LIKE)
while ((p = _aligned_malloc(size, static_cast<size_t>(alignment))) == nullptr)
#else
while (::posix_memalign(&p, static_cast<size_t>(alignment), size) != 0)
@@ -256,7 +256,7 @@ void
operator delete(void* ptr, std::align_val_t) _NOEXCEPT
{
if (ptr)
-#if defined(_LIBCPP_MSVCRT)
+#if defined(_LIBCPP_MSVCRT_LIKE)
::_aligned_free(ptr);
#else
::free(ptr);
diff --git a/contrib/libc++/src/strstream.cpp b/contrib/libc++/src/strstream.cpp
index be94f9c89e83..01523cf45462 100644
--- a/contrib/libc++/src/strstream.cpp
+++ b/contrib/libc++/src/strstream.cpp
@@ -13,6 +13,7 @@
#include "cstring"
#include "cstdlib"
#include "__debug"
+#include "__undef_macros"
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/contrib/libc++/src/system_error.cpp b/contrib/libc++/src/system_error.cpp
index cbbbb5dcd15c..17f2c9a5ba79 100644
--- a/contrib/libc++/src/system_error.cpp
+++ b/contrib/libc++/src/system_error.cpp
@@ -65,7 +65,7 @@ constexpr size_t strerror_buff_size = 1024;
string do_strerror_r(int ev);
-#if defined(_LIBCPP_MSVCRT)
+#if defined(_LIBCPP_MSVCRT_LIKE)
string do_strerror_r(int ev) {
char buffer[strerror_buff_size];
if (::strerror_s(buffer, strerror_buff_size, ev) == 0)
diff --git a/contrib/libc++/src/thread.cpp b/contrib/libc++/src/thread.cpp
index 412a8fa0a620..550da8ea71f3 100644
--- a/contrib/libc++/src/thread.cpp
+++ b/contrib/libc++/src/thread.cpp
@@ -34,7 +34,7 @@
#if defined(_LIBCPP_WIN32API)
#include <windows.h>
-#endif // defined(_LIBCPP_WIN32API)
+#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/contrib/llvm/include/llvm/Analysis/TargetTransformInfo.h b/contrib/llvm/include/llvm/Analysis/TargetTransformInfo.h
index 6cbe3a1f515e..7211508e975a 100644
--- a/contrib/llvm/include/llvm/Analysis/TargetTransformInfo.h
+++ b/contrib/llvm/include/llvm/Analysis/TargetTransformInfo.h
@@ -454,6 +454,9 @@ public:
/// \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;
@@ -828,6 +831,7 @@ public:
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,
@@ -1047,6 +1051,9 @@ public:
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();
}
diff --git a/contrib/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h b/contrib/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h
index ad1a7cb748fe..d73a60eba850 100644
--- a/contrib/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h
+++ b/contrib/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h
@@ -274,6 +274,8 @@ public:
bool enableAggressiveInterleaving(bool LoopHasReductions) { return false; }
+ bool expandMemCmp(Instruction *I, unsigned &MaxLoadSize) { return false; }
+
bool enableInterleavedAccessVectorization() { return false; }
bool isFPVectorizationPotentiallyUnsafe() { return false; }
diff --git a/contrib/llvm/include/llvm/Analysis/ValueTracking.h b/contrib/llvm/include/llvm/Analysis/ValueTracking.h
index b1ee76159c4b..612779b1ce86 100644
--- a/contrib/llvm/include/llvm/Analysis/ValueTracking.h
+++ b/contrib/llvm/include/llvm/Analysis/ValueTracking.h
@@ -85,6 +85,8 @@ 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. For pointers, if the context instruction and dominator tree are
diff --git a/contrib/llvm/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h b/contrib/llvm/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h
index f32233b3a9e4..e3549d8988cd 100644
--- a/contrib/llvm/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h
+++ b/contrib/llvm/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h
@@ -396,7 +396,7 @@ protected:
mutable DenseMap<unsigned, std::unique_ptr<const InstructionMapping>>
MapOfInstructionMappings;
- /// Create a RegisterBankInfo that can accomodate up to \p NumRegBanks
+ /// Create a RegisterBankInfo that can accommodate up to \p NumRegBanks
/// RegisterBank instances.
RegisterBankInfo(RegisterBank **RegBanks, unsigned NumRegBanks);
diff --git a/contrib/llvm/include/llvm/CodeGen/ISDOpcodes.h b/contrib/llvm/include/llvm/CodeGen/ISDOpcodes.h
index 2300a106c358..bc5d2353f63e 100644
--- a/contrib/llvm/include/llvm/CodeGen/ISDOpcodes.h
+++ b/contrib/llvm/include/llvm/CodeGen/ISDOpcodes.h
@@ -410,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
diff --git a/contrib/llvm/include/llvm/CodeGen/MIRYamlMapping.h b/contrib/llvm/include/llvm/CodeGen/MIRYamlMapping.h
index 47b40de6fe1f..30e88fe38ac3 100644
--- a/contrib/llvm/include/llvm/CodeGen/MIRYamlMapping.h
+++ b/contrib/llvm/include/llvm/CodeGen/MIRYamlMapping.h
@@ -381,7 +381,6 @@ struct MachineFunction {
StringRef Name;
unsigned Alignment = 0;
bool ExposesReturnsTwice = false;
- bool NoVRegs;
// GISel MachineFunctionProperties.
bool Legalized = false;
bool RegBankSelected = false;
@@ -406,7 +405,6 @@ template <> struct MappingTraits<MachineFunction> {
YamlIO.mapRequired("name", MF.Name);
YamlIO.mapOptional("alignment", MF.Alignment);
YamlIO.mapOptional("exposesReturnsTwice", MF.ExposesReturnsTwice);
- YamlIO.mapOptional("noVRegs", MF.NoVRegs);
YamlIO.mapOptional("legalized", MF.Legalized);
YamlIO.mapOptional("regBankSelected", MF.RegBankSelected);
YamlIO.mapOptional("selected", MF.Selected);
diff --git a/contrib/llvm/include/llvm/CodeGen/MachineBasicBlock.h b/contrib/llvm/include/llvm/CodeGen/MachineBasicBlock.h
index 8da48c379d00..26ed8bb487a2 100644
--- a/contrib/llvm/include/llvm/CodeGen/MachineBasicBlock.h
+++ b/contrib/llvm/include/llvm/CodeGen/MachineBasicBlock.h
@@ -335,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;
diff --git a/contrib/llvm/include/llvm/CodeGen/MachineConstantPool.h b/contrib/llvm/include/llvm/CodeGen/MachineConstantPool.h
index d2036c4a29a5..1705a0f7e59b 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/MachineFunction.h b/contrib/llvm/include/llvm/CodeGen/MachineFunction.h
index 5859a4e61fdd..10125864cd90 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/DenseMap.h"
+#include "llvm/ADT/GraphTraits.h"
#include "llvm/ADT/ilist.h"
+#include "llvm/ADT/iterator.h"
#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.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.
@@ -487,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
@@ -499,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
@@ -507,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
@@ -518,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
@@ -528,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::*
@@ -590,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;
@@ -610,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);
@@ -623,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.
@@ -653,7 +661,7 @@ public:
MachineMemOperand *getMachineMemOperand(const MachineMemOperand *MMO,
int64_t Offset, uint64_t Size);
- typedef ArrayRecycler<MachineOperand>::Capacity OperandCapacity;
+ using OperandCapacity = ArrayRecycler<MachineOperand>::Capacity;
/// Allocate an array of MachineOperands. This is only intended for use by
/// internal MachineInstr functions.
@@ -700,7 +708,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
@@ -858,13 +865,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*> :
@@ -872,37 +882,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
index c644c9783e2f..0fbcb480b1ab 100644
--- a/contrib/llvm/include/llvm/CodeGen/MachineFunctionInitializer.h
+++ b/contrib/llvm/include/llvm/CodeGen/MachineFunctionInitializer.h
@@ -1,4 +1,4 @@
-//===- MachineFunctionInitializer.h - machine function initializer ---------===//
+//=- MachineFunctionInitializer.h - machine function initializer --*- C++ -*-=//
//
// The LLVM Compiler Infrastructure
//
@@ -25,7 +25,7 @@ class MachineFunctionInitializer {
virtual void anchor();
public:
- virtual ~MachineFunctionInitializer() {}
+ virtual ~MachineFunctionInitializer() = default;
/// Initialize the machine function.
///
@@ -35,4 +35,4 @@ public:
} // end namespace llvm
-#endif
+#endif // LLVM_CODEGEN_MACHINEFUNCTIONINITIALIZER_H
diff --git a/contrib/llvm/include/llvm/CodeGen/MachineInstr.h b/contrib/llvm/include/llvm/CodeGen/MachineInstr.h
index 8d040beff7a6..95401e98b297 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; }
@@ -713,7 +718,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 +771,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 +780,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 +793,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;
}
@@ -978,7 +993,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.
@@ -987,7 +1001,6 @@ public:
///
/// Returns NULL if the static register class constraint cannot be
/// determined.
- ///
const TargetRegisterClass*
getRegClassConstraint(unsigned OpIdx,
const TargetInstrInfo *TII,
@@ -1328,6 +1341,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/MachineInstrBundleIterator.h b/contrib/llvm/include/llvm/CodeGen/MachineInstrBundleIterator.h
index 3104185385ea..5fe4964ff116 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 5c814f22f99b..58cffaade9d2 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 {
@@ -71,6 +73,7 @@ public:
private:
friend class LoopInfoBase<MachineBasicBlock, MachineLoop>;
+
explicit MachineLoop(MachineBasicBlock *MBB)
: LoopBase<MachineBasicBlock, MachineLoop>(MBB) {}
};
@@ -79,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
@@ -91,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; }
@@ -103,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(); }
@@ -166,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(); }
@@ -178,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/MachineModuleInfo.h b/contrib/llvm/include/llvm/CodeGen/MachineModuleInfo.h
index f46ef41879d1..d4ac58c3bd22 100644
--- a/contrib/llvm/include/llvm/CodeGen/MachineModuleInfo.h
+++ b/contrib/llvm/include/llvm/CodeGen/MachineModuleInfo.h
@@ -31,35 +31,26 @@
#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 +60,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>&);
@@ -252,6 +244,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/Passes.h b/contrib/llvm/include/llvm/CodeGen/Passes.h
index f3e04cffcda6..3bcfc1c4254b 100644
--- a/contrib/llvm/include/llvm/CodeGen/Passes.h
+++ b/contrib/llvm/include/llvm/CodeGen/Passes.h
@@ -133,6 +133,10 @@ 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;
diff --git a/contrib/llvm/include/llvm/CodeGen/TargetPassConfig.h b/contrib/llvm/include/llvm/CodeGen/TargetPassConfig.h
index f0c826dc1d45..fcf1937c186e 100644
--- a/contrib/llvm/include/llvm/CodeGen/TargetPassConfig.h
+++ b/contrib/llvm/include/llvm/CodeGen/TargetPassConfig.h
@@ -22,7 +22,7 @@ namespace llvm {
class PassConfigImpl;
class ScheduleDAGInstrs;
-class TargetMachine;
+class LLVMTargetMachine;
struct MachineSchedContext;
// The old pass manager infrastructure is hidden in a legacy namespace now.
@@ -103,7 +103,7 @@ private:
bool AddingMachinePasses;
protected:
- TargetMachine *TM;
+ LLVMTargetMachine *TM;
PassConfigImpl *Impl; // Internal data structures
bool Initialized; // Flagged after all passes are configured.
@@ -120,7 +120,7 @@ protected:
bool RequireCodeGenSCCOrder;
public:
- TargetPassConfig(TargetMachine *tm, PassManagerBase &pm);
+ TargetPassConfig(LLVMTargetMachine &TM, PassManagerBase &pm);
// Dummy constructor.
TargetPassConfig();
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/CodeView.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/CodeView.h
index 3316e71916ed..4e8c8feb7a12 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
@@ -22,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) \
@@ -280,7 +284,7 @@ CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(MethodOptions)
/// Equivalent to CV_LABEL_TYPE_e.
enum class LabelType : uint16_t {
Near = 0x0,
- Far = 0x4,
+ Far = 0x4,
};
/// Equivalent to CV_modifier_t.
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/CVSymbolTypes.def b/contrib/llvm/include/llvm/DebugInfo/CodeView/CodeViewSymbols.def
index 32813d861d90..32813d861d90 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 8c193bb13cb7..8c193bb13cb7 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeRecords.def
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/CodeViewTypes.def
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolDeserializer.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolDeserializer.h
index c1a5152930ff..428ff153d5d1 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolDeserializer.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolDeserializer.h
@@ -34,6 +34,17 @@ class SymbolDeserializer : public SymbolVisitorCallbacks {
};
public:
+ template <typename T> static Error deserializeAs(CVSymbol Symbol, T &Record) {
+ SymbolDeserializer S(nullptr);
+ 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)
: Delegate(Delegate) {}
@@ -54,7 +65,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) {
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolRecord.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolRecord.h
index c5a5549bf818..a3e4dff647bd 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolRecord.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolRecord.h
@@ -35,8 +35,6 @@ protected:
public:
SymbolRecordKind getKind() const { return Kind; }
-
-private:
SymbolRecordKind Kind;
};
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolRecordMapping.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolRecordMapping.h
index 0a1837a0d935..5d072a3b2723 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolRecordMapping.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolRecordMapping.h
@@ -29,7 +29,7 @@ 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;
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolSerializer.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolSerializer.h
index f2e99bd83326..a8fe1a3ae1d0 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolSerializer.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolSerializer.h
@@ -45,6 +45,17 @@ class SymbolSerializer : public SymbolVisitorCallbacks {
}
public:
+ template <typename SymType>
+ static CVSymbol writeOneSymbol(SymType &Sym, BumpPtrAllocator &Storage) {
+ CVSymbol Result;
+ Result.Type = static_cast<SymbolKind>(Sym.Kind);
+ SymbolSerializer Serializer(Storage);
+ consumeError(Serializer.visitSymbolBegin(Result));
+ consumeError(Serializer.visitKnownRecord(Result, Sym));
+ consumeError(Serializer.visitSymbolEnd(Result));
+ return Result;
+ }
+
explicit SymbolSerializer(BumpPtrAllocator &Storage);
virtual Error visitSymbolBegin(CVSymbol &Record) override;
@@ -55,7 +66,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 RecordKind>
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolVisitorCallbackPipeline.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolVisitorCallbackPipeline.h
index 96a93bf7e576..5f4205bd6e08 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolVisitorCallbackPipeline.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolVisitorCallbackPipeline.h
@@ -59,7 +59,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 aaa9d2e85e13..2ef7eabdaa9d 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h
@@ -39,7 +39,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/TypeDatabaseVisitor.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeDatabaseVisitor.h
index c064e19a7e90..77dbc91a7d38 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeDatabaseVisitor.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeDatabaseVisitor.h
@@ -39,7 +39,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:
StringRef getTypeName(TypeIndex Index) const;
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeDeserializer.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeDeserializer.h
index a9c5cf42fc5b..965cdfd85f48 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeDeserializer.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeDeserializer.h
@@ -41,6 +41,7 @@ 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;
@@ -75,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>
@@ -127,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 65b3a33e6548..afb8b3636361 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeDumpVisitor.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeDumpVisitor.h
@@ -58,7 +58,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:
void printMemberAttributes(MemberAttributes Attrs);
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeRecord.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeRecord.h
index 92745ebfcded..3a64a437aa4d 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeRecord.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeRecord.h
@@ -123,13 +123,13 @@ 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),
@@ -145,6 +145,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,
@@ -169,6 +170,7 @@ public:
// LF_MFUNCTION
class MemberFunctionRecord : public TypeRecord {
public:
+ MemberFunctionRecord() = default;
explicit MemberFunctionRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
MemberFunctionRecord(TypeIndex ReturnType, TypeIndex ClassType,
@@ -203,6 +205,7 @@ public:
// LF_LABEL
class LabelRecord : public TypeRecord {
public:
+ LabelRecord() = default;
explicit LabelRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
LabelRecord(LabelType Mode) : TypeRecord(TypeRecordKind::Label), Mode(Mode) {}
@@ -213,6 +216,7 @@ public:
// LF_MFUNC_ID
class MemberFuncIdRecord : public TypeRecord {
public:
+ MemberFuncIdRecord() = default;
explicit MemberFuncIdRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
MemberFuncIdRecord(TypeIndex ClassType, TypeIndex FunctionType,
StringRef Name)
@@ -230,6 +234,7 @@ public:
// LF_ARGLIST
class ArgListRecord : public TypeRecord {
public:
+ ArgListRecord() = default;
explicit ArgListRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
ArgListRecord(TypeRecordKind Kind, ArrayRef<TypeIndex> Indices)
@@ -243,6 +248,7 @@ public:
// LF_SUBSTR_LIST
class StringListRecord : public TypeRecord {
public:
+ StringListRecord() = default;
explicit StringListRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
StringListRecord(TypeRecordKind Kind, ArrayRef<TypeIndex> Indices)
@@ -267,6 +273,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)
@@ -341,6 +348,7 @@ 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) {}
@@ -355,6 +363,7 @@ 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) {}
@@ -365,6 +374,7 @@ public:
// 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)
@@ -384,6 +394,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)
@@ -416,6 +427,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,
@@ -447,6 +459,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)
@@ -468,6 +481,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)
@@ -482,6 +496,7 @@ public:
// 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),
@@ -498,6 +513,7 @@ 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) {}
@@ -518,6 +534,7 @@ 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),
@@ -537,6 +554,7 @@ 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) {}
@@ -551,6 +569,7 @@ 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),
@@ -570,6 +589,7 @@ 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),
@@ -587,6 +607,7 @@ 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)
@@ -607,6 +628,7 @@ public:
// LF_BUILDINFO
class BuildInfoRecord : public TypeRecord {
public:
+ BuildInfoRecord() = default;
explicit BuildInfoRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
BuildInfoRecord(ArrayRef<TypeIndex> ArgIndices)
: TypeRecord(TypeRecordKind::BuildInfo),
@@ -619,6 +641,7 @@ public:
// 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,
@@ -646,7 +669,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)
@@ -678,6 +701,7 @@ 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) {}
@@ -689,6 +713,7 @@ public:
/// 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)
@@ -706,6 +731,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)
@@ -730,6 +756,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),
@@ -750,6 +777,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),
@@ -770,6 +798,7 @@ public:
// LF_VFUNCTAB
class VFPtrRecord : public TypeRecord {
public:
+ VFPtrRecord() = default;
explicit VFPtrRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
VFPtrRecord(TypeIndex Type)
: TypeRecord(TypeRecordKind::VFPtr), Type(Type) {}
@@ -782,6 +811,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),
@@ -802,6 +832,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,
@@ -831,6 +862,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),
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeRecordMapping.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeRecordMapping.h
index 924ca0470fad..6156223b2560 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeRecordMapping.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeRecordMapping.h
@@ -37,7 +37,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 435c43f7edcb..1dee86a1da79 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeSerializer.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeSerializer.h
@@ -106,7 +106,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>
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeTableBuilder.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeTableBuilder.h
index 7bdc9ecb20cf..907ed1010e5b 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>
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h
index ed48df33249f..126fb8abb0da 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h
@@ -94,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 0ea754deb425..d7a473306bc2 100644
--- a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h
+++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h
@@ -58,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 d51408122fc9..2ab1c9508522 100644
--- a/contrib/llvm/include/llvm/DebugInfo/DIContext.h
+++ b/contrib/llvm/include/llvm/DebugInfo/DIContext.h
@@ -146,6 +146,14 @@ 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;
+};
+
class DIContext {
public:
enum DIContextKind {
@@ -158,8 +166,7 @@ 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.
diff --git a/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h b/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h
index 7fa68f3f2314..519ecf618558 100644
--- a/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h
+++ b/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h
@@ -105,8 +105,7 @@ 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;
bool verify(raw_ostream &OS, DIDumpType DumpType = DIDT_All) override;
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/Native/RawConstants.h b/contrib/llvm/include/llvm/DebugInfo/PDB/Native/RawConstants.h
index f5d4df8feb2e..e1bd86b2870b 100644
--- a/contrib/llvm/include/llvm/DebugInfo/PDB/Native/RawConstants.h
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/Native/RawConstants.h
@@ -12,7 +12,6 @@
#include "llvm/ADT/BitmaskEnum.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
-
#include <cstdint>
namespace llvm {
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/Native/TpiHashing.h b/contrib/llvm/include/llvm/DebugInfo/PDB/Native/TpiHashing.h
index dd2698c354a2..156abb59a6be 100644
--- a/contrib/llvm/include/llvm/DebugInfo/PDB/Native/TpiHashing.h
+++ b/contrib/llvm/include/llvm/DebugInfo/PDB/Native/TpiHashing.h
@@ -38,7 +38,7 @@ public:
#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"
+#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
private:
template <typename RecordKind>
diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/PDBContext.h b/contrib/llvm/include/llvm/DebugInfo/PDB/PDBContext.h
index 84ab8ed173cb..0ce49f5ef922 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/IR/Attributes.h b/contrib/llvm/include/llvm/IR/Attributes.h
index ace309ed95a4..687863857698 100644
--- a/contrib/llvm/include/llvm/IR/Attributes.h
+++ b/contrib/llvm/include/llvm/IR/Attributes.h
@@ -228,34 +228,31 @@ public:
bool operator==(const AttributeSet &O) { return SetNode == O.SetNode; }
bool operator!=(const AttributeSet &O) { return !(*this == O); }
- /// Add an argument attribute. Because
- /// attribute sets are immutable, this returns a new set.
- AttributeSet addAttribute(LLVMContext &C,
- Attribute::AttrKind Kind) const;
+ /// 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. Because
- /// attribute sets are immutable, this returns a new set.
+ /// 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. Because
- /// attribute sets are immutable, this returns a new set.
+ /// 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. Because
- /// attribute sets are immutable, this returns a new set.
- 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, Attribute::AttrKind Kind) const;
- /// Remove the specified attribute from this set. Because
- /// attribute sets are immutable, this returns a new set.
- AttributeSet removeAttribute(LLVMContext &C,
- StringRef 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. Because
- /// attribute sets are immutable, this returns a new set.
+ /// Remove the specified attributes from this set. Returns a new set because
+ /// attribute sets are immutable.
AttributeSet removeAttributes(LLVMContext &C,
- const AttrBuilder &AttrsToRemove) const;
+ const AttrBuilder &AttrsToRemove) const;
/// Return the number of attributes in this set.
unsigned getNumAttributes() const;
@@ -377,73 +374,138 @@ public:
static AttributeList get(LLVMContext &C, unsigned Index,
const AttrBuilder &B);
- /// 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);
- }
-
- /// \brief Add an attribute to the attribute set at the given index. Because
- /// attribute sets are immutable, this returns a new set.
+ /// \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. Because
- /// attribute sets are immutable, this returns a new set.
+ /// \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 indices. Because
- /// attribute sets are immutable, this returns a new set.
- AttributeList addAttribute(LLVMContext &C, ArrayRef<unsigned> Indices,
- Attribute A) 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. Because
- /// attribute sets are immutable, this returns a new set.
+ /// \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 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;
+
+ /// 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.
+ /// 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.
+ /// 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.
+ /// 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. Because attribute lists are immutable, this returns the
- /// new list.
+ /// attribute list. Returns a new list because attribute lists are immutable.
AttributeList removeAttributes(LLVMContext &C, unsigned Index) const;
- /// \brief Add the dereferenceable attribute to the attribute set at the given
- /// index. Because attribute sets are immutable, this returns a new set.
+ /// \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 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_or_null attribute to the attribute set at
- /// the given index. Because attribute sets are immutable, this returns a new
- /// set.
+ /// 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 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.
+ /// 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);
+ }
+
//===--------------------------------------------------------------------===//
// AttributeList Accessors
//===--------------------------------------------------------------------===//
@@ -473,6 +535,21 @@ public:
/// \brief Return true if attribute exists at the given index.
bool hasAttributes(unsigned Index) const;
+ /// \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;
@@ -496,6 +573,16 @@ 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;
@@ -508,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;
diff --git a/contrib/llvm/include/llvm/IR/Function.h b/contrib/llvm/include/llvm/IR/Function.h
index f27e5c50a47f..29f512ddd076 100644
--- a/contrib/llvm/include/llvm/IR/Function.h
+++ b/contrib/llvm/include/llvm/IR/Function.h
@@ -214,10 +214,6 @@ public:
addAttribute(AttributeList::FunctionIndex, Attr);
}
- void addParamAttr(unsigned ArgNo, Attribute::AttrKind Kind) {
- addAttribute(ArgNo + AttributeList::FirstArgIndex, Kind);
- }
-
/// @brief Remove function attributes from this function.
void removeFnAttr(Attribute::AttrKind Kind) {
removeAttribute(AttributeList::FunctionIndex, Kind);
@@ -229,10 +225,6 @@ public:
getContext(), AttributeList::FunctionIndex, Kind));
}
- void removeParamAttr(unsigned ArgNo, Attribute::AttrKind Kind) {
- removeAttribute(ArgNo + AttributeList::FirstArgIndex, Kind);
- }
-
/// \brief Set the entry count for this function.
///
/// Entry count is the number of times this function was executed based on
@@ -299,6 +291,15 @@ public:
/// @brief adds the attributes to the list of attributes.
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);
@@ -308,6 +309,15 @@ public:
/// @brief removes the attributes from the list of attributes.
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);
@@ -329,10 +339,18 @@ 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 ArgNo) const {
return AttributeSets.getParamAlignment(ArgNo);
@@ -345,6 +363,12 @@ public:
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.
@@ -352,6 +376,13 @@ public:
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);
diff --git a/contrib/llvm/include/llvm/IR/Instructions.h b/contrib/llvm/include/llvm/IR/Instructions.h
index 6fab59613dd6..1f7990b99ebe 100644
--- a/contrib/llvm/include/llvm/IR/Instructions.h
+++ b/contrib/llvm/include/llvm/IR/Instructions.h
@@ -1660,6 +1660,9 @@ public:
/// 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);
@@ -1669,6 +1672,9 @@ public:
/// 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);
@@ -1704,6 +1710,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.
///
diff --git a/contrib/llvm/include/llvm/InitializePasses.h b/contrib/llvm/include/llvm/InitializePasses.h
index 3ca21c15577b..5b9796d4fba6 100644
--- a/contrib/llvm/include/llvm/InitializePasses.h
+++ b/contrib/llvm/include/llvm/InitializePasses.h
@@ -188,6 +188,7 @@ void initializeLintPass(PassRegistry&);
void initializeLiveDebugValuesPass(PassRegistry&);
void initializeLiveDebugVariablesPass(PassRegistry&);
void initializeLiveIntervalsPass(PassRegistry&);
+void initializeLiveRangeShrinkPass(PassRegistry&);
void initializeLiveRegMatrixPass(PassRegistry&);
void initializeLiveStacksPass(PassRegistry&);
void initializeLiveVariablesPass(PassRegistry&);
diff --git a/contrib/llvm/include/llvm/Object/WindowsResource.h b/contrib/llvm/include/llvm/Object/WindowsResource.h
index f94ad09ce0c6..2484f551aee0 100644
--- a/contrib/llvm/include/llvm/Object/WindowsResource.h
+++ b/contrib/llvm/include/llvm/Object/WindowsResource.h
@@ -30,11 +30,18 @@
#define LLVM_INCLUDE_LLVM_OBJECT_RESFILE_H
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/Object/Binary.h"
+#include "llvm/Object/Error.h"
#include "llvm/Support/BinaryByteStream.h"
#include "llvm/Support/BinaryStreamReader.h"
+#include "llvm/Support/COFF.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 {
@@ -44,23 +51,44 @@ class WindowsResource;
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; }
private:
friend class WindowsResource;
ResourceEntryRef(BinaryStreamRef Ref, const WindowsResource *Owner,
Error &Err);
+
Error loadNext();
+ struct HeaderSuffix {
+ support::ulittle32_t DataVersion;
+ support::ulittle16_t MemoryFlags;
+ support::ulittle16_t Language;
+ support::ulittle32_t Version;
+ support::ulittle32_t Characteristics;
+ };
+
BinaryStreamReader Reader;
- BinaryStreamRef HeaderBytes;
- BinaryStreamRef DataBytes;
+ bool IsStringType;
+ ArrayRef<UTF16> Type;
+ uint16_t TypeID;
+ bool IsStringName;
+ ArrayRef<UTF16> Name;
+ uint16_t NameID;
+ const HeaderSuffix *Suffix = nullptr;
+ ArrayRef<uint8_t> Data;
const WindowsResource *OwningRes = nullptr;
};
class WindowsResource : public Binary {
public:
- ~WindowsResource() override;
Expected<ResourceEntryRef> getHeadEntry();
static bool classof(const Binary *V) { return V->isWinRes(); }
@@ -76,6 +104,36 @@ private:
BinaryByteStream BBS;
};
+class WindowsResourceParser {
+public:
+ WindowsResourceParser();
+
+ Error parse(WindowsResource *WR);
+
+ void printTree() const;
+
+private:
+ class TreeNode {
+ public:
+ TreeNode() = default;
+ explicit TreeNode(ArrayRef<UTF16> Ref);
+ void addEntry(const ResourceEntryRef &Entry);
+ void print(ScopedPrinter &Writer, StringRef Name) const;
+
+ private:
+ TreeNode &addTypeNode(const ResourceEntryRef &Entry);
+ TreeNode &addNameNode(const ResourceEntryRef &Entry);
+ TreeNode &addLanguageNode(const ResourceEntryRef &Entry);
+ TreeNode &addChild(uint32_t ID);
+ TreeNode &addChild(ArrayRef<UTF16> NameRef);
+ std::vector<UTF16> Name;
+ std::map<uint32_t, std::unique_ptr<TreeNode>> IDChildren;
+ std::map<std::string, std::unique_ptr<TreeNode>> StringChildren;
+ };
+
+ TreeNode Root;
+};
+
} // namespace object
} // namespace llvm
diff --git a/contrib/llvm/include/llvm/ObjectYAML/CodeViewYAMLDebugSections.h b/contrib/llvm/include/llvm/ObjectYAML/CodeViewYAMLDebugSections.h
new file mode 100644
index 000000000000..6ddae2e2b41c
--- /dev/null
+++ b/contrib/llvm/include/llvm/ObjectYAML/CodeViewYAMLDebugSections.h
@@ -0,0 +1,91 @@
+//===- CodeViewYAMLDebugSections.h - CodeView YAMLIO debug sections -------===//
+//
+// 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/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/DebugSubsection.h"
+#include "llvm/ObjectYAML/YAML.h"
+
+namespace llvm {
+namespace CodeViewYAML {
+namespace detail {
+struct C13FragmentBase;
+}
+
+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 SourceFileInfo {
+ std::vector<SourceFileChecksumEntry> FileChecksums;
+ std::vector<SourceLineInfo> LineFragments;
+ std::vector<InlineeInfo> Inlinees;
+};
+
+struct C13DebugSection {
+ std::vector<detail::C13FragmentBase> Fragments;
+};
+} // namespace CodeViewYAML
+} // namespace llvm
+
+LLVM_YAML_DECLARE_MAPPING_TRAITS(CodeViewYAML::SourceFileInfo)
+
+#endif
diff --git a/contrib/llvm/include/llvm/ObjectYAML/CodeViewYAMLSymbols.h b/contrib/llvm/include/llvm/ObjectYAML/CodeViewYAMLSymbols.h
new file mode 100644
index 000000000000..ee4e2ac9d404
--- /dev/null
+++ b/contrib/llvm/include/llvm/ObjectYAML/CodeViewYAMLSymbols.h
@@ -0,0 +1,41 @@
+//===- 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/ObjectYAML/YAML.h"
+
+namespace llvm {
+namespace CodeViewYAML {
+namespace detail {
+struct SymbolRecordBase;
+}
+
+struct SymbolRecord {
+ std::shared_ptr<detail::SymbolRecordBase> Symbol;
+
+ codeview::CVSymbol toCodeViewSymbol(BumpPtrAllocator &Allocator) const;
+ static Expected<SymbolRecord> fromCodeViewSymbol(codeview::CVSymbol Symbol);
+};
+
+} // namespace CodeViewYAML
+} // namespace llvm
+
+LLVM_YAML_DECLARE_MAPPING_TRAITS(CodeViewYAML::SymbolRecord)
+LLVM_YAML_IS_SEQUENCE_VECTOR(CodeViewYAML::SymbolRecord)
+
+#endif
diff --git a/contrib/llvm/include/llvm/ObjectYAML/CodeViewYAMLTypes.h b/contrib/llvm/include/llvm/ObjectYAML/CodeViewYAMLTypes.h
new file mode 100644
index 000000000000..a57ada34a4fa
--- /dev/null
+++ b/contrib/llvm/include/llvm/ObjectYAML/CodeViewYAMLTypes.h
@@ -0,0 +1,48 @@
+//===- CodeViewYAMLTypes.h - CodeView YAMLIO Type Record 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_CODEVIEWYAMLTYPES_H
+#define LLVM_OBJECTYAML_CODEVIEWYAMLTYPES_H
+
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/TypeRecord.h"
+#include "llvm/ObjectYAML/YAML.h"
+
+namespace llvm {
+namespace CodeViewYAML {
+namespace detail {
+struct LeafRecordBase;
+struct MemberRecordBase;
+}
+
+struct MemberRecord {
+ std::shared_ptr<detail::MemberRecordBase> Member;
+};
+
+struct LeafRecord {
+ std::shared_ptr<detail::LeafRecordBase> Leaf;
+
+ codeview::CVType toCodeViewRecord(BumpPtrAllocator &Allocator) const;
+ static Expected<LeafRecord> fromCodeViewRecord(codeview::CVType Type);
+};
+} // namespace CodeViewYAML
+} // namespace llvm
+
+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
diff --git a/contrib/llvm/include/llvm/Passes/PassBuilder.h b/contrib/llvm/include/llvm/Passes/PassBuilder.h
index efa36d957fbd..12b05e4ff0c5 100644
--- a/contrib/llvm/include/llvm/Passes/PassBuilder.h
+++ b/contrib/llvm/include/llvm/Passes/PassBuilder.h
@@ -192,6 +192,39 @@ public:
buildFunctionSimplificationPipeline(OptimizationLevel Level,
bool DebugLogging = 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.
+ ModulePassManager
+ buildModuleSimplificationPipeline(OptimizationLevel Level,
+ bool DebugLogging = 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.
///
/// This provides a good default optimization pipeline for per-module
@@ -206,6 +239,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.
///
diff --git a/contrib/llvm/include/llvm/Support/ARMTargetParser.def b/contrib/llvm/include/llvm/Support/ARMTargetParser.def
index 32dc57a0fedf..65cb2715a6a5 100644
--- a/contrib/llvm/include/llvm/Support/ARMTargetParser.def
+++ b/contrib/llvm/include/llvm/Support/ARMTargetParser.def
@@ -206,7 +206,7 @@ ARM_CPU_NAME("cortex-a5", AK_ARMV7A, FK_NEON_VFPV4, false,
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_HWDIVTHUMB))
-ARM_CPU_NAME("cortex-a8", AK_ARMV7A, FK_NEON, true, ARM::AEK_SEC)
+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 |
@@ -236,7 +236,7 @@ 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)
diff --git a/contrib/llvm/include/llvm/Support/BinaryStreamReader.h b/contrib/llvm/include/llvm/Support/BinaryStreamReader.h
index 56375f41d2c0..29e8a2ab08aa 100644
--- a/contrib/llvm/include/llvm/Support/BinaryStreamReader.h
+++ b/contrib/llvm/include/llvm/Support/BinaryStreamReader.h
@@ -14,6 +14,7 @@
#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"
@@ -104,6 +105,13 @@ public:
/// 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.
diff --git a/contrib/llvm/include/llvm/Support/YAMLTraits.h b/contrib/llvm/include/llvm/Support/YAMLTraits.h
index ffea679fab82..8949d69ce724 100644
--- a/contrib/llvm/include/llvm/Support/YAMLTraits.h
+++ b/contrib/llvm/include/llvm/Support/YAMLTraits.h
@@ -1606,6 +1606,44 @@ template <typename T> struct StdMapStringCustomMappingTraitsImpl {
} \
}
+#define LLVM_YAML_DECLARE_MAPPING_TRAITS(Type) \
+ namespace llvm { \
+ namespace yaml { \
+ 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); \
+ }; \
+ } \
+ }
+
+#define LLVM_YAML_DECLARE_SCALAR_TRAITS(Type, MustQuote) \
+ namespace llvm { \
+ namespace yaml { \
+ template <> struct ScalarTraits<Type> { \
+ static void output(const Type &Value, void *ctx, llvm::raw_ostream &Out); \
+ static StringRef input(StringRef Scalar, void *ctxt, Type &Value); \
+ static bool mustQuote(StringRef) { return MustQuote; } \
+ }; \
+ } \
+ }
+
/// Utility for declaring that a std::vector of a particular type
/// should be considered a YAML document list.
#define LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(_type) \
diff --git a/contrib/llvm/include/llvm/TableGen/Record.h b/contrib/llvm/include/llvm/TableGen/Record.h
index 437f68b24e57..3c181f0e511b 100644
--- a/contrib/llvm/include/llvm/TableGen/Record.h
+++ b/contrib/llvm/include/llvm/TableGen/Record.h
@@ -1237,7 +1237,6 @@ class RecordVal {
public:
RecordVal(Init *N, RecTy *T, bool P);
- RecordVal(StringRef N, RecTy *T, bool P);
StringRef getName() const;
Init *getNameInit() const { return Name; }
@@ -1340,7 +1339,6 @@ public:
}
void setName(Init *Name); // Also updates RecordKeeper.
- void setName(StringRef Name); // Also updates RecordKeeper.
ArrayRef<SMLoc> getLoc() const { return Locs; }
@@ -1378,13 +1376,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) {
@@ -1492,7 +1488,7 @@ public:
/// 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
@@ -1522,7 +1518,7 @@ public:
/// 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
diff --git a/contrib/llvm/include/llvm/Target/TargetLowering.h b/contrib/llvm/include/llvm/Target/TargetLowering.h
index 17182b958ecb..7258a5cc2d89 100644
--- a/contrib/llvm/include/llvm/Target/TargetLowering.h
+++ b/contrib/llvm/include/llvm/Target/TargetLowering.h
@@ -1143,6 +1143,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
@@ -2330,6 +2340,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.
///
diff --git a/contrib/llvm/include/llvm/Target/TargetMachine.h b/contrib/llvm/include/llvm/Target/TargetMachine.h
index 73ae2ad12988..ed390799cfc3 100644
--- a/contrib/llvm/include/llvm/Target/TargetMachine.h
+++ b/contrib/llvm/include/llvm/Target/TargetMachine.h
@@ -299,6 +299,12 @@ 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; }
};
} // end namespace llvm
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 000000000000..bf04bbfe92d8
--- /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/Scalar/GVN.h b/contrib/llvm/include/llvm/Transforms/Scalar/GVN.h
index 3f97789cabbc..589aaaca02fe 100644
--- a/contrib/llvm/include/llvm/Transforms/Scalar/GVN.h
+++ b/contrib/llvm/include/llvm/Transforms/Scalar/GVN.h
@@ -68,24 +68,6 @@ public:
class ValueTable {
DenseMap<Value *, uint32_t> valueNumbering;
DenseMap<Expression, uint32_t> expressionNumbering;
-
- // Expressions is the vector of Expression. ExprIdx is the mapping from
- // value number to the index of Expression in Expressions. We use it
- // instead of a DenseMap because filling such mapping is faster than
- // filling a DenseMap and the compile time is a little better.
- uint32_t nextExprNumber;
- std::vector<Expression> Expressions;
- std::vector<uint32_t> ExprIdx;
- // Value number to PHINode mapping. Used for phi-translate in scalarpre.
- DenseMap<uint32_t, PHINode *> NumberingPhi;
- // Cache for phi-translate in scalarpre.
- typedef DenseMap<std::pair<uint32_t, const BasicBlock *>, uint32_t>
- PhiTranslateMap;
- PhiTranslateMap PhiTranslateTable;
- // Map the block to reversed postorder traversal number. It is used to
- // find back edge easily.
- DenseMap<const BasicBlock *, uint32_t> BlockRPONumber;
-
AliasAnalysis *AA;
MemoryDependenceResults *MD;
DominatorTree *DT;
@@ -97,10 +79,6 @@ public:
Value *LHS, Value *RHS);
Expression createExtractvalueExpr(ExtractValueInst *EI);
uint32_t lookupOrAddCall(CallInst *C);
- uint32_t phiTranslateImpl(const BasicBlock *BB, const BasicBlock *PhiBlock,
- uint32_t Num, GVN &Gvn);
- std::pair<uint32_t, bool> assignExpNewValueNum(Expression &exp);
- bool areAllValsInBB(uint32_t num, const BasicBlock *BB, GVN &Gvn);
public:
ValueTable();
@@ -109,12 +87,9 @@ public:
~ValueTable();
uint32_t lookupOrAdd(Value *V);
- uint32_t lookup(Value *V, bool Verify = true) const;
+ uint32_t lookup(Value *V) const;
uint32_t lookupOrAddCmp(unsigned Opcode, CmpInst::Predicate Pred,
Value *LHS, Value *RHS);
- uint32_t phiTranslate(const BasicBlock *BB, const BasicBlock *PhiBlock,
- uint32_t Num, GVN &Gvn);
- void assignBlockRPONumber(Function &F);
bool exists(Value *V) const;
void add(Value *V, uint32_t num);
void clear();
diff --git a/contrib/llvm/include/llvm/Transforms/Utils/CodeExtractor.h b/contrib/llvm/include/llvm/Transforms/Utils/CodeExtractor.h
index a602498e5f22..7e23544af1ab 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;
@@ -103,7 +104,17 @@ 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;
+ /// 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 sinked are collected in
+ /// 'Allocas'.
+ void findAllocas(ValueSet &Allocas) const;
private:
void severSplitPHINodes(BasicBlock *&Header);
diff --git a/contrib/llvm/include/llvm/module.modulemap b/contrib/llvm/include/llvm/module.modulemap
index 5e15e8d49802..e0780885d159 100644
--- a/contrib/llvm/include/llvm/module.modulemap
+++ b/contrib/llvm/include/llvm/module.modulemap
@@ -95,8 +95,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 {
diff --git a/contrib/llvm/lib/Analysis/CFLGraph.h b/contrib/llvm/lib/Analysis/CFLGraph.h
index a8fb12b72568..54782b6bd4ad 100644
--- a/contrib/llvm/lib/Analysis/CFLGraph.h
+++ b/contrib/llvm/lib/Analysis/CFLGraph.h
@@ -210,6 +210,11 @@ template <typename CFLAA> class CFLGraphBuilder {
void addDerefEdge(Value *From, Value *To, bool IsRead) {
assert(From != nullptr && To != nullptr);
+ // FIXME: This is subtly broken, due to how we model some instructions
+ // (e.g. extractvalue, extractelement) as loads. Since those take
+ // non-pointer operands, we'll entirely skip adding edges for those.
+ //
+ // addAssignEdge seems to have a similar issue with insertvalue, etc.
if (!From->getType()->isPointerTy() || !To->getType()->isPointerTy())
return;
addNode(From);
@@ -540,6 +545,7 @@ template <typename CFLAA> class CFLGraphBuilder {
case Instruction::ExtractValue: {
auto *Ptr = CE->getOperand(0);
addLoadEdge(Ptr, CE);
+ break;
}
case Instruction::ShuffleVector: {
auto *From1 = CE->getOperand(0);
diff --git a/contrib/llvm/lib/Analysis/ConstantFolding.cpp b/contrib/llvm/lib/Analysis/ConstantFolding.cpp
index 79517ec6a3a8..6a1af87450c9 100644
--- a/contrib/llvm/lib/Analysis/ConstantFolding.cpp
+++ b/contrib/llvm/lib/Analysis/ConstantFolding.cpp
@@ -1739,6 +1739,7 @@ Constant *ConstantFoldScalarCall(StringRef Name, unsigned IntrinsicID, Type *Ty,
if ((Name == "round" && TLI->has(LibFunc_round)) ||
(Name == "roundf" && TLI->has(LibFunc_roundf)))
return ConstantFoldFP(round, V, Ty);
+ break;
case 's':
if ((Name == "sin" && TLI->has(LibFunc_sin)) ||
(Name == "sinf" && TLI->has(LibFunc_sinf)))
@@ -1807,6 +1808,7 @@ Constant *ConstantFoldScalarCall(StringRef Name, unsigned IntrinsicID, Type *Ty,
dyn_cast_or_null<ConstantFP>(Op->getAggregateElement(0U)))
return ConstantFoldSSEConvertToInt(FPOp->getValueAPF(),
/*roundTowardZero=*/false, Ty);
+ LLVM_FALLTHROUGH;
case Intrinsic::x86_sse_cvttss2si:
case Intrinsic::x86_sse_cvttss2si64:
case Intrinsic::x86_sse2_cvttsd2si:
diff --git a/contrib/llvm/lib/Analysis/EHPersonalities.cpp b/contrib/llvm/lib/Analysis/EHPersonalities.cpp
index ebf0a370b0b0..b12ae9884e3d 100644
--- a/contrib/llvm/lib/Analysis/EHPersonalities.cpp
+++ b/contrib/llvm/lib/Analysis/EHPersonalities.cpp
@@ -27,8 +27,10 @@ EHPersonality llvm::classifyEHPersonality(const Value *Pers) {
return StringSwitch<EHPersonality>(F->getName())
.Case("__gnat_eh_personality", EHPersonality::GNU_Ada)
.Case("__gxx_personality_v0", EHPersonality::GNU_CXX)
+ .Case("__gxx_personality_seh0",EHPersonality::GNU_CXX)
.Case("__gxx_personality_sj0", EHPersonality::GNU_CXX_SjLj)
.Case("__gcc_personality_v0", EHPersonality::GNU_C)
+ .Case("__gcc_personality_seh0",EHPersonality::GNU_C)
.Case("__gcc_personality_sj0", EHPersonality::GNU_C_SjLj)
.Case("__objc_personality_v0", EHPersonality::GNU_ObjC)
.Case("_except_handler3", EHPersonality::MSVC_X86SEH)
diff --git a/contrib/llvm/lib/Analysis/InstructionSimplify.cpp b/contrib/llvm/lib/Analysis/InstructionSimplify.cpp
index 122442bafb11..66ac847455cd 100644
--- a/contrib/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/contrib/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -103,13 +103,8 @@ static bool ValueDominatesPHI(Value *V, PHINode *P, const DominatorTree *DT) {
return false;
// If we have a DominatorTree then do a precise test.
- if (DT) {
- if (!DT->isReachableFromEntry(P->getParent()))
- return true;
- if (!DT->isReachableFromEntry(I->getParent()))
- return false;
+ if (DT)
return DT->dominates(I, P);
- }
// Otherwise, if the instruction is in the entry block and is not an invoke,
// then it obviously dominates all phi nodes.
diff --git a/contrib/llvm/lib/Analysis/MemoryDependenceAnalysis.cpp b/contrib/llvm/lib/Analysis/MemoryDependenceAnalysis.cpp
index 66a0d145dcd8..188885063b39 100644
--- a/contrib/llvm/lib/Analysis/MemoryDependenceAnalysis.cpp
+++ b/contrib/llvm/lib/Analysis/MemoryDependenceAnalysis.cpp
@@ -691,6 +691,7 @@ MemDepResult MemoryDependenceResults::getSimplePointerDependencyFrom(
// load query, we can safely ignore it (scan past it).
if (isLoad)
continue;
+ LLVM_FALLTHROUGH;
default:
// Otherwise, there is a potential dependence. Return a clobber.
return MemDepResult::getClobber(Inst);
diff --git a/contrib/llvm/lib/Analysis/ScalarEvolution.cpp b/contrib/llvm/lib/Analysis/ScalarEvolution.cpp
index f55ce202bcbb..d96697cafbe9 100644
--- a/contrib/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/contrib/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -8182,6 +8182,7 @@ bool ScalarEvolution::isKnownPredicateViaNoOverflow(ICmpInst::Predicate Pred,
case ICmpInst::ICMP_SGE:
std::swap(LHS, RHS);
+ LLVM_FALLTHROUGH;
case ICmpInst::ICMP_SLE:
// X s<= (X + C)<nsw> if C >= 0
if (MatchBinaryAddToConst(RHS, LHS, C, SCEV::FlagNSW) && C.isNonNegative())
@@ -8195,6 +8196,7 @@ bool ScalarEvolution::isKnownPredicateViaNoOverflow(ICmpInst::Predicate Pred,
case ICmpInst::ICMP_SGT:
std::swap(LHS, RHS);
+ LLVM_FALLTHROUGH;
case ICmpInst::ICMP_SLT:
// X s< (X + C)<nsw> if C > 0
if (MatchBinaryAddToConst(RHS, LHS, C, SCEV::FlagNSW) &&
@@ -8552,6 +8554,7 @@ bool ScalarEvolution::isImpliedCond(ICmpInst::Predicate Pred, const SCEV *LHS,
if (isImpliedCondOperands(Pred, LHS, RHS, V,
getConstant(SharperMin)))
return true;
+ LLVM_FALLTHROUGH;
case ICmpInst::ICMP_SGT:
case ICmpInst::ICMP_UGT:
@@ -8566,6 +8569,7 @@ bool ScalarEvolution::isImpliedCond(ICmpInst::Predicate Pred, const SCEV *LHS,
if (isImpliedCondOperands(Pred, LHS, RHS, V, getConstant(Min)))
return true;
+ LLVM_FALLTHROUGH;
default:
// No change
diff --git a/contrib/llvm/lib/Analysis/TargetTransformInfo.cpp b/contrib/llvm/lib/Analysis/TargetTransformInfo.cpp
index 7a8d4f3be24f..ac646716476b 100644
--- a/contrib/llvm/lib/Analysis/TargetTransformInfo.cpp
+++ b/contrib/llvm/lib/Analysis/TargetTransformInfo.cpp
@@ -215,6 +215,10 @@ bool TargetTransformInfo::enableAggressiveInterleaving(bool LoopHasReductions) c
return TTIImpl->enableAggressiveInterleaving(LoopHasReductions);
}
+bool TargetTransformInfo::expandMemCmp(Instruction *I, unsigned &MaxLoadSize) const {
+ return TTIImpl->expandMemCmp(I, MaxLoadSize);
+}
+
bool TargetTransformInfo::enableInterleavedAccessVectorization() const {
return TTIImpl->enableInterleavedAccessVectorization();
}
diff --git a/contrib/llvm/lib/Analysis/ValueTracking.cpp b/contrib/llvm/lib/Analysis/ValueTracking.cpp
index bd79cd56a18b..a5dceb6c2271 100644
--- a/contrib/llvm/lib/Analysis/ValueTracking.cpp
+++ b/contrib/llvm/lib/Analysis/ValueTracking.cpp
@@ -172,6 +172,18 @@ bool llvm::haveNoCommonBitsSet(const Value *LHS, const Value *RHS,
}
+bool llvm::isOnlyUsedInZeroEqualityComparison(const Instruction *CxtI) {
+ for (const User *U : CxtI->users()) {
+ if (const ICmpInst *IC = dyn_cast<ICmpInst>(U))
+ if (IC->isEquality())
+ if (Constant *C = dyn_cast<Constant>(IC->getOperand(1)))
+ if (C->isNullValue())
+ continue;
+ return false;
+ }
+ return true;
+}
+
static bool isKnownToBeAPowerOfTwo(const Value *V, bool OrZero, unsigned Depth,
const Query &Q);
@@ -2327,6 +2339,7 @@ bool llvm::ComputeMultiple(Value *V, unsigned Base, Value *&Multiple,
case Instruction::SExt:
if (!LookThroughSExt) return false;
// otherwise fall through to ZExt
+ LLVM_FALLTHROUGH;
case Instruction::ZExt:
return ComputeMultiple(I->getOperand(0), Base, Multiple,
LookThroughSExt, Depth+1);
diff --git a/contrib/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/contrib/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
index c1d81ac203a1..a402b4ddd462 100644
--- a/contrib/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ b/contrib/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -378,18 +378,10 @@ private:
ModuleToSummariesForIndex->count(ModulePath);
}
- bool hasValueId(GlobalValue::GUID ValGUID) {
- const auto &VMI = GUIDToValueIdMap.find(ValGUID);
- return VMI != GUIDToValueIdMap.end();
- }
- void assignValueId(GlobalValue::GUID ValGUID) {
- unsigned &ValueId = GUIDToValueIdMap[ValGUID];
- if (ValueId == 0)
- ValueId = ++GlobalValueId;
- }
- unsigned getValueId(GlobalValue::GUID ValGUID) {
+ Optional<unsigned> getValueId(GlobalValue::GUID ValGUID) {
auto VMI = GUIDToValueIdMap.find(ValGUID);
- assert(VMI != GUIDToValueIdMap.end());
+ if (VMI == GUIDToValueIdMap.end())
+ return None;
return VMI->second;
}
std::map<GlobalValue::GUID, unsigned> &valueIds() { return GUIDToValueIdMap; }
@@ -3413,12 +3405,6 @@ void IndexBitcodeWriter::writeCombinedGlobalValueSummary() {
Stream.EnterSubblock(bitc::GLOBALVAL_SUMMARY_BLOCK_ID, 3);
Stream.EmitRecord(bitc::FS_VERSION, ArrayRef<uint64_t>{INDEX_VERSION});
- // Create value IDs for undefined references.
- forEachSummary([&](GVInfo I) {
- for (auto &RI : I.second->refs())
- assignValueId(RI.getGUID());
- });
-
for (const auto &GVI : valueIds()) {
Stream.EmitRecord(bitc::FS_VALUE_GUID,
ArrayRef<uint64_t>{GVI.second, GVI.first});
@@ -3492,9 +3478,9 @@ void IndexBitcodeWriter::writeCombinedGlobalValueSummary() {
GlobalValueSummary *S = I.second;
assert(S);
- assert(hasValueId(I.first));
- unsigned ValueId = getValueId(I.first);
- SummaryToValueIdMap[S] = ValueId;
+ auto ValueId = getValueId(I.first);
+ assert(ValueId);
+ SummaryToValueIdMap[S] = *ValueId;
if (auto *AS = dyn_cast<AliasSummary>(S)) {
// Will process aliases as a post-pass because the reader wants all
@@ -3504,11 +3490,14 @@ void IndexBitcodeWriter::writeCombinedGlobalValueSummary() {
}
if (auto *VS = dyn_cast<GlobalVarSummary>(S)) {
- NameVals.push_back(ValueId);
+ NameVals.push_back(*ValueId);
NameVals.push_back(Index.getModuleId(VS->modulePath()));
NameVals.push_back(getEncodedGVSummaryFlags(VS->flags()));
for (auto &RI : VS->refs()) {
- NameVals.push_back(getValueId(RI.getGUID()));
+ auto RefValueId = getValueId(RI.getGUID());
+ if (!RefValueId)
+ continue;
+ NameVals.push_back(*RefValueId);
}
// Emit the finished record.
@@ -3522,15 +3511,22 @@ void IndexBitcodeWriter::writeCombinedGlobalValueSummary() {
auto *FS = cast<FunctionSummary>(S);
writeFunctionTypeMetadataRecords(Stream, FS);
- NameVals.push_back(ValueId);
+ NameVals.push_back(*ValueId);
NameVals.push_back(Index.getModuleId(FS->modulePath()));
NameVals.push_back(getEncodedGVSummaryFlags(FS->flags()));
NameVals.push_back(FS->instCount());
- NameVals.push_back(FS->refs().size());
+ // Fill in below
+ NameVals.push_back(0);
+ unsigned Count = 0;
for (auto &RI : FS->refs()) {
- NameVals.push_back(getValueId(RI.getGUID()));
+ auto RefValueId = getValueId(RI.getGUID());
+ if (!RefValueId)
+ continue;
+ NameVals.push_back(*RefValueId);
+ Count++;
}
+ NameVals[4] = Count;
bool HasProfileData = false;
for (auto &EI : FS->calls()) {
@@ -3543,15 +3539,19 @@ void IndexBitcodeWriter::writeCombinedGlobalValueSummary() {
// If this GUID doesn't have a value id, it doesn't have a function
// summary and we don't need to record any calls to it.
GlobalValue::GUID GUID = EI.first.getGUID();
- if (!hasValueId(GUID)) {
+ auto CallValueId = getValueId(GUID);
+ if (!CallValueId) {
// For SamplePGO, the indirect call targets for local functions will
// have its original name annotated in profile. We try to find the
// corresponding PGOFuncName as the GUID.
GUID = Index.getGUIDFromOriginalID(GUID);
- if (GUID == 0 || !hasValueId(GUID))
+ if (GUID == 0)
+ continue;
+ CallValueId = getValueId(GUID);
+ if (!CallValueId)
continue;
}
- NameVals.push_back(getValueId(GUID));
+ NameVals.push_back(*CallValueId);
if (HasProfileData)
NameVals.push_back(static_cast<uint8_t>(EI.second.Hotness));
}
diff --git a/contrib/llvm/lib/CodeGen/AggressiveAntiDepBreaker.cpp b/contrib/llvm/lib/CodeGen/AggressiveAntiDepBreaker.cpp
index 43b245c66400..5abf50e5bd10 100644
--- a/contrib/llvm/lib/CodeGen/AggressiveAntiDepBreaker.cpp
+++ b/contrib/llvm/lib/CodeGen/AggressiveAntiDepBreaker.cpp
@@ -165,7 +165,7 @@ void AggressiveAntiDepBreaker::StartBlock(MachineBasicBlock *BB) {
for (const MCPhysReg *I = MF.getRegInfo().getCalleeSavedRegs(); *I;
++I) {
unsigned Reg = *I;
- if (!IsReturnBlock && !(Pristine.test(Reg) || BB->isLiveIn(Reg)))
+ if (!IsReturnBlock && !Pristine.test(Reg))
continue;
for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI) {
unsigned AliasReg = *AI;
diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/contrib/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index d72cf5922987..e61e22abe82a 100644
--- a/contrib/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/contrib/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -949,6 +949,19 @@ void AsmPrinter::emitFrameAlloc(const MachineInstr &MI) {
MCConstantExpr::create(FrameOffset, OutContext));
}
+static bool needFuncLabelsForEHOrDebugInfo(const MachineFunction &MF,
+ MachineModuleInfo *MMI) {
+ if (!MF.getLandingPads().empty() || MF.hasEHFunclets() || MMI->hasDebugInfo())
+ return true;
+
+ // We might emit an EH table that uses function begin and end labels even if
+ // we don't have any landingpads.
+ if (!MF.getFunction()->hasPersonalityFn())
+ return false;
+ return !isNoOpWithoutInvoke(
+ classifyEHPersonality(MF.getFunction()->getPersonalityFn()));
+}
+
/// EmitFunctionBody - This method emits the body and trailer for a
/// function.
void AsmPrinter::EmitFunctionBody() {
@@ -1076,8 +1089,8 @@ void AsmPrinter::EmitFunctionBody() {
// Emit target-specific gunk after the function body.
EmitFunctionBodyEnd();
- if (!MF->getLandingPads().empty() || MMI->hasDebugInfo() ||
- MF->hasEHFunclets() || MAI->hasDotTypeDotSizeDirective()) {
+ if (needFuncLabelsForEHOrDebugInfo(*MF, MMI) ||
+ MAI->hasDotTypeDotSizeDirective()) {
// Create a symbol for the end of function.
CurrentFnEnd = createTempSymbol("func_end");
OutStreamer->EmitLabel(CurrentFnEnd);
@@ -1402,8 +1415,7 @@ void AsmPrinter::SetupMachineFunction(MachineFunction &MF) {
CurrentFnBegin = nullptr;
CurExceptionSym = nullptr;
bool NeedsLocalForSize = MAI->needsLocalForSize();
- if (!MF.getLandingPads().empty() || MMI->hasDebugInfo() ||
- MF.hasEHFunclets() || NeedsLocalForSize) {
+ if (needFuncLabelsForEHOrDebugInfo(MF, MMI) || NeedsLocalForSize) {
CurrentFnBegin = createTempSymbol("func_begin");
if (NeedsLocalForSize)
CurrentFnSymForSize = CurrentFnBegin;
diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/EHStreamer.cpp b/contrib/llvm/lib/CodeGen/AsmPrinter/EHStreamer.cpp
index 0a4a7a06cb2e..e14d5be1177a 100644
--- a/contrib/llvm/lib/CodeGen/AsmPrinter/EHStreamer.cpp
+++ b/contrib/llvm/lib/CodeGen/AsmPrinter/EHStreamer.cpp
@@ -309,7 +309,7 @@ computeCallSiteTable(SmallVectorImpl<CallSiteEntry> &CallSites,
// If some instruction between the previous try-range and the end of the
// function may throw, create a call-site entry with no landing pad for the
// region following the try-range.
- if (SawPotentiallyThrowing && !IsSJLJ && LastLabel != nullptr) {
+ if (SawPotentiallyThrowing && !IsSJLJ) {
CallSiteEntry Site = { LastLabel, nullptr, nullptr, 0 };
CallSites.push_back(Site);
}
diff --git a/contrib/llvm/lib/CodeGen/CodeGen.cpp b/contrib/llvm/lib/CodeGen/CodeGen.cpp
index 2a2715beaadc..4d30c6574b12 100644
--- a/contrib/llvm/lib/CodeGen/CodeGen.cpp
+++ b/contrib/llvm/lib/CodeGen/CodeGen.cpp
@@ -43,6 +43,7 @@ void llvm::initializeCodeGen(PassRegistry &Registry) {
initializeLiveDebugValuesPass(Registry);
initializeLiveDebugVariablesPass(Registry);
initializeLiveIntervalsPass(Registry);
+ initializeLiveRangeShrinkPass(Registry);
initializeLiveStacksPass(Registry);
initializeLiveVariablesPass(Registry);
initializeLocalStackSlotPassPass(Registry);
diff --git a/contrib/llvm/lib/CodeGen/CodeGenPrepare.cpp b/contrib/llvm/lib/CodeGen/CodeGenPrepare.cpp
index 4e85708efafc..568b278dd47c 100644
--- a/contrib/llvm/lib/CodeGen/CodeGenPrepare.cpp
+++ b/contrib/llvm/lib/CodeGen/CodeGenPrepare.cpp
@@ -24,12 +24,13 @@
#include "llvm/Analysis/CFG.h"
#include "llvm/Analysis/InstructionSimplify.h"
#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/Analysis/MemoryBuiltins.h"
#include "llvm/Analysis/ProfileSummaryInfo.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/Analysis/ValueTracking.h"
-#include "llvm/Analysis/MemoryBuiltins.h"
#include "llvm/CodeGen/Analysis.h"
+#include "llvm/CodeGen/Passes.h"
#include "llvm/IR/CallSite.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
@@ -60,6 +61,7 @@
#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Transforms/Utils/SimplifyLibCalls.h"
#include "llvm/Transforms/Utils/ValueMapper.h"
+
using namespace llvm;
using namespace llvm::PatternMatch;
@@ -84,6 +86,12 @@ STATISTIC(NumDbgValueMoved, "Number of debug value instructions moved");
STATISTIC(NumSelectsExpanded, "Number of selects turned into branches");
STATISTIC(NumStoreExtractExposed, "Number of store(extractelement) exposed");
+STATISTIC(NumMemCmpCalls, "Number of memcmp calls");
+STATISTIC(NumMemCmpNotConstant, "Number of memcmp calls without constant size");
+STATISTIC(NumMemCmpGreaterThanMax,
+ "Number of memcmp calls with size greater than max size");
+STATISTIC(NumMemCmpInlined, "Number of inlined memcmp calls");
+
static cl::opt<bool> DisableBranchOpts(
"disable-cgp-branch-opts", cl::Hidden, cl::init(false),
cl::desc("Disable branch optimizations in CodeGenPrepare"));
@@ -144,6 +152,11 @@ EnableTypePromotionMerge("cgp-type-promotion-merge", cl::Hidden,
cl::desc("Enable merging of redundant sexts when one is dominating"
" the other."), cl::init(true));
+static cl::opt<unsigned> MemCmpNumLoadsPerBlock(
+ "memcmp-num-loads-per-block", cl::Hidden, cl::init(1),
+ cl::desc("The number of loads per basic block for inline expansion of "
+ "memcmp that is only being compared against zero."));
+
namespace {
typedef SmallPtrSet<Instruction *, 16> SetOfInstrs;
typedef PointerIntPair<Type *, 1, bool> TypeIsSExt;
@@ -1629,6 +1642,593 @@ static bool despeculateCountZeros(IntrinsicInst *CountZeros,
return true;
}
+// This class provides helper functions to expand a memcmp library call into an
+// inline expansion.
+class MemCmpExpansion {
+ struct ResultBlock {
+ BasicBlock *BB;
+ PHINode *PhiSrc1;
+ PHINode *PhiSrc2;
+ ResultBlock();
+ };
+
+ CallInst *CI;
+ ResultBlock ResBlock;
+ unsigned MaxLoadSize;
+ unsigned NumBlocks;
+ unsigned NumBlocksNonOneByte;
+ unsigned NumLoadsPerBlock;
+ std::vector<BasicBlock *> LoadCmpBlocks;
+ BasicBlock *EndBlock;
+ PHINode *PhiRes;
+ bool IsUsedForZeroCmp;
+ int calculateNumBlocks(unsigned Size);
+ void createLoadCmpBlocks();
+ void createResultBlock();
+ void setupResultBlockPHINodes();
+ void setupEndBlockPHINodes();
+ void emitLoadCompareBlock(unsigned Index, int LoadSize, int GEPIndex,
+ bool IsLittleEndian);
+ void emitLoadCompareBlockMultipleLoads(unsigned Index, unsigned Size,
+ unsigned &NumBytesProcessed);
+ void emitLoadCompareByteBlock(unsigned Index, int GEPIndex);
+ void emitMemCmpResultBlock(bool IsLittleEndian);
+ Value *getMemCmpExpansionZeroCase(unsigned Size, bool IsLittleEndian);
+ unsigned getLoadSize(unsigned Size);
+ unsigned getNumLoads(unsigned Size);
+
+public:
+ MemCmpExpansion(CallInst *CI, unsigned MaxLoadSize,
+ unsigned NumLoadsPerBlock);
+ Value *getMemCmpExpansion(bool IsLittleEndian);
+};
+
+MemCmpExpansion::ResultBlock::ResultBlock()
+ : BB(nullptr), PhiSrc1(nullptr), PhiSrc2(nullptr) {}
+
+// Initialize the basic block structure required for expansion of memcmp call
+// with given maximum load size and memcmp size parameter.
+// This structure includes:
+// 1. A list of load compare blocks - LoadCmpBlocks.
+// 2. An EndBlock, split from original instruction point, which is the block to
+// return from.
+// 3. ResultBlock, block to branch to for early exit when a
+// LoadCmpBlock finds a difference.
+MemCmpExpansion::MemCmpExpansion(CallInst *CI, unsigned MaxLoadSize,
+ unsigned NumLoadsPerBlock)
+ : CI(CI), MaxLoadSize(MaxLoadSize), NumLoadsPerBlock(NumLoadsPerBlock) {
+
+ IRBuilder<> Builder(CI->getContext());
+
+ BasicBlock *StartBlock = CI->getParent();
+ EndBlock = StartBlock->splitBasicBlock(CI, "endblock");
+ setupEndBlockPHINodes();
+ IsUsedForZeroCmp = isOnlyUsedInZeroEqualityComparison(CI);
+
+ ConstantInt *SizeCast = dyn_cast<ConstantInt>(CI->getArgOperand(2));
+ uint64_t Size = SizeCast->getZExtValue();
+
+ // Calculate how many load compare blocks are required for an expansion of
+ // given Size.
+ NumBlocks = calculateNumBlocks(Size);
+ createResultBlock();
+
+ // If return value of memcmp is not used in a zero equality, we need to
+ // calculate which source was larger. The calculation requires the
+ // two loaded source values of each load compare block.
+ // These will be saved in the phi nodes created by setupResultBlockPHINodes.
+ if (!IsUsedForZeroCmp)
+ setupResultBlockPHINodes();
+
+ // Create the number of required load compare basic blocks.
+ createLoadCmpBlocks();
+
+ // Update the terminator added by splitBasicBlock to branch to the first
+ // LoadCmpBlock.
+ Builder.SetCurrentDebugLocation(CI->getDebugLoc());
+ StartBlock->getTerminator()->setSuccessor(0, LoadCmpBlocks[0]);
+}
+
+void MemCmpExpansion::createLoadCmpBlocks() {
+ for (unsigned i = 0; i < NumBlocks; i++) {
+ BasicBlock *BB = BasicBlock::Create(CI->getContext(), "loadbb",
+ EndBlock->getParent(), EndBlock);
+ LoadCmpBlocks.push_back(BB);
+ }
+}
+
+void MemCmpExpansion::createResultBlock() {
+ ResBlock.BB = BasicBlock::Create(CI->getContext(), "res_block",
+ EndBlock->getParent(), EndBlock);
+}
+
+// This function creates the IR instructions for loading and comparing 1 byte.
+// It loads 1 byte from each source of the memcmp paramters with the given
+// GEPIndex. It then subtracts the two loaded values and adds this result to the
+// final phi node for selecting the memcmp result.
+void MemCmpExpansion::emitLoadCompareByteBlock(unsigned Index, int GEPIndex) {
+ IRBuilder<> Builder(CI->getContext());
+
+ Value *Source1 = CI->getArgOperand(0);
+ Value *Source2 = CI->getArgOperand(1);
+
+ Builder.SetInsertPoint(LoadCmpBlocks[Index]);
+ Type *LoadSizeType = Type::getInt8Ty(CI->getContext());
+ // Cast source to LoadSizeType*
+ if (Source1->getType() != LoadSizeType)
+ Source1 = Builder.CreateBitCast(Source1, LoadSizeType->getPointerTo());
+ if (Source2->getType() != LoadSizeType)
+ Source2 = Builder.CreateBitCast(Source2, LoadSizeType->getPointerTo());
+
+ // Get the base address using the GEPIndex
+ if (GEPIndex != 0) {
+ Source1 = Builder.CreateGEP(LoadSizeType, Source1,
+ ConstantInt::get(LoadSizeType, GEPIndex));
+ Source2 = Builder.CreateGEP(LoadSizeType, Source2,
+ ConstantInt::get(LoadSizeType, GEPIndex));
+ }
+
+ Value *LoadSrc1 = Builder.CreateLoad(LoadSizeType, Source1);
+ Value *LoadSrc2 = Builder.CreateLoad(LoadSizeType, Source2);
+
+ LoadSrc1 = Builder.CreateZExt(LoadSrc1, Type::getInt32Ty(CI->getContext()));
+ LoadSrc2 = Builder.CreateZExt(LoadSrc2, Type::getInt32Ty(CI->getContext()));
+ Value *Diff = Builder.CreateSub(LoadSrc1, LoadSrc2);
+
+ PhiRes->addIncoming(Diff, LoadCmpBlocks[Index]);
+
+ if (Index < (LoadCmpBlocks.size() - 1)) {
+ // Early exit branch if difference found to EndBlock, otherwise continue to
+ // next LoadCmpBlock
+
+ Value *Cmp = Builder.CreateICmp(ICmpInst::ICMP_NE, Diff,
+ ConstantInt::get(Diff->getType(), 0));
+ BranchInst *CmpBr =
+ BranchInst::Create(EndBlock, LoadCmpBlocks[Index + 1], Cmp);
+ Builder.Insert(CmpBr);
+ } else {
+ // The last block has an unconditional branch to EndBlock
+ BranchInst *CmpBr = BranchInst::Create(EndBlock);
+ Builder.Insert(CmpBr);
+ }
+}
+
+unsigned MemCmpExpansion::getNumLoads(unsigned Size) {
+ return (Size / MaxLoadSize) + countPopulation(Size % MaxLoadSize);
+}
+
+unsigned MemCmpExpansion::getLoadSize(unsigned Size) {
+ return MinAlign(PowerOf2Floor(Size), MaxLoadSize);
+}
+
+void MemCmpExpansion::emitLoadCompareBlockMultipleLoads(
+ unsigned Index, unsigned Size, unsigned &NumBytesProcessed) {
+
+ IRBuilder<> Builder(CI->getContext());
+
+ std::vector<Value *> XorList, OrList;
+ Value *Diff;
+
+ unsigned RemainingBytes = Size - NumBytesProcessed;
+ unsigned NumLoadsRemaining = getNumLoads(RemainingBytes);
+ unsigned NumLoads = std::min(NumLoadsRemaining, NumLoadsPerBlock);
+
+ Builder.SetInsertPoint(LoadCmpBlocks[Index]);
+
+ for (unsigned i = 0; i < NumLoads; ++i) {
+ unsigned LoadSize = getLoadSize(RemainingBytes);
+ unsigned GEPIndex = NumBytesProcessed / LoadSize;
+ NumBytesProcessed += LoadSize;
+ RemainingBytes -= LoadSize;
+
+ Type *LoadSizeType = IntegerType::get(CI->getContext(), LoadSize * 8);
+ Type *MaxLoadType = IntegerType::get(CI->getContext(), MaxLoadSize * 8);
+
+ Value *Source1 = CI->getArgOperand(0);
+ Value *Source2 = CI->getArgOperand(1);
+
+ // Cast source to LoadSizeType*
+ if (Source1->getType() != LoadSizeType)
+ Source1 = Builder.CreateBitCast(Source1, LoadSizeType->getPointerTo());
+ if (Source2->getType() != LoadSizeType)
+ Source2 = Builder.CreateBitCast(Source2, LoadSizeType->getPointerTo());
+
+ // Get the base address using the GEPIndex
+ if (GEPIndex != 0) {
+ Source1 = Builder.CreateGEP(LoadSizeType, Source1,
+ ConstantInt::get(LoadSizeType, GEPIndex));
+ Source2 = Builder.CreateGEP(LoadSizeType, Source2,
+ ConstantInt::get(LoadSizeType, GEPIndex));
+ }
+
+ // Load LoadSizeType from the base address
+ Value *LoadSrc1 = Builder.CreateLoad(LoadSizeType, Source1);
+ Value *LoadSrc2 = Builder.CreateLoad(LoadSizeType, Source2);
+ if (LoadSizeType != MaxLoadType) {
+ LoadSrc1 = Builder.CreateZExtOrTrunc(LoadSrc1, MaxLoadType);
+ LoadSrc2 = Builder.CreateZExtOrTrunc(LoadSrc2, MaxLoadType);
+ }
+ Diff = Builder.CreateXor(LoadSrc1, LoadSrc2);
+ Diff = Builder.CreateZExtOrTrunc(Diff, MaxLoadType);
+ XorList.push_back(Diff);
+ }
+
+ auto pairWiseOr = [&](std::vector<Value *> &InList) -> std::vector<Value *> {
+ std::vector<Value *> OutList;
+ for (unsigned i = 0; i < InList.size() - 1; i = i + 2) {
+ Value *Or = Builder.CreateOr(InList[i], InList[i + 1]);
+ OutList.push_back(Or);
+ }
+ if (InList.size() % 2 != 0)
+ OutList.push_back(InList.back());
+ return OutList;
+ };
+
+ // Pair wise OR the XOR results
+ OrList = pairWiseOr(XorList);
+
+ // Pair wise OR the OR results until one result left
+ while (OrList.size() != 1) {
+ OrList = pairWiseOr(OrList);
+ }
+
+ Value *Cmp = Builder.CreateICmp(ICmpInst::ICMP_NE, OrList[0],
+ ConstantInt::get(Diff->getType(), 0));
+ BasicBlock *NextBB = (Index == (LoadCmpBlocks.size() - 1))
+ ? EndBlock
+ : LoadCmpBlocks[Index + 1];
+ // Early exit branch if difference found to ResultBlock, otherwise continue to
+ // next LoadCmpBlock or EndBlock.
+ BranchInst *CmpBr = BranchInst::Create(ResBlock.BB, NextBB, Cmp);
+ Builder.Insert(CmpBr);
+
+ // Add a phi edge for the last LoadCmpBlock to Endblock with a value of 0
+ // since early exit to ResultBlock was not taken (no difference was found in
+ // any of the bytes)
+ if (Index == LoadCmpBlocks.size() - 1) {
+ Value *Zero = ConstantInt::get(Type::getInt32Ty(CI->getContext()), 0);
+ PhiRes->addIncoming(Zero, LoadCmpBlocks[Index]);
+ }
+}
+
+// This function creates the IR intructions for loading and comparing using the
+// given LoadSize. It loads the number of bytes specified by LoadSize from each
+// source of the memcmp parameters. It then does a subtract to see if there was
+// a difference in the loaded values. If a difference is found, it branches
+// with an early exit to the ResultBlock for calculating which source was
+// larger. Otherwise, it falls through to the either the next LoadCmpBlock or
+// the EndBlock if this is the last LoadCmpBlock. Loading 1 byte is handled with
+// a special case through emitLoadCompareByteBlock. The special handling can
+// simply subtract the loaded values and add it to the result phi node.
+void MemCmpExpansion::emitLoadCompareBlock(unsigned Index, int LoadSize,
+ int GEPIndex, bool IsLittleEndian) {
+ if (LoadSize == 1) {
+ MemCmpExpansion::emitLoadCompareByteBlock(Index, GEPIndex);
+ return;
+ }
+
+ IRBuilder<> Builder(CI->getContext());
+
+ Type *LoadSizeType = IntegerType::get(CI->getContext(), LoadSize * 8);
+ Type *MaxLoadType = IntegerType::get(CI->getContext(), MaxLoadSize * 8);
+
+ Value *Source1 = CI->getArgOperand(0);
+ Value *Source2 = CI->getArgOperand(1);
+
+ Builder.SetInsertPoint(LoadCmpBlocks[Index]);
+ // Cast source to LoadSizeType*
+ if (Source1->getType() != LoadSizeType)
+ Source1 = Builder.CreateBitCast(Source1, LoadSizeType->getPointerTo());
+ if (Source2->getType() != LoadSizeType)
+ Source2 = Builder.CreateBitCast(Source2, LoadSizeType->getPointerTo());
+
+ // Get the base address using the GEPIndex
+ if (GEPIndex != 0) {
+ Source1 = Builder.CreateGEP(LoadSizeType, Source1,
+ ConstantInt::get(LoadSizeType, GEPIndex));
+ Source2 = Builder.CreateGEP(LoadSizeType, Source2,
+ ConstantInt::get(LoadSizeType, GEPIndex));
+ }
+
+ // Load LoadSizeType from the base address
+ Value *LoadSrc1 = Builder.CreateLoad(LoadSizeType, Source1);
+ Value *LoadSrc2 = Builder.CreateLoad(LoadSizeType, Source2);
+
+ if (IsLittleEndian) {
+ Function *F = LoadCmpBlocks[Index]->getParent();
+
+ Function *Bswap = Intrinsic::getDeclaration(F->getParent(),
+ Intrinsic::bswap, LoadSizeType);
+ LoadSrc1 = Builder.CreateCall(Bswap, LoadSrc1);
+ LoadSrc2 = Builder.CreateCall(Bswap, LoadSrc2);
+ }
+
+ if (LoadSizeType != MaxLoadType) {
+ LoadSrc1 = Builder.CreateZExtOrTrunc(LoadSrc1, MaxLoadType);
+ LoadSrc2 = Builder.CreateZExtOrTrunc(LoadSrc2, MaxLoadType);
+ }
+
+ // Add the loaded values to the phi nodes for calculating memcmp result only
+ // if result is not used in a zero equality.
+ if (!IsUsedForZeroCmp) {
+ ResBlock.PhiSrc1->addIncoming(LoadSrc1, LoadCmpBlocks[Index]);
+ ResBlock.PhiSrc2->addIncoming(LoadSrc2, LoadCmpBlocks[Index]);
+ }
+
+ Value *Diff = Builder.CreateSub(LoadSrc1, LoadSrc2);
+
+ Value *Cmp = Builder.CreateICmp(ICmpInst::ICMP_NE, Diff,
+ ConstantInt::get(Diff->getType(), 0));
+ BasicBlock *NextBB = (Index == (LoadCmpBlocks.size() - 1))
+ ? EndBlock
+ : LoadCmpBlocks[Index + 1];
+ // Early exit branch if difference found to ResultBlock, otherwise continue to
+ // next LoadCmpBlock or EndBlock.
+ BranchInst *CmpBr = BranchInst::Create(ResBlock.BB, NextBB, Cmp);
+ Builder.Insert(CmpBr);
+
+ // Add a phi edge for the last LoadCmpBlock to Endblock with a value of 0
+ // since early exit to ResultBlock was not taken (no difference was found in
+ // any of the bytes)
+ if (Index == LoadCmpBlocks.size() - 1) {
+ Value *Zero = ConstantInt::get(Type::getInt32Ty(CI->getContext()), 0);
+ PhiRes->addIncoming(Zero, LoadCmpBlocks[Index]);
+ }
+}
+
+// This function populates the ResultBlock with a sequence to calculate the
+// memcmp result. It compares the two loaded source values and returns -1 if
+// src1 < src2 and 1 if src1 > src2.
+void MemCmpExpansion::emitMemCmpResultBlock(bool IsLittleEndian) {
+ IRBuilder<> Builder(CI->getContext());
+
+ // Special case: if memcmp result is used in a zero equality, result does not
+ // need to be calculated and can simply return 1.
+ if (IsUsedForZeroCmp) {
+ BasicBlock::iterator InsertPt = ResBlock.BB->getFirstInsertionPt();
+ Builder.SetInsertPoint(ResBlock.BB, InsertPt);
+ Value *Res = ConstantInt::get(Type::getInt32Ty(CI->getContext()), 1);
+ PhiRes->addIncoming(Res, ResBlock.BB);
+ BranchInst *NewBr = BranchInst::Create(EndBlock);
+ Builder.Insert(NewBr);
+ return;
+ }
+ BasicBlock::iterator InsertPt = ResBlock.BB->getFirstInsertionPt();
+ Builder.SetInsertPoint(ResBlock.BB, InsertPt);
+
+ Value *Cmp = Builder.CreateICmp(ICmpInst::ICMP_ULT, ResBlock.PhiSrc1,
+ ResBlock.PhiSrc2);
+
+ Value *Res =
+ Builder.CreateSelect(Cmp, ConstantInt::get(Builder.getInt32Ty(), -1),
+ ConstantInt::get(Builder.getInt32Ty(), 1));
+
+ BranchInst *NewBr = BranchInst::Create(EndBlock);
+ Builder.Insert(NewBr);
+ PhiRes->addIncoming(Res, ResBlock.BB);
+}
+
+int MemCmpExpansion::calculateNumBlocks(unsigned Size) {
+ int NumBlocks = 0;
+ bool haveOneByteLoad = false;
+ unsigned RemainingSize = Size;
+ unsigned LoadSize = MaxLoadSize;
+ while (RemainingSize) {
+ if (LoadSize == 1)
+ haveOneByteLoad = true;
+ NumBlocks += RemainingSize / LoadSize;
+ RemainingSize = RemainingSize % LoadSize;
+ LoadSize = LoadSize / 2;
+ }
+ NumBlocksNonOneByte = haveOneByteLoad ? (NumBlocks - 1) : NumBlocks;
+
+ if (IsUsedForZeroCmp)
+ NumBlocks = NumBlocks / NumLoadsPerBlock +
+ (NumBlocks % NumLoadsPerBlock != 0 ? 1 : 0);
+
+ return NumBlocks;
+}
+
+void MemCmpExpansion::setupResultBlockPHINodes() {
+ IRBuilder<> Builder(CI->getContext());
+ Type *MaxLoadType = IntegerType::get(CI->getContext(), MaxLoadSize * 8);
+ Builder.SetInsertPoint(ResBlock.BB);
+ ResBlock.PhiSrc1 =
+ Builder.CreatePHI(MaxLoadType, NumBlocksNonOneByte, "phi.src1");
+ ResBlock.PhiSrc2 =
+ Builder.CreatePHI(MaxLoadType, NumBlocksNonOneByte, "phi.src2");
+}
+
+void MemCmpExpansion::setupEndBlockPHINodes() {
+ IRBuilder<> Builder(CI->getContext());
+
+ Builder.SetInsertPoint(&EndBlock->front());
+ PhiRes = Builder.CreatePHI(Type::getInt32Ty(CI->getContext()), 2, "phi.res");
+}
+
+Value *MemCmpExpansion::getMemCmpExpansionZeroCase(unsigned Size,
+ bool IsLittleEndian) {
+ unsigned NumBytesProcessed = 0;
+ // This loop populates each of the LoadCmpBlocks with IR sequence to handle
+ // multiple loads per block
+ for (unsigned i = 0; i < NumBlocks; ++i) {
+ emitLoadCompareBlockMultipleLoads(i, Size, NumBytesProcessed);
+ }
+
+ emitMemCmpResultBlock(IsLittleEndian);
+ return PhiRes;
+}
+
+// This function expands the memcmp call into an inline expansion and returns
+// the memcmp result.
+Value *MemCmpExpansion::getMemCmpExpansion(bool IsLittleEndian) {
+
+ ConstantInt *SizeCast = dyn_cast<ConstantInt>(CI->getArgOperand(2));
+ uint64_t Size = SizeCast->getZExtValue();
+
+ int LoadSize = MaxLoadSize;
+ int NumBytesToBeProcessed = Size;
+
+ if (IsUsedForZeroCmp) {
+ return getMemCmpExpansionZeroCase(Size, IsLittleEndian);
+ }
+
+ unsigned Index = 0;
+ // This loop calls emitLoadCompareBlock for comparing SizeVal bytes of the two
+ // memcmp source. It starts with loading using the maximum load size set by
+ // the target. It processes any remaining bytes using a load size which is the
+ // next smallest power of 2.
+ while (NumBytesToBeProcessed) {
+ // Calculate how many blocks we can create with the current load size
+ int NumBlocks = NumBytesToBeProcessed / LoadSize;
+ int GEPIndex = (Size - NumBytesToBeProcessed) / LoadSize;
+ NumBytesToBeProcessed = NumBytesToBeProcessed % LoadSize;
+
+ // For each NumBlocks, populate the instruction sequence for loading and
+ // comparing LoadSize bytes
+ while (NumBlocks--) {
+ emitLoadCompareBlock(Index, LoadSize, GEPIndex, IsLittleEndian);
+ Index++;
+ GEPIndex++;
+ }
+ // Get the next LoadSize to use
+ LoadSize = LoadSize / 2;
+ }
+
+ emitMemCmpResultBlock(IsLittleEndian);
+ return PhiRes;
+}
+
+// This function checks to see if an expansion of memcmp can be generated.
+// It checks for constant compare size that is less than the max inline size.
+// If an expansion cannot occur, returns false to leave as a library call.
+// Otherwise, the library call is replaced wtih new IR instruction sequence.
+/// We want to transform:
+/// %call = call signext i32 @memcmp(i8* %0, i8* %1, i64 15)
+/// To:
+/// loadbb:
+/// %0 = bitcast i32* %buffer2 to i8*
+/// %1 = bitcast i32* %buffer1 to i8*
+/// %2 = bitcast i8* %1 to i64*
+/// %3 = bitcast i8* %0 to i64*
+/// %4 = load i64, i64* %2
+/// %5 = load i64, i64* %3
+/// %6 = call i64 @llvm.bswap.i64(i64 %4)
+/// %7 = call i64 @llvm.bswap.i64(i64 %5)
+/// %8 = sub i64 %6, %7
+/// %9 = icmp ne i64 %8, 0
+/// br i1 %9, label %res_block, label %loadbb1
+/// res_block: ; preds = %loadbb2,
+/// %loadbb1, %loadbb
+/// %phi.src1 = phi i64 [ %6, %loadbb ], [ %22, %loadbb1 ], [ %36, %loadbb2 ]
+/// %phi.src2 = phi i64 [ %7, %loadbb ], [ %23, %loadbb1 ], [ %37, %loadbb2 ]
+/// %10 = icmp ult i64 %phi.src1, %phi.src2
+/// %11 = select i1 %10, i32 -1, i32 1
+/// br label %endblock
+/// loadbb1: ; preds = %loadbb
+/// %12 = bitcast i32* %buffer2 to i8*
+/// %13 = bitcast i32* %buffer1 to i8*
+/// %14 = bitcast i8* %13 to i32*
+/// %15 = bitcast i8* %12 to i32*
+/// %16 = getelementptr i32, i32* %14, i32 2
+/// %17 = getelementptr i32, i32* %15, i32 2
+/// %18 = load i32, i32* %16
+/// %19 = load i32, i32* %17
+/// %20 = call i32 @llvm.bswap.i32(i32 %18)
+/// %21 = call i32 @llvm.bswap.i32(i32 %19)
+/// %22 = zext i32 %20 to i64
+/// %23 = zext i32 %21 to i64
+/// %24 = sub i64 %22, %23
+/// %25 = icmp ne i64 %24, 0
+/// br i1 %25, label %res_block, label %loadbb2
+/// loadbb2: ; preds = %loadbb1
+/// %26 = bitcast i32* %buffer2 to i8*
+/// %27 = bitcast i32* %buffer1 to i8*
+/// %28 = bitcast i8* %27 to i16*
+/// %29 = bitcast i8* %26 to i16*
+/// %30 = getelementptr i16, i16* %28, i16 6
+/// %31 = getelementptr i16, i16* %29, i16 6
+/// %32 = load i16, i16* %30
+/// %33 = load i16, i16* %31
+/// %34 = call i16 @llvm.bswap.i16(i16 %32)
+/// %35 = call i16 @llvm.bswap.i16(i16 %33)
+/// %36 = zext i16 %34 to i64
+/// %37 = zext i16 %35 to i64
+/// %38 = sub i64 %36, %37
+/// %39 = icmp ne i64 %38, 0
+/// br i1 %39, label %res_block, label %loadbb3
+/// loadbb3: ; preds = %loadbb2
+/// %40 = bitcast i32* %buffer2 to i8*
+/// %41 = bitcast i32* %buffer1 to i8*
+/// %42 = getelementptr i8, i8* %41, i8 14
+/// %43 = getelementptr i8, i8* %40, i8 14
+/// %44 = load i8, i8* %42
+/// %45 = load i8, i8* %43
+/// %46 = zext i8 %44 to i32
+/// %47 = zext i8 %45 to i32
+/// %48 = sub i32 %46, %47
+/// br label %endblock
+/// endblock: ; preds = %res_block,
+/// %loadbb3
+/// %phi.res = phi i32 [ %48, %loadbb3 ], [ %11, %res_block ]
+/// ret i32 %phi.res
+static bool expandMemCmp(CallInst *CI, const TargetTransformInfo *TTI,
+ const TargetLowering *TLI, const DataLayout *DL) {
+ NumMemCmpCalls++;
+ IRBuilder<> Builder(CI->getContext());
+
+ // TTI call to check if target would like to expand memcmp and get the
+ // MaxLoadSize
+ unsigned MaxLoadSize;
+ if (!TTI->expandMemCmp(CI, MaxLoadSize))
+ return false;
+
+ // Early exit from expansion if -Oz
+ if (CI->getParent()->getParent()->optForMinSize()) {
+ return false;
+ }
+
+ // Early exit from expansion if size is not a constant
+ ConstantInt *SizeCast = dyn_cast<ConstantInt>(CI->getArgOperand(2));
+ if (!SizeCast) {
+ NumMemCmpNotConstant++;
+ return false;
+ }
+
+ // Early exit from expansion if size greater than max bytes to load
+ uint64_t SizeVal = SizeCast->getZExtValue();
+
+ unsigned NumLoads = 0;
+ unsigned RemainingSize = SizeVal;
+ unsigned LoadSize = MaxLoadSize;
+ while (RemainingSize) {
+ NumLoads += RemainingSize / LoadSize;
+ RemainingSize = RemainingSize % LoadSize;
+ LoadSize = LoadSize / 2;
+ }
+
+ if (NumLoads >
+ TLI->getMaxExpandSizeMemcmp(CI->getParent()->getParent()->optForSize())) {
+ NumMemCmpGreaterThanMax++;
+ return false;
+ }
+
+ NumMemCmpInlined++;
+
+ // MemCmpHelper object, creates and sets up basic blocks required for
+ // expanding memcmp with size SizeVal
+ unsigned NumLoadsPerBlock = MemCmpNumLoadsPerBlock;
+ MemCmpExpansion MemCmpHelper(CI, MaxLoadSize, NumLoadsPerBlock);
+
+ Value *Res = MemCmpHelper.getMemCmpExpansion(DL->isLittleEndian());
+
+ // Replace call with result of expansion and erarse call.
+ CI->replaceAllUsesWith(Res);
+ CI->eraseFromParent();
+
+ return true;
+}
+
bool CodeGenPrepare::optimizeCallInst(CallInst *CI, bool& ModifiedDT) {
BasicBlock *BB = CI->getParent();
@@ -1780,6 +2380,15 @@ bool CodeGenPrepare::optimizeCallInst(CallInst *CI, bool& ModifiedDT) {
CI->eraseFromParent();
return true;
}
+
+ LibFunc Func;
+ if (TLInfo->getLibFunc(*CI->getCalledFunction(), Func) &&
+ Func == LibFunc_memcmp) {
+ if (expandMemCmp(CI, TTI, TLI, DL)) {
+ ModifiedDT = true;
+ return true;
+ }
+ }
return false;
}
@@ -4927,6 +5536,7 @@ bool CodeGenPrepare::optimizeSwitchInst(SwitchInst *SI) {
return true;
}
+
namespace {
/// \brief Helper class to promote a scalar operation to a vector one.
/// This class is used to move downward extractelement transition.
diff --git a/contrib/llvm/lib/CodeGen/CriticalAntiDepBreaker.cpp b/contrib/llvm/lib/CodeGen/CriticalAntiDepBreaker.cpp
index b2d6652b075e..a3cf2846d2f5 100644
--- a/contrib/llvm/lib/CodeGen/CriticalAntiDepBreaker.cpp
+++ b/contrib/llvm/lib/CodeGen/CriticalAntiDepBreaker.cpp
@@ -74,7 +74,7 @@ void CriticalAntiDepBreaker::StartBlock(MachineBasicBlock *BB) {
for (const MCPhysReg *I = MF.getRegInfo().getCalleeSavedRegs(); *I;
++I) {
unsigned Reg = *I;
- if (!IsReturnBlock && !(Pristine.test(Reg) || BB->isLiveIn(Reg)))
+ if (!IsReturnBlock && !Pristine.test(Reg))
continue;
for (MCRegAliasIterator AI(*I, TRI, true); AI.isValid(); ++AI) {
unsigned Reg = *AI;
diff --git a/contrib/llvm/lib/CodeGen/GlobalISel/Localizer.cpp b/contrib/llvm/lib/CodeGen/GlobalISel/Localizer.cpp
index c2a568e4b452..c5d0999fe438 100644
--- a/contrib/llvm/lib/CodeGen/GlobalISel/Localizer.cpp
+++ b/contrib/llvm/lib/CodeGen/GlobalISel/Localizer.cpp
@@ -98,12 +98,10 @@ bool Localizer::runOnMachineFunction(MachineFunction &MF) {
// Create the localized instruction.
MachineInstr *LocalizedMI = MF.CloneMachineInstr(&MI);
LocalizedInstrs.insert(LocalizedMI);
- // Move it at the right place.
- MachineInstr &MIUse = *MOUse.getParent();
- if (MIUse.getParent() == InsertMBB)
- InsertMBB->insert(MIUse, LocalizedMI);
- else
- InsertMBB->insert(InsertMBB->getFirstNonPHI(), LocalizedMI);
+ // Don't try to be smart for the insertion point.
+ // There is no guarantee that the first seen use is the first
+ // use in the block.
+ InsertMBB->insert(InsertMBB->getFirstNonPHI(), LocalizedMI);
// Set a new register for the definition.
unsigned NewReg =
diff --git a/contrib/llvm/lib/CodeGen/ImplicitNullChecks.cpp b/contrib/llvm/lib/CodeGen/ImplicitNullChecks.cpp
index 24e289dd4f1b..444416a77008 100644
--- a/contrib/llvm/lib/CodeGen/ImplicitNullChecks.cpp
+++ b/contrib/llvm/lib/CodeGen/ImplicitNullChecks.cpp
@@ -607,8 +607,20 @@ MachineInstr *ImplicitNullChecks::insertFaultingInstr(
.addMBB(HandlerMBB)
.addImm(MI->getOpcode());
- for (auto &MO : MI->uses())
- MIB.add(MO);
+ for (auto &MO : MI->uses()) {
+ if (MO.isReg()) {
+ MachineOperand NewMO = MO;
+ if (MO.isUse()) {
+ NewMO.setIsKill(false);
+ } else {
+ assert(MO.isDef() && "Expected def or use");
+ NewMO.setIsDead(false);
+ }
+ MIB.add(NewMO);
+ } else {
+ MIB.add(MO);
+ }
+ }
MIB.setMemRefs(MI->memoperands_begin(), MI->memoperands_end());
diff --git a/contrib/llvm/lib/CodeGen/LiveRangeShrink.cpp b/contrib/llvm/lib/CodeGen/LiveRangeShrink.cpp
new file mode 100644
index 000000000000..552f4b5393fe
--- /dev/null
+++ b/contrib/llvm/lib/CodeGen/LiveRangeShrink.cpp
@@ -0,0 +1,231 @@
+//===-- LiveRangeShrink.cpp - Move instructions to shrink live range ------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+///===---------------------------------------------------------------------===//
+///
+/// \file
+/// This pass moves instructions close to the definition of its operands to
+/// shrink live range of the def instruction. The code motion is limited within
+/// the basic block. The moved instruction should have 1 def, and more than one
+/// uses, all of which are the only use of the def.
+///
+///===---------------------------------------------------------------------===//
+#include "llvm/ADT/Statistic.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/Support/Debug.h"
+
+#define DEBUG_TYPE "lrshrink"
+
+STATISTIC(NumInstrsHoistedToShrinkLiveRange,
+ "Number of insructions hoisted to shrink live range.");
+
+using namespace llvm;
+
+namespace {
+class LiveRangeShrink : public MachineFunctionPass {
+public:
+ static char ID;
+
+ LiveRangeShrink() : MachineFunctionPass(ID) {
+ initializeLiveRangeShrinkPass(*PassRegistry::getPassRegistry());
+ }
+
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
+ AU.setPreservesCFG();
+ MachineFunctionPass::getAnalysisUsage(AU);
+ }
+
+ StringRef getPassName() const override { return "Live Range Shrink"; }
+
+ bool runOnMachineFunction(MachineFunction &MF) override;
+};
+} // End anonymous namespace.
+
+char LiveRangeShrink::ID = 0;
+char &llvm::LiveRangeShrinkID = LiveRangeShrink::ID;
+
+INITIALIZE_PASS(LiveRangeShrink, "lrshrink", "Live Range Shrink Pass", false,
+ false)
+namespace {
+typedef DenseMap<MachineInstr *, unsigned> InstOrderMap;
+
+/// Returns \p New if it's dominated by \p Old, otherwise return \p Old.
+/// \p M maintains a map from instruction to its dominating order that satisfies
+/// M[A] > M[B] guarantees that A is dominated by B.
+/// If \p New is not in \p M, return \p Old. Otherwise if \p Old is null, return
+/// \p New.
+MachineInstr *FindDominatedInstruction(MachineInstr &New, MachineInstr *Old,
+ const InstOrderMap &M) {
+ auto NewIter = M.find(&New);
+ if (NewIter == M.end())
+ return Old;
+ if (Old == nullptr)
+ return &New;
+ unsigned OrderOld = M.find(Old)->second;
+ unsigned OrderNew = NewIter->second;
+ if (OrderOld != OrderNew)
+ return OrderOld < OrderNew ? &New : Old;
+ // OrderOld == OrderNew, we need to iterate down from Old to see if it
+ // can reach New, if yes, New is dominated by Old.
+ for (MachineInstr *I = Old->getNextNode(); M.find(I)->second == OrderNew;
+ I = I->getNextNode())
+ if (I == &New)
+ return &New;
+ return Old;
+}
+
+/// Builds Instruction to its dominating order number map \p M by traversing
+/// from instruction \p Start.
+void BuildInstOrderMap(MachineBasicBlock::iterator Start, InstOrderMap &M) {
+ M.clear();
+ unsigned i = 0;
+ for (MachineInstr &I : make_range(Start, Start->getParent()->end()))
+ M[&I] = i++;
+}
+} // end anonymous namespace
+
+bool LiveRangeShrink::runOnMachineFunction(MachineFunction &MF) {
+ if (skipFunction(*MF.getFunction()))
+ return false;
+
+ MachineRegisterInfo &MRI = MF.getRegInfo();
+
+ DEBUG(dbgs() << "**** Analysing " << MF.getName() << '\n');
+
+ InstOrderMap IOM;
+ // Map from register to instruction order (value of IOM) where the
+ // register is used last. When moving instructions up, we need to
+ // make sure all its defs (including dead def) will not cross its
+ // last use when moving up.
+ DenseMap<unsigned, std::pair<unsigned, MachineInstr *>> UseMap;
+
+ for (MachineBasicBlock &MBB : MF) {
+ if (MBB.empty())
+ continue;
+ bool SawStore = false;
+ BuildInstOrderMap(MBB.begin(), IOM);
+ UseMap.clear();
+
+ for (MachineBasicBlock::iterator Next = MBB.begin(); Next != MBB.end();) {
+ MachineInstr &MI = *Next;
+ ++Next;
+ if (MI.isPHI() || MI.isDebugValue())
+ continue;
+ if (MI.mayStore())
+ SawStore = true;
+
+ unsigned CurrentOrder = IOM[&MI];
+ unsigned Barrier = 0;
+ MachineInstr *BarrierMI = nullptr;
+ for (const MachineOperand &MO : MI.operands()) {
+ if (!MO.isReg() || MO.isDebug())
+ continue;
+ if (MO.isUse())
+ UseMap[MO.getReg()] = std::make_pair(CurrentOrder, &MI);
+ else if (MO.isDead() && UseMap.count(MO.getReg()))
+ // Barrier is the last instruction where MO get used. MI should not
+ // be moved above Barrier.
+ if (Barrier < UseMap[MO.getReg()].first) {
+ Barrier = UseMap[MO.getReg()].first;
+ BarrierMI = UseMap[MO.getReg()].second;
+ }
+ }
+
+ if (!MI.isSafeToMove(nullptr, SawStore)) {
+ // If MI has side effects, it should become a barrier for code motion.
+ // IOM is rebuild from the next instruction to prevent later
+ // instructions from being moved before this MI.
+ if (MI.hasUnmodeledSideEffects() && Next != MBB.end()) {
+ BuildInstOrderMap(Next, IOM);
+ SawStore = false;
+ }
+ continue;
+ }
+
+ const MachineOperand *DefMO = nullptr;
+ MachineInstr *Insert = nullptr;
+
+ // Number of live-ranges that will be shortened. We do not count
+ // live-ranges that are defined by a COPY as it could be coalesced later.
+ unsigned NumEligibleUse = 0;
+
+ for (const MachineOperand &MO : MI.operands()) {
+ if (!MO.isReg() || MO.isDead() || MO.isDebug())
+ continue;
+ unsigned Reg = MO.getReg();
+ // Do not move the instruction if it def/uses a physical register,
+ // unless it is a constant physical register or a noreg.
+ if (!TargetRegisterInfo::isVirtualRegister(Reg)) {
+ if (!Reg || MRI.isConstantPhysReg(Reg))
+ continue;
+ Insert = nullptr;
+ break;
+ }
+ if (MO.isDef()) {
+ // Do not move if there is more than one def.
+ if (DefMO) {
+ Insert = nullptr;
+ break;
+ }
+ DefMO = &MO;
+ } else if (MRI.hasOneNonDBGUse(Reg) && MRI.hasOneDef(Reg) && DefMO &&
+ MRI.getRegClass(DefMO->getReg()) ==
+ MRI.getRegClass(MO.getReg())) {
+ // The heuristic does not handle different register classes yet
+ // (registers of different sizes, looser/tighter constraints). This
+ // is because it needs more accurate model to handle register
+ // pressure correctly.
+ MachineInstr &DefInstr = *MRI.def_instr_begin(Reg);
+ if (!DefInstr.isCopy())
+ NumEligibleUse++;
+ Insert = FindDominatedInstruction(DefInstr, Insert, IOM);
+ } else {
+ Insert = nullptr;
+ break;
+ }
+ }
+
+ // If Barrier equals IOM[I], traverse forward to find if BarrierMI is
+ // after Insert, if yes, then we should not hoist.
+ for (MachineInstr *I = Insert; I && IOM[I] == Barrier;
+ I = I->getNextNode())
+ if (I == BarrierMI) {
+ Insert = nullptr;
+ break;
+ }
+ // Move the instruction when # of shrunk live range > 1.
+ if (DefMO && Insert && NumEligibleUse > 1 && Barrier <= IOM[Insert]) {
+ MachineBasicBlock::iterator I = std::next(Insert->getIterator());
+ // Skip all the PHI and debug instructions.
+ while (I != MBB.end() && (I->isPHI() || I->isDebugValue()))
+ I = std::next(I);
+ if (I == MI.getIterator())
+ continue;
+
+ // Update the dominator order to be the same as the insertion point.
+ // We do this to maintain a non-decreasing order without need to update
+ // all instruction orders after the insertion point.
+ unsigned NewOrder = IOM[&*I];
+ IOM[&MI] = NewOrder;
+ NumInstrsHoistedToShrinkLiveRange++;
+
+ // Find MI's debug value following MI.
+ MachineBasicBlock::iterator EndIter = std::next(MI.getIterator());
+ if (MI.getOperand(0).isReg())
+ for (; EndIter != MBB.end() && EndIter->isDebugValue() &&
+ EndIter->getOperand(0).isReg() &&
+ EndIter->getOperand(0).getReg() == MI.getOperand(0).getReg();
+ ++EndIter, ++Next)
+ IOM[&*EndIter] = NewOrder;
+ MBB.splice(I, &MBB, MI.getIterator(), EndIter);
+ }
+ }
+ }
+ return false;
+}
diff --git a/contrib/llvm/lib/CodeGen/MIRParser/MIRParser.cpp b/contrib/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
index bd04acd049db..ff12297e3fc6 100644
--- a/contrib/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
+++ b/contrib/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
@@ -332,8 +332,6 @@ bool MIRParserImpl::initializeMachineFunction(MachineFunction &MF) {
MF.setAlignment(YamlMF.Alignment);
MF.setExposesReturnsTwice(YamlMF.ExposesReturnsTwice);
- if (YamlMF.NoVRegs)
- MF.getProperties().set(MachineFunctionProperties::Property::NoVRegs);
if (YamlMF.Legalized)
MF.getProperties().set(MachineFunctionProperties::Property::Legalized);
if (YamlMF.RegBankSelected)
diff --git a/contrib/llvm/lib/CodeGen/MIRPrinter.cpp b/contrib/llvm/lib/CodeGen/MIRPrinter.cpp
index 6f6a67d81b0f..293fc7358b8e 100644
--- a/contrib/llvm/lib/CodeGen/MIRPrinter.cpp
+++ b/contrib/llvm/lib/CodeGen/MIRPrinter.cpp
@@ -183,8 +183,6 @@ void MIRPrinter::print(const MachineFunction &MF) {
YamlMF.Alignment = MF.getAlignment();
YamlMF.ExposesReturnsTwice = MF.exposesReturnsTwice();
- YamlMF.NoVRegs = MF.getProperties().hasProperty(
- MachineFunctionProperties::Property::NoVRegs);
YamlMF.Legalized = MF.getProperties().hasProperty(
MachineFunctionProperties::Property::Legalized);
YamlMF.RegBankSelected = MF.getProperties().hasProperty(
diff --git a/contrib/llvm/lib/CodeGen/MachineBasicBlock.cpp b/contrib/llvm/lib/CodeGen/MachineBasicBlock.cpp
index 06112723497b..590acc01008a 100644
--- a/contrib/llvm/lib/CodeGen/MachineBasicBlock.cpp
+++ b/contrib/llvm/lib/CodeGen/MachineBasicBlock.cpp
@@ -350,6 +350,13 @@ void MachineBasicBlock::removeLiveIn(MCPhysReg Reg, LaneBitmask LaneMask) {
LiveIns.erase(I);
}
+MachineBasicBlock::livein_iterator
+MachineBasicBlock::removeLiveIn(MachineBasicBlock::livein_iterator I) {
+ // Get non-const version of iterator.
+ LiveInVector::iterator LI = LiveIns.begin() + (I - LiveIns.begin());
+ return LiveIns.erase(LI);
+}
+
bool MachineBasicBlock::isLiveIn(MCPhysReg Reg, LaneBitmask LaneMask) const {
livein_iterator I = find_if(
LiveIns, [Reg](const RegisterMaskPair &LI) { return LI.PhysReg == Reg; });
diff --git a/contrib/llvm/lib/CodeGen/MachineInstr.cpp b/contrib/llvm/lib/CodeGen/MachineInstr.cpp
index d665201a5d17..306b75dbbae7 100644
--- a/contrib/llvm/lib/CodeGen/MachineInstr.cpp
+++ b/contrib/llvm/lib/CodeGen/MachineInstr.cpp
@@ -1,4 +1,4 @@
-//===-- lib/CodeGen/MachineInstr.cpp --------------------------------------===//
+//===- lib/CodeGen/MachineInstr.cpp ---------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -11,21 +11,34 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/ADT/APFloat.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/Hashing.h"
+#include "llvm/ADT/None.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/Analysis/AliasAnalysis.h"
-#include "llvm/CodeGen/MachineConstantPool.h"
+#include "llvm/Analysis/MemoryLocation.h"
+#include "llvm/CodeGen/GlobalISel/RegisterBank.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineInstrBundle.h"
#include "llvm/CodeGen/MachineMemOperand.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
+#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/PseudoSourceValue.h"
#include "llvm/IR/Constants.h"
-#include "llvm/IR/DebugInfo.h"
+#include "llvm/IR/DebugInfoMetadata.h"
+#include "llvm/IR/DebugLoc.h"
+#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/InlineAsm.h"
+#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Metadata.h"
@@ -35,9 +48,13 @@
#include "llvm/IR/Value.h"
#include "llvm/MC/MCInstrDesc.h"
#include "llvm/MC/MCSymbol.h"
+#include "llvm/MC/MCRegisterInfo.h"
+#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/LowLevelTypeImpl.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetInstrInfo.h"
@@ -45,6 +62,14 @@
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/Target/TargetSubtargetInfo.h"
+#include <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
+#include <cstring>
+#include <iterator>
+#include <utility>
+
using namespace llvm;
static cl::opt<bool> PrintWholeRegMask(
@@ -256,7 +281,7 @@ bool MachineOperand::isIdenticalTo(const MachineOperand &Other) const {
case MachineOperand::MO_GlobalAddress:
return getGlobal() == Other.getGlobal() && getOffset() == Other.getOffset();
case MachineOperand::MO_ExternalSymbol:
- return !strcmp(getSymbolName(), Other.getSymbolName()) &&
+ return strcmp(getSymbolName(), Other.getSymbolName()) == 0 &&
getOffset() == Other.getOffset();
case MachineOperand::MO_BlockAddress:
return getBlockAddress() == Other.getBlockAddress() &&
@@ -723,9 +748,7 @@ void MachineInstr::addImplicitDefUseOperands(MachineFunction &MF) {
/// the MCInstrDesc.
MachineInstr::MachineInstr(MachineFunction &MF, const MCInstrDesc &tid,
DebugLoc dl, bool NoImp)
- : MCID(&tid), Parent(nullptr), Operands(nullptr), NumOperands(0), Flags(0),
- AsmPrinterFlags(0), NumMemRefs(0), MemRefs(nullptr),
- debugLoc(std::move(dl)) {
+ : MCID(&tid), debugLoc(std::move(dl)) {
assert(debugLoc.hasTrivialDestructor() && "Expected trivial destructor");
// Reserve space for the expected number of operands.
@@ -742,9 +765,8 @@ MachineInstr::MachineInstr(MachineFunction &MF, const MCInstrDesc &tid,
/// MachineInstr ctor - Copies MachineInstr arg exactly
///
MachineInstr::MachineInstr(MachineFunction &MF, const MachineInstr &MI)
- : MCID(&MI.getDesc()), Parent(nullptr), Operands(nullptr), NumOperands(0),
- Flags(0), AsmPrinterFlags(0), NumMemRefs(MI.NumMemRefs),
- MemRefs(MI.MemRefs), debugLoc(MI.getDebugLoc()) {
+ : MCID(&MI.getDesc()), NumMemRefs(MI.NumMemRefs), MemRefs(MI.MemRefs),
+ debugLoc(MI.getDebugLoc()) {
assert(debugLoc.hasTrivialDestructor() && "Expected trivial destructor");
CapOperands = OperandCapacity::get(MI.getNumOperands());
@@ -1633,8 +1655,8 @@ bool MachineInstr::mayAlias(AliasAnalysis *AA, MachineInstr &Other,
// memory objects. It can save compile time, and possibly catch some
// corner cases not currently covered.
- assert ((MMOa->getOffset() >= 0) && "Negative MachineMemOperand offset");
- assert ((MMOb->getOffset() >= 0) && "Negative MachineMemOperand offset");
+ assert((MMOa->getOffset() >= 0) && "Negative MachineMemOperand offset");
+ assert((MMOb->getOffset() >= 0) && "Negative MachineMemOperand offset");
int64_t MinOffset = std::min(MMOa->getOffset(), MMOb->getOffset());
int64_t Overlapa = MMOa->getSize() + MMOa->getOffset() - MinOffset;
@@ -1667,7 +1689,7 @@ bool MachineInstr::hasOrderedMemoryRef() const {
return true;
// Check if any of our memory operands are ordered.
- return any_of(memoperands(), [](const MachineMemOperand *MMO) {
+ return llvm::any_of(memoperands(), [](const MachineMemOperand *MMO) {
return !MMO->isUnordered();
});
}
@@ -1841,7 +1863,6 @@ void MachineInstr::print(raw_ostream &OS, ModuleSlotTracker &MST,
return;
// Print the rest of the operands.
- bool OmittedAnyCallClobbers = false;
bool FirstOp = true;
unsigned AsmDescOp = ~0u;
unsigned AsmOpCount = 0;
@@ -1878,31 +1899,6 @@ void MachineInstr::print(raw_ostream &OS, ModuleSlotTracker &MST,
if (MO.isReg() && TargetRegisterInfo::isVirtualRegister(MO.getReg()))
VirtRegs.push_back(MO.getReg());
- // Omit call-clobbered registers which aren't used anywhere. This makes
- // call instructions much less noisy on targets where calls clobber lots
- // of registers. Don't rely on MO.isDead() because we may be called before
- // LiveVariables is run, or we may be looking at a non-allocatable reg.
- if (MRI && isCall() &&
- MO.isReg() && MO.isImplicit() && MO.isDef()) {
- unsigned Reg = MO.getReg();
- if (TargetRegisterInfo::isPhysicalRegister(Reg)) {
- if (MRI->use_empty(Reg)) {
- bool HasAliasLive = false;
- for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI) {
- unsigned AliasReg = *AI;
- if (!MRI->use_empty(AliasReg)) {
- HasAliasLive = true;
- break;
- }
- }
- if (!HasAliasLive) {
- OmittedAnyCallClobbers = true;
- continue;
- }
- }
- }
- }
-
if (FirstOp) FirstOp = false; else OS << ",";
OS << " ";
if (i < getDesc().NumOperands) {
@@ -1984,12 +1980,6 @@ void MachineInstr::print(raw_ostream &OS, ModuleSlotTracker &MST,
MO.print(OS, MST, TRI);
}
- // Briefly indicate whether any call clobbers were omitted.
- if (OmittedAnyCallClobbers) {
- if (!FirstOp) OS << ",";
- OS << " ...";
- }
-
bool HaveSemi = false;
const unsigned PrintableFlags = FrameSetup | FrameDestroy;
if (Flags & PrintableFlags) {
@@ -2255,8 +2245,8 @@ void MachineInstr::setPhysRegsDeadExcept(ArrayRef<unsigned> UsedRegs,
unsigned Reg = MO.getReg();
if (!TargetRegisterInfo::isPhysicalRegister(Reg)) continue;
// If there are no uses, including partial uses, the def is dead.
- if (none_of(UsedRegs,
- [&](unsigned Use) { return TRI.regsOverlap(Use, Reg); }))
+ if (llvm::none_of(UsedRegs,
+ [&](unsigned Use) { return TRI.regsOverlap(Use, Reg); }))
MO.setIsDead();
}
diff --git a/contrib/llvm/lib/CodeGen/MachineModuleInfo.cpp b/contrib/llvm/lib/CodeGen/MachineModuleInfo.cpp
index 6cf751d34e26..c1b72430e605 100644
--- a/contrib/llvm/lib/CodeGen/MachineModuleInfo.cpp
+++ b/contrib/llvm/lib/CodeGen/MachineModuleInfo.cpp
@@ -7,27 +7,34 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/CodeGen/MachineModuleInfo.h"
-#include "llvm/ADT/PointerUnion.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/PostOrderIterator.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/TinyPtrVector.h"
-#include "llvm/Analysis/EHPersonalities.h"
-#include "llvm/Analysis/ValueTracking.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionInitializer.h"
-#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/Passes.h"
-#include "llvm/IR/Constants.h"
+#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/DerivedTypes.h"
-#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Module.h"
-#include "llvm/MC/MCObjectFileInfo.h"
+#include "llvm/IR/Value.h"
+#include "llvm/IR/ValueHandle.h"
+#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCSymbol.h"
-#include "llvm/Support/Dwarf.h"
+#include "llvm/Pass.h"
+#include "llvm/Support/Casting.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetMachine.h"
+#include <algorithm>
+#include <cassert>
+#include <memory>
+#include <utility>
+#include <vector>
+
using namespace llvm;
using namespace llvm::dwarf;
@@ -37,14 +44,16 @@ INITIALIZE_PASS(MachineModuleInfo, "machinemoduleinfo",
char MachineModuleInfo::ID = 0;
// Out of line virtual method.
-MachineModuleInfoImpl::~MachineModuleInfoImpl() {}
+MachineModuleInfoImpl::~MachineModuleInfoImpl() = default;
namespace llvm {
+
class MMIAddrLabelMapCallbackPtr final : CallbackVH {
- MMIAddrLabelMap *Map;
+ MMIAddrLabelMap *Map = nullptr;
+
public:
- MMIAddrLabelMapCallbackPtr() : Map(nullptr) {}
- MMIAddrLabelMapCallbackPtr(Value *V) : CallbackVH(V), Map(nullptr) {}
+ MMIAddrLabelMapCallbackPtr() = default;
+ MMIAddrLabelMapCallbackPtr(Value *V) : CallbackVH(V) {}
void setPtr(BasicBlock *BB) {
ValueHandleBase::operator=(BB);
@@ -75,11 +84,12 @@ class MMIAddrLabelMap {
/// This is a per-function list of symbols whose corresponding BasicBlock got
/// deleted. These symbols need to be emitted at some point in the file, so
/// AsmPrinter emits them after the function body.
- DenseMap<AssertingVH<Function>, std::vector<MCSymbol*> >
+ DenseMap<AssertingVH<Function>, std::vector<MCSymbol*>>
DeletedAddrLabelsNeedingEmission;
-public:
+public:
MMIAddrLabelMap(MCContext &context) : Context(context) {}
+
~MMIAddrLabelMap() {
assert(DeletedAddrLabelsNeedingEmission.empty() &&
"Some labels for deleted blocks never got emitted");
@@ -93,7 +103,8 @@ public:
void UpdateForDeletedBlock(BasicBlock *BB);
void UpdateForRAUWBlock(BasicBlock *Old, BasicBlock *New);
};
-}
+
+} // end namespace llvm
ArrayRef<MCSymbol *> MMIAddrLabelMap::getAddrLabelSymbolToEmit(BasicBlock *BB) {
assert(BB->hasAddressTaken() &&
@@ -119,7 +130,7 @@ ArrayRef<MCSymbol *> MMIAddrLabelMap::getAddrLabelSymbolToEmit(BasicBlock *BB) {
/// If we have any deleted symbols for F, return them.
void MMIAddrLabelMap::
takeDeletedSymbolsForFunction(Function *F, std::vector<MCSymbol*> &Result) {
- DenseMap<AssertingVH<Function>, std::vector<MCSymbol*> >::iterator I =
+ DenseMap<AssertingVH<Function>, std::vector<MCSymbol*>>::iterator I =
DeletedAddrLabelsNeedingEmission.find(F);
// If there are no entries for the function, just return.
@@ -130,7 +141,6 @@ takeDeletedSymbolsForFunction(Function *F, std::vector<MCSymbol*> &Result) {
DeletedAddrLabelsNeedingEmission.erase(I);
}
-
void MMIAddrLabelMap::UpdateForDeletedBlock(BasicBlock *BB) {
// If the block got deleted, there is no need for the symbol. If the symbol
// was already emitted, we can just forget about it, otherwise we need to
@@ -177,7 +187,6 @@ void MMIAddrLabelMap::UpdateForRAUWBlock(BasicBlock *Old, BasicBlock *New) {
OldEntry.Symbols.end());
}
-
void MMIAddrLabelMapCallbackPtr::deleted() {
Map->UpdateForDeletedBlock(cast<BasicBlock>(getValPtr()));
}
@@ -186,9 +195,6 @@ void MMIAddrLabelMapCallbackPtr::allUsesReplacedWith(Value *V2) {
Map->UpdateForRAUWBlock(cast<BasicBlock>(getValPtr()), cast<BasicBlock>(V2));
}
-
-//===----------------------------------------------------------------------===//
-
MachineModuleInfo::MachineModuleInfo(const TargetMachine *TM)
: ImmutablePass(ID), TM(*TM),
Context(TM->getMCAsmInfo(), TM->getMCRegisterInfo(),
@@ -196,11 +202,9 @@ MachineModuleInfo::MachineModuleInfo(const TargetMachine *TM)
initializeMachineModuleInfoPass(*PassRegistry::getPassRegistry());
}
-MachineModuleInfo::~MachineModuleInfo() {
-}
+MachineModuleInfo::~MachineModuleInfo() = default;
bool MachineModuleInfo::doInitialization(Module &M) {
-
ObjFileMMI = nullptr;
CurCallSite = 0;
DbgInfoAvailable = UsesVAFloatArgument = UsesMorestackAddr = false;
@@ -211,7 +215,6 @@ bool MachineModuleInfo::doInitialization(Module &M) {
}
bool MachineModuleInfo::doFinalization(Module &M) {
-
Personalities.clear();
delete AddrLabelSymbols;
@@ -290,10 +293,12 @@ void MachineModuleInfo::deleteMachineFunctionFor(Function &F) {
}
namespace {
+
/// This pass frees the MachineFunction object associated with a Function.
class FreeMachineFunction : public FunctionPass {
public:
static char ID;
+
FreeMachineFunction() : FunctionPass(ID) {}
void getAnalysisUsage(AnalysisUsage &AU) const override {
@@ -311,14 +316,14 @@ public:
return "Free MachineFunction";
}
};
-char FreeMachineFunction::ID;
+
} // end anonymous namespace
-namespace llvm {
-FunctionPass *createFreeMachineFunctionPass() {
+char FreeMachineFunction::ID;
+
+FunctionPass *llvm::createFreeMachineFunctionPass() {
return new FreeMachineFunction();
}
-} // end namespace llvm
//===- MMI building helpers -----------------------------------------------===//
diff --git a/contrib/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/contrib/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index ab36bc1417ae..fb51a4eb1421 100644
--- a/contrib/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/contrib/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -280,6 +280,7 @@ namespace {
SDValue visitSELECT_CC(SDNode *N);
SDValue visitSETCC(SDNode *N);
SDValue visitSETCCE(SDNode *N);
+ SDValue visitSETCCCARRY(SDNode *N);
SDValue visitSIGN_EXTEND(SDNode *N);
SDValue visitZERO_EXTEND(SDNode *N);
SDValue visitANY_EXTEND(SDNode *N);
@@ -1457,6 +1458,7 @@ SDValue DAGCombiner::visit(SDNode *N) {
case ISD::SELECT_CC: return visitSELECT_CC(N);
case ISD::SETCC: return visitSETCC(N);
case ISD::SETCCE: return visitSETCCE(N);
+ case ISD::SETCCCARRY: return visitSETCCCARRY(N);
case ISD::SIGN_EXTEND: return visitSIGN_EXTEND(N);
case ISD::ZERO_EXTEND: return visitZERO_EXTEND(N);
case ISD::ANY_EXTEND: return visitANY_EXTEND(N);
@@ -1958,7 +1960,7 @@ SDValue DAGCombiner::visitADD(SDNode *N) {
// fold (a+b) -> (a|b) iff a and b share no bits.
if ((!LegalOperations || TLI.isOperationLegal(ISD::OR, VT)) &&
- VT.isInteger() && DAG.haveNoCommonBitsSet(N0, N1))
+ DAG.haveNoCommonBitsSet(N0, N1))
return DAG.getNode(ISD::OR, DL, VT, N0, N1);
if (SDValue Combined = visitADDLike(N0, N1, N))
@@ -1970,6 +1972,44 @@ SDValue DAGCombiner::visitADD(SDNode *N) {
return SDValue();
}
+static SDValue getAsCarry(const TargetLowering &TLI, SDValue V) {
+ bool Masked = false;
+
+ // First, peel away TRUNCATE/ZERO_EXTEND/AND nodes due to legalization.
+ while (true) {
+ if (V.getOpcode() == ISD::TRUNCATE || V.getOpcode() == ISD::ZERO_EXTEND) {
+ V = V.getOperand(0);
+ continue;
+ }
+
+ if (V.getOpcode() == ISD::AND && isOneConstant(V.getOperand(1))) {
+ Masked = true;
+ V = V.getOperand(0);
+ continue;
+ }
+
+ break;
+ }
+
+ // If this is not a carry, return.
+ if (V.getResNo() != 1)
+ return SDValue();
+
+ if (V.getOpcode() != ISD::ADDCARRY && V.getOpcode() != ISD::SUBCARRY &&
+ V.getOpcode() != ISD::UADDO && V.getOpcode() != ISD::USUBO)
+ return SDValue();
+
+ // If the result is masked, then no matter what kind of bool it is we can
+ // return. If it isn't, then we need to make sure the bool type is either 0 or
+ // 1 and not other values.
+ if (Masked ||
+ TLI.getBooleanContents(V.getValueType()) ==
+ TargetLoweringBase::ZeroOrOneBooleanContent)
+ return V;
+
+ return SDValue();
+}
+
SDValue DAGCombiner::visitADDLike(SDValue N0, SDValue N1, SDNode *LocReference) {
EVT VT = N0.getValueType();
SDLoc DL(LocReference);
@@ -2017,6 +2057,13 @@ SDValue DAGCombiner::visitADDLike(SDValue N0, SDValue N1, SDNode *LocReference)
return DAG.getNode(ISD::ADDCARRY, DL, N1->getVTList(),
N0, N1.getOperand(0), N1.getOperand(2));
+ // (add X, Carry) -> (addcarry X, 0, Carry)
+ if (TLI.isOperationLegalOrCustom(ISD::ADDCARRY, VT))
+ if (SDValue Carry = getAsCarry(TLI, N1))
+ return DAG.getNode(ISD::ADDCARRY, DL,
+ DAG.getVTList(VT, Carry.getValueType()), N0,
+ DAG.getConstant(0, DL, VT), Carry);
+
return SDValue();
}
@@ -2090,6 +2137,8 @@ SDValue DAGCombiner::visitUADDO(SDNode *N) {
}
SDValue DAGCombiner::visitUADDOLike(SDValue N0, SDValue N1, SDNode *N) {
+ auto VT = N0.getValueType();
+
// (uaddo X, (addcarry Y, 0, Carry)) -> (addcarry X, Y, Carry)
// If Y + 1 cannot overflow.
if (N1.getOpcode() == ISD::ADDCARRY && isNullConstant(N1.getOperand(1))) {
@@ -2100,6 +2149,12 @@ SDValue DAGCombiner::visitUADDOLike(SDValue N0, SDValue N1, SDNode *N) {
N1.getOperand(2));
}
+ // (uaddo X, Carry) -> (addcarry X, 0, Carry)
+ if (TLI.isOperationLegalOrCustom(ISD::ADDCARRY, VT))
+ if (SDValue Carry = getAsCarry(TLI, N1))
+ return DAG.getNode(ISD::ADDCARRY, SDLoc(N), N->getVTList(), N0,
+ DAG.getConstant(0, SDLoc(N), VT), Carry);
+
return SDValue();
}
@@ -2167,6 +2222,41 @@ SDValue DAGCombiner::visitADDCARRYLike(SDValue N0, SDValue N1, SDValue CarryIn,
return DAG.getNode(ISD::ADDCARRY, SDLoc(N), N->getVTList(),
N0.getOperand(0), N0.getOperand(1), CarryIn);
+ /**
+ * When one of the addcarry argument is itself a carry, we may be facing
+ * a diamond carry propagation. In which case we try to transform the DAG
+ * to ensure linear carry propagation if that is possible.
+ *
+ * We are trying to get:
+ * (addcarry X, 0, (addcarry A, B, Z):Carry)
+ */
+ if (auto Y = getAsCarry(TLI, N1)) {
+ /**
+ * (uaddo A, B)
+ * / \
+ * Carry Sum
+ * | \
+ * | (addcarry *, 0, Z)
+ * | /
+ * \ Carry
+ * | /
+ * (addcarry X, *, *)
+ */
+ if (Y.getOpcode() == ISD::UADDO &&
+ CarryIn.getResNo() == 1 &&
+ CarryIn.getOpcode() == ISD::ADDCARRY &&
+ isNullConstant(CarryIn.getOperand(1)) &&
+ CarryIn.getOperand(0) == Y.getValue(0)) {
+ auto NewY = DAG.getNode(ISD::ADDCARRY, SDLoc(N), Y->getVTList(),
+ Y.getOperand(0), Y.getOperand(1),
+ CarryIn.getOperand(2));
+ AddToWorklist(NewY.getNode());
+ return DAG.getNode(ISD::ADDCARRY, SDLoc(N), N->getVTList(), N0,
+ DAG.getConstant(0, SDLoc(N), N0.getValueType()),
+ NewY.getValue(1));
+ }
+ }
+
return SDValue();
}
@@ -6754,6 +6844,19 @@ SDValue DAGCombiner::visitSETCCE(SDNode *N) {
return SDValue();
}
+SDValue DAGCombiner::visitSETCCCARRY(SDNode *N) {
+ SDValue LHS = N->getOperand(0);
+ SDValue RHS = N->getOperand(1);
+ SDValue Carry = N->getOperand(2);
+ SDValue Cond = N->getOperand(3);
+
+ // If Carry is false, fold to a regular SETCC.
+ if (isNullConstant(Carry))
+ return DAG.getNode(ISD::SETCC, SDLoc(N), N->getVTList(), LHS, RHS, Cond);
+
+ return SDValue();
+}
+
/// Try to fold a sext/zext/aext dag node into a ConstantSDNode or
/// a build_vector of constants.
/// This function is called by the DAGCombiner when visiting sext/zext/aext
@@ -7124,12 +7227,11 @@ SDValue DAGCombiner::visitSIGN_EXTEND(SDNode *N) {
SDValue ExtLoad = DAG.getExtLoad(ISD::SEXTLOAD, DL, VT, LN0->getChain(),
LN0->getBasePtr(), N0.getValueType(),
LN0->getMemOperand());
- CombineTo(N, ExtLoad);
SDValue Trunc = DAG.getNode(ISD::TRUNCATE, SDLoc(N0),
N0.getValueType(), ExtLoad);
- CombineTo(N0.getNode(), Trunc, ExtLoad.getValue(1));
ExtendSetCCUses(SetCCs, Trunc, ExtLoad, DL, ISD::SIGN_EXTEND);
- return SDValue(N, 0); // Return N so it doesn't get rechecked!
+ CombineTo(N0.getNode(), Trunc, ExtLoad.getValue(1));
+ return CombineTo(N, ExtLoad); // Return N so it doesn't get rechecked!
}
}
@@ -7185,10 +7287,9 @@ SDValue DAGCombiner::visitSIGN_EXTEND(SDNode *N) {
SDValue Trunc = DAG.getNode(ISD::TRUNCATE,
SDLoc(N0.getOperand(0)),
N0.getOperand(0).getValueType(), ExtLoad);
- CombineTo(N, And);
- CombineTo(N0.getOperand(0).getNode(), Trunc, ExtLoad.getValue(1));
ExtendSetCCUses(SetCCs, Trunc, ExtLoad, DL, ISD::SIGN_EXTEND);
- return SDValue(N, 0); // Return N so it doesn't get rechecked!
+ CombineTo(N0.getOperand(0).getNode(), Trunc, ExtLoad.getValue(1));
+ return CombineTo(N, And); // Return N so it doesn't get rechecked!
}
}
}
@@ -7427,12 +7528,9 @@ SDValue DAGCombiner::visitZERO_EXTEND(SDNode *N) {
SDValue Trunc = DAG.getNode(ISD::TRUNCATE, SDLoc(N0),
N0.getValueType(), ExtLoad);
+ ExtendSetCCUses(SetCCs, Trunc, ExtLoad, SDLoc(N), ISD::ZERO_EXTEND);
CombineTo(N0.getNode(), Trunc, ExtLoad.getValue(1));
-
- ExtendSetCCUses(SetCCs, Trunc, ExtLoad, SDLoc(N),
- ISD::ZERO_EXTEND);
- CombineTo(N, ExtLoad);
- return SDValue(N, 0); // Return N so it doesn't get rechecked!
+ return CombineTo(N, ExtLoad); // Return N so it doesn't get rechecked!
}
}
@@ -7482,11 +7580,9 @@ SDValue DAGCombiner::visitZERO_EXTEND(SDNode *N) {
SDValue Trunc = DAG.getNode(ISD::TRUNCATE,
SDLoc(N0.getOperand(0)),
N0.getOperand(0).getValueType(), ExtLoad);
- CombineTo(N, And);
+ ExtendSetCCUses(SetCCs, Trunc, ExtLoad, DL, ISD::ZERO_EXTEND);
CombineTo(N0.getOperand(0).getNode(), Trunc, ExtLoad.getValue(1));
- ExtendSetCCUses(SetCCs, Trunc, ExtLoad, DL,
- ISD::ZERO_EXTEND);
- return SDValue(N, 0); // Return N so it doesn't get rechecked!
+ return CombineTo(N, And); // Return N so it doesn't get rechecked!
}
}
}
@@ -12777,10 +12873,10 @@ bool DAGCombiner::MergeConsecutiveStores(StoreSDNode *St) {
}
// If we have load/store pair instructions and we only have two values,
- // don't bother.
+ // don't bother merging.
unsigned RequiredAlignment;
if (LoadNodes.size() == 2 && TLI.hasPairedLoad(MemVT, RequiredAlignment) &&
- St->getAlignment() >= RequiredAlignment) {
+ StoreNodes[0].MemNode->getAlignment() >= RequiredAlignment) {
StoreNodes.erase(StoreNodes.begin(), StoreNodes.begin() + 2);
continue;
}
diff --git a/contrib/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/contrib/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
index 92b0d2ae4015..0d5e07ded25c 100644
--- a/contrib/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
+++ b/contrib/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
@@ -2875,6 +2875,7 @@ bool DAGTypeLegalizer::ExpandIntegerOperand(SDNode *N, unsigned OpNo) {
case ISD::SELECT_CC: Res = ExpandIntOp_SELECT_CC(N); break;
case ISD::SETCC: Res = ExpandIntOp_SETCC(N); break;
case ISD::SETCCE: Res = ExpandIntOp_SETCCE(N); break;
+ case ISD::SETCCCARRY: Res = ExpandIntOp_SETCCCARRY(N); break;
case ISD::SINT_TO_FP: Res = ExpandIntOp_SINT_TO_FP(N); break;
case ISD::STORE: Res = ExpandIntOp_STORE(cast<StoreSDNode>(N), OpNo); break;
case ISD::TRUNCATE: Res = ExpandIntOp_TRUNCATE(N); break;
@@ -3009,14 +3010,16 @@ void DAGTypeLegalizer::IntegerExpandSetCCOperands(SDValue &NewLHS,
return;
}
- // Lower with SETCCE if the target supports it.
+ // Lower with SETCCE or SETCCCARRY if the target supports it.
+ EVT HiVT = LHSHi.getValueType();
+ EVT ExpandVT = TLI.getTypeToExpandTo(*DAG.getContext(), HiVT);
+ bool HasSETCCCARRY = TLI.isOperationLegalOrCustom(ISD::SETCCCARRY, ExpandVT);
+
// FIXME: Make all targets support this, then remove the other lowering.
- if (TLI.getOperationAction(
- ISD::SETCCE,
- TLI.getTypeToExpandTo(*DAG.getContext(), LHSLo.getValueType())) ==
- TargetLowering::Custom) {
- // SETCCE can detect < and >= directly. For > and <=, flip operands and
- // condition code.
+ if (HasSETCCCARRY ||
+ TLI.getOperationAction(ISD::SETCCE, ExpandVT) == TargetLowering::Custom) {
+ // SETCCE/SETCCCARRY can detect < and >= directly. For > and <=, flip
+ // operands and condition code.
bool FlipOperands = false;
switch (CCCode) {
case ISD::SETGT: CCCode = ISD::SETLT; FlipOperands = true; break;
@@ -3030,27 +3033,28 @@ void DAGTypeLegalizer::IntegerExpandSetCCOperands(SDValue &NewLHS,
std::swap(LHSHi, RHSHi);
}
// Perform a wide subtraction, feeding the carry from the low part into
- // SETCCE. The SETCCE operation is essentially looking at the high part of
- // the result of LHS - RHS. It is negative iff LHS < RHS. It is zero or
- // positive iff LHS >= RHS.
- SDVTList VTList = DAG.getVTList(LHSLo.getValueType(), MVT::Glue);
- SDValue LowCmp = DAG.getNode(ISD::SUBC, dl, VTList, LHSLo, RHSLo);
- SDValue Res =
- DAG.getNode(ISD::SETCCE, dl, getSetCCResultType(LHSLo.getValueType()),
- LHSHi, RHSHi, LowCmp.getValue(1), DAG.getCondCode(CCCode));
+ // SETCCE/SETCCCARRY. The SETCCE/SETCCCARRY operation is essentially
+ // looking at the high part of the result of LHS - RHS. It is negative
+ // iff LHS < RHS. It is zero or positive iff LHS >= RHS.
+ EVT LoVT = LHSLo.getValueType();
+ SDVTList VTList = DAG.getVTList(
+ LoVT, HasSETCCCARRY ? getSetCCResultType(LoVT) : MVT::Glue);
+ SDValue LowCmp = DAG.getNode(HasSETCCCARRY ? ISD::USUBO : ISD::SUBC, dl,
+ VTList, LHSLo, RHSLo);
+ SDValue Res = DAG.getNode(HasSETCCCARRY ? ISD::SETCCCARRY : ISD::SETCCE, dl,
+ getSetCCResultType(HiVT), LHSHi, RHSHi,
+ LowCmp.getValue(1), DAG.getCondCode(CCCode));
NewLHS = Res;
NewRHS = SDValue();
return;
}
- NewLHS = TLI.SimplifySetCC(getSetCCResultType(LHSHi.getValueType()),
- LHSHi, RHSHi, ISD::SETEQ, false,
- DagCombineInfo, dl);
+ NewLHS = TLI.SimplifySetCC(getSetCCResultType(HiVT), LHSHi, RHSHi, ISD::SETEQ,
+ false, DagCombineInfo, dl);
if (!NewLHS.getNode())
- NewLHS = DAG.getSetCC(dl, getSetCCResultType(LHSHi.getValueType()),
- LHSHi, RHSHi, ISD::SETEQ);
- NewLHS = DAG.getSelect(dl, LoCmp.getValueType(),
- NewLHS, LoCmp, HiCmp);
+ NewLHS =
+ DAG.getSetCC(dl, getSetCCResultType(HiVT), LHSHi, RHSHi, ISD::SETEQ);
+ NewLHS = DAG.getSelect(dl, LoCmp.getValueType(), NewLHS, LoCmp, HiCmp);
NewRHS = SDValue();
}
@@ -3103,8 +3107,8 @@ SDValue DAGTypeLegalizer::ExpandIntOp_SETCC(SDNode *N) {
}
// Otherwise, update N to have the operands specified.
- return SDValue(DAG.UpdateNodeOperands(N, NewLHS, NewRHS,
- DAG.getCondCode(CCCode)), 0);
+ return SDValue(
+ DAG.UpdateNodeOperands(N, NewLHS, NewRHS, DAG.getCondCode(CCCode)), 0);
}
SDValue DAGTypeLegalizer::ExpandIntOp_SETCCE(SDNode *N) {
@@ -3125,6 +3129,24 @@ SDValue DAGTypeLegalizer::ExpandIntOp_SETCCE(SDNode *N) {
LowCmp.getValue(1), Cond);
}
+SDValue DAGTypeLegalizer::ExpandIntOp_SETCCCARRY(SDNode *N) {
+ SDValue LHS = N->getOperand(0);
+ SDValue RHS = N->getOperand(1);
+ SDValue Carry = N->getOperand(2);
+ SDValue Cond = N->getOperand(3);
+ SDLoc dl = SDLoc(N);
+
+ SDValue LHSLo, LHSHi, RHSLo, RHSHi;
+ GetExpandedInteger(LHS, LHSLo, LHSHi);
+ GetExpandedInteger(RHS, RHSLo, RHSHi);
+
+ // Expand to a SUBE for the low part and a smaller SETCCCARRY for the high.
+ SDVTList VTList = DAG.getVTList(LHSLo.getValueType(), Carry.getValueType());
+ SDValue LowCmp = DAG.getNode(ISD::SUBCARRY, dl, VTList, LHSLo, RHSLo, Carry);
+ return DAG.getNode(ISD::SETCCCARRY, dl, N->getValueType(0), LHSHi, RHSHi,
+ LowCmp.getValue(1), Cond);
+}
+
SDValue DAGTypeLegalizer::ExpandIntOp_Shift(SDNode *N) {
// The value being shifted is legal, but the shift amount is too big.
// It follows that either the result of the shift is undefined, or the
diff --git a/contrib/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h b/contrib/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
index 4c3b514856b7..8e999188d8e1 100644
--- a/contrib/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
+++ b/contrib/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
@@ -381,6 +381,7 @@ private:
SDValue ExpandIntOp_SELECT_CC(SDNode *N);
SDValue ExpandIntOp_SETCC(SDNode *N);
SDValue ExpandIntOp_SETCCE(SDNode *N);
+ SDValue ExpandIntOp_SETCCCARRY(SDNode *N);
SDValue ExpandIntOp_Shift(SDNode *N);
SDValue ExpandIntOp_SINT_TO_FP(SDNode *N);
SDValue ExpandIntOp_STORE(StoreSDNode *N, unsigned OpNo);
diff --git a/contrib/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp b/contrib/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
index 4f4025d8ae6a..579112c9bfc8 100644
--- a/contrib/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
+++ b/contrib/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
@@ -226,6 +226,7 @@ private:
void UnscheduleNodeBottomUp(SUnit*);
void RestoreHazardCheckerBottomUp();
void BacktrackBottomUp(SUnit*, SUnit*);
+ SUnit *TryUnfoldSU(SUnit *);
SUnit *CopyAndMoveSuccessors(SUnit*);
void InsertCopiesAndMoveSuccs(SUnit*, unsigned,
const TargetRegisterClass*,
@@ -780,7 +781,7 @@ void ScheduleDAGRRList::ScheduleNodeBottomUp(SUnit *SU) {
}
/// CapturePred - This does the opposite of ReleasePred. Since SU is being
-/// unscheduled, incrcease the succ left count of its predecessors. Remove
+/// unscheduled, increase the succ left count of its predecessors. Remove
/// them from AvailableQueue if necessary.
void ScheduleDAGRRList::CapturePred(SDep *PredEdge) {
SUnit *PredSU = PredEdge->getSUnit();
@@ -934,6 +935,146 @@ static bool isOperandOf(const SUnit *SU, SDNode *N) {
return false;
}
+/// TryUnfold - Attempt to unfold
+SUnit *ScheduleDAGRRList::TryUnfoldSU(SUnit *SU) {
+ SDNode *N = SU->getNode();
+ // Use while over if to ease fall through.
+ SmallVector<SDNode *, 2> NewNodes;
+ if (!TII->unfoldMemoryOperand(*DAG, N, NewNodes))
+ return nullptr;
+
+ // unfolding an x86 DEC64m operation results in store, dec, load which
+ // can't be handled here so quit
+ if (NewNodes.size() == 3)
+ return nullptr;
+
+ assert(NewNodes.size() == 2 && "Expected a load folding node!");
+
+ N = NewNodes[1];
+ SDNode *LoadNode = NewNodes[0];
+ unsigned NumVals = N->getNumValues();
+ unsigned OldNumVals = SU->getNode()->getNumValues();
+
+ // LoadNode may already exist. This can happen when there is another
+ // load from the same location and producing the same type of value
+ // but it has different alignment or volatileness.
+ bool isNewLoad = true;
+ SUnit *LoadSU;
+ if (LoadNode->getNodeId() != -1) {
+ LoadSU = &SUnits[LoadNode->getNodeId()];
+ // If LoadSU has already been scheduled, we should clone it but
+ // this would negate the benefit to unfolding so just return SU.
+ if (LoadSU->isScheduled)
+ return SU;
+ isNewLoad = false;
+ } else {
+ LoadSU = CreateNewSUnit(LoadNode);
+ LoadNode->setNodeId(LoadSU->NodeNum);
+
+ InitNumRegDefsLeft(LoadSU);
+ computeLatency(LoadSU);
+ }
+
+ DEBUG(dbgs() << "Unfolding SU #" << SU->NodeNum << "\n");
+
+ // Now that we are committed to unfolding replace DAG Uses.
+ for (unsigned i = 0; i != NumVals; ++i)
+ DAG->ReplaceAllUsesOfValueWith(SDValue(SU->getNode(), i), SDValue(N, i));
+ DAG->ReplaceAllUsesOfValueWith(SDValue(SU->getNode(), OldNumVals - 1),
+ SDValue(LoadNode, 1));
+
+ SUnit *NewSU = CreateNewSUnit(N);
+ assert(N->getNodeId() == -1 && "Node already inserted!");
+ N->setNodeId(NewSU->NodeNum);
+
+ const MCInstrDesc &MCID = TII->get(N->getMachineOpcode());
+ for (unsigned i = 0; i != MCID.getNumOperands(); ++i) {
+ if (MCID.getOperandConstraint(i, MCOI::TIED_TO) != -1) {
+ NewSU->isTwoAddress = true;
+ break;
+ }
+ }
+ if (MCID.isCommutable())
+ NewSU->isCommutable = true;
+
+ InitNumRegDefsLeft(NewSU);
+ computeLatency(NewSU);
+
+ // Record all the edges to and from the old SU, by category.
+ SmallVector<SDep, 4> ChainPreds;
+ SmallVector<SDep, 4> ChainSuccs;
+ SmallVector<SDep, 4> LoadPreds;
+ SmallVector<SDep, 4> NodePreds;
+ SmallVector<SDep, 4> NodeSuccs;
+ for (SDep &Pred : SU->Preds) {
+ if (Pred.isCtrl())
+ ChainPreds.push_back(Pred);
+ else if (isOperandOf(Pred.getSUnit(), LoadNode))
+ LoadPreds.push_back(Pred);
+ else
+ NodePreds.push_back(Pred);
+ }
+ for (SDep &Succ : SU->Succs) {
+ if (Succ.isCtrl())
+ ChainSuccs.push_back(Succ);
+ else
+ NodeSuccs.push_back(Succ);
+ }
+
+ // Now assign edges to the newly-created nodes.
+ for (const SDep &Pred : ChainPreds) {
+ RemovePred(SU, Pred);
+ if (isNewLoad)
+ AddPred(LoadSU, Pred);
+ }
+ for (const SDep &Pred : LoadPreds) {
+ RemovePred(SU, Pred);
+ if (isNewLoad)
+ AddPred(LoadSU, Pred);
+ }
+ for (const SDep &Pred : NodePreds) {
+ RemovePred(SU, Pred);
+ AddPred(NewSU, Pred);
+ }
+ for (SDep D : NodeSuccs) {
+ SUnit *SuccDep = D.getSUnit();
+ D.setSUnit(SU);
+ RemovePred(SuccDep, D);
+ D.setSUnit(NewSU);
+ AddPred(SuccDep, D);
+ // Balance register pressure.
+ if (AvailableQueue->tracksRegPressure() && SuccDep->isScheduled &&
+ !D.isCtrl() && NewSU->NumRegDefsLeft > 0)
+ --NewSU->NumRegDefsLeft;
+ }
+ for (SDep D : ChainSuccs) {
+ SUnit *SuccDep = D.getSUnit();
+ D.setSUnit(SU);
+ RemovePred(SuccDep, D);
+ if (isNewLoad) {
+ D.setSUnit(LoadSU);
+ AddPred(SuccDep, D);
+ }
+ }
+
+ // Add a data dependency to reflect that NewSU reads the value defined
+ // by LoadSU.
+ SDep D(LoadSU, SDep::Data, 0);
+ D.setLatency(LoadSU->Latency);
+ AddPred(NewSU, D);
+
+ if (isNewLoad)
+ AvailableQueue->addNode(LoadSU);
+ AvailableQueue->addNode(NewSU);
+
+ ++NumUnfolds;
+
+ if (NewSU->NumSuccsLeft == 0)
+ NewSU->isAvailable = true;
+
+ return NewSU;
+}
+
/// CopyAndMoveSuccessors - Clone the specified node and move its scheduled
/// successors to the newly created node.
SUnit *ScheduleDAGRRList::CopyAndMoveSuccessors(SUnit *SU) {
@@ -959,135 +1100,16 @@ SUnit *ScheduleDAGRRList::CopyAndMoveSuccessors(SUnit *SU) {
return nullptr;
}
+ // If possible unfold instruction.
if (TryUnfold) {
- SmallVector<SDNode*, 2> NewNodes;
- if (!TII->unfoldMemoryOperand(*DAG, N, NewNodes))
+ SUnit *UnfoldSU = TryUnfoldSU(SU);
+ if (!UnfoldSU)
return nullptr;
-
- // unfolding an x86 DEC64m operation results in store, dec, load which
- // can't be handled here so quit
- if (NewNodes.size() == 3)
- return nullptr;
-
- DEBUG(dbgs() << "Unfolding SU #" << SU->NodeNum << "\n");
- assert(NewNodes.size() == 2 && "Expected a load folding node!");
-
- N = NewNodes[1];
- SDNode *LoadNode = NewNodes[0];
- unsigned NumVals = N->getNumValues();
- unsigned OldNumVals = SU->getNode()->getNumValues();
- for (unsigned i = 0; i != NumVals; ++i)
- DAG->ReplaceAllUsesOfValueWith(SDValue(SU->getNode(), i), SDValue(N, i));
- DAG->ReplaceAllUsesOfValueWith(SDValue(SU->getNode(), OldNumVals-1),
- SDValue(LoadNode, 1));
-
- // LoadNode may already exist. This can happen when there is another
- // load from the same location and producing the same type of value
- // but it has different alignment or volatileness.
- bool isNewLoad = true;
- SUnit *LoadSU;
- if (LoadNode->getNodeId() != -1) {
- LoadSU = &SUnits[LoadNode->getNodeId()];
- isNewLoad = false;
- } else {
- LoadSU = CreateNewSUnit(LoadNode);
- LoadNode->setNodeId(LoadSU->NodeNum);
-
- InitNumRegDefsLeft(LoadSU);
- computeLatency(LoadSU);
- }
-
- SUnit *NewSU = CreateNewSUnit(N);
- assert(N->getNodeId() == -1 && "Node already inserted!");
- N->setNodeId(NewSU->NodeNum);
-
- const MCInstrDesc &MCID = TII->get(N->getMachineOpcode());
- for (unsigned i = 0; i != MCID.getNumOperands(); ++i) {
- if (MCID.getOperandConstraint(i, MCOI::TIED_TO) != -1) {
- NewSU->isTwoAddress = true;
- break;
- }
- }
- if (MCID.isCommutable())
- NewSU->isCommutable = true;
-
- InitNumRegDefsLeft(NewSU);
- computeLatency(NewSU);
-
- // Record all the edges to and from the old SU, by category.
- SmallVector<SDep, 4> ChainPreds;
- SmallVector<SDep, 4> ChainSuccs;
- SmallVector<SDep, 4> LoadPreds;
- SmallVector<SDep, 4> NodePreds;
- SmallVector<SDep, 4> NodeSuccs;
- for (SDep &Pred : SU->Preds) {
- if (Pred.isCtrl())
- ChainPreds.push_back(Pred);
- else if (isOperandOf(Pred.getSUnit(), LoadNode))
- LoadPreds.push_back(Pred);
- else
- NodePreds.push_back(Pred);
- }
- for (SDep &Succ : SU->Succs) {
- if (Succ.isCtrl())
- ChainSuccs.push_back(Succ);
- else
- NodeSuccs.push_back(Succ);
- }
-
- // Now assign edges to the newly-created nodes.
- for (const SDep &Pred : ChainPreds) {
- RemovePred(SU, Pred);
- if (isNewLoad)
- AddPred(LoadSU, Pred);
- }
- for (const SDep &Pred : LoadPreds) {
- RemovePred(SU, Pred);
- if (isNewLoad)
- AddPred(LoadSU, Pred);
- }
- for (const SDep &Pred : NodePreds) {
- RemovePred(SU, Pred);
- AddPred(NewSU, Pred);
- }
- for (SDep D : NodeSuccs) {
- SUnit *SuccDep = D.getSUnit();
- D.setSUnit(SU);
- RemovePred(SuccDep, D);
- D.setSUnit(NewSU);
- AddPred(SuccDep, D);
- // Balance register pressure.
- if (AvailableQueue->tracksRegPressure() && SuccDep->isScheduled
- && !D.isCtrl() && NewSU->NumRegDefsLeft > 0)
- --NewSU->NumRegDefsLeft;
- }
- for (SDep D : ChainSuccs) {
- SUnit *SuccDep = D.getSUnit();
- D.setSUnit(SU);
- RemovePred(SuccDep, D);
- if (isNewLoad) {
- D.setSUnit(LoadSU);
- AddPred(SuccDep, D);
- }
- }
-
- // Add a data dependency to reflect that NewSU reads the value defined
- // by LoadSU.
- SDep D(LoadSU, SDep::Data, 0);
- D.setLatency(LoadSU->Latency);
- AddPred(NewSU, D);
-
- if (isNewLoad)
- AvailableQueue->addNode(LoadSU);
- AvailableQueue->addNode(NewSU);
-
- ++NumUnfolds;
-
- if (NewSU->NumSuccsLeft == 0) {
- NewSU->isAvailable = true;
- return NewSU;
- }
- SU = NewSU;
+ SU = UnfoldSU;
+ N = SU->getNode();
+ // If this can be scheduled don't bother duplicating and just return
+ if (SU->NumSuccsLeft == 0)
+ return SU;
}
DEBUG(dbgs() << " Duplicating SU #" << SU->NodeNum << "\n");
diff --git a/contrib/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp b/contrib/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
index c37d7080f2c5..0dbd9e846aa6 100644
--- a/contrib/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
+++ b/contrib/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
@@ -214,6 +214,7 @@ std::string SDNode::getOperationName(const SelectionDAG *G) const {
case ISD::FPOWI: return "fpowi";
case ISD::SETCC: return "setcc";
case ISD::SETCCE: return "setcce";
+ case ISD::SETCCCARRY: return "setcccarry";
case ISD::SELECT: return "select";
case ISD::VSELECT: return "vselect";
case ISD::SELECT_CC: return "select_cc";
diff --git a/contrib/llvm/lib/CodeGen/TargetLoweringBase.cpp b/contrib/llvm/lib/CodeGen/TargetLoweringBase.cpp
index 0def5ae6d0d0..900c0318b179 100644
--- a/contrib/llvm/lib/CodeGen/TargetLoweringBase.cpp
+++ b/contrib/llvm/lib/CodeGen/TargetLoweringBase.cpp
@@ -842,9 +842,10 @@ TargetLoweringBase::TargetLoweringBase(const TargetMachine &tm) : TM(tm) {
initActions();
// Perform these initializations only once.
- MaxStoresPerMemset = MaxStoresPerMemcpy = MaxStoresPerMemmove = 8;
- MaxStoresPerMemsetOptSize = MaxStoresPerMemcpyOptSize
- = MaxStoresPerMemmoveOptSize = 4;
+ MaxStoresPerMemset = MaxStoresPerMemcpy = MaxStoresPerMemmove =
+ MaxLoadsPerMemcmp = 8;
+ MaxStoresPerMemsetOptSize = MaxStoresPerMemcpyOptSize =
+ MaxStoresPerMemmoveOptSize = MaxLoadsPerMemcmpOptSize = 4;
UseUnderscoreSetJmp = false;
UseUnderscoreLongJmp = false;
HasMultipleConditionRegisters = false;
@@ -926,6 +927,7 @@ void TargetLoweringBase::initActions() {
// ADDCARRY operations default to expand
setOperationAction(ISD::ADDCARRY, VT, Expand);
setOperationAction(ISD::SUBCARRY, VT, Expand);
+ setOperationAction(ISD::SETCCCARRY, VT, Expand);
// These default to Expand so they will be expanded to CTLZ/CTTZ by default.
setOperationAction(ISD::CTLZ_ZERO_UNDEF, VT, Expand);
diff --git a/contrib/llvm/lib/CodeGen/TargetPassConfig.cpp b/contrib/llvm/lib/CodeGen/TargetPassConfig.cpp
index 83348058eca9..72d5e995ac22 100644
--- a/contrib/llvm/lib/CodeGen/TargetPassConfig.cpp
+++ b/contrib/llvm/lib/CodeGen/TargetPassConfig.cpp
@@ -261,9 +261,9 @@ TargetPassConfig::~TargetPassConfig() {
// Out of line constructor provides default values for pass options and
// registers all common codegen passes.
-TargetPassConfig::TargetPassConfig(TargetMachine *tm, PassManagerBase &pm)
+TargetPassConfig::TargetPassConfig(LLVMTargetMachine &TM, PassManagerBase &pm)
: ImmutablePass(ID), PM(&pm), Started(true), Stopped(false),
- AddingMachinePasses(false), TM(tm), Impl(nullptr), Initialized(false),
+ AddingMachinePasses(false), TM(&TM), Impl(nullptr), Initialized(false),
DisableVerify(false), EnableTailMerge(true),
RequireCodeGenSCCOrder(false) {
@@ -282,9 +282,9 @@ TargetPassConfig::TargetPassConfig(TargetMachine *tm, PassManagerBase &pm)
substitutePass(&PostRAMachineLICMID, &MachineLICMID);
if (StringRef(PrintMachineInstrs.getValue()).equals(""))
- TM->Options.PrintMachineCode = true;
+ TM.Options.PrintMachineCode = true;
- if (TM->Options.EnableIPRA)
+ if (TM.Options.EnableIPRA)
setRequiresCodeGenSCCOrder();
}
@@ -310,7 +310,7 @@ void TargetPassConfig::insertPass(AnalysisID TargetPassID,
///
/// Targets may override this to extend TargetPassConfig.
TargetPassConfig *LLVMTargetMachine::createPassConfig(PassManagerBase &PM) {
- return new TargetPassConfig(this, PM);
+ return new TargetPassConfig(*this, PM);
}
TargetPassConfig::TargetPassConfig()
@@ -430,7 +430,12 @@ void TargetPassConfig::addPrintPass(const std::string &Banner) {
}
void TargetPassConfig::addVerifyPass(const std::string &Banner) {
- if (VerifyMachineCode)
+ bool Verify = VerifyMachineCode;
+#ifdef EXPENSIVE_CHECKS
+ if (VerifyMachineCode == cl::BOU_UNSET)
+ Verify = TM->isMachineVerifierClean();
+#endif
+ if (Verify)
PM->add(createMachineVerifierPass(Banner));
}
diff --git a/contrib/llvm/lib/DebugInfo/CodeView/CVSymbolVisitor.cpp b/contrib/llvm/lib/DebugInfo/CodeView/CVSymbolVisitor.cpp
index 4c78caf03477..d058f4864975 100644
--- a/contrib/llvm/lib/DebugInfo/CodeView/CVSymbolVisitor.cpp
+++ b/contrib/llvm/lib/DebugInfo/CodeView/CVSymbolVisitor.cpp
@@ -46,7 +46,7 @@ Error CVSymbolVisitor::visitSymbolRecord(CVSymbol &Record) {
}
#define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) \
SYMBOL_RECORD(EnumVal, EnumVal, AliasName)
-#include "llvm/DebugInfo/CodeView/CVSymbolTypes.def"
+#include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
}
if (auto EC = Callbacks.visitSymbolEnd(Record))
diff --git a/contrib/llvm/lib/DebugInfo/CodeView/CVTypeVisitor.cpp b/contrib/llvm/lib/DebugInfo/CodeView/CVTypeVisitor.cpp
index 705b548141b0..f0debd9e9702 100644
--- a/contrib/llvm/lib/DebugInfo/CodeView/CVTypeVisitor.cpp
+++ b/contrib/llvm/lib/DebugInfo/CodeView/CVTypeVisitor.cpp
@@ -71,7 +71,7 @@ static Error visitMemberRecord(CVMemberRecord &Record,
MEMBER_RECORD(EnumVal, EnumVal, AliasName)
#define TYPE_RECORD(EnumName, EnumVal, Name)
#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
-#include "llvm/DebugInfo/CodeView/TypeRecords.def"
+#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
}
if (auto EC = Callbacks.visitMemberEnd(Record))
@@ -155,7 +155,7 @@ Error CVTypeVisitor::finishVisitation(CVType &Record) {
TYPE_RECORD(EnumVal, EnumVal, AliasName)
#define MEMBER_RECORD(EnumName, EnumVal, Name)
#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
-#include "llvm/DebugInfo/CodeView/TypeRecords.def"
+#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
}
if (auto EC = Callbacks.visitTypeEnd(Record))
diff --git a/contrib/llvm/lib/DebugInfo/CodeView/EnumTables.cpp b/contrib/llvm/lib/DebugInfo/CodeView/EnumTables.cpp
index 0441110c85ef..01d8ccf2d31e 100644
--- a/contrib/llvm/lib/DebugInfo/CodeView/EnumTables.cpp
+++ b/contrib/llvm/lib/DebugInfo/CodeView/EnumTables.cpp
@@ -20,13 +20,13 @@ using namespace codeview;
static const EnumEntry<SymbolKind> SymbolTypeNames[] = {
#define CV_SYMBOL(enum, val) {#enum, enum},
-#include "llvm/DebugInfo/CodeView/CVSymbolTypes.def"
+#include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
#undef CV_SYMBOL
};
static const EnumEntry<TypeLeafKind> TypeLeafNames[] = {
#define CV_TYPE(name, val) {#name, name},
-#include "llvm/DebugInfo/CodeView/TypeRecords.def"
+#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
#undef CV_TYPE
};
diff --git a/contrib/llvm/lib/DebugInfo/CodeView/SymbolDumper.cpp b/contrib/llvm/lib/DebugInfo/CodeView/SymbolDumper.cpp
index 2f5a7d256c60..3d49a7198d1a 100644
--- a/contrib/llvm/lib/DebugInfo/CodeView/SymbolDumper.cpp
+++ b/contrib/llvm/lib/DebugInfo/CodeView/SymbolDumper.cpp
@@ -41,7 +41,7 @@ public:
#define SYMBOL_RECORD(EnumName, EnumVal, Name) \
Error visitKnownRecord(CVSymbol &CVR, Name &Record) override;
#define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
-#include "llvm/DebugInfo/CodeView/CVSymbolTypes.def"
+#include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
Error visitSymbolBegin(CVSymbol &Record) override;
Error visitSymbolEnd(CVSymbol &Record) override;
diff --git a/contrib/llvm/lib/DebugInfo/CodeView/TypeDumpVisitor.cpp b/contrib/llvm/lib/DebugInfo/CodeView/TypeDumpVisitor.cpp
index 84f52a055815..04b0384d8190 100644
--- a/contrib/llvm/lib/DebugInfo/CodeView/TypeDumpVisitor.cpp
+++ b/contrib/llvm/lib/DebugInfo/CodeView/TypeDumpVisitor.cpp
@@ -26,7 +26,7 @@ using namespace llvm::codeview;
static const EnumEntry<TypeLeafKind> LeafTypeNames[] = {
#define CV_TYPE(enum, val) {#enum, enum},
-#include "llvm/DebugInfo/CodeView/TypeRecords.def"
+#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
};
#define ENUM_ENTRY(enum_class, enum) \
@@ -155,7 +155,7 @@ static StringRef getLeafTypeName(TypeLeafKind LT) {
#define TYPE_RECORD(ename, value, name) \
case ename: \
return #name;
-#include "llvm/DebugInfo/CodeView/TypeRecords.def"
+#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
default:
break;
}
diff --git a/contrib/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp b/contrib/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
index 5ed55ce4c0dc..1be156d6ea9b 100644
--- a/contrib/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
+++ b/contrib/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
@@ -84,8 +84,12 @@ static void dumpAccelSection(raw_ostream &OS, StringRef Name,
Accel.dump(OS);
}
-void DWARFContext::dump(raw_ostream &OS, DIDumpType DumpType, bool DumpEH,
- bool SummarizeTypes) {
+void DWARFContext::dump(raw_ostream &OS, DIDumpOptions DumpOpts){
+
+ DIDumpType DumpType = DumpOpts.DumpType;
+ bool DumpEH = DumpOpts.DumpEH;
+ bool SummarizeTypes = DumpOpts.SummarizeTypes;
+
if (DumpType == DIDT_All || DumpType == DIDT_Abbrev) {
OS << ".debug_abbrev contents:\n";
getDebugAbbrev()->dump(OS);
diff --git a/contrib/llvm/lib/DebugInfo/PDB/Native/InfoStream.cpp b/contrib/llvm/lib/DebugInfo/PDB/Native/InfoStream.cpp
index 2a1d12e82390..7c6069652da6 100644
--- a/contrib/llvm/lib/DebugInfo/PDB/Native/InfoStream.cpp
+++ b/contrib/llvm/lib/DebugInfo/PDB/Native/InfoStream.cpp
@@ -79,6 +79,7 @@ Error InfoStream::reload() {
break;
case uint32_t(PdbRaw_FeatureSig::MinimalDebugInfo):
Features |= PdbFeatureMinimalDebugInfo;
+ break;
default:
continue;
}
diff --git a/contrib/llvm/lib/DebugInfo/PDB/PDBContext.cpp b/contrib/llvm/lib/DebugInfo/PDB/PDBContext.cpp
index 94b81ecf561e..f6b6b951ebe1 100644
--- a/contrib/llvm/lib/DebugInfo/PDB/PDBContext.cpp
+++ b/contrib/llvm/lib/DebugInfo/PDB/PDBContext.cpp
@@ -29,8 +29,7 @@ PDBContext::PDBContext(const COFFObjectFile &Object,
Session->setLoadAddress(ImageBase.get());
}
-void PDBContext::dump(raw_ostream &OS, DIDumpType DumpType, bool DumpEH,
- bool SummarizeTypes) {}
+void PDBContext::dump(raw_ostream &OS, DIDumpOptions DumpOpts){}
DILineInfo PDBContext::getLineInfoForAddress(uint64_t Address,
DILineInfoSpecifier Specifier) {
diff --git a/contrib/llvm/lib/IR/Attributes.cpp b/contrib/llvm/lib/IR/Attributes.cpp
index 19b7c3027232..a76c944f0005 100644
--- a/contrib/llvm/lib/IR/Attributes.cpp
+++ b/contrib/llvm/lib/IR/Attributes.cpp
@@ -1006,6 +1006,10 @@ AttributeList AttributeList::get(LLVMContext &C,
for (AttributeList List : Attrs)
MaxSize = std::max(MaxSize, List.getNumAttrSets());
+ // If every list was empty, there is no point in merging the lists.
+ if (MaxSize == 0)
+ return AttributeList();
+
SmallVector<AttributeSet, 8> NewAttrSets(MaxSize);
for (unsigned I = 0; I < MaxSize; ++I) {
AttrBuilder CurBuilder;
@@ -1033,24 +1037,11 @@ AttributeList AttributeList::addAttribute(LLVMContext &C, unsigned Index,
return addAttributes(C, Index, B);
}
-AttributeList AttributeList::addAttribute(LLVMContext &C,
- ArrayRef<unsigned> Indices,
+AttributeList AttributeList::addAttribute(LLVMContext &C, unsigned Index,
Attribute A) const {
- assert(std::is_sorted(Indices.begin(), Indices.end()));
-
- SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end());
- unsigned MaxIndex = attrIdxToArrayIdx(Indices.back());
- if (MaxIndex >= AttrSets.size())
- AttrSets.resize(MaxIndex + 1);
-
- for (unsigned Index : Indices) {
- Index = attrIdxToArrayIdx(Index);
- AttrBuilder B(AttrSets[Index]);
- B.addAttribute(A);
- AttrSets[Index] = AttributeSet::get(C, B);
- }
-
- return getImpl(C, AttrSets);
+ AttrBuilder B;
+ B.addAttribute(A);
+ return addAttributes(C, Index, B);
}
AttributeList AttributeList::addAttributes(LLVMContext &C, unsigned Index,
@@ -1082,6 +1073,26 @@ AttributeList AttributeList::addAttributes(LLVMContext &C, unsigned Index,
return getImpl(C, AttrSets);
}
+AttributeList AttributeList::addParamAttribute(LLVMContext &C,
+ ArrayRef<unsigned> ArgNos,
+ Attribute A) const {
+ assert(std::is_sorted(ArgNos.begin(), ArgNos.end()));
+
+ SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end());
+ unsigned MaxIndex = attrIdxToArrayIdx(ArgNos.back() + FirstArgIndex);
+ if (MaxIndex >= AttrSets.size())
+ AttrSets.resize(MaxIndex + 1);
+
+ for (unsigned ArgNo : ArgNos) {
+ unsigned Index = attrIdxToArrayIdx(ArgNo + FirstArgIndex);
+ AttrBuilder B(AttrSets[Index]);
+ B.addAttribute(A);
+ AttrSets[Index] = AttributeSet::get(C, B);
+ }
+
+ return getImpl(C, AttrSets);
+}
+
AttributeList AttributeList::removeAttribute(LLVMContext &C, unsigned Index,
Attribute::AttrKind Kind) const {
if (!hasAttribute(Index, Kind)) return *this;
diff --git a/contrib/llvm/lib/IR/Function.cpp b/contrib/llvm/lib/IR/Function.cpp
index 39de4b0a97fa..fc68c0e3cad9 100644
--- a/contrib/llvm/lib/IR/Function.cpp
+++ b/contrib/llvm/lib/IR/Function.cpp
@@ -118,15 +118,13 @@ unsigned Argument::getParamAlignment() const {
uint64_t Argument::getDereferenceableBytes() const {
assert(getType()->isPointerTy() &&
"Only pointers have dereferenceable bytes");
- return getParent()->getDereferenceableBytes(getArgNo() +
- AttributeList::FirstArgIndex);
+ return getParent()->getParamDereferenceableBytes(getArgNo());
}
uint64_t Argument::getDereferenceableOrNullBytes() const {
assert(getType()->isPointerTy() &&
"Only pointers have dereferenceable bytes");
- return getParent()->getDereferenceableOrNullBytes(
- getArgNo() + AttributeList::FirstArgIndex);
+ return getParent()->getParamDereferenceableOrNullBytes(getArgNo());
}
bool Argument::hasNestAttr() const {
@@ -169,21 +167,20 @@ bool Argument::onlyReadsMemory() const {
void Argument::addAttrs(AttrBuilder &B) {
AttributeList AL = getParent()->getAttributes();
- AL = AL.addAttributes(Parent->getContext(),
- getArgNo() + AttributeList::FirstArgIndex, B);
+ AL = AL.addParamAttributes(Parent->getContext(), getArgNo(), B);
getParent()->setAttributes(AL);
}
void Argument::addAttr(Attribute::AttrKind Kind) {
- getParent()->addAttribute(getArgNo() + AttributeList::FirstArgIndex, Kind);
+ getParent()->addParamAttr(getArgNo(), Kind);
}
void Argument::addAttr(Attribute Attr) {
- getParent()->addAttribute(getArgNo() + AttributeList::FirstArgIndex, Attr);
+ getParent()->addParamAttr(getArgNo(), Attr);
}
void Argument::removeAttr(Attribute::AttrKind Kind) {
- getParent()->removeAttribute(getArgNo() + AttributeList::FirstArgIndex, Kind);
+ getParent()->removeParamAttr(getArgNo(), Kind);
}
bool Argument::hasAttribute(Attribute::AttrKind Kind) const {
@@ -365,6 +362,24 @@ void Function::addAttributes(unsigned i, const AttrBuilder &Attrs) {
setAttributes(PAL);
}
+void Function::addParamAttr(unsigned ArgNo, Attribute::AttrKind Kind) {
+ AttributeList PAL = getAttributes();
+ PAL = PAL.addParamAttribute(getContext(), ArgNo, Kind);
+ setAttributes(PAL);
+}
+
+void Function::addParamAttr(unsigned ArgNo, Attribute Attr) {
+ AttributeList PAL = getAttributes();
+ PAL = PAL.addParamAttribute(getContext(), ArgNo, Attr);
+ setAttributes(PAL);
+}
+
+void Function::addParamAttrs(unsigned ArgNo, const AttrBuilder &Attrs) {
+ AttributeList PAL = getAttributes();
+ PAL = PAL.addParamAttributes(getContext(), ArgNo, Attrs);
+ setAttributes(PAL);
+}
+
void Function::removeAttribute(unsigned i, Attribute::AttrKind Kind) {
AttributeList PAL = getAttributes();
PAL = PAL.removeAttribute(getContext(), i, Kind);
@@ -383,18 +398,49 @@ void Function::removeAttributes(unsigned i, const AttrBuilder &Attrs) {
setAttributes(PAL);
}
+void Function::removeParamAttr(unsigned ArgNo, Attribute::AttrKind Kind) {
+ AttributeList PAL = getAttributes();
+ PAL = PAL.removeParamAttribute(getContext(), ArgNo, Kind);
+ setAttributes(PAL);
+}
+
+void Function::removeParamAttr(unsigned ArgNo, StringRef Kind) {
+ AttributeList PAL = getAttributes();
+ PAL = PAL.removeParamAttribute(getContext(), ArgNo, Kind);
+ setAttributes(PAL);
+}
+
+void Function::removeParamAttrs(unsigned ArgNo, const AttrBuilder &Attrs) {
+ AttributeList PAL = getAttributes();
+ PAL = PAL.removeParamAttributes(getContext(), ArgNo, Attrs);
+ setAttributes(PAL);
+}
+
void Function::addDereferenceableAttr(unsigned i, uint64_t Bytes) {
AttributeList PAL = getAttributes();
PAL = PAL.addDereferenceableAttr(getContext(), i, Bytes);
setAttributes(PAL);
}
+void Function::addDereferenceableParamAttr(unsigned ArgNo, uint64_t Bytes) {
+ AttributeList PAL = getAttributes();
+ PAL = PAL.addDereferenceableParamAttr(getContext(), ArgNo, Bytes);
+ setAttributes(PAL);
+}
+
void Function::addDereferenceableOrNullAttr(unsigned i, uint64_t Bytes) {
AttributeList PAL = getAttributes();
PAL = PAL.addDereferenceableOrNullAttr(getContext(), i, Bytes);
setAttributes(PAL);
}
+void Function::addDereferenceableOrNullParamAttr(unsigned ArgNo,
+ uint64_t Bytes) {
+ AttributeList PAL = getAttributes();
+ PAL = PAL.addDereferenceableOrNullParamAttr(getContext(), ArgNo, Bytes);
+ setAttributes(PAL);
+}
+
const std::string &Function::getGC() const {
assert(hasGC() && "Function has no collector");
return getContext().getGC(*this);
diff --git a/contrib/llvm/lib/IR/Instructions.cpp b/contrib/llvm/lib/IR/Instructions.cpp
index d7baa9ebc223..46c27331ff95 100644
--- a/contrib/llvm/lib/IR/Instructions.cpp
+++ b/contrib/llvm/lib/IR/Instructions.cpp
@@ -393,7 +393,17 @@ void CallInst::addAttribute(unsigned i, Attribute Attr) {
}
void CallInst::addParamAttr(unsigned ArgNo, Attribute::AttrKind Kind) {
- addAttribute(ArgNo + AttributeList::FirstArgIndex, Kind);
+ assert(ArgNo < getNumArgOperands() && "Out of bounds");
+ AttributeList PAL = getAttributes();
+ PAL = PAL.addParamAttribute(getContext(), ArgNo, Kind);
+ setAttributes(PAL);
+}
+
+void CallInst::addParamAttr(unsigned ArgNo, Attribute Attr) {
+ assert(ArgNo < getNumArgOperands() && "Out of bounds");
+ AttributeList PAL = getAttributes();
+ PAL = PAL.addParamAttribute(getContext(), ArgNo, Attr);
+ setAttributes(PAL);
}
void CallInst::removeAttribute(unsigned i, Attribute::AttrKind Kind) {
@@ -409,7 +419,17 @@ void CallInst::removeAttribute(unsigned i, StringRef Kind) {
}
void CallInst::removeParamAttr(unsigned ArgNo, Attribute::AttrKind Kind) {
- removeAttribute(ArgNo + AttributeList::FirstArgIndex, Kind);
+ assert(ArgNo < getNumArgOperands() && "Out of bounds");
+ AttributeList PAL = getAttributes();
+ PAL = PAL.removeParamAttribute(getContext(), ArgNo, Kind);
+ setAttributes(PAL);
+}
+
+void CallInst::removeParamAttr(unsigned ArgNo, StringRef Kind) {
+ assert(ArgNo < getNumArgOperands() && "Out of bounds");
+ AttributeList PAL = getAttributes();
+ PAL = PAL.removeParamAttribute(getContext(), ArgNo, Kind);
+ setAttributes(PAL);
}
void CallInst::addDereferenceableAttr(unsigned i, uint64_t Bytes) {
@@ -808,7 +828,9 @@ void InvokeInst::addAttribute(unsigned i, Attribute Attr) {
}
void InvokeInst::addParamAttr(unsigned ArgNo, Attribute::AttrKind Kind) {
- addAttribute(ArgNo + AttributeList::FirstArgIndex, Kind);
+ AttributeList PAL = getAttributes();
+ PAL = PAL.addParamAttribute(getContext(), ArgNo, Kind);
+ setAttributes(PAL);
}
void InvokeInst::removeAttribute(unsigned i, Attribute::AttrKind Kind) {
@@ -824,7 +846,9 @@ void InvokeInst::removeAttribute(unsigned i, StringRef Kind) {
}
void InvokeInst::removeParamAttr(unsigned ArgNo, Attribute::AttrKind Kind) {
- removeAttribute(ArgNo + AttributeList::FirstArgIndex, Kind);
+ AttributeList PAL = getAttributes();
+ PAL = PAL.removeParamAttribute(getContext(), ArgNo, Kind);
+ setAttributes(PAL);
}
void InvokeInst::addDereferenceableAttr(unsigned i, uint64_t Bytes) {
diff --git a/contrib/llvm/lib/LTO/LTOBackend.cpp b/contrib/llvm/lib/LTO/LTOBackend.cpp
index 668667a53562..f9c41f5c9744 100644
--- a/contrib/llvm/lib/LTO/LTOBackend.cpp
+++ b/contrib/llvm/lib/LTO/LTOBackend.cpp
@@ -136,7 +136,8 @@ createTargetMachine(Config &Conf, const Target *TheTarget, Module &M) {
Conf.CodeModel, Conf.CGOptLevel));
}
-static void runNewPMPasses(Module &Mod, TargetMachine *TM, unsigned OptLevel) {
+static void runNewPMPasses(Module &Mod, TargetMachine *TM, unsigned OptLevel,
+ bool IsThinLTO) {
PassBuilder PB(TM);
AAManager AA;
@@ -180,7 +181,10 @@ static void runNewPMPasses(Module &Mod, TargetMachine *TM, unsigned OptLevel) {
break;
}
- MPM = PB.buildLTODefaultPipeline(OL, false /* DebugLogging */);
+ if (IsThinLTO)
+ MPM = PB.buildThinLTODefaultPipeline(OL, false /* DebugLogging */);
+ else
+ MPM = PB.buildLTODefaultPipeline(OL, false /* DebugLogging */);
MPM.run(Mod, MAM);
// FIXME (davide): verify the output.
@@ -258,17 +262,12 @@ static void runOldPMPasses(Config &Conf, Module &Mod, TargetMachine *TM,
bool opt(Config &Conf, TargetMachine *TM, unsigned Task, Module &Mod,
bool IsThinLTO, ModuleSummaryIndex *ExportSummary,
const ModuleSummaryIndex *ImportSummary) {
- // There's still no ThinLTO pipeline hooked up in the new pass manager,
- // once there is one, we can just remove this.
- if (LTOUseNewPM && IsThinLTO)
- report_fatal_error("ThinLTO not supported with the new PM yet!");
-
// FIXME: Plumb the combined index into the new pass manager.
if (!Conf.OptPipeline.empty())
runNewPMCustomPasses(Mod, TM, Conf.OptPipeline, Conf.AAPipeline,
Conf.DisableVerify);
else if (LTOUseNewPM)
- runNewPMPasses(Mod, TM, Conf.OptLevel);
+ runNewPMPasses(Mod, TM, Conf.OptLevel, IsThinLTO);
else
runOldPMPasses(Conf, Mod, TM, IsThinLTO, ExportSummary, ImportSummary);
return !Conf.PostOptModuleHook || Conf.PostOptModuleHook(Task, Mod);
diff --git a/contrib/llvm/lib/MC/MCCodeView.cpp b/contrib/llvm/lib/MC/MCCodeView.cpp
index a0a0ef312276..6c9a4f9f982d 100644
--- a/contrib/llvm/lib/MC/MCCodeView.cpp
+++ b/contrib/llvm/lib/MC/MCCodeView.cpp
@@ -12,11 +12,11 @@
//===----------------------------------------------------------------------===//
#include "llvm/MC/MCCodeView.h"
-#include "llvm/MC/MCAsmLayout.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/DebugInfo/CodeView/Line.h"
#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
+#include "llvm/MC/MCAsmLayout.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCObjectStreamer.h"
#include "llvm/MC/MCValue.h"
diff --git a/contrib/llvm/lib/Object/MachOObjectFile.cpp b/contrib/llvm/lib/Object/MachOObjectFile.cpp
index bfb8875f47d4..084159a61f55 100644
--- a/contrib/llvm/lib/Object/MachOObjectFile.cpp
+++ b/contrib/llvm/lib/Object/MachOObjectFile.cpp
@@ -3269,7 +3269,6 @@ void MachOBindEntry::moveNext() {
if (ImmValue) {
SignExtended = MachO::BIND_OPCODE_MASK | ImmValue;
Ordinal = SignExtended;
- LibraryOrdinalSet = true;
if (Ordinal < MachO::BIND_SPECIAL_DYLIB_FLAT_LOOKUP) {
*E = malformedError("for BIND_OPCODE_SET_DYLIB_SPECIAL_IMM unknown "
"special ordinal: " + Twine((int)Ordinal) + " for opcode at: "
@@ -3279,6 +3278,7 @@ void MachOBindEntry::moveNext() {
}
} else
Ordinal = 0;
+ LibraryOrdinalSet = true;
DEBUG_WITH_TYPE(
"mach-o-bind",
dbgs() << "BIND_OPCODE_SET_DYLIB_SPECIAL_IMM: "
diff --git a/contrib/llvm/lib/Object/WindowsResource.cpp b/contrib/llvm/lib/Object/WindowsResource.cpp
index b52563469094..e46d38e466a0 100644
--- a/contrib/llvm/lib/Object/WindowsResource.cpp
+++ b/contrib/llvm/lib/Object/WindowsResource.cpp
@@ -12,20 +12,23 @@
//===----------------------------------------------------------------------===//
#include "llvm/Object/WindowsResource.h"
-#include "llvm/Object/Error.h"
+#include "llvm/Support/COFF.h"
+#include <sstream>
#include <system_error>
namespace llvm {
namespace object {
-static const size_t ResourceMagicSize = 16;
-
-static const size_t NullEntrySize = 16;
-
#define RETURN_IF_ERROR(X) \
if (auto EC = X) \
return EC;
+const uint32_t MIN_HEADER_SIZE = 7 * sizeof(uint32_t) + 2 * sizeof(uint16_t);
+
+static const size_t ResourceMagicSize = 16;
+
+static const size_t NullEntrySize = 16;
+
WindowsResource::WindowsResource(MemoryBufferRef Source)
: Binary(Binary::ID_WinRes, Source) {
size_t LeadingSize = ResourceMagicSize + NullEntrySize;
@@ -33,8 +36,6 @@ WindowsResource::WindowsResource(MemoryBufferRef Source)
support::little);
}
-WindowsResource::~WindowsResource() = default;
-
Expected<std::unique_ptr<WindowsResource>>
WindowsResource::createWindowsResource(MemoryBufferRef Source) {
if (Source.getBufferSize() < ResourceMagicSize + NullEntrySize)
@@ -72,19 +73,150 @@ Error ResourceEntryRef::moveNext(bool &End) {
return Error::success();
}
+static Error readStringOrId(BinaryStreamReader &Reader, uint16_t &ID,
+ ArrayRef<UTF16> &Str, bool &IsString) {
+ uint16_t IDFlag;
+ RETURN_IF_ERROR(Reader.readInteger(IDFlag));
+ IsString = IDFlag != 0xffff;
+
+ if (IsString) {
+ Reader.setOffset(
+ Reader.getOffset() -
+ sizeof(uint16_t)); // Re-read the bytes which we used to check the flag.
+ RETURN_IF_ERROR(Reader.readWideString(Str));
+ } else
+ RETURN_IF_ERROR(Reader.readInteger(ID));
+
+ return Error::success();
+}
+
Error ResourceEntryRef::loadNext() {
uint32_t DataSize;
RETURN_IF_ERROR(Reader.readInteger(DataSize));
uint32_t HeaderSize;
RETURN_IF_ERROR(Reader.readInteger(HeaderSize));
- // The data and header size ints are themselves part of the header, so we must
- // subtract them from the size.
- RETURN_IF_ERROR(
- Reader.readStreamRef(HeaderBytes, HeaderSize - 2 * sizeof(uint32_t)));
- RETURN_IF_ERROR(Reader.readStreamRef(DataBytes, DataSize));
+
+ if (HeaderSize < MIN_HEADER_SIZE)
+ return make_error<GenericBinaryError>("Header size is too small.",
+ object_error::parse_failed);
+
+ RETURN_IF_ERROR(readStringOrId(Reader, TypeID, Type, IsStringType));
+
+ RETURN_IF_ERROR(readStringOrId(Reader, NameID, Name, IsStringName));
+
RETURN_IF_ERROR(Reader.padToAlignment(sizeof(uint32_t)));
+
+ RETURN_IF_ERROR(Reader.readObject(Suffix));
+
+ RETURN_IF_ERROR(Reader.readArray(Data, DataSize));
+
+ RETURN_IF_ERROR(Reader.padToAlignment(sizeof(uint32_t)));
+
+ return Error::success();
+}
+
+WindowsResourceParser::WindowsResourceParser() {}
+
+Error WindowsResourceParser::parse(WindowsResource *WR) {
+ auto EntryOrErr = WR->getHeadEntry();
+ if (!EntryOrErr)
+ return EntryOrErr.takeError();
+
+ ResourceEntryRef Entry = EntryOrErr.get();
+ bool End = false;
+
+ while (!End) {
+
+ Root.addEntry(Entry);
+
+ RETURN_IF_ERROR(Entry.moveNext(End));
+ }
+
return Error::success();
}
+void WindowsResourceParser::printTree() const {
+ ScopedPrinter Writer(outs());
+ Root.print(Writer, "Resource Tree");
+}
+
+void WindowsResourceParser::TreeNode::addEntry(const ResourceEntryRef &Entry) {
+ TreeNode &TypeNode = addTypeNode(Entry);
+ TreeNode &NameNode = TypeNode.addNameNode(Entry);
+ NameNode.addLanguageNode(Entry);
+}
+
+WindowsResourceParser::TreeNode::TreeNode(ArrayRef<UTF16> NameRef)
+ : Name(NameRef) {}
+
+WindowsResourceParser::TreeNode &
+WindowsResourceParser::TreeNode::addTypeNode(const ResourceEntryRef &Entry) {
+ if (Entry.checkTypeString())
+ return addChild(Entry.getTypeString());
+ else
+ return addChild(Entry.getTypeID());
+}
+
+WindowsResourceParser::TreeNode &
+WindowsResourceParser::TreeNode::addNameNode(const ResourceEntryRef &Entry) {
+ if (Entry.checkNameString())
+ return addChild(Entry.getNameString());
+ else
+ return addChild(Entry.getNameID());
+}
+
+WindowsResourceParser::TreeNode &
+WindowsResourceParser::TreeNode::addLanguageNode(
+ const ResourceEntryRef &Entry) {
+ return addChild(Entry.getLanguage());
+}
+
+WindowsResourceParser::TreeNode &
+WindowsResourceParser::TreeNode::addChild(uint32_t ID) {
+ auto Child = IDChildren.find(ID);
+ if (Child == IDChildren.end()) {
+ auto NewChild = llvm::make_unique<WindowsResourceParser::TreeNode>(ID);
+ WindowsResourceParser::TreeNode &Node = *NewChild;
+ IDChildren.emplace(ID, std::move(NewChild));
+ return Node;
+ } else
+ return *(Child->second);
+}
+
+WindowsResourceParser::TreeNode &
+WindowsResourceParser::TreeNode::addChild(ArrayRef<UTF16> NameRef) {
+ std::string NameString;
+ ArrayRef<UTF16> CorrectedName;
+ std::vector<UTF16> EndianCorrectedName;
+ if (llvm::sys::IsBigEndianHost) {
+ EndianCorrectedName.resize(NameRef.size() + 1);
+ std::copy(NameRef.begin(), NameRef.end(), EndianCorrectedName.begin() + 1);
+ EndianCorrectedName[0] = UNI_UTF16_BYTE_ORDER_MARK_SWAPPED;
+ CorrectedName = makeArrayRef(EndianCorrectedName);
+ } else
+ CorrectedName = NameRef;
+ llvm::convertUTF16ToUTF8String(CorrectedName, NameString);
+
+ auto Child = StringChildren.find(NameString);
+ if (Child == StringChildren.end()) {
+ auto NewChild = llvm::make_unique<WindowsResourceParser::TreeNode>(NameRef);
+ WindowsResourceParser::TreeNode &Node = *NewChild;
+ StringChildren.emplace(NameString, std::move(NewChild));
+ return Node;
+ } else
+ return *(Child->second);
+}
+
+void WindowsResourceParser::TreeNode::print(ScopedPrinter &Writer,
+ StringRef Name) const {
+ ListScope NodeScope(Writer, Name);
+ for (auto const &Child : StringChildren) {
+ Child.second->print(Writer, Child.first);
+ }
+ for (auto const &Child : IDChildren) {
+ Child.second->print(Writer, to_string(Child.first));
+ }
+}
+
} // namespace object
} // namespace llvm
diff --git a/contrib/llvm/lib/ObjectYAML/CodeViewYAMLDebugSections.cpp b/contrib/llvm/lib/ObjectYAML/CodeViewYAMLDebugSections.cpp
new file mode 100644
index 000000000000..f652ff57f30d
--- /dev/null
+++ b/contrib/llvm/lib/ObjectYAML/CodeViewYAMLDebugSections.cpp
@@ -0,0 +1,127 @@
+//===- CodeViewYAMLDebugSections.cpp - CodeView YAMLIO debug sections -----===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ObjectYAML/CodeViewYAMLDebugSections.h"
+
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/DebugInfo/CodeView/CodeViewError.h"
+#include "llvm/DebugInfo/CodeView/EnumTables.h"
+#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
+
+using namespace llvm;
+using namespace llvm::codeview;
+using namespace llvm::CodeViewYAML;
+using namespace llvm::CodeViewYAML::detail;
+using namespace llvm::yaml;
+
+LLVM_YAML_IS_SEQUENCE_VECTOR(SourceFileChecksumEntry)
+LLVM_YAML_IS_SEQUENCE_VECTOR(SourceLineEntry)
+LLVM_YAML_IS_SEQUENCE_VECTOR(SourceColumnEntry)
+LLVM_YAML_IS_SEQUENCE_VECTOR(SourceLineBlock)
+LLVM_YAML_IS_SEQUENCE_VECTOR(SourceLineInfo)
+LLVM_YAML_IS_SEQUENCE_VECTOR(InlineeSite)
+LLVM_YAML_IS_SEQUENCE_VECTOR(InlineeInfo)
+LLVM_YAML_IS_SEQUENCE_VECTOR(StringRef)
+
+LLVM_YAML_DECLARE_SCALAR_TRAITS(HexFormattedString, false)
+LLVM_YAML_DECLARE_ENUM_TRAITS(FileChecksumKind)
+LLVM_YAML_DECLARE_BITSET_TRAITS(LineFlags)
+
+LLVM_YAML_DECLARE_MAPPING_TRAITS(CodeViewYAML::SourceLineEntry)
+LLVM_YAML_DECLARE_MAPPING_TRAITS(CodeViewYAML::SourceColumnEntry)
+LLVM_YAML_DECLARE_MAPPING_TRAITS(CodeViewYAML::SourceFileChecksumEntry)
+LLVM_YAML_DECLARE_MAPPING_TRAITS(CodeViewYAML::SourceLineInfo)
+LLVM_YAML_DECLARE_MAPPING_TRAITS(CodeViewYAML::SourceLineBlock)
+LLVM_YAML_DECLARE_MAPPING_TRAITS(CodeViewYAML::InlineeInfo)
+LLVM_YAML_DECLARE_MAPPING_TRAITS(CodeViewYAML::InlineeSite)
+
+void ScalarBitSetTraits<LineFlags>::bitset(IO &io, LineFlags &Flags) {
+ io.bitSetCase(Flags, "HasColumnInfo", LF_HaveColumns);
+ io.enumFallback<Hex16>(Flags);
+}
+
+void ScalarEnumerationTraits<FileChecksumKind>::enumeration(
+ IO &io, FileChecksumKind &Kind) {
+ io.enumCase(Kind, "None", FileChecksumKind::None);
+ io.enumCase(Kind, "MD5", FileChecksumKind::MD5);
+ io.enumCase(Kind, "SHA1", FileChecksumKind::SHA1);
+ io.enumCase(Kind, "SHA256", FileChecksumKind::SHA256);
+}
+
+void ScalarTraits<HexFormattedString>::output(const HexFormattedString &Value,
+ void *ctx, raw_ostream &Out) {
+ StringRef Bytes(reinterpret_cast<const char *>(Value.Bytes.data()),
+ Value.Bytes.size());
+ Out << toHex(Bytes);
+}
+
+StringRef ScalarTraits<HexFormattedString>::input(StringRef Scalar, void *ctxt,
+ HexFormattedString &Value) {
+ std::string H = fromHex(Scalar);
+ Value.Bytes.assign(H.begin(), H.end());
+ return StringRef();
+}
+
+void MappingTraits<SourceLineEntry>::mapping(IO &IO, SourceLineEntry &Obj) {
+ IO.mapRequired("Offset", Obj.Offset);
+ IO.mapRequired("LineStart", Obj.LineStart);
+ IO.mapRequired("IsStatement", Obj.IsStatement);
+ IO.mapRequired("EndDelta", Obj.EndDelta);
+}
+
+void MappingTraits<SourceColumnEntry>::mapping(IO &IO, SourceColumnEntry &Obj) {
+ IO.mapRequired("StartColumn", Obj.StartColumn);
+ IO.mapRequired("EndColumn", Obj.EndColumn);
+}
+
+void MappingTraits<SourceLineBlock>::mapping(IO &IO, SourceLineBlock &Obj) {
+ IO.mapRequired("FileName", Obj.FileName);
+ IO.mapRequired("Lines", Obj.Lines);
+ IO.mapRequired("Columns", Obj.Columns);
+}
+
+void MappingTraits<SourceFileChecksumEntry>::mapping(
+ IO &IO, SourceFileChecksumEntry &Obj) {
+ IO.mapRequired("FileName", Obj.FileName);
+ IO.mapRequired("Kind", Obj.Kind);
+ IO.mapRequired("Checksum", Obj.ChecksumBytes);
+}
+
+void MappingTraits<SourceLineInfo>::mapping(IO &IO, SourceLineInfo &Obj) {
+ IO.mapRequired("CodeSize", Obj.CodeSize);
+
+ IO.mapRequired("Flags", Obj.Flags);
+ IO.mapRequired("RelocOffset", Obj.RelocOffset);
+ IO.mapRequired("RelocSegment", Obj.RelocSegment);
+ IO.mapRequired("Blocks", Obj.Blocks);
+}
+
+void MappingTraits<SourceFileInfo>::mapping(IO &IO, SourceFileInfo &Obj) {
+ IO.mapOptional("Checksums", Obj.FileChecksums);
+ IO.mapOptional("Lines", Obj.LineFragments);
+ IO.mapOptional("InlineeLines", Obj.Inlinees);
+}
+
+void MappingTraits<InlineeSite>::mapping(IO &IO, InlineeSite &Obj) {
+ IO.mapRequired("FileName", Obj.FileName);
+ IO.mapRequired("LineNum", Obj.SourceLineNum);
+ IO.mapRequired("Inlinee", Obj.Inlinee);
+ IO.mapOptional("ExtraFiles", Obj.ExtraFiles);
+}
+
+void MappingTraits<InlineeInfo>::mapping(IO &IO, InlineeInfo &Obj) {
+ IO.mapRequired("HasExtraFiles", Obj.HasExtraFiles);
+ IO.mapRequired("Sites", Obj.Sites);
+}
diff --git a/contrib/llvm/lib/ObjectYAML/CodeViewYAMLSymbols.cpp b/contrib/llvm/lib/ObjectYAML/CodeViewYAMLSymbols.cpp
new file mode 100644
index 000000000000..6e8bb5c7372c
--- /dev/null
+++ b/contrib/llvm/lib/ObjectYAML/CodeViewYAMLSymbols.cpp
@@ -0,0 +1,496 @@
+//===- CodeViewYAMLSymbols.cpp - 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.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ObjectYAML/CodeViewYAMLSymbols.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
+#include "llvm/DebugInfo/CodeView/CodeViewError.h"
+#include "llvm/DebugInfo/CodeView/EnumTables.h"
+#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
+#include "llvm/DebugInfo/CodeView/SymbolSerializer.h"
+
+using namespace llvm;
+using namespace llvm::codeview;
+using namespace llvm::CodeViewYAML;
+using namespace llvm::CodeViewYAML::detail;
+using namespace llvm::yaml;
+
+LLVM_YAML_IS_SEQUENCE_VECTOR(StringRef)
+LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(TypeIndex)
+
+// We only need to declare these, the definitions are in CodeViewYAMLTypes.cpp
+LLVM_YAML_DECLARE_SCALAR_TRAITS(APSInt, false)
+LLVM_YAML_DECLARE_SCALAR_TRAITS(TypeIndex, false)
+
+LLVM_YAML_DECLARE_ENUM_TRAITS(SymbolKind)
+
+LLVM_YAML_DECLARE_BITSET_TRAITS(CompileSym2Flags)
+LLVM_YAML_DECLARE_BITSET_TRAITS(CompileSym3Flags)
+LLVM_YAML_DECLARE_BITSET_TRAITS(ExportFlags)
+LLVM_YAML_DECLARE_BITSET_TRAITS(LocalSymFlags)
+LLVM_YAML_DECLARE_BITSET_TRAITS(ProcSymFlags)
+LLVM_YAML_DECLARE_BITSET_TRAITS(FrameProcedureOptions)
+LLVM_YAML_DECLARE_ENUM_TRAITS(CPUType)
+LLVM_YAML_DECLARE_ENUM_TRAITS(RegisterId)
+LLVM_YAML_DECLARE_ENUM_TRAITS(TrampolineType)
+LLVM_YAML_DECLARE_ENUM_TRAITS(ThunkOrdinal)
+
+void ScalarEnumerationTraits<SymbolKind>::enumeration(IO &io,
+ SymbolKind &Value) {
+ auto SymbolNames = getSymbolTypeNames();
+ for (const auto &E : SymbolNames)
+ io.enumCase(Value, E.Name.str().c_str(), E.Value);
+}
+
+void ScalarBitSetTraits<CompileSym2Flags>::bitset(IO &io,
+ CompileSym2Flags &Flags) {
+ auto FlagNames = getCompileSym2FlagNames();
+ for (const auto &E : FlagNames) {
+ io.bitSetCase(Flags, E.Name.str().c_str(),
+ static_cast<CompileSym2Flags>(E.Value));
+ }
+}
+
+void ScalarBitSetTraits<CompileSym3Flags>::bitset(IO &io,
+ CompileSym3Flags &Flags) {
+ auto FlagNames = getCompileSym3FlagNames();
+ for (const auto &E : FlagNames) {
+ io.bitSetCase(Flags, E.Name.str().c_str(),
+ static_cast<CompileSym3Flags>(E.Value));
+ }
+}
+
+void ScalarBitSetTraits<ExportFlags>::bitset(IO &io, ExportFlags &Flags) {
+ auto FlagNames = getExportSymFlagNames();
+ for (const auto &E : FlagNames) {
+ io.bitSetCase(Flags, E.Name.str().c_str(),
+ static_cast<ExportFlags>(E.Value));
+ }
+}
+
+void ScalarBitSetTraits<LocalSymFlags>::bitset(IO &io, LocalSymFlags &Flags) {
+ auto FlagNames = getLocalFlagNames();
+ for (const auto &E : FlagNames) {
+ io.bitSetCase(Flags, E.Name.str().c_str(),
+ static_cast<LocalSymFlags>(E.Value));
+ }
+}
+
+void ScalarBitSetTraits<ProcSymFlags>::bitset(IO &io, ProcSymFlags &Flags) {
+ auto FlagNames = getProcSymFlagNames();
+ for (const auto &E : FlagNames) {
+ io.bitSetCase(Flags, E.Name.str().c_str(),
+ static_cast<ProcSymFlags>(E.Value));
+ }
+}
+
+void ScalarBitSetTraits<FrameProcedureOptions>::bitset(
+ IO &io, FrameProcedureOptions &Flags) {
+ auto FlagNames = getFrameProcSymFlagNames();
+ for (const auto &E : FlagNames) {
+ io.bitSetCase(Flags, E.Name.str().c_str(),
+ static_cast<FrameProcedureOptions>(E.Value));
+ }
+}
+
+void ScalarEnumerationTraits<CPUType>::enumeration(IO &io, CPUType &Cpu) {
+ auto CpuNames = getCPUTypeNames();
+ for (const auto &E : CpuNames) {
+ io.enumCase(Cpu, E.Name.str().c_str(), static_cast<CPUType>(E.Value));
+ }
+}
+
+void ScalarEnumerationTraits<RegisterId>::enumeration(IO &io, RegisterId &Reg) {
+ auto RegNames = getRegisterNames();
+ for (const auto &E : RegNames) {
+ io.enumCase(Reg, E.Name.str().c_str(), static_cast<RegisterId>(E.Value));
+ }
+ io.enumFallback<Hex16>(Reg);
+}
+
+void ScalarEnumerationTraits<TrampolineType>::enumeration(
+ IO &io, TrampolineType &Tramp) {
+ auto TrampNames = getTrampolineNames();
+ for (const auto &E : TrampNames) {
+ io.enumCase(Tramp, E.Name.str().c_str(),
+ static_cast<TrampolineType>(E.Value));
+ }
+}
+
+void ScalarEnumerationTraits<ThunkOrdinal>::enumeration(IO &io,
+ ThunkOrdinal &Ord) {
+ auto ThunkNames = getThunkOrdinalNames();
+ for (const auto &E : ThunkNames) {
+ io.enumCase(Ord, E.Name.str().c_str(), static_cast<ThunkOrdinal>(E.Value));
+ }
+}
+
+namespace llvm {
+namespace CodeViewYAML {
+namespace detail {
+
+struct SymbolRecordBase {
+ codeview::SymbolKind Kind;
+ explicit SymbolRecordBase(codeview::SymbolKind K) : Kind(K) {}
+
+ virtual ~SymbolRecordBase() {}
+ virtual void map(yaml::IO &io) = 0;
+ virtual codeview::CVSymbol
+ toCodeViewSymbol(BumpPtrAllocator &Allocator) const = 0;
+ virtual Error fromCodeViewSymbol(codeview::CVSymbol Type) = 0;
+};
+
+template <typename T> struct SymbolRecordImpl : public SymbolRecordBase {
+ explicit SymbolRecordImpl(codeview::SymbolKind K)
+ : SymbolRecordBase(K), Symbol(static_cast<SymbolRecordKind>(K)) {}
+
+ void map(yaml::IO &io) override;
+
+ codeview::CVSymbol
+ toCodeViewSymbol(BumpPtrAllocator &Allocator) const override {
+ return SymbolSerializer::writeOneSymbol(Symbol, Allocator);
+ }
+ Error fromCodeViewSymbol(codeview::CVSymbol CVS) override {
+ return SymbolDeserializer::deserializeAs<T>(CVS, Symbol);
+ }
+
+ mutable T Symbol;
+};
+
+template <> void SymbolRecordImpl<ScopeEndSym>::map(IO &IO) {}
+
+template <> void SymbolRecordImpl<Thunk32Sym>::map(IO &IO) {
+ IO.mapRequired("Parent", Symbol.Parent);
+ IO.mapRequired("End", Symbol.End);
+ IO.mapRequired("Next", Symbol.Next);
+ IO.mapRequired("Off", Symbol.Offset);
+ IO.mapRequired("Seg", Symbol.Segment);
+ IO.mapRequired("Len", Symbol.Length);
+ IO.mapRequired("Ordinal", Symbol.Thunk);
+}
+
+template <> void SymbolRecordImpl<TrampolineSym>::map(IO &IO) {
+ IO.mapRequired("Type", Symbol.Type);
+ IO.mapRequired("Size", Symbol.Size);
+ IO.mapRequired("ThunkOff", Symbol.ThunkOffset);
+ IO.mapRequired("TargetOff", Symbol.TargetOffset);
+ IO.mapRequired("ThunkSection", Symbol.ThunkSection);
+ IO.mapRequired("TargetSection", Symbol.TargetSection);
+}
+
+template <> void SymbolRecordImpl<SectionSym>::map(IO &IO) {
+ IO.mapRequired("SectionNumber", Symbol.SectionNumber);
+ IO.mapRequired("Alignment", Symbol.Alignment);
+ IO.mapRequired("Rva", Symbol.Rva);
+ IO.mapRequired("Length", Symbol.Length);
+ IO.mapRequired("Characteristics", Symbol.Characteristics);
+ IO.mapRequired("Name", Symbol.Name);
+}
+
+template <> void SymbolRecordImpl<CoffGroupSym>::map(IO &IO) {
+ IO.mapRequired("Size", Symbol.Size);
+ IO.mapRequired("Characteristics", Symbol.Characteristics);
+ IO.mapRequired("Offset", Symbol.Offset);
+ IO.mapRequired("Segment", Symbol.Segment);
+ IO.mapRequired("Name", Symbol.Name);
+}
+
+template <> void SymbolRecordImpl<ExportSym>::map(IO &IO) {
+ IO.mapRequired("Ordinal", Symbol.Ordinal);
+ IO.mapRequired("Flags", Symbol.Flags);
+ IO.mapRequired("Name", Symbol.Name);
+}
+
+template <> void SymbolRecordImpl<ProcSym>::map(IO &IO) {
+ // TODO: Print the linkage name
+
+ IO.mapRequired("PtrParent", Symbol.Parent);
+ IO.mapRequired("PtrEnd", Symbol.End);
+ IO.mapRequired("PtrNext", Symbol.Next);
+ IO.mapRequired("CodeSize", Symbol.CodeSize);
+ IO.mapRequired("DbgStart", Symbol.DbgStart);
+ IO.mapRequired("DbgEnd", Symbol.DbgEnd);
+ IO.mapRequired("FunctionType", Symbol.FunctionType);
+ IO.mapRequired("Segment", Symbol.Segment);
+ IO.mapRequired("Flags", Symbol.Flags);
+ IO.mapRequired("DisplayName", Symbol.Name);
+}
+
+template <> void SymbolRecordImpl<RegisterSym>::map(IO &IO) {
+ IO.mapRequired("Type", Symbol.Index);
+ IO.mapRequired("Seg", Symbol.Register);
+ IO.mapRequired("Name", Symbol.Name);
+}
+
+template <> void SymbolRecordImpl<PublicSym32>::map(IO &IO) {
+ IO.mapRequired("Type", Symbol.Index);
+ IO.mapRequired("Seg", Symbol.Segment);
+ IO.mapRequired("Off", Symbol.Offset);
+ IO.mapRequired("Name", Symbol.Name);
+}
+
+template <> void SymbolRecordImpl<ProcRefSym>::map(IO &IO) {
+ IO.mapRequired("SumName", Symbol.SumName);
+ IO.mapRequired("SymOffset", Symbol.SymOffset);
+ IO.mapRequired("Mod", Symbol.Module);
+ IO.mapRequired("Name", Symbol.Name);
+}
+
+template <> void SymbolRecordImpl<EnvBlockSym>::map(IO &IO) {
+ IO.mapRequired("Entries", Symbol.Fields);
+}
+
+template <> void SymbolRecordImpl<InlineSiteSym>::map(IO &IO) {
+ IO.mapRequired("PtrParent", Symbol.Parent);
+ IO.mapRequired("PtrEnd", Symbol.End);
+ IO.mapRequired("Inlinee", Symbol.Inlinee);
+ // TODO: The binary annotations
+}
+
+template <> void SymbolRecordImpl<LocalSym>::map(IO &IO) {
+ IO.mapRequired("Type", Symbol.Type);
+ IO.mapRequired("Flags", Symbol.Flags);
+ IO.mapRequired("VarName", Symbol.Name);
+}
+
+template <> void SymbolRecordImpl<DefRangeSym>::map(IO &IO) {
+ // TODO: Print the subfields
+}
+
+template <> void SymbolRecordImpl<DefRangeSubfieldSym>::map(IO &IO) {
+ // TODO: Print the subfields
+}
+
+template <> void SymbolRecordImpl<DefRangeRegisterSym>::map(IO &IO) {
+ // TODO: Print the subfields
+}
+
+template <> void SymbolRecordImpl<DefRangeFramePointerRelSym>::map(IO &IO) {
+ // TODO: Print the subfields
+}
+
+template <> void SymbolRecordImpl<DefRangeSubfieldRegisterSym>::map(IO &IO) {
+ // TODO: Print the subfields
+}
+
+template <>
+void SymbolRecordImpl<DefRangeFramePointerRelFullScopeSym>::map(IO &IO) {
+ // TODO: Print the subfields
+}
+
+template <> void SymbolRecordImpl<DefRangeRegisterRelSym>::map(IO &IO) {
+ // TODO: Print the subfields
+}
+
+template <> void SymbolRecordImpl<BlockSym>::map(IO &IO) {
+ // TODO: Print the linkage name
+ IO.mapRequired("PtrParent", Symbol.Parent);
+ IO.mapRequired("PtrEnd", Symbol.End);
+ IO.mapRequired("CodeSize", Symbol.CodeSize);
+ IO.mapRequired("Segment", Symbol.Segment);
+ IO.mapRequired("BlockName", Symbol.Name);
+}
+
+template <> void SymbolRecordImpl<LabelSym>::map(IO &IO) {
+ // TODO: Print the linkage name
+ IO.mapRequired("Segment", Symbol.Segment);
+ IO.mapRequired("Flags", Symbol.Flags);
+ IO.mapRequired("Flags", Symbol.Flags);
+ IO.mapRequired("DisplayName", Symbol.Name);
+}
+
+template <> void SymbolRecordImpl<ObjNameSym>::map(IO &IO) {
+ IO.mapRequired("Signature", Symbol.Signature);
+ IO.mapRequired("ObjectName", Symbol.Name);
+}
+
+template <> void SymbolRecordImpl<Compile2Sym>::map(IO &IO) {
+ IO.mapRequired("Flags", Symbol.Flags);
+ IO.mapRequired("Machine", Symbol.Machine);
+ IO.mapRequired("FrontendMajor", Symbol.VersionFrontendMajor);
+ IO.mapRequired("FrontendMinor", Symbol.VersionFrontendMinor);
+ IO.mapRequired("FrontendBuild", Symbol.VersionFrontendBuild);
+ IO.mapRequired("BackendMajor", Symbol.VersionBackendMajor);
+ IO.mapRequired("BackendMinor", Symbol.VersionBackendMinor);
+ IO.mapRequired("BackendBuild", Symbol.VersionBackendBuild);
+ IO.mapRequired("Version", Symbol.Version);
+}
+
+template <> void SymbolRecordImpl<Compile3Sym>::map(IO &IO) {
+ IO.mapRequired("Flags", Symbol.Flags);
+ IO.mapRequired("Machine", Symbol.Machine);
+ IO.mapRequired("FrontendMajor", Symbol.VersionFrontendMajor);
+ IO.mapRequired("FrontendMinor", Symbol.VersionFrontendMinor);
+ IO.mapRequired("FrontendBuild", Symbol.VersionFrontendBuild);
+ IO.mapRequired("FrontendQFE", Symbol.VersionFrontendQFE);
+ IO.mapRequired("BackendMajor", Symbol.VersionBackendMajor);
+ IO.mapRequired("BackendMinor", Symbol.VersionBackendMinor);
+ IO.mapRequired("BackendBuild", Symbol.VersionBackendBuild);
+ IO.mapRequired("BackendQFE", Symbol.VersionBackendQFE);
+ IO.mapRequired("Version", Symbol.Version);
+}
+
+template <> void SymbolRecordImpl<FrameProcSym>::map(IO &IO) {
+ IO.mapRequired("TotalFrameBytes", Symbol.TotalFrameBytes);
+ IO.mapRequired("PaddingFrameBytes", Symbol.PaddingFrameBytes);
+ IO.mapRequired("OffsetToPadding", Symbol.OffsetToPadding);
+ IO.mapRequired("BytesOfCalleeSavedRegisters",
+ Symbol.BytesOfCalleeSavedRegisters);
+ IO.mapRequired("OffsetOfExceptionHandler", Symbol.OffsetOfExceptionHandler);
+ IO.mapRequired("SectionIdOfExceptionHandler",
+ Symbol.SectionIdOfExceptionHandler);
+ IO.mapRequired("Flags", Symbol.Flags);
+}
+
+template <> void SymbolRecordImpl<CallSiteInfoSym>::map(IO &IO) {
+ // TODO: Map Linkage Name
+ IO.mapRequired("Segment", Symbol.Segment);
+ IO.mapRequired("Type", Symbol.Type);
+}
+
+template <> void SymbolRecordImpl<FileStaticSym>::map(IO &IO) {
+ IO.mapRequired("Index", Symbol.Index);
+ IO.mapRequired("ModFilenameOffset", Symbol.ModFilenameOffset);
+ IO.mapRequired("Flags", Symbol.Flags);
+ IO.mapRequired("Name", Symbol.Name);
+}
+
+template <> void SymbolRecordImpl<HeapAllocationSiteSym>::map(IO &IO) {
+ // TODO: Map Linkage Name
+ IO.mapRequired("Segment", Symbol.Segment);
+ IO.mapRequired("CallInstructionSize", Symbol.CallInstructionSize);
+ IO.mapRequired("Type", Symbol.Type);
+}
+
+template <> void SymbolRecordImpl<FrameCookieSym>::map(IO &IO) {
+ // TODO: Map Linkage Name
+ IO.mapRequired("Register", Symbol.Register);
+ IO.mapRequired("CookieKind", Symbol.CookieKind);
+ IO.mapRequired("Flags", Symbol.Flags);
+}
+
+template <> void SymbolRecordImpl<CallerSym>::map(IO &IO) {
+ IO.mapRequired("FuncID", Symbol.Indices);
+}
+
+template <> void SymbolRecordImpl<UDTSym>::map(IO &IO) {
+ IO.mapRequired("Type", Symbol.Type);
+ IO.mapRequired("UDTName", Symbol.Name);
+}
+
+template <> void SymbolRecordImpl<BuildInfoSym>::map(IO &IO) {
+ IO.mapRequired("BuildId", Symbol.BuildId);
+}
+
+template <> void SymbolRecordImpl<BPRelativeSym>::map(IO &IO) {
+ IO.mapRequired("Offset", Symbol.Offset);
+ IO.mapRequired("Type", Symbol.Type);
+ IO.mapRequired("VarName", Symbol.Name);
+}
+
+template <> void SymbolRecordImpl<RegRelativeSym>::map(IO &IO) {
+ IO.mapRequired("Offset", Symbol.Offset);
+ IO.mapRequired("Type", Symbol.Type);
+ IO.mapRequired("Register", Symbol.Register);
+ IO.mapRequired("VarName", Symbol.Name);
+}
+
+template <> void SymbolRecordImpl<ConstantSym>::map(IO &IO) {
+ IO.mapRequired("Type", Symbol.Type);
+ IO.mapRequired("Value", Symbol.Value);
+ IO.mapRequired("Name", Symbol.Name);
+}
+
+template <> void SymbolRecordImpl<DataSym>::map(IO &IO) {
+ // TODO: Map linkage name
+ IO.mapRequired("Type", Symbol.Type);
+ IO.mapRequired("DisplayName", Symbol.Name);
+}
+
+template <> void SymbolRecordImpl<ThreadLocalDataSym>::map(IO &IO) {
+ // TODO: Map linkage name
+ IO.mapRequired("Type", Symbol.Type);
+ IO.mapRequired("DisplayName", Symbol.Name);
+}
+}
+}
+}
+
+CVSymbol CodeViewYAML::SymbolRecord::toCodeViewSymbol(
+ BumpPtrAllocator &Allocator) const {
+ return Symbol->toCodeViewSymbol(Allocator);
+}
+
+namespace llvm {
+namespace yaml {
+template <> struct MappingTraits<SymbolRecordBase> {
+ static void mapping(IO &io, SymbolRecordBase &Record) { Record.map(io); }
+};
+}
+}
+
+template <typename SymbolType>
+static inline Expected<CodeViewYAML::SymbolRecord>
+fromCodeViewSymbolImpl(CVSymbol Symbol) {
+ CodeViewYAML::SymbolRecord Result;
+
+ auto Impl = std::make_shared<SymbolRecordImpl<SymbolType>>(Symbol.kind());
+ if (auto EC = Impl->fromCodeViewSymbol(Symbol))
+ return std::move(EC);
+ Result.Symbol = Impl;
+ return Result;
+}
+
+Expected<CodeViewYAML::SymbolRecord>
+CodeViewYAML::SymbolRecord::fromCodeViewSymbol(CVSymbol Symbol) {
+#define SYMBOL_RECORD(EnumName, EnumVal, ClassName) \
+ case EnumName: \
+ return fromCodeViewSymbolImpl<ClassName>(Symbol);
+#define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) \
+ SYMBOL_RECORD(EnumName, EnumVal, ClassName)
+ switch (Symbol.kind()) {
+#include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
+ default: { llvm_unreachable("Unknown symbol kind!"); }
+ }
+ return make_error<CodeViewError>(cv_error_code::corrupt_record);
+}
+
+template <typename ConcreteType>
+static void mapSymbolRecordImpl(IO &IO, const char *Class, SymbolKind Kind,
+ CodeViewYAML::SymbolRecord &Obj) {
+ if (!IO.outputting())
+ Obj.Symbol = std::make_shared<SymbolRecordImpl<ConcreteType>>(Kind);
+
+ IO.mapRequired(Class, *Obj.Symbol);
+}
+
+void MappingTraits<CodeViewYAML::SymbolRecord>::mapping(
+ IO &IO, CodeViewYAML::SymbolRecord &Obj) {
+ SymbolKind Kind;
+ if (IO.outputting())
+ Kind = Obj.Symbol->Kind;
+ IO.mapRequired("Kind", Kind);
+
+#define SYMBOL_RECORD(EnumName, EnumVal, ClassName) \
+ case EnumName: \
+ mapSymbolRecordImpl<ClassName>(IO, #ClassName, Kind, Obj); \
+ break;
+#define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) \
+ SYMBOL_RECORD(EnumName, EnumVal, ClassName)
+ switch (Kind) {
+#include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
+ default: { llvm_unreachable("Unknown symbol kind!"); }
+ }
+}
diff --git a/contrib/llvm/lib/ObjectYAML/CodeViewYAMLTypes.cpp b/contrib/llvm/lib/ObjectYAML/CodeViewYAMLTypes.cpp
new file mode 100644
index 000000000000..4e82a299a672
--- /dev/null
+++ b/contrib/llvm/lib/ObjectYAML/CodeViewYAMLTypes.cpp
@@ -0,0 +1,712 @@
+//===- CodeViewYAMLTypes.cpp - CodeView YAMLIO types 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.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ObjectYAML/CodeViewYAMLTypes.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
+#include "llvm/DebugInfo/CodeView/CodeViewError.h"
+#include "llvm/DebugInfo/CodeView/EnumTables.h"
+#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
+#include "llvm/DebugInfo/CodeView/TypeTableBuilder.h"
+
+using namespace llvm;
+using namespace llvm::codeview;
+using namespace llvm::CodeViewYAML;
+using namespace llvm::CodeViewYAML::detail;
+using namespace llvm::yaml;
+
+LLVM_YAML_IS_SEQUENCE_VECTOR(OneMethodRecord)
+LLVM_YAML_IS_SEQUENCE_VECTOR(StringRef)
+LLVM_YAML_IS_SEQUENCE_VECTOR(VFTableSlotKind)
+LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(TypeIndex)
+
+LLVM_YAML_DECLARE_SCALAR_TRAITS(TypeIndex, false)
+LLVM_YAML_DECLARE_SCALAR_TRAITS(APSInt, false)
+
+LLVM_YAML_DECLARE_ENUM_TRAITS(TypeLeafKind)
+LLVM_YAML_DECLARE_ENUM_TRAITS(PointerToMemberRepresentation)
+LLVM_YAML_DECLARE_ENUM_TRAITS(VFTableSlotKind)
+LLVM_YAML_DECLARE_ENUM_TRAITS(CallingConvention)
+LLVM_YAML_DECLARE_ENUM_TRAITS(PointerKind)
+LLVM_YAML_DECLARE_ENUM_TRAITS(PointerMode)
+LLVM_YAML_DECLARE_ENUM_TRAITS(HfaKind)
+LLVM_YAML_DECLARE_ENUM_TRAITS(MemberAccess)
+LLVM_YAML_DECLARE_ENUM_TRAITS(MethodKind)
+LLVM_YAML_DECLARE_ENUM_TRAITS(WindowsRTClassKind)
+LLVM_YAML_DECLARE_ENUM_TRAITS(LabelType)
+
+LLVM_YAML_DECLARE_BITSET_TRAITS(PointerOptions)
+LLVM_YAML_DECLARE_BITSET_TRAITS(ModifierOptions)
+LLVM_YAML_DECLARE_BITSET_TRAITS(FunctionOptions)
+LLVM_YAML_DECLARE_BITSET_TRAITS(ClassOptions)
+LLVM_YAML_DECLARE_BITSET_TRAITS(MethodOptions)
+
+LLVM_YAML_DECLARE_MAPPING_TRAITS(OneMethodRecord)
+LLVM_YAML_DECLARE_MAPPING_TRAITS(MemberPointerInfo)
+
+namespace llvm {
+namespace CodeViewYAML {
+namespace detail {
+
+struct LeafRecordBase {
+ TypeLeafKind Kind;
+ explicit LeafRecordBase(TypeLeafKind K) : Kind(K) {}
+
+ virtual ~LeafRecordBase() {}
+ virtual void map(yaml::IO &io) = 0;
+ virtual CVType toCodeViewRecord(BumpPtrAllocator &Allocator) const = 0;
+ virtual Error fromCodeViewRecord(CVType Type) = 0;
+};
+
+template <typename T> struct LeafRecordImpl : public LeafRecordBase {
+ explicit LeafRecordImpl(TypeLeafKind K)
+ : LeafRecordBase(K), Record(static_cast<TypeRecordKind>(K)) {}
+
+ void map(yaml::IO &io) override;
+
+ Error fromCodeViewRecord(CVType Type) override {
+ return TypeDeserializer::deserializeAs<T>(Type, Record);
+ }
+
+ CVType toCodeViewRecord(BumpPtrAllocator &Allocator) const override {
+ TypeTableBuilder Table(Allocator);
+ Table.writeKnownType(Record);
+ return CVType(Kind, Table.records().front());
+ }
+
+ mutable T Record;
+};
+
+template <> struct LeafRecordImpl<FieldListRecord> : public LeafRecordBase {
+ explicit LeafRecordImpl(TypeLeafKind K) : LeafRecordBase(K) {}
+
+ void map(yaml::IO &io) override;
+ CVType toCodeViewRecord(BumpPtrAllocator &Allocator) const override;
+ Error fromCodeViewRecord(CVType Type) override;
+
+ std::vector<MemberRecord> Members;
+};
+
+struct MemberRecordBase {
+ TypeLeafKind Kind;
+ explicit MemberRecordBase(TypeLeafKind K) : Kind(K) {}
+
+ virtual ~MemberRecordBase() {}
+ virtual void map(yaml::IO &io) = 0;
+ virtual void writeTo(FieldListRecordBuilder &FLRB) = 0;
+};
+
+template <typename T> struct MemberRecordImpl : public MemberRecordBase {
+ explicit MemberRecordImpl(TypeLeafKind K)
+ : MemberRecordBase(K), Record(static_cast<TypeRecordKind>(K)) {}
+ void map(yaml::IO &io) override;
+
+ void writeTo(FieldListRecordBuilder &FLRB) override {
+ FLRB.writeMemberType(Record);
+ }
+
+ mutable T Record;
+};
+}
+}
+}
+
+void ScalarTraits<TypeIndex>::output(const TypeIndex &S, void *,
+ llvm::raw_ostream &OS) {
+ OS << S.getIndex();
+}
+
+StringRef ScalarTraits<TypeIndex>::input(StringRef Scalar, void *Ctx,
+ TypeIndex &S) {
+ uint32_t I;
+ StringRef Result = ScalarTraits<uint32_t>::input(Scalar, Ctx, I);
+ S.setIndex(I);
+ return Result;
+}
+
+void ScalarTraits<APSInt>::output(const APSInt &S, void *,
+ llvm::raw_ostream &OS) {
+ S.print(OS, true);
+}
+
+StringRef ScalarTraits<APSInt>::input(StringRef Scalar, void *Ctx, APSInt &S) {
+ S = APSInt(Scalar);
+ return "";
+}
+
+void ScalarEnumerationTraits<TypeLeafKind>::enumeration(IO &io,
+ TypeLeafKind &Value) {
+#define CV_TYPE(name, val) io.enumCase(Value, #name, name);
+#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
+#undef CV_TYPE
+}
+
+void ScalarEnumerationTraits<PointerToMemberRepresentation>::enumeration(
+ IO &IO, PointerToMemberRepresentation &Value) {
+ IO.enumCase(Value, "Unknown", PointerToMemberRepresentation::Unknown);
+ IO.enumCase(Value, "SingleInheritanceData",
+ PointerToMemberRepresentation::SingleInheritanceData);
+ IO.enumCase(Value, "MultipleInheritanceData",
+ PointerToMemberRepresentation::MultipleInheritanceData);
+ IO.enumCase(Value, "VirtualInheritanceData",
+ PointerToMemberRepresentation::VirtualInheritanceData);
+ IO.enumCase(Value, "GeneralData", PointerToMemberRepresentation::GeneralData);
+ IO.enumCase(Value, "SingleInheritanceFunction",
+ PointerToMemberRepresentation::SingleInheritanceFunction);
+ IO.enumCase(Value, "MultipleInheritanceFunction",
+ PointerToMemberRepresentation::MultipleInheritanceFunction);
+ IO.enumCase(Value, "VirtualInheritanceFunction",
+ PointerToMemberRepresentation::VirtualInheritanceFunction);
+ IO.enumCase(Value, "GeneralFunction",
+ PointerToMemberRepresentation::GeneralFunction);
+}
+
+void ScalarEnumerationTraits<VFTableSlotKind>::enumeration(
+ IO &IO, VFTableSlotKind &Kind) {
+ IO.enumCase(Kind, "Near16", VFTableSlotKind::Near16);
+ IO.enumCase(Kind, "Far16", VFTableSlotKind::Far16);
+ IO.enumCase(Kind, "This", VFTableSlotKind::This);
+ IO.enumCase(Kind, "Outer", VFTableSlotKind::Outer);
+ IO.enumCase(Kind, "Meta", VFTableSlotKind::Meta);
+ IO.enumCase(Kind, "Near", VFTableSlotKind::Near);
+ IO.enumCase(Kind, "Far", VFTableSlotKind::Far);
+}
+
+void ScalarEnumerationTraits<CallingConvention>::enumeration(
+ IO &IO, CallingConvention &Value) {
+ IO.enumCase(Value, "NearC", CallingConvention::NearC);
+ IO.enumCase(Value, "FarC", CallingConvention::FarC);
+ IO.enumCase(Value, "NearPascal", CallingConvention::NearPascal);
+ IO.enumCase(Value, "FarPascal", CallingConvention::FarPascal);
+ IO.enumCase(Value, "NearFast", CallingConvention::NearFast);
+ IO.enumCase(Value, "FarFast", CallingConvention::FarFast);
+ IO.enumCase(Value, "NearStdCall", CallingConvention::NearStdCall);
+ IO.enumCase(Value, "FarStdCall", CallingConvention::FarStdCall);
+ IO.enumCase(Value, "NearSysCall", CallingConvention::NearSysCall);
+ IO.enumCase(Value, "FarSysCall", CallingConvention::FarSysCall);
+ IO.enumCase(Value, "ThisCall", CallingConvention::ThisCall);
+ IO.enumCase(Value, "MipsCall", CallingConvention::MipsCall);
+ IO.enumCase(Value, "Generic", CallingConvention::Generic);
+ IO.enumCase(Value, "AlphaCall", CallingConvention::AlphaCall);
+ IO.enumCase(Value, "PpcCall", CallingConvention::PpcCall);
+ IO.enumCase(Value, "SHCall", CallingConvention::SHCall);
+ IO.enumCase(Value, "ArmCall", CallingConvention::ArmCall);
+ IO.enumCase(Value, "AM33Call", CallingConvention::AM33Call);
+ IO.enumCase(Value, "TriCall", CallingConvention::TriCall);
+ IO.enumCase(Value, "SH5Call", CallingConvention::SH5Call);
+ IO.enumCase(Value, "M32RCall", CallingConvention::M32RCall);
+ IO.enumCase(Value, "ClrCall", CallingConvention::ClrCall);
+ IO.enumCase(Value, "Inline", CallingConvention::Inline);
+ IO.enumCase(Value, "NearVector", CallingConvention::NearVector);
+}
+
+void ScalarEnumerationTraits<PointerKind>::enumeration(IO &IO,
+ PointerKind &Kind) {
+ IO.enumCase(Kind, "Near16", PointerKind::Near16);
+ IO.enumCase(Kind, "Far16", PointerKind::Far16);
+ IO.enumCase(Kind, "Huge16", PointerKind::Huge16);
+ IO.enumCase(Kind, "BasedOnSegment", PointerKind::BasedOnSegment);
+ IO.enumCase(Kind, "BasedOnValue", PointerKind::BasedOnValue);
+ IO.enumCase(Kind, "BasedOnSegmentValue", PointerKind::BasedOnSegmentValue);
+ IO.enumCase(Kind, "BasedOnAddress", PointerKind::BasedOnAddress);
+ IO.enumCase(Kind, "BasedOnSegmentAddress",
+ PointerKind::BasedOnSegmentAddress);
+ IO.enumCase(Kind, "BasedOnType", PointerKind::BasedOnType);
+ IO.enumCase(Kind, "BasedOnSelf", PointerKind::BasedOnSelf);
+ IO.enumCase(Kind, "Near32", PointerKind::Near32);
+ IO.enumCase(Kind, "Far32", PointerKind::Far32);
+ IO.enumCase(Kind, "Near64", PointerKind::Near64);
+}
+
+void ScalarEnumerationTraits<PointerMode>::enumeration(IO &IO,
+ PointerMode &Mode) {
+ IO.enumCase(Mode, "Pointer", PointerMode::Pointer);
+ IO.enumCase(Mode, "LValueReference", PointerMode::LValueReference);
+ IO.enumCase(Mode, "PointerToDataMember", PointerMode::PointerToDataMember);
+ IO.enumCase(Mode, "PointerToMemberFunction",
+ PointerMode::PointerToMemberFunction);
+ IO.enumCase(Mode, "RValueReference", PointerMode::RValueReference);
+}
+
+void ScalarEnumerationTraits<HfaKind>::enumeration(IO &IO, HfaKind &Value) {
+ IO.enumCase(Value, "None", HfaKind::None);
+ IO.enumCase(Value, "Float", HfaKind::Float);
+ IO.enumCase(Value, "Double", HfaKind::Double);
+ IO.enumCase(Value, "Other", HfaKind::Other);
+}
+
+void ScalarEnumerationTraits<MemberAccess>::enumeration(IO &IO,
+ MemberAccess &Access) {
+ IO.enumCase(Access, "None", MemberAccess::None);
+ IO.enumCase(Access, "Private", MemberAccess::Private);
+ IO.enumCase(Access, "Protected", MemberAccess::Protected);
+ IO.enumCase(Access, "Public", MemberAccess::Public);
+}
+
+void ScalarEnumerationTraits<MethodKind>::enumeration(IO &IO,
+ MethodKind &Kind) {
+ IO.enumCase(Kind, "Vanilla", MethodKind::Vanilla);
+ IO.enumCase(Kind, "Virtual", MethodKind::Virtual);
+ IO.enumCase(Kind, "Static", MethodKind::Static);
+ IO.enumCase(Kind, "Friend", MethodKind::Friend);
+ IO.enumCase(Kind, "IntroducingVirtual", MethodKind::IntroducingVirtual);
+ IO.enumCase(Kind, "PureVirtual", MethodKind::PureVirtual);
+ IO.enumCase(Kind, "PureIntroducingVirtual",
+ MethodKind::PureIntroducingVirtual);
+}
+
+void ScalarEnumerationTraits<WindowsRTClassKind>::enumeration(
+ IO &IO, WindowsRTClassKind &Value) {
+ IO.enumCase(Value, "None", WindowsRTClassKind::None);
+ IO.enumCase(Value, "Ref", WindowsRTClassKind::RefClass);
+ IO.enumCase(Value, "Value", WindowsRTClassKind::ValueClass);
+ IO.enumCase(Value, "Interface", WindowsRTClassKind::Interface);
+}
+
+void ScalarEnumerationTraits<LabelType>::enumeration(IO &IO, LabelType &Value) {
+ IO.enumCase(Value, "Near", LabelType::Near);
+ IO.enumCase(Value, "Far", LabelType::Far);
+}
+
+void ScalarBitSetTraits<PointerOptions>::bitset(IO &IO,
+ PointerOptions &Options) {
+ IO.bitSetCase(Options, "None", PointerOptions::None);
+ IO.bitSetCase(Options, "Flat32", PointerOptions::Flat32);
+ IO.bitSetCase(Options, "Volatile", PointerOptions::Volatile);
+ IO.bitSetCase(Options, "Const", PointerOptions::Const);
+ IO.bitSetCase(Options, "Unaligned", PointerOptions::Unaligned);
+ IO.bitSetCase(Options, "Restrict", PointerOptions::Restrict);
+ IO.bitSetCase(Options, "WinRTSmartPointer",
+ PointerOptions::WinRTSmartPointer);
+}
+
+void ScalarBitSetTraits<ModifierOptions>::bitset(IO &IO,
+ ModifierOptions &Options) {
+ IO.bitSetCase(Options, "None", ModifierOptions::None);
+ IO.bitSetCase(Options, "Const", ModifierOptions::Const);
+ IO.bitSetCase(Options, "Volatile", ModifierOptions::Volatile);
+ IO.bitSetCase(Options, "Unaligned", ModifierOptions::Unaligned);
+}
+
+void ScalarBitSetTraits<FunctionOptions>::bitset(IO &IO,
+ FunctionOptions &Options) {
+ IO.bitSetCase(Options, "None", FunctionOptions::None);
+ IO.bitSetCase(Options, "CxxReturnUdt", FunctionOptions::CxxReturnUdt);
+ IO.bitSetCase(Options, "Constructor", FunctionOptions::Constructor);
+ IO.bitSetCase(Options, "ConstructorWithVirtualBases",
+ FunctionOptions::ConstructorWithVirtualBases);
+}
+
+void ScalarBitSetTraits<ClassOptions>::bitset(IO &IO, ClassOptions &Options) {
+ IO.bitSetCase(Options, "None", ClassOptions::None);
+ IO.bitSetCase(Options, "HasConstructorOrDestructor",
+ ClassOptions::HasConstructorOrDestructor);
+ IO.bitSetCase(Options, "HasOverloadedOperator",
+ ClassOptions::HasOverloadedOperator);
+ IO.bitSetCase(Options, "Nested", ClassOptions::Nested);
+ IO.bitSetCase(Options, "ContainsNestedClass",
+ ClassOptions::ContainsNestedClass);
+ IO.bitSetCase(Options, "HasOverloadedAssignmentOperator",
+ ClassOptions::HasOverloadedAssignmentOperator);
+ IO.bitSetCase(Options, "HasConversionOperator",
+ ClassOptions::HasConversionOperator);
+ IO.bitSetCase(Options, "ForwardReference", ClassOptions::ForwardReference);
+ IO.bitSetCase(Options, "Scoped", ClassOptions::Scoped);
+ IO.bitSetCase(Options, "HasUniqueName", ClassOptions::HasUniqueName);
+ IO.bitSetCase(Options, "Sealed", ClassOptions::Sealed);
+ IO.bitSetCase(Options, "Intrinsic", ClassOptions::Intrinsic);
+}
+
+void ScalarBitSetTraits<MethodOptions>::bitset(IO &IO, MethodOptions &Options) {
+ IO.bitSetCase(Options, "None", MethodOptions::None);
+ IO.bitSetCase(Options, "Pseudo", MethodOptions::Pseudo);
+ IO.bitSetCase(Options, "NoInherit", MethodOptions::NoInherit);
+ IO.bitSetCase(Options, "NoConstruct", MethodOptions::NoConstruct);
+ IO.bitSetCase(Options, "CompilerGenerated", MethodOptions::CompilerGenerated);
+ IO.bitSetCase(Options, "Sealed", MethodOptions::Sealed);
+}
+
+void MappingTraits<MemberPointerInfo>::mapping(IO &IO, MemberPointerInfo &MPI) {
+ IO.mapRequired("ContainingType", MPI.ContainingType);
+ IO.mapRequired("Representation", MPI.Representation);
+}
+
+namespace llvm {
+namespace CodeViewYAML {
+namespace detail {
+template <> void LeafRecordImpl<ModifierRecord>::map(IO &IO) {
+ IO.mapRequired("ModifiedType", Record.ModifiedType);
+ IO.mapRequired("Modifiers", Record.Modifiers);
+}
+
+template <> void LeafRecordImpl<ProcedureRecord>::map(IO &IO) {
+ IO.mapRequired("ReturnType", Record.ReturnType);
+ IO.mapRequired("CallConv", Record.CallConv);
+ IO.mapRequired("Options", Record.Options);
+ IO.mapRequired("ParameterCount", Record.ParameterCount);
+ IO.mapRequired("ArgumentList", Record.ArgumentList);
+}
+
+template <> void LeafRecordImpl<MemberFunctionRecord>::map(IO &IO) {
+ IO.mapRequired("ReturnType", Record.ReturnType);
+ IO.mapRequired("ClassType", Record.ClassType);
+ IO.mapRequired("ThisType", Record.ThisType);
+ IO.mapRequired("CallConv", Record.CallConv);
+ IO.mapRequired("Options", Record.Options);
+ IO.mapRequired("ParameterCount", Record.ParameterCount);
+ IO.mapRequired("ArgumentList", Record.ArgumentList);
+ IO.mapRequired("ThisPointerAdjustment", Record.ThisPointerAdjustment);
+}
+
+template <> void LeafRecordImpl<LabelRecord>::map(IO &IO) {
+ IO.mapRequired("Mode", Record.Mode);
+}
+
+template <> void LeafRecordImpl<MemberFuncIdRecord>::map(IO &IO) {
+ IO.mapRequired("ClassType", Record.ClassType);
+ IO.mapRequired("FunctionType", Record.FunctionType);
+ IO.mapRequired("Name", Record.Name);
+}
+
+template <> void LeafRecordImpl<ArgListRecord>::map(IO &IO) {
+ IO.mapRequired("ArgIndices", Record.ArgIndices);
+}
+
+template <> void LeafRecordImpl<StringListRecord>::map(IO &IO) {
+ IO.mapRequired("StringIndices", Record.StringIndices);
+}
+
+template <> void LeafRecordImpl<PointerRecord>::map(IO &IO) {
+ IO.mapRequired("ReferentType", Record.ReferentType);
+ IO.mapRequired("Attrs", Record.Attrs);
+ IO.mapOptional("MemberInfo", Record.MemberInfo);
+}
+
+template <> void LeafRecordImpl<ArrayRecord>::map(IO &IO) {
+ IO.mapRequired("ElementType", Record.ElementType);
+ IO.mapRequired("IndexType", Record.IndexType);
+ IO.mapRequired("Size", Record.Size);
+ IO.mapRequired("Name", Record.Name);
+}
+
+void LeafRecordImpl<FieldListRecord>::map(IO &IO) {
+ IO.mapRequired("FieldList", Members);
+}
+}
+}
+}
+
+namespace {
+class MemberRecordConversionVisitor : public TypeVisitorCallbacks {
+public:
+ explicit MemberRecordConversionVisitor(std::vector<MemberRecord> &Records)
+ : Records(Records) {}
+
+#define TYPE_RECORD(EnumName, EnumVal, Name)
+#define MEMBER_RECORD(EnumName, EnumVal, Name) \
+ Error visitKnownMember(CVMemberRecord &CVR, Name##Record &Record) override { \
+ return visitKnownMemberImpl(Record); \
+ }
+#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
+#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
+#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
+private:
+ template <typename T> Error visitKnownMemberImpl(T &Record) {
+ TypeLeafKind K = static_cast<TypeLeafKind>(Record.getKind());
+ auto Impl = std::make_shared<MemberRecordImpl<T>>(K);
+ Impl->Record = Record;
+ Records.push_back(MemberRecord{Impl});
+ return Error::success();
+ }
+
+ std::vector<MemberRecord> &Records;
+};
+}
+
+Error LeafRecordImpl<FieldListRecord>::fromCodeViewRecord(CVType Type) {
+ MemberRecordConversionVisitor V(Members);
+ return visitMemberRecordStream(Type.content(), V);
+}
+
+CVType LeafRecordImpl<FieldListRecord>::toCodeViewRecord(
+ BumpPtrAllocator &Allocator) const {
+ TypeTableBuilder TTB(Allocator);
+ FieldListRecordBuilder FLRB(TTB);
+ FLRB.begin();
+ for (const auto &Member : Members) {
+ Member.Member->writeTo(FLRB);
+ }
+ FLRB.end(true);
+ return CVType(Kind, TTB.records().front());
+}
+
+void MappingTraits<OneMethodRecord>::mapping(IO &io, OneMethodRecord &Record) {
+ io.mapRequired("Type", Record.Type);
+ io.mapRequired("Attrs", Record.Attrs.Attrs);
+ io.mapRequired("VFTableOffset", Record.VFTableOffset);
+ io.mapRequired("Name", Record.Name);
+}
+
+namespace llvm {
+namespace CodeViewYAML {
+namespace detail {
+template <> void LeafRecordImpl<ClassRecord>::map(IO &IO) {
+ IO.mapRequired("MemberCount", Record.MemberCount);
+ IO.mapRequired("Options", Record.Options);
+ IO.mapRequired("FieldList", Record.FieldList);
+ IO.mapRequired("Name", Record.Name);
+ IO.mapRequired("UniqueName", Record.UniqueName);
+
+ IO.mapRequired("DerivationList", Record.DerivationList);
+ IO.mapRequired("VTableShape", Record.VTableShape);
+ IO.mapRequired("Size", Record.Size);
+}
+
+template <> void LeafRecordImpl<UnionRecord>::map(IO &IO) {
+ IO.mapRequired("MemberCount", Record.MemberCount);
+ IO.mapRequired("Options", Record.Options);
+ IO.mapRequired("FieldList", Record.FieldList);
+ IO.mapRequired("Name", Record.Name);
+ IO.mapRequired("UniqueName", Record.UniqueName);
+
+ IO.mapRequired("Size", Record.Size);
+}
+
+template <> void LeafRecordImpl<EnumRecord>::map(IO &IO) {
+ IO.mapRequired("NumEnumerators", Record.MemberCount);
+ IO.mapRequired("Options", Record.Options);
+ IO.mapRequired("FieldList", Record.FieldList);
+ IO.mapRequired("Name", Record.Name);
+ IO.mapRequired("UniqueName", Record.UniqueName);
+
+ IO.mapRequired("UnderlyingType", Record.UnderlyingType);
+}
+
+template <> void LeafRecordImpl<BitFieldRecord>::map(IO &IO) {
+ IO.mapRequired("Type", Record.Type);
+ IO.mapRequired("BitSize", Record.BitSize);
+ IO.mapRequired("BitOffset", Record.BitOffset);
+}
+
+template <> void LeafRecordImpl<VFTableShapeRecord>::map(IO &IO) {
+ IO.mapRequired("Slots", Record.Slots);
+}
+
+template <> void LeafRecordImpl<TypeServer2Record>::map(IO &IO) {
+ IO.mapRequired("Guid", Record.Guid);
+ IO.mapRequired("Age", Record.Age);
+ IO.mapRequired("Name", Record.Name);
+}
+
+template <> void LeafRecordImpl<StringIdRecord>::map(IO &IO) {
+ IO.mapRequired("Id", Record.Id);
+ IO.mapRequired("String", Record.String);
+}
+
+template <> void LeafRecordImpl<FuncIdRecord>::map(IO &IO) {
+ IO.mapRequired("ParentScope", Record.ParentScope);
+ IO.mapRequired("FunctionType", Record.FunctionType);
+ IO.mapRequired("Name", Record.Name);
+}
+
+template <> void LeafRecordImpl<UdtSourceLineRecord>::map(IO &IO) {
+ IO.mapRequired("UDT", Record.UDT);
+ IO.mapRequired("SourceFile", Record.SourceFile);
+ IO.mapRequired("LineNumber", Record.LineNumber);
+}
+
+template <> void LeafRecordImpl<UdtModSourceLineRecord>::map(IO &IO) {
+ IO.mapRequired("UDT", Record.UDT);
+ IO.mapRequired("SourceFile", Record.SourceFile);
+ IO.mapRequired("LineNumber", Record.LineNumber);
+ IO.mapRequired("Module", Record.Module);
+}
+
+template <> void LeafRecordImpl<BuildInfoRecord>::map(IO &IO) {
+ IO.mapRequired("ArgIndices", Record.ArgIndices);
+}
+
+template <> void LeafRecordImpl<VFTableRecord>::map(IO &IO) {
+ IO.mapRequired("CompleteClass", Record.CompleteClass);
+ IO.mapRequired("OverriddenVFTable", Record.OverriddenVFTable);
+ IO.mapRequired("VFPtrOffset", Record.VFPtrOffset);
+ IO.mapRequired("MethodNames", Record.MethodNames);
+}
+
+template <> void LeafRecordImpl<MethodOverloadListRecord>::map(IO &IO) {
+ IO.mapRequired("Methods", Record.Methods);
+}
+
+template <> void MemberRecordImpl<OneMethodRecord>::map(IO &IO) {
+ MappingTraits<OneMethodRecord>::mapping(IO, Record);
+}
+
+template <> void MemberRecordImpl<OverloadedMethodRecord>::map(IO &IO) {
+ IO.mapRequired("NumOverloads", Record.NumOverloads);
+ IO.mapRequired("MethodList", Record.MethodList);
+ IO.mapRequired("Name", Record.Name);
+}
+
+template <> void MemberRecordImpl<NestedTypeRecord>::map(IO &IO) {
+ IO.mapRequired("Type", Record.Type);
+ IO.mapRequired("Name", Record.Name);
+}
+
+template <> void MemberRecordImpl<DataMemberRecord>::map(IO &IO) {
+ IO.mapRequired("Attrs", Record.Attrs.Attrs);
+ IO.mapRequired("Type", Record.Type);
+ IO.mapRequired("FieldOffset", Record.FieldOffset);
+ IO.mapRequired("Name", Record.Name);
+}
+
+template <> void MemberRecordImpl<StaticDataMemberRecord>::map(IO &IO) {
+ IO.mapRequired("Attrs", Record.Attrs.Attrs);
+ IO.mapRequired("Type", Record.Type);
+ IO.mapRequired("Name", Record.Name);
+}
+
+template <> void MemberRecordImpl<EnumeratorRecord>::map(IO &IO) {
+ IO.mapRequired("Attrs", Record.Attrs.Attrs);
+ IO.mapRequired("Value", Record.Value);
+ IO.mapRequired("Name", Record.Name);
+}
+
+template <> void MemberRecordImpl<VFPtrRecord>::map(IO &IO) {
+ IO.mapRequired("Type", Record.Type);
+}
+
+template <> void MemberRecordImpl<BaseClassRecord>::map(IO &IO) {
+ IO.mapRequired("Attrs", Record.Attrs.Attrs);
+ IO.mapRequired("Type", Record.Type);
+ IO.mapRequired("Offset", Record.Offset);
+}
+
+template <> void MemberRecordImpl<VirtualBaseClassRecord>::map(IO &IO) {
+ IO.mapRequired("Attrs", Record.Attrs.Attrs);
+ IO.mapRequired("BaseType", Record.BaseType);
+ IO.mapRequired("VBPtrType", Record.VBPtrType);
+ IO.mapRequired("VBPtrOffset", Record.VBPtrOffset);
+ IO.mapRequired("VTableIndex", Record.VTableIndex);
+}
+
+template <> void MemberRecordImpl<ListContinuationRecord>::map(IO &IO) {
+ IO.mapRequired("ContinuationIndex", Record.ContinuationIndex);
+}
+}
+}
+}
+
+template <typename T>
+static inline Expected<LeafRecord> fromCodeViewRecordImpl(CVType Type) {
+ LeafRecord Result;
+
+ auto Impl = std::make_shared<LeafRecordImpl<T>>(Type.kind());
+ if (auto EC = Impl->fromCodeViewRecord(Type))
+ return std::move(EC);
+ Result.Leaf = Impl;
+ return Result;
+}
+
+Expected<LeafRecord> LeafRecord::fromCodeViewRecord(CVType Type) {
+#define TYPE_RECORD(EnumName, EnumVal, ClassName) \
+ case EnumName: \
+ return fromCodeViewRecordImpl<ClassName##Record>(Type);
+#define TYPE_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) \
+ TYPE_RECORD(EnumName, EnumVal, ClassName)
+#define MEMBER_RECORD(EnumName, EnumVal, ClassName)
+#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName)
+ switch (Type.kind()) {
+#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
+ default: { llvm_unreachable("Unknown leaf kind!"); }
+ }
+ return make_error<CodeViewError>(cv_error_code::corrupt_record);
+}
+
+CVType LeafRecord::toCodeViewRecord(BumpPtrAllocator &Allocator) const {
+ return Leaf->toCodeViewRecord(Allocator);
+}
+
+namespace llvm {
+namespace yaml {
+template <> struct MappingTraits<LeafRecordBase> {
+ static void mapping(IO &io, LeafRecordBase &Record) { Record.map(io); }
+};
+
+template <> struct MappingTraits<MemberRecordBase> {
+ static void mapping(IO &io, MemberRecordBase &Record) { Record.map(io); }
+};
+}
+}
+
+template <typename ConcreteType>
+static void mapLeafRecordImpl(IO &IO, const char *Class, TypeLeafKind Kind,
+ LeafRecord &Obj) {
+ if (!IO.outputting())
+ Obj.Leaf = std::make_shared<LeafRecordImpl<ConcreteType>>(Kind);
+
+ if (Kind == LF_FIELDLIST)
+ Obj.Leaf->map(IO);
+ else
+ IO.mapRequired(Class, *Obj.Leaf);
+}
+
+void MappingTraits<LeafRecord>::mapping(IO &IO, LeafRecord &Obj) {
+ TypeLeafKind Kind;
+ if (IO.outputting())
+ Kind = Obj.Leaf->Kind;
+ IO.mapRequired("Kind", Kind);
+
+#define TYPE_RECORD(EnumName, EnumVal, ClassName) \
+ case EnumName: \
+ mapLeafRecordImpl<ClassName##Record>(IO, #ClassName, Kind, Obj); \
+ break;
+#define TYPE_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) \
+ TYPE_RECORD(EnumName, EnumVal, ClassName)
+#define MEMBER_RECORD(EnumName, EnumVal, ClassName)
+#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName)
+ switch (Kind) {
+#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
+ default: { llvm_unreachable("Unknown leaf kind!"); }
+ }
+}
+
+template <typename ConcreteType>
+static void mapMemberRecordImpl(IO &IO, const char *Class, TypeLeafKind Kind,
+ MemberRecord &Obj) {
+ if (!IO.outputting())
+ Obj.Member = std::make_shared<MemberRecordImpl<ConcreteType>>(Kind);
+
+ IO.mapRequired(Class, *Obj.Member);
+}
+
+void MappingTraits<MemberRecord>::mapping(IO &IO, MemberRecord &Obj) {
+ TypeLeafKind Kind;
+ if (IO.outputting())
+ Kind = Obj.Member->Kind;
+ IO.mapRequired("Kind", Kind);
+
+#define MEMBER_RECORD(EnumName, EnumVal, ClassName) \
+ case EnumName: \
+ mapMemberRecordImpl<ClassName##Record>(IO, #ClassName, Kind, Obj); \
+ break;
+#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) \
+ MEMBER_RECORD(EnumName, EnumVal, ClassName)
+#define TYPE_RECORD(EnumName, EnumVal, ClassName)
+#define TYPE_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName)
+ switch (Kind) {
+#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
+ default: { llvm_unreachable("Unknown member kind!"); }
+ }
+}
diff --git a/contrib/llvm/lib/Passes/PassBuilder.cpp b/contrib/llvm/lib/Passes/PassBuilder.cpp
index abc53e97aa72..eb81e58b9b0e 100644
--- a/contrib/llvm/lib/Passes/PassBuilder.cpp
+++ b/contrib/llvm/lib/Passes/PassBuilder.cpp
@@ -164,7 +164,8 @@ static cl::opt<bool> EnableGVNHoist(
"enable-npm-gvn-hoist", cl::init(false), cl::Hidden,
cl::desc("Enable the GVN hoisting pass for the new PM (default = off)"));
-static Regex DefaultAliasRegex("^(default|lto-pre-link|lto)<(O[0123sz])>$");
+static Regex DefaultAliasRegex(
+ "^(default|thinlto-pre-link|thinlto|lto-pre-link|lto)<(O[0123sz])>$");
static bool isOptimizingForSize(PassBuilder::OptimizationLevel Level) {
switch (Level) {
@@ -345,6 +346,9 @@ PassBuilder::buildFunctionSimplificationPipeline(OptimizationLevel Level,
LPM2.addPass(IndVarSimplifyPass());
LPM2.addPass(LoopIdiomRecognizePass());
LPM2.addPass(LoopDeletionPass());
+ // FIXME: The old pass manager has a hack to disable loop unrolling during
+ // ThinLTO when using sample PGO. Need to either fix it or port some
+ // workaround.
LPM2.addPass(LoopUnrollPass::createFull(Level));
// We provide the opt remark emitter pass for LICM to use. We only need to do
@@ -454,14 +458,10 @@ static void addPGOInstrPasses(ModulePassManager &MPM, bool DebugLogging,
}
ModulePassManager
-PassBuilder::buildPerModuleDefaultPipeline(OptimizationLevel Level,
- bool DebugLogging) {
- assert(Level != O0 && "Must request optimizations for the default pipeline!");
+PassBuilder::buildModuleSimplificationPipeline(OptimizationLevel Level,
+ bool DebugLogging) {
ModulePassManager MPM(DebugLogging);
- // Force any function attributes we want the rest of the pipeline te observe.
- MPM.addPass(ForceFunctionAttrsPass());
-
// Do basic inference of function attributes from known properties of system
// libraries and other oracles.
MPM.addPass(InferFunctionAttrsPass());
@@ -504,16 +504,16 @@ PassBuilder::buildPerModuleDefaultPipeline(OptimizationLevel Level,
GlobalCleanupPM.addPass(SimplifyCFGPass());
MPM.addPass(createModuleToFunctionPassAdaptor(std::move(GlobalCleanupPM)));
- // Add all the requested passes for PGO Instrumentation, if requested.
+ // Add all the requested passes for PGO, if requested.
if (PGOOpt) {
assert(PGOOpt->RunProfileGen || PGOOpt->SamplePGO ||
!PGOOpt->ProfileUseFile.empty());
addPGOInstrPasses(MPM, DebugLogging, Level, PGOOpt->RunProfileGen,
PGOOpt->ProfileGenFile, PGOOpt->ProfileUseFile);
- }
- // Indirect call promotion that promotes intra-module targes only.
- MPM.addPass(PGOIndirectCallPromotion(false, PGOOpt && PGOOpt->SamplePGO));
+ // Indirect call promotion that promotes intra-module targes only.
+ MPM.addPass(PGOIndirectCallPromotion(false, PGOOpt && PGOOpt->SamplePGO));
+ }
// Require the GlobalsAA analysis for the module so we can query it within
// the CGSCC pipeline.
@@ -562,17 +562,30 @@ PassBuilder::buildPerModuleDefaultPipeline(OptimizationLevel Level,
createModuleToPostOrderCGSCCPassAdaptor(createDevirtSCCRepeatedPass(
std::move(MainCGPipeline), MaxDevirtIterations, DebugLogging)));
- // This ends the canonicalization and simplification phase of the pipeline.
- // At this point, we expect to have canonical and simple IR which we begin
- // *optimizing* for efficient execution going forward.
+ return MPM;
+}
+
+ModulePassManager
+PassBuilder::buildModuleOptimizationPipeline(OptimizationLevel Level,
+ bool DebugLogging) {
+ ModulePassManager MPM(DebugLogging);
+
+ // Optimize globals now that the module is fully simplified.
+ MPM.addPass(GlobalOptPass());
// Run partial inlining pass to partially inline functions that have
// large bodies.
if (RunPartialInlining)
MPM.addPass(PartialInlinerPass());
- // Eliminate externally available functions now that inlining is over -- we
- // won't emit these anyways.
+ // Remove avail extern fns and globals definitions since we aren't compiling
+ // an object file for later LTO. For LTO we want to preserve these so they
+ // are eligible for inlining at link-time. Note if they are unreferenced they
+ // will be removed by GlobalDCE later, so this only impacts referenced
+ // available externally globals. Eventually they will be suppressed during
+ // codegen, but eliminating here enables more opportunity for GlobalDCE as it
+ // may make globals referenced by available external functions dead and saves
+ // running remaining passes on the eliminated functions.
MPM.addPass(EliminateAvailableExternallyPass());
// Do RPO function attribute inference across the module to forward-propagate
@@ -671,6 +684,87 @@ PassBuilder::buildPerModuleDefaultPipeline(OptimizationLevel Level,
}
ModulePassManager
+PassBuilder::buildPerModuleDefaultPipeline(OptimizationLevel Level,
+ bool DebugLogging) {
+ assert(Level != O0 && "Must request optimizations for the default pipeline!");
+
+ ModulePassManager MPM(DebugLogging);
+
+ // Force any function attributes we want the rest of the pipeline to observe.
+ MPM.addPass(ForceFunctionAttrsPass());
+
+ // Add the core simplification pipeline.
+ MPM.addPass(buildModuleSimplificationPipeline(Level, DebugLogging));
+
+ // Now add the optimization pipeline.
+ MPM.addPass(buildModuleOptimizationPipeline(Level, DebugLogging));
+
+ return MPM;
+}
+
+ModulePassManager
+PassBuilder::buildThinLTOPreLinkDefaultPipeline(OptimizationLevel Level,
+ bool DebugLogging) {
+ assert(Level != O0 && "Must request optimizations for the default pipeline!");
+
+ ModulePassManager MPM(DebugLogging);
+
+ // Force any function attributes we want the rest of the pipeline to observe.
+ MPM.addPass(ForceFunctionAttrsPass());
+
+ // If we are planning to perform ThinLTO later, we don't bloat the code with
+ // unrolling/vectorization/... now. Just simplify the module as much as we
+ // can.
+ MPM.addPass(buildModuleSimplificationPipeline(Level, DebugLogging));
+
+ // Run partial inlining pass to partially inline functions that have
+ // large bodies.
+ // FIXME: It isn't clear whether this is really the right place to run this
+ // in ThinLTO. Because there is another canonicalization and simplification
+ // phase that will run after the thin link, running this here ends up with
+ // less information than will be available later and it may grow functions in
+ // ways that aren't beneficial.
+ if (RunPartialInlining)
+ MPM.addPass(PartialInlinerPass());
+
+ // Reduce the size of the IR as much as possible.
+ MPM.addPass(GlobalOptPass());
+
+ // Rename anon globals to be able to export them in the summary.
+ MPM.addPass(NameAnonGlobalPass());
+
+ return MPM;
+}
+
+ModulePassManager
+PassBuilder::buildThinLTODefaultPipeline(OptimizationLevel Level,
+ bool DebugLogging) {
+ // FIXME: The summary index is not hooked in the new pass manager yet.
+ // When it's going to be hooked, enable WholeProgramDevirt and LowerTypeTest
+ // here.
+
+ ModulePassManager MPM(DebugLogging);
+
+ // Force any function attributes we want the rest of the pipeline to observe.
+ MPM.addPass(ForceFunctionAttrsPass());
+
+ // During the ThinLTO backend phase we perform early indirect call promotion
+ // here, before globalopt. Otherwise imported available_externally functions
+ // look unreferenced and are removed.
+ MPM.addPass(PGOIndirectCallPromotion(true /* InLTO */,
+ PGOOpt && PGOOpt->SamplePGO &&
+ !PGOOpt->ProfileUseFile.empty()));
+
+ // Add the core simplification pipeline.
+ MPM.addPass(buildModuleSimplificationPipeline(Level, DebugLogging));
+
+ // Now add the optimization pipeline.
+ MPM.addPass(buildModuleOptimizationPipeline(Level, DebugLogging));
+
+ return MPM;
+}
+
+ModulePassManager
PassBuilder::buildLTOPreLinkDefaultPipeline(OptimizationLevel Level,
bool DebugLogging) {
assert(Level != O0 && "Must request optimizations for the default pipeline!");
@@ -893,9 +987,16 @@ static Optional<int> parseDevirtPassName(StringRef Name) {
return Count;
}
+/// Tests whether a pass name starts with a valid prefix for a default pipeline
+/// alias.
+static bool startsWithDefaultPipelineAliasPrefix(StringRef Name) {
+ return Name.startswith("default") || Name.startswith("thinlto") ||
+ Name.startswith("lto");
+}
+
static bool isModulePassName(StringRef Name) {
// Manually handle aliases for pre-configured pipeline fragments.
- if (Name.startswith("default") || Name.startswith("lto"))
+ if (startsWithDefaultPipelineAliasPrefix(Name))
return DefaultAliasRegex.match(Name);
// Explicitly handle pass manager names.
@@ -1090,7 +1191,7 @@ bool PassBuilder::parseModulePass(ModulePassManager &MPM,
}
// Manually handle aliases for pre-configured pipeline fragments.
- if (Name.startswith("default") || Name.startswith("lto")) {
+ if (startsWithDefaultPipelineAliasPrefix(Name)) {
SmallVector<StringRef, 3> Matches;
if (!DefaultAliasRegex.match(Name, &Matches))
return false;
@@ -1109,6 +1210,10 @@ bool PassBuilder::parseModulePass(ModulePassManager &MPM,
if (Matches[1] == "default") {
MPM.addPass(buildPerModuleDefaultPipeline(L, DebugLogging));
+ } else if (Matches[1] == "thinlto-pre-link") {
+ MPM.addPass(buildThinLTOPreLinkDefaultPipeline(L, DebugLogging));
+ } else if (Matches[1] == "thinlto") {
+ MPM.addPass(buildThinLTODefaultPipeline(L, DebugLogging));
} else if (Matches[1] == "lto-pre-link") {
MPM.addPass(buildLTOPreLinkDefaultPipeline(L, DebugLogging));
} else {
diff --git a/contrib/llvm/lib/Support/BinaryStreamReader.cpp b/contrib/llvm/lib/Support/BinaryStreamReader.cpp
index 862232971162..bfb658cfa0b7 100644
--- a/contrib/llvm/lib/Support/BinaryStreamReader.cpp
+++ b/contrib/llvm/lib/Support/BinaryStreamReader.cpp
@@ -69,6 +69,26 @@ Error BinaryStreamReader::readCString(StringRef &Dest) {
return Error::success();
}
+Error BinaryStreamReader::readWideString(ArrayRef<UTF16> &Dest) {
+ uint32_t Length = 0;
+ uint32_t OriginalOffset = getOffset();
+ const UTF16 *C;
+ while (true) {
+ if (auto EC = readObject(C))
+ return EC;
+ if (*C == 0x0000)
+ break;
+ ++Length;
+ }
+ uint32_t NewOffset = getOffset();
+ setOffset(OriginalOffset);
+
+ if (auto EC = readArray(Dest, Length))
+ return EC;
+ setOffset(NewOffset);
+ return Error::success();
+}
+
Error BinaryStreamReader::readFixedString(StringRef &Dest, uint32_t Length) {
ArrayRef<uint8_t> Bytes;
if (auto EC = readBytes(Bytes, Length))
diff --git a/contrib/llvm/lib/Support/Unix/Path.inc b/contrib/llvm/lib/Support/Unix/Path.inc
index fa28ba1b6ab6..ce638d453c19 100644
--- a/contrib/llvm/lib/Support/Unix/Path.inc
+++ b/contrib/llvm/lib/Support/Unix/Path.inc
@@ -381,6 +381,11 @@ static bool is_local_impl(struct STATVFS &Vfs) {
#elif defined(__CYGWIN__)
// Cygwin doesn't expose this information; would need to use Win32 API.
return false;
+#elif defined(__sun)
+ // statvfs::f_basetype contains a null-terminated FSType name of the mounted target
+ StringRef fstype(Vfs.f_basetype);
+ // NFS is the only non-local fstype??
+ return !fstype.equals("nfs");
#else
return !!(STATVFS_F_FLAG(Vfs) & MNT_LOCAL);
#endif
diff --git a/contrib/llvm/lib/TableGen/Record.cpp b/contrib/llvm/lib/TableGen/Record.cpp
index f07208b1fb90..83f7147dc9f6 100644
--- a/contrib/llvm/lib/TableGen/Record.cpp
+++ b/contrib/llvm/lib/TableGen/Record.cpp
@@ -1572,12 +1572,6 @@ RecordVal::RecordVal(Init *N, RecTy *T, bool P)
assert(Value && "Cannot create unset value for current type!");
}
-RecordVal::RecordVal(StringRef N, RecTy *T, bool P)
- : Name(StringInit::get(N)), TyAndPrefix(T, P) {
- Value = UnsetInit::get()->convertInitializerTo(T);
- assert(Value && "Cannot create unset value for current type!");
-}
-
StringRef RecordVal::getName() const {
return cast<StringInit>(getNameInit())->getValue();
}
@@ -1603,8 +1597,7 @@ void Record::init() {
// Every record potentially has a def at the top. This value is
// replaced with the top-level def name at instantiation time.
- RecordVal DN("NAME", StringRecTy::get(), false);
- addValue(DN);
+ addValue(RecordVal(StringInit::get("NAME"), StringRecTy::get(), false));
}
void Record::checkName() {
@@ -1640,10 +1633,6 @@ void Record::setName(Init *NewName) {
// this. See TGParser::ParseDef and TGParser::ParseDefm.
}
-void Record::setName(StringRef Name) {
- setName(StringInit::get(Name));
-}
-
void Record::resolveReferencesTo(const RecordVal *RV) {
for (RecordVal &Value : Values) {
if (RV == &Value) // Skip resolve the same field as the given one
@@ -1714,7 +1703,7 @@ Init *Record::getValueInit(StringRef FieldName) const {
return R->getValue();
}
-std::string Record::getValueAsString(StringRef FieldName) const {
+StringRef Record::getValueAsString(StringRef FieldName) const {
const RecordVal *R = getValue(FieldName);
if (!R || !R->getValue())
PrintFatalError(getLoc(), "Record `" + getName() +
@@ -1793,10 +1782,10 @@ Record::getValueAsListOfInts(StringRef FieldName) const {
return Ints;
}
-std::vector<std::string>
+std::vector<StringRef>
Record::getValueAsListOfStrings(StringRef FieldName) const {
ListInit *List = getValueAsListInit(FieldName);
- std::vector<std::string> Strings;
+ std::vector<StringRef> Strings;
for (Init *I : List->getValues()) {
if (StringInit *SI = dyn_cast<StringInit>(I))
Strings.push_back(SI->getValue());
diff --git a/contrib/llvm/lib/TableGen/TGParser.cpp b/contrib/llvm/lib/TableGen/TGParser.cpp
index 96015b06d798..b492cf9495c0 100644
--- a/contrib/llvm/lib/TableGen/TGParser.cpp
+++ b/contrib/llvm/lib/TableGen/TGParser.cpp
@@ -339,7 +339,7 @@ bool TGParser::ProcessForeachDefs(Record *CurRec, SMLoc Loc, IterSet &IterVals){
if (!IVal)
return Error(Loc, "foreach iterator value is untyped");
- IterRec->addValue(RecordVal(IterVar->getName(), IVal->getType(), false));
+ IterRec->addValue(RecordVal(IterVar->getNameInit(), IVal->getType(), false));
if (SetValue(IterRec.get(), Loc, IterVar->getNameInit(), None, IVal))
return Error(Loc, "when instantiating this def");
@@ -378,8 +378,8 @@ static bool isObjectStart(tgtok::TokKind K) {
/// GetNewAnonymousName - Generate a unique anonymous name that can be used as
/// an identifier.
-std::string TGParser::GetNewAnonymousName() {
- return "anonymous_" + utostr(AnonCounter++);
+Init *TGParser::GetNewAnonymousName() {
+ return StringInit::get("anonymous_" + utostr(AnonCounter++));
}
/// ParseObjectName - If an object name is specified, return it. Otherwise,
@@ -2350,7 +2350,7 @@ Record *TGParser::InstantiateMulticlassDef(MultiClass &MC, Record *DefProto,
bool IsAnonymous = false;
if (!DefmPrefix) {
- DefmPrefix = StringInit::get(GetNewAnonymousName());
+ DefmPrefix = GetNewAnonymousName();
IsAnonymous = true;
}
diff --git a/contrib/llvm/lib/TableGen/TGParser.h b/contrib/llvm/lib/TableGen/TGParser.h
index 76f7d8fe5026..1b2966c9f6c9 100644
--- a/contrib/llvm/lib/TableGen/TGParser.h
+++ b/contrib/llvm/lib/TableGen/TGParser.h
@@ -110,7 +110,7 @@ private: // Semantic analysis methods.
bool AddSubMultiClass(MultiClass *CurMC,
SubMultiClassReference &SubMultiClass);
- std::string GetNewAnonymousName();
+ Init *GetNewAnonymousName();
// IterRecord: Map an iterator name to a value.
struct IterRecord {
diff --git a/contrib/llvm/lib/Target/AArch64/AArch64.td b/contrib/llvm/lib/Target/AArch64/AArch64.td
index 4af5fef4287c..abe28460c83a 100644
--- a/contrib/llvm/lib/Target/AArch64/AArch64.td
+++ b/contrib/llvm/lib/Target/AArch64/AArch64.td
@@ -190,6 +190,7 @@ def ProcA53 : SubtargetFeature<"a53", "ARMProcFamily", "CortexA53",
FeatureCrypto,
FeatureCustomCheapAsMoveHandling,
FeatureFPARMv8,
+ FeatureFuseAES,
FeatureNEON,
FeaturePerfMon,
FeaturePostRAScheduler,
@@ -226,6 +227,7 @@ def ProcA73 : SubtargetFeature<"a73", "ARMProcFamily", "CortexA73",
FeatureCRC,
FeatureCrypto,
FeatureFPARMv8,
+ FeatureFuseAES,
FeatureNEON,
FeaturePerfMon
]>;
diff --git a/contrib/llvm/lib/Target/AArch64/AArch64SchedM1.td b/contrib/llvm/lib/Target/AArch64/AArch64SchedM1.td
index 3fbbc0be682d..3b71cf8399a0 100644
--- a/contrib/llvm/lib/Target/AArch64/AArch64SchedM1.td
+++ b/contrib/llvm/lib/Target/AArch64/AArch64SchedM1.td
@@ -23,7 +23,7 @@ def ExynosM1Model : SchedMachineModel {
let LoopMicroOpBufferSize = 24; // Based on the instruction queue size.
let LoadLatency = 4; // Optimistic load cases.
let MispredictPenalty = 14; // Minimum branch misprediction penalty.
- let CompleteModel = 0; // Use the default model otherwise.
+ let CompleteModel = 1; // Use the default model otherwise.
}
//===----------------------------------------------------------------------===//
@@ -72,14 +72,14 @@ def M1WriteC2 : SchedWriteRes<[M1UnitC]> { let Latency = 2; }
def M1WriteB1 : SchedWriteRes<[M1UnitB]> { let Latency = 1; }
def M1WriteL5 : SchedWriteRes<[M1UnitL]> { let Latency = 5; }
-def M1WriteLA : SchedWriteVariant<[SchedVar<ScaledIdxPred, [M1WriteL5,
+def M1WriteLX : SchedWriteVariant<[SchedVar<ScaledIdxPred, [M1WriteL5,
M1WriteA1]>,
SchedVar<NoSchedPred, [M1WriteL5]>]>;
def M1WriteS1 : SchedWriteRes<[M1UnitS]> { let Latency = 1; }
def M1WriteS2 : SchedWriteRes<[M1UnitS]> { let Latency = 2; }
def M1WriteS4 : SchedWriteRes<[M1UnitS]> { let Latency = 4; }
-def M1WriteSA : SchedWriteVariant<[SchedVar<ScaledIdxPred, [M1WriteS2,
+def M1WriteSX : SchedWriteVariant<[SchedVar<ScaledIdxPred, [M1WriteS2,
M1WriteA1]>,
SchedVar<NoSchedPred, [M1WriteS1]>]>;
@@ -125,13 +125,13 @@ def : WriteRes<WriteAdr, []> { let Latency = 0; }
// Load instructions.
def : WriteRes<WriteLD, [M1UnitL]> { let Latency = 4; }
def : WriteRes<WriteLDHi, [M1UnitALU]> { let Latency = 4; }
-def : SchedAlias<WriteLDIdx, M1WriteLA>;
+def : SchedAlias<WriteLDIdx, M1WriteLX>;
// Store instructions.
def : WriteRes<WriteST, [M1UnitS]> { let Latency = 1; }
def : WriteRes<WriteSTP, [M1UnitS]> { let Latency = 1; }
def : WriteRes<WriteSTX, [M1UnitS]> { let Latency = 1; }
-def : SchedAlias<WriteSTIdx, M1WriteSA>;
+def : SchedAlias<WriteSTIdx, M1WriteSX>;
// FP data instructions.
def : WriteRes<WriteF, [M1UnitFADD]> { let Latency = 3; }
@@ -231,6 +231,111 @@ def M1WriteNMISC3 : SchedWriteRes<[M1UnitNMISC]> { let Latency = 3; }
def M1WriteNMISC4 : SchedWriteRes<[M1UnitNMISC]> { let Latency = 4; }
def M1WriteTB : SchedWriteRes<[M1UnitC,
M1UnitALU]> { let Latency = 2; }
+def M1WriteVLDA : SchedWriteRes<[M1UnitL,
+ M1UnitL]> { let Latency = 6; }
+def M1WriteVLDB : SchedWriteRes<[M1UnitL,
+ M1UnitL,
+ M1UnitL]> { let Latency = 7; }
+def M1WriteVLDC : SchedWriteRes<[M1UnitL,
+ M1UnitL,
+ M1UnitL,
+ M1UnitL]> { let Latency = 8; }
+def M1WriteVLDD : SchedWriteRes<[M1UnitL,
+ M1UnitNALU]> { let Latency = 7;
+ let ResourceCycles = [2]; }
+def M1WriteVLDE : SchedWriteRes<[M1UnitL,
+ M1UnitNALU]> { let Latency = 6; }
+def M1WriteVLDF : SchedWriteRes<[M1UnitL,
+ M1UnitL]> { let Latency = 10;
+ let ResourceCycles = [5]; }
+def M1WriteVLDG : SchedWriteRes<[M1UnitL,
+ M1UnitNALU,
+ M1UnitNALU]> { let Latency = 7;
+ let ResourceCycles = [2]; }
+def M1WriteVLDH : SchedWriteRes<[M1UnitL,
+ M1UnitNALU,
+ M1UnitNALU]> { let Latency = 6; }
+def M1WriteVLDI : SchedWriteRes<[M1UnitL,
+ M1UnitL,
+ M1UnitL]> { let Latency = 12;
+ let ResourceCycles = [6]; }
+def M1WriteVLDJ : SchedWriteRes<[M1UnitL,
+ M1UnitNALU,
+ M1UnitNALU,
+ M1UnitNALU]> { let Latency = 9;
+ let ResourceCycles = [4]; }
+def M1WriteVLDK : SchedWriteRes<[M1UnitL,
+ M1UnitNALU,
+ M1UnitNALU,
+ M1UnitNALU,
+ M1UnitNALU]> { let Latency = 9;
+ let ResourceCycles = [4]; }
+def M1WriteVLDL : SchedWriteRes<[M1UnitL,
+ M1UnitNALU,
+ M1UnitNALU,
+ M1UnitNALU]> { let Latency = 7;
+ let ResourceCycles = [2]; }
+def M1WriteVLDM : SchedWriteRes<[M1UnitL,
+ M1UnitNALU,
+ M1UnitNALU,
+ M1UnitNALU,
+ M1UnitNALU]> { let Latency = 7;
+ let ResourceCycles = [2]; }
+def M1WriteVLDN : SchedWriteRes<[M1UnitL,
+ M1UnitL,
+ M1UnitL,
+ M1UnitL]> { let Latency = 14;
+ let ResourceCycles = [7]; }
+
+def M1WriteVSTA : WriteSequence<[WriteVST], 2>;
+def M1WriteVSTB : WriteSequence<[WriteVST], 3>;
+def M1WriteVSTC : WriteSequence<[WriteVST], 4>;
+def M1WriteVSTD : SchedWriteRes<[M1UnitS,
+ M1UnitFST,
+ M1UnitFST]> { let Latency = 7;
+ let ResourceCycles = [7]; }
+def M1WriteVSTE : SchedWriteRes<[M1UnitS,
+ M1UnitFST,
+ M1UnitS,
+ M1UnitFST,
+ M1UnitFST]> { let Latency = 8;
+ let ResourceCycles = [8]; }
+def M1WriteVSTF : SchedWriteRes<[M1UnitNALU,
+ M1UnitS,
+ M1UnitFST,
+ M1UnitS,
+ M1UnitFST,
+ M1UnitFST,
+ M1UnitFST]> { let Latency = 15;
+ let ResourceCycles = [15]; }
+def M1WriteVSTG : SchedWriteRes<[M1UnitNALU,
+ M1UnitS,
+ M1UnitFST,
+ M1UnitS,
+ M1UnitFST,
+ M1UnitS,
+ M1UnitFST,
+ M1UnitFST,
+ M1UnitFST]> { let Latency = 16;
+ let ResourceCycles = [16]; }
+def M1WriteVSTH : SchedWriteRes<[M1UnitNALU,
+ M1UnitS,
+ M1UnitFST,
+ M1UnitFST,
+ M1UnitFST]> { let Latency = 14;
+ let ResourceCycles = [14]; }
+def M1WriteVSTI : SchedWriteRes<[M1UnitNALU,
+ M1UnitS,
+ M1UnitFST,
+ M1UnitS,
+ M1UnitFST,
+ M1UnitS,
+ M1UnitFST,
+ M1UnitS,
+ M1UnitFST,
+ M1UnitFST,
+ M1UnitFST]> { let Latency = 17;
+ let ResourceCycles = [17]; }
// Branch instructions
def : InstRW<[M1WriteB1], (instrs Bcc)>;
@@ -360,8 +465,233 @@ def : InstRW<[M1WriteNALU2], (instregex "^(TRN|UZP)[12](v16i8|v8i16|v4i32|v2i64
def : InstRW<[M1WriteNALU1], (instregex "^ZIP[12]v")>;
// ASIMD load instructions.
+def : InstRW<[M1WriteVLDD], (instregex "LD1i(8|16|32)$")>;
+def : InstRW<[M1WriteVLDD,
+ WriteAdr], (instregex "LD1i(8|16|32)_POST$")>;
+def : InstRW<[M1WriteVLDE], (instregex "LD1i(64)$")>;
+def : InstRW<[M1WriteVLDE,
+ WriteAdr], (instregex "LD1i(64)_POST$")>;
+
+def : InstRW<[M1WriteL5], (instregex "LD1Rv(8b|4h|2s)$")>;
+def : InstRW<[M1WriteL5,
+ WriteAdr], (instregex "LD1Rv(8b|4h|2s)_POST$")>;
+def : InstRW<[M1WriteL5], (instregex "LD1Rv(1d)$")>;
+def : InstRW<[M1WriteL5,
+ WriteAdr], (instregex "LD1Rv(1d)_POST$")>;
+def : InstRW<[M1WriteL5], (instregex "LD1Rv(16b|8h|4s|2d)$")>;
+def : InstRW<[M1WriteL5,
+ WriteAdr], (instregex "LD1Rv(16b|8h|4s|2d)_POST$")>;
+
+def : InstRW<[M1WriteL5], (instregex "LD1Onev(8b|4h|2s|1d)$")>;
+def : InstRW<[M1WriteL5,
+ WriteAdr], (instregex "LD1Onev(8b|4h|2s|1d)_POST$")>;
+def : InstRW<[M1WriteL5], (instregex "LD1Onev(16b|8h|4s|2d)$")>;
+def : InstRW<[M1WriteL5,
+ WriteAdr], (instregex "LD1Onev(16b|8h|4s|2d)_POST$")>;
+def : InstRW<[M1WriteVLDA], (instregex "LD1Twov(8b|4h|2s|1d)$")>;
+def : InstRW<[M1WriteVLDA,
+ WriteAdr], (instregex "LD1Twov(8b|4h|2s|1d)_POST$")>;
+def : InstRW<[M1WriteVLDA], (instregex "LD1Twov(16b|8h|4s|2d)$")>;
+def : InstRW<[M1WriteVLDA,
+ WriteAdr], (instregex "LD1Twov(16b|8h|4s|2d)_POST$")>;
+def : InstRW<[M1WriteVLDB], (instregex "LD1Threev(8b|4h|2s|1d)$")>;
+def : InstRW<[M1WriteVLDB,
+ WriteAdr], (instregex "LD1Threev(8b|4h|2s|1d)_POST$")>;
+def : InstRW<[M1WriteVLDB], (instregex "LD1Threev(16b|8h|4s|2d)$")>;
+def : InstRW<[M1WriteVLDB,
+ WriteAdr], (instregex "LD1Threev(16b|8h|4s|2d)_POST$")>;
+def : InstRW<[M1WriteVLDC], (instregex "LD1Fourv(8b|4h|2s|1d)$")>;
+def : InstRW<[M1WriteVLDC,
+ WriteAdr], (instregex "LD1Fourv(8b|4h|2s|1d)_POST$")>;
+def : InstRW<[M1WriteVLDC], (instregex "LD1Fourv(16b|8h|4s|2d)$")>;
+def : InstRW<[M1WriteVLDC,
+ WriteAdr], (instregex "LD1Fourv(16b|8h|4s|2d)_POST$")>;
+
+def : InstRW<[M1WriteVLDG], (instregex "LD2i(8|16)$")>;
+def : InstRW<[M1WriteVLDG,
+ WriteAdr], (instregex "LD2i(8|16)_POST$")>;
+def : InstRW<[M1WriteVLDG], (instregex "LD2i(32)$")>;
+def : InstRW<[M1WriteVLDG,
+ WriteAdr], (instregex "LD2i(32)_POST$")>;
+def : InstRW<[M1WriteVLDH], (instregex "LD2i(64)$")>;
+def : InstRW<[M1WriteVLDH,
+ WriteAdr], (instregex "LD2i(64)_POST$")>;
+
+def : InstRW<[M1WriteVLDA], (instregex "LD2Rv(8b|4h|2s)$")>;
+def : InstRW<[M1WriteVLDA,
+ WriteAdr], (instregex "LD2Rv(8b|4h|2s)_POST$")>;
+def : InstRW<[M1WriteVLDA], (instregex "LD2Rv(1d)$")>;
+def : InstRW<[M1WriteVLDA,
+ WriteAdr], (instregex "LD2Rv(1d)_POST$")>;
+def : InstRW<[M1WriteVLDA], (instregex "LD2Rv(16b|8h|4s|2d)$")>;
+def : InstRW<[M1WriteVLDA,
+ WriteAdr], (instregex "LD2Rv(16b|8h|4s|2d)_POST$")>;
+
+def : InstRW<[M1WriteVLDF], (instregex "LD2Twov(8b|4h|2s)$")>;
+def : InstRW<[M1WriteVLDF,
+ WriteAdr], (instregex "LD2Twov(8b|4h|2s)_POST$")>;
+def : InstRW<[M1WriteVLDF], (instregex "LD2Twov(16b|8h|4s)$")>;
+def : InstRW<[M1WriteVLDF,
+ WriteAdr], (instregex "LD2Twov(16b|8h|4s)_POST$")>;
+def : InstRW<[M1WriteVLDF], (instregex "LD2Twov(2d)$")>;
+def : InstRW<[M1WriteVLDF,
+ WriteAdr], (instregex "LD2Twov(2d)_POST$")>;
+
+def : InstRW<[M1WriteVLDJ], (instregex "LD3i(8|16)$")>;
+def : InstRW<[M1WriteVLDJ,
+ WriteAdr], (instregex "LD3i(8|16)_POST$")>;
+def : InstRW<[M1WriteVLDJ], (instregex "LD3i(32)$")>;
+def : InstRW<[M1WriteVLDJ,
+ WriteAdr], (instregex "LD3i(32)_POST$")>;
+def : InstRW<[M1WriteVLDL], (instregex "LD3i(64)$")>;
+def : InstRW<[M1WriteVLDL,
+ WriteAdr], (instregex "LD3i(64)_POST$")>;
+
+def : InstRW<[M1WriteVLDB], (instregex "LD3Rv(8b|4h|2s)$")>;
+def : InstRW<[M1WriteVLDB,
+ WriteAdr], (instregex "LD3Rv(8b|4h|2s)_POST$")>;
+def : InstRW<[M1WriteVLDB], (instregex "LD3Rv(1d)$")>;
+def : InstRW<[M1WriteVLDB,
+ WriteAdr], (instregex "LD3Rv(1d)_POST$")>;
+def : InstRW<[M1WriteVLDB], (instregex "LD3Rv(16b|8h|4s)$")>;
+def : InstRW<[M1WriteVLDB,
+ WriteAdr], (instregex "LD3Rv(16b|8h|4s)_POST$")>;
+def : InstRW<[M1WriteVLDB], (instregex "LD3Rv(2d)$")>;
+def : InstRW<[M1WriteVLDB,
+ WriteAdr], (instregex "LD3Rv(2d)_POST$")>;
+
+def : InstRW<[M1WriteVLDI], (instregex "LD3Threev(8b|4h|2s)$")>;
+def : InstRW<[M1WriteVLDI,
+ WriteAdr], (instregex "LD3Threev(8b|4h|2s)_POST$")>;
+def : InstRW<[M1WriteVLDI], (instregex "LD3Threev(16b|8h|4s)$")>;
+def : InstRW<[M1WriteVLDI,
+ WriteAdr], (instregex "LD3Threev(16b|8h|4s)_POST$")>;
+def : InstRW<[M1WriteVLDI], (instregex "LD3Threev(2d)$")>;
+def : InstRW<[M1WriteVLDI,
+ WriteAdr], (instregex "LD3Threev(2d)_POST$")>;
+
+def : InstRW<[M1WriteVLDK], (instregex "LD4i(8|16)$")>;
+def : InstRW<[M1WriteVLDK,
+ WriteAdr], (instregex "LD4i(8|16)_POST$")>;
+def : InstRW<[M1WriteVLDK], (instregex "LD4i(32)$")>;
+def : InstRW<[M1WriteVLDK,
+ WriteAdr], (instregex "LD4i(32)_POST$")>;
+def : InstRW<[M1WriteVLDM], (instregex "LD4i(64)$")>;
+def : InstRW<[M1WriteVLDM,
+ WriteAdr], (instregex "LD4i(64)_POST$")>;
+
+def : InstRW<[M1WriteVLDC], (instregex "LD4Rv(8b|4h|2s)$")>;
+def : InstRW<[M1WriteVLDC,
+ WriteAdr], (instregex "LD4Rv(8b|4h|2s)_POST$")>;
+def : InstRW<[M1WriteVLDC], (instregex "LD4Rv(1d)$")>;
+def : InstRW<[M1WriteVLDC,
+ WriteAdr], (instregex "LD4Rv(1d)_POST$")>;
+def : InstRW<[M1WriteVLDC], (instregex "LD4Rv(16b|8h|4s)$")>;
+def : InstRW<[M1WriteVLDC,
+ WriteAdr], (instregex "LD4Rv(16b|8h|4s)_POST$")>;
+def : InstRW<[M1WriteVLDC], (instregex "LD4Rv(2d)$")>;
+def : InstRW<[M1WriteVLDC,
+ WriteAdr], (instregex "LD4Rv(2d)_POST$")>;
+
+def : InstRW<[M1WriteVLDN], (instregex "LD4Fourv(8b|4h|2s)$")>;
+def : InstRW<[M1WriteVLDN,
+ WriteAdr], (instregex "LD4Fourv(8b|4h|2s)_POST$")>;
+def : InstRW<[M1WriteVLDN], (instregex "LD4Fourv(16b|8h|4s)$")>;
+def : InstRW<[M1WriteVLDN,
+ WriteAdr], (instregex "LD4Fourv(16b|8h|4s)_POST$")>;
+def : InstRW<[M1WriteVLDN], (instregex "LD4Fourv(2d)$")>;
+def : InstRW<[M1WriteVLDN,
+ WriteAdr], (instregex "LD4Fourv(2d)_POST$")>;
// ASIMD store instructions.
+def : InstRW<[M1WriteVSTD], (instregex "ST1i(8|16|32)$")>;
+def : InstRW<[M1WriteVSTD,
+ WriteAdr], (instregex "ST1i(8|16|32)_POST$")>;
+def : InstRW<[M1WriteVSTD], (instregex "ST1i(64)$")>;
+def : InstRW<[M1WriteVSTD,
+ WriteAdr], (instregex "ST1i(64)_POST$")>;
+
+def : InstRW<[WriteVST], (instregex "ST1Onev(8b|4h|2s|1d)$")>;
+def : InstRW<[WriteVST,
+ WriteAdr], (instregex "ST1Onev(8b|4h|2s|1d)_POST$")>;
+def : InstRW<[WriteVST], (instregex "ST1Onev(16b|8h|4s|2d)$")>;
+def : InstRW<[WriteVST,
+ WriteAdr], (instregex "ST1Onev(16b|8h|4s|2d)_POST$")>;
+def : InstRW<[M1WriteVSTA], (instregex "ST1Twov(8b|4h|2s|1d)$")>;
+def : InstRW<[M1WriteVSTA,
+ WriteAdr], (instregex "ST1Twov(8b|4h|2s|1d)_POST$")>;
+def : InstRW<[M1WriteVSTA], (instregex "ST1Twov(16b|8h|4s|2d)$")>;
+def : InstRW<[M1WriteVSTA,
+ WriteAdr], (instregex "ST1Twov(16b|8h|4s|2d)_POST$")>;
+def : InstRW<[M1WriteVSTB], (instregex "ST1Threev(8b|4h|2s|1d)$")>;
+def : InstRW<[M1WriteVSTB,
+ WriteAdr], (instregex "ST1Threev(8b|4h|2s|1d)_POST$")>;
+def : InstRW<[M1WriteVSTB], (instregex "ST1Threev(16b|8h|4s|2d)$")>;
+def : InstRW<[M1WriteVSTB,
+ WriteAdr], (instregex "ST1Threev(16b|8h|4s|2d)_POST$")>;
+def : InstRW<[M1WriteVSTC], (instregex "ST1Fourv(8b|4h|2s|1d)$")>;
+def : InstRW<[M1WriteVSTC,
+ WriteAdr], (instregex "ST1Fourv(8b|4h|2s|1d)_POST$")>;
+def : InstRW<[M1WriteVSTC], (instregex "ST1Fourv(16b|8h|4s|2d)$")>;
+def : InstRW<[M1WriteVSTC,
+ WriteAdr], (instregex "ST1Fourv(16b|8h|4s|2d)_POST$")>;
+
+def : InstRW<[M1WriteVSTD], (instregex "ST2i(8|16|32)$")>;
+def : InstRW<[M1WriteVSTD,
+ WriteAdr], (instregex "ST2i(8|16|32)_POST$")>;
+def : InstRW<[M1WriteVSTD], (instregex "ST2i(64)$")>;
+def : InstRW<[M1WriteVSTD,
+ WriteAdr], (instregex "ST2i(64)_POST$")>;
+
+def : InstRW<[M1WriteVSTD], (instregex "ST2Twov(8b|4h|2s)$")>;
+def : InstRW<[M1WriteVSTD,
+ WriteAdr], (instregex "ST2Twov(8b|4h|2s)_POST$")>;
+def : InstRW<[M1WriteVSTE], (instregex "ST2Twov(16b|8h|4s)$")>;
+def : InstRW<[M1WriteVSTE,
+ WriteAdr], (instregex "ST2Twov(16b|8h|4s)_POST$")>;
+def : InstRW<[M1WriteVSTE], (instregex "ST2Twov(2d)$")>;
+def : InstRW<[M1WriteVSTE,
+ WriteAdr], (instregex "ST2Twov(2d)_POST$")>;
+
+def : InstRW<[M1WriteVSTH], (instregex "ST3i(8|16)$")>;
+def : InstRW<[M1WriteVSTH,
+ WriteAdr], (instregex "ST3i(8|16)_POST$")>;
+def : InstRW<[M1WriteVSTH], (instregex "ST3i(32)$")>;
+def : InstRW<[M1WriteVSTH,
+ WriteAdr], (instregex "ST3i(32)_POST$")>;
+def : InstRW<[M1WriteVSTF], (instregex "ST3i(64)$")>;
+def : InstRW<[M1WriteVSTF,
+ WriteAdr], (instregex "ST3i(64)_POST$")>;
+
+def : InstRW<[M1WriteVSTF], (instregex "ST3Threev(8b|4h|2s)$")>;
+def : InstRW<[M1WriteVSTF,
+ WriteAdr], (instregex "ST3Threev(8b|4h|2s)_POST$")>;
+def : InstRW<[M1WriteVSTG], (instregex "ST3Threev(16b|8h|4s)$")>;
+def : InstRW<[M1WriteVSTG,
+ WriteAdr], (instregex "ST3Threev(16b|8h|4s)_POST$")>;
+def : InstRW<[M1WriteVSTG], (instregex "ST3Threev(2d)$")>;
+def : InstRW<[M1WriteVSTG,
+ WriteAdr], (instregex "ST3Threev(2d)_POST$")>;
+
+def : InstRW<[M1WriteVSTH], (instregex "ST4i(8|16)$")>;
+def : InstRW<[M1WriteVSTH,
+ WriteAdr], (instregex "ST4i(8|16)_POST$")>;
+def : InstRW<[M1WriteVSTH], (instregex "ST4i(32)$")>;
+def : InstRW<[M1WriteVSTH,
+ WriteAdr], (instregex "ST4i(32)_POST$")>;
+def : InstRW<[M1WriteVSTF], (instregex "ST4i(64)$")>;
+def : InstRW<[M1WriteVSTF,
+ WriteAdr], (instregex "ST4i(64)_POST$")>;
+
+def : InstRW<[M1WriteVSTF], (instregex "ST4Fourv(8b|4h|2s)$")>;
+def : InstRW<[M1WriteVSTF,
+ WriteAdr], (instregex "ST4Fourv(8b|4h|2s)_POST$")>;
+def : InstRW<[M1WriteVSTI], (instregex "ST4Fourv(16b|8h|4s)$")>;
+def : InstRW<[M1WriteVSTI,
+ WriteAdr], (instregex "ST4Fourv(16b|8h|4s)_POST$")>;
+def : InstRW<[M1WriteVSTI], (instregex "ST4Fourv(2d)$")>;
+def : InstRW<[M1WriteVSTI,
+ WriteAdr], (instregex "ST4Fourv(2d)_POST$")>;
// Cryptography instructions.
def M1WriteAES : SchedWriteRes<[M1UnitNCRYPT]> { let Latency = 1; }
diff --git a/contrib/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp b/contrib/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp
index cb3f72a524f5..d4a8cecdb29f 100644
--- a/contrib/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp
+++ b/contrib/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp
@@ -256,9 +256,9 @@ namespace {
/// AArch64 Code Generator Pass Configuration Options.
class AArch64PassConfig : public TargetPassConfig {
public:
- AArch64PassConfig(AArch64TargetMachine *TM, PassManagerBase &PM)
+ AArch64PassConfig(AArch64TargetMachine &TM, PassManagerBase &PM)
: TargetPassConfig(TM, PM) {
- if (TM->getOptLevel() != CodeGenOpt::None)
+ if (TM.getOptLevel() != CodeGenOpt::None)
substitutePass(&PostRASchedulerID, &PostMachineSchedulerID);
}
@@ -317,7 +317,7 @@ TargetIRAnalysis AArch64TargetMachine::getTargetIRAnalysis() {
}
TargetPassConfig *AArch64TargetMachine::createPassConfig(PassManagerBase &PM) {
- return new AArch64PassConfig(this, PM);
+ return new AArch64PassConfig(*this, PM);
}
void AArch64PassConfig::addIRPasses() {
diff --git a/contrib/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp b/contrib/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp
index f473944cd528..0959014812d8 100644
--- a/contrib/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp
+++ b/contrib/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp
@@ -503,40 +503,37 @@ AMDGPUAsmPrinter::SIFunctionResourceInfo AMDGPUAsmPrinter::analyzeResourceUsage(
Info.HasDynamicallySizedStack = FrameInfo.hasVarSizedObjects();
Info.PrivateSegmentSize = FrameInfo.getStackSize();
- if (!FrameInfo.hasCalls()) {
- Info.UsesVCC = MRI.isPhysRegUsed(AMDGPU::VCC_LO) ||
- MRI.isPhysRegUsed(AMDGPU::VCC_HI);
-
- // If there are no calls, MachineRegisterInfo can tell us the used register
- // count easily.
-
- MCPhysReg HighestVGPRReg = AMDGPU::NoRegister;
- for (MCPhysReg Reg : reverse(AMDGPU::VGPR_32RegClass.getRegisters())) {
- if (MRI.isPhysRegUsed(Reg)) {
- HighestVGPRReg = Reg;
- break;
- }
- }
- MCPhysReg HighestSGPRReg = AMDGPU::NoRegister;
- for (MCPhysReg Reg : reverse(AMDGPU::SGPR_32RegClass.getRegisters())) {
- if (MRI.isPhysRegUsed(Reg)) {
- HighestSGPRReg = Reg;
- break;
- }
- }
+ Info.UsesVCC = MRI.isPhysRegUsed(AMDGPU::VCC_LO) ||
+ MRI.isPhysRegUsed(AMDGPU::VCC_HI);
- // We found the maximum register index. They start at 0, so add one to get the
- // number of registers.
- Info.NumVGPR = HighestVGPRReg == AMDGPU::NoRegister ? 0 :
- TRI.getHWRegIndex(HighestVGPRReg) + 1;
- Info.NumExplicitSGPR = HighestSGPRReg == AMDGPU::NoRegister ? 0 :
- TRI.getHWRegIndex(HighestSGPRReg) + 1;
+ // If there are no calls, MachineRegisterInfo can tell us the used register
+ // count easily.
- return Info;
+ MCPhysReg HighestVGPRReg = AMDGPU::NoRegister;
+ for (MCPhysReg Reg : reverse(AMDGPU::VGPR_32RegClass.getRegisters())) {
+ if (MRI.isPhysRegUsed(Reg)) {
+ HighestVGPRReg = Reg;
+ break;
+ }
}
- llvm_unreachable("calls not implemented");
+ MCPhysReg HighestSGPRReg = AMDGPU::NoRegister;
+ for (MCPhysReg Reg : reverse(AMDGPU::SGPR_32RegClass.getRegisters())) {
+ if (MRI.isPhysRegUsed(Reg)) {
+ HighestSGPRReg = Reg;
+ break;
+ }
+ }
+
+ // We found the maximum register index. They start at 0, so add one to get the
+ // number of registers.
+ Info.NumVGPR = HighestVGPRReg == AMDGPU::NoRegister ? 0 :
+ TRI.getHWRegIndex(HighestVGPRReg) + 1;
+ Info.NumExplicitSGPR = HighestSGPRReg == AMDGPU::NoRegister ? 0 :
+ TRI.getHWRegIndex(HighestSGPRReg) + 1;
+
+ return Info;
}
void AMDGPUAsmPrinter::getSIProgramInfo(SIProgramInfo &ProgInfo,
diff --git a/contrib/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp b/contrib/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
index 48827f463997..596f02ae4a64 100644
--- a/contrib/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
+++ b/contrib/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
@@ -456,7 +456,7 @@ namespace {
class AMDGPUPassConfig : public TargetPassConfig {
public:
- AMDGPUPassConfig(TargetMachine *TM, PassManagerBase &PM)
+ AMDGPUPassConfig(LLVMTargetMachine &TM, PassManagerBase &PM)
: TargetPassConfig(TM, PM) {
// Exceptions and StackMaps are not supported, so these passes will never do
// anything.
@@ -487,7 +487,7 @@ public:
class R600PassConfig final : public AMDGPUPassConfig {
public:
- R600PassConfig(TargetMachine *TM, PassManagerBase &PM)
+ R600PassConfig(LLVMTargetMachine &TM, PassManagerBase &PM)
: AMDGPUPassConfig(TM, PM) {}
ScheduleDAGInstrs *createMachineScheduler(
@@ -503,7 +503,7 @@ public:
class GCNPassConfig final : public AMDGPUPassConfig {
public:
- GCNPassConfig(TargetMachine *TM, PassManagerBase &PM)
+ GCNPassConfig(LLVMTargetMachine &TM, PassManagerBase &PM)
: AMDGPUPassConfig(TM, PM) {}
GCNTargetMachine &getGCNTargetMachine() const {
@@ -682,7 +682,7 @@ void R600PassConfig::addPreEmitPass() {
}
TargetPassConfig *R600TargetMachine::createPassConfig(PassManagerBase &PM) {
- return new R600PassConfig(this, PM);
+ return new R600PassConfig(*this, PM);
}
//===----------------------------------------------------------------------===//
@@ -844,6 +844,6 @@ void GCNPassConfig::addPreEmitPass() {
}
TargetPassConfig *GCNTargetMachine::createPassConfig(PassManagerBase &PM) {
- return new GCNPassConfig(this, PM);
+ return new GCNPassConfig(*this, PM);
}
diff --git a/contrib/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.h b/contrib/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.h
index 934bf7f31bab..a3c7c1982d0a 100644
--- a/contrib/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.h
+++ b/contrib/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.h
@@ -69,7 +69,6 @@ public:
return -1;
return 0;
}
-
};
//===----------------------------------------------------------------------===//
@@ -89,6 +88,10 @@ public:
TargetPassConfig *createPassConfig(PassManagerBase &PM) override;
const R600Subtarget *getSubtargetImpl(const Function &) const override;
+
+ bool isMachineVerifierClean() const override {
+ return false;
+ }
};
//===----------------------------------------------------------------------===//
diff --git a/contrib/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp b/contrib/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
index f5541e08e1b7..cc68c971b249 100644
--- a/contrib/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
+++ b/contrib/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
@@ -161,7 +161,8 @@ public:
ImmTyOpSel,
ImmTyOpSelHi,
ImmTyNegLo,
- ImmTyNegHi
+ ImmTyNegHi,
+ ImmTySwizzle
};
struct TokOp {
@@ -474,6 +475,7 @@ public:
bool isSWaitCnt() const;
bool isHwreg() const;
bool isSendMsg() const;
+ bool isSwizzle() const;
bool isSMRDOffset8() const;
bool isSMRDOffset20() const;
bool isSMRDLiteralOffset() const;
@@ -659,6 +661,7 @@ public:
case ImmTyOpSelHi: OS << "OpSelHi"; break;
case ImmTyNegLo: OS << "NegLo"; break;
case ImmTyNegHi: OS << "NegHi"; break;
+ case ImmTySwizzle: OS << "Swizzle"; break;
}
}
@@ -994,6 +997,12 @@ private:
bool isInlineConstant(const MCInst &Inst, unsigned OpIdx) const;
unsigned findImplicitSGPRReadInVOP(const MCInst &Inst) const;
+ bool trySkipId(const StringRef Id);
+ bool trySkipToken(const AsmToken::TokenKind Kind);
+ bool skipToken(const AsmToken::TokenKind Kind, const StringRef ErrMsg);
+ bool parseString(StringRef &Val, const StringRef ErrMsg = "expected a string");
+ bool parseExpr(int64_t &Imm);
+
public:
OperandMatchResultTy parseOptionalOperand(OperandVector &Operands);
@@ -1003,6 +1012,19 @@ public:
OperandMatchResultTy parseInterpAttr(OperandVector &Operands);
OperandMatchResultTy parseSOppBrTarget(OperandVector &Operands);
+ bool parseSwizzleOperands(const unsigned OpNum, int64_t* Op,
+ const unsigned MinVal,
+ const unsigned MaxVal,
+ const StringRef ErrMsg);
+ OperandMatchResultTy parseSwizzleOp(OperandVector &Operands);
+ bool parseSwizzleOffset(int64_t &Imm);
+ bool parseSwizzleMacro(int64_t &Imm);
+ bool parseSwizzleQuadPerm(int64_t &Imm);
+ bool parseSwizzleBitmaskPerm(int64_t &Imm);
+ bool parseSwizzleBroadcast(int64_t &Imm);
+ bool parseSwizzleSwap(int64_t &Imm);
+ bool parseSwizzleReverse(int64_t &Imm);
+
void cvtMubuf(MCInst &Inst, const OperandVector &Operands) { cvtMubufImpl(Inst, Operands, false, false); }
void cvtMubufAtomic(MCInst &Inst, const OperandVector &Operands) { cvtMubufImpl(Inst, Operands, true, false); }
void cvtMubufAtomicReturn(MCInst &Inst, const OperandVector &Operands) { cvtMubufImpl(Inst, Operands, true, true); }
@@ -2785,7 +2807,13 @@ void AMDGPUAsmParser::cvtDSImpl(MCInst &Inst, const OperandVector &Operands,
OptionalIdx[Op.getImmTy()] = i;
}
- addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyOffset);
+ AMDGPUOperand::ImmTy OffsetType =
+ (Inst.getOpcode() == AMDGPU::DS_SWIZZLE_B32_si ||
+ Inst.getOpcode() == AMDGPU::DS_SWIZZLE_B32_vi) ? AMDGPUOperand::ImmTySwizzle :
+ AMDGPUOperand::ImmTyOffset;
+
+ addOptionalImmOperand(Inst, Operands, OptionalIdx, OffsetType);
+
if (!IsGdsHardcoded) {
addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyGDS);
}
@@ -3384,6 +3412,298 @@ bool AMDGPUOperand::isSendMsg() const {
}
//===----------------------------------------------------------------------===//
+// parser helpers
+//===----------------------------------------------------------------------===//
+
+bool
+AMDGPUAsmParser::trySkipId(const StringRef Id) {
+ if (getLexer().getKind() == AsmToken::Identifier &&
+ Parser.getTok().getString() == Id) {
+ Parser.Lex();
+ return true;
+ }
+ return false;
+}
+
+bool
+AMDGPUAsmParser::trySkipToken(const AsmToken::TokenKind Kind) {
+ if (getLexer().getKind() == Kind) {
+ Parser.Lex();
+ return true;
+ }
+ return false;
+}
+
+bool
+AMDGPUAsmParser::skipToken(const AsmToken::TokenKind Kind,
+ const StringRef ErrMsg) {
+ if (!trySkipToken(Kind)) {
+ Error(Parser.getTok().getLoc(), ErrMsg);
+ return false;
+ }
+ return true;
+}
+
+bool
+AMDGPUAsmParser::parseExpr(int64_t &Imm) {
+ return !getParser().parseAbsoluteExpression(Imm);
+}
+
+bool
+AMDGPUAsmParser::parseString(StringRef &Val, const StringRef ErrMsg) {
+ SMLoc S = Parser.getTok().getLoc();
+ if (getLexer().getKind() == AsmToken::String) {
+ Val = Parser.getTok().getStringContents();
+ Parser.Lex();
+ return true;
+ } else {
+ Error(S, ErrMsg);
+ return false;
+ }
+}
+
+//===----------------------------------------------------------------------===//
+// swizzle
+//===----------------------------------------------------------------------===//
+
+LLVM_READNONE
+static unsigned
+encodeBitmaskPerm(const unsigned AndMask,
+ const unsigned OrMask,
+ const unsigned XorMask) {
+ using namespace llvm::AMDGPU::Swizzle;
+
+ return BITMASK_PERM_ENC |
+ (AndMask << BITMASK_AND_SHIFT) |
+ (OrMask << BITMASK_OR_SHIFT) |
+ (XorMask << BITMASK_XOR_SHIFT);
+}
+
+bool
+AMDGPUAsmParser::parseSwizzleOperands(const unsigned OpNum, int64_t* Op,
+ const unsigned MinVal,
+ const unsigned MaxVal,
+ const StringRef ErrMsg) {
+ for (unsigned i = 0; i < OpNum; ++i) {
+ if (!skipToken(AsmToken::Comma, "expected a comma")){
+ return false;
+ }
+ SMLoc ExprLoc = Parser.getTok().getLoc();
+ if (!parseExpr(Op[i])) {
+ return false;
+ }
+ if (Op[i] < MinVal || Op[i] > MaxVal) {
+ Error(ExprLoc, ErrMsg);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool
+AMDGPUAsmParser::parseSwizzleQuadPerm(int64_t &Imm) {
+ using namespace llvm::AMDGPU::Swizzle;
+
+ int64_t Lane[LANE_NUM];
+ if (parseSwizzleOperands(LANE_NUM, Lane, 0, LANE_MAX,
+ "expected a 2-bit lane id")) {
+ Imm = QUAD_PERM_ENC;
+ for (auto i = 0; i < LANE_NUM; ++i) {
+ Imm |= Lane[i] << (LANE_SHIFT * i);
+ }
+ return true;
+ }
+ return false;
+}
+
+bool
+AMDGPUAsmParser::parseSwizzleBroadcast(int64_t &Imm) {
+ using namespace llvm::AMDGPU::Swizzle;
+
+ SMLoc S = Parser.getTok().getLoc();
+ int64_t GroupSize;
+ int64_t LaneIdx;
+
+ if (!parseSwizzleOperands(1, &GroupSize,
+ 2, 32,
+ "group size must be in the interval [2,32]")) {
+ return false;
+ }
+ if (!isPowerOf2_64(GroupSize)) {
+ Error(S, "group size must be a power of two");
+ return false;
+ }
+ if (parseSwizzleOperands(1, &LaneIdx,
+ 0, GroupSize - 1,
+ "lane id must be in the interval [0,group size - 1]")) {
+ Imm = encodeBitmaskPerm(BITMASK_MAX - GroupSize + 1, LaneIdx, 0);
+ return true;
+ }
+ return false;
+}
+
+bool
+AMDGPUAsmParser::parseSwizzleReverse(int64_t &Imm) {
+ using namespace llvm::AMDGPU::Swizzle;
+
+ SMLoc S = Parser.getTok().getLoc();
+ int64_t GroupSize;
+
+ if (!parseSwizzleOperands(1, &GroupSize,
+ 2, 32, "group size must be in the interval [2,32]")) {
+ return false;
+ }
+ if (!isPowerOf2_64(GroupSize)) {
+ Error(S, "group size must be a power of two");
+ return false;
+ }
+
+ Imm = encodeBitmaskPerm(BITMASK_MAX, 0, GroupSize - 1);
+ return true;
+}
+
+bool
+AMDGPUAsmParser::parseSwizzleSwap(int64_t &Imm) {
+ using namespace llvm::AMDGPU::Swizzle;
+
+ SMLoc S = Parser.getTok().getLoc();
+ int64_t GroupSize;
+
+ if (!parseSwizzleOperands(1, &GroupSize,
+ 1, 16, "group size must be in the interval [1,16]")) {
+ return false;
+ }
+ if (!isPowerOf2_64(GroupSize)) {
+ Error(S, "group size must be a power of two");
+ return false;
+ }
+
+ Imm = encodeBitmaskPerm(BITMASK_MAX, 0, GroupSize);
+ return true;
+}
+
+bool
+AMDGPUAsmParser::parseSwizzleBitmaskPerm(int64_t &Imm) {
+ using namespace llvm::AMDGPU::Swizzle;
+
+ if (!skipToken(AsmToken::Comma, "expected a comma")) {
+ return false;
+ }
+
+ StringRef Ctl;
+ SMLoc StrLoc = Parser.getTok().getLoc();
+ if (!parseString(Ctl)) {
+ return false;
+ }
+ if (Ctl.size() != BITMASK_WIDTH) {
+ Error(StrLoc, "expected a 5-character mask");
+ return false;
+ }
+
+ unsigned AndMask = 0;
+ unsigned OrMask = 0;
+ unsigned XorMask = 0;
+
+ for (size_t i = 0; i < Ctl.size(); ++i) {
+ unsigned Mask = 1 << (BITMASK_WIDTH - 1 - i);
+ switch(Ctl[i]) {
+ default:
+ Error(StrLoc, "invalid mask");
+ return false;
+ case '0':
+ break;
+ case '1':
+ OrMask |= Mask;
+ break;
+ case 'p':
+ AndMask |= Mask;
+ break;
+ case 'i':
+ AndMask |= Mask;
+ XorMask |= Mask;
+ break;
+ }
+ }
+
+ Imm = encodeBitmaskPerm(AndMask, OrMask, XorMask);
+ return true;
+}
+
+bool
+AMDGPUAsmParser::parseSwizzleOffset(int64_t &Imm) {
+
+ SMLoc OffsetLoc = Parser.getTok().getLoc();
+
+ if (!parseExpr(Imm)) {
+ return false;
+ }
+ if (!isUInt<16>(Imm)) {
+ Error(OffsetLoc, "expected a 16-bit offset");
+ return false;
+ }
+ return true;
+}
+
+bool
+AMDGPUAsmParser::parseSwizzleMacro(int64_t &Imm) {
+ using namespace llvm::AMDGPU::Swizzle;
+
+ if (skipToken(AsmToken::LParen, "expected a left parentheses")) {
+
+ SMLoc ModeLoc = Parser.getTok().getLoc();
+ bool Ok = false;
+
+ if (trySkipId(IdSymbolic[ID_QUAD_PERM])) {
+ Ok = parseSwizzleQuadPerm(Imm);
+ } else if (trySkipId(IdSymbolic[ID_BITMASK_PERM])) {
+ Ok = parseSwizzleBitmaskPerm(Imm);
+ } else if (trySkipId(IdSymbolic[ID_BROADCAST])) {
+ Ok = parseSwizzleBroadcast(Imm);
+ } else if (trySkipId(IdSymbolic[ID_SWAP])) {
+ Ok = parseSwizzleSwap(Imm);
+ } else if (trySkipId(IdSymbolic[ID_REVERSE])) {
+ Ok = parseSwizzleReverse(Imm);
+ } else {
+ Error(ModeLoc, "expected a swizzle mode");
+ }
+
+ return Ok && skipToken(AsmToken::RParen, "expected a closing parentheses");
+ }
+
+ return false;
+}
+
+OperandMatchResultTy
+AMDGPUAsmParser::parseSwizzleOp(OperandVector &Operands) {
+ SMLoc S = Parser.getTok().getLoc();
+ int64_t Imm = 0;
+
+ if (trySkipId("offset")) {
+
+ bool Ok = false;
+ if (skipToken(AsmToken::Colon, "expected a colon")) {
+ if (trySkipId("swizzle")) {
+ Ok = parseSwizzleMacro(Imm);
+ } else {
+ Ok = parseSwizzleOffset(Imm);
+ }
+ }
+
+ Operands.push_back(AMDGPUOperand::CreateImm(this, Imm, S, AMDGPUOperand::ImmTySwizzle));
+
+ return Ok? MatchOperand_Success : MatchOperand_ParseFail;
+ } else {
+ return MatchOperand_NoMatch;
+ }
+}
+
+bool
+AMDGPUOperand::isSwizzle() const {
+ return isImmTy(ImmTySwizzle);
+}
+
+//===----------------------------------------------------------------------===//
// sopp branch targets
//===----------------------------------------------------------------------===//
diff --git a/contrib/llvm/lib/Target/AMDGPU/DSInstructions.td b/contrib/llvm/lib/Target/AMDGPU/DSInstructions.td
index 357e18108e7e..fc516c3b39c2 100644
--- a/contrib/llvm/lib/Target/AMDGPU/DSInstructions.td
+++ b/contrib/llvm/lib/Target/AMDGPU/DSInstructions.td
@@ -145,10 +145,10 @@ class DS_1A2D_Off8_RET<string opName,
let hasPostISelHook = 1;
}
-class DS_1A_RET<string opName, RegisterClass rc = VGPR_32>
+class DS_1A_RET<string opName, RegisterClass rc = VGPR_32, Operand ofs = offset>
: DS_Pseudo<opName,
(outs rc:$vdst),
- (ins VGPR_32:$addr, offset:$offset, gds:$gds),
+ (ins VGPR_32:$addr, ofs:$offset, gds:$gds),
"$vdst, $addr$offset$gds"> {
let has_data0 = 0;
@@ -440,7 +440,7 @@ def DS_WRITE_SRC2_B32 : DS_1A<"ds_write_src2_b32">;
def DS_WRITE_SRC2_B64 : DS_1A<"ds_write_src2_b64">;
let Uses = [EXEC], mayLoad = 0, mayStore = 0, isConvergent = 1 in {
-def DS_SWIZZLE_B32 : DS_1A_RET <"ds_swizzle_b32">;
+def DS_SWIZZLE_B32 : DS_1A_RET <"ds_swizzle_b32", VGPR_32, SwizzleImm>;
}
let mayStore = 0 in {
diff --git a/contrib/llvm/lib/Target/AMDGPU/InstPrinter/AMDGPUInstPrinter.cpp b/contrib/llvm/lib/Target/AMDGPU/InstPrinter/AMDGPUInstPrinter.cpp
index a817ff3cbaf0..523eea41897e 100644
--- a/contrib/llvm/lib/Target/AMDGPU/InstPrinter/AMDGPUInstPrinter.cpp
+++ b/contrib/llvm/lib/Target/AMDGPU/InstPrinter/AMDGPUInstPrinter.cpp
@@ -1160,6 +1160,112 @@ void AMDGPUInstPrinter::printSendMsg(const MCInst *MI, unsigned OpNo,
O << SImm16; // Unknown simm16 code.
}
+static void printSwizzleBitmask(const uint16_t AndMask,
+ const uint16_t OrMask,
+ const uint16_t XorMask,
+ raw_ostream &O) {
+ using namespace llvm::AMDGPU::Swizzle;
+
+ uint16_t Probe0 = ((0 & AndMask) | OrMask) ^ XorMask;
+ uint16_t Probe1 = ((BITMASK_MASK & AndMask) | OrMask) ^ XorMask;
+
+ O << "\"";
+
+ for (unsigned Mask = 1 << (BITMASK_WIDTH - 1); Mask > 0; Mask >>= 1) {
+ uint16_t p0 = Probe0 & Mask;
+ uint16_t p1 = Probe1 & Mask;
+
+ if (p0 == p1) {
+ if (p0 == 0) {
+ O << "0";
+ } else {
+ O << "1";
+ }
+ } else {
+ if (p0 == 0) {
+ O << "p";
+ } else {
+ O << "i";
+ }
+ }
+ }
+
+ O << "\"";
+}
+
+void AMDGPUInstPrinter::printSwizzle(const MCInst *MI, unsigned OpNo,
+ const MCSubtargetInfo &STI,
+ raw_ostream &O) {
+ using namespace llvm::AMDGPU::Swizzle;
+
+ uint16_t Imm = MI->getOperand(OpNo).getImm();
+ if (Imm == 0) {
+ return;
+ }
+
+ O << " offset:";
+
+ if ((Imm & QUAD_PERM_ENC_MASK) == QUAD_PERM_ENC) {
+
+ O << "swizzle(" << IdSymbolic[ID_QUAD_PERM];
+ for (auto i = 0; i < LANE_NUM; ++i) {
+ O << ",";
+ O << formatDec(Imm & LANE_MASK);
+ Imm >>= LANE_SHIFT;
+ }
+ O << ")";
+
+ } else if ((Imm & BITMASK_PERM_ENC_MASK) == BITMASK_PERM_ENC) {
+
+ uint16_t AndMask = (Imm >> BITMASK_AND_SHIFT) & BITMASK_MASK;
+ uint16_t OrMask = (Imm >> BITMASK_OR_SHIFT) & BITMASK_MASK;
+ uint16_t XorMask = (Imm >> BITMASK_XOR_SHIFT) & BITMASK_MASK;
+
+ if (AndMask == BITMASK_MAX &&
+ OrMask == 0 &&
+ countPopulation(XorMask) == 1) {
+
+ O << "swizzle(" << IdSymbolic[ID_SWAP];
+ O << ",";
+ O << formatDec(XorMask);
+ O << ")";
+
+ } else if (AndMask == BITMASK_MAX &&
+ OrMask == 0 && XorMask > 0 &&
+ isPowerOf2_64(XorMask + 1)) {
+
+ O << "swizzle(" << IdSymbolic[ID_REVERSE];
+ O << ",";
+ O << formatDec(XorMask + 1);
+ O << ")";
+
+ } else {
+
+ uint16_t GroupSize = BITMASK_MAX - AndMask + 1;
+ if (GroupSize > 1 &&
+ isPowerOf2_64(GroupSize) &&
+ OrMask < GroupSize &&
+ XorMask == 0) {
+
+ O << "swizzle(" << IdSymbolic[ID_BROADCAST];
+ O << ",";
+ O << formatDec(GroupSize);
+ O << ",";
+ O << formatDec(OrMask);
+ O << ")";
+
+ } else {
+ O << "swizzle(" << IdSymbolic[ID_BITMASK_PERM];
+ O << ",";
+ printSwizzleBitmask(AndMask, OrMask, XorMask, O);
+ O << ")";
+ }
+ }
+ } else {
+ printU16ImmDecOperand(MI, OpNo, O);
+ }
+}
+
void AMDGPUInstPrinter::printWaitFlag(const MCInst *MI, unsigned OpNo,
const MCSubtargetInfo &STI,
raw_ostream &O) {
diff --git a/contrib/llvm/lib/Target/AMDGPU/InstPrinter/AMDGPUInstPrinter.h b/contrib/llvm/lib/Target/AMDGPU/InstPrinter/AMDGPUInstPrinter.h
index c0b8e5c51089..c8094c4b840a 100644
--- a/contrib/llvm/lib/Target/AMDGPU/InstPrinter/AMDGPUInstPrinter.h
+++ b/contrib/llvm/lib/Target/AMDGPU/InstPrinter/AMDGPUInstPrinter.h
@@ -193,6 +193,8 @@ private:
raw_ostream &O);
void printSendMsg(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI,
raw_ostream &O);
+ void printSwizzle(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI,
+ raw_ostream &O);
void printWaitFlag(const MCInst *MI, unsigned OpNo,
const MCSubtargetInfo &STI, raw_ostream &O);
void printHwreg(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI,
diff --git a/contrib/llvm/lib/Target/AMDGPU/SIDefines.h b/contrib/llvm/lib/Target/AMDGPU/SIDefines.h
index 80967edee0ab..5cd90323ff67 100644
--- a/contrib/llvm/lib/Target/AMDGPU/SIDefines.h
+++ b/contrib/llvm/lib/Target/AMDGPU/SIDefines.h
@@ -281,6 +281,46 @@ enum WidthMinusOne { // WidthMinusOne, (5) [15:11]
} // namespace Hwreg
+namespace Swizzle { // Encoding of swizzle macro used in ds_swizzle_b32.
+
+enum Id { // id of symbolic names
+ ID_QUAD_PERM = 0,
+ ID_BITMASK_PERM,
+ ID_SWAP,
+ ID_REVERSE,
+ ID_BROADCAST
+};
+
+enum EncBits {
+
+ // swizzle mode encodings
+
+ QUAD_PERM_ENC = 0x8000,
+ QUAD_PERM_ENC_MASK = 0xFF00,
+
+ BITMASK_PERM_ENC = 0x0000,
+ BITMASK_PERM_ENC_MASK = 0x8000,
+
+ // QUAD_PERM encodings
+
+ LANE_MASK = 0x3,
+ LANE_MAX = LANE_MASK,
+ LANE_SHIFT = 2,
+ LANE_NUM = 4,
+
+ // BITMASK_PERM encodings
+
+ BITMASK_MASK = 0x1F,
+ BITMASK_MAX = BITMASK_MASK,
+ BITMASK_WIDTH = 5,
+
+ BITMASK_AND_SHIFT = 0,
+ BITMASK_OR_SHIFT = 5,
+ BITMASK_XOR_SHIFT = 10
+};
+
+} // namespace Swizzle
+
namespace SDWA {
enum SdwaSel {
diff --git a/contrib/llvm/lib/Target/AMDGPU/SIInsertWaitcnts.cpp b/contrib/llvm/lib/Target/AMDGPU/SIInsertWaitcnts.cpp
index b5e3ce3dfe3e..e22166d03e9a 100644
--- a/contrib/llvm/lib/Target/AMDGPU/SIInsertWaitcnts.cpp
+++ b/contrib/llvm/lib/Target/AMDGPU/SIInsertWaitcnts.cpp
@@ -826,7 +826,8 @@ MachineInstr *SIInsertWaitcnts::generateSWaitCntInstBefore(
// NOTE: this could be improved with knowledge of all call sites or
// with knowledge of the called routines.
if (MI.getOpcode() == AMDGPU::RETURN ||
- MI.getOpcode() == AMDGPU::SI_RETURN_TO_EPILOG) {
+ MI.getOpcode() == AMDGPU::SI_RETURN_TO_EPILOG ||
+ MI.getOpcode() == AMDGPU::S_SETPC_B64_return) {
for (enum InstCounterType T = VM_CNT; T < NUM_INST_CNTS;
T = (enum InstCounterType)(T + 1)) {
if (ScoreBrackets->getScoreUB(T) > ScoreBrackets->getScoreLB(T)) {
@@ -1149,8 +1150,10 @@ void SIInsertWaitcnts::updateEventWaitCntAfter(
// instruction, update the upper-bound of the appropriate counter's
// bracket and the destination operand scores.
// TODO: Use the (TSFlags & SIInstrFlags::LGKM_CNT) property everywhere.
- if (TII->isDS(Inst) && (Inst.mayLoad() || Inst.mayStore())) {
- if (TII->getNamedOperand(Inst, AMDGPU::OpName::gds)->getImm() != 0) {
+ uint64_t TSFlags = Inst.getDesc().TSFlags;
+ if (TII->isDS(Inst) && (TSFlags & SIInstrFlags::LGKM_CNT)) {
+ if (TII->getNamedOperand(Inst, AMDGPU::OpName::gds) &&
+ TII->getNamedOperand(Inst, AMDGPU::OpName::gds)->getImm() != 0) {
ScoreBrackets->updateByEvent(TII, TRI, MRI, GDS_ACCESS, Inst);
ScoreBrackets->updateByEvent(TII, TRI, MRI, GDS_GPR_LOCK, Inst);
} else {
@@ -1183,7 +1186,7 @@ void SIInsertWaitcnts::updateEventWaitCntAfter(
Inst.getOpcode() != AMDGPU::BUFFER_WBINVL1_VOL) {
ScoreBrackets->updateByEvent(TII, TRI, MRI, VMEM_ACCESS, Inst);
if ( // TODO: assumed yes -- target_info->MemWriteNeedsExpWait() &&
- (Inst.mayStore() || AMDGPU::getAtomicNoRetOp(Inst.getOpcode()))) {
+ (Inst.mayStore() || AMDGPU::getAtomicNoRetOp(Inst.getOpcode()) != -1)) {
ScoreBrackets->updateByEvent(TII, TRI, MRI, VMW_GPR_LOCK, Inst);
}
} else if (TII->isSMRD(Inst)) {
@@ -1715,6 +1718,7 @@ bool SIInsertWaitcnts::runOnMachineFunction(MachineFunction &MF) {
MRI = &MF.getRegInfo();
MLI = &getAnalysis<MachineLoopInfo>();
IV = AMDGPU::IsaInfo::getIsaVersion(ST->getFeatureBits());
+ const SIMachineFunctionInfo *MFI = MF.getInfo<SIMachineFunctionInfo>();
AMDGPUASI = ST->getAMDGPUAS();
HardwareLimits.VmcntMax = AMDGPU::getVmcntBitMask(IV);
@@ -1859,5 +1863,19 @@ bool SIInsertWaitcnts::runOnMachineFunction(MachineFunction &MF) {
}
}
+ if (!MFI->isEntryFunction()) {
+ // Wait for any outstanding memory operations that the input registers may
+ // depend on. We can't track them and it's better to to the wait after the
+ // costly call sequence.
+
+ // TODO: Could insert earlier and schedule more liberally with operations
+ // that only use caller preserved registers.
+ MachineBasicBlock &EntryBB = MF.front();
+ BuildMI(EntryBB, EntryBB.getFirstNonPHI(), DebugLoc(), TII->get(AMDGPU::S_WAITCNT))
+ .addImm(0);
+
+ Modified = true;
+ }
+
return Modified;
}
diff --git a/contrib/llvm/lib/Target/AMDGPU/SIInstrInfo.td b/contrib/llvm/lib/Target/AMDGPU/SIInstrInfo.td
index c5287c7f64ba..445bf79a7814 100644
--- a/contrib/llvm/lib/Target/AMDGPU/SIInstrInfo.td
+++ b/contrib/llvm/lib/Target/AMDGPU/SIInstrInfo.td
@@ -383,6 +383,14 @@ def SendMsgMatchClass : AsmOperandClass {
let RenderMethod = "addImmOperands";
}
+def SwizzleMatchClass : AsmOperandClass {
+ let Name = "Swizzle";
+ let PredicateMethod = "isSwizzle";
+ let ParserMethod = "parseSwizzleOp";
+ let RenderMethod = "addImmOperands";
+ let IsOptional = 1;
+}
+
def ExpTgtMatchClass : AsmOperandClass {
let Name = "ExpTgt";
let PredicateMethod = "isExpTgt";
@@ -395,6 +403,11 @@ def SendMsgImm : Operand<i32> {
let ParserMatchClass = SendMsgMatchClass;
}
+def SwizzleImm : Operand<i16> {
+ let PrintMethod = "printSwizzle";
+ let ParserMatchClass = SwizzleMatchClass;
+}
+
def SWaitMatchClass : AsmOperandClass {
let Name = "SWaitCnt";
let RenderMethod = "addImmOperands";
diff --git a/contrib/llvm/lib/Target/AMDGPU/SIRegisterInfo.h b/contrib/llvm/lib/Target/AMDGPU/SIRegisterInfo.h
index b91cdddc5520..a648c178101a 100644
--- a/contrib/llvm/lib/Target/AMDGPU/SIRegisterInfo.h
+++ b/contrib/llvm/lib/Target/AMDGPU/SIRegisterInfo.h
@@ -66,6 +66,12 @@ public:
const uint32_t *getCallPreservedMask(const MachineFunction &MF,
CallingConv::ID) const override;
+ // Stack access is very expensive. CSRs are also the high registers, and we
+ // want to minimize the number of used registers.
+ unsigned getCSRFirstUseCost() const override {
+ return 100;
+ }
+
unsigned getFrameRegister(const MachineFunction &MF) const override;
bool requiresRegisterScavenging(const MachineFunction &Fn) const override;
diff --git a/contrib/llvm/lib/Target/AMDGPU/Utils/AMDGPUAsmUtils.cpp b/contrib/llvm/lib/Target/AMDGPU/Utils/AMDGPUAsmUtils.cpp
index b6868de6a74e..03b11ae80500 100644
--- a/contrib/llvm/lib/Target/AMDGPU/Utils/AMDGPUAsmUtils.cpp
+++ b/contrib/llvm/lib/Target/AMDGPU/Utils/AMDGPUAsmUtils.cpp
@@ -65,5 +65,18 @@ const char* const IdSymbolic[] = {
};
} // namespace Hwreg
+
+namespace Swizzle {
+
+// This must be in sync with llvm::AMDGPU::Swizzle::Id enum members, see SIDefines.h.
+const char* const IdSymbolic[] = {
+ "QUAD_PERM",
+ "BITMASK_PERM",
+ "SWAP",
+ "REVERSE",
+ "BROADCAST",
+};
+
+} // namespace Swizzle
} // namespace AMDGPU
} // namespace llvm
diff --git a/contrib/llvm/lib/Target/AMDGPU/Utils/AMDGPUAsmUtils.h b/contrib/llvm/lib/Target/AMDGPU/Utils/AMDGPUAsmUtils.h
index b2dc2c0e364c..ebb2be22b487 100644
--- a/contrib/llvm/lib/Target/AMDGPU/Utils/AMDGPUAsmUtils.h
+++ b/contrib/llvm/lib/Target/AMDGPU/Utils/AMDGPUAsmUtils.h
@@ -25,6 +25,12 @@ namespace Hwreg { // Symbolic names for the hwreg(...) syntax.
extern const char* const IdSymbolic[];
} // namespace Hwreg
+
+namespace Swizzle { // Symbolic names for the swizzle(...) syntax.
+
+extern const char* const IdSymbolic[];
+
+} // namespace Swizzle
} // namespace AMDGPU
} // namespace llvm
diff --git a/contrib/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp b/contrib/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp
index 90baabcdb652..ec49f0d37af4 100644
--- a/contrib/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp
+++ b/contrib/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp
@@ -757,14 +757,9 @@ void ARMExpandPseudo::ExpandMOV32BitImm(MachineBasicBlock &MBB,
MI.eraseFromParent();
}
-static void addPostLoopLiveIns(MachineBasicBlock *MBB, LivePhysRegs &LiveRegs) {
- for (auto I = LiveRegs.begin(); I != LiveRegs.end(); ++I)
- MBB->addLiveIn(*I);
-}
-
/// Expand a CMP_SWAP pseudo-inst to an ldrex/strex loop as simply as
-/// possible. This only gets used at -O0 so we don't care about efficiency of the
-/// generated code.
+/// possible. This only gets used at -O0 so we don't care about efficiency of
+/// the generated code.
bool ARMExpandPseudo::ExpandCMP_SWAP(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MBBI,
unsigned LdrexOp, unsigned StrexOp,
@@ -773,16 +768,15 @@ bool ARMExpandPseudo::ExpandCMP_SWAP(MachineBasicBlock &MBB,
bool IsThumb = STI->isThumb();
MachineInstr &MI = *MBBI;
DebugLoc DL = MI.getDebugLoc();
- MachineOperand &Dest = MI.getOperand(0);
+ const MachineOperand &Dest = MI.getOperand(0);
unsigned StatusReg = MI.getOperand(1).getReg();
- MachineOperand &Addr = MI.getOperand(2);
- MachineOperand &Desired = MI.getOperand(3);
- MachineOperand &New = MI.getOperand(4);
-
- LivePhysRegs LiveRegs(TII->getRegisterInfo());
- LiveRegs.addLiveOuts(MBB);
- for (auto I = std::prev(MBB.end()); I != MBBI; --I)
- LiveRegs.stepBackward(*I);
+ bool StatusDead = MI.getOperand(1).isDead();
+ // Duplicating undef operands into 2 instructions does not guarantee the same
+ // value on both; However undef should be replaced by xzr anyway.
+ assert(!MI.getOperand(2).isUndef() && "cannot handle undef");
+ unsigned AddrReg = MI.getOperand(2).getReg();
+ unsigned DesiredReg = MI.getOperand(3).getReg();
+ unsigned NewReg = MI.getOperand(4).getReg();
MachineFunction *MF = MBB.getParent();
auto LoadCmpBB = MF->CreateMachineBasicBlock(MBB.getBasicBlock());
@@ -795,25 +789,35 @@ bool ARMExpandPseudo::ExpandCMP_SWAP(MachineBasicBlock &MBB,
if (UxtOp) {
MachineInstrBuilder MIB =
- BuildMI(MBB, MBBI, DL, TII->get(UxtOp), Desired.getReg())
- .addReg(Desired.getReg(), RegState::Kill);
+ BuildMI(MBB, MBBI, DL, TII->get(UxtOp), DesiredReg)
+ .addReg(DesiredReg, RegState::Kill);
if (!IsThumb)
MIB.addImm(0);
MIB.add(predOps(ARMCC::AL));
}
// .Lloadcmp:
+ // mov wStatus, #0
// ldrex rDest, [rAddr]
// cmp rDest, rDesired
// bne .Ldone
- LoadCmpBB->addLiveIn(Addr.getReg());
- LoadCmpBB->addLiveIn(Dest.getReg());
- LoadCmpBB->addLiveIn(Desired.getReg());
- addPostLoopLiveIns(LoadCmpBB, LiveRegs);
+ if (!StatusDead) {
+ if (IsThumb) {
+ BuildMI(LoadCmpBB, DL, TII->get(ARM::tMOVi8), StatusReg)
+ .addDef(ARM::CPSR, RegState::Dead)
+ .addImm(0)
+ .add(predOps(ARMCC::AL));
+ } else {
+ BuildMI(LoadCmpBB, DL, TII->get(ARM::MOVi), StatusReg)
+ .addImm(0)
+ .add(predOps(ARMCC::AL))
+ .add(condCodeOp());
+ }
+ }
MachineInstrBuilder MIB;
MIB = BuildMI(LoadCmpBB, DL, TII->get(LdrexOp), Dest.getReg());
- MIB.addReg(Addr.getReg());
+ MIB.addReg(AddrReg);
if (LdrexOp == ARM::t2LDREX)
MIB.addImm(0); // a 32-bit Thumb ldrex (only) allows an offset.
MIB.add(predOps(ARMCC::AL));
@@ -821,7 +825,7 @@ bool ARMExpandPseudo::ExpandCMP_SWAP(MachineBasicBlock &MBB,
unsigned CMPrr = IsThumb ? ARM::tCMPhir : ARM::CMPrr;
BuildMI(LoadCmpBB, DL, TII->get(CMPrr))
.addReg(Dest.getReg(), getKillRegState(Dest.isDead()))
- .add(Desired)
+ .addReg(DesiredReg)
.add(predOps(ARMCC::AL));
unsigned Bcc = IsThumb ? ARM::tBcc : ARM::Bcc;
BuildMI(LoadCmpBB, DL, TII->get(Bcc))
@@ -835,21 +839,16 @@ bool ARMExpandPseudo::ExpandCMP_SWAP(MachineBasicBlock &MBB,
// strex rStatus, rNew, [rAddr]
// cmp rStatus, #0
// bne .Lloadcmp
- StoreBB->addLiveIn(Addr.getReg());
- StoreBB->addLiveIn(New.getReg());
- addPostLoopLiveIns(StoreBB, LiveRegs);
-
-
- MIB = BuildMI(StoreBB, DL, TII->get(StrexOp), StatusReg);
- MIB.add(New);
- MIB.add(Addr);
+ MIB = BuildMI(StoreBB, DL, TII->get(StrexOp), StatusReg)
+ .addReg(NewReg)
+ .addReg(AddrReg);
if (StrexOp == ARM::t2STREX)
MIB.addImm(0); // a 32-bit Thumb strex (only) allows an offset.
MIB.add(predOps(ARMCC::AL));
unsigned CMPri = IsThumb ? ARM::t2CMPri : ARM::CMPri;
BuildMI(StoreBB, DL, TII->get(CMPri))
- .addReg(StatusReg, RegState::Kill)
+ .addReg(StatusReg, getKillRegState(StatusDead))
.addImm(0)
.add(predOps(ARMCC::AL));
BuildMI(StoreBB, DL, TII->get(Bcc))
@@ -861,12 +860,24 @@ bool ARMExpandPseudo::ExpandCMP_SWAP(MachineBasicBlock &MBB,
DoneBB->splice(DoneBB->end(), &MBB, MI, MBB.end());
DoneBB->transferSuccessors(&MBB);
- addPostLoopLiveIns(DoneBB, LiveRegs);
MBB.addSuccessor(LoadCmpBB);
NextMBBI = MBB.end();
MI.eraseFromParent();
+
+ // Recompute livein lists.
+ const MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();
+ LivePhysRegs LiveRegs;
+ computeLiveIns(LiveRegs, MRI, *DoneBB);
+ computeLiveIns(LiveRegs, MRI, *StoreBB);
+ computeLiveIns(LiveRegs, MRI, *LoadCmpBB);
+ // Do an extra pass around the loop to get loop carried registers right.
+ StoreBB->clearLiveIns();
+ computeLiveIns(LiveRegs, MRI, *StoreBB);
+ LoadCmpBB->clearLiveIns();
+ computeLiveIns(LiveRegs, MRI, *LoadCmpBB);
+
return true;
}
@@ -894,19 +905,19 @@ bool ARMExpandPseudo::ExpandCMP_SWAP_64(MachineBasicBlock &MBB,
DebugLoc DL = MI.getDebugLoc();
MachineOperand &Dest = MI.getOperand(0);
unsigned StatusReg = MI.getOperand(1).getReg();
- MachineOperand &Addr = MI.getOperand(2);
- MachineOperand &Desired = MI.getOperand(3);
- MachineOperand &New = MI.getOperand(4);
+ bool StatusDead = MI.getOperand(1).isDead();
+ // Duplicating undef operands into 2 instructions does not guarantee the same
+ // value on both; However undef should be replaced by xzr anyway.
+ assert(!MI.getOperand(2).isUndef() && "cannot handle undef");
+ unsigned AddrReg = MI.getOperand(2).getReg();
+ unsigned DesiredReg = MI.getOperand(3).getReg();
+ MachineOperand New = MI.getOperand(4);
+ New.setIsKill(false);
unsigned DestLo = TRI->getSubReg(Dest.getReg(), ARM::gsub_0);
unsigned DestHi = TRI->getSubReg(Dest.getReg(), ARM::gsub_1);
- unsigned DesiredLo = TRI->getSubReg(Desired.getReg(), ARM::gsub_0);
- unsigned DesiredHi = TRI->getSubReg(Desired.getReg(), ARM::gsub_1);
-
- LivePhysRegs LiveRegs(TII->getRegisterInfo());
- LiveRegs.addLiveOuts(MBB);
- for (auto I = std::prev(MBB.end()); I != MBBI; --I)
- LiveRegs.stepBackward(*I);
+ unsigned DesiredLo = TRI->getSubReg(DesiredReg, ARM::gsub_0);
+ unsigned DesiredHi = TRI->getSubReg(DesiredReg, ARM::gsub_1);
MachineFunction *MF = MBB.getParent();
auto LoadCmpBB = MF->CreateMachineBasicBlock(MBB.getBasicBlock());
@@ -922,26 +933,21 @@ bool ARMExpandPseudo::ExpandCMP_SWAP_64(MachineBasicBlock &MBB,
// cmp rDestLo, rDesiredLo
// sbcs rStatus<dead>, rDestHi, rDesiredHi
// bne .Ldone
- LoadCmpBB->addLiveIn(Addr.getReg());
- LoadCmpBB->addLiveIn(Dest.getReg());
- LoadCmpBB->addLiveIn(Desired.getReg());
- addPostLoopLiveIns(LoadCmpBB, LiveRegs);
-
unsigned LDREXD = IsThumb ? ARM::t2LDREXD : ARM::LDREXD;
MachineInstrBuilder MIB;
MIB = BuildMI(LoadCmpBB, DL, TII->get(LDREXD));
addExclusiveRegPair(MIB, Dest, RegState::Define, IsThumb, TRI);
- MIB.addReg(Addr.getReg()).add(predOps(ARMCC::AL));
+ MIB.addReg(AddrReg).add(predOps(ARMCC::AL));
unsigned CMPrr = IsThumb ? ARM::tCMPhir : ARM::CMPrr;
BuildMI(LoadCmpBB, DL, TII->get(CMPrr))
.addReg(DestLo, getKillRegState(Dest.isDead()))
- .addReg(DesiredLo, getKillRegState(Desired.isDead()))
+ .addReg(DesiredLo)
.add(predOps(ARMCC::AL));
BuildMI(LoadCmpBB, DL, TII->get(CMPrr))
.addReg(DestHi, getKillRegState(Dest.isDead()))
- .addReg(DesiredHi, getKillRegState(Desired.isDead()))
+ .addReg(DesiredHi)
.addImm(ARMCC::EQ).addReg(ARM::CPSR, RegState::Kill);
unsigned Bcc = IsThumb ? ARM::tBcc : ARM::Bcc;
@@ -956,18 +962,14 @@ bool ARMExpandPseudo::ExpandCMP_SWAP_64(MachineBasicBlock &MBB,
// strexd rStatus, rNewLo, rNewHi, [rAddr]
// cmp rStatus, #0
// bne .Lloadcmp
- StoreBB->addLiveIn(Addr.getReg());
- StoreBB->addLiveIn(New.getReg());
- addPostLoopLiveIns(StoreBB, LiveRegs);
-
unsigned STREXD = IsThumb ? ARM::t2STREXD : ARM::STREXD;
MIB = BuildMI(StoreBB, DL, TII->get(STREXD), StatusReg);
addExclusiveRegPair(MIB, New, 0, IsThumb, TRI);
- MIB.add(Addr).add(predOps(ARMCC::AL));
+ MIB.addReg(AddrReg).add(predOps(ARMCC::AL));
unsigned CMPri = IsThumb ? ARM::t2CMPri : ARM::CMPri;
BuildMI(StoreBB, DL, TII->get(CMPri))
- .addReg(StatusReg, RegState::Kill)
+ .addReg(StatusReg, getKillRegState(StatusDead))
.addImm(0)
.add(predOps(ARMCC::AL));
BuildMI(StoreBB, DL, TII->get(Bcc))
@@ -979,12 +981,24 @@ bool ARMExpandPseudo::ExpandCMP_SWAP_64(MachineBasicBlock &MBB,
DoneBB->splice(DoneBB->end(), &MBB, MI, MBB.end());
DoneBB->transferSuccessors(&MBB);
- addPostLoopLiveIns(DoneBB, LiveRegs);
MBB.addSuccessor(LoadCmpBB);
NextMBBI = MBB.end();
MI.eraseFromParent();
+
+ // Recompute livein lists.
+ const MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();
+ LivePhysRegs LiveRegs;
+ computeLiveIns(LiveRegs, MRI, *DoneBB);
+ computeLiveIns(LiveRegs, MRI, *StoreBB);
+ computeLiveIns(LiveRegs, MRI, *LoadCmpBB);
+ // Do an extra pass around the loop to get loop carried registers right.
+ StoreBB->clearLiveIns();
+ computeLiveIns(LiveRegs, MRI, *StoreBB);
+ LoadCmpBB->clearLiveIns();
+ computeLiveIns(LiveRegs, MRI, *LoadCmpBB);
+
return true;
}
diff --git a/contrib/llvm/lib/Target/ARM/ARMFrameLowering.cpp b/contrib/llvm/lib/Target/ARM/ARMFrameLowering.cpp
index 4f7a0ab4e220..c2b2502843c0 100644
--- a/contrib/llvm/lib/Target/ARM/ARMFrameLowering.cpp
+++ b/contrib/llvm/lib/Target/ARM/ARMFrameLowering.cpp
@@ -968,8 +968,9 @@ void ARMFrameLowering::emitPushInst(MachineBasicBlock &MBB,
if (Reg >= ARM::D8 && Reg < ARM::D8 + NumAlignedDPRCS2Regs)
continue;
- bool isLiveIn = MF.getRegInfo().isLiveIn(Reg);
- if (!isLiveIn)
+ const MachineRegisterInfo &MRI = MF.getRegInfo();
+ bool isLiveIn = MRI.isLiveIn(Reg);
+ if (!isLiveIn && !MRI.isReserved(Reg))
MBB.addLiveIn(Reg);
// If NoGap is true, push consecutive registers and then leave the rest
// for other instructions. e.g.
diff --git a/contrib/llvm/lib/Target/ARM/ARMInstrThumb.td b/contrib/llvm/lib/Target/ARM/ARMInstrThumb.td
index bee83dfb6f63..423f97ccacd6 100644
--- a/contrib/llvm/lib/Target/ARM/ARMInstrThumb.td
+++ b/contrib/llvm/lib/Target/ARM/ARMInstrThumb.td
@@ -1413,7 +1413,8 @@ def tLEApcrelJT : tPseudoInst<(outs tGPR:$Rd),
// Thumb-1 doesn't have the TBB or TBH instructions, but we can synthesize them
// and make use of the same compressed jump table format as Thumb-2.
-let Size = 2 in {
+let Size = 2, isBranch = 1, isTerminator = 1, isBarrier = 1,
+ isIndirectBranch = 1 in {
def tTBB_JT : tPseudoInst<(outs),
(ins tGPR:$base, tGPR:$index, i32imm:$jt, i32imm:$pclbl), 0, IIC_Br, []>,
Sched<[WriteBr]>;
diff --git a/contrib/llvm/lib/Target/ARM/ARMInstrThumb2.td b/contrib/llvm/lib/Target/ARM/ARMInstrThumb2.td
index bf3d820e7b7d..45471a4e95b3 100644
--- a/contrib/llvm/lib/Target/ARM/ARMInstrThumb2.td
+++ b/contrib/llvm/lib/Target/ARM/ARMInstrThumb2.td
@@ -3494,7 +3494,8 @@ def t2B : T2I<(outs), (ins thumb_br_target:$target), IIC_Br,
let AsmMatchConverter = "cvtThumbBranches";
}
-let Size = 4, isNotDuplicable = 1, isIndirectBranch = 1 in {
+let Size = 4, isNotDuplicable = 1, isBranch = 1, isTerminator = 1,
+ isBarrier = 1, isIndirectBranch = 1 in {
// available in both v8-M.Baseline and Thumb2 targets
def t2BR_JT : t2basePseudoInst<(outs),
diff --git a/contrib/llvm/lib/Target/ARM/ARMTargetMachine.cpp b/contrib/llvm/lib/Target/ARM/ARMTargetMachine.cpp
index c4f23c66e4ea..f5e4043882ff 100644
--- a/contrib/llvm/lib/Target/ARM/ARMTargetMachine.cpp
+++ b/contrib/llvm/lib/Target/ARM/ARMTargetMachine.cpp
@@ -382,7 +382,7 @@ namespace {
/// ARM Code Generator Pass Configuration Options.
class ARMPassConfig : public TargetPassConfig {
public:
- ARMPassConfig(ARMBaseTargetMachine *TM, PassManagerBase &PM)
+ ARMPassConfig(ARMBaseTargetMachine &TM, PassManagerBase &PM)
: TargetPassConfig(TM, PM) {}
ARMBaseTargetMachine &getARMTargetMachine() const {
@@ -419,7 +419,7 @@ INITIALIZE_PASS(ARMExecutionDepsFix, "arm-execution-deps-fix",
"ARM Execution Dependency Fix", false, false)
TargetPassConfig *ARMBaseTargetMachine::createPassConfig(PassManagerBase &PM) {
- return new ARMPassConfig(this, PM);
+ return new ARMPassConfig(*this, PM);
}
void ARMPassConfig::addIRPasses() {
diff --git a/contrib/llvm/lib/Target/ARM/ARMTargetMachine.h b/contrib/llvm/lib/Target/ARM/ARMTargetMachine.h
index e5eb27114c72..2fcee73228fe 100644
--- a/contrib/llvm/lib/Target/ARM/ARMTargetMachine.h
+++ b/contrib/llvm/lib/Target/ARM/ARMTargetMachine.h
@@ -60,6 +60,10 @@ public:
TargetLoweringObjectFile *getObjFileLowering() const override {
return TLOF.get();
}
+
+ bool isMachineVerifierClean() const override {
+ return false;
+ }
};
/// ARM/Thumb little endian target machine.
diff --git a/contrib/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp b/contrib/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
index 40bf545e8322..b0d1d3fb9ef0 100644
--- a/contrib/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
+++ b/contrib/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
@@ -729,6 +729,15 @@ void ARMAsmBackend::processFixupValue(const MCAssembler &Asm,
// linker can handle it. GNU AS produces an error in this case.
if (Sym->isExternal() || Value >= 0x400004)
IsResolved = false;
+ // When an ARM function is called from a Thumb function, produce a
+ // relocation so the linker will use the correct branch instruction for ELF
+ // binaries.
+ if (Sym->isELF()) {
+ unsigned Type = dyn_cast<MCSymbolELF>(Sym)->getType();
+ if ((Type == ELF::STT_FUNC || Type == ELF::STT_GNU_IFUNC) &&
+ !Asm.isThumbFunc(Sym))
+ IsResolved = false;
+ }
}
// We must always generate a relocation for BL/BLX instructions if we have
// a symbol to reference, as the linker relies on knowing the destination
diff --git a/contrib/llvm/lib/Target/ARM/Thumb1FrameLowering.cpp b/contrib/llvm/lib/Target/ARM/Thumb1FrameLowering.cpp
index f917c35b9ceb..f10427e2ed57 100644
--- a/contrib/llvm/lib/Target/ARM/Thumb1FrameLowering.cpp
+++ b/contrib/llvm/lib/Target/ARM/Thumb1FrameLowering.cpp
@@ -698,13 +698,14 @@ spillCalleeSavedRegisters(MachineBasicBlock &MBB,
CopyRegs.insert(ArgReg);
// Push the low registers and lr
+ const MachineRegisterInfo &MRI = MF.getRegInfo();
if (!LoRegsToSave.empty()) {
MachineInstrBuilder MIB =
BuildMI(MBB, MI, DL, TII.get(ARM::tPUSH)).add(predOps(ARMCC::AL));
for (unsigned Reg : {ARM::R4, ARM::R5, ARM::R6, ARM::R7, ARM::LR}) {
if (LoRegsToSave.count(Reg)) {
- bool isKill = !MF.getRegInfo().isLiveIn(Reg);
- if (isKill)
+ bool isKill = !MRI.isLiveIn(Reg);
+ if (isKill && !MRI.isReserved(Reg))
MBB.addLiveIn(Reg);
MIB.addReg(Reg, getKillRegState(isKill));
@@ -746,8 +747,8 @@ spillCalleeSavedRegisters(MachineBasicBlock &MBB,
SmallVector<unsigned, 4> RegsToPush;
while (HiRegToSave != AllHighRegsEnd && CopyReg != AllCopyRegsEnd) {
if (HiRegsToSave.count(*HiRegToSave)) {
- bool isKill = !MF.getRegInfo().isLiveIn(*HiRegToSave);
- if (isKill)
+ bool isKill = !MRI.isLiveIn(*HiRegToSave);
+ if (isKill && !MRI.isReserved(*HiRegToSave))
MBB.addLiveIn(*HiRegToSave);
// Emit a MOV from the high reg to the low reg.
diff --git a/contrib/llvm/lib/Target/AVR/AVRISelLowering.cpp b/contrib/llvm/lib/Target/AVR/AVRISelLowering.cpp
index ef9c00e4b784..7d3faac1dcc2 100644
--- a/contrib/llvm/lib/Target/AVR/AVRISelLowering.cpp
+++ b/contrib/llvm/lib/Target/AVR/AVRISelLowering.cpp
@@ -1500,9 +1500,9 @@ MachineBasicBlock *AVRTargetLowering::insertShift(MachineInstr &MI,
unsigned DstReg = MI.getOperand(0).getReg();
// BB:
- // cp 0, N
+ // cpi N, 0
// breq RemBB
- BuildMI(BB, dl, TII.get(AVR::CPRdRr)).addReg(ShiftAmtSrcReg).addReg(AVR::R0);
+ BuildMI(BB, dl, TII.get(AVR::CPIRdK)).addReg(ShiftAmtSrcReg).addImm(0);
BuildMI(BB, dl, TII.get(AVR::BREQk)).addMBB(RemBB);
// LoopBB:
diff --git a/contrib/llvm/lib/Target/AVR/AVRInstrInfo.td b/contrib/llvm/lib/Target/AVR/AVRInstrInfo.td
index f10ca394f36c..5dd8b2c27b21 100644
--- a/contrib/llvm/lib/Target/AVR/AVRInstrInfo.td
+++ b/contrib/llvm/lib/Target/AVR/AVRInstrInfo.td
@@ -904,7 +904,7 @@ let Defs = [SREG] in
// Compares a register with an 8 bit immediate.
def CPIRdK : FRdK<0b0011,
(outs),
- (ins GPR8:$rd, imm_ldi8:$k),
+ (ins LD8:$rd, imm_ldi8:$k),
"cpi\t$rd, $k",
[(AVRcmp i8:$rd, imm:$k), (implicit SREG)]>;
}
diff --git a/contrib/llvm/lib/Target/AVR/AVRTargetMachine.cpp b/contrib/llvm/lib/Target/AVR/AVRTargetMachine.cpp
index fb3262916b4f..2ab0b1080c6a 100644
--- a/contrib/llvm/lib/Target/AVR/AVRTargetMachine.cpp
+++ b/contrib/llvm/lib/Target/AVR/AVRTargetMachine.cpp
@@ -57,7 +57,7 @@ namespace {
/// AVR Code Generator Pass Configuration Options.
class AVRPassConfig : public TargetPassConfig {
public:
- AVRPassConfig(AVRTargetMachine *TM, PassManagerBase &PM)
+ AVRPassConfig(AVRTargetMachine &TM, PassManagerBase &PM)
: TargetPassConfig(TM, PM) {}
AVRTargetMachine &getAVRTargetMachine() const {
@@ -71,7 +71,7 @@ public:
} // namespace
TargetPassConfig *AVRTargetMachine::createPassConfig(PassManagerBase &PM) {
- return new AVRPassConfig(this, PM);
+ return new AVRPassConfig(*this, PM);
}
extern "C" void LLVMInitializeAVRTarget() {
diff --git a/contrib/llvm/lib/Target/AVR/AVRTargetMachine.h b/contrib/llvm/lib/Target/AVR/AVRTargetMachine.h
index 10345193d14a..795e94e6af03 100644
--- a/contrib/llvm/lib/Target/AVR/AVRTargetMachine.h
+++ b/contrib/llvm/lib/Target/AVR/AVRTargetMachine.h
@@ -41,6 +41,10 @@ public:
TargetPassConfig *createPassConfig(PassManagerBase &PM) override;
+ bool isMachineVerifierClean() const override {
+ return false;
+ }
+
private:
std::unique_ptr<TargetLoweringObjectFile> TLOF;
AVRSubtarget SubTarget;
diff --git a/contrib/llvm/lib/Target/BPF/BPFTargetMachine.cpp b/contrib/llvm/lib/Target/BPF/BPFTargetMachine.cpp
index 897695633e46..cf8e73540904 100644
--- a/contrib/llvm/lib/Target/BPF/BPFTargetMachine.cpp
+++ b/contrib/llvm/lib/Target/BPF/BPFTargetMachine.cpp
@@ -58,7 +58,7 @@ namespace {
// BPF Code Generator Pass Configuration Options.
class BPFPassConfig : public TargetPassConfig {
public:
- BPFPassConfig(BPFTargetMachine *TM, PassManagerBase &PM)
+ BPFPassConfig(BPFTargetMachine &TM, PassManagerBase &PM)
: TargetPassConfig(TM, PM) {}
BPFTargetMachine &getBPFTargetMachine() const {
@@ -70,7 +70,7 @@ public:
}
TargetPassConfig *BPFTargetMachine::createPassConfig(PassManagerBase &PM) {
- return new BPFPassConfig(this, PM);
+ return new BPFPassConfig(*this, PM);
}
// Install an instruction selector pass using
diff --git a/contrib/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp b/contrib/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp
index 8e10c521a77d..e4434136bf86 100644
--- a/contrib/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp
+++ b/contrib/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp
@@ -71,6 +71,9 @@ public:
return true;
}
+ bool ComplexPatternFuncMutatesDAG() const override {
+ return true;
+ }
void PreprocessISelDAG() override;
void EmitFunctionEntryCode() override;
@@ -81,6 +84,7 @@ public:
inline bool SelectAddrGP(SDValue &N, SDValue &R);
bool SelectGlobalAddress(SDValue &N, SDValue &R, bool UseGP);
bool SelectAddrFI(SDValue &N, SDValue &R);
+ bool DetectUseSxtw(SDValue &N, SDValue &R);
StringRef getPassName() const override {
return "Hexagon DAG->DAG Pattern Instruction Selection";
@@ -106,7 +110,6 @@ public:
void SelectIndexedStore(StoreSDNode *ST, const SDLoc &dl);
void SelectStore(SDNode *N);
void SelectSHL(SDNode *N);
- void SelectMul(SDNode *N);
void SelectZeroExtend(SDNode *N);
void SelectIntrinsicWChain(SDNode *N);
void SelectIntrinsicWOChain(SDNode *N);
@@ -118,7 +121,7 @@ public:
#include "HexagonGenDAGISel.inc"
private:
- bool isValueExtension(const SDValue &Val, unsigned FromBits, SDValue &Src);
+ bool keepsLowBits(const SDValue &Val, unsigned NumBits, SDValue &Src);
bool isOrEquivalentToAdd(const SDNode *N) const;
bool isAlignedMemNode(const MemSDNode *N) const;
bool isPositiveHalfWord(const SDNode *N) const;
@@ -597,90 +600,6 @@ void HexagonDAGToDAGISel::SelectStore(SDNode *N) {
SelectCode(ST);
}
-void HexagonDAGToDAGISel::SelectMul(SDNode *N) {
- SDLoc dl(N);
-
- // %conv.i = sext i32 %tmp1 to i64
- // %conv2.i = sext i32 %add to i64
- // %mul.i = mul nsw i64 %conv2.i, %conv.i
- //
- // --- match with the following ---
- //
- // %mul.i = mpy (%tmp1, %add)
- //
-
- if (N->getValueType(0) == MVT::i64) {
- // Shifting a i64 signed multiply.
- SDValue MulOp0 = N->getOperand(0);
- SDValue MulOp1 = N->getOperand(1);
-
- SDValue OP0;
- SDValue OP1;
-
- // Handle sign_extend and sextload.
- if (MulOp0.getOpcode() == ISD::SIGN_EXTEND) {
- SDValue Sext0 = MulOp0.getOperand(0);
- if (Sext0.getNode()->getValueType(0) != MVT::i32) {
- SelectCode(N);
- return;
- }
- OP0 = Sext0;
- } else if (MulOp0.getOpcode() == ISD::LOAD) {
- LoadSDNode *LD = cast<LoadSDNode>(MulOp0.getNode());
- if (LD->getMemoryVT() != MVT::i32 ||
- LD->getExtensionType() != ISD::SEXTLOAD ||
- LD->getAddressingMode() != ISD::UNINDEXED) {
- SelectCode(N);
- return;
- }
- SDValue Chain = LD->getChain();
- SDValue TargetConst0 = CurDAG->getTargetConstant(0, dl, MVT::i32);
- OP0 = SDValue(CurDAG->getMachineNode(Hexagon::L2_loadri_io, dl, MVT::i32,
- MVT::Other,
- LD->getBasePtr(), TargetConst0,
- Chain), 0);
- } else {
- SelectCode(N);
- return;
- }
-
- // Same goes for the second operand.
- if (MulOp1.getOpcode() == ISD::SIGN_EXTEND) {
- SDValue Sext1 = MulOp1.getOperand(0);
- if (Sext1.getNode()->getValueType(0) != MVT::i32) {
- SelectCode(N);
- return;
- }
- OP1 = Sext1;
- } else if (MulOp1.getOpcode() == ISD::LOAD) {
- LoadSDNode *LD = cast<LoadSDNode>(MulOp1.getNode());
- if (LD->getMemoryVT() != MVT::i32 ||
- LD->getExtensionType() != ISD::SEXTLOAD ||
- LD->getAddressingMode() != ISD::UNINDEXED) {
- SelectCode(N);
- return;
- }
- SDValue Chain = LD->getChain();
- SDValue TargetConst0 = CurDAG->getTargetConstant(0, dl, MVT::i32);
- OP1 = SDValue(CurDAG->getMachineNode(Hexagon::L2_loadri_io, dl, MVT::i32,
- MVT::Other,
- LD->getBasePtr(), TargetConst0,
- Chain), 0);
- } else {
- SelectCode(N);
- return;
- }
-
- // Generate a mpy instruction.
- SDNode *Result = CurDAG->getMachineNode(Hexagon::M2_dpmpyss_s0, dl,
- MVT::i64, OP0, OP1);
- ReplaceNode(N, Result);
- return;
- }
-
- SelectCode(N);
-}
-
void HexagonDAGToDAGISel::SelectSHL(SDNode *N) {
SDLoc dl(N);
SDValue Shl_0 = N->getOperand(0);
@@ -843,7 +762,7 @@ void HexagonDAGToDAGISel::SelectIntrinsicWOChain(SDNode *N) {
SDValue V = N->getOperand(1);
SDValue U;
- if (isValueExtension(V, Bits, U)) {
+ if (keepsLowBits(V, Bits, U)) {
SDValue R = CurDAG->getNode(N->getOpcode(), SDLoc(N), N->getValueType(0),
N->getOperand(0), U);
ReplaceNode(N, R.getNode());
@@ -949,7 +868,6 @@ void HexagonDAGToDAGISel::Select(SDNode *N) {
case ISD::SHL: return SelectSHL(N);
case ISD::LOAD: return SelectLoad(N);
case ISD::STORE: return SelectStore(N);
- case ISD::MUL: return SelectMul(N);
case ISD::ZERO_EXTEND: return SelectZeroExtend(N);
case ISD::INTRINSIC_W_CHAIN: return SelectIntrinsicWChain(N);
case ISD::INTRINSIC_WO_CHAIN: return SelectIntrinsicWOChain(N);
@@ -1327,7 +1245,7 @@ void HexagonDAGToDAGISel::EmitFunctionEntryCode() {
}
// Match a frame index that can be used in an addressing mode.
-bool HexagonDAGToDAGISel::SelectAddrFI(SDValue& N, SDValue &R) {
+bool HexagonDAGToDAGISel::SelectAddrFI(SDValue &N, SDValue &R) {
if (N.getOpcode() != ISD::FrameIndex)
return false;
auto &HFI = *HST->getFrameLowering();
@@ -1388,16 +1306,83 @@ bool HexagonDAGToDAGISel::SelectGlobalAddress(SDValue &N, SDValue &R,
return false;
}
-bool HexagonDAGToDAGISel::isValueExtension(const SDValue &Val,
- unsigned FromBits, SDValue &Src) {
+bool HexagonDAGToDAGISel::DetectUseSxtw(SDValue &N, SDValue &R) {
+ // This (complex pattern) function is meant to detect a sign-extension
+ // i32->i64 on a per-operand basis. This would allow writing single
+ // patterns that would cover a number of combinations of different ways
+ // a sign-extensions could be written. For example:
+ // (mul (DetectUseSxtw x) (DetectUseSxtw y)) -> (M2_dpmpyss_s0 x y)
+ // could match either one of these:
+ // (mul (sext x) (sext_inreg y))
+ // (mul (sext-load *p) (sext_inreg y))
+ // (mul (sext_inreg x) (sext y))
+ // etc.
+ //
+ // The returned value will have type i64 and its low word will
+ // contain the value being extended. The high bits are not specified.
+ // The returned type is i64 because the original type of N was i64,
+ // but the users of this function should only use the low-word of the
+ // result, e.g.
+ // (mul sxtw:x, sxtw:y) -> (M2_dpmpyss_s0 (LoReg sxtw:x), (LoReg sxtw:y))
+
+ if (N.getValueType() != MVT::i64)
+ return false;
+ EVT SrcVT;
+ unsigned Opc = N.getOpcode();
+ switch (Opc) {
+ case ISD::SIGN_EXTEND:
+ case ISD::SIGN_EXTEND_INREG: {
+ // sext_inreg has the source type as a separate operand.
+ EVT T = Opc == ISD::SIGN_EXTEND
+ ? N.getOperand(0).getValueType()
+ : cast<VTSDNode>(N.getOperand(1))->getVT();
+ if (T.getSizeInBits() != 32)
+ return false;
+ R = N.getOperand(0);
+ break;
+ }
+ case ISD::LOAD: {
+ LoadSDNode *L = cast<LoadSDNode>(N);
+ if (L->getExtensionType() != ISD::SEXTLOAD)
+ return false;
+ // All extending loads extend to i32, so even if the value in
+ // memory is shorter than 32 bits, it will be i32 after the load.
+ if (L->getMemoryVT().getSizeInBits() > 32)
+ return false;
+ R = N;
+ break;
+ }
+ default:
+ return false;
+ }
+ EVT RT = R.getValueType();
+ if (RT == MVT::i64)
+ return true;
+ assert(RT == MVT::i32);
+ // This is only to produce a value of type i64. Do not rely on the
+ // high bits produced by this.
+ const SDLoc &dl(N);
+ SDValue Ops[] = {
+ CurDAG->getTargetConstant(Hexagon::DoubleRegsRegClassID, dl, MVT::i32),
+ R, CurDAG->getTargetConstant(Hexagon::isub_hi, dl, MVT::i32),
+ R, CurDAG->getTargetConstant(Hexagon::isub_lo, dl, MVT::i32)
+ };
+ SDNode *T = CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl,
+ MVT::i64, Ops);
+ R = SDValue(T, 0);
+ return true;
+}
+
+bool HexagonDAGToDAGISel::keepsLowBits(const SDValue &Val, unsigned NumBits,
+ SDValue &Src) {
unsigned Opc = Val.getOpcode();
switch (Opc) {
case ISD::SIGN_EXTEND:
case ISD::ZERO_EXTEND:
case ISD::ANY_EXTEND: {
- SDValue const &Op0 = Val.getOperand(0);
+ const SDValue &Op0 = Val.getOperand(0);
EVT T = Op0.getValueType();
- if (T.isInteger() && T.getSizeInBits() == FromBits) {
+ if (T.isInteger() && T.getSizeInBits() == NumBits) {
Src = Op0;
return true;
}
@@ -1408,23 +1393,23 @@ bool HexagonDAGToDAGISel::isValueExtension(const SDValue &Val,
case ISD::AssertZext:
if (Val.getOperand(0).getValueType().isInteger()) {
VTSDNode *T = cast<VTSDNode>(Val.getOperand(1));
- if (T->getVT().getSizeInBits() == FromBits) {
+ if (T->getVT().getSizeInBits() == NumBits) {
Src = Val.getOperand(0);
return true;
}
}
break;
case ISD::AND: {
- // Check if this is an AND with "FromBits" of lower bits set to 1.
- uint64_t FromMask = (1 << FromBits) - 1;
+ // Check if this is an AND with NumBits of lower bits set to 1.
+ uint64_t Mask = (1 << NumBits) - 1;
if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Val.getOperand(0))) {
- if (C->getZExtValue() == FromMask) {
+ if (C->getZExtValue() == Mask) {
Src = Val.getOperand(1);
return true;
}
}
if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Val.getOperand(1))) {
- if (C->getZExtValue() == FromMask) {
+ if (C->getZExtValue() == Mask) {
Src = Val.getOperand(0);
return true;
}
@@ -1433,16 +1418,16 @@ bool HexagonDAGToDAGISel::isValueExtension(const SDValue &Val,
}
case ISD::OR:
case ISD::XOR: {
- // OR/XOR with the lower "FromBits" bits set to 0.
- uint64_t FromMask = (1 << FromBits) - 1;
+ // OR/XOR with the lower NumBits bits set to 0.
+ uint64_t Mask = (1 << NumBits) - 1;
if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Val.getOperand(0))) {
- if ((C->getZExtValue() & FromMask) == 0) {
+ if ((C->getZExtValue() & Mask) == 0) {
Src = Val.getOperand(1);
return true;
}
}
if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Val.getOperand(1))) {
- if ((C->getZExtValue() & FromMask) == 0) {
+ if ((C->getZExtValue() & Mask) == 0) {
Src = Val.getOperand(0);
return true;
}
diff --git a/contrib/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp b/contrib/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp
index 5ecf9320d5c2..4c6c6eeafbe0 100644
--- a/contrib/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp
+++ b/contrib/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp
@@ -1928,11 +1928,7 @@ HexagonTargetLowering::HexagonTargetLowering(const TargetMachine &TM,
setOperationAction(ISD::BITREVERSE, MVT::i64, Legal);
setOperationAction(ISD::BSWAP, MVT::i32, Legal);
setOperationAction(ISD::BSWAP, MVT::i64, Legal);
-
- // We custom lower i64 to i64 mul, so that it is not considered as a legal
- // operation. There is a pattern that will match i64 mul and transform it
- // to a series of instructions.
- setOperationAction(ISD::MUL, MVT::i64, Expand);
+ setOperationAction(ISD::MUL, MVT::i64, Legal);
for (unsigned IntExpOp :
{ ISD::SDIV, ISD::UDIV, ISD::SREM, ISD::UREM,
diff --git a/contrib/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp b/contrib/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp
index 66e07c67958e..0fef91ec4d3e 100644
--- a/contrib/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp
+++ b/contrib/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp
@@ -1769,161 +1769,6 @@ bool HexagonInstrInfo::isCompoundBranchInstr(const MachineInstr &MI) const {
return getType(MI) == HexagonII::TypeCJ && MI.isBranch();
}
-bool HexagonInstrInfo::isCondInst(const MachineInstr &MI) const {
- return (MI.isBranch() && isPredicated(MI)) ||
- isConditionalTransfer(MI) ||
- isConditionalALU32(MI) ||
- isConditionalLoad(MI) ||
- // Predicated stores which don't have a .new on any operands.
- (MI.mayStore() && isPredicated(MI) && !isNewValueStore(MI) &&
- !isPredicatedNew(MI));
-}
-
-bool HexagonInstrInfo::isConditionalALU32(const MachineInstr &MI) const {
- switch (MI.getOpcode()) {
- case Hexagon::A2_paddf:
- case Hexagon::A2_paddfnew:
- case Hexagon::A2_paddif:
- case Hexagon::A2_paddifnew:
- case Hexagon::A2_paddit:
- case Hexagon::A2_padditnew:
- case Hexagon::A2_paddt:
- case Hexagon::A2_paddtnew:
- case Hexagon::A2_pandf:
- case Hexagon::A2_pandfnew:
- case Hexagon::A2_pandt:
- case Hexagon::A2_pandtnew:
- case Hexagon::A2_porf:
- case Hexagon::A2_porfnew:
- case Hexagon::A2_port:
- case Hexagon::A2_portnew:
- case Hexagon::A2_psubf:
- case Hexagon::A2_psubfnew:
- case Hexagon::A2_psubt:
- case Hexagon::A2_psubtnew:
- case Hexagon::A2_pxorf:
- case Hexagon::A2_pxorfnew:
- case Hexagon::A2_pxort:
- case Hexagon::A2_pxortnew:
- case Hexagon::A4_paslhf:
- case Hexagon::A4_paslhfnew:
- case Hexagon::A4_paslht:
- case Hexagon::A4_paslhtnew:
- case Hexagon::A4_pasrhf:
- case Hexagon::A4_pasrhfnew:
- case Hexagon::A4_pasrht:
- case Hexagon::A4_pasrhtnew:
- case Hexagon::A4_psxtbf:
- case Hexagon::A4_psxtbfnew:
- case Hexagon::A4_psxtbt:
- case Hexagon::A4_psxtbtnew:
- case Hexagon::A4_psxthf:
- case Hexagon::A4_psxthfnew:
- case Hexagon::A4_psxtht:
- case Hexagon::A4_psxthtnew:
- case Hexagon::A4_pzxtbf:
- case Hexagon::A4_pzxtbfnew:
- case Hexagon::A4_pzxtbt:
- case Hexagon::A4_pzxtbtnew:
- case Hexagon::A4_pzxthf:
- case Hexagon::A4_pzxthfnew:
- case Hexagon::A4_pzxtht:
- case Hexagon::A4_pzxthtnew:
- case Hexagon::C2_ccombinewf:
- case Hexagon::C2_ccombinewt:
- return true;
- }
- return false;
-}
-
-// FIXME - Function name and it's functionality don't match.
-// It should be renamed to hasPredNewOpcode()
-bool HexagonInstrInfo::isConditionalLoad(const MachineInstr &MI) const {
- if (!MI.getDesc().mayLoad() || !isPredicated(MI))
- return false;
-
- int PNewOpcode = Hexagon::getPredNewOpcode(MI.getOpcode());
- // Instruction with valid predicated-new opcode can be promoted to .new.
- return PNewOpcode >= 0;
-}
-
-// Returns true if an instruction is a conditional store.
-//
-// Note: It doesn't include conditional new-value stores as they can't be
-// converted to .new predicate.
-bool HexagonInstrInfo::isConditionalStore(const MachineInstr &MI) const {
- switch (MI.getOpcode()) {
- default: return false;
- case Hexagon::S4_storeirbt_io:
- case Hexagon::S4_storeirbf_io:
- case Hexagon::S4_pstorerbt_rr:
- case Hexagon::S4_pstorerbf_rr:
- case Hexagon::S2_pstorerbt_io:
- case Hexagon::S2_pstorerbf_io:
- case Hexagon::S2_pstorerbt_pi:
- case Hexagon::S2_pstorerbf_pi:
- case Hexagon::S2_pstorerdt_io:
- case Hexagon::S2_pstorerdf_io:
- case Hexagon::S4_pstorerdt_rr:
- case Hexagon::S4_pstorerdf_rr:
- case Hexagon::S2_pstorerdt_pi:
- case Hexagon::S2_pstorerdf_pi:
- case Hexagon::S2_pstorerht_io:
- case Hexagon::S2_pstorerhf_io:
- case Hexagon::S4_storeirht_io:
- case Hexagon::S4_storeirhf_io:
- case Hexagon::S4_pstorerht_rr:
- case Hexagon::S4_pstorerhf_rr:
- case Hexagon::S2_pstorerht_pi:
- case Hexagon::S2_pstorerhf_pi:
- case Hexagon::S2_pstorerit_io:
- case Hexagon::S2_pstorerif_io:
- case Hexagon::S4_storeirit_io:
- case Hexagon::S4_storeirif_io:
- case Hexagon::S4_pstorerit_rr:
- case Hexagon::S4_pstorerif_rr:
- case Hexagon::S2_pstorerit_pi:
- case Hexagon::S2_pstorerif_pi:
-
- // V4 global address store before promoting to dot new.
- case Hexagon::S4_pstorerdt_abs:
- case Hexagon::S4_pstorerdf_abs:
- case Hexagon::S4_pstorerbt_abs:
- case Hexagon::S4_pstorerbf_abs:
- case Hexagon::S4_pstorerht_abs:
- case Hexagon::S4_pstorerhf_abs:
- case Hexagon::S4_pstorerit_abs:
- case Hexagon::S4_pstorerif_abs:
- return true;
-
- // Predicated new value stores (i.e. if (p0) memw(..)=r0.new) are excluded
- // from the "Conditional Store" list. Because a predicated new value store
- // would NOT be promoted to a double dot new store.
- // This function returns yes for those stores that are predicated but not
- // yet promoted to predicate dot new instructions.
- }
-}
-
-bool HexagonInstrInfo::isConditionalTransfer(const MachineInstr &MI) const {
- switch (MI.getOpcode()) {
- case Hexagon::A2_tfrt:
- case Hexagon::A2_tfrf:
- case Hexagon::C2_cmoveit:
- case Hexagon::C2_cmoveif:
- case Hexagon::A2_tfrtnew:
- case Hexagon::A2_tfrfnew:
- case Hexagon::C2_cmovenewit:
- case Hexagon::C2_cmovenewif:
- case Hexagon::A2_tfrpt:
- case Hexagon::A2_tfrpf:
- return true;
-
- default:
- return false;
- }
- return false;
-}
-
// TODO: In order to have isExtendable for fpimm/f32Ext, we need to handle
// isFPImm and later getFPImm as well.
bool HexagonInstrInfo::isConstExtended(const MachineInstr &MI) const {
@@ -3474,6 +3319,8 @@ int HexagonInstrInfo::getDotNewOp(const MachineInstr &MI) const {
// Returns the opcode to use when converting MI, which is a conditional jump,
// into a conditional instruction which uses the .new value of the predicate.
// We also use branch probabilities to add a hint to the jump.
+// If MBPI is null, all edges will be treated as equally likely for the
+// purposes of establishing a predication hint.
int HexagonInstrInfo::getDotNewPredJumpOp(const MachineInstr &MI,
const MachineBranchProbabilityInfo *MBPI) const {
// We assume that block can have at most two successors.
@@ -3482,9 +3329,16 @@ int HexagonInstrInfo::getDotNewPredJumpOp(const MachineInstr &MI,
bool Taken = false;
const BranchProbability OneHalf(1, 2);
+ auto getEdgeProbability = [MBPI] (const MachineBasicBlock *Src,
+ const MachineBasicBlock *Dst) {
+ if (MBPI)
+ return MBPI->getEdgeProbability(Src, Dst);
+ return BranchProbability(1, Src->succ_size());
+ };
+
if (BrTarget.isMBB()) {
const MachineBasicBlock *Dst = BrTarget.getMBB();
- Taken = MBPI->getEdgeProbability(Src, Dst) >= OneHalf;
+ Taken = getEdgeProbability(Src, Dst) >= OneHalf;
} else {
// The branch target is not a basic block (most likely a function).
// Since BPI only gives probabilities for targets that are basic blocks,
@@ -3521,7 +3375,7 @@ int HexagonInstrInfo::getDotNewPredJumpOp(const MachineInstr &MI,
for (const MachineBasicBlock *SB : B.successors()) {
if (!B.isLayoutSuccessor(SB))
continue;
- Taken = MBPI->getEdgeProbability(Src, SB) < OneHalf;
+ Taken = getEdgeProbability(Src, SB) < OneHalf;
break;
}
} else {
@@ -3534,7 +3388,7 @@ int HexagonInstrInfo::getDotNewPredJumpOp(const MachineInstr &MI,
BT = Op.getMBB();
break;
}
- Taken = BT && MBPI->getEdgeProbability(Src, BT) < OneHalf;
+ Taken = BT && getEdgeProbability(Src, BT) < OneHalf;
}
} // if (!Bad)
}
diff --git a/contrib/llvm/lib/Target/Hexagon/HexagonInstrInfo.h b/contrib/llvm/lib/Target/Hexagon/HexagonInstrInfo.h
index 97b9bc954688..944d0161a7c8 100644
--- a/contrib/llvm/lib/Target/Hexagon/HexagonInstrInfo.h
+++ b/contrib/llvm/lib/Target/Hexagon/HexagonInstrInfo.h
@@ -314,11 +314,6 @@ public:
bool isAccumulator(const MachineInstr &MI) const;
bool isComplex(const MachineInstr &MI) const;
bool isCompoundBranchInstr(const MachineInstr &MI) const;
- bool isCondInst(const MachineInstr &MI) const;
- bool isConditionalALU32 (const MachineInstr &MI) const;
- bool isConditionalLoad(const MachineInstr &MI) const;
- bool isConditionalStore(const MachineInstr &MI) const;
- bool isConditionalTransfer(const MachineInstr &MI) const;
bool isConstExtended(const MachineInstr &MI) const;
bool isDeallocRet(const MachineInstr &MI) const;
bool isDependent(const MachineInstr &ProdMI,
diff --git a/contrib/llvm/lib/Target/Hexagon/HexagonLoopIdiomRecognition.cpp b/contrib/llvm/lib/Target/Hexagon/HexagonLoopIdiomRecognition.cpp
index e6ea67d55b43..9aa185fc85a6 100644
--- a/contrib/llvm/lib/Target/Hexagon/HexagonLoopIdiomRecognition.cpp
+++ b/contrib/llvm/lib/Target/Hexagon/HexagonLoopIdiomRecognition.cpp
@@ -59,6 +59,9 @@ cl::opt<bool> HexagonVolatileMemcpy("disable-hexagon-volatile-memcpy",
cl::Hidden, cl::init(false),
cl::desc("Enable Hexagon-specific memcpy for volatile destination."));
+static cl::opt<unsigned> SimplifyLimit("hlir-simplify-limit", cl::init(10000),
+ cl::Hidden, cl::desc("Maximum number of simplification steps in HLIR"));
+
static const char *HexagonVolatileMemcpyName
= "hexagon_memcpy_forward_vp4cp4n2";
@@ -477,7 +480,7 @@ Value *Simplifier::simplify(Context &C) {
WorkListType Q;
Q.push_back(C.Root);
unsigned Count = 0;
- const unsigned Limit = 100000;
+ const unsigned Limit = SimplifyLimit;
while (!Q.empty()) {
if (Count++ >= Limit)
@@ -501,8 +504,7 @@ Value *Simplifier::simplify(Context &C) {
Q.push_back(Op);
}
}
- assert(Count < Limit && "Infinite loop in HLIR/simplify?");
- return C.Root;
+ return Count < Limit ? C.Root : nullptr;
}
diff --git a/contrib/llvm/lib/Target/Hexagon/HexagonPatterns.td b/contrib/llvm/lib/Target/Hexagon/HexagonPatterns.td
index 81b5e10c1173..70ed123bc898 100644
--- a/contrib/llvm/lib/Target/Hexagon/HexagonPatterns.td
+++ b/contrib/llvm/lib/Target/Hexagon/HexagonPatterns.td
@@ -382,48 +382,42 @@ def: T_MType_acc_pat3 <M4_or_andn, and, or>;
def: T_MType_acc_pat3 <M4_and_andn, and, and>;
def: T_MType_acc_pat3 <M4_xor_andn, and, xor>;
+// This complex pattern is really only to detect various forms of
+// sign-extension i32->i64. The selected value will be of type i64
+// whose low word is the value being extended. The high word is
+// unspecified.
+def Usxtw : ComplexPattern<i64, 1, "DetectUseSxtw", [], []>;
+
def Aext64: PatFrag<(ops node:$Rs), (i64 (anyext node:$Rs))>;
-def Sext64: PatFrag<(ops node:$Rs), (i64 (sext node:$Rs))>;
def Zext64: PatFrag<(ops node:$Rs), (i64 (zext node:$Rs))>;
+def Sext64: PatLeaf<(i64 Usxtw:$Rs)>;
-// Return true if for a 32 to 64-bit sign-extended load.
-def Sext64Ld : PatLeaf<(i64 DoubleRegs:$src1), [{
- LoadSDNode *LD = dyn_cast<LoadSDNode>(N);
- if (!LD)
- return false;
- return LD->getExtensionType() == ISD::SEXTLOAD &&
- LD->getMemoryVT().getScalarType() == MVT::i32;
-}]>;
-
-def: Pat<(mul (Aext64 I32:$src1), (Aext64 I32:$src2)),
- (M2_dpmpyuu_s0 IntRegs:$src1, IntRegs:$src2)>;
-
-def: Pat<(mul (Sext64 I32:$src1), (Sext64 I32:$src2)),
- (M2_dpmpyss_s0 IntRegs:$src1, IntRegs:$src2)>;
+def: Pat<(mul (Aext64 I32:$Rs), (Aext64 I32:$Rt)),
+ (M2_dpmpyuu_s0 I32:$Rs, I32:$Rt)>;
-def: Pat<(mul Sext64Ld:$src1, Sext64Ld:$src2),
- (M2_dpmpyss_s0 (LoReg DoubleRegs:$src1), (LoReg DoubleRegs:$src2))>;
+def: Pat<(mul Sext64:$Rs, Sext64:$Rt),
+ (M2_dpmpyss_s0 (LoReg Sext64:$Rs), (LoReg Sext64:$Rt))>;
// Multiply and accumulate, use full result.
// Rxx[+-]=mpy(Rs,Rt)
-def: Pat<(add I64:$src1, (mul (Sext64 I32:$src2), (Sext64 I32:$src3))),
- (M2_dpmpyss_acc_s0 DoubleRegs:$src1, IntRegs:$src2, IntRegs:$src3)>;
+def: Pat<(add I64:$Rx, (mul Sext64:$Rs, Sext64:$Rt)),
+ (M2_dpmpyss_acc_s0 I64:$Rx, (LoReg Sext64:$Rs), (LoReg Sext64:$Rt))>;
-def: Pat<(sub I64:$src1, (mul (Sext64 I32:$src2), (Sext64 I32:$src3))),
- (M2_dpmpyss_nac_s0 DoubleRegs:$src1, IntRegs:$src2, IntRegs:$src3)>;
+def: Pat<(sub I64:$Rx, (mul Sext64:$Rs, Sext64:$Rt)),
+ (M2_dpmpyss_nac_s0 I64:$Rx, (LoReg Sext64:$Rs), (LoReg Sext64:$Rt))>;
-def: Pat<(add I64:$src1, (mul (Aext64 I32:$src2), (Aext64 I32:$src3))),
- (M2_dpmpyuu_acc_s0 DoubleRegs:$src1, IntRegs:$src2, IntRegs:$src3)>;
+def: Pat<(add I64:$Rx, (mul (Aext64 I32:$Rs), (Aext64 I32:$Rt))),
+ (M2_dpmpyuu_acc_s0 I64:$Rx, I32:$Rs, I32:$Rt)>;
-def: Pat<(add I64:$src1, (mul (Zext64 I32:$src2), (Zext64 I32:$src3))),
- (M2_dpmpyuu_acc_s0 DoubleRegs:$src1, IntRegs:$src2, IntRegs:$src3)>;
+def: Pat<(add I64:$Rx, (mul (Zext64 I32:$Rs), (Zext64 I32:$Rt))),
+ (M2_dpmpyuu_acc_s0 I64:$Rx, I32:$Rs, I32:$Rt)>;
-def: Pat<(sub I64:$src1, (mul (Aext64 I32:$src2), (Aext64 I32:$src3))),
- (M2_dpmpyuu_nac_s0 DoubleRegs:$src1, IntRegs:$src2, IntRegs:$src3)>;
+def: Pat<(sub I64:$Rx, (mul (Aext64 I32:$Rs), (Aext64 I32:$Rt))),
+ (M2_dpmpyuu_nac_s0 I64:$Rx, I32:$Rs, I32:$Rt)>;
-def: Pat<(sub I64:$src1, (mul (Zext64 I32:$src2), (Zext64 I32:$src3))),
- (M2_dpmpyuu_nac_s0 DoubleRegs:$src1, IntRegs:$src2, IntRegs:$src3)>;
+def: Pat<(sub I64:$Rx, (mul (Zext64 I32:$Rs), (Zext64 I32:$Rt))),
+ (M2_dpmpyuu_nac_s0 I64:$Rx, I32:$Rs, I32:$Rt)>;
class Storepi_pat<PatFrag Store, PatFrag Value, PatFrag Offset,
InstHexagon MI>
@@ -545,7 +539,8 @@ def: Storexm_simple_pat<truncstorei8, I64, LoReg, S2_storerb_io>;
def: Storexm_simple_pat<truncstorei16, I64, LoReg, S2_storerh_io>;
def: Storexm_simple_pat<truncstorei32, I64, LoReg, S2_storeri_io>;
-def: Pat <(Sext64 I32:$src), (A2_sxtw I32:$src)>;
+def: Pat <(i64 (sext I32:$src)), (A2_sxtw I32:$src)>;
+def: Pat <(i64 (sext_inreg I64:$src, i32)), (A2_sxtw (LoReg I64:$src))>;
def: Pat<(select (i1 (setlt I32:$src, 0)), (sub 0, I32:$src), I32:$src),
(A2_abs IntRegs:$src)>;
@@ -1159,8 +1154,8 @@ multiclass MinMax_pats_p<PatFrag Op, InstHexagon Inst, InstHexagon SwapInst> {
defm: T_MinMax_pats<Op, I64, Inst, SwapInst>;
}
-def: Pat<(add (Sext64 I32:$Rs), I64:$Rt),
- (A2_addsp IntRegs:$Rs, DoubleRegs:$Rt)>;
+def: Pat<(add Sext64:$Rs, I64:$Rt),
+ (A2_addsp (LoReg Sext64:$Rs), DoubleRegs:$Rt)>;
let AddedComplexity = 200 in {
defm: MinMax_pats_p<setge, A2_maxp, A2_minp>;
diff --git a/contrib/llvm/lib/Target/Hexagon/HexagonTargetMachine.cpp b/contrib/llvm/lib/Target/Hexagon/HexagonTargetMachine.cpp
index 8e93df6201ae..14ecf297d351 100644
--- a/contrib/llvm/lib/Target/Hexagon/HexagonTargetMachine.cpp
+++ b/contrib/llvm/lib/Target/Hexagon/HexagonTargetMachine.cpp
@@ -223,7 +223,7 @@ namespace {
/// Hexagon Code Generator Pass Configuration Options.
class HexagonPassConfig : public TargetPassConfig {
public:
- HexagonPassConfig(HexagonTargetMachine *TM, PassManagerBase &PM)
+ HexagonPassConfig(HexagonTargetMachine &TM, PassManagerBase &PM)
: TargetPassConfig(TM, PM) {}
HexagonTargetMachine &getHexagonTargetMachine() const {
@@ -245,7 +245,7 @@ public:
} // namespace
TargetPassConfig *HexagonTargetMachine::createPassConfig(PassManagerBase &PM) {
- return new HexagonPassConfig(this, PM);
+ return new HexagonPassConfig(*this, PM);
}
void HexagonPassConfig::addIRPasses() {
diff --git a/contrib/llvm/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp b/contrib/llvm/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp
index cd474921d4bc..fa08afe4019d 100644
--- a/contrib/llvm/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp
+++ b/contrib/llvm/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp
@@ -273,25 +273,17 @@ bool HexagonPacketizerList::isCallDependent(const MachineInstr &MI,
if (DepReg == HRI->getFrameRegister() || DepReg == HRI->getStackRegister())
return true;
- // Check if this is a predicate dependence.
- const TargetRegisterClass* RC = HRI->getMinimalPhysRegClass(DepReg);
- if (RC == &Hexagon::PredRegsRegClass)
- return true;
-
- // Assumes that the first operand of the CALLr is the function address.
- if (HII->isIndirectCall(MI) && (DepType == SDep::Data)) {
- const MachineOperand MO = MI.getOperand(0);
- if (MO.isReg() && MO.isUse() && (MO.getReg() == DepReg))
- return true;
+ // Call-like instructions can be packetized with preceding instructions
+ // that define registers implicitly used or modified by the call. Explicit
+ // uses are still prohibited, as in the case of indirect calls:
+ // r0 = ...
+ // J2_jumpr r0
+ if (DepType == SDep::Data) {
+ for (const MachineOperand MO : MI.operands())
+ if (MO.isReg() && MO.getReg() == DepReg && !MO.isImplicit())
+ return true;
}
- if (HII->isJumpR(MI)) {
- const MachineOperand &MO = HII->isPredicated(MI) ? MI.getOperand(1)
- : MI.getOperand(0);
- assert(MO.isReg() && MO.isUse());
- if (MO.getReg() == DepReg)
- return true;
- }
return false;
}
@@ -333,11 +325,13 @@ bool HexagonPacketizerList::isNewifiable(const MachineInstr &MI,
const TargetRegisterClass *NewRC) {
// Vector stores can be predicated, and can be new-value stores, but
// they cannot be predicated on a .new predicate value.
- if (NewRC == &Hexagon::PredRegsRegClass)
+ if (NewRC == &Hexagon::PredRegsRegClass) {
if (HII->isHVXVec(MI) && MI.mayStore())
return false;
- return HII->isCondInst(MI) || HII->isJumpR(MI) || MI.isReturn() ||
- HII->mayBeNewStore(MI);
+ return HII->isPredicated(MI) && HII->getDotNewPredOp(MI, nullptr) > 0;
+ }
+ // If the class is not PredRegs, it could only apply to new-value stores.
+ return HII->mayBeNewStore(MI);
}
// Promote an instructiont to its .cur form.
@@ -760,11 +754,14 @@ bool HexagonPacketizerList::canPromoteToNewValue(const MachineInstr &MI,
return false;
}
-static bool isImplicitDependency(const MachineInstr &I, unsigned DepReg) {
+static bool isImplicitDependency(const MachineInstr &I, bool CheckDef,
+ unsigned DepReg) {
for (auto &MO : I.operands()) {
- if (MO.isRegMask() && MO.clobbersPhysReg(DepReg))
+ if (CheckDef && MO.isRegMask() && MO.clobbersPhysReg(DepReg))
return true;
- if (MO.isReg() && MO.isDef() && (MO.getReg() == DepReg) && MO.isImplicit())
+ if (!MO.isReg() || MO.getReg() != DepReg || !MO.isImplicit())
+ continue;
+ if (CheckDef == MO.isDef())
return true;
}
return false;
@@ -798,7 +795,8 @@ bool HexagonPacketizerList::canPromoteToDotNew(const MachineInstr &MI,
// If dependency is trough an implicitly defined register, we should not
// newify the use.
- if (isImplicitDependency(PI, DepReg))
+ if (isImplicitDependency(PI, true, DepReg) ||
+ isImplicitDependency(MI, false, DepReg))
return false;
const MCInstrDesc& MCID = PI.getDesc();
@@ -808,8 +806,7 @@ bool HexagonPacketizerList::canPromoteToDotNew(const MachineInstr &MI,
// predicate .new
if (RC == &Hexagon::PredRegsRegClass)
- if (HII->isCondInst(MI) || HII->isJumpR(MI) || MI.isReturn())
- return HII->predCanBeUsedAsDotNew(PI, DepReg);
+ return HII->predCanBeUsedAsDotNew(PI, DepReg);
if (RC != &Hexagon::PredRegsRegClass && !HII->mayBeNewStore(MI))
return false;
diff --git a/contrib/llvm/lib/Target/Lanai/LanaiTargetMachine.cpp b/contrib/llvm/lib/Target/Lanai/LanaiTargetMachine.cpp
index 2a9bc25d7fad..a2f005ce445a 100644
--- a/contrib/llvm/lib/Target/Lanai/LanaiTargetMachine.cpp
+++ b/contrib/llvm/lib/Target/Lanai/LanaiTargetMachine.cpp
@@ -76,7 +76,7 @@ namespace {
// Lanai Code Generator Pass Configuration Options.
class LanaiPassConfig : public TargetPassConfig {
public:
- LanaiPassConfig(LanaiTargetMachine *TM, PassManagerBase *PassManager)
+ LanaiPassConfig(LanaiTargetMachine &TM, PassManagerBase *PassManager)
: TargetPassConfig(TM, *PassManager) {}
LanaiTargetMachine &getLanaiTargetMachine() const {
@@ -91,7 +91,7 @@ public:
TargetPassConfig *
LanaiTargetMachine::createPassConfig(PassManagerBase &PassManager) {
- return new LanaiPassConfig(this, &PassManager);
+ return new LanaiPassConfig(*this, &PassManager);
}
// Install an instruction selector pass.
diff --git a/contrib/llvm/lib/Target/Lanai/LanaiTargetMachine.h b/contrib/llvm/lib/Target/Lanai/LanaiTargetMachine.h
index 5278c70d909d..083ba6fdf841 100644
--- a/contrib/llvm/lib/Target/Lanai/LanaiTargetMachine.h
+++ b/contrib/llvm/lib/Target/Lanai/LanaiTargetMachine.h
@@ -49,6 +49,10 @@ public:
TargetLoweringObjectFile *getObjFileLowering() const override {
return TLOF.get();
}
+
+ bool isMachineVerifierClean() const override {
+ return false;
+ }
};
} // namespace llvm
diff --git a/contrib/llvm/lib/Target/MSP430/MSP430TargetMachine.cpp b/contrib/llvm/lib/Target/MSP430/MSP430TargetMachine.cpp
index bebe5fa35ad4..d8fdc8ba674e 100644
--- a/contrib/llvm/lib/Target/MSP430/MSP430TargetMachine.cpp
+++ b/contrib/llvm/lib/Target/MSP430/MSP430TargetMachine.cpp
@@ -52,7 +52,7 @@ namespace {
/// MSP430 Code Generator Pass Configuration Options.
class MSP430PassConfig : public TargetPassConfig {
public:
- MSP430PassConfig(MSP430TargetMachine *TM, PassManagerBase &PM)
+ MSP430PassConfig(MSP430TargetMachine &TM, PassManagerBase &PM)
: TargetPassConfig(TM, PM) {}
MSP430TargetMachine &getMSP430TargetMachine() const {
@@ -65,7 +65,7 @@ public:
} // namespace
TargetPassConfig *MSP430TargetMachine::createPassConfig(PassManagerBase &PM) {
- return new MSP430PassConfig(this, PM);
+ return new MSP430PassConfig(*this, PM);
}
bool MSP430PassConfig::addInstSelector() {
diff --git a/contrib/llvm/lib/Target/Mips/Mips16FrameLowering.cpp b/contrib/llvm/lib/Target/Mips/Mips16FrameLowering.cpp
index e7ceca9612a9..a222080f6b81 100644
--- a/contrib/llvm/lib/Target/Mips/Mips16FrameLowering.cpp
+++ b/contrib/llvm/lib/Target/Mips/Mips16FrameLowering.cpp
@@ -1,4 +1,4 @@
-//===-- Mips16FrameLowering.cpp - Mips16 Frame Information ----------------===//
+//===- Mips16FrameLowering.cpp - Mips16 Frame Information -----------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -11,20 +11,29 @@
//
//===----------------------------------------------------------------------===//
-#include "Mips16FrameLowering.h"
#include "MCTargetDesc/MipsBaseInfo.h"
+#include "Mips16FrameLowering.h"
#include "Mips16InstrInfo.h"
#include "MipsInstrInfo.h"
#include "MipsRegisterInfo.h"
#include "MipsSubtarget.h"
+#include "llvm/ADT/BitVector.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
-#include "llvm/CodeGen/MachineRegisterInfo.h"
-#include "llvm/IR/DataLayout.h"
-#include "llvm/IR/Function.h"
-#include "llvm/Target/TargetOptions.h"
+#include "llvm/IR/DebugLoc.h"
+#include "llvm/MC/MachineLocation.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCDwarf.h"
+#include "llvm/MC/MCRegisterInfo.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Target/TargetFrameLowering.h"
+#include <cassert>
+#include <cstdint>
+#include <vector>
using namespace llvm;
@@ -63,7 +72,7 @@ void Mips16FrameLowering::emitPrologue(MachineFunction &MF,
const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();
- if (CSI.size()) {
+ if (!CSI.empty()) {
const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();
for (std::vector<CalleeSavedInfo>::const_iterator I = CSI.begin(),
@@ -80,7 +89,6 @@ void Mips16FrameLowering::emitPrologue(MachineFunction &MF,
if (hasFP(MF))
BuildMI(MBB, MBBI, dl, TII.get(Mips::MoveR3216), Mips::S0)
.addReg(Mips::SP).setMIFlag(MachineInstr::FrameSetup);
-
}
void Mips16FrameLowering::emitEpilogue(MachineFunction &MF,
diff --git a/contrib/llvm/lib/Target/Mips/MipsTargetMachine.cpp b/contrib/llvm/lib/Target/Mips/MipsTargetMachine.cpp
index 092de216e9b8..a9d6ab055892 100644
--- a/contrib/llvm/lib/Target/Mips/MipsTargetMachine.cpp
+++ b/contrib/llvm/lib/Target/Mips/MipsTargetMachine.cpp
@@ -201,7 +201,7 @@ namespace {
/// Mips Code Generator Pass Configuration Options.
class MipsPassConfig : public TargetPassConfig {
public:
- MipsPassConfig(MipsTargetMachine *TM, PassManagerBase &PM)
+ MipsPassConfig(MipsTargetMachine &TM, PassManagerBase &PM)
: TargetPassConfig(TM, PM) {
// The current implementation of long branch pass requires a scratch
// register ($at) to be available before branch instructions. Tail merging
@@ -227,7 +227,7 @@ public:
} // end anonymous namespace
TargetPassConfig *MipsTargetMachine::createPassConfig(PassManagerBase &PM) {
- return new MipsPassConfig(this, PM);
+ return new MipsPassConfig(*this, PM);
}
void MipsPassConfig::addIRPasses() {
diff --git a/contrib/llvm/lib/Target/Mips/MipsTargetMachine.h b/contrib/llvm/lib/Target/Mips/MipsTargetMachine.h
index 140d7133f879..a3462868cb11 100644
--- a/contrib/llvm/lib/Target/Mips/MipsTargetMachine.h
+++ b/contrib/llvm/lib/Target/Mips/MipsTargetMachine.h
@@ -66,6 +66,10 @@ public:
bool isLittleEndian() const { return isLittle; }
const MipsABIInfo &getABI() const { return ABI; }
+
+ bool isMachineVerifierClean() const override {
+ return false;
+ }
};
/// Mips32/64 big endian target machine.
diff --git a/contrib/llvm/lib/Target/NVPTX/NVPTXTargetMachine.cpp b/contrib/llvm/lib/Target/NVPTX/NVPTXTargetMachine.cpp
index ab5298d0dcfd..8dfbfece9b8e 100644
--- a/contrib/llvm/lib/Target/NVPTX/NVPTXTargetMachine.cpp
+++ b/contrib/llvm/lib/Target/NVPTX/NVPTXTargetMachine.cpp
@@ -132,7 +132,7 @@ namespace {
class NVPTXPassConfig : public TargetPassConfig {
public:
- NVPTXPassConfig(NVPTXTargetMachine *TM, PassManagerBase &PM)
+ NVPTXPassConfig(NVPTXTargetMachine &TM, PassManagerBase &PM)
: TargetPassConfig(TM, PM) {}
NVPTXTargetMachine &getNVPTXTargetMachine() const {
@@ -163,7 +163,7 @@ private:
} // end anonymous namespace
TargetPassConfig *NVPTXTargetMachine::createPassConfig(PassManagerBase &PM) {
- return new NVPTXPassConfig(this, PM);
+ return new NVPTXPassConfig(*this, PM);
}
void NVPTXTargetMachine::adjustPassManager(PassManagerBuilder &Builder) {
diff --git a/contrib/llvm/lib/Target/NVPTX/NVPTXTargetMachine.h b/contrib/llvm/lib/Target/NVPTX/NVPTXTargetMachine.h
index 1ed8e3b1e935..2f3981be22f8 100644
--- a/contrib/llvm/lib/Target/NVPTX/NVPTXTargetMachine.h
+++ b/contrib/llvm/lib/Target/NVPTX/NVPTXTargetMachine.h
@@ -65,6 +65,9 @@ public:
TargetIRAnalysis getTargetIRAnalysis() override;
+ bool isMachineVerifierClean() const override {
+ return false;
+ }
}; // NVPTXTargetMachine.
class NVPTXTargetMachine32 : public NVPTXTargetMachine {
diff --git a/contrib/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp b/contrib/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
index 5fa7b2c6bfb1..54414457388d 100644
--- a/contrib/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
+++ b/contrib/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
@@ -77,6 +77,11 @@ STATISTIC(SignExtensionsAdded,
"Number of sign extensions for compare inputs added.");
STATISTIC(ZeroExtensionsAdded,
"Number of zero extensions for compare inputs added.");
+STATISTIC(NumLogicOpsOnComparison,
+ "Number of logical ops on i1 values calculated in GPR.");
+STATISTIC(OmittedForNonExtendUses,
+ "Number of compares not eliminated as they have non-extending uses.");
+
// FIXME: Remove this once the bug has been fixed!
cl::opt<bool> ANDIGlueBug("expose-ppc-andi-glue-bug",
cl::desc("expose the ANDI glue bug on PPC"), cl::Hidden);
@@ -275,6 +280,8 @@ private:
bool trySETCC(SDNode *N);
bool tryEXTEND(SDNode *N);
+ bool tryLogicOpOfCompares(SDNode *N);
+ SDValue computeLogicOpInGPR(SDValue LogicOp);
SDValue signExtendInputIfNeeded(SDValue Input);
SDValue zeroExtendInputIfNeeded(SDValue Input);
SDValue addExtOrTrunc(SDValue NatWidthRes, ExtOrTruncConversion Conv);
@@ -282,6 +289,10 @@ private:
int64_t RHSValue, SDLoc dl);
SDValue get32BitSExtCompare(SDValue LHS, SDValue RHS, ISD::CondCode CC,
int64_t RHSValue, SDLoc dl);
+ SDValue get64BitZExtCompare(SDValue LHS, SDValue RHS, ISD::CondCode CC,
+ int64_t RHSValue, SDLoc dl);
+ SDValue get64BitSExtCompare(SDValue LHS, SDValue RHS, ISD::CondCode CC,
+ int64_t RHSValue, SDLoc dl);
SDValue getSETCCInGPR(SDValue Compare, SetccInGPROpts ConvOpts);
void PeepholePPC64();
@@ -2501,6 +2512,11 @@ bool PPCDAGToDAGISel::trySETCC(SDNode *N) {
return true;
}
+// Is this opcode a bitwise logical operation?
+static bool isLogicOp(unsigned Opc) {
+ return Opc == ISD::AND || Opc == ISD::OR || Opc == ISD::XOR;
+}
+
/// If this node is a sign/zero extension of an integer comparison,
/// it can usually be computed in GPR's rather than using comparison
/// instructions and ISEL. We only do this on 64-bit targets for now
@@ -2513,13 +2529,20 @@ bool PPCDAGToDAGISel::tryEXTEND(SDNode *N) {
N->getOpcode() == ISD::SIGN_EXTEND) &&
"Expecting a zero/sign extend node!");
- if (N->getOperand(0).getOpcode() != ISD::SETCC)
+ SDValue WideRes;
+ // If we are zero-extending the result of a logical operation on i1
+ // values, we can keep the values in GPRs.
+ if (isLogicOp(N->getOperand(0).getOpcode()) &&
+ N->getOperand(0).getValueType() == MVT::i1 &&
+ N->getOpcode() == ISD::ZERO_EXTEND)
+ WideRes = computeLogicOpInGPR(N->getOperand(0));
+ else if (N->getOperand(0).getOpcode() != ISD::SETCC)
return false;
-
- SDValue WideRes =
- getSETCCInGPR(N->getOperand(0),
- N->getOpcode() == ISD::SIGN_EXTEND ?
- SetccInGPROpts::SExtOrig : SetccInGPROpts::ZExtOrig);
+ else
+ WideRes =
+ getSETCCInGPR(N->getOperand(0),
+ N->getOpcode() == ISD::SIGN_EXTEND ?
+ SetccInGPROpts::SExtOrig : SetccInGPROpts::ZExtOrig);
if (!WideRes)
return false;
@@ -2540,6 +2563,159 @@ bool PPCDAGToDAGISel::tryEXTEND(SDNode *N) {
return true;
}
+// Lower a logical operation on i1 values into a GPR sequence if possible.
+// The result can be kept in a GPR if requested.
+// Three types of inputs can be handled:
+// - SETCC
+// - TRUNCATE
+// - Logical operation (AND/OR/XOR)
+// There is also a special case that is handled (namely a complement operation
+// achieved with xor %a, -1).
+SDValue PPCDAGToDAGISel::computeLogicOpInGPR(SDValue LogicOp) {
+ assert(isLogicOp(LogicOp.getOpcode()) &&
+ "Can only handle logic operations here.");
+ assert(LogicOp.getValueType() == MVT::i1 &&
+ "Can only handle logic operations on i1 values here.");
+ SDLoc dl(LogicOp);
+ SDValue LHS, RHS;
+
+ // Special case: xor %a, -1
+ bool IsBitwiseNegation = isBitwiseNot(LogicOp);
+
+ // Produces a GPR sequence for each operand of the binary logic operation.
+ // For SETCC, it produces the respective comparison, for TRUNCATE it truncates
+ // the value in a GPR and for logic operations, it will recursively produce
+ // a GPR sequence for the operation.
+ auto getLogicOperand = [&] (SDValue Operand) -> SDValue {
+ unsigned OperandOpcode = Operand.getOpcode();
+ if (OperandOpcode == ISD::SETCC)
+ return getSETCCInGPR(Operand, SetccInGPROpts::ZExtOrig);
+ else if (OperandOpcode == ISD::TRUNCATE) {
+ SDValue InputOp = Operand.getOperand(0);
+ EVT InVT = InputOp.getValueType();
+ return
+ SDValue(CurDAG->getMachineNode(InVT == MVT::i32 ? PPC::RLDICL_32 :
+ PPC::RLDICL, dl, InVT, InputOp,
+ getI64Imm(0, dl), getI64Imm(63, dl)), 0);
+ } else if (isLogicOp(OperandOpcode))
+ return computeLogicOpInGPR(Operand);
+ return SDValue();
+ };
+ LHS = getLogicOperand(LogicOp.getOperand(0));
+ RHS = getLogicOperand(LogicOp.getOperand(1));
+
+ // If a GPR sequence can't be produced for the LHS we can't proceed.
+ // Not producing a GPR sequence for the RHS is only a problem if this isn't
+ // a bitwise negation operation.
+ if (!LHS || (!RHS && !IsBitwiseNegation))
+ return SDValue();
+
+ NumLogicOpsOnComparison++;
+
+ // We will use the inputs as 64-bit values.
+ if (LHS.getValueType() == MVT::i32)
+ LHS = addExtOrTrunc(LHS, ExtOrTruncConversion::Ext);
+ if (!IsBitwiseNegation && RHS.getValueType() == MVT::i32)
+ RHS = addExtOrTrunc(RHS, ExtOrTruncConversion::Ext);
+
+ unsigned NewOpc;
+ switch (LogicOp.getOpcode()) {
+ default: llvm_unreachable("Unknown logic operation.");
+ case ISD::AND: NewOpc = PPC::AND8; break;
+ case ISD::OR: NewOpc = PPC::OR8; break;
+ case ISD::XOR: NewOpc = PPC::XOR8; break;
+ }
+
+ if (IsBitwiseNegation) {
+ RHS = getI64Imm(1, dl);
+ NewOpc = PPC::XORI8;
+ }
+
+ return SDValue(CurDAG->getMachineNode(NewOpc, dl, MVT::i64, LHS, RHS), 0);
+
+}
+
+/// Try performing logical operations on results of comparisons in GPRs.
+/// It is typically preferred from a performance perspective over performing
+/// the operations on individual bits in the CR. We only do this on 64-bit
+/// targets for now as the code is specialized for 64-bit (it uses 64-bit
+/// instructions and assumes 64-bit registers).
+bool PPCDAGToDAGISel::tryLogicOpOfCompares(SDNode *N) {
+ if (TM.getOptLevel() == CodeGenOpt::None || !TM.isPPC64())
+ return false;
+ if (N->getValueType(0) != MVT::i1)
+ return false;
+ assert(isLogicOp(N->getOpcode()) &&
+ "Expected a logic operation on setcc results.");
+ SDValue LoweredLogical = computeLogicOpInGPR(SDValue(N, 0));
+ if (!LoweredLogical)
+ return false;
+
+ SDLoc dl(N);
+ bool IsBitwiseNegate = LoweredLogical.getMachineOpcode() == PPC::XORI8;
+ unsigned SubRegToExtract = IsBitwiseNegate ? PPC::sub_eq : PPC::sub_gt;
+ SDValue CR0Reg = CurDAG->getRegister(PPC::CR0, MVT::i32);
+ SDValue LHS = LoweredLogical.getOperand(0);
+ SDValue RHS = LoweredLogical.getOperand(1);
+ SDValue WideOp;
+ SDValue OpToConvToRecForm;
+
+ // Look through any 32-bit to 64-bit implicit extend nodes to find the opcode
+ // that is input to the XORI.
+ if (IsBitwiseNegate &&
+ LoweredLogical.getOperand(0).getMachineOpcode() == PPC::INSERT_SUBREG)
+ OpToConvToRecForm = LoweredLogical.getOperand(0).getOperand(1);
+ else if (IsBitwiseNegate)
+ // If the input to the XORI isn't an extension, that's what we're after.
+ OpToConvToRecForm = LoweredLogical.getOperand(0);
+ else
+ // If this is not an XORI, it is a reg-reg logical op and we can convert it
+ // to record-form.
+ OpToConvToRecForm = LoweredLogical;
+
+ // Get the record-form version of the node we're looking to use to get the
+ // CR result from.
+ uint16_t NonRecOpc = OpToConvToRecForm.getMachineOpcode();
+ int NewOpc = PPCInstrInfo::getRecordFormOpcode(NonRecOpc);
+
+ // Convert the right node to record-form. This is either the logical we're
+ // looking at or it is the input node to the negation (if we're looking at
+ // a bitwise negation).
+ if (NewOpc != -1 && IsBitwiseNegate) {
+ // The input to the XORI has a record-form. Use it.
+ assert(LoweredLogical.getConstantOperandVal(1) == 1 &&
+ "Expected a PPC::XORI8 only for bitwise negation.");
+ // Emit the record-form instruction.
+ std::vector<SDValue> Ops;
+ for (int i = 0, e = OpToConvToRecForm.getNumOperands(); i < e; i++)
+ Ops.push_back(OpToConvToRecForm.getOperand(i));
+
+ WideOp =
+ SDValue(CurDAG->getMachineNode(NewOpc, dl,
+ OpToConvToRecForm.getValueType(),
+ MVT::Glue, Ops), 0);
+ } else {
+ assert((NewOpc != -1 || !IsBitwiseNegate) &&
+ "No record form available for AND8/OR8/XOR8?");
+ WideOp =
+ SDValue(CurDAG->getMachineNode(NewOpc == -1 ? PPC::ANDIo8 : NewOpc, dl,
+ MVT::i64, MVT::Glue, LHS, RHS), 0);
+ }
+
+ // Select this node to a single bit from CR0 set by the record-form node
+ // just created. For bitwise negation, use the EQ bit which is the equivalent
+ // of negating the result (i.e. it is a bit set when the result of the
+ // operation is zero).
+ SDValue SRIdxVal =
+ CurDAG->getTargetConstant(SubRegToExtract, dl, MVT::i32);
+ SDValue CRBit =
+ SDValue(CurDAG->getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl,
+ MVT::i1, CR0Reg, SRIdxVal,
+ WideOp.getValue(1)), 0);
+ ReplaceNode(N, CRBit.getNode());
+ return true;
+}
+
/// If the value isn't guaranteed to be sign-extended to 64-bits, extend it.
/// Useful when emitting comparison code for 32-bit values without using
/// the compare instruction (which only considers the lower 32-bits).
@@ -2677,6 +2853,77 @@ SDValue PPCDAGToDAGISel::get32BitSExtCompare(SDValue LHS, SDValue RHS,
}
}
+/// Produces a zero-extended result of comparing two 64-bit values according to
+/// the passed condition code.
+SDValue PPCDAGToDAGISel::get64BitZExtCompare(SDValue LHS, SDValue RHS,
+ ISD::CondCode CC,
+ int64_t RHSValue, SDLoc dl) {
+ bool IsRHSZero = RHSValue == 0;
+ switch (CC) {
+ default: return SDValue();
+ case ISD::SETEQ: {
+ // (zext (setcc %a, %b, seteq)) -> (lshr (ctlz (xor %a, %b)), 6)
+ // (zext (setcc %a, 0, seteq)) -> (lshr (ctlz %a), 6)
+ SDValue Xor = IsRHSZero ? LHS :
+ SDValue(CurDAG->getMachineNode(PPC::XOR8, dl, MVT::i64, LHS, RHS), 0);
+ SDValue Clz =
+ SDValue(CurDAG->getMachineNode(PPC::CNTLZD, dl, MVT::i64, Xor), 0);
+ return SDValue(CurDAG->getMachineNode(PPC::RLDICL, dl, MVT::i64, Clz,
+ getI64Imm(58, dl), getI64Imm(63, dl)),
+ 0);
+ }
+ }
+}
+
+/// Produces a sign-extended result of comparing two 64-bit values according to
+/// the passed condition code.
+SDValue PPCDAGToDAGISel::get64BitSExtCompare(SDValue LHS, SDValue RHS,
+ ISD::CondCode CC,
+ int64_t RHSValue, SDLoc dl) {
+ bool IsRHSZero = RHSValue == 0;
+ switch (CC) {
+ default: return SDValue();
+ case ISD::SETEQ: {
+ // {addc.reg, addc.CA} = (addcarry (xor %a, %b), -1)
+ // (sext (setcc %a, %b, seteq)) -> (sube addc.reg, addc.reg, addc.CA)
+ // {addcz.reg, addcz.CA} = (addcarry %a, -1)
+ // (sext (setcc %a, 0, seteq)) -> (sube addcz.reg, addcz.reg, addcz.CA)
+ SDValue AddInput = IsRHSZero ? LHS :
+ SDValue(CurDAG->getMachineNode(PPC::XOR8, dl, MVT::i64, LHS, RHS), 0);
+ SDValue Addic =
+ SDValue(CurDAG->getMachineNode(PPC::ADDIC8, dl, MVT::i64, MVT::Glue,
+ AddInput, getI32Imm(~0U, dl)), 0);
+ return SDValue(CurDAG->getMachineNode(PPC::SUBFE8, dl, MVT::i64, Addic,
+ Addic, Addic.getValue(1)), 0);
+ }
+ }
+}
+
+/// Does this SDValue have any uses for which keeping the value in a GPR is
+/// appropriate. This is meant to be used on values that have type i1 since
+/// it is somewhat meaningless to ask if values of other types can be kept in
+/// GPR's.
+static bool allUsesExtend(SDValue Compare, SelectionDAG *CurDAG) {
+ assert(Compare.getOpcode() == ISD::SETCC &&
+ "An ISD::SETCC node required here.");
+
+ // For values that have a single use, the caller should obviously already have
+ // checked if that use is an extending use. We check the other uses here.
+ if (Compare.hasOneUse())
+ return true;
+ // We want the value in a GPR if it is being extended, used for a select, or
+ // used in logical operations.
+ for (auto CompareUse : Compare.getNode()->uses())
+ if (CompareUse->getOpcode() != ISD::SIGN_EXTEND &&
+ CompareUse->getOpcode() != ISD::ZERO_EXTEND &&
+ CompareUse->getOpcode() != ISD::SELECT &&
+ !isLogicOp(CompareUse->getOpcode())) {
+ OmittedForNonExtendUses++;
+ return false;
+ }
+ return true;
+}
+
/// Returns an equivalent of a SETCC node but with the result the same width as
/// the inputs. This can nalso be used for SELECT_CC if either the true or false
/// values is a power of two while the other is zero.
@@ -2686,6 +2933,11 @@ SDValue PPCDAGToDAGISel::getSETCCInGPR(SDValue Compare,
Compare.getOpcode() == ISD::SELECT_CC) &&
"An ISD::SETCC node required here.");
+ // Don't convert this comparison to a GPR sequence because there are uses
+ // of the i1 result (i.e. uses that require the result in the CR).
+ if ((Compare.getOpcode() == ISD::SETCC) && !allUsesExtend(Compare, CurDAG))
+ return SDValue();
+
SDValue LHS = Compare.getOperand(0);
SDValue RHS = Compare.getOperand(1);
@@ -2694,30 +2946,35 @@ SDValue PPCDAGToDAGISel::getSETCCInGPR(SDValue Compare,
ISD::CondCode CC =
cast<CondCodeSDNode>(Compare.getOperand(CCOpNum))->get();
EVT InputVT = LHS.getValueType();
- if (InputVT != MVT::i32)
+ if (InputVT != MVT::i32 && InputVT != MVT::i64)
return SDValue();
- SDLoc dl(Compare);
- ConstantSDNode *RHSConst = dyn_cast<ConstantSDNode>(RHS);
- int64_t RHSValue = RHSConst ? RHSConst->getSExtValue() : INT64_MAX;
-
if (ConvOpts == SetccInGPROpts::ZExtInvert ||
ConvOpts == SetccInGPROpts::SExtInvert)
CC = ISD::getSetCCInverse(CC, true);
- if (ISD::isSignedIntSetCC(CC)) {
+ bool Inputs32Bit = InputVT == MVT::i32;
+ if (ISD::isSignedIntSetCC(CC) && Inputs32Bit) {
LHS = signExtendInputIfNeeded(LHS);
RHS = signExtendInputIfNeeded(RHS);
- } else if (ISD::isUnsignedIntSetCC(CC)) {
+ } else if (ISD::isUnsignedIntSetCC(CC) && Inputs32Bit) {
LHS = zeroExtendInputIfNeeded(LHS);
RHS = zeroExtendInputIfNeeded(RHS);
}
+ SDLoc dl(Compare);
+ ConstantSDNode *RHSConst = dyn_cast<ConstantSDNode>(RHS);
+ int64_t RHSValue = RHSConst ? RHSConst->getSExtValue() : INT64_MAX;
bool IsSext = ConvOpts == SetccInGPROpts::SExtOrig ||
ConvOpts == SetccInGPROpts::SExtInvert;
- if (IsSext)
+
+ if (IsSext && Inputs32Bit)
return get32BitSExtCompare(LHS, RHS, CC, RHSValue, dl);
- return get32BitZExtCompare(LHS, RHS, CC, RHSValue, dl);
+ else if (Inputs32Bit)
+ return get32BitZExtCompare(LHS, RHS, CC, RHSValue, dl);
+ else if (IsSext)
+ return get64BitSExtCompare(LHS, RHS, CC, RHSValue, dl);
+ return get64BitZExtCompare(LHS, RHS, CC, RHSValue, dl);
}
void PPCDAGToDAGISel::transferMemOperands(SDNode *N, SDNode *Result) {
@@ -2906,6 +3163,9 @@ void PPCDAGToDAGISel::Select(SDNode *N) {
}
case ISD::AND: {
+ if (tryLogicOpOfCompares(N))
+ return;
+
unsigned Imm, Imm2, SH, MB, ME;
uint64_t Imm64;
@@ -3025,6 +3285,9 @@ void PPCDAGToDAGISel::Select(SDNode *N) {
if (tryBitfieldInsert(N))
return;
+ if (tryLogicOpOfCompares(N))
+ return;
+
short Imm;
if (N->getOperand(0)->getOpcode() == ISD::FrameIndex &&
isIntS16Immediate(N->getOperand(1), Imm)) {
@@ -3042,6 +3305,11 @@ void PPCDAGToDAGISel::Select(SDNode *N) {
// Other cases are autogenerated.
break;
}
+ case ISD::XOR: {
+ if (tryLogicOpOfCompares(N))
+ return;
+ break;
+ }
case ISD::ADD: {
short Imm;
if (N->getOperand(0)->getOpcode() == ISD::FrameIndex &&
diff --git a/contrib/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/contrib/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index 216efcc4a1ee..41ff9d903aa0 100644
--- a/contrib/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/contrib/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -1041,6 +1041,10 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
MaxStoresPerMemset = 128;
MaxStoresPerMemcpy = 128;
MaxStoresPerMemmove = 128;
+ MaxLoadsPerMemcmp = 128;
+ } else {
+ MaxLoadsPerMemcmp = 8;
+ MaxLoadsPerMemcmpOptSize = 4;
}
}
@@ -1112,6 +1116,7 @@ const char *PPCTargetLowering::getTargetNodeName(unsigned Opcode) const {
case PPCISD::VPERM: return "PPCISD::VPERM";
case PPCISD::XXSPLT: return "PPCISD::XXSPLT";
case PPCISD::XXINSERT: return "PPCISD::XXINSERT";
+ case PPCISD::XXPERMDI: return "PPCISD::XXPERMDI";
case PPCISD::VECSHL: return "PPCISD::VECSHL";
case PPCISD::CMPB: return "PPCISD::CMPB";
case PPCISD::Hi: return "PPCISD::Hi";
@@ -1593,17 +1598,25 @@ bool PPC::isSplatShuffleMask(ShuffleVectorSDNode *N, unsigned EltSize) {
return true;
}
- // Check that the mask is shuffling words
-static bool isWordShuffleMask(ShuffleVectorSDNode *N) {
- for (unsigned i = 0; i < 4; ++i) {
- unsigned B0 = N->getMaskElt(i*4);
- unsigned B1 = N->getMaskElt(i*4+1);
- unsigned B2 = N->getMaskElt(i*4+2);
- unsigned B3 = N->getMaskElt(i*4+3);
- if (B0 % 4)
- return false;
- if (B1 != B0+1 || B2 != B1+1 || B3 != B2+1)
+// Check that the mask is shuffling N byte elements.
+static bool isNByteElemShuffleMask(ShuffleVectorSDNode *N, unsigned Width) {
+ assert((Width == 2 || Width == 4 || Width == 8 || Width == 16) &&
+ "Unexpected element width.");
+
+ unsigned NumOfElem = 16 / Width;
+ unsigned MaskVal[16]; // Width is never greater than 16
+ for (unsigned i = 0; i < NumOfElem; ++i) {
+ MaskVal[0] = N->getMaskElt(i * Width);
+ if (MaskVal[0] % Width) {
return false;
+ }
+
+ for (unsigned int j = 1; j < Width; ++j) {
+ MaskVal[j] = N->getMaskElt(i * Width + j);
+ if (MaskVal[j] != MaskVal[j-1] + 1) {
+ return false;
+ }
+ }
}
return true;
@@ -1611,7 +1624,7 @@ static bool isWordShuffleMask(ShuffleVectorSDNode *N) {
bool PPC::isXXINSERTWMask(ShuffleVectorSDNode *N, unsigned &ShiftElts,
unsigned &InsertAtByte, bool &Swap, bool IsLE) {
- if (!isWordShuffleMask(N))
+ if (!isNByteElemShuffleMask(N, 4))
return false;
// Now we look at mask elements 0,4,8,12
@@ -1688,7 +1701,7 @@ bool PPC::isXXSLDWIShuffleMask(ShuffleVectorSDNode *N, unsigned &ShiftElts,
bool &Swap, bool IsLE) {
assert(N->getValueType(0) == MVT::v16i8 && "Shuffle vector expects v16i8");
// Ensure each byte index of the word is consecutive.
- if (!isWordShuffleMask(N))
+ if (!isNByteElemShuffleMask(N, 4))
return false;
// Now we look at mask elements 0,4,8,12, which are the beginning of words.
@@ -1746,6 +1759,66 @@ bool PPC::isXXSLDWIShuffleMask(ShuffleVectorSDNode *N, unsigned &ShiftElts,
}
}
+/// Can node \p N be lowered to an XXPERMDI instruction? If so, set \p Swap
+/// if the inputs to the instruction should be swapped and set \p DM to the
+/// value for the immediate.
+/// Specifically, set \p Swap to true only if \p N can be lowered to XXPERMDI
+/// AND element 0 of the result comes from the first input (LE) or second input
+/// (BE). Set \p DM to the calculated result (0-3) only if \p N can be lowered.
+/// \return true iff the given mask of shuffle node \p N is a XXPERMDI shuffle
+/// mask.
+bool PPC::isXXPERMDIShuffleMask(ShuffleVectorSDNode *N, unsigned &DM,
+ bool &Swap, bool IsLE) {
+ assert(N->getValueType(0) == MVT::v16i8 && "Shuffle vector expects v16i8");
+
+ // Ensure each byte index of the double word is consecutive.
+ if (!isNByteElemShuffleMask(N, 8))
+ return false;
+
+ unsigned M0 = N->getMaskElt(0) / 8;
+ unsigned M1 = N->getMaskElt(8) / 8;
+ assert(((M0 | M1) < 4) && "A mask element out of bounds?");
+
+ // If both vector operands for the shuffle are the same vector, the mask will
+ // contain only elements from the first one and the second one will be undef.
+ if (N->getOperand(1).isUndef()) {
+ if ((M0 | M1) < 2) {
+ DM = IsLE ? (((~M1) & 1) << 1) + ((~M0) & 1) : (M0 << 1) + (M1 & 1);
+ Swap = false;
+ return true;
+ } else
+ return false;
+ }
+
+ if (IsLE) {
+ if (M0 > 1 && M1 < 2) {
+ Swap = false;
+ } else if (M0 < 2 && M1 > 1) {
+ M0 = (M0 + 2) % 4;
+ M1 = (M1 + 2) % 4;
+ Swap = true;
+ } else
+ return false;
+
+ // Note: if control flow comes here that means Swap is already set above
+ DM = (((~M1) & 1) << 1) + ((~M0) & 1);
+ return true;
+ } else { // BE
+ if (M0 < 2 && M1 > 1) {
+ Swap = false;
+ } else if (M0 > 1 && M1 < 2) {
+ M0 = (M0 + 2) % 4;
+ M1 = (M1 + 2) % 4;
+ Swap = true;
+ } else
+ return false;
+
+ // Note: if control flow comes here that means Swap is already set above
+ DM = (M0 << 1) + (M1 & 1);
+ return true;
+ }
+}
+
/// getVSPLTImmediate - Return the appropriate VSPLT* immediate to splat the
/// specified isSplatShuffleMask VECTOR_SHUFFLE mask.
@@ -7760,6 +7833,19 @@ SDValue PPCTargetLowering::LowerVECTOR_SHUFFLE(SDValue Op,
return DAG.getNode(ISD::BITCAST, dl, MVT::v16i8, Shl);
}
+ if (Subtarget.hasVSX() &&
+ PPC::isXXPERMDIShuffleMask(SVOp, ShiftElts, Swap, isLittleEndian)) {
+ if (Swap)
+ std::swap(V1, V2);
+ SDValue Conv1 = DAG.getNode(ISD::BITCAST, dl, MVT::v2i64, V1);
+ SDValue Conv2 =
+ DAG.getNode(ISD::BITCAST, dl, MVT::v2i64, V2.isUndef() ? V1 : V2);
+
+ SDValue PermDI = DAG.getNode(PPCISD::XXPERMDI, dl, MVT::v2i64, Conv1, Conv2,
+ DAG.getConstant(ShiftElts, dl, MVT::i32));
+ return DAG.getNode(ISD::BITCAST, dl, MVT::v16i8, PermDI);
+ }
+
if (Subtarget.hasVSX()) {
if (V2.isUndef() && PPC::isSplatShuffleMask(SVOp, 4)) {
int SplatIdx = PPC::getVSPLTImmediate(SVOp, 4, DAG);
diff --git a/contrib/llvm/lib/Target/PowerPC/PPCISelLowering.h b/contrib/llvm/lib/Target/PowerPC/PPCISelLowering.h
index 2f9eb95f6de6..7982a4a9e9fb 100644
--- a/contrib/llvm/lib/Target/PowerPC/PPCISelLowering.h
+++ b/contrib/llvm/lib/Target/PowerPC/PPCISelLowering.h
@@ -90,6 +90,10 @@ namespace llvm {
///
VECSHL,
+ /// XXPERMDI - The PPC XXPERMDI instruction
+ ///
+ XXPERMDI,
+
/// The CMPB instruction (takes two operands of i32 or i64).
CMPB,
@@ -454,6 +458,10 @@ namespace llvm {
/// for a XXSLDWI instruction.
bool isXXSLDWIShuffleMask(ShuffleVectorSDNode *N, unsigned &ShiftElts,
bool &Swap, bool IsLE);
+ /// isXXPERMDIShuffleMask - Return true if this is a shuffle mask suitable
+ /// for a XXPERMDI instruction.
+ bool isXXPERMDIShuffleMask(ShuffleVectorSDNode *N, unsigned &ShiftElts,
+ bool &Swap, bool IsLE);
/// isVSLDOIShuffleMask - If this is a vsldoi shuffle mask, return the
/// shift amount, otherwise return -1.
diff --git a/contrib/llvm/lib/Target/PowerPC/PPCInstr64Bit.td b/contrib/llvm/lib/Target/PowerPC/PPCInstr64Bit.td
index 165970f9678c..295590b2acf6 100644
--- a/contrib/llvm/lib/Target/PowerPC/PPCInstr64Bit.td
+++ b/contrib/llvm/lib/Target/PowerPC/PPCInstr64Bit.td
@@ -735,12 +735,12 @@ def RLDICL_32_64 : MDForm_1<30, 0,
"rldicl $rA, $rS, $SH, $MBE", IIC_IntRotateDI,
[]>, isPPC64;
// End fast-isel.
-let isCodeGenOnly = 1 in
-def RLDICL_32 : MDForm_1<30, 0,
- (outs gprc:$rA),
- (ins gprc:$rS, u6imm:$SH, u6imm:$MBE),
- "rldicl $rA, $rS, $SH, $MBE", IIC_IntRotateDI,
- []>, isPPC64;
+let Interpretation64Bit = 1, isCodeGenOnly = 1 in
+defm RLDICL_32 : MDForm_1r<30, 0,
+ (outs gprc:$rA),
+ (ins gprc:$rS, u6imm:$SH, u6imm:$MBE),
+ "rldicl", "$rA, $rS, $SH, $MBE", IIC_IntRotateDI,
+ []>, isPPC64;
defm RLDICR : MDForm_1r<30, 1,
(outs g8rc:$rA), (ins g8rc:$rS, u6imm:$SH, u6imm:$MBE),
"rldicr", "$rA, $rS, $SH, $MBE", IIC_IntRotateDI,
diff --git a/contrib/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp b/contrib/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp
index fd6785e963a6..f3c68c443b1b 100644
--- a/contrib/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp
+++ b/contrib/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp
@@ -1983,3 +1983,7 @@ PPCInstrInfo::updatedRC(const TargetRegisterClass *RC) const {
return &PPC::VSRCRegClass;
return RC;
}
+
+int PPCInstrInfo::getRecordFormOpcode(unsigned Opcode) {
+ return PPC::getRecordFormOpcode(Opcode);
+}
diff --git a/contrib/llvm/lib/Target/PowerPC/PPCInstrInfo.h b/contrib/llvm/lib/Target/PowerPC/PPCInstrInfo.h
index b30d09e03ec4..8dd4dbb60879 100644
--- a/contrib/llvm/lib/Target/PowerPC/PPCInstrInfo.h
+++ b/contrib/llvm/lib/Target/PowerPC/PPCInstrInfo.h
@@ -290,6 +290,7 @@ public:
return Reg >= PPC::V0 && Reg <= PPC::V31;
}
const TargetRegisterClass *updatedRC(const TargetRegisterClass *RC) const;
+ static int getRecordFormOpcode(unsigned Opcode);
};
}
diff --git a/contrib/llvm/lib/Target/PowerPC/PPCInstrInfo.td b/contrib/llvm/lib/Target/PowerPC/PPCInstrInfo.td
index 26b99eced23c..8223aa655e38 100644
--- a/contrib/llvm/lib/Target/PowerPC/PPCInstrInfo.td
+++ b/contrib/llvm/lib/Target/PowerPC/PPCInstrInfo.td
@@ -53,6 +53,10 @@ def SDT_PPCVecInsert : SDTypeProfile<1, 3, [ SDTCisVec<0>,
SDTCisVec<1>, SDTCisVec<2>, SDTCisInt<3>
]>;
+def SDT_PPCxxpermdi: SDTypeProfile<1, 3, [ SDTCisVec<0>,
+ SDTCisVec<1>, SDTCisVec<2>, SDTCisInt<3>
+]>;
+
def SDT_PPCvcmp : SDTypeProfile<1, 3, [
SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>, SDTCisVT<3, i32>
]>;
@@ -170,6 +174,7 @@ def PPCaddiDtprelL : SDNode<"PPCISD::ADDI_DTPREL_L", SDTIntBinOp>;
def PPCvperm : SDNode<"PPCISD::VPERM", SDT_PPCvperm, []>;
def PPCxxsplt : SDNode<"PPCISD::XXSPLT", SDT_PPCVecSplat, []>;
def PPCxxinsert : SDNode<"PPCISD::XXINSERT", SDT_PPCVecInsert, []>;
+def PPCxxpermdi : SDNode<"PPCISD::XXPERMDI", SDT_PPCxxpermdi, []>;
def PPCvecshl : SDNode<"PPCISD::VECSHL", SDT_PPCVecShift, []>;
def PPCqvfperm : SDNode<"PPCISD::QVFPERM", SDT_PPCqvfperm, []>;
diff --git a/contrib/llvm/lib/Target/PowerPC/PPCInstrVSX.td b/contrib/llvm/lib/Target/PowerPC/PPCInstrVSX.td
index 1589ab03e507..c4139ca8b7bd 100644
--- a/contrib/llvm/lib/Target/PowerPC/PPCInstrVSX.td
+++ b/contrib/llvm/lib/Target/PowerPC/PPCInstrVSX.td
@@ -843,7 +843,9 @@ let Uses = [RM] in {
def XXPERMDI : XX3Form_2<60, 10,
(outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB, u2imm:$DM),
- "xxpermdi $XT, $XA, $XB, $DM", IIC_VecPerm, []>;
+ "xxpermdi $XT, $XA, $XB, $DM", IIC_VecPerm,
+ [(set v2i64:$XT, (PPCxxpermdi v2i64:$XA, v2i64:$XB,
+ imm32SExt16:$DM))]>;
let isCodeGenOnly = 1 in
def XXPERMDIs : XX3Form_2s<60, 10, (outs vsrc:$XT), (ins vsfrc:$XA, u2imm:$DM),
"xxpermdi $XT, $XA, $XA, $DM", IIC_VecPerm, []>;
diff --git a/contrib/llvm/lib/Target/PowerPC/PPCTargetMachine.cpp b/contrib/llvm/lib/Target/PowerPC/PPCTargetMachine.cpp
index ddae5befee3e..b9004cc8a9f5 100644
--- a/contrib/llvm/lib/Target/PowerPC/PPCTargetMachine.cpp
+++ b/contrib/llvm/lib/Target/PowerPC/PPCTargetMachine.cpp
@@ -296,7 +296,7 @@ namespace {
/// PPC Code Generator Pass Configuration Options.
class PPCPassConfig : public TargetPassConfig {
public:
- PPCPassConfig(PPCTargetMachine *TM, PassManagerBase &PM)
+ PPCPassConfig(PPCTargetMachine &TM, PassManagerBase &PM)
: TargetPassConfig(TM, PM) {}
PPCTargetMachine &getPPCTargetMachine() const {
@@ -316,7 +316,7 @@ public:
} // end anonymous namespace
TargetPassConfig *PPCTargetMachine::createPassConfig(PassManagerBase &PM) {
- return new PPCPassConfig(this, PM);
+ return new PPCPassConfig(*this, PM);
}
void PPCPassConfig::addIRPasses() {
diff --git a/contrib/llvm/lib/Target/PowerPC/PPCTargetMachine.h b/contrib/llvm/lib/Target/PowerPC/PPCTargetMachine.h
index f2838351cee5..b8f5a2083d80 100644
--- a/contrib/llvm/lib/Target/PowerPC/PPCTargetMachine.h
+++ b/contrib/llvm/lib/Target/PowerPC/PPCTargetMachine.h
@@ -55,6 +55,10 @@ public:
const Triple &TT = getTargetTriple();
return (TT.getArch() == Triple::ppc64 || TT.getArch() == Triple::ppc64le);
};
+
+ bool isMachineVerifierClean() const override {
+ return false;
+ }
};
/// PowerPC 32-bit target machine.
diff --git a/contrib/llvm/lib/Target/PowerPC/PPCTargetTransformInfo.cpp b/contrib/llvm/lib/Target/PowerPC/PPCTargetTransformInfo.cpp
index 7ee1317bf72f..5559cdc5fe46 100644
--- a/contrib/llvm/lib/Target/PowerPC/PPCTargetTransformInfo.cpp
+++ b/contrib/llvm/lib/Target/PowerPC/PPCTargetTransformInfo.cpp
@@ -215,6 +215,11 @@ bool PPCTTIImpl::enableAggressiveInterleaving(bool LoopHasReductions) {
return LoopHasReductions;
}
+bool PPCTTIImpl::expandMemCmp(Instruction *I, unsigned &MaxLoadSize) {
+ MaxLoadSize = 8;
+ return true;
+}
+
bool PPCTTIImpl::enableInterleavedAccessVectorization() {
return true;
}
@@ -239,9 +244,18 @@ unsigned PPCTTIImpl::getRegisterBitWidth(bool Vector) {
}
unsigned PPCTTIImpl::getCacheLineSize() {
- // This is currently only used for the data prefetch pass which is only
- // enabled for BG/Q by default.
- return CacheLineSize;
+ // Check first if the user specified a custom line size.
+ if (CacheLineSize.getNumOccurrences() > 0)
+ return CacheLineSize;
+
+ // On P7, P8 or P9 we have a cache line size of 128.
+ unsigned Directive = ST->getDarwinDirective();
+ if (Directive == PPC::DIR_PWR7 || Directive == PPC::DIR_PWR8 ||
+ Directive == PPC::DIR_PWR9)
+ return 128;
+
+ // On other processors return a default of 64 bytes.
+ return 64;
}
unsigned PPCTTIImpl::getPrefetchDistance() {
diff --git a/contrib/llvm/lib/Target/PowerPC/PPCTargetTransformInfo.h b/contrib/llvm/lib/Target/PowerPC/PPCTargetTransformInfo.h
index 6ce70fbd8778..2e0116fee04c 100644
--- a/contrib/llvm/lib/Target/PowerPC/PPCTargetTransformInfo.h
+++ b/contrib/llvm/lib/Target/PowerPC/PPCTargetTransformInfo.h
@@ -60,6 +60,7 @@ public:
/// @{
bool enableAggressiveInterleaving(bool LoopHasReductions);
+ bool expandMemCmp(Instruction *I, unsigned &MaxLoadSize);
bool enableInterleavedAccessVectorization();
unsigned getNumberOfRegisters(bool Vector);
unsigned getRegisterBitWidth(bool Vector);
diff --git a/contrib/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp b/contrib/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp
index a20331cd0a3e..efdde04c582d 100644
--- a/contrib/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp
+++ b/contrib/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp
@@ -56,5 +56,5 @@ RISCVTargetMachine::RISCVTargetMachine(const Target &T, const Triple &TT,
}
TargetPassConfig *RISCVTargetMachine::createPassConfig(PassManagerBase &PM) {
- return new TargetPassConfig(this, PM);
+ return new TargetPassConfig(*this, PM);
}
diff --git a/contrib/llvm/lib/Target/Sparc/SparcTargetMachine.cpp b/contrib/llvm/lib/Target/Sparc/SparcTargetMachine.cpp
index 1da4d3604304..49c67e0819f7 100644
--- a/contrib/llvm/lib/Target/Sparc/SparcTargetMachine.cpp
+++ b/contrib/llvm/lib/Target/Sparc/SparcTargetMachine.cpp
@@ -114,7 +114,7 @@ namespace {
/// Sparc Code Generator Pass Configuration Options.
class SparcPassConfig : public TargetPassConfig {
public:
- SparcPassConfig(SparcTargetMachine *TM, PassManagerBase &PM)
+ SparcPassConfig(SparcTargetMachine &TM, PassManagerBase &PM)
: TargetPassConfig(TM, PM) {}
SparcTargetMachine &getSparcTargetMachine() const {
@@ -128,7 +128,7 @@ public:
} // namespace
TargetPassConfig *SparcTargetMachine::createPassConfig(PassManagerBase &PM) {
- return new SparcPassConfig(this, PM);
+ return new SparcPassConfig(*this, PM);
}
void SparcPassConfig::addIRPasses() {
diff --git a/contrib/llvm/lib/Target/Sparc/SparcTargetMachine.h b/contrib/llvm/lib/Target/Sparc/SparcTargetMachine.h
index 48193fe095be..faf714cbe2c9 100644
--- a/contrib/llvm/lib/Target/Sparc/SparcTargetMachine.h
+++ b/contrib/llvm/lib/Target/Sparc/SparcTargetMachine.h
@@ -40,6 +40,10 @@ public:
TargetLoweringObjectFile *getObjFileLowering() const override {
return TLOF.get();
}
+
+ bool isMachineVerifierClean() const override {
+ return false;
+ }
};
/// Sparc 32-bit target machine
diff --git a/contrib/llvm/lib/Target/SystemZ/SystemZTargetMachine.cpp b/contrib/llvm/lib/Target/SystemZ/SystemZTargetMachine.cpp
index ede5005fa491..f30d52f859d7 100644
--- a/contrib/llvm/lib/Target/SystemZ/SystemZTargetMachine.cpp
+++ b/contrib/llvm/lib/Target/SystemZ/SystemZTargetMachine.cpp
@@ -119,7 +119,7 @@ namespace {
/// SystemZ Code Generator Pass Configuration Options.
class SystemZPassConfig : public TargetPassConfig {
public:
- SystemZPassConfig(SystemZTargetMachine *TM, PassManagerBase &PM)
+ SystemZPassConfig(SystemZTargetMachine &TM, PassManagerBase &PM)
: TargetPassConfig(TM, PM) {}
SystemZTargetMachine &getSystemZTargetMachine() const {
@@ -212,7 +212,7 @@ void SystemZPassConfig::addPreEmitPass() {
}
TargetPassConfig *SystemZTargetMachine::createPassConfig(PassManagerBase &PM) {
- return new SystemZPassConfig(this, PM);
+ return new SystemZPassConfig(*this, PM);
}
TargetIRAnalysis SystemZTargetMachine::getTargetIRAnalysis() {
diff --git a/contrib/llvm/lib/Target/SystemZ/SystemZTargetMachine.h b/contrib/llvm/lib/Target/SystemZ/SystemZTargetMachine.h
index a10ca64fa632..eb2f17a2091c 100644
--- a/contrib/llvm/lib/Target/SystemZ/SystemZTargetMachine.h
+++ b/contrib/llvm/lib/Target/SystemZ/SystemZTargetMachine.h
@@ -51,6 +51,8 @@ public:
}
bool targetSchedulesPostRAScheduling() const override { return true; };
+
+ bool isMachineVerifierClean() const override { return false; }
};
} // end namespace llvm
diff --git a/contrib/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp b/contrib/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
index b974681fb6af..d9b2b8743649 100644
--- a/contrib/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
+++ b/contrib/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
@@ -129,7 +129,7 @@ namespace {
/// WebAssembly Code Generator Pass Configuration Options.
class WebAssemblyPassConfig final : public TargetPassConfig {
public:
- WebAssemblyPassConfig(WebAssemblyTargetMachine *TM, PassManagerBase &PM)
+ WebAssemblyPassConfig(WebAssemblyTargetMachine &TM, PassManagerBase &PM)
: TargetPassConfig(TM, PM) {}
WebAssemblyTargetMachine &getWebAssemblyTargetMachine() const {
@@ -154,7 +154,7 @@ TargetIRAnalysis WebAssemblyTargetMachine::getTargetIRAnalysis() {
TargetPassConfig *
WebAssemblyTargetMachine::createPassConfig(PassManagerBase &PM) {
- return new WebAssemblyPassConfig(this, PM);
+ return new WebAssemblyPassConfig(*this, PM);
}
FunctionPass *WebAssemblyPassConfig::createTargetRegisterAllocator(bool) {
diff --git a/contrib/llvm/lib/Target/X86/InstPrinter/X86InstComments.cpp b/contrib/llvm/lib/Target/X86/InstPrinter/X86InstComments.cpp
index 6e062ec59347..b5a926f915af 100644
--- a/contrib/llvm/lib/Target/X86/InstPrinter/X86InstComments.cpp
+++ b/contrib/llvm/lib/Target/X86/InstPrinter/X86InstComments.cpp
@@ -587,6 +587,7 @@ bool llvm::EmitAnyX86InstComments(const MCInst *MI, raw_ostream &OS,
case X86::VPSLLDQZ256rr:
case X86::VPSLLDQZ512rr:
Src1Name = getRegName(MI->getOperand(1).getReg());
+ LLVM_FALLTHROUGH;
case X86::VPSLLDQZ128rm:
case X86::VPSLLDQZ256rm:
case X86::VPSLLDQZ512rm:
@@ -604,6 +605,7 @@ bool llvm::EmitAnyX86InstComments(const MCInst *MI, raw_ostream &OS,
case X86::VPSRLDQZ256rr:
case X86::VPSRLDQZ512rr:
Src1Name = getRegName(MI->getOperand(1).getReg());
+ LLVM_FALLTHROUGH;
case X86::VPSRLDQZ128rm:
case X86::VPSRLDQZ256rm:
case X86::VPSRLDQZ512rm:
@@ -1091,6 +1093,7 @@ bool llvm::EmitAnyX86InstComments(const MCInst *MI, raw_ostream &OS,
CASE_AVX512_INS_COMMON(BROADCASTF32X2, Z256, r)
CASE_AVX512_INS_COMMON(BROADCASTI32X2, Z256, r)
Src1Name = getRegName(MI->getOperand(NumOperands - 1).getReg());
+ LLVM_FALLTHROUGH;
CASE_AVX512_INS_COMMON(BROADCASTF32X2, Z256, m)
CASE_AVX512_INS_COMMON(BROADCASTI32X2, Z256, m)
DecodeSubVectorBroadcast(MVT::v8f32, MVT::v2f32, ShuffleMask);
@@ -1099,6 +1102,7 @@ bool llvm::EmitAnyX86InstComments(const MCInst *MI, raw_ostream &OS,
CASE_AVX512_INS_COMMON(BROADCASTF32X2, Z, r)
CASE_AVX512_INS_COMMON(BROADCASTI32X2, Z, r)
Src1Name = getRegName(MI->getOperand(NumOperands - 1).getReg());
+ LLVM_FALLTHROUGH;
CASE_AVX512_INS_COMMON(BROADCASTF32X2, Z, m)
CASE_AVX512_INS_COMMON(BROADCASTI32X2, Z, m)
DecodeSubVectorBroadcast(MVT::v16f32, MVT::v2f32, ShuffleMask);
diff --git a/contrib/llvm/lib/Target/X86/X86FloatingPoint.cpp b/contrib/llvm/lib/Target/X86/X86FloatingPoint.cpp
index 313920e02c3e..5582526541ba 100644
--- a/contrib/llvm/lib/Target/X86/X86FloatingPoint.cpp
+++ b/contrib/llvm/lib/Target/X86/X86FloatingPoint.cpp
@@ -123,18 +123,26 @@ namespace {
EdgeBundles *Bundles;
// Return a bitmask of FP registers in block's live-in list.
- static unsigned calcLiveInMask(MachineBasicBlock *MBB) {
+ static unsigned calcLiveInMask(MachineBasicBlock *MBB, bool RemoveFPs) {
unsigned Mask = 0;
- for (const auto &LI : MBB->liveins()) {
- if (LI.PhysReg < X86::FP0 || LI.PhysReg > X86::FP6)
- continue;
- Mask |= 1 << (LI.PhysReg - X86::FP0);
+ for (MachineBasicBlock::livein_iterator I = MBB->livein_begin();
+ I != MBB->livein_end(); ) {
+ MCPhysReg Reg = I->PhysReg;
+ static_assert(X86::FP6 - X86::FP0 == 6, "sequential regnums");
+ if (Reg >= X86::FP0 && Reg <= X86::FP6) {
+ Mask |= 1 << (Reg - X86::FP0);
+ if (RemoveFPs) {
+ I = MBB->removeLiveIn(I);
+ continue;
+ }
+ }
+ ++I;
}
return Mask;
}
// Partition all the CFG edges into LiveBundles.
- void bundleCFG(MachineFunction &MF);
+ void bundleCFGRecomputeKillFlags(MachineFunction &MF);
MachineBasicBlock *MBB; // Current basic block
@@ -327,7 +335,7 @@ bool FPS::runOnMachineFunction(MachineFunction &MF) {
TII = MF.getSubtarget().getInstrInfo();
// Prepare cross-MBB liveness.
- bundleCFG(MF);
+ bundleCFGRecomputeKillFlags(MF);
StackTop = 0;
@@ -375,13 +383,15 @@ bool FPS::runOnMachineFunction(MachineFunction &MF) {
/// registers live-out from a block is identical to the live-in set of all
/// successors. This is not enforced by the normal live-in lists since
/// registers may be implicitly defined, or not used by all successors.
-void FPS::bundleCFG(MachineFunction &MF) {
+void FPS::bundleCFGRecomputeKillFlags(MachineFunction &MF) {
assert(LiveBundles.empty() && "Stale data in LiveBundles");
LiveBundles.resize(Bundles->getNumBundles());
// Gather the actual live-in masks for all MBBs.
for (MachineBasicBlock &MBB : MF) {
- const unsigned Mask = calcLiveInMask(&MBB);
+ setKillFlags(MBB);
+
+ const unsigned Mask = calcLiveInMask(&MBB, false);
if (!Mask)
continue;
// Update MBB ingoing bundle mask.
@@ -396,7 +406,6 @@ bool FPS::processBasicBlock(MachineFunction &MF, MachineBasicBlock &BB) {
bool Changed = false;
MBB = &BB;
- setKillFlags(BB);
setupBlockStack();
for (MachineBasicBlock::iterator I = BB.begin(); I != BB.end(); ++I) {
@@ -453,6 +462,7 @@ bool FPS::processBasicBlock(MachineFunction &MF, MachineBasicBlock &BB) {
unsigned Reg = DeadRegs[i];
// Check if Reg is live on the stack. An inline-asm register operand that
// is in the clobber list and marked dead might not be live on the stack.
+ static_assert(X86::FP7 - X86::FP0 == 7, "sequential FP regnumbers");
if (Reg >= X86::FP0 && Reg <= X86::FP6 && isLive(Reg-X86::FP0)) {
DEBUG(dbgs() << "Register FP#" << Reg-X86::FP0 << " is dead!\n");
freeStackSlotAfter(I, Reg-X86::FP0);
@@ -506,7 +516,6 @@ void FPS::setupBlockStack() {
// Push the fixed live-in registers.
for (unsigned i = Bundle.FixCount; i > 0; --i) {
- MBB->addLiveIn(X86::ST0+i-1);
DEBUG(dbgs() << "Live-in st(" << (i-1) << "): %FP"
<< unsigned(Bundle.FixStack[i-1]) << '\n');
pushReg(Bundle.FixStack[i-1]);
@@ -515,7 +524,8 @@ void FPS::setupBlockStack() {
// Kill off unwanted live-ins. This can happen with a critical edge.
// FIXME: We could keep these live registers around as zombies. They may need
// to be revived at the end of a short block. It might save a few instrs.
- adjustLiveRegs(calcLiveInMask(MBB), MBB->begin());
+ unsigned Mask = calcLiveInMask(MBB, /*RemoveFPs=*/true);
+ adjustLiveRegs(Mask, MBB->begin());
DEBUG(MBB->dump());
}
diff --git a/contrib/llvm/lib/Target/X86/X86FrameLowering.cpp b/contrib/llvm/lib/Target/X86/X86FrameLowering.cpp
index 331e56976db7..328a80304602 100644
--- a/contrib/llvm/lib/Target/X86/X86FrameLowering.cpp
+++ b/contrib/llvm/lib/Target/X86/X86FrameLowering.cpp
@@ -1062,6 +1062,8 @@ void X86FrameLowering::emitPrologue(MachineFunction &MF,
}
if (HasFP) {
+ assert(MF.getRegInfo().isReserved(MachineFramePtr) && "FP reserved");
+
// Calculate required stack adjustment.
uint64_t FrameSize = StackSize - SlotSize;
// If required, include space for extra hidden slot for stashing base pointer.
@@ -1124,13 +1126,6 @@ void X86FrameLowering::emitPrologue(MachineFunction &MF,
nullptr, DwarfFramePtr));
}
}
-
- // Mark the FramePtr as live-in in every block. Don't do this again for
- // funclet prologues.
- if (!IsFunclet) {
- for (MachineBasicBlock &EveryMBB : MF)
- EveryMBB.addLiveIn(MachineFramePtr);
- }
} else {
assert(!IsFunclet && "funclets without FPs not yet implemented");
NumBytes = StackSize - X86FI->getCalleeSavedFrameSize();
diff --git a/contrib/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp b/contrib/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
index c899f0fd5100..2a1633de0a23 100644
--- a/contrib/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
+++ b/contrib/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
@@ -418,8 +418,6 @@ X86DAGToDAGISel::IsProfitableToFold(SDValue N, SDNode *U, SDNode *Root) const {
case X86ISD::XOR:
case X86ISD::OR:
case ISD::ADD:
- case ISD::ADDC:
- case ISD::ADDE:
case ISD::ADDCARRY:
case ISD::AND:
case ISD::OR:
diff --git a/contrib/llvm/lib/Target/X86/X86ISelLowering.cpp b/contrib/llvm/lib/Target/X86/X86ISelLowering.cpp
index 8d78308afe9d..0a41f35f9320 100644
--- a/contrib/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/contrib/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -1,3 +1,4 @@
+
//===-- X86ISelLowering.cpp - X86 DAG Lowering Implementation -------------===//
//
// The LLVM Compiler Infrastructure
@@ -80,12 +81,6 @@ static cl::opt<int> ExperimentalPrefLoopAlignment(
" of the loop header PC will be 0)."),
cl::Hidden);
-static cl::opt<bool> MulConstantOptimization(
- "mul-constant-optimization", cl::init(true),
- cl::desc("Replace 'mul x, Const' with more effective instructions like "
- "SHIFT, LEA, etc."),
- cl::Hidden);
-
/// Call this when the user attempts to do something unsupported, like
/// returning a double without SSE2 enabled on x86_64. This is not fatal, unlike
/// report_fatal_error, so calling code should attempt to recover without
@@ -317,16 +312,6 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
setOperationAction(ISD::UREM, VT, Expand);
}
- for (auto VT : { MVT::i8, MVT::i16, MVT::i32, MVT::i64 }) {
- if (VT == MVT::i64 && !Subtarget.is64Bit())
- continue;
- // Add/Sub overflow ops with MVT::Glues are lowered to EFLAGS dependences.
- setOperationAction(ISD::ADDC, VT, Custom);
- setOperationAction(ISD::ADDE, VT, Custom);
- setOperationAction(ISD::SUBC, VT, Custom);
- setOperationAction(ISD::SUBE, VT, Custom);
- }
-
setOperationAction(ISD::BR_JT , MVT::Other, Expand);
setOperationAction(ISD::BRCOND , MVT::Other, Custom);
for (auto VT : { MVT::f32, MVT::f64, MVT::f80, MVT::f128,
@@ -428,7 +413,6 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
continue;
setOperationAction(ISD::SELECT, VT, Custom);
setOperationAction(ISD::SETCC, VT, Custom);
- setOperationAction(ISD::SETCCE, VT, Custom);
}
setOperationAction(ISD::EH_RETURN , MVT::Other, Custom);
// NOTE: EH_SJLJ_SETJMP/_LONGJMP supported here is NOT intended to support
@@ -1583,6 +1567,7 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
// Support carry in as value rather than glue.
setOperationAction(ISD::ADDCARRY, VT, Custom);
setOperationAction(ISD::SUBCARRY, VT, Custom);
+ setOperationAction(ISD::SETCCCARRY, VT, Custom);
}
if (!Subtarget.is64Bit()) {
@@ -16304,6 +16289,7 @@ SDValue X86TargetLowering::EmitTest(SDValue Op, unsigned X86CC, const SDLoc &dl,
case ISD::SHL:
if (Op.getNode()->getFlags().hasNoSignedWrap())
break;
+ LLVM_FALLTHROUGH;
default:
NeedOF = true;
break;
@@ -17167,17 +17153,17 @@ static SDValue LowerVSETCC(SDValue Op, const X86Subtarget &Subtarget,
switch (SetCCOpcode) {
default: llvm_unreachable("Unexpected SETCC condition");
- case ISD::SETNE: Invert = true;
+ case ISD::SETNE: Invert = true; LLVM_FALLTHROUGH;
case ISD::SETEQ: Opc = X86ISD::PCMPEQ; break;
- case ISD::SETLT: Swap = true;
+ case ISD::SETLT: Swap = true; LLVM_FALLTHROUGH;
case ISD::SETGT: Opc = X86ISD::PCMPGT; break;
- case ISD::SETGE: Swap = true;
+ case ISD::SETGE: Swap = true; LLVM_FALLTHROUGH;
case ISD::SETLE: Opc = X86ISD::PCMPGT;
Invert = true; break;
- case ISD::SETULT: Swap = true;
+ case ISD::SETULT: Swap = true; LLVM_FALLTHROUGH;
case ISD::SETUGT: Opc = X86ISD::PCMPGT;
FlipSigns = true; break;
- case ISD::SETUGE: Swap = true;
+ case ISD::SETUGE: Swap = true; LLVM_FALLTHROUGH;
case ISD::SETULE: Opc = X86ISD::PCMPGT;
FlipSigns = true; Invert = true; break;
}
@@ -17398,19 +17384,24 @@ SDValue X86TargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) const {
return SetCC;
}
-SDValue X86TargetLowering::LowerSETCCE(SDValue Op, SelectionDAG &DAG) const {
+SDValue X86TargetLowering::LowerSETCCCARRY(SDValue Op, SelectionDAG &DAG) const {
SDValue LHS = Op.getOperand(0);
SDValue RHS = Op.getOperand(1);
SDValue Carry = Op.getOperand(2);
SDValue Cond = Op.getOperand(3);
SDLoc DL(Op);
- assert(LHS.getSimpleValueType().isInteger() && "SETCCE is integer only.");
+ assert(LHS.getSimpleValueType().isInteger() && "SETCCCARRY is integer only.");
X86::CondCode CC = TranslateIntegerX86CC(cast<CondCodeSDNode>(Cond)->get());
- assert(Carry.getOpcode() != ISD::CARRY_FALSE);
+ // Recreate the carry if needed.
+ EVT CarryVT = Carry.getValueType();
+ APInt NegOne = APInt::getAllOnesValue(CarryVT.getScalarSizeInBits());
+ Carry = DAG.getNode(X86ISD::ADD, DL, DAG.getVTList(CarryVT, MVT::i32),
+ Carry, DAG.getConstant(NegOne, DL, CarryVT));
+
SDVTList VTs = DAG.getVTList(LHS.getValueType(), MVT::i32);
- SDValue Cmp = DAG.getNode(X86ISD::SBB, DL, VTs, LHS, RHS, Carry);
+ SDValue Cmp = DAG.getNode(X86ISD::SBB, DL, VTs, LHS, RHS, Carry.getValue(1));
SDValue SetCC = getSETCC(CC, Cmp.getValue(1), DL, DAG);
if (Op.getSimpleValueType() == MVT::i1)
return DAG.getNode(ISD::TRUNCATE, DL, MVT::i1, SetCC);
@@ -23269,32 +23260,6 @@ static SDValue LowerATOMIC_STORE(SDValue Op, SelectionDAG &DAG) {
return Op;
}
-static SDValue LowerADDC_ADDE_SUBC_SUBE(SDValue Op, SelectionDAG &DAG) {
- MVT VT = Op.getNode()->getSimpleValueType(0);
-
- // Let legalize expand this if it isn't a legal type yet.
- if (!DAG.getTargetLoweringInfo().isTypeLegal(VT))
- return SDValue();
-
- SDVTList VTs = DAG.getVTList(VT, MVT::i32);
-
- unsigned Opc;
- bool ExtraOp = false;
- switch (Op.getOpcode()) {
- default: llvm_unreachable("Invalid code");
- case ISD::ADDC: Opc = X86ISD::ADD; break;
- case ISD::ADDE: Opc = X86ISD::ADC; ExtraOp = true; break;
- case ISD::SUBC: Opc = X86ISD::SUB; break;
- case ISD::SUBE: Opc = X86ISD::SBB; ExtraOp = true; break;
- }
-
- if (!ExtraOp)
- return DAG.getNode(Opc, SDLoc(Op), VTs, Op.getOperand(0),
- Op.getOperand(1));
- return DAG.getNode(Opc, SDLoc(Op), VTs, Op.getOperand(0),
- Op.getOperand(1), Op.getOperand(2));
-}
-
static SDValue LowerADDSUBCARRY(SDValue Op, SelectionDAG &DAG) {
SDNode *N = Op.getNode();
MVT VT = N->getSimpleValueType(0);
@@ -23785,7 +23750,7 @@ SDValue X86TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
case ISD::FCOPYSIGN: return LowerFCOPYSIGN(Op, DAG);
case ISD::FGETSIGN: return LowerFGETSIGN(Op, DAG);
case ISD::SETCC: return LowerSETCC(Op, DAG);
- case ISD::SETCCE: return LowerSETCCE(Op, DAG);
+ case ISD::SETCCCARRY: return LowerSETCCCARRY(Op, DAG);
case ISD::SELECT: return LowerSELECT(Op, DAG);
case ISD::BRCOND: return LowerBRCOND(Op, DAG);
case ISD::JumpTable: return LowerJumpTable(Op, DAG);
@@ -23830,10 +23795,6 @@ SDValue X86TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
case ISD::UMULO: return LowerXALUO(Op, DAG);
case ISD::READCYCLECOUNTER: return LowerREADCYCLECOUNTER(Op, Subtarget,DAG);
case ISD::BITCAST: return LowerBITCAST(Op, Subtarget, DAG);
- case ISD::ADDC:
- case ISD::ADDE:
- case ISD::SUBC:
- case ISD::SUBE: return LowerADDC_ADDE_SUBC_SUBE(Op, DAG);
case ISD::ADDCARRY:
case ISD::SUBCARRY: return LowerADDSUBCARRY(Op, DAG);
case ISD::ADD:
@@ -28946,12 +28907,118 @@ static SDValue XFormVExtractWithShuffleIntoLoad(SDNode *N, SelectionDAG &DAG,
EltNo);
}
+// Try to match patterns such as
+// (i16 bitcast (v16i1 x))
+// ->
+// (i16 movmsk (16i8 sext (v16i1 x)))
+// before the illegal vector is scalarized on subtargets that don't have legal
+// vxi1 types.
+static SDValue combineBitcastvxi1(SelectionDAG &DAG, SDValue BitCast,
+ const X86Subtarget &Subtarget) {
+ EVT VT = BitCast.getValueType();
+ SDValue N0 = BitCast.getOperand(0);
+ EVT VecVT = N0->getValueType(0);
+
+ if (!VT.isScalarInteger() || !VecVT.isSimple())
+ return SDValue();
+
+ // With AVX512 vxi1 types are legal and we prefer using k-regs.
+ // MOVMSK is supported in SSE2 or later.
+ if (Subtarget.hasAVX512() || !Subtarget.hasSSE2())
+ return SDValue();
+
+ // There are MOVMSK flavors for types v16i8, v32i8, v4f32, v8f32, v4f64 and
+ // v8f64. So all legal 128-bit and 256-bit vectors are covered except for
+ // v8i16 and v16i16.
+ // For these two cases, we can shuffle the upper element bytes to a
+ // consecutive sequence at the start of the vector and treat the results as
+ // v16i8 or v32i8, and for v61i8 this is the prefferable solution. However,
+ // for v16i16 this is not the case, because the shuffle is expensive, so we
+ // avoid sign-exteding to this type entirely.
+ // For example, t0 := (v8i16 sext(v8i1 x)) needs to be shuffled as:
+ // (v16i8 shuffle <0,2,4,6,8,10,12,14,u,u,...,u> (v16i8 bitcast t0), undef)
+ MVT SExtVT;
+ MVT FPCastVT = MVT::INVALID_SIMPLE_VALUE_TYPE;
+ switch (VecVT.getSimpleVT().SimpleTy) {
+ default:
+ return SDValue();
+ case MVT::v2i1:
+ SExtVT = MVT::v2i64;
+ FPCastVT = MVT::v2f64;
+ break;
+ case MVT::v4i1:
+ SExtVT = MVT::v4i32;
+ FPCastVT = MVT::v4f32;
+ // For cases such as (i4 bitcast (v4i1 setcc v4i64 v1, v2))
+ // sign-extend to a 256-bit operation to avoid truncation.
+ if (N0->getOpcode() == ISD::SETCC &&
+ N0->getOperand(0)->getValueType(0).is256BitVector() &&
+ Subtarget.hasInt256()) {
+ SExtVT = MVT::v4i64;
+ FPCastVT = MVT::v4f64;
+ }
+ break;
+ case MVT::v8i1:
+ SExtVT = MVT::v8i16;
+ // For cases such as (i8 bitcast (v8i1 setcc v8i32 v1, v2)),
+ // sign-extend to a 256-bit operation to match the compare.
+ // If the setcc operand is 128-bit, prefer sign-extending to 128-bit over
+ // 256-bit because the shuffle is cheaper than sign extending the result of
+ // the compare.
+ if (N0->getOpcode() == ISD::SETCC &&
+ N0->getOperand(0)->getValueType(0).is256BitVector() &&
+ Subtarget.hasInt256()) {
+ SExtVT = MVT::v8i32;
+ FPCastVT = MVT::v8f32;
+ }
+ break;
+ case MVT::v16i1:
+ SExtVT = MVT::v16i8;
+ // For the case (i16 bitcast (v16i1 setcc v16i16 v1, v2)),
+ // it is not profitable to sign-extend to 256-bit because this will
+ // require an extra cross-lane shuffle which is more exprensive than
+ // truncating the result of the compare to 128-bits.
+ break;
+ case MVT::v32i1:
+ // TODO: Handle pre-AVX2 cases by splitting to two v16i1's.
+ if (!Subtarget.hasInt256())
+ return SDValue();
+ SExtVT = MVT::v32i8;
+ break;
+ };
+
+ SDLoc DL(BitCast);
+ SDValue V = DAG.getSExtOrTrunc(N0, DL, SExtVT);
+ if (SExtVT == MVT::v8i16) {
+ V = DAG.getBitcast(MVT::v16i8, V);
+ V = DAG.getVectorShuffle(
+ MVT::v16i8, DL, V, DAG.getUNDEF(MVT::v16i8),
+ {0, 2, 4, 6, 8, 10, 12, 14, -1, -1, -1, -1, -1, -1, -1, -1});
+ } else
+ assert(SExtVT.getScalarType() != MVT::i16 &&
+ "Vectors of i16 must be shuffled");
+ if (FPCastVT != MVT::INVALID_SIMPLE_VALUE_TYPE)
+ V = DAG.getBitcast(FPCastVT, V);
+ V = DAG.getNode(X86ISD::MOVMSK, DL, MVT::i32, V);
+ return DAG.getZExtOrTrunc(V, DL, VT);
+}
+
static SDValue combineBitcast(SDNode *N, SelectionDAG &DAG,
+ TargetLowering::DAGCombinerInfo &DCI,
const X86Subtarget &Subtarget) {
SDValue N0 = N->getOperand(0);
EVT VT = N->getValueType(0);
EVT SrcVT = N0.getValueType();
+ // Try to match patterns such as
+ // (i16 bitcast (v16i1 x))
+ // ->
+ // (i16 movmsk (16i8 sext (v16i1 x)))
+ // before the setcc result is scalarized on subtargets that don't have legal
+ // vxi1 types.
+ if (DCI.isBeforeLegalize())
+ if (SDValue V = combineBitcastvxi1(DAG, SDValue(N, 0), Subtarget))
+ return V;
// Since MMX types are special and don't usually play with other vector types,
// it's better to handle them early to be sure we emit efficient code by
// avoiding store-load conversions.
@@ -29944,6 +30011,7 @@ static SDValue combineSelect(SDNode *N, SelectionDAG &DAG,
// Converting this to a min would handle both negative zeros and NaNs
// incorrectly, but we can swap the operands to fix both.
std::swap(LHS, RHS);
+ LLVM_FALLTHROUGH;
case ISD::SETOLT:
case ISD::SETLT:
case ISD::SETLE:
@@ -29974,6 +30042,7 @@ static SDValue combineSelect(SDNode *N, SelectionDAG &DAG,
// Converting this to a max would handle both negative zeros and NaNs
// incorrectly, but we can swap the operands to fix both.
std::swap(LHS, RHS);
+ LLVM_FALLTHROUGH;
case ISD::SETOGT:
case ISD::SETGT:
case ISD::SETGE:
@@ -30008,6 +30077,7 @@ static SDValue combineSelect(SDNode *N, SelectionDAG &DAG,
// Converting this to a min would handle both negative zeros and NaNs
// incorrectly, but we can swap the operands to fix both.
std::swap(LHS, RHS);
+ LLVM_FALLTHROUGH;
case ISD::SETOGT:
case ISD::SETGT:
case ISD::SETGE:
@@ -30036,6 +30106,7 @@ static SDValue combineSelect(SDNode *N, SelectionDAG &DAG,
// Converting this to a max would handle both negative zeros and NaNs
// incorrectly, but we can swap the operands to fix both.
std::swap(LHS, RHS);
+ LLVM_FALLTHROUGH;
case ISD::SETOLT:
case ISD::SETLT:
case ISD::SETLE:
@@ -30933,75 +31004,6 @@ static SDValue reduceVMULWidth(SDNode *N, SelectionDAG &DAG,
}
}
-static SDValue combineMulSpecial(uint64_t MulAmt, SDNode *N, SelectionDAG &DAG,
- EVT VT, SDLoc DL) {
-
- auto combineMulShlAddOrSub = [&](int Mult, int Shift, bool isAdd) {
- SDValue Result = DAG.getNode(X86ISD::MUL_IMM, DL, VT, N->getOperand(0),
- DAG.getConstant(Mult, DL, VT));
- Result = DAG.getNode(ISD::SHL, DL, VT, Result,
- DAG.getConstant(Shift, DL, MVT::i8));
- Result = DAG.getNode(isAdd ? ISD::ADD : ISD::SUB, DL, VT, N->getOperand(0),
- Result);
- return Result;
- };
-
- auto combineMulMulAddOrSub = [&](bool isAdd) {
- SDValue Result = DAG.getNode(X86ISD::MUL_IMM, DL, VT, N->getOperand(0),
- DAG.getConstant(9, DL, VT));
- Result = DAG.getNode(ISD::MUL, DL, VT, Result, DAG.getConstant(3, DL, VT));
- Result = DAG.getNode(isAdd ? ISD::ADD : ISD::SUB, DL, VT, N->getOperand(0),
- Result);
- return Result;
- };
-
- switch (MulAmt) {
- default:
- break;
- case 11:
- // mul x, 11 => add ((shl (mul x, 5), 1), x)
- return combineMulShlAddOrSub(5, 1, /*isAdd*/ true);
- case 21:
- // mul x, 21 => add ((shl (mul x, 5), 2), x)
- return combineMulShlAddOrSub(5, 2, /*isAdd*/ true);
- case 22:
- // mul x, 22 => add (add ((shl (mul x, 5), 2), x), x)
- return DAG.getNode(ISD::ADD, DL, VT, N->getOperand(0),
- combineMulShlAddOrSub(5, 2, /*isAdd*/ true));
- case 19:
- // mul x, 19 => sub ((shl (mul x, 5), 2), x)
- return combineMulShlAddOrSub(5, 2, /*isAdd*/ false);
- case 13:
- // mul x, 13 => add ((shl (mul x, 3), 2), x)
- return combineMulShlAddOrSub(3, 2, /*isAdd*/ true);
- case 23:
- // mul x, 13 => sub ((shl (mul x, 3), 3), x)
- return combineMulShlAddOrSub(3, 3, /*isAdd*/ false);
- case 14:
- // mul x, 14 => add (add ((shl (mul x, 3), 2), x), x)
- return DAG.getNode(ISD::ADD, DL, VT, N->getOperand(0),
- combineMulShlAddOrSub(3, 2, /*isAdd*/ true));
- case 26:
- // mul x, 26 => sub ((mul (mul x, 9), 3), x)
- return combineMulMulAddOrSub(/*isAdd*/ false);
- case 28:
- // mul x, 28 => add ((mul (mul x, 9), 3), x)
- return combineMulMulAddOrSub(/*isAdd*/ true);
- case 29:
- // mul x, 29 => add (add ((mul (mul x, 9), 3), x), x)
- return DAG.getNode(ISD::ADD, DL, VT, N->getOperand(0),
- combineMulMulAddOrSub(/*isAdd*/ true));
- case 30:
- // mul x, 30 => sub (sub ((shl x, 5), x), x)
- return DAG.getNode(
- ISD::SUB, DL, VT, N->getOperand(0),
- DAG.getNode(ISD::SUB, DL, VT, N->getOperand(0),
- DAG.getNode(ISD::SHL, DL, VT, N->getOperand(0),
- DAG.getConstant(5, DL, MVT::i8))));
- }
- return SDValue();
-}
-
/// Optimize a single multiply with constant into two operations in order to
/// implement it with two cheaper instructions, e.g. LEA + SHL, LEA + LEA.
static SDValue combineMul(SDNode *N, SelectionDAG &DAG,
@@ -31011,8 +31013,6 @@ static SDValue combineMul(SDNode *N, SelectionDAG &DAG,
if (DCI.isBeforeLegalize() && VT.isVector())
return reduceVMULWidth(N, DAG, Subtarget);
- if (!MulConstantOptimization)
- return SDValue();
// An imul is usually smaller than the alternative sequence.
if (DAG.getMachineFunction().getFunction()->optForMinSize())
return SDValue();
@@ -31068,8 +31068,7 @@ static SDValue combineMul(SDNode *N, SelectionDAG &DAG,
else
NewMul = DAG.getNode(X86ISD::MUL_IMM, DL, VT, NewMul,
DAG.getConstant(MulAmt2, DL, VT));
- } else if (!Subtarget.slowLEA())
- NewMul = combineMulSpecial(MulAmt, N, DAG, VT, DL);
+ }
if (!NewMul) {
assert(MulAmt != 0 &&
@@ -34558,8 +34557,7 @@ static SDValue combineX86ADD(SDNode *N, SelectionDAG &DAG,
isOneConstant(Carry.getOperand(1))))
Carry = Carry.getOperand(0);
- if (Carry.getOpcode() == ISD::SETCC ||
- Carry.getOpcode() == X86ISD::SETCC ||
+ if (Carry.getOpcode() == X86ISD::SETCC ||
Carry.getOpcode() == X86ISD::SETCC_CARRY) {
if (Carry.getConstantOperandVal(0) == X86::COND_B)
return DCI.CombineTo(N, SDValue(N, 0), Carry.getOperand(1));
@@ -35126,7 +35124,7 @@ SDValue X86TargetLowering::PerformDAGCombine(SDNode *N,
case ISD::VSELECT:
case ISD::SELECT:
case X86ISD::SHRUNKBLEND: return combineSelect(N, DAG, DCI, Subtarget);
- case ISD::BITCAST: return combineBitcast(N, DAG, Subtarget);
+ case ISD::BITCAST: return combineBitcast(N, DAG, DCI, Subtarget);
case X86ISD::CMOV: return combineCMov(N, DAG, DCI, Subtarget);
case ISD::ADD: return combineAdd(N, DAG, Subtarget);
case ISD::SUB: return combineSub(N, DAG, Subtarget);
@@ -35510,6 +35508,7 @@ TargetLowering::ConstraintWeight
switch (*constraint) {
default:
weight = TargetLowering::getSingleConstraintMatchWeight(info, constraint);
+ LLVM_FALLTHROUGH;
case 'R':
case 'q':
case 'Q':
@@ -35861,6 +35860,7 @@ X86TargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
return std::make_pair(0U, &X86::GR64RegClass);
break;
}
+ LLVM_FALLTHROUGH;
// 32-bit fallthrough
case 'Q': // Q_REGS
if (VT == MVT::i32 || VT == MVT::f32)
diff --git a/contrib/llvm/lib/Target/X86/X86ISelLowering.h b/contrib/llvm/lib/Target/X86/X86ISelLowering.h
index 18106c2eb394..f51b6641db2f 100644
--- a/contrib/llvm/lib/Target/X86/X86ISelLowering.h
+++ b/contrib/llvm/lib/Target/X86/X86ISelLowering.h
@@ -1163,7 +1163,7 @@ namespace llvm {
SDValue LowerToBT(SDValue And, ISD::CondCode CC, const SDLoc &dl,
SelectionDAG &DAG) const;
SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG) const;
- SDValue LowerSETCCE(SDValue Op, SelectionDAG &DAG) const;
+ SDValue LowerSETCCCARRY(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerSELECT(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerBRCOND(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG) const;
diff --git a/contrib/llvm/lib/Target/X86/X86InstrInfo.cpp b/contrib/llvm/lib/Target/X86/X86InstrInfo.cpp
index 33fbd41bb631..0aee30081a35 100644
--- a/contrib/llvm/lib/Target/X86/X86InstrInfo.cpp
+++ b/contrib/llvm/lib/Target/X86/X86InstrInfo.cpp
@@ -195,6 +195,7 @@ X86InstrInfo::isCoalescableExtInstr(const MachineInstr &MI,
// It's not always legal to reference the low 8-bit of the larger
// register in 32-bit mode.
return false;
+ LLVM_FALLTHROUGH;
case X86::MOVSX32rr16:
case X86::MOVZX32rr16:
case X86::MOVSX64rr16:
diff --git a/contrib/llvm/lib/Target/X86/X86TargetMachine.cpp b/contrib/llvm/lib/Target/X86/X86TargetMachine.cpp
index 53a8e83b36fc..cb21f1bd7706 100644
--- a/contrib/llvm/lib/Target/X86/X86TargetMachine.cpp
+++ b/contrib/llvm/lib/Target/X86/X86TargetMachine.cpp
@@ -323,7 +323,7 @@ namespace {
/// X86 Code Generator Pass Configuration Options.
class X86PassConfig : public TargetPassConfig {
public:
- X86PassConfig(X86TargetMachine *TM, PassManagerBase &PM)
+ X86PassConfig(X86TargetMachine &TM, PassManagerBase &PM)
: TargetPassConfig(TM, PM) {}
X86TargetMachine &getX86TargetMachine() const {
@@ -369,7 +369,7 @@ INITIALIZE_PASS(X86ExecutionDepsFix, "x86-execution-deps-fix",
"X86 Execution Dependency Fix", false, false)
TargetPassConfig *X86TargetMachine::createPassConfig(PassManagerBase &PM) {
- return new X86PassConfig(this, PM);
+ return new X86PassConfig(*this, PM);
}
void X86PassConfig::addIRPasses() {
@@ -433,6 +433,7 @@ bool X86PassConfig::addPreISel() {
void X86PassConfig::addPreRegAlloc() {
if (getOptLevel() != CodeGenOpt::None) {
+ addPass(&LiveRangeShrinkID);
addPass(createX86FixupSetCC());
addPass(createX86OptimizeLEAs());
addPass(createX86CallFrameOptimization());
diff --git a/contrib/llvm/lib/Target/X86/X86TargetMachine.h b/contrib/llvm/lib/Target/X86/X86TargetMachine.h
index cf933f52604e..1bf267d34ec2 100644
--- a/contrib/llvm/lib/Target/X86/X86TargetMachine.h
+++ b/contrib/llvm/lib/Target/X86/X86TargetMachine.h
@@ -49,6 +49,10 @@ public:
TargetLoweringObjectFile *getObjFileLowering() const override {
return TLOF.get();
}
+
+ bool isMachineVerifierClean() const override {
+ return false;
+ }
};
} // end namespace llvm
diff --git a/contrib/llvm/lib/Target/XCore/XCoreTargetMachine.cpp b/contrib/llvm/lib/Target/XCore/XCoreTargetMachine.cpp
index 2950e2efbea3..1a1cbd474888 100644
--- a/contrib/llvm/lib/Target/XCore/XCoreTargetMachine.cpp
+++ b/contrib/llvm/lib/Target/XCore/XCoreTargetMachine.cpp
@@ -54,7 +54,7 @@ namespace {
/// XCore Code Generator Pass Configuration Options.
class XCorePassConfig : public TargetPassConfig {
public:
- XCorePassConfig(XCoreTargetMachine *TM, PassManagerBase &PM)
+ XCorePassConfig(XCoreTargetMachine &TM, PassManagerBase &PM)
: TargetPassConfig(TM, PM) {}
XCoreTargetMachine &getXCoreTargetMachine() const {
@@ -70,7 +70,7 @@ public:
} // end anonymous namespace
TargetPassConfig *XCoreTargetMachine::createPassConfig(PassManagerBase &PM) {
- return new XCorePassConfig(this, PM);
+ return new XCorePassConfig(*this, PM);
}
void XCorePassConfig::addIRPasses() {
diff --git a/contrib/llvm/lib/Transforms/Coroutines/CoroCleanup.cpp b/contrib/llvm/lib/Transforms/Coroutines/CoroCleanup.cpp
index 5cf2a8c25d83..359876627fce 100644
--- a/contrib/llvm/lib/Transforms/Coroutines/CoroCleanup.cpp
+++ b/contrib/llvm/lib/Transforms/Coroutines/CoroCleanup.cpp
@@ -101,7 +101,9 @@ namespace {
struct CoroCleanup : FunctionPass {
static char ID; // Pass identification, replacement for typeid
- CoroCleanup() : FunctionPass(ID) {}
+ CoroCleanup() : FunctionPass(ID) {
+ initializeCoroCleanupPass(*PassRegistry::getPassRegistry());
+ }
std::unique_ptr<Lowerer> L;
diff --git a/contrib/llvm/lib/Transforms/Coroutines/CoroEarly.cpp b/contrib/llvm/lib/Transforms/Coroutines/CoroEarly.cpp
index b52989186165..ba05896af150 100644
--- a/contrib/llvm/lib/Transforms/Coroutines/CoroEarly.cpp
+++ b/contrib/llvm/lib/Transforms/Coroutines/CoroEarly.cpp
@@ -183,7 +183,9 @@ namespace {
struct CoroEarly : public FunctionPass {
static char ID; // Pass identification, replacement for typeid.
- CoroEarly() : FunctionPass(ID) {}
+ CoroEarly() : FunctionPass(ID) {
+ initializeCoroEarlyPass(*PassRegistry::getPassRegistry());
+ }
std::unique_ptr<Lowerer> L;
diff --git a/contrib/llvm/lib/Transforms/Coroutines/CoroElide.cpp b/contrib/llvm/lib/Transforms/Coroutines/CoroElide.cpp
index acb22449142b..42fd6d746145 100644
--- a/contrib/llvm/lib/Transforms/Coroutines/CoroElide.cpp
+++ b/contrib/llvm/lib/Transforms/Coroutines/CoroElide.cpp
@@ -258,7 +258,9 @@ static bool replaceDevirtTrigger(Function &F) {
namespace {
struct CoroElide : FunctionPass {
static char ID;
- CoroElide() : FunctionPass(ID) {}
+ CoroElide() : FunctionPass(ID) {
+ initializeCoroElidePass(*PassRegistry::getPassRegistry());
+ }
std::unique_ptr<Lowerer> L;
diff --git a/contrib/llvm/lib/Transforms/Coroutines/CoroSplit.cpp b/contrib/llvm/lib/Transforms/Coroutines/CoroSplit.cpp
index cd549e4be282..613b4a7f03e9 100644
--- a/contrib/llvm/lib/Transforms/Coroutines/CoroSplit.cpp
+++ b/contrib/llvm/lib/Transforms/Coroutines/CoroSplit.cpp
@@ -681,7 +681,9 @@ namespace {
struct CoroSplit : public CallGraphSCCPass {
static char ID; // Pass identification, replacement for typeid
- CoroSplit() : CallGraphSCCPass(ID) {}
+ CoroSplit() : CallGraphSCCPass(ID) {
+ initializeCoroSplitPass(*PassRegistry::getPassRegistry());
+ }
bool Run = false;
diff --git a/contrib/llvm/lib/Transforms/IPO/PartialInlining.cpp b/contrib/llvm/lib/Transforms/IPO/PartialInlining.cpp
index 4c417f1c55eb..bc0967448cdd 100644
--- a/contrib/llvm/lib/Transforms/IPO/PartialInlining.cpp
+++ b/contrib/llvm/lib/Transforms/IPO/PartialInlining.cpp
@@ -652,12 +652,21 @@ Function *PartialInlinerImpl::unswitchFunction(Function *F) {
// only split block when necessary:
PHINode *FirstPhi = getFirstPHI(PreReturn);
unsigned NumPredsFromEntries = OI->ReturnBlockPreds.size();
+ auto IsTrivialPhi = [](PHINode *PN) -> Value * {
+ Value *CommonValue = PN->getIncomingValue(0);
+ if (all_of(PN->incoming_values(),
+ [&](Value *V) { return V == CommonValue; }))
+ return CommonValue;
+ return nullptr;
+ };
+
if (FirstPhi && FirstPhi->getNumIncomingValues() > NumPredsFromEntries + 1) {
NewReturnBlock = NewReturnBlock->splitBasicBlock(
NewReturnBlock->getFirstNonPHI()->getIterator());
BasicBlock::iterator I = PreReturn->begin();
Instruction *Ins = &NewReturnBlock->front();
+ SmallVector<Instruction *, 4> DeadPhis;
while (I != PreReturn->end()) {
PHINode *OldPhi = dyn_cast<PHINode>(I);
if (!OldPhi)
@@ -674,8 +683,22 @@ Function *PartialInlinerImpl::unswitchFunction(Function *F) {
RetPhi->addIncoming(OldPhi->getIncomingValueForBlock(NewE), NewE);
OldPhi->removeIncomingValue(NewE);
}
+
+ // After incoming values splitting, the old phi may become trivial.
+ // Keeping the trivial phi can introduce definition inside the outline
+ // region which is live-out, causing necessary overhead (load, store
+ // arg passing etc).
+ if (auto *OldPhiVal = IsTrivialPhi(OldPhi)) {
+ OldPhi->replaceAllUsesWith(OldPhiVal);
+ DeadPhis.push_back(OldPhi);
+ }
+
++I;
}
+
+ for (auto *DP : DeadPhis)
+ DP->eraseFromParent();
+
for (auto E : OI->ReturnBlockPreds) {
BasicBlock *NewE = cast<BasicBlock>(VMap[E]);
NewE->getTerminator()->replaceUsesOfWith(PreReturn, NewReturnBlock);
diff --git a/contrib/llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp b/contrib/llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp
index 659cb9df00a2..9dede4cedd1d 100644
--- a/contrib/llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp
+++ b/contrib/llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp
@@ -6,14 +6,8 @@
// 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.
-//
-//===----------------------------------------------------------------------===//
+#include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h"
#include "llvm/Analysis/BasicAliasAnalysis.h"
#include "llvm/Analysis/ModuleSummaryAnalysis.h"
#include "llvm/Analysis/ProfileSummaryInfo.h"
@@ -436,3 +430,15 @@ ModulePass *llvm::createWriteThinLTOBitcodePass(raw_ostream &Str,
raw_ostream *ThinLinkOS) {
return new WriteThinLTOBitcode(Str, ThinLinkOS);
}
+
+PreservedAnalyses
+llvm::ThinLTOBitcodeWriterPass::run(Module &M, ModuleAnalysisManager &AM) {
+ FunctionAnalysisManager &FAM =
+ AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
+ writeThinLTOBitcode(OS, ThinLinkOS,
+ [&FAM](Function &F) -> AAResults & {
+ return FAM.getResult<AAManager>(F);
+ },
+ M, &AM.getResult<ModuleSummaryIndexAnalysis>(M));
+ return PreservedAnalyses::all();
+}
diff --git a/contrib/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/contrib/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index 92a38f26dde7..b44499ec4be9 100644
--- a/contrib/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/contrib/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -3838,24 +3838,24 @@ Instruction *InstCombiner::visitCallSite(CallSite CS) {
// Mark any parameters that are known to be non-null with the nonnull
// attribute. This is helpful for inlining calls to functions with null
// checks on their arguments.
- SmallVector<unsigned, 4> Indices;
+ SmallVector<unsigned, 4> ArgNos;
unsigned ArgNo = 0;
for (Value *V : CS.args()) {
if (V->getType()->isPointerTy() &&
!CS.paramHasAttr(ArgNo, Attribute::NonNull) &&
isKnownNonNullAt(V, CS.getInstruction(), &DT))
- Indices.push_back(ArgNo + AttributeList::FirstArgIndex);
+ ArgNos.push_back(ArgNo);
ArgNo++;
}
assert(ArgNo == CS.arg_size() && "sanity check");
- if (!Indices.empty()) {
+ if (!ArgNos.empty()) {
AttributeList AS = CS.getAttributes();
LLVMContext &Ctx = CS.getInstruction()->getContext();
- AS = AS.addAttribute(Ctx, Indices,
- Attribute::get(Ctx, Attribute::NonNull));
+ AS = AS.addParamAttribute(Ctx, ArgNos,
+ Attribute::get(Ctx, Attribute::NonNull));
CS.setAttributes(AS);
Changed = true;
}
diff --git a/contrib/llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp b/contrib/llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp
index 1e30dbf6b55a..b2d95271479c 100644
--- a/contrib/llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp
+++ b/contrib/llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp
@@ -182,6 +182,14 @@ static cl::opt<bool>
cl::desc("Use this option to turn on/off "
"memory intrinsic size profiling."));
+// Emit branch probability as optimization remarks.
+static cl::opt<bool>
+ EmitBranchProbability("pgo-emit-branch-prob", cl::init(false), cl::Hidden,
+ cl::desc("When this option is on, the annotated "
+ "branch probability will be emitted as "
+ " optimization remarks: -Rpass-analysis="
+ "pgo-instr-use"));
+
// Command line option to turn on CFG dot dump after profile annotation.
// Defined in Analysis/BlockFrequencyInfo.cpp: -pgo-view-counts
extern cl::opt<bool> PGOViewCounts;
@@ -192,6 +200,39 @@ extern cl::opt<std::string> ViewBlockFreqFuncName;
namespace {
+// Return a string describing the branch condition that can be
+// used in static branch probability heuristics:
+std::string getBranchCondString(Instruction *TI) {
+ BranchInst *BI = dyn_cast<BranchInst>(TI);
+ if (!BI || !BI->isConditional())
+ return std::string();
+
+ Value *Cond = BI->getCondition();
+ ICmpInst *CI = dyn_cast<ICmpInst>(Cond);
+ if (!CI)
+ return std::string();
+
+ std::string result;
+ raw_string_ostream OS(result);
+ OS << CmpInst::getPredicateName(CI->getPredicate()) << "_";
+ CI->getOperand(0)->getType()->print(OS, true);
+
+ Value *RHS = CI->getOperand(1);
+ ConstantInt *CV = dyn_cast<ConstantInt>(RHS);
+ if (CV) {
+ if (CV->isZero())
+ OS << "_Zero";
+ else if (CV->isOne())
+ OS << "_One";
+ else if (CV->isAllOnesValue())
+ OS << "_MinusOne";
+ else
+ OS << "_Const";
+ }
+ OS.flush();
+ return result;
+}
+
/// The select instruction visitor plays three roles specified
/// by the mode. In \c VM_counting mode, it simply counts the number of
/// select instructions. In \c VM_instrument mode, it inserts code to count
@@ -1424,6 +1465,29 @@ void setProfMetadata(Module *M, Instruction *TI, ArrayRef<uint64_t> EdgeCounts,
for (const auto &W : Weights) { dbgs() << W << " "; }
dbgs() << "\n";);
TI->setMetadata(llvm::LLVMContext::MD_prof, MDB.createBranchWeights(Weights));
+ if (EmitBranchProbability) {
+ std::string BrCondStr = getBranchCondString(TI);
+ if (BrCondStr.empty())
+ return;
+
+ unsigned WSum =
+ std::accumulate(Weights.begin(), Weights.end(), 0,
+ [](unsigned w1, unsigned w2) { return w1 + w2; });
+ uint64_t TotalCount =
+ std::accumulate(EdgeCounts.begin(), EdgeCounts.end(), 0,
+ [](uint64_t c1, uint64_t c2) { return c1 + c2; });
+ BranchProbability BP(Weights[0], WSum);
+ std::string BranchProbStr;
+ raw_string_ostream OS(BranchProbStr);
+ OS << BP;
+ OS << " (total count : " << TotalCount << ")";
+ OS.flush();
+ Function *F = TI->getParent()->getParent();
+ emitOptimizationRemarkAnalysis(
+ F->getContext(), "pgo-use-annot", *F, TI->getDebugLoc(),
+ Twine(BrCondStr) +
+ " is true with probability : " + Twine(BranchProbStr));
+ }
}
template <> struct GraphTraits<PGOUseFunc *> {
diff --git a/contrib/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp b/contrib/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
index 300085eccb0c..325b64cd8b43 100644
--- a/contrib/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
+++ b/contrib/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
@@ -7,24 +7,7 @@
//
//===----------------------------------------------------------------------===//
//
-// Coverage instrumentation that works with AddressSanitizer
-// and potentially with other Sanitizers.
-//
-// We create a Guard variable with the same linkage
-// as the function and inject this code into the entry block (SCK_Function)
-// or all blocks (SCK_BB):
-// if (Guard < 0) {
-// __sanitizer_cov(&Guard);
-// }
-// The accesses to Guard are atomic. The rest of the logic is
-// in __sanitizer_cov (it's fine to call it more than once).
-//
-// With SCK_Edge we also split critical edges this effectively
-// instrumenting all edges.
-//
-// This coverage implementation provides very limited data:
-// it only tells if a given function (block) was ever executed. No counters.
-// But for many use cases this is what we need and the added slowdown small.
+// Coverage instrumentation done on LLVM IR level, works with Sanitizers.
//
//===----------------------------------------------------------------------===//
@@ -56,9 +39,6 @@ using namespace llvm;
#define DEBUG_TYPE "sancov"
-static const char *const SanCovModuleInitName = "__sanitizer_cov_module_init";
-static const char *const SanCovName = "__sanitizer_cov";
-static const char *const SanCovWithCheckName = "__sanitizer_cov_with_check";
static const char *const SanCovTracePCIndirName =
"__sanitizer_cov_trace_pc_indir";
static const char *const SanCovTracePCName = "__sanitizer_cov_trace_pc";
@@ -84,12 +64,6 @@ static cl::opt<int> ClCoverageLevel(
"3: all blocks and critical edges"),
cl::Hidden, cl::init(0));
-static cl::opt<unsigned> ClCoverageBlockThreshold(
- "sanitizer-coverage-block-threshold",
- cl::desc("Use a callback with a guard check inside it if there are"
- " more than this number of blocks."),
- cl::Hidden, cl::init(0));
-
static cl::opt<bool> ClExperimentalTracePC("sanitizer-coverage-trace-pc",
cl::desc("Experimental pc tracing"),
cl::Hidden, cl::init(false));
@@ -151,6 +125,8 @@ SanitizerCoverageOptions OverrideFromCL(SanitizerCoverageOptions Options) {
Options.TraceGep |= ClGEPTracing;
Options.TracePC |= ClExperimentalTracePC;
Options.TracePCGuard |= ClTracePCGuard;
+ if (!Options.TracePCGuard && !Options.TracePC)
+ Options.TracePCGuard = true; // TracePCGuard is default.
Options.NoPrune |= !ClPruneBlocks;
return Options;
}
@@ -184,18 +160,10 @@ private:
ArrayRef<Instruction *> SwitchTraceTargets);
bool InjectCoverage(Function &F, ArrayRef<BasicBlock *> AllBlocks);
void CreateFunctionGuardArray(size_t NumGuards, Function &F);
- void SetNoSanitizeMetadata(Instruction *I);
- void InjectCoverageAtBlock(Function &F, BasicBlock &BB, size_t Idx,
- bool UseCalls);
- unsigned NumberOfInstrumentedBlocks() {
- return SanCovFunction->getNumUses() +
- SanCovWithCheckFunction->getNumUses();
- }
+ void InjectCoverageAtBlock(Function &F, BasicBlock &BB, size_t Idx);
StringRef getSanCovTracePCGuardSection() const;
StringRef getSanCovTracePCGuardSectionStart() const;
StringRef getSanCovTracePCGuardSectionEnd() const;
- Function *SanCovFunction;
- Function *SanCovWithCheckFunction;
Function *SanCovTracePCIndir;
Function *SanCovTracePC, *SanCovTracePCGuard;
Function *SanCovTraceCmpFunction[4];
@@ -209,7 +177,6 @@ private:
LLVMContext *C;
const DataLayout *DL;
- GlobalVariable *GuardArray;
GlobalVariable *FunctionGuardArray; // for trace-pc-guard.
bool HasSancovGuardsSection;
@@ -230,16 +197,11 @@ bool SanitizerCoverageModule::runOnModule(Module &M) {
IntptrPtrTy = PointerType::getUnqual(IntptrTy);
Type *VoidTy = Type::getVoidTy(*C);
IRBuilder<> IRB(*C);
- Type *Int8PtrTy = PointerType::getUnqual(IRB.getInt8Ty());
Int64PtrTy = PointerType::getUnqual(IRB.getInt64Ty());
Int32PtrTy = PointerType::getUnqual(IRB.getInt32Ty());
Int64Ty = IRB.getInt64Ty();
Int32Ty = IRB.getInt32Ty();
- SanCovFunction = checkSanitizerInterfaceFunction(
- M.getOrInsertFunction(SanCovName, VoidTy, Int32PtrTy));
- SanCovWithCheckFunction = checkSanitizerInterfaceFunction(
- M.getOrInsertFunction(SanCovWithCheckName, VoidTy, Int32PtrTy));
SanCovTracePCIndir = checkSanitizerInterfaceFunction(
M.getOrInsertFunction(SanCovTracePCIndirName, VoidTy, IntptrTy));
SanCovTraceCmpFunction[0] =
@@ -278,41 +240,10 @@ bool SanitizerCoverageModule::runOnModule(Module &M) {
SanCovTracePCGuard = checkSanitizerInterfaceFunction(M.getOrInsertFunction(
SanCovTracePCGuardName, VoidTy, Int32PtrTy));
- // At this point we create a dummy array of guards because we don't
- // know how many elements we will need.
- Type *Int32Ty = IRB.getInt32Ty();
-
- if (!Options.TracePCGuard)
- GuardArray =
- new GlobalVariable(M, Int32Ty, false, GlobalValue::ExternalLinkage,
- nullptr, "__sancov_gen_cov_tmp");
-
for (auto &F : M)
runOnFunction(F);
- auto N = NumberOfInstrumentedBlocks();
-
- GlobalVariable *RealGuardArray = nullptr;
- if (!Options.TracePCGuard) {
- // Now we know how many elements we need. Create an array of guards
- // with one extra element at the beginning for the size.
- Type *Int32ArrayNTy = ArrayType::get(Int32Ty, N + 1);
- RealGuardArray = new GlobalVariable(
- M, Int32ArrayNTy, false, GlobalValue::PrivateLinkage,
- Constant::getNullValue(Int32ArrayNTy), "__sancov_gen_cov");
-
- // Replace the dummy array with the real one.
- GuardArray->replaceAllUsesWith(
- IRB.CreatePointerCast(RealGuardArray, Int32PtrTy));
- GuardArray->eraseFromParent();
- }
-
// Create variable for module (compilation unit) name
- Constant *ModNameStrConst =
- ConstantDataArray::getString(M.getContext(), M.getName(), true);
- GlobalVariable *ModuleName = new GlobalVariable(
- M, ModNameStrConst->getType(), true, GlobalValue::PrivateLinkage,
- ModNameStrConst, "__sancov_gen_modname");
if (Options.TracePCGuard) {
if (HasSancovGuardsSection) {
Function *CtorFunc;
@@ -339,18 +270,7 @@ bool SanitizerCoverageModule::runOnModule(Module &M) {
appendToGlobalCtors(M, CtorFunc, SanCtorAndDtorPriority);
}
}
- } else if (!Options.TracePC) {
- Function *CtorFunc;
- std::tie(CtorFunc, std::ignore) = createSanitizerCtorAndInitFunctions(
- M, SanCovModuleCtorName, SanCovModuleInitName,
- {Int32PtrTy, IntptrTy, Int8PtrTy, Int8PtrTy},
- {IRB.CreatePointerCast(RealGuardArray, Int32PtrTy),
- ConstantInt::get(IntptrTy, N), Constant::getNullValue(Int8PtrTy),
- IRB.CreatePointerCast(ModuleName, Int8PtrTy)});
-
- appendToGlobalCtors(M, CtorFunc, SanCtorAndDtorPriority);
}
-
return true;
}
@@ -494,13 +414,12 @@ bool SanitizerCoverageModule::InjectCoverage(Function &F,
return false;
case SanitizerCoverageOptions::SCK_Function:
CreateFunctionGuardArray(1, F);
- InjectCoverageAtBlock(F, F.getEntryBlock(), 0, false);
+ InjectCoverageAtBlock(F, F.getEntryBlock(), 0);
return true;
default: {
- bool UseCalls = ClCoverageBlockThreshold < AllBlocks.size();
CreateFunctionGuardArray(AllBlocks.size(), F);
for (size_t i = 0, N = AllBlocks.size(); i < N; i++)
- InjectCoverageAtBlock(F, *AllBlocks[i], i, UseCalls);
+ InjectCoverageAtBlock(F, *AllBlocks[i], i);
return true;
}
}
@@ -517,8 +436,7 @@ void SanitizerCoverageModule::InjectCoverageForIndirectCalls(
Function &F, ArrayRef<Instruction *> IndirCalls) {
if (IndirCalls.empty())
return;
- if (!Options.TracePC && !Options.TracePCGuard)
- return;
+ assert(Options.TracePC || Options.TracePCGuard);
for (auto I : IndirCalls) {
IRBuilder<> IRB(I);
CallSite CS(I);
@@ -625,13 +543,8 @@ void SanitizerCoverageModule::InjectTraceForCmp(
}
}
-void SanitizerCoverageModule::SetNoSanitizeMetadata(Instruction *I) {
- I->setMetadata(I->getModule()->getMDKindID("nosanitize"),
- MDNode::get(*C, None));
-}
-
void SanitizerCoverageModule::InjectCoverageAtBlock(Function &F, BasicBlock &BB,
- size_t Idx, bool UseCalls) {
+ size_t Idx) {
BasicBlock::iterator IP = BB.getFirstInsertionPt();
bool IsEntryBB = &BB == &F.getEntryBlock();
DebugLoc EntryLoc;
@@ -651,47 +564,14 @@ void SanitizerCoverageModule::InjectCoverageAtBlock(Function &F, BasicBlock &BB,
if (Options.TracePC) {
IRB.CreateCall(SanCovTracePC); // gets the PC using GET_CALLER_PC.
IRB.CreateCall(EmptyAsm, {}); // Avoids callback merge.
- } else if (Options.TracePCGuard) {
+ } else {
+ assert(Options.TracePCGuard);
auto GuardPtr = IRB.CreateIntToPtr(
IRB.CreateAdd(IRB.CreatePointerCast(FunctionGuardArray, IntptrTy),
ConstantInt::get(IntptrTy, Idx * 4)),
Int32PtrTy);
- if (!UseCalls) {
- auto GuardLoad = IRB.CreateLoad(GuardPtr);
- GuardLoad->setAtomic(AtomicOrdering::Monotonic);
- GuardLoad->setAlignment(8);
- SetNoSanitizeMetadata(GuardLoad); // Don't instrument with e.g. asan.
- auto Cmp = IRB.CreateICmpNE(
- GuardLoad, Constant::getNullValue(GuardLoad->getType()));
- auto Ins = SplitBlockAndInsertIfThen(
- Cmp, &*IP, false, MDBuilder(*C).createBranchWeights(1, 100000));
- IRB.SetInsertPoint(Ins);
- IRB.SetCurrentDebugLocation(EntryLoc);
- }
IRB.CreateCall(SanCovTracePCGuard, GuardPtr);
IRB.CreateCall(EmptyAsm, {}); // Avoids callback merge.
- } else {
- Value *GuardP = IRB.CreateAdd(
- IRB.CreatePointerCast(GuardArray, IntptrTy),
- ConstantInt::get(IntptrTy, (1 + NumberOfInstrumentedBlocks()) * 4));
- GuardP = IRB.CreateIntToPtr(GuardP, Int32PtrTy);
- if (UseCalls) {
- IRB.CreateCall(SanCovWithCheckFunction, GuardP);
- } else {
- LoadInst *Load = IRB.CreateLoad(GuardP);
- Load->setAtomic(AtomicOrdering::Monotonic);
- Load->setAlignment(4);
- SetNoSanitizeMetadata(Load);
- Value *Cmp =
- IRB.CreateICmpSGE(Constant::getNullValue(Load->getType()), Load);
- Instruction *Ins = SplitBlockAndInsertIfThen(
- Cmp, &*IP, false, MDBuilder(*C).createBranchWeights(1, 100000));
- IRB.SetInsertPoint(Ins);
- IRB.SetCurrentDebugLocation(EntryLoc);
- // __sanitizer_cov gets the PC of the instruction using GET_CALLER_PC.
- IRB.CreateCall(SanCovFunction, GuardP);
- IRB.CreateCall(EmptyAsm, {}); // Avoids callback merge.
- }
}
}
diff --git a/contrib/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp b/contrib/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp
index ee493a8ec7e1..7b625b9b136e 100644
--- a/contrib/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp
+++ b/contrib/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp
@@ -305,7 +305,7 @@ static bool processSwitch(SwitchInst *SI, LazyValueInfo *LVI) {
/// Infer nonnull attributes for the arguments at the specified callsite.
static bool processCallSite(CallSite CS, LazyValueInfo *LVI) {
- SmallVector<unsigned, 4> Indices;
+ SmallVector<unsigned, 4> ArgNos;
unsigned ArgNo = 0;
for (Value *V : CS.args()) {
@@ -318,18 +318,19 @@ static bool processCallSite(CallSite CS, LazyValueInfo *LVI) {
LVI->getPredicateAt(ICmpInst::ICMP_EQ, V,
ConstantPointerNull::get(Type),
CS.getInstruction()) == LazyValueInfo::False)
- Indices.push_back(ArgNo + AttributeList::FirstArgIndex);
+ ArgNos.push_back(ArgNo);
ArgNo++;
}
assert(ArgNo == CS.arg_size() && "sanity check");
- if (Indices.empty())
+ if (ArgNos.empty())
return false;
AttributeList AS = CS.getAttributes();
LLVMContext &Ctx = CS.getInstruction()->getContext();
- AS = AS.addAttribute(Ctx, Indices, Attribute::get(Ctx, Attribute::NonNull));
+ AS = AS.addParamAttribute(Ctx, ArgNos,
+ Attribute::get(Ctx, Attribute::NonNull));
CS.setAttributes(AS);
return true;
diff --git a/contrib/llvm/lib/Transforms/Scalar/GVN.cpp b/contrib/llvm/lib/Transforms/Scalar/GVN.cpp
index 0d6e0538261d..0490d93f6455 100644
--- a/contrib/llvm/lib/Transforms/Scalar/GVN.cpp
+++ b/contrib/llvm/lib/Transforms/Scalar/GVN.cpp
@@ -80,10 +80,9 @@ MaxRecurseDepth("max-recurse-depth", cl::Hidden, cl::init(1000), cl::ZeroOrMore,
struct llvm::GVN::Expression {
uint32_t opcode;
Type *type;
- bool commutative;
SmallVector<uint32_t, 4> varargs;
- Expression(uint32_t o = ~2U) : opcode(o), commutative(false) {}
+ Expression(uint32_t o = ~2U) : opcode(o) {}
bool operator==(const Expression &other) const {
if (opcode != other.opcode)
@@ -247,7 +246,6 @@ GVN::Expression GVN::ValueTable::createExpr(Instruction *I) {
assert(I->getNumOperands() == 2 && "Unsupported commutative instruction!");
if (e.varargs[0] > e.varargs[1])
std::swap(e.varargs[0], e.varargs[1]);
- e.commutative = true;
}
if (CmpInst *C = dyn_cast<CmpInst>(I)) {
@@ -258,7 +256,6 @@ GVN::Expression GVN::ValueTable::createExpr(Instruction *I) {
Predicate = CmpInst::getSwappedPredicate(Predicate);
}
e.opcode = (C->getOpcode() << 8) | Predicate;
- e.commutative = true;
} else if (InsertValueInst *E = dyn_cast<InsertValueInst>(I)) {
for (InsertValueInst::idx_iterator II = E->idx_begin(), IE = E->idx_end();
II != IE; ++II)
@@ -284,7 +281,6 @@ GVN::Expression GVN::ValueTable::createCmpExpr(unsigned Opcode,
Predicate = CmpInst::getSwappedPredicate(Predicate);
}
e.opcode = (Opcode << 8) | Predicate;
- e.commutative = true;
return e;
}
@@ -352,25 +348,25 @@ GVN::ValueTable::~ValueTable() = default;
/// add - Insert a value into the table with a specified value number.
void GVN::ValueTable::add(Value *V, uint32_t num) {
valueNumbering.insert(std::make_pair(V, num));
- if (PHINode *PN = dyn_cast<PHINode>(V))
- NumberingPhi[num] = PN;
}
uint32_t GVN::ValueTable::lookupOrAddCall(CallInst *C) {
if (AA->doesNotAccessMemory(C)) {
Expression exp = createExpr(C);
- uint32_t e = assignExpNewValueNum(exp).first;
+ uint32_t &e = expressionNumbering[exp];
+ if (!e) e = nextValueNumber++;
valueNumbering[C] = e;
return e;
} else if (AA->onlyReadsMemory(C)) {
Expression exp = createExpr(C);
- auto ValNum = assignExpNewValueNum(exp);
- if (ValNum.second) {
- valueNumbering[C] = ValNum.first;
- return ValNum.first;
+ uint32_t &e = expressionNumbering[exp];
+ if (!e) {
+ e = nextValueNumber++;
+ valueNumbering[C] = e;
+ return e;
}
if (!MD) {
- uint32_t e = assignExpNewValueNum(exp).first;
+ e = nextValueNumber++;
valueNumbering[C] = e;
return e;
}
@@ -526,29 +522,23 @@ uint32_t GVN::ValueTable::lookupOrAdd(Value *V) {
case Instruction::ExtractValue:
exp = createExtractvalueExpr(cast<ExtractValueInst>(I));
break;
- case Instruction::PHI:
- valueNumbering[V] = nextValueNumber;
- NumberingPhi[nextValueNumber] = cast<PHINode>(V);
- return nextValueNumber++;
default:
valueNumbering[V] = nextValueNumber;
return nextValueNumber++;
}
- uint32_t e = assignExpNewValueNum(exp).first;
+ uint32_t& e = expressionNumbering[exp];
+ if (!e) e = nextValueNumber++;
valueNumbering[V] = e;
return e;
}
/// Returns the value number of the specified value. Fails if
/// the value has not yet been numbered.
-uint32_t GVN::ValueTable::lookup(Value *V, bool Verify) const {
+uint32_t GVN::ValueTable::lookup(Value *V) const {
DenseMap<Value*, uint32_t>::const_iterator VI = valueNumbering.find(V);
- if (Verify) {
- assert(VI != valueNumbering.end() && "Value not numbered?");
- return VI->second;
- }
- return (VI != valueNumbering.end()) ? VI->second : 0;
+ assert(VI != valueNumbering.end() && "Value not numbered?");
+ return VI->second;
}
/// Returns the value number of the given comparison,
@@ -559,29 +549,21 @@ uint32_t GVN::ValueTable::lookupOrAddCmp(unsigned Opcode,
CmpInst::Predicate Predicate,
Value *LHS, Value *RHS) {
Expression exp = createCmpExpr(Opcode, Predicate, LHS, RHS);
- return assignExpNewValueNum(exp).first;
+ uint32_t& e = expressionNumbering[exp];
+ if (!e) e = nextValueNumber++;
+ return e;
}
/// Remove all entries from the ValueTable.
void GVN::ValueTable::clear() {
valueNumbering.clear();
expressionNumbering.clear();
- NumberingPhi.clear();
- PhiTranslateTable.clear();
- BlockRPONumber.clear();
nextValueNumber = 1;
- Expressions.clear();
- ExprIdx.clear();
- nextExprNumber = 0;
}
/// Remove a value from the value numbering.
void GVN::ValueTable::erase(Value *V) {
- uint32_t Num = valueNumbering.lookup(V);
valueNumbering.erase(V);
- // If V is PHINode, V <--> value number is an one-to-one mapping.
- if (isa<PHINode>(V))
- NumberingPhi.erase(Num);
}
/// verifyRemoved - Verify that the value is removed from all internal data
@@ -1469,104 +1451,6 @@ bool GVN::processLoad(LoadInst *L) {
return false;
}
-/// Return a pair the first field showing the value number of \p Exp and the
-/// second field showing whether it is a value number newly created.
-std::pair<uint32_t, bool>
-GVN::ValueTable::assignExpNewValueNum(Expression &Exp) {
- uint32_t &e = expressionNumbering[Exp];
- bool CreateNewValNum = !e;
- if (CreateNewValNum) {
- Expressions.push_back(Exp);
- if (ExprIdx.size() < nextValueNumber + 1)
- ExprIdx.resize(nextValueNumber * 2);
- e = nextValueNumber;
- ExprIdx[nextValueNumber++] = nextExprNumber++;
- }
- return {e, CreateNewValNum};
-}
-
-void GVN::ValueTable::assignBlockRPONumber(Function &F) {
- uint32_t NextBlockNumber = 1;
- ReversePostOrderTraversal<Function *> RPOT(&F);
- for (BasicBlock *BB : RPOT)
- BlockRPONumber[BB] = NextBlockNumber++;
-}
-
-/// Return whether all the values related with the same \p num are
-/// defined in \p BB.
-bool GVN::ValueTable::areAllValsInBB(uint32_t Num, const BasicBlock *BB,
- GVN &Gvn) {
- LeaderTableEntry *Vals = &Gvn.LeaderTable[Num];
- while (Vals && Vals->BB == BB)
- Vals = Vals->Next;
- return !Vals;
-}
-
-/// Wrap phiTranslateImpl to provide caching functionality.
-uint32_t GVN::ValueTable::phiTranslate(const BasicBlock *Pred,
- const BasicBlock *PhiBlock, uint32_t Num,
- GVN &Gvn) {
- auto FindRes = PhiTranslateTable.find({Num, Pred});
- if (FindRes != PhiTranslateTable.end())
- return FindRes->second;
- uint32_t NewNum = phiTranslateImpl(Pred, PhiBlock, Num, Gvn);
- PhiTranslateTable.insert({{Num, Pred}, NewNum});
- return NewNum;
-}
-
-/// Translate value number \p Num using phis, so that it has the values of
-/// the phis in BB.
-uint32_t GVN::ValueTable::phiTranslateImpl(const BasicBlock *Pred,
- const BasicBlock *PhiBlock,
- uint32_t Num, GVN &Gvn) {
- if (PHINode *PN = NumberingPhi[Num]) {
- if (BlockRPONumber[Pred] >= BlockRPONumber[PhiBlock])
- return Num;
- for (unsigned i = 0; i != PN->getNumIncomingValues(); ++i) {
- if (PN->getParent() == PhiBlock && PN->getIncomingBlock(i) == Pred)
- if (uint32_t TransVal = lookup(PN->getIncomingValue(i), false))
- return TransVal;
- }
- return Num;
- }
-
- // If there is any value related with Num is defined in a BB other than
- // PhiBlock, it cannot depend on a phi in PhiBlock without going through
- // a backedge. We can do an early exit in that case to save compile time.
- if (!areAllValsInBB(Num, PhiBlock, Gvn))
- return Num;
-
- if (ExprIdx[Num] == 0 || Num >= ExprIdx.size())
- return Num;
- Expression Exp = Expressions[ExprIdx[Num]];
-
- for (unsigned i = 0; i < Exp.varargs.size(); i++) {
- // For InsertValue and ExtractValue, some varargs are index numbers
- // instead of value numbers. Those index numbers should not be
- // translated.
- if ((i > 1 && Exp.opcode == Instruction::InsertValue) ||
- (i > 0 && Exp.opcode == Instruction::ExtractValue))
- continue;
- Exp.varargs[i] = phiTranslate(Pred, PhiBlock, Exp.varargs[i], Gvn);
- }
-
- if (Exp.commutative) {
- assert(Exp.varargs.size() == 2 && "Unsupported commutative expression!");
- if (Exp.varargs[0] > Exp.varargs[1]) {
- std::swap(Exp.varargs[0], Exp.varargs[1]);
- uint32_t Opcode = Exp.opcode >> 8;
- if (Opcode == Instruction::ICmp || Opcode == Instruction::FCmp)
- Exp.opcode = (Opcode << 8) |
- CmpInst::getSwappedPredicate(
- static_cast<CmpInst::Predicate>(Exp.opcode & 255));
- }
- }
-
- if (uint32_t NewNum = expressionNumbering[Exp])
- return NewNum;
- return Num;
-}
-
// In order to find a leader for a given value number at a
// specific basic block, we first obtain the list of all Values for that number,
// and then scan the list to find one whose block dominates the block in
@@ -1972,7 +1856,6 @@ bool GVN::runImpl(Function &F, AssumptionCache &RunAC, DominatorTree &RunDT,
// Fabricate val-num for dead-code in order to suppress assertion in
// performPRE().
assignValNumForDeadCode();
- VN.assignBlockRPONumber(F);
bool PREChanged = true;
while (PREChanged) {
PREChanged = performPRE(F);
@@ -2062,9 +1945,7 @@ bool GVN::performScalarPREInsertion(Instruction *Instr, BasicBlock *Pred,
success = false;
break;
}
- uint32_t TValNo =
- VN.phiTranslate(Pred, Instr->getParent(), VN.lookup(Op), *this);
- if (Value *V = findLeader(Pred, TValNo)) {
+ if (Value *V = findLeader(Pred, VN.lookup(Op))) {
Instr->setOperand(i, V);
} else {
success = false;
@@ -2081,12 +1962,10 @@ bool GVN::performScalarPREInsertion(Instruction *Instr, BasicBlock *Pred,
Instr->insertBefore(Pred->getTerminator());
Instr->setName(Instr->getName() + ".pre");
Instr->setDebugLoc(Instr->getDebugLoc());
-
- unsigned Num = VN.lookupOrAdd(Instr);
- VN.add(Instr, Num);
+ VN.add(Instr, ValNo);
// Update the availability map to include the new instruction.
- addToLeaderTable(Num, Instr, Pred);
+ addToLeaderTable(ValNo, Instr, Pred);
return true;
}
@@ -2135,8 +2014,7 @@ bool GVN::performScalarPRE(Instruction *CurInst) {
break;
}
- uint32_t TValNo = VN.phiTranslate(P, CurrentBlock, ValNo, *this);
- Value *predV = findLeader(P, TValNo);
+ Value *predV = findLeader(P, ValNo);
if (!predV) {
predMap.push_back(std::make_pair(static_cast<Value *>(nullptr), P));
PREPred = P;
diff --git a/contrib/llvm/lib/Transforms/Scalar/LowerExpectIntrinsic.cpp b/contrib/llvm/lib/Transforms/Scalar/LowerExpectIntrinsic.cpp
index a143b9a3c645..930696b036c0 100644
--- a/contrib/llvm/lib/Transforms/Scalar/LowerExpectIntrinsic.cpp
+++ b/contrib/llvm/lib/Transforms/Scalar/LowerExpectIntrinsic.cpp
@@ -98,11 +98,20 @@ template <class BrSelInst> static bool handleBrSelExpect(BrSelInst &BSI) {
CallInst *CI;
ICmpInst *CmpI = dyn_cast<ICmpInst>(BSI.getCondition());
+ CmpInst::Predicate Predicate;
+ uint64_t ValueComparedTo = 0;
if (!CmpI) {
CI = dyn_cast<CallInst>(BSI.getCondition());
+ Predicate = CmpInst::ICMP_NE;
+ ValueComparedTo = 0;
} else {
- if (CmpI->getPredicate() != CmpInst::ICMP_NE)
+ Predicate = CmpI->getPredicate();
+ if (Predicate != CmpInst::ICMP_NE && Predicate != CmpInst::ICMP_EQ)
return false;
+ ConstantInt *CmpConstOperand = dyn_cast<ConstantInt>(CmpI->getOperand(1));
+ if (!CmpConstOperand)
+ return false;
+ ValueComparedTo = CmpConstOperand->getZExtValue();
CI = dyn_cast<CallInst>(CmpI->getOperand(0));
}
@@ -121,9 +130,8 @@ template <class BrSelInst> static bool handleBrSelExpect(BrSelInst &BSI) {
MDBuilder MDB(CI->getContext());
MDNode *Node;
- // If expect value is equal to 1 it means that we are more likely to take
- // branch 0, in other case more likely is branch 1.
- if (ExpectedValue->isOne())
+ if ((ExpectedValue->getZExtValue() == ValueComparedTo) ==
+ (Predicate == CmpInst::ICMP_EQ))
Node = MDB.createBranchWeights(LikelyBranchWeight, UnlikelyBranchWeight);
else
Node = MDB.createBranchWeights(UnlikelyBranchWeight, LikelyBranchWeight);
diff --git a/contrib/llvm/lib/Transforms/Scalar/NewGVN.cpp b/contrib/llvm/lib/Transforms/Scalar/NewGVN.cpp
index 5e9f40019ce8..27809f5b6f66 100644
--- a/contrib/llvm/lib/Transforms/Scalar/NewGVN.cpp
+++ b/contrib/llvm/lib/Transforms/Scalar/NewGVN.cpp
@@ -613,7 +613,7 @@ private:
return CClass;
}
void initializeCongruenceClasses(Function &F);
- const Expression *makePossiblePhiOfOps(Instruction *, bool,
+ const Expression *makePossiblePhiOfOps(Instruction *,
SmallPtrSetImpl<Value *> &);
void addPhiOfOps(PHINode *Op, BasicBlock *BB, Instruction *ExistingValue);
@@ -1937,7 +1937,8 @@ void NewGVN::touchAndErase(Map &M, const KeyType &Key) {
}
void NewGVN::addAdditionalUsers(Value *To, Value *User) const {
- AdditionalUsers[To].insert(User);
+ if (isa<Instruction>(To))
+ AdditionalUsers[To].insert(User);
}
void NewGVN::markUsersTouched(Value *V) {
@@ -2423,7 +2424,7 @@ static bool okayForPHIOfOps(const Instruction *I) {
// When we see an instruction that is an op of phis, generate the equivalent phi
// of ops form.
const Expression *
-NewGVN::makePossiblePhiOfOps(Instruction *I, bool HasBackedge,
+NewGVN::makePossiblePhiOfOps(Instruction *I,
SmallPtrSetImpl<Value *> &Visited) {
if (!okayForPHIOfOps(I))
return nullptr;
@@ -2438,24 +2439,6 @@ NewGVN::makePossiblePhiOfOps(Instruction *I, bool HasBackedge,
return nullptr;
unsigned IDFSNum = InstrToDFSNum(I);
- // Pretty much all of the instructions we can convert to phi of ops over a
- // backedge that are adds, are really induction variables, and those are
- // pretty much pointless to convert. This is very coarse-grained for a
- // test, so if we do find some value, we can change it later.
- // But otherwise, what can happen is we convert the induction variable from
- //
- // i = phi (0, tmp)
- // tmp = i + 1
- //
- // to
- // i = phi (0, tmpphi)
- // tmpphi = phi(1, tmpphi+1)
- //
- // Which we don't want to happen. We could just avoid this for all non-cycle
- // free phis, and we made go that route.
- if (HasBackedge && I->getOpcode() == Instruction::Add)
- return nullptr;
-
SmallPtrSet<const Value *, 8> ProcessedPHIs;
// TODO: We don't do phi translation on memory accesses because it's
// complicated. For a load, we'd need to be able to simulate a new memoryuse,
@@ -2470,6 +2453,16 @@ NewGVN::makePossiblePhiOfOps(Instruction *I, bool HasBackedge,
// Convert op of phis to phi of ops
for (auto &Op : I->operands()) {
+ // TODO: We can't handle expressions that must be recursively translated
+ // IE
+ // a = phi (b, c)
+ // f = use a
+ // g = f + phi of something
+ // To properly make a phi of ops for g, we'd have to properly translate and
+ // use the instruction for f. We should add this by splitting out the
+ // instruction creation we do below.
+ if (isa<Instruction>(Op) && PHINodeUses.count(cast<Instruction>(Op)))
+ return nullptr;
if (!isa<PHINode>(Op))
continue;
auto *OpPHI = cast<PHINode>(Op);
@@ -2782,8 +2775,7 @@ void NewGVN::valueNumberInstruction(Instruction *I) {
// Make a phi of ops if necessary
if (Symbolized && !isa<ConstantExpression>(Symbolized) &&
!isa<VariableExpression>(Symbolized) && PHINodeUses.count(I)) {
- // FIXME: Backedge argument
- auto *PHIE = makePossiblePhiOfOps(I, false, Visited);
+ auto *PHIE = makePossiblePhiOfOps(I, Visited);
if (PHIE)
Symbolized = PHIE;
}
diff --git a/contrib/llvm/lib/Transforms/Utils/CodeExtractor.cpp b/contrib/llvm/lib/Transforms/Utils/CodeExtractor.cpp
index ed72099ec3ed..24d28a6c2831 100644
--- a/contrib/llvm/lib/Transforms/Utils/CodeExtractor.cpp
+++ b/contrib/llvm/lib/Transforms/Utils/CodeExtractor.cpp
@@ -27,6 +27,7 @@
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/Instructions.h"
+#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/MDBuilder.h"
@@ -141,16 +142,77 @@ static bool definedInCaller(const SetVector<BasicBlock *> &Blocks, Value *V) {
return false;
}
-void CodeExtractor::findInputsOutputs(ValueSet &Inputs,
- ValueSet &Outputs) const {
+void CodeExtractor::findAllocas(ValueSet &SinkCands) const {
+ Function *Func = (*Blocks.begin())->getParent();
+ for (BasicBlock &BB : *Func) {
+ if (Blocks.count(&BB))
+ continue;
+ for (Instruction &II : BB) {
+ auto *AI = dyn_cast<AllocaInst>(&II);
+ if (!AI)
+ continue;
+
+ // Returns true if matching life time markers are found within
+ // the outlined region.
+ auto GetLifeTimeMarkers = [&](Instruction *Addr) {
+ Instruction *LifeStart = nullptr, *LifeEnd = nullptr;
+ for (User *U : Addr->users()) {
+ if (!definedInRegion(Blocks, U))
+ return false;
+
+ IntrinsicInst *IntrInst = dyn_cast<IntrinsicInst>(U);
+ if (IntrInst) {
+ if (IntrInst->getIntrinsicID() == Intrinsic::lifetime_start)
+ LifeStart = IntrInst;
+ if (IntrInst->getIntrinsicID() == Intrinsic::lifetime_end)
+ LifeEnd = IntrInst;
+ }
+ }
+ return LifeStart && LifeEnd;
+ };
+
+ if (GetLifeTimeMarkers(AI)) {
+ SinkCands.insert(AI);
+ continue;
+ }
+
+ // Follow the bitcast:
+ Instruction *MarkerAddr = nullptr;
+ for (User *U : AI->users()) {
+ if (U->stripPointerCasts() == AI) {
+ Instruction *Bitcast = cast<Instruction>(U);
+ if (GetLifeTimeMarkers(Bitcast)) {
+ MarkerAddr = Bitcast;
+ continue;
+ }
+ }
+ if (!definedInRegion(Blocks, U)) {
+ MarkerAddr = nullptr;
+ break;
+ }
+ }
+ if (MarkerAddr) {
+ if (!definedInRegion(Blocks, MarkerAddr))
+ SinkCands.insert(MarkerAddr);
+ SinkCands.insert(AI);
+ }
+ }
+ }
+}
+
+void CodeExtractor::findInputsOutputs(ValueSet &Inputs, ValueSet &Outputs,
+ const ValueSet &SinkCands) const {
+
for (BasicBlock *BB : Blocks) {
// If a used value is defined outside the region, it's an input. If an
// instruction is used outside the region, it's an output.
for (Instruction &II : *BB) {
for (User::op_iterator OI = II.op_begin(), OE = II.op_end(); OI != OE;
- ++OI)
- if (definedInCaller(Blocks, *OI))
- Inputs.insert(*OI);
+ ++OI) {
+ Value *V = *OI;
+ if (!SinkCands.count(V) && definedInCaller(Blocks, V))
+ Inputs.insert(V);
+ }
for (User *U : II.users())
if (!definedInRegion(Blocks, U)) {
@@ -718,7 +780,7 @@ Function *CodeExtractor::extractCodeRegion() {
if (!isEligible())
return nullptr;
- ValueSet inputs, outputs;
+ ValueSet inputs, outputs, SinkingCands;
// Assumption: this is a single-entry code region, and the header is the first
// block in the region.
@@ -757,8 +819,15 @@ Function *CodeExtractor::extractCodeRegion() {
"newFuncRoot");
newFuncRoot->getInstList().push_back(BranchInst::Create(header));
+ findAllocas(SinkingCands);
+
// Find inputs to, outputs from the code region.
- findInputsOutputs(inputs, outputs);
+ findInputsOutputs(inputs, outputs, SinkingCands);
+
+ // Now sink all instructions which only have non-phi uses inside the region
+ for (auto *II : SinkingCands)
+ cast<Instruction>(II)->moveBefore(*newFuncRoot,
+ newFuncRoot->getFirstInsertionPt());
// Calculate the exit blocks for the extracted region and the total exit
// weights for each of those blocks.
diff --git a/contrib/llvm/lib/Transforms/Utils/PredicateInfo.cpp b/contrib/llvm/lib/Transforms/Utils/PredicateInfo.cpp
index 8877aeafecde..9e71cba4f1b7 100644
--- a/contrib/llvm/lib/Transforms/Utils/PredicateInfo.cpp
+++ b/contrib/llvm/lib/Transforms/Utils/PredicateInfo.cpp
@@ -541,7 +541,40 @@ Value *PredicateInfo::materializeStack(unsigned int &Counter,
//
// TODO: Use this algorithm to perform fast single-variable renaming in
// promotememtoreg and memoryssa.
-void PredicateInfo::renameUses(SmallPtrSetImpl<Value *> &OpsToRename) {
+void PredicateInfo::renameUses(SmallPtrSetImpl<Value *> &OpSet) {
+ // Sort OpsToRename since we are going to iterate it.
+ SmallVector<Value *, 8> OpsToRename(OpSet.begin(), OpSet.end());
+ std::sort(OpsToRename.begin(), OpsToRename.end(), [&](const Value *A,
+ const Value *B) {
+ auto *ArgA = dyn_cast_or_null<Argument>(A);
+ auto *ArgB = dyn_cast_or_null<Argument>(B);
+
+ // If A and B are args, order them based on their arg no.
+ if (ArgA && !ArgB)
+ return true;
+ if (ArgB && !ArgA)
+ return false;
+ if (ArgA && ArgB)
+ return ArgA->getArgNo() < ArgB->getArgNo();
+
+ // Else, A are B are instructions.
+ // If they belong to different BBs, order them by the dominance of BBs.
+ auto *AInst = cast<Instruction>(A);
+ auto *BInst = cast<Instruction>(B);
+ if (AInst->getParent() != BInst->getParent())
+ return DT.dominates(AInst->getParent(), BInst->getParent());
+
+ // Else, A and B belong to the same BB.
+ // Order A and B by their dominance.
+ auto *BB = AInst->getParent();
+ auto LookupResult = OBBMap.find(BB);
+ if (LookupResult != OBBMap.end())
+ return LookupResult->second->dominates(AInst, BInst);
+
+ auto Result = OBBMap.insert({BB, make_unique<OrderedBasicBlock>(BB)});
+ return Result.first->second->dominates(AInst, BInst);
+ });
+
ValueDFS_Compare Compare(OBBMap);
// Compute liveness, and rename in O(uses) per Op.
for (auto *Op : OpsToRename) {
diff --git a/contrib/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp b/contrib/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
index 49effda5d833..cc6c47e8f978 100644
--- a/contrib/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
+++ b/contrib/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
@@ -85,20 +85,6 @@ static bool isCallingConvCCompatible(CallInst *CI) {
return false;
}
-/// Return true if it only matters that the value is equal or not-equal to zero.
-static bool isOnlyUsedInZeroEqualityComparison(Value *V) {
- for (User *U : V->users()) {
- if (ICmpInst *IC = dyn_cast<ICmpInst>(U))
- if (IC->isEquality())
- if (Constant *C = dyn_cast<Constant>(IC->getOperand(1)))
- if (C->isNullValue())
- continue;
- // Unknown instruction.
- return false;
- }
- return true;
-}
-
/// Return true if it is only used in equality comparisons with With.
static bool isOnlyUsedInEqualityComparison(Value *V, Value *With) {
for (User *U : V->users()) {
diff --git a/contrib/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/contrib/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
index 2b83b8426d14..8b9a64c220cc 100644
--- a/contrib/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
+++ b/contrib/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
@@ -7170,10 +7170,8 @@ LoopVectorizationCostModel::getInstructionCost(Instruction *I, unsigned VF) {
Type *VectorTy;
unsigned C = getInstructionCost(I, VF, VectorTy);
- // Note: Even if all instructions are scalarized, return true if any memory
- // accesses appear in the loop to get benefits from address folding etc.
bool TypeNotScalarized =
- VF > 1 && !VectorTy->isVoidTy() && TTI.getNumberOfParts(VectorTy) < VF;
+ VF > 1 && VectorTy->isVectorTy() && TTI.getNumberOfParts(VectorTy) < VF;
return VectorizationCostTy(C, TypeNotScalarized);
}
@@ -7312,7 +7310,7 @@ unsigned LoopVectorizationCostModel::getInstructionCost(Instruction *I,
Type *RetTy = I->getType();
if (canTruncateToMinimalBitwidth(I, VF))
RetTy = IntegerType::get(RetTy->getContext(), MinBWs[I]);
- VectorTy = ToVectorTy(RetTy, VF);
+ VectorTy = isScalarAfterVectorization(I, VF) ? RetTy : ToVectorTy(RetTy, VF);
auto SE = PSE.getSE();
// TODO: We need to estimate the cost of intrinsic calls.
@@ -7445,9 +7443,10 @@ unsigned LoopVectorizationCostModel::getInstructionCost(Instruction *I,
} else if (Legal->isUniform(Op2)) {
Op2VK = TargetTransformInfo::OK_UniformValue;
}
- SmallVector<const Value *, 4> Operands(I->operand_values());
- return TTI.getArithmeticInstrCost(I->getOpcode(), VectorTy, Op1VK,
- Op2VK, Op1VP, Op2VP, Operands);
+ SmallVector<const Value *, 4> Operands(I->operand_values());
+ unsigned N = isScalarAfterVectorization(I, VF) ? VF : 1;
+ return N * TTI.getArithmeticInstrCost(I->getOpcode(), VectorTy, Op1VK,
+ Op2VK, Op1VP, Op2VP, Operands);
}
case Instruction::Select: {
SelectInst *SI = cast<SelectInst>(I);
@@ -7470,7 +7469,15 @@ unsigned LoopVectorizationCostModel::getInstructionCost(Instruction *I,
}
case Instruction::Store:
case Instruction::Load: {
- VectorTy = ToVectorTy(getMemInstValueType(I), VF);
+ unsigned Width = VF;
+ if (Width > 1) {
+ InstWidening Decision = getWideningDecision(I, Width);
+ assert(Decision != CM_Unknown &&
+ "CM decision should be taken at this point");
+ if (Decision == CM_Scalarize)
+ Width = 1;
+ }
+ VectorTy = ToVectorTy(getMemInstValueType(I), Width);
return getMemoryInstructionCost(I, VF);
}
case Instruction::ZExt:
@@ -7495,7 +7502,8 @@ unsigned LoopVectorizationCostModel::getInstructionCost(Instruction *I,
}
Type *SrcScalarTy = I->getOperand(0)->getType();
- Type *SrcVecTy = ToVectorTy(SrcScalarTy, VF);
+ Type *SrcVecTy =
+ VectorTy->isVectorTy() ? ToVectorTy(SrcScalarTy, VF) : SrcScalarTy;
if (canTruncateToMinimalBitwidth(I, VF)) {
// This cast is going to be shrunk. This may remove the cast or it might
// turn it into slightly different cast. For example, if MinBW == 16,
@@ -7515,7 +7523,8 @@ unsigned LoopVectorizationCostModel::getInstructionCost(Instruction *I,
}
}
- return TTI.getCastInstrCost(I->getOpcode(), VectorTy, SrcVecTy, I);
+ unsigned N = isScalarAfterVectorization(I, VF) ? VF : 1;
+ return N * TTI.getCastInstrCost(I->getOpcode(), VectorTy, SrcVecTy, I);
}
case Instruction::Call: {
bool NeedToScalarize;
diff --git a/contrib/llvm/tools/bugpoint/OptimizerDriver.cpp b/contrib/llvm/tools/bugpoint/OptimizerDriver.cpp
index 246580c8bdbe..ae3a31adaea3 100644
--- a/contrib/llvm/tools/bugpoint/OptimizerDriver.cpp
+++ b/contrib/llvm/tools/bugpoint/OptimizerDriver.cpp
@@ -47,14 +47,13 @@ static cl::opt<bool> PreserveBitcodeUseListOrder(
cl::desc("Preserve use-list order when writing LLVM bitcode."),
cl::init(true), cl::Hidden);
-namespace {
// ChildOutput - This option captures the name of the child output file that
// is set up by the parent bugpoint process
-cl::opt<std::string> ChildOutput("child-output", cl::ReallyHidden);
-cl::opt<std::string> OptCmd("opt-command", cl::init(""),
- cl::desc("Path to opt. (default: search path "
- "for 'opt'.)"));
-}
+static cl::opt<std::string> ChildOutput("child-output", cl::ReallyHidden);
+static cl::opt<std::string>
+ OptCmd("opt-command", cl::init(""),
+ cl::desc("Path to opt. (default: search path "
+ "for 'opt'.)"));
/// writeProgramToFile - This writes the current "Program" to the named bitcode
/// file. If an error occurs, true is returned.
diff --git a/contrib/llvm/tools/clang/include/clang/AST/VTableBuilder.h b/contrib/llvm/tools/clang/include/clang/AST/VTableBuilder.h
index 5cbcf51dd69b..b0b71e473516 100644
--- a/contrib/llvm/tools/clang/include/clang/AST/VTableBuilder.h
+++ b/contrib/llvm/tools/clang/include/clang/AST/VTableBuilder.h
@@ -154,6 +154,28 @@ public:
bool isRTTIKind() const { return isRTTIKind(getKind()); }
+ GlobalDecl getGlobalDecl() const {
+ assert(isUsedFunctionPointerKind() &&
+ "GlobalDecl can be created only from virtual function");
+
+ auto *DtorDecl = dyn_cast<CXXDestructorDecl>(getFunctionDecl());
+ switch (getKind()) {
+ case CK_FunctionPointer:
+ return GlobalDecl(getFunctionDecl());
+ case CK_CompleteDtorPointer:
+ return GlobalDecl(DtorDecl, CXXDtorType::Dtor_Complete);
+ case CK_DeletingDtorPointer:
+ return GlobalDecl(DtorDecl, CXXDtorType::Dtor_Deleting);
+ case CK_VCallOffset:
+ case CK_VBaseOffset:
+ case CK_OffsetToTop:
+ case CK_RTTI:
+ case CK_UnusedFunctionPointer:
+ llvm_unreachable("Only function pointers kinds");
+ }
+ llvm_unreachable("Should already return");
+ }
+
private:
static bool isFunctionPointerKind(Kind ComponentKind) {
return isUsedFunctionPointerKind(ComponentKind) ||
diff --git a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticGroups.td b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticGroups.td
index e1a41584023c..cf404768472f 100644
--- a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticGroups.td
@@ -733,6 +733,7 @@ def Pedantic : DiagGroup<"pedantic">;
// Aliases.
def : DiagGroup<"", [Extra]>; // -W = -Wextra
def : DiagGroup<"endif-labels", [ExtraTokens]>; // -Wendif-labels=-Wextra-tokens
+def : DiagGroup<"cpp", [PoundWarning]>; // -Wcpp = -W#warnings
def : DiagGroup<"comments", [Comment]>; // -Wcomments = -Wcomment
def : DiagGroup<"conversion-null",
[NullConversion]>; // -Wconversion-null = -Wnull-conversion
diff --git a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticIDs.h b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticIDs.h
index 7646e33d2366..479d1978c62d 100644
--- a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticIDs.h
+++ b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticIDs.h
@@ -32,7 +32,7 @@ namespace clang {
DIAG_START_FRONTEND = DIAG_START_DRIVER + 200,
DIAG_START_SERIALIZATION = DIAG_START_FRONTEND + 100,
DIAG_START_LEX = DIAG_START_SERIALIZATION + 120,
- DIAG_START_PARSE = DIAG_START_LEX + 300,
+ DIAG_START_PARSE = DIAG_START_LEX + 400,
DIAG_START_AST = DIAG_START_PARSE + 500,
DIAG_START_COMMENT = DIAG_START_AST + 110,
DIAG_START_SEMA = DIAG_START_COMMENT + 100,
diff --git a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 629e8b837f59..4de4f47b8a5a 100644
--- a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -8979,10 +8979,10 @@ def err_coroutine_promise_new_requires_nothrow : Error<
def note_coroutine_promise_call_implicitly_required : Note<
"call to %0 implicitly required by coroutine function here">;
def err_await_suspend_invalid_return_type : Error<
- "the return type of 'await_suspend' is required to be 'void' or 'bool' (have %0)"
+ "return type of 'await_suspend' is required to be 'void' or 'bool' (have %0)"
>;
def note_await_ready_no_bool_conversion : Note<
- "the return type of 'await_ready' is required to be contextually convertible to 'bool'"
+ "return type of 'await_ready' is required to be contextually convertible to 'bool'"
>;
}
diff --git a/contrib/llvm/tools/clang/include/clang/Basic/Module.h b/contrib/llvm/tools/clang/include/clang/Basic/Module.h
index 28aa7db52992..326d84eeb6c2 100644
--- a/contrib/llvm/tools/clang/include/clang/Basic/Module.h
+++ b/contrib/llvm/tools/clang/include/clang/Basic/Module.h
@@ -83,6 +83,10 @@ public:
/// are found.
const DirectoryEntry *Directory;
+ /// \brief The presumed file name for the module map defining this module.
+ /// Only non-empty when building from preprocessed source.
+ std::string PresumedModuleMapFile;
+
/// \brief The umbrella header or directory.
llvm::PointerUnion<const DirectoryEntry *, const FileEntry *> Umbrella;
diff --git a/contrib/llvm/tools/clang/include/clang/Basic/Sanitizers.def b/contrib/llvm/tools/clang/include/clang/Basic/Sanitizers.def
index f20d326e08f8..71b11974dbfd 100644
--- a/contrib/llvm/tools/clang/include/clang/Basic/Sanitizers.def
+++ b/contrib/llvm/tools/clang/include/clang/Basic/Sanitizers.def
@@ -73,6 +73,7 @@ SANITIZER("nullability-return", NullabilityReturn)
SANITIZER_GROUP("nullability", Nullability,
NullabilityArg | NullabilityAssign | NullabilityReturn)
SANITIZER("object-size", ObjectSize)
+SANITIZER("pointer-overflow", PointerOverflow)
SANITIZER("return", Return)
SANITIZER("returns-nonnull-attribute", ReturnsNonnullAttribute)
SANITIZER("shift-base", ShiftBase)
@@ -108,9 +109,9 @@ SANITIZER("safe-stack", SafeStack)
SANITIZER_GROUP("undefined", Undefined,
Alignment | Bool | ArrayBounds | Enum | FloatCastOverflow |
FloatDivideByZero | IntegerDivideByZero | NonnullAttribute |
- Null | ObjectSize | Return | ReturnsNonnullAttribute |
- Shift | SignedIntegerOverflow | Unreachable | VLABound |
- Function | Vptr)
+ Null | ObjectSize | PointerOverflow | Return |
+ ReturnsNonnullAttribute | Shift | SignedIntegerOverflow |
+ Unreachable | VLABound | Function | Vptr)
// -fsanitize=undefined-trap is an alias for -fsanitize=undefined.
SANITIZER_GROUP("undefined-trap", UndefinedTrap, Undefined)
diff --git a/contrib/llvm/tools/clang/include/clang/Basic/TokenKinds.def b/contrib/llvm/tools/clang/include/clang/Basic/TokenKinds.def
index 968b203a3827..be67663a1015 100644
--- a/contrib/llvm/tools/clang/include/clang/Basic/TokenKinds.def
+++ b/contrib/llvm/tools/clang/include/clang/Basic/TokenKinds.def
@@ -411,6 +411,7 @@ TYPE_TRAIT_1(__is_sealed, IsSealed, KEYMS)
// MSVC12.0 / VS2013 Type Traits
TYPE_TRAIT_1(__is_destructible, IsDestructible, KEYMS)
+TYPE_TRAIT_1(__is_trivially_destructible, IsTriviallyDestructible, KEYCXX)
TYPE_TRAIT_1(__is_nothrow_destructible, IsNothrowDestructible, KEYMS)
TYPE_TRAIT_2(__is_nothrow_assignable, IsNothrowAssignable, KEYCXX)
TYPE_TRAIT_N(__is_constructible, IsConstructible, KEYCXX)
@@ -439,7 +440,6 @@ TYPE_TRAIT_2(__is_convertible_to, IsConvertibleTo, KEYCXX)
TYPE_TRAIT_1(__is_empty, IsEmpty, KEYCXX)
TYPE_TRAIT_1(__is_enum, IsEnum, KEYCXX)
TYPE_TRAIT_1(__is_final, IsFinal, KEYCXX)
-// Tentative name - there's no implementation of std::is_literal_type yet.
TYPE_TRAIT_1(__is_literal, IsLiteral, KEYCXX)
// Name for GCC 4.6 compatibility - people have already written libraries using
// this name unfortunately.
diff --git a/contrib/llvm/tools/clang/include/clang/Basic/TypeTraits.h b/contrib/llvm/tools/clang/include/clang/Basic/TypeTraits.h
index ffe62559002e..6aadf795d82e 100644
--- a/contrib/llvm/tools/clang/include/clang/Basic/TypeTraits.h
+++ b/contrib/llvm/tools/clang/include/clang/Basic/TypeTraits.h
@@ -65,6 +65,7 @@ namespace clang {
UTT_IsStandardLayout,
UTT_IsTrivial,
UTT_IsTriviallyCopyable,
+ UTT_IsTriviallyDestructible,
UTT_IsUnion,
UTT_IsUnsigned,
UTT_IsVoid,
diff --git a/contrib/llvm/tools/clang/include/clang/Driver/CLCompatOptions.td b/contrib/llvm/tools/clang/include/clang/Driver/CLCompatOptions.td
index d0d9c679de7a..aebb36ed0e2b 100644
--- a/contrib/llvm/tools/clang/include/clang/Driver/CLCompatOptions.td
+++ b/contrib/llvm/tools/clang/include/clang/Driver/CLCompatOptions.td
@@ -63,6 +63,12 @@ def _SLASH_C : CLFlag<"C">,
def _SLASH_c : CLFlag<"c">, HelpText<"Compile only">, Alias<c>;
def _SLASH_d1reportAllClassLayout : CLFlag<"d1reportAllClassLayout">,
HelpText<"Dump record layout information">, Alias<fdump_record_layouts>;
+def _SLASH_diagnostics_caret : CLFlag<"diagnostics:caret">,
+ HelpText<"Enable caret and column diagnostics (on by default)">;
+def _SLASH_diagnostics_column : CLFlag<"diagnostics:column">,
+ HelpText<"Disable caret diagnostics but keep column info">;
+def _SLASH_diagnostics_classic : CLFlag<"diagnostics:classic">,
+ HelpText<"Disable column and caret diagnostics">;
def _SLASH_D : CLJoinedOrSeparate<"D">, HelpText<"Define macro">,
MetaVarName<"<macro[=value]>">, Alias<D>;
def _SLASH_E : CLFlag<"E">, HelpText<"Preprocess to stdout">, Alias<E>;
@@ -324,6 +330,7 @@ def _SLASH_Zc_forScope : CLIgnoredFlag<"Zc:forScope">;
def _SLASH_Zc_inline : CLIgnoredFlag<"Zc:inline">;
def _SLASH_Zc_rvalueCast : CLIgnoredFlag<"Zc:rvalueCast">;
def _SLASH_Zc_wchar_t : CLIgnoredFlag<"Zc:wchar_t">;
+def _SLASH_Zc_ternary : CLIgnoredFlag<"Zc:ternary">;
def _SLASH_Zm : CLIgnoredJoined<"Zm">;
def _SLASH_Zo : CLIgnoredFlag<"Zo">;
def _SLASH_Zo_ : CLIgnoredFlag<"Zo-">;
diff --git a/contrib/llvm/tools/clang/include/clang/Driver/Options.td b/contrib/llvm/tools/clang/include/clang/Driver/Options.td
index 2de4a2d1b419..12e36cc52b0b 100644
--- a/contrib/llvm/tools/clang/include/clang/Driver/Options.td
+++ b/contrib/llvm/tools/clang/include/clang/Driver/Options.td
@@ -2084,7 +2084,7 @@ def no_cpp_precomp : Flag<["-"], "no-cpp-precomp">, Group<clang_ignored_f_Group>
def no_integrated_cpp : Flag<["-", "--"], "no-integrated-cpp">, Flags<[DriverOption]>;
def no_pedantic : Flag<["-", "--"], "no-pedantic">, Group<pedantic_Group>;
def no__dead__strip__inits__and__terms : Flag<["-"], "no_dead_strip_inits_and_terms">;
-def nobuiltininc : Flag<["-"], "nobuiltininc">, Flags<[CC1Option]>,
+def nobuiltininc : Flag<["-"], "nobuiltininc">, Flags<[CC1Option, CoreOption]>,
HelpText<"Disable builtin #include directories">;
def nocudainc : Flag<["-"], "nocudainc">;
def nocudalib : Flag<["-"], "nocudalib">;
@@ -2096,7 +2096,7 @@ def nopie : Flag<["-"], "nopie">;
def noprebind : Flag<["-"], "noprebind">;
def noseglinkedit : Flag<["-"], "noseglinkedit">;
def nostartfiles : Flag<["-"], "nostartfiles">;
-def nostdinc : Flag<["-"], "nostdinc">;
+def nostdinc : Flag<["-"], "nostdinc">, Flags<[CoreOption]>;
def nostdlibinc : Flag<["-"], "nostdlibinc">;
def nostdincxx : Flag<["-"], "nostdinc++">, Flags<[CC1Option]>,
HelpText<"Disable standard #include directories for the C++ standard library">;
diff --git a/contrib/llvm/tools/clang/include/clang/Lex/HeaderSearch.h b/contrib/llvm/tools/clang/include/clang/Lex/HeaderSearch.h
index 6e24e1893ab6..ee17dcbb8b5a 100644
--- a/contrib/llvm/tools/clang/include/clang/Lex/HeaderSearch.h
+++ b/contrib/llvm/tools/clang/include/clang/Lex/HeaderSearch.h
@@ -543,10 +543,13 @@ public:
/// \param Offset [inout] An offset within ID to start parsing. On exit,
/// filled by the end of the parsed contents (either EOF or the
/// location of an end-of-module-map pragma).
- ///
+ /// \param OriginalModuleMapFile The original path to the module map file,
+ /// used to resolve paths within the module (this is required when
+ /// building the module from preprocessed source).
/// \returns true if an error occurred, false otherwise.
bool loadModuleMapFile(const FileEntry *File, bool IsSystem,
- FileID ID = FileID(), unsigned *Offset = nullptr);
+ FileID ID = FileID(), unsigned *Offset = nullptr,
+ StringRef OriginalModuleMapFile = StringRef());
/// \brief Collect the set of all known, top-level modules.
///
diff --git a/contrib/llvm/tools/clang/lib/AST/ODRHash.cpp b/contrib/llvm/tools/clang/lib/AST/ODRHash.cpp
index 24371db64d07..0e822ce35b8c 100644
--- a/contrib/llvm/tools/clang/lib/AST/ODRHash.cpp
+++ b/contrib/llvm/tools/clang/lib/AST/ODRHash.cpp
@@ -110,7 +110,24 @@ void ODRHash::AddNestedNameSpecifier(const NestedNameSpecifier *NNS) {
}
}
-void ODRHash::AddTemplateName(TemplateName Name) {}
+void ODRHash::AddTemplateName(TemplateName Name) {
+ auto Kind = Name.getKind();
+ ID.AddInteger(Kind);
+
+ switch (Kind) {
+ case TemplateName::Template:
+ AddDecl(Name.getAsTemplateDecl());
+ break;
+ // TODO: Support these cases.
+ case TemplateName::OverloadedTemplate:
+ case TemplateName::QualifiedTemplate:
+ case TemplateName::DependentTemplate:
+ case TemplateName::SubstTemplateTemplateParm:
+ case TemplateName::SubstTemplateTemplateParmPack:
+ break;
+ }
+}
+
void ODRHash::AddTemplateArgument(TemplateArgument TA) {}
void ODRHash::AddTemplateParameterList(const TemplateParameterList *TPL) {}
@@ -492,6 +509,15 @@ public:
AddQualType(T->getNamedType());
VisitTypeWithKeyword(T);
}
+
+ void VisitTemplateSpecializationType(const TemplateSpecializationType *T) {
+ ID.AddInteger(T->getNumArgs());
+ for (const auto &TA : T->template_arguments()) {
+ Hash.AddTemplateArgument(TA);
+ }
+ Hash.AddTemplateName(T->getTemplateName());
+ VisitType(T);
+ }
};
void ODRHash::AddType(const Type *T) {
diff --git a/contrib/llvm/tools/clang/lib/Basic/Targets.cpp b/contrib/llvm/tools/clang/lib/Basic/Targets.cpp
index 6be83d22a256..605f73802afb 100644
--- a/contrib/llvm/tools/clang/lib/Basic/Targets.cpp
+++ b/contrib/llvm/tools/clang/lib/Basic/Targets.cpp
@@ -3123,6 +3123,7 @@ public:
case CC_Swift:
case CC_X86Pascal:
case CC_IntelOclBicc:
+ case CC_OpenCLKernel:
return CCCR_OK;
default:
return CCCR_Warning;
@@ -4834,6 +4835,7 @@ public:
case CC_PreserveMost:
case CC_PreserveAll:
case CC_X86RegCall:
+ case CC_OpenCLKernel:
return CCCR_OK;
default:
return CCCR_Warning;
@@ -4907,6 +4909,7 @@ public:
case CC_X86_64SysV:
case CC_Swift:
case CC_X86RegCall:
+ case CC_OpenCLKernel:
return CCCR_OK;
default:
return CCCR_Warning;
@@ -5860,6 +5863,7 @@ public:
case CC_AAPCS:
case CC_AAPCS_VFP:
case CC_Swift:
+ case CC_OpenCLKernel:
return CCCR_OK;
default:
return CCCR_Warning;
@@ -6019,6 +6023,7 @@ public:
case CC_X86VectorCall:
return CCCR_Ignore;
case CC_C:
+ case CC_OpenCLKernel:
return CCCR_OK;
default:
return CCCR_Warning;
@@ -6329,6 +6334,7 @@ public:
case CC_Swift:
case CC_PreserveMost:
case CC_PreserveAll:
+ case CC_OpenCLKernel:
return CCCR_OK;
default:
return CCCR_Warning;
@@ -7380,6 +7386,7 @@ public:
switch (CC) {
case CC_C:
case CC_Swift:
+ case CC_OpenCLKernel:
return CCCR_OK;
default:
return CCCR_Warning;
@@ -7663,6 +7670,15 @@ public:
ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
return None;
}
+ CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
+ switch (CC) {
+ default:
+ return CCCR_Warning;
+ case CC_C:
+ case CC_OpenCLKernel:
+ return CCCR_OK;
+ }
+ }
};
class MipsTargetInfo : public TargetInfo {
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/ABIInfo.h b/contrib/llvm/tools/clang/lib/CodeGen/ABIInfo.h
index c0be60ef53bc..e4dce2f2a004 100644
--- a/contrib/llvm/tools/clang/lib/CodeGen/ABIInfo.h
+++ b/contrib/llvm/tools/clang/lib/CodeGen/ABIInfo.h
@@ -149,7 +149,6 @@ namespace swiftcall {
return info->supportsSwift();
}
};
-
} // end namespace CodeGen
} // end namespace clang
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CGCall.cpp b/contrib/llvm/tools/clang/lib/CodeGen/CGCall.cpp
index c677d9887acc..8f405eee6e52 100644
--- a/contrib/llvm/tools/clang/lib/CodeGen/CGCall.cpp
+++ b/contrib/llvm/tools/clang/lib/CodeGen/CGCall.cpp
@@ -707,6 +707,12 @@ CodeGenTypes::arrangeCall(const CGFunctionInfo &signature,
signature.getRequiredArgs());
}
+namespace clang {
+namespace CodeGen {
+void computeSPIRKernelABIInfo(CodeGenModule &CGM, CGFunctionInfo &FI);
+}
+}
+
/// Arrange the argument and result information for an abstract value
/// of a given function type. This is the method which all of the
/// above functions ultimately defer to.
@@ -741,12 +747,16 @@ CodeGenTypes::arrangeLLVMFunctionInfo(CanQualType resultType,
bool inserted = FunctionsBeingProcessed.insert(FI).second;
(void)inserted;
assert(inserted && "Recursively being processed?");
-
+
// Compute ABI information.
- if (info.getCC() != CC_Swift) {
- getABIInfo().computeInfo(*FI);
- } else {
+ if (CC == llvm::CallingConv::SPIR_KERNEL) {
+ // Force target independent argument handling for the host visible
+ // kernel functions.
+ computeSPIRKernelABIInfo(CGM, *FI);
+ } else if (info.getCC() == CC_Swift) {
swiftcall::computeABIInfo(CGM, *FI);
+ } else {
+ getABIInfo().computeInfo(*FI);
}
// Loop over all of the computed argument and return value info. If any of
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CGCleanup.cpp b/contrib/llvm/tools/clang/lib/CodeGen/CGCleanup.cpp
index e8bcf0a3ac56..b5453bc11e30 100644
--- a/contrib/llvm/tools/clang/lib/CodeGen/CGCleanup.cpp
+++ b/contrib/llvm/tools/clang/lib/CodeGen/CGCleanup.cpp
@@ -448,6 +448,13 @@ void CodeGenFunction::PopCleanupBlocks(
auto *Inst = dyn_cast_or_null<llvm::Instruction>(*ReloadedValue);
if (!Inst)
continue;
+
+ // Don't spill static allocas, they dominate all cleanups. These are created
+ // by binding a reference to a local variable or temporary.
+ auto *AI = dyn_cast<llvm::AllocaInst>(Inst);
+ if (AI && AI->isStaticAlloca())
+ continue;
+
Address Tmp =
CreateDefaultAlignTempAlloca(Inst->getType(), "tmp.exprcleanup");
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CGExpr.cpp b/contrib/llvm/tools/clang/lib/CodeGen/CGExpr.cpp
index b918a663ce5c..84ce896506d5 100644
--- a/contrib/llvm/tools/clang/lib/CodeGen/CGExpr.cpp
+++ b/contrib/llvm/tools/clang/lib/CodeGen/CGExpr.cpp
@@ -3002,9 +3002,10 @@ static llvm::Value *emitArraySubscriptGEP(CodeGenFunction &CGF,
llvm::Value *ptr,
ArrayRef<llvm::Value*> indices,
bool inbounds,
+ SourceLocation loc,
const llvm::Twine &name = "arrayidx") {
if (inbounds) {
- return CGF.Builder.CreateInBoundsGEP(ptr, indices, name);
+ return CGF.EmitCheckedInBoundsGEP(ptr, indices, loc, name);
} else {
return CGF.Builder.CreateGEP(ptr, indices, name);
}
@@ -3035,8 +3036,9 @@ static QualType getFixedSizeElementType(const ASTContext &ctx,
}
static Address emitArraySubscriptGEP(CodeGenFunction &CGF, Address addr,
- ArrayRef<llvm::Value*> indices,
+ ArrayRef<llvm::Value *> indices,
QualType eltType, bool inbounds,
+ SourceLocation loc,
const llvm::Twine &name = "arrayidx") {
// All the indices except that last must be zero.
#ifndef NDEBUG
@@ -3057,7 +3059,7 @@ static Address emitArraySubscriptGEP(CodeGenFunction &CGF, Address addr,
getArrayElementAlign(addr.getAlignment(), indices.back(), eltSize);
llvm::Value *eltPtr =
- emitArraySubscriptGEP(CGF, addr.getPointer(), indices, inbounds, name);
+ emitArraySubscriptGEP(CGF, addr.getPointer(), indices, inbounds, loc, name);
return Address(eltPtr, eltAlign);
}
@@ -3110,7 +3112,8 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E,
Address Addr = EmitExtVectorElementLValue(LV);
QualType EltType = LV.getType()->castAs<VectorType>()->getElementType();
- Addr = emitArraySubscriptGEP(*this, Addr, Idx, EltType, /*inbounds*/ true);
+ Addr = emitArraySubscriptGEP(*this, Addr, Idx, EltType, /*inbounds*/ true,
+ E->getExprLoc());
return MakeAddrLValue(Addr, EltType, LV.getBaseInfo());
}
@@ -3138,7 +3141,8 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E,
}
Addr = emitArraySubscriptGEP(*this, Addr, Idx, vla->getElementType(),
- !getLangOpts().isSignedOverflowDefined());
+ !getLangOpts().isSignedOverflowDefined(),
+ E->getExprLoc());
} else if (const ObjCObjectType *OIT = E->getType()->getAs<ObjCObjectType>()){
// Indexing over an interface, as in "NSString *P; P[4];"
@@ -3163,8 +3167,8 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E,
// Do the GEP.
CharUnits EltAlign =
getArrayElementAlign(Addr.getAlignment(), Idx, InterfaceSize);
- llvm::Value *EltPtr =
- emitArraySubscriptGEP(*this, Addr.getPointer(), ScaledIdx, false);
+ llvm::Value *EltPtr = emitArraySubscriptGEP(
+ *this, Addr.getPointer(), ScaledIdx, false, E->getExprLoc());
Addr = Address(EltPtr, EltAlign);
// Cast back.
@@ -3189,14 +3193,16 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E,
Addr = emitArraySubscriptGEP(*this, ArrayLV.getAddress(),
{CGM.getSize(CharUnits::Zero()), Idx},
E->getType(),
- !getLangOpts().isSignedOverflowDefined());
+ !getLangOpts().isSignedOverflowDefined(),
+ E->getExprLoc());
BaseInfo = ArrayLV.getBaseInfo();
} else {
// The base must be a pointer; emit it with an estimate of its alignment.
Addr = EmitPointerWithAlignment(E->getBase(), &BaseInfo);
auto *Idx = EmitIdxAfterBase(/*Promote*/true);
Addr = emitArraySubscriptGEP(*this, Addr, Idx, E->getType(),
- !getLangOpts().isSignedOverflowDefined());
+ !getLangOpts().isSignedOverflowDefined(),
+ E->getExprLoc());
}
LValue LV = MakeAddrLValue(Addr, E->getType(), BaseInfo);
@@ -3368,7 +3374,8 @@ LValue CodeGenFunction::EmitOMPArraySectionExpr(const OMPArraySectionExpr *E,
else
Idx = Builder.CreateNSWMul(Idx, NumElements);
EltPtr = emitArraySubscriptGEP(*this, Base, Idx, VLA->getElementType(),
- !getLangOpts().isSignedOverflowDefined());
+ !getLangOpts().isSignedOverflowDefined(),
+ E->getExprLoc());
} else if (const Expr *Array = isSimpleArrayDecayOperand(E->getBase())) {
// If this is A[i] where A is an array, the frontend will have decayed the
// base to be a ArrayToPointerDecay implicit cast. While correct, it is
@@ -3387,13 +3394,15 @@ LValue CodeGenFunction::EmitOMPArraySectionExpr(const OMPArraySectionExpr *E,
// Propagate the alignment from the array itself to the result.
EltPtr = emitArraySubscriptGEP(
*this, ArrayLV.getAddress(), {CGM.getSize(CharUnits::Zero()), Idx},
- ResultExprTy, !getLangOpts().isSignedOverflowDefined());
+ ResultExprTy, !getLangOpts().isSignedOverflowDefined(),
+ E->getExprLoc());
BaseInfo = ArrayLV.getBaseInfo();
} else {
Address Base = emitOMPArraySectionBase(*this, E->getBase(), BaseInfo,
BaseTy, ResultExprTy, IsLowerBound);
EltPtr = emitArraySubscriptGEP(*this, Base, Idx, ResultExprTy,
- !getLangOpts().isSignedOverflowDefined());
+ !getLangOpts().isSignedOverflowDefined(),
+ E->getExprLoc());
}
return MakeAddrLValue(EltPtr, ResultExprTy, BaseInfo);
@@ -3530,6 +3539,25 @@ static Address emitAddrOfFieldStorage(CodeGenFunction &CGF, Address base,
return CGF.Builder.CreateStructGEP(base, idx, offset, field->getName());
}
+static bool hasAnyVptr(const QualType Type, const ASTContext &Context) {
+ const auto *RD = Type.getTypePtr()->getAsCXXRecordDecl();
+ if (!RD)
+ return false;
+
+ if (RD->isDynamicClass())
+ return true;
+
+ for (const auto &Base : RD->bases())
+ if (hasAnyVptr(Base.getType(), Context))
+ return true;
+
+ for (const FieldDecl *Field : RD->fields())
+ if (hasAnyVptr(Field->getType(), Context))
+ return true;
+
+ return false;
+}
+
LValue CodeGenFunction::EmitLValueForField(LValue base,
const FieldDecl *field) {
LValueBaseInfo BaseInfo = base.getBaseInfo();
@@ -3572,6 +3600,14 @@ LValue CodeGenFunction::EmitLValueForField(LValue base,
assert(!type->isReferenceType() && "union has reference member");
// TODO: handle path-aware TBAA for union.
TBAAPath = false;
+
+ const auto FieldType = field->getType();
+ if (CGM.getCodeGenOpts().StrictVTablePointers &&
+ hasAnyVptr(FieldType, getContext()))
+ // Because unions can easily skip invariant.barriers, we need to add
+ // a barrier every time CXXRecord field with vptr is referenced.
+ addr = Address(Builder.CreateInvariantGroupBarrier(addr.getPointer()),
+ addr.getAlignment());
} else {
// For structs, we GEP to the field that the record layout suggests.
addr = emitAddrOfFieldStorage(*this, addr, field);
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CGExprScalar.cpp b/contrib/llvm/tools/clang/lib/CodeGen/CGExprScalar.cpp
index 048b50d8261d..d604b4130a23 100644
--- a/contrib/llvm/tools/clang/lib/CodeGen/CGExprScalar.cpp
+++ b/contrib/llvm/tools/clang/lib/CodeGen/CGExprScalar.cpp
@@ -30,6 +30,7 @@
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Function.h"
+#include "llvm/IR/GetElementPtrTypeIterator.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/Module.h"
@@ -44,6 +45,43 @@ using llvm::Value;
//===----------------------------------------------------------------------===//
namespace {
+
+/// Determine whether the given binary operation may overflow.
+/// Sets \p Result to the value of the operation for BO_Add, BO_Sub, BO_Mul,
+/// and signed BO_{Div,Rem}. For these opcodes, and for unsigned BO_{Div,Rem},
+/// the returned overflow check is precise. The returned value is 'true' for
+/// all other opcodes, to be conservative.
+bool mayHaveIntegerOverflow(llvm::ConstantInt *LHS, llvm::ConstantInt *RHS,
+ BinaryOperator::Opcode Opcode, bool Signed,
+ llvm::APInt &Result) {
+ // Assume overflow is possible, unless we can prove otherwise.
+ bool Overflow = true;
+ const auto &LHSAP = LHS->getValue();
+ const auto &RHSAP = RHS->getValue();
+ if (Opcode == BO_Add) {
+ if (Signed)
+ Result = LHSAP.sadd_ov(RHSAP, Overflow);
+ else
+ Result = LHSAP.uadd_ov(RHSAP, Overflow);
+ } else if (Opcode == BO_Sub) {
+ if (Signed)
+ Result = LHSAP.ssub_ov(RHSAP, Overflow);
+ else
+ Result = LHSAP.usub_ov(RHSAP, Overflow);
+ } else if (Opcode == BO_Mul) {
+ if (Signed)
+ Result = LHSAP.smul_ov(RHSAP, Overflow);
+ else
+ Result = LHSAP.umul_ov(RHSAP, Overflow);
+ } else if (Opcode == BO_Div || Opcode == BO_Rem) {
+ if (Signed && !RHS->isZero())
+ Result = LHSAP.sdiv_ov(RHSAP, Overflow);
+ else
+ return false;
+ }
+ return Overflow;
+}
+
struct BinOpInfo {
Value *LHS;
Value *RHS;
@@ -55,37 +93,14 @@ struct BinOpInfo {
/// Check if the binop can result in integer overflow.
bool mayHaveIntegerOverflow() const {
// Without constant input, we can't rule out overflow.
- const auto *LHSCI = dyn_cast<llvm::ConstantInt>(LHS);
- const auto *RHSCI = dyn_cast<llvm::ConstantInt>(RHS);
+ auto *LHSCI = dyn_cast<llvm::ConstantInt>(LHS);
+ auto *RHSCI = dyn_cast<llvm::ConstantInt>(RHS);
if (!LHSCI || !RHSCI)
return true;
- // Assume overflow is possible, unless we can prove otherwise.
- bool Overflow = true;
- const auto &LHSAP = LHSCI->getValue();
- const auto &RHSAP = RHSCI->getValue();
- if (Opcode == BO_Add) {
- if (Ty->hasSignedIntegerRepresentation())
- (void)LHSAP.sadd_ov(RHSAP, Overflow);
- else
- (void)LHSAP.uadd_ov(RHSAP, Overflow);
- } else if (Opcode == BO_Sub) {
- if (Ty->hasSignedIntegerRepresentation())
- (void)LHSAP.ssub_ov(RHSAP, Overflow);
- else
- (void)LHSAP.usub_ov(RHSAP, Overflow);
- } else if (Opcode == BO_Mul) {
- if (Ty->hasSignedIntegerRepresentation())
- (void)LHSAP.smul_ov(RHSAP, Overflow);
- else
- (void)LHSAP.umul_ov(RHSAP, Overflow);
- } else if (Opcode == BO_Div || Opcode == BO_Rem) {
- if (Ty->hasSignedIntegerRepresentation() && !RHSCI->isZero())
- (void)LHSAP.sdiv_ov(RHSAP, Overflow);
- else
- return false;
- }
- return Overflow;
+ llvm::APInt Result;
+ return ::mayHaveIntegerOverflow(
+ LHSCI, RHSCI, Opcode, Ty->hasSignedIntegerRepresentation(), Result);
}
/// Check if the binop computes a division or a remainder.
@@ -1925,7 +1940,8 @@ ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
if (CGF.getLangOpts().isSignedOverflowDefined())
value = Builder.CreateGEP(value, numElts, "vla.inc");
else
- value = Builder.CreateInBoundsGEP(value, numElts, "vla.inc");
+ value = CGF.EmitCheckedInBoundsGEP(value, numElts, E->getExprLoc(),
+ "vla.inc");
// Arithmetic on function pointers (!) is just +-1.
} else if (type->isFunctionType()) {
@@ -1935,7 +1951,8 @@ ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
if (CGF.getLangOpts().isSignedOverflowDefined())
value = Builder.CreateGEP(value, amt, "incdec.funcptr");
else
- value = Builder.CreateInBoundsGEP(value, amt, "incdec.funcptr");
+ value = CGF.EmitCheckedInBoundsGEP(value, amt, E->getExprLoc(),
+ "incdec.funcptr");
value = Builder.CreateBitCast(value, input->getType());
// For everything else, we can just do a simple increment.
@@ -1944,7 +1961,8 @@ ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
if (CGF.getLangOpts().isSignedOverflowDefined())
value = Builder.CreateGEP(value, amt, "incdec.ptr");
else
- value = Builder.CreateInBoundsGEP(value, amt, "incdec.ptr");
+ value = CGF.EmitCheckedInBoundsGEP(value, amt, E->getExprLoc(),
+ "incdec.ptr");
}
// Vector increment/decrement.
@@ -2025,7 +2043,8 @@ ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
if (CGF.getLangOpts().isSignedOverflowDefined())
value = Builder.CreateGEP(value, sizeValue, "incdec.objptr");
else
- value = Builder.CreateInBoundsGEP(value, sizeValue, "incdec.objptr");
+ value = CGF.EmitCheckedInBoundsGEP(value, sizeValue, E->getExprLoc(),
+ "incdec.objptr");
value = Builder.CreateBitCast(value, input->getType());
}
@@ -2692,7 +2711,8 @@ static Value *emitPointerArithmetic(CodeGenFunction &CGF,
pointer = CGF.Builder.CreateGEP(pointer, index, "add.ptr");
} else {
index = CGF.Builder.CreateNSWMul(index, numElements, "vla.index");
- pointer = CGF.Builder.CreateInBoundsGEP(pointer, index, "add.ptr");
+ pointer = CGF.EmitCheckedInBoundsGEP(pointer, index, op.E->getExprLoc(),
+ "add.ptr");
}
return pointer;
}
@@ -2709,7 +2729,8 @@ static Value *emitPointerArithmetic(CodeGenFunction &CGF,
if (CGF.getLangOpts().isSignedOverflowDefined())
return CGF.Builder.CreateGEP(pointer, index, "add.ptr");
- return CGF.Builder.CreateInBoundsGEP(pointer, index, "add.ptr");
+ return CGF.EmitCheckedInBoundsGEP(pointer, index, op.E->getExprLoc(),
+ "add.ptr");
}
// Construct an fmuladd intrinsic to represent a fused mul-add of MulOp and
@@ -3824,3 +3845,124 @@ LValue CodeGenFunction::EmitCompoundAssignmentLValue(
llvm_unreachable("Unhandled compound assignment operator");
}
+
+Value *CodeGenFunction::EmitCheckedInBoundsGEP(Value *Ptr,
+ ArrayRef<Value *> IdxList,
+ SourceLocation Loc,
+ const Twine &Name) {
+ Value *GEPVal = Builder.CreateInBoundsGEP(Ptr, IdxList, Name);
+
+ // If the pointer overflow sanitizer isn't enabled, do nothing.
+ if (!SanOpts.has(SanitizerKind::PointerOverflow))
+ return GEPVal;
+
+ // If the GEP has already been reduced to a constant, leave it be.
+ if (isa<llvm::Constant>(GEPVal))
+ return GEPVal;
+
+ // Only check for overflows in the default address space.
+ if (GEPVal->getType()->getPointerAddressSpace())
+ return GEPVal;
+
+ auto *GEP = cast<llvm::GEPOperator>(GEPVal);
+ assert(GEP->isInBounds() && "Expected inbounds GEP");
+
+ SanitizerScope SanScope(this);
+ auto &VMContext = getLLVMContext();
+ const auto &DL = CGM.getDataLayout();
+ auto *IntPtrTy = DL.getIntPtrType(GEP->getPointerOperandType());
+
+ // Grab references to the signed add/mul overflow intrinsics for intptr_t.
+ auto *Zero = llvm::ConstantInt::getNullValue(IntPtrTy);
+ auto *SAddIntrinsic =
+ CGM.getIntrinsic(llvm::Intrinsic::sadd_with_overflow, IntPtrTy);
+ auto *SMulIntrinsic =
+ CGM.getIntrinsic(llvm::Intrinsic::smul_with_overflow, IntPtrTy);
+
+ // The total (signed) byte offset for the GEP.
+ llvm::Value *TotalOffset = nullptr;
+ // The offset overflow flag - true if the total offset overflows.
+ llvm::Value *OffsetOverflows = Builder.getFalse();
+
+ /// Return the result of the given binary operation.
+ auto eval = [&](BinaryOperator::Opcode Opcode, llvm::Value *LHS,
+ llvm::Value *RHS) -> llvm::Value * {
+ assert(Opcode == BO_Add || Opcode == BO_Mul && "Can't eval binop");
+
+ // If the operands are constants, return a constant result.
+ if (auto *LHSCI = dyn_cast<llvm::ConstantInt>(LHS)) {
+ if (auto *RHSCI = dyn_cast<llvm::ConstantInt>(RHS)) {
+ llvm::APInt N;
+ bool HasOverflow = mayHaveIntegerOverflow(LHSCI, RHSCI, Opcode,
+ /*Signed=*/true, N);
+ if (HasOverflow)
+ OffsetOverflows = Builder.getTrue();
+ return llvm::ConstantInt::get(VMContext, N);
+ }
+ }
+
+ // Otherwise, compute the result with checked arithmetic.
+ auto *ResultAndOverflow = Builder.CreateCall(
+ (Opcode == BO_Add) ? SAddIntrinsic : SMulIntrinsic, {LHS, RHS});
+ OffsetOverflows = Builder.CreateOr(
+ OffsetOverflows, Builder.CreateExtractValue(ResultAndOverflow, 1));
+ return Builder.CreateExtractValue(ResultAndOverflow, 0);
+ };
+
+ // Determine the total byte offset by looking at each GEP operand.
+ for (auto GTI = llvm::gep_type_begin(GEP), GTE = llvm::gep_type_end(GEP);
+ GTI != GTE; ++GTI) {
+ llvm::Value *LocalOffset;
+ auto *Index = GTI.getOperand();
+ // Compute the local offset contributed by this indexing step:
+ if (auto *STy = GTI.getStructTypeOrNull()) {
+ // For struct indexing, the local offset is the byte position of the
+ // specified field.
+ unsigned FieldNo = cast<llvm::ConstantInt>(Index)->getZExtValue();
+ LocalOffset = llvm::ConstantInt::get(
+ IntPtrTy, DL.getStructLayout(STy)->getElementOffset(FieldNo));
+ } else {
+ // Otherwise this is array-like indexing. The local offset is the index
+ // multiplied by the element size.
+ auto *ElementSize = llvm::ConstantInt::get(
+ IntPtrTy, DL.getTypeAllocSize(GTI.getIndexedType()));
+ auto *IndexS = Builder.CreateIntCast(Index, IntPtrTy, /*isSigned=*/true);
+ LocalOffset = eval(BO_Mul, ElementSize, IndexS);
+ }
+
+ // If this is the first offset, set it as the total offset. Otherwise, add
+ // the local offset into the running total.
+ if (!TotalOffset || TotalOffset == Zero)
+ TotalOffset = LocalOffset;
+ else
+ TotalOffset = eval(BO_Add, TotalOffset, LocalOffset);
+ }
+
+ // Common case: if the total offset is zero, don't emit a check.
+ if (TotalOffset == Zero)
+ return GEPVal;
+
+ // Now that we've computed the total offset, add it to the base pointer (with
+ // wrapping semantics).
+ auto *IntPtr = Builder.CreatePtrToInt(GEP->getPointerOperand(), IntPtrTy);
+ auto *ComputedGEP = Builder.CreateAdd(IntPtr, TotalOffset);
+
+ // The GEP is valid if:
+ // 1) The total offset doesn't overflow, and
+ // 2) The sign of the difference between the computed address and the base
+ // pointer matches the sign of the total offset.
+ llvm::Value *PosOrZeroValid = Builder.CreateICmpUGE(ComputedGEP, IntPtr);
+ llvm::Value *NegValid = Builder.CreateICmpULT(ComputedGEP, IntPtr);
+ auto *PosOrZeroOffset = Builder.CreateICmpSGE(TotalOffset, Zero);
+ llvm::Value *ValidGEP = Builder.CreateAnd(
+ Builder.CreateNot(OffsetOverflows),
+ Builder.CreateSelect(PosOrZeroOffset, PosOrZeroValid, NegValid));
+
+ llvm::Constant *StaticArgs[] = {EmitCheckSourceLocation(Loc)};
+ // Pass the computed GEP to the runtime to avoid emitting poisoned arguments.
+ llvm::Value *DynamicArgs[] = {IntPtr, ComputedGEP};
+ EmitCheck(std::make_pair(ValidGEP, SanitizerKind::PointerOverflow),
+ SanitizerHandler::PointerOverflow, StaticArgs, DynamicArgs);
+
+ return GEPVal;
+}
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CGObjCRuntime.cpp b/contrib/llvm/tools/clang/lib/CodeGen/CGObjCRuntime.cpp
index 3e3d04672357..b5599dad3096 100644
--- a/contrib/llvm/tools/clang/lib/CodeGen/CGObjCRuntime.cpp
+++ b/contrib/llvm/tools/clang/lib/CodeGen/CGObjCRuntime.cpp
@@ -90,7 +90,11 @@ LValue CGObjCRuntime::EmitValueForIvarAtOffset(CodeGen::CodeGenFunction &CGF,
unsigned CVRQualifiers,
llvm::Value *Offset) {
// Compute (type*) ( (char *) BaseValue + Offset)
- QualType IvarTy = Ivar->getType().withCVRQualifiers(CVRQualifiers);
+ QualType InterfaceTy{OID->getTypeForDecl(), 0};
+ QualType ObjectPtrTy =
+ CGF.CGM.getContext().getObjCObjectPointerType(InterfaceTy);
+ QualType IvarTy =
+ Ivar->getUsageType(ObjectPtrTy).withCVRQualifiers(CVRQualifiers);
llvm::Type *LTy = CGF.CGM.getTypes().ConvertTypeForMem(IvarTy);
llvm::Value *V = CGF.Builder.CreateBitCast(BaseValue, CGF.Int8PtrTy);
V = CGF.Builder.CreateInBoundsGEP(V, Offset, "add.ptr");
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CGVTables.cpp b/contrib/llvm/tools/clang/lib/CodeGen/CGVTables.cpp
index 1869c0e809df..64b6d0d3fe9f 100644
--- a/contrib/llvm/tools/clang/lib/CodeGen/CGVTables.cpp
+++ b/contrib/llvm/tools/clang/lib/CodeGen/CGVTables.cpp
@@ -901,6 +901,8 @@ void CodeGenModule::EmitDeferredVTables() {
for (const CXXRecordDecl *RD : DeferredVTables)
if (shouldEmitVTableAtEndOfTranslationUnit(*this, RD))
VTables.GenerateClassData(RD);
+ else if (shouldOpportunisticallyEmitVTables())
+ OpportunisticVTables.push_back(RD);
assert(savedSize == DeferredVTables.size() &&
"deferred extra vtables during vtable emission?");
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CodeGenFunction.h b/contrib/llvm/tools/clang/lib/CodeGen/CodeGenFunction.h
index 526ef9a1e579..42ffd0d3efcc 100644
--- a/contrib/llvm/tools/clang/lib/CodeGen/CodeGenFunction.h
+++ b/contrib/llvm/tools/clang/lib/CodeGen/CodeGenFunction.h
@@ -120,6 +120,7 @@ enum TypeEvaluationKind {
SANITIZER_CHECK(NonnullArg, nonnull_arg, 0) \
SANITIZER_CHECK(NonnullReturn, nonnull_return, 0) \
SANITIZER_CHECK(OutOfBounds, out_of_bounds, 0) \
+ SANITIZER_CHECK(PointerOverflow, pointer_overflow, 0) \
SANITIZER_CHECK(ShiftOutOfBounds, shift_out_of_bounds, 0) \
SANITIZER_CHECK(SubOverflow, sub_overflow, 0) \
SANITIZER_CHECK(TypeMismatch, type_mismatch, 1) \
@@ -3551,6 +3552,13 @@ public:
/// nonnull, if \p LHS is marked _Nonnull.
void EmitNullabilityCheck(LValue LHS, llvm::Value *RHS, SourceLocation Loc);
+ /// Same as IRBuilder::CreateInBoundsGEP, but additionally emits a check to
+ /// detect undefined behavior when the pointer overflow sanitizer is enabled.
+ llvm::Value *EmitCheckedInBoundsGEP(llvm::Value *Ptr,
+ ArrayRef<llvm::Value *> IdxList,
+ SourceLocation Loc,
+ const Twine &Name = "");
+
/// \brief Emit a description of a type in a format suitable for passing to
/// a runtime sanitizer handler.
llvm::Constant *EmitCheckTypeDescriptor(QualType T);
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CodeGenModule.cpp b/contrib/llvm/tools/clang/lib/CodeGen/CodeGenModule.cpp
index e4e5fce02279..c61a5f6ffa71 100644
--- a/contrib/llvm/tools/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/contrib/llvm/tools/clang/lib/CodeGen/CodeGenModule.cpp
@@ -382,6 +382,7 @@ void InstrProfStats::reportDiagnostics(DiagnosticsEngine &Diags,
void CodeGenModule::Release() {
EmitDeferred();
+ EmitVTablesOpportunistically();
applyGlobalValReplacements();
applyReplacements();
checkAliases();
@@ -472,10 +473,10 @@ void CodeGenModule::Release() {
// Width of wchar_t in bytes
uint64_t WCharWidth =
Context.getTypeSizeInChars(Context.getWideCharType()).getQuantity();
- assert(LangOpts.ShortWChar ||
- llvm::TargetLibraryInfoImpl::getTargetWCharSize(Target.getTriple()) ==
- Target.getWCharWidth() / 8 &&
- "LLVM wchar_t size out of sync");
+ assert((LangOpts.ShortWChar ||
+ llvm::TargetLibraryInfoImpl::getTargetWCharSize(Target.getTriple()) ==
+ Target.getWCharWidth() / 8) &&
+ "LLVM wchar_t size out of sync");
// We need to record the widths of enums and wchar_t, so that we can generate
// the correct build attributes in the ARM backend. wchar_size is also used by
@@ -1386,6 +1387,24 @@ void CodeGenModule::EmitDeferred() {
}
}
+void CodeGenModule::EmitVTablesOpportunistically() {
+ // Try to emit external vtables as available_externally if they have emitted
+ // all inlined virtual functions. It runs after EmitDeferred() and therefore
+ // is not allowed to create new references to things that need to be emitted
+ // lazily. Note that it also uses fact that we eagerly emitting RTTI.
+
+ assert((OpportunisticVTables.empty() || shouldOpportunisticallyEmitVTables())
+ && "Only emit opportunistic vtables with optimizations");
+
+ for (const CXXRecordDecl *RD : OpportunisticVTables) {
+ assert(getVTables().isVTableExternal(RD) &&
+ "This queue should only contain external vtables");
+ if (getCXXABI().canSpeculativelyEmitVTable(RD))
+ VTables.GenerateClassData(RD);
+ }
+ OpportunisticVTables.clear();
+}
+
void CodeGenModule::EmitGlobalAnnotations() {
if (Annotations.empty())
return;
@@ -1906,6 +1925,10 @@ bool CodeGenModule::shouldEmitFunction(GlobalDecl GD) {
return !isTriviallyRecursive(F);
}
+bool CodeGenModule::shouldOpportunisticallyEmitVTables() {
+ return CodeGenOpts.OptimizationLevel > 0;
+}
+
void CodeGenModule::EmitGlobalDefinition(GlobalDecl GD, llvm::GlobalValue *GV) {
const auto *D = cast<ValueDecl>(GD.getDecl());
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CodeGenModule.h b/contrib/llvm/tools/clang/lib/CodeGen/CodeGenModule.h
index e38337814ebc..0a71c635e8f0 100644
--- a/contrib/llvm/tools/clang/lib/CodeGen/CodeGenModule.h
+++ b/contrib/llvm/tools/clang/lib/CodeGen/CodeGenModule.h
@@ -341,6 +341,9 @@ private:
/// A queue of (optional) vtables to consider emitting.
std::vector<const CXXRecordDecl*> DeferredVTables;
+ /// A queue of (optional) vtables that may be emitted opportunistically.
+ std::vector<const CXXRecordDecl *> OpportunisticVTables;
+
/// List of global values which are required to be present in the object file;
/// bitcast to i8*. This is used for forcing visibility of symbols which may
/// otherwise be optimized out.
@@ -450,7 +453,7 @@ private:
bool isTriviallyRecursive(const FunctionDecl *F);
bool shouldEmitFunction(GlobalDecl GD);
-
+ bool shouldOpportunisticallyEmitVTables();
/// Map used to be sure we don't emit the same CompoundLiteral twice.
llvm::DenseMap<const CompoundLiteralExpr *, llvm::GlobalVariable *>
EmittedCompoundLiterals;
@@ -1278,6 +1281,12 @@ private:
/// Emit any needed decls for which code generation was deferred.
void EmitDeferred();
+ /// Try to emit external vtables as available_externally if they have emitted
+ /// all inlined virtual functions. It runs after EmitDeferred() and therefore
+ /// is not allowed to create new references to things that need to be emitted
+ /// lazily.
+ void EmitVTablesOpportunistically();
+
/// Call replaceAllUsesWith on all pairs in Replacements.
void applyReplacements();
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/ItaniumCXXABI.cpp b/contrib/llvm/tools/clang/lib/CodeGen/ItaniumCXXABI.cpp
index 66f51305430a..62b0e6155f99 100644
--- a/contrib/llvm/tools/clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/contrib/llvm/tools/clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -366,20 +366,30 @@ public:
void emitCXXStructor(const CXXMethodDecl *MD, StructorType Type) override;
private:
- bool hasAnyVirtualInlineFunction(const CXXRecordDecl *RD) const {
- const auto &VtableLayout =
- CGM.getItaniumVTableContext().getVTableLayout(RD);
-
- for (const auto &VtableComponent : VtableLayout.vtable_components()) {
- // Skip empty slot.
- if (!VtableComponent.isUsedFunctionPointerKind())
- continue;
-
- const CXXMethodDecl *Method = VtableComponent.getFunctionDecl();
- if (Method->getCanonicalDecl()->isInlined())
- return true;
- }
- return false;
+ bool hasAnyUnusedVirtualInlineFunction(const CXXRecordDecl *RD) const {
+ const auto &VtableLayout =
+ CGM.getItaniumVTableContext().getVTableLayout(RD);
+
+ for (const auto &VtableComponent : VtableLayout.vtable_components()) {
+ // Skip empty slot.
+ if (!VtableComponent.isUsedFunctionPointerKind())
+ continue;
+
+ const CXXMethodDecl *Method = VtableComponent.getFunctionDecl();
+ if (!Method->getCanonicalDecl()->isInlined())
+ continue;
+
+ StringRef Name = CGM.getMangledName(VtableComponent.getGlobalDecl());
+ auto *Entry = CGM.GetGlobalValue(Name);
+ // This checks if virtual inline function has already been emitted.
+ // Note that it is possible that this inline function would be emitted
+ // after trying to emit vtable speculatively. Because of this we do
+ // an extra pass after emitting all deferred vtables to find and emit
+ // these vtables opportunistically.
+ if (!Entry || Entry->isDeclaration())
+ return true;
+ }
+ return false;
}
bool isVTableHidden(const CXXRecordDecl *RD) const {
@@ -1687,11 +1697,11 @@ bool ItaniumCXXABI::canSpeculativelyEmitVTable(const CXXRecordDecl *RD) const {
if (CGM.getLangOpts().AppleKext)
return false;
- // If we don't have any inline virtual functions, and if vtable is not hidden,
- // then we are safe to emit available_externally copy of vtable.
+ // If we don't have any not emitted inline virtual function, and if vtable is
+ // not hidden, then we are safe to emit available_externally copy of vtable.
// FIXME we can still emit a copy of the vtable if we
// can emit definition of the inline functions.
- return !hasAnyVirtualInlineFunction(RD) && !isVTableHidden(RD);
+ return !hasAnyUnusedVirtualInlineFunction(RD) && !isVTableHidden(RD);
}
static llvm::Value *performTypeAdjustment(CodeGenFunction &CGF,
Address InitialPtr,
@@ -2576,6 +2586,9 @@ ItaniumRTTIBuilder::GetAddrOfExternalRTTIDescriptor(QualType Ty) {
if (!GV) {
// Create a new global variable.
+ // Note for the future: If we would ever like to do deferred emission of
+ // RTTI, check if emitting vtables opportunistically need any adjustment.
+
GV = new llvm::GlobalVariable(CGM.getModule(), CGM.Int8PtrTy,
/*Constant=*/true,
llvm::GlobalValue::ExternalLinkage, nullptr,
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/MicrosoftCXXABI.cpp b/contrib/llvm/tools/clang/lib/CodeGen/MicrosoftCXXABI.cpp
index 4cacf494e694..ff5aca88131e 100644
--- a/contrib/llvm/tools/clang/lib/CodeGen/MicrosoftCXXABI.cpp
+++ b/contrib/llvm/tools/clang/lib/CodeGen/MicrosoftCXXABI.cpp
@@ -3756,6 +3756,9 @@ llvm::Constant *MicrosoftCXXABI::getAddrOfRTTIDescriptor(QualType Type) {
if (llvm::GlobalVariable *GV = CGM.getModule().getNamedGlobal(MangledName))
return llvm::ConstantExpr::getBitCast(GV, CGM.Int8PtrTy);
+ // Note for the future: If we would ever like to do deferred emission of
+ // RTTI, check if emitting vtables opportunistically need any adjustment.
+
// Compute the fields for the TypeDescriptor.
SmallString<256> TypeInfoString;
{
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/TargetInfo.cpp b/contrib/llvm/tools/clang/lib/CodeGen/TargetInfo.cpp
index d0ba74119b7d..427ec06a2fff 100644
--- a/contrib/llvm/tools/clang/lib/CodeGen/TargetInfo.cpp
+++ b/contrib/llvm/tools/clang/lib/CodeGen/TargetInfo.cpp
@@ -398,7 +398,17 @@ TargetCodeGenInfo::getDependentLibraryOption(llvm::StringRef Lib,
}
unsigned TargetCodeGenInfo::getOpenCLKernelCallingConv() const {
- return llvm::CallingConv::C;
+ // OpenCL kernels are called via an explicit runtime API with arguments
+ // set with clSetKernelArg(), not as normal sub-functions.
+ // Return SPIR_KERNEL by default as the kernel calling convention to
+ // ensure the fingerprint is fixed such way that each OpenCL argument
+ // gets one matching argument in the produced kernel function argument
+ // list to enable feasible implementation of clSetKernelArg() with
+ // aggregates etc. In case we would use the default C calling conv here,
+ // clSetKernelArg() might break depending on the target-specific
+ // conventions; different targets might split structs passed as values
+ // to multiple function arguments etc.
+ return llvm::CallingConv::SPIR_KERNEL;
}
llvm::Constant *TargetCodeGenInfo::getNullPointer(const CodeGen::CodeGenModule &CGM,
@@ -8068,8 +8078,18 @@ public:
CodeGen::CodeGenModule &M) const override;
unsigned getOpenCLKernelCallingConv() const override;
};
+
} // End anonymous namespace.
+namespace clang {
+namespace CodeGen {
+void computeSPIRKernelABIInfo(CodeGenModule &CGM, CGFunctionInfo &FI) {
+ DefaultABIInfo SPIRABI(CGM.getTypes());
+ SPIRABI.computeInfo(FI);
+}
+}
+}
+
/// Emit SPIR specific metadata: OpenCL and SPIR version.
void SPIRTargetCodeGenInfo::emitTargetMD(const Decl *D, llvm::GlobalValue *GV,
CodeGen::CodeGenModule &CGM) const {
diff --git a/contrib/llvm/tools/clang/lib/Driver/ToolChains/Clang.cpp b/contrib/llvm/tools/clang/lib/Driver/ToolChains/Clang.cpp
index 555847aeeb23..698c3aa326cb 100644
--- a/contrib/llvm/tools/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/contrib/llvm/tools/clang/lib/Driver/ToolChains/Clang.cpp
@@ -3985,9 +3985,30 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
<< value;
}
+ bool CaretDefault = true;
+ bool ColumnDefault = true;
+ if (Arg *DiagArg = Args.getLastArg(options::OPT__SLASH_diagnostics_classic,
+ options::OPT__SLASH_diagnostics_column,
+ options::OPT__SLASH_diagnostics_caret)) {
+ switch (DiagArg->getOption().getID()) {
+ case options::OPT__SLASH_diagnostics_caret:
+ CaretDefault = true;
+ ColumnDefault = true;
+ break;
+ case options::OPT__SLASH_diagnostics_column:
+ CaretDefault = false;
+ ColumnDefault = true;
+ break;
+ case options::OPT__SLASH_diagnostics_classic:
+ CaretDefault = false;
+ ColumnDefault = false;
+ break;
+ }
+ }
+
// -fcaret-diagnostics is default.
if (!Args.hasFlag(options::OPT_fcaret_diagnostics,
- options::OPT_fno_caret_diagnostics, true))
+ options::OPT_fno_caret_diagnostics, CaretDefault))
CmdArgs.push_back("-fno-caret-diagnostics");
// -fdiagnostics-fixit-info is default, only pass non-default.
@@ -4059,7 +4080,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back("-fdiagnostics-absolute-paths");
if (!Args.hasFlag(options::OPT_fshow_column, options::OPT_fno_show_column,
- true))
+ ColumnDefault))
CmdArgs.push_back("-fno-show-column");
if (!Args.hasFlag(options::OPT_fspell_checking,
@@ -4781,14 +4802,36 @@ void Clang::AddClangCLArgs(const ArgList &Args, types::ID InputType,
CmdArgs.push_back("-fms-memptr-rep=virtual");
}
- if (Args.getLastArg(options::OPT__SLASH_Gd))
- CmdArgs.push_back("-fdefault-calling-conv=cdecl");
- else if (Args.getLastArg(options::OPT__SLASH_Gr))
- CmdArgs.push_back("-fdefault-calling-conv=fastcall");
- else if (Args.getLastArg(options::OPT__SLASH_Gz))
- CmdArgs.push_back("-fdefault-calling-conv=stdcall");
- else if (Args.getLastArg(options::OPT__SLASH_Gv))
- CmdArgs.push_back("-fdefault-calling-conv=vectorcall");
+ // Parse the default calling convention options.
+ if (Arg *CCArg =
+ Args.getLastArg(options::OPT__SLASH_Gd, options::OPT__SLASH_Gr,
+ options::OPT__SLASH_Gz, options::OPT__SLASH_Gv)) {
+ unsigned DCCOptId = CCArg->getOption().getID();
+ const char *DCCFlag = nullptr;
+ bool ArchSupported = true;
+ llvm::Triple::ArchType Arch = getToolChain().getArch();
+ switch (DCCOptId) {
+ case options::OPT__SLASH_Gd:
+ DCCFlag = "-fdefault-calling-conv=cdecl";
+ break;
+ case options::OPT__SLASH_Gr:
+ ArchSupported = Arch == llvm::Triple::x86;
+ DCCFlag = "-fdefault-calling-conv=fastcall";
+ break;
+ case options::OPT__SLASH_Gz:
+ ArchSupported = Arch == llvm::Triple::x86;
+ DCCFlag = "-fdefault-calling-conv=stdcall";
+ break;
+ case options::OPT__SLASH_Gv:
+ ArchSupported = Arch == llvm::Triple::x86 || Arch == llvm::Triple::x86_64;
+ DCCFlag = "-fdefault-calling-conv=vectorcall";
+ break;
+ }
+
+ // MSVC doesn't warn if /Gr or /Gz is used on x64, so we don't either.
+ if (ArchSupported && DCCFlag)
+ CmdArgs.push_back(DCCFlag);
+ }
if (Arg *A = Args.getLastArg(options::OPT_vtordisp_mode_EQ))
A->render(Args, CmdArgs);
diff --git a/contrib/llvm/tools/clang/lib/Driver/ToolChains/Gnu.cpp b/contrib/llvm/tools/clang/lib/Driver/ToolChains/Gnu.cpp
index 1a398fd8a773..d50f8e21f62f 100644
--- a/contrib/llvm/tools/clang/lib/Driver/ToolChains/Gnu.cpp
+++ b/contrib/llvm/tools/clang/lib/Driver/ToolChains/Gnu.cpp
@@ -278,20 +278,20 @@ static void AddOpenMPLinkerScript(const ToolChain &TC, Compilation &C,
LksStream << "SECTIONS\n";
LksStream << "{\n";
- LksStream << " .omp_offloading :\n";
- LksStream << " ALIGN(0x10)\n";
- LksStream << " {\n";
- for (auto &BI : InputBinaryInfo) {
- LksStream << " . = ALIGN(0x10);\n";
+ // Put each target binary into a separate section.
+ for (const auto &BI : InputBinaryInfo) {
+ LksStream << " .omp_offloading." << BI.first << " :\n";
+ LksStream << " ALIGN(0x10)\n";
+ LksStream << " {\n";
LksStream << " PROVIDE_HIDDEN(.omp_offloading.img_start." << BI.first
<< " = .);\n";
LksStream << " " << BI.second << "\n";
LksStream << " PROVIDE_HIDDEN(.omp_offloading.img_end." << BI.first
<< " = .);\n";
+ LksStream << " }\n";
}
- LksStream << " }\n";
// Add commands to define host entries begin and end. We use 1-byte subalign
// so that the linker does not add any padding and the elements in this
// section form an array.
diff --git a/contrib/llvm/tools/clang/lib/Format/UnwrappedLineParser.cpp b/contrib/llvm/tools/clang/lib/Format/UnwrappedLineParser.cpp
index ae79ea5d8a66..eda7ef36434d 100644
--- a/contrib/llvm/tools/clang/lib/Format/UnwrappedLineParser.cpp
+++ b/contrib/llvm/tools/clang/lib/Format/UnwrappedLineParser.cpp
@@ -360,16 +360,21 @@ void UnwrappedLineParser::calculateBraceTypes(bool ExpectClassBody) {
switch (Tok->Tok.getKind()) {
case tok::l_brace:
- if (Style.Language == FormatStyle::LK_JavaScript && PrevTok &&
- PrevTok->is(tok::colon))
- // A colon indicates this code is in a type, or a braced list following
- // a label in an object literal ({a: {b: 1}}).
- // The code below could be confused by semicolons between the individual
- // members in a type member list, which would normally trigger BK_Block.
- // In both cases, this must be parsed as an inline braced init.
- Tok->BlockKind = BK_BracedInit;
- else
+ if (Style.Language == FormatStyle::LK_JavaScript && PrevTok) {
+ if (PrevTok->is(tok::colon))
+ // A colon indicates this code is in a type, or a braced list
+ // following a label in an object literal ({a: {b: 1}}). The code
+ // below could be confused by semicolons between the individual
+ // members in a type member list, which would normally trigger
+ // BK_Block. In both cases, this must be parsed as an inline braced
+ // init.
+ Tok->BlockKind = BK_BracedInit;
+ else if (PrevTok->is(tok::r_paren))
+ // `) { }` can only occur in function or method declarations in JS.
+ Tok->BlockKind = BK_Block;
+ } else {
Tok->BlockKind = BK_Unknown;
+ }
LBraceStack.push_back(Tok);
break;
case tok::r_brace:
@@ -391,6 +396,8 @@ void UnwrappedLineParser::calculateBraceTypes(bool ExpectClassBody) {
// BlockKind later if we parse a braced list (where all blocks
// inside are by default braced lists), or when we explicitly detect
// blocks (for example while parsing lambdas).
+ // FIXME: Some of these do not apply to JS, e.g. "} {" can never be a
+ // braced list in JS.
ProbablyBracedList =
(Style.Language == FormatStyle::LK_JavaScript &&
NextTok->isOneOf(Keywords.kw_of, Keywords.kw_in,
diff --git a/contrib/llvm/tools/clang/lib/Frontend/CompilerInvocation.cpp b/contrib/llvm/tools/clang/lib/Frontend/CompilerInvocation.cpp
index 7d7e7d49e9f0..47c763d29357 100644
--- a/contrib/llvm/tools/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/contrib/llvm/tools/clang/lib/Frontend/CompilerInvocation.cpp
@@ -2214,8 +2214,8 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
llvm::Triple T(TargetOpts.Triple);
llvm::Triple::ArchType Arch = T.getArch();
bool emitError = (DefaultCC == LangOptions::DCC_FastCall ||
- DefaultCC == LangOptions::DCC_StdCall) &&
- Arch != llvm::Triple::x86;
+ DefaultCC == LangOptions::DCC_StdCall) &&
+ Arch != llvm::Triple::x86;
emitError |= DefaultCC == LangOptions::DCC_VectorCall &&
!(Arch == llvm::Triple::x86 || Arch == llvm::Triple::x86_64);
if (emitError)
diff --git a/contrib/llvm/tools/clang/lib/Frontend/FrontendAction.cpp b/contrib/llvm/tools/clang/lib/Frontend/FrontendAction.cpp
index 874c1b6be41e..cd67e469ddad 100644
--- a/contrib/llvm/tools/clang/lib/Frontend/FrontendAction.cpp
+++ b/contrib/llvm/tools/clang/lib/Frontend/FrontendAction.cpp
@@ -373,10 +373,11 @@ collectModuleHeaderIncludes(const LangOptions &LangOpts, FileManager &FileMgr,
return std::error_code();
}
-static bool
-loadModuleMapForModuleBuild(CompilerInstance &CI, StringRef Filename,
- bool IsSystem, bool IsPreprocessed,
- unsigned &Offset) {
+static bool loadModuleMapForModuleBuild(CompilerInstance &CI,
+ StringRef Filename, bool IsSystem,
+ bool IsPreprocessed,
+ std::string &PresumedModuleMapFile,
+ unsigned &Offset) {
auto &SrcMgr = CI.getSourceManager();
HeaderSearch &HS = CI.getPreprocessor().getHeaderSearchInfo();
@@ -388,16 +389,15 @@ loadModuleMapForModuleBuild(CompilerInstance &CI, StringRef Filename,
// line directives are not part of the module map syntax in general.
Offset = 0;
if (IsPreprocessed) {
- std::string PresumedModuleMapFile;
SourceLocation EndOfLineMarker =
ReadOriginalFileName(CI, PresumedModuleMapFile, /*AddLineNote*/true);
if (EndOfLineMarker.isValid())
Offset = CI.getSourceManager().getDecomposedLoc(EndOfLineMarker).second;
- // FIXME: Use PresumedModuleMapFile as the MODULE_MAP_FILE in the PCM.
}
// Load the module map file.
- if (HS.loadModuleMapFile(ModuleMap, IsSystem, ModuleMapID, &Offset))
+ if (HS.loadModuleMapFile(ModuleMap, IsSystem, ModuleMapID, &Offset,
+ PresumedModuleMapFile))
return true;
if (SrcMgr.getBuffer(ModuleMapID)->getBufferSize() == Offset)
@@ -664,15 +664,19 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI,
if (Input.getKind().getFormat() == InputKind::ModuleMap) {
CI.getLangOpts().setCompilingModule(LangOptions::CMK_ModuleMap);
+ std::string PresumedModuleMapFile;
unsigned OffsetToContents;
if (loadModuleMapForModuleBuild(CI, Input.getFile(), Input.isSystem(),
- Input.isPreprocessed(), OffsetToContents))
+ Input.isPreprocessed(),
+ PresumedModuleMapFile, OffsetToContents))
goto failure;
auto *CurrentModule = prepareToBuildModule(CI, Input.getFile());
if (!CurrentModule)
goto failure;
+ CurrentModule->PresumedModuleMapFile = PresumedModuleMapFile;
+
if (OffsetToContents)
// If the module contents are in the same file, skip to them.
CI.getPreprocessor().setSkipMainFilePreamble(OffsetToContents, true);
diff --git a/contrib/llvm/tools/clang/lib/Lex/HeaderSearch.cpp b/contrib/llvm/tools/clang/lib/Lex/HeaderSearch.cpp
index f5b7c59e446f..9084bc352f76 100644
--- a/contrib/llvm/tools/clang/lib/Lex/HeaderSearch.cpp
+++ b/contrib/llvm/tools/clang/lib/Lex/HeaderSearch.cpp
@@ -1326,14 +1326,27 @@ static const FileEntry *getPrivateModuleMap(const FileEntry *File,
}
bool HeaderSearch::loadModuleMapFile(const FileEntry *File, bool IsSystem,
- FileID ID, unsigned *Offset) {
+ FileID ID, unsigned *Offset,
+ StringRef OriginalModuleMapFile) {
// Find the directory for the module. For frameworks, that may require going
// up from the 'Modules' directory.
const DirectoryEntry *Dir = nullptr;
if (getHeaderSearchOpts().ModuleMapFileHomeIsCwd)
Dir = FileMgr.getDirectory(".");
else {
- Dir = File->getDir();
+ if (!OriginalModuleMapFile.empty()) {
+ // We're building a preprocessed module map. Find or invent the directory
+ // that it originally occupied.
+ Dir = FileMgr.getDirectory(
+ llvm::sys::path::parent_path(OriginalModuleMapFile));
+ if (!Dir) {
+ auto *FakeFile = FileMgr.getVirtualFile(OriginalModuleMapFile, 0, 0);
+ Dir = FakeFile->getDir();
+ }
+ } else {
+ Dir = File->getDir();
+ }
+
StringRef DirName(Dir->getName());
if (llvm::sys::path::filename(DirName) == "Modules") {
DirName = llvm::sys::path::parent_path(DirName);
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaCoroutine.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaCoroutine.cpp
index ae6c35f22065..8a548c0ab861 100644
--- a/contrib/llvm/tools/clang/lib/Sema/SemaCoroutine.cpp
+++ b/contrib/llvm/tools/clang/lib/Sema/SemaCoroutine.cpp
@@ -391,8 +391,11 @@ static ReadySuspendResumeResult buildCoawaitCalls(Sema &S, VarDecl *CoroPromise,
// [expr.await]p3 [...]
// - await-suspend is the expression e.await_suspend(h), which shall be
// a prvalue of type void or bool.
- QualType RetType = AwaitSuspend->getType();
- if (RetType != S.Context.BoolTy && RetType != S.Context.VoidTy) {
+ QualType RetType = AwaitSuspend->getCallReturnType(S.Context);
+ // non-class prvalues always have cv-unqualified types
+ QualType AdjRetType = RetType.getUnqualifiedType();
+ if (RetType->isReferenceType() ||
+ (AdjRetType != S.Context.BoolTy && AdjRetType != S.Context.VoidTy)) {
S.Diag(AwaitSuspend->getCalleeDecl()->getLocation(),
diag::err_await_suspend_invalid_return_type)
<< RetType;
@@ -437,6 +440,7 @@ VarDecl *Sema::buildCoroutinePromise(SourceLocation Loc) {
if (VD->isInvalidDecl())
return nullptr;
ActOnUninitializedDecl(VD);
+ FD->addDecl(VD);
assert(!VD->isInvalidDecl());
return VD;
}
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaDecl.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaDecl.cpp
index a9adbec4f842..ea1f7526a832 100644
--- a/contrib/llvm/tools/clang/lib/Sema/SemaDecl.cpp
+++ b/contrib/llvm/tools/clang/lib/Sema/SemaDecl.cpp
@@ -11116,6 +11116,17 @@ void Sema::CheckCompleteVariableDeclaration(VarDecl *var) {
<< Init->getSourceRange();
Diag(attr->getLocation(), diag::note_declared_required_constant_init_here)
<< attr->getRange();
+ if (getLangOpts().CPlusPlus11) {
+ APValue Value;
+ SmallVector<PartialDiagnosticAt, 8> Notes;
+ Init->EvaluateAsInitializer(Value, getASTContext(), var, Notes);
+ for (auto &it : Notes)
+ Diag(it.first, it.second);
+ } else {
+ Diag(CacheCulprit->getExprLoc(),
+ diag::note_invalid_subexpr_in_const_expr)
+ << CacheCulprit->getSourceRange();
+ }
}
}
else if (!var->isConstexpr() && IsGlobal &&
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaDeclObjC.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaDeclObjC.cpp
index 370461c4a24e..2c8080dbf02b 100644
--- a/contrib/llvm/tools/clang/lib/Sema/SemaDeclObjC.cpp
+++ b/contrib/llvm/tools/clang/lib/Sema/SemaDeclObjC.cpp
@@ -1851,10 +1851,6 @@ Decl *Sema::ActOnStartCategoryImplementation(
// FIXME: PushOnScopeChains?
CurContext->addDecl(CDecl);
- // If the interface is deprecated/unavailable, warn/error about it.
- if (IDecl)
- DiagnoseUseOfDecl(IDecl, ClassLoc);
-
// If the interface has the objc_runtime_visible attribute, we
// cannot implement a category for it.
if (IDecl && IDecl->hasAttr<ObjCRuntimeVisibleAttr>()) {
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaExprCXX.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaExprCXX.cpp
index 8500b748a3ec..a05f7a7e406b 100644
--- a/contrib/llvm/tools/clang/lib/Sema/SemaExprCXX.cpp
+++ b/contrib/llvm/tools/clang/lib/Sema/SemaExprCXX.cpp
@@ -4080,24 +4080,23 @@ static bool CheckUnaryTypeTraitTypeCompleteness(Sema &S, TypeTrait UTT,
Loc, ArgTy, diag::err_incomplete_type_used_in_type_trait_expr);
return true;
- // C++0x [meta.unary.prop] Table 49 requires the following traits to be
- // applied to a complete type.
+ // C++1z [meta.unary.prop]:
+ // remove_all_extents_t<T> shall be a complete type or cv void.
case UTT_IsAggregate:
case UTT_IsTrivial:
case UTT_IsTriviallyCopyable:
case UTT_IsStandardLayout:
case UTT_IsPOD:
case UTT_IsLiteral:
+ ArgTy = QualType(ArgTy->getBaseElementTypeUnsafe(), 0);
+ LLVM_FALLTHROUGH;
+ // C++1z [meta.unary.prop]:
+ // T shall be a complete type, cv void, or an array of unknown bound.
case UTT_IsDestructible:
case UTT_IsNothrowDestructible:
- // Fall-through
-
- // These trait expressions are designed to help implement predicates in
- // [meta.unary.prop] despite not being named the same. They are specified
- // by both GCC and the Embarcadero C++ compiler, and require the complete
- // type due to the overarching C++0x type predicates being implemented
- // requiring the complete type.
+ case UTT_IsTriviallyDestructible:
+ // Per the GCC type traits documentation, the same constraints apply to these.
case UTT_HasNothrowAssign:
case UTT_HasNothrowMoveAssign:
case UTT_HasNothrowConstructor:
@@ -4109,17 +4108,11 @@ static bool CheckUnaryTypeTraitTypeCompleteness(Sema &S, TypeTrait UTT,
case UTT_HasTrivialCopy:
case UTT_HasTrivialDestructor:
case UTT_HasVirtualDestructor:
- // Arrays of unknown bound are expressly allowed.
- QualType ElTy = ArgTy;
- if (ArgTy->isIncompleteArrayType())
- ElTy = S.Context.getAsArrayType(ArgTy)->getElementType();
-
- // The void type is expressly allowed.
- if (ElTy->isVoidType())
+ if (ArgTy->isIncompleteArrayType() || ArgTy->isVoidType())
return true;
return !S.RequireCompleteType(
- Loc, ElTy, diag::err_incomplete_type_used_in_type_trait_expr);
+ Loc, ArgTy, diag::err_incomplete_type_used_in_type_trait_expr);
}
}
@@ -4356,6 +4349,7 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, TypeTrait UTT,
!RD->hasNonTrivialCopyAssignment();
return false;
case UTT_IsDestructible:
+ case UTT_IsTriviallyDestructible:
case UTT_IsNothrowDestructible:
// C++14 [meta.unary.prop]:
// For reference types, is_destructible<T>::value is true.
@@ -4373,6 +4367,11 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, TypeTrait UTT,
if (T->isIncompleteType() || T->isFunctionType())
return false;
+ // A type that requires destruction (via a non-trivial destructor or ARC
+ // lifetime semantics) is not trivially-destructible.
+ if (UTT == UTT_IsTriviallyDestructible && T.isDestructedType())
+ return false;
+
// C++14 [meta.unary.prop]:
// For object types and given U equal to remove_all_extents_t<T>, if the
// expression std::declval<U&>().~U() is well-formed when treated as an
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaOverload.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaOverload.cpp
index 1ba84034fa47..7bdd8872456a 100644
--- a/contrib/llvm/tools/clang/lib/Sema/SemaOverload.cpp
+++ b/contrib/llvm/tools/clang/lib/Sema/SemaOverload.cpp
@@ -49,12 +49,12 @@ static bool functionHasPassObjectSizeParams(const FunctionDecl *FD) {
static ExprResult
CreateFunctionRefExpr(Sema &S, FunctionDecl *Fn, NamedDecl *FoundDecl,
bool HadMultipleCandidates,
- SourceLocation Loc = SourceLocation(),
+ SourceLocation Loc = SourceLocation(),
const DeclarationNameLoc &LocInfo = DeclarationNameLoc()){
if (S.DiagnoseUseOfDecl(FoundDecl, Loc))
- return ExprError();
+ return ExprError();
// If FoundDecl is different from Fn (such as if one is a template
- // and the other a specialization), make sure DiagnoseUseOfDecl is
+ // and the other a specialization), make sure DiagnoseUseOfDecl is
// called on both.
// FIXME: This would be more comprehensively addressed by modifying
// DiagnoseUseOfDecl to accept both the FoundDecl and the decl
@@ -79,7 +79,7 @@ static bool IsStandardConversion(Sema &S, Expr* From, QualType ToType,
bool CStyle,
bool AllowObjCWritebackConversion);
-static bool IsTransparentUnionStandardConversion(Sema &S, Expr* From,
+static bool IsTransparentUnionStandardConversion(Sema &S, Expr* From,
QualType &ToType,
bool InOverloadResolution,
StandardConversionSequence &SCS,
@@ -330,13 +330,13 @@ StandardConversionSequence::getNarrowingKind(ASTContext &Ctx,
} else if (FromType->isIntegralType(Ctx) && ToType->isRealFloatingType()) {
llvm::APSInt IntConstantValue;
const Expr *Initializer = IgnoreNarrowingConversion(Converted);
+ assert(Initializer && "Unknown conversion expression");
// If it's value-dependent, we can't tell whether it's narrowing.
if (Initializer->isValueDependent())
return NK_Dependent_Narrowing;
- if (Initializer &&
- Initializer->isIntegerConstantExpr(IntConstantValue, Ctx)) {
+ if (Initializer->isIntegerConstantExpr(IntConstantValue, Ctx)) {
// Convert the integer to the floating type.
llvm::APFloat Result(Ctx.getFloatTypeSemantics(ToType));
Result.convertFromAPInt(IntConstantValue, IntConstantValue.isSigned(),
@@ -852,7 +852,7 @@ namespace {
Expr *Saved;
};
SmallVector<Entry, 2> Entries;
-
+
public:
void save(Sema &S, Expr *&E) {
assert(E->hasPlaceholderType(BuiltinType::ARCUnbridgedCast));
@@ -863,7 +863,7 @@ namespace {
void restore() {
for (SmallVectorImpl<Entry>::iterator
- i = Entries.begin(), e = Entries.end(); i != e; ++i)
+ i = Entries.begin(), e = Entries.end(); i != e; ++i)
*i->Addr = i->Saved;
}
};
@@ -1368,9 +1368,9 @@ Sema::TryImplicitConversion(Expr *From, QualType ToType,
bool InOverloadResolution,
bool CStyle,
bool AllowObjCWritebackConversion) {
- return ::TryImplicitConversion(*this, From, ToType,
+ return ::TryImplicitConversion(*this, From, ToType,
SuppressUserConversions, AllowExplicit,
- InOverloadResolution, CStyle,
+ InOverloadResolution, CStyle,
AllowObjCWritebackConversion,
/*AllowObjCConversionOnExplicit=*/false);
}
@@ -1396,7 +1396,7 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType,
// Objective-C ARC: Determine whether we will allow the writeback conversion.
bool AllowObjCWritebackConversion
- = getLangOpts().ObjCAutoRefCount &&
+ = getLangOpts().ObjCAutoRefCount &&
(Action == AA_Passing || Action == AA_Sending);
if (getLangOpts().ObjC1)
CheckObjCBridgeRelatedConversions(From->getLocStart(),
@@ -1592,15 +1592,15 @@ static bool IsStandardConversion(Sema &S, Expr* From, QualType ToType,
// if the function type matches except for [[noreturn]], it's ok
if (!S.IsFunctionConversion(FromType,
S.ExtractUnqualifiedFunctionType(ToType), resultTy))
- // otherwise, only a boolean conversion is standard
- if (!ToType->isBooleanType())
- return false;
+ // otherwise, only a boolean conversion is standard
+ if (!ToType->isBooleanType())
+ return false;
}
// Check if the "from" expression is taking the address of an overloaded
// function and recompute the FromType accordingly. Take advantage of the
// fact that non-static member functions *must* have such an address-of
- // expression.
+ // expression.
CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Fn);
if (Method && !Method->isStatic()) {
assert(isa<UnaryOperator>(From->IgnoreParens()) &&
@@ -1638,7 +1638,7 @@ static bool IsStandardConversion(Sema &S, Expr* From, QualType ToType,
SCS.First = ICK_Lvalue_To_Rvalue;
// C11 6.3.2.1p2:
- // ... if the lvalue has atomic type, the value has the non-atomic version
+ // ... if the lvalue has atomic type, the value has the non-atomic version
// of the type of the lvalue ...
if (const AtomicType *Atomic = FromType->getAs<AtomicType>())
FromType = Atomic->getValueType();
@@ -1890,12 +1890,12 @@ static bool IsStandardConversion(Sema &S, Expr* From, QualType ToType,
}
static bool
-IsTransparentUnionStandardConversion(Sema &S, Expr* From,
+IsTransparentUnionStandardConversion(Sema &S, Expr* From,
QualType &ToType,
bool InOverloadResolution,
StandardConversionSequence &SCS,
bool CStyle) {
-
+
const RecordType *UT = ToType->getAsUnionType();
if (!UT || !UT->getDecl()->hasAttr<TransparentUnionAttr>())
return false;
@@ -2129,7 +2129,7 @@ BuildSimilarlyQualifiedPointerType(const Type *FromPtr,
"Invalid similarly-qualified pointer type");
/// Conversions to 'id' subsume cv-qualifier conversions.
- if (ToType->isObjCIdType() || ToType->isObjCQualifiedIdType())
+ if (ToType->isObjCIdType() || ToType->isObjCQualifiedIdType())
return ToType.getUnqualifiedType();
QualType CanonFromPointee
@@ -2139,7 +2139,7 @@ BuildSimilarlyQualifiedPointerType(const Type *FromPtr,
if (StripObjCLifetime)
Quals.removeObjCLifetime();
-
+
// Exact qualifier match -> return the pointer type we're converting to.
if (CanonToPointee.getLocalQualifiers() == Quals) {
// ToType is exactly what we need. Return it.
@@ -2323,21 +2323,21 @@ bool Sema::IsPointerConversion(Expr *From, QualType FromType, QualType ToType,
ToType, Context);
return true;
}
-
+
return false;
}
-
+
/// \brief Adopt the given qualifiers for the given type.
static QualType AdoptQualifiers(ASTContext &Context, QualType T, Qualifiers Qs){
Qualifiers TQs = T.getQualifiers();
-
+
// Check whether qualifiers already match.
if (TQs == Qs)
return T;
-
+
if (Qs.compatiblyIncludes(TQs))
return Context.getQualifiedType(T, Qs);
-
+
return Context.getQualifiedType(T.getUnqualifiedType(), Qs);
}
@@ -2352,7 +2352,7 @@ bool Sema::isObjCPointerConversion(QualType FromType, QualType ToType,
// The set of qualifiers on the type we're converting from.
Qualifiers FromQualifiers = FromType.getQualifiers();
-
+
// First, we handle all conversions on ObjC object pointer types.
const ObjCObjectPointerType* ToObjCPtr =
ToType->getAs<ObjCObjectPointerType>();
@@ -2443,7 +2443,7 @@ bool Sema::isObjCPointerConversion(QualType FromType, QualType ToType,
ToPointeeType->getAs<ObjCObjectPointerType>() &&
isObjCPointerConversion(FromPointeeType, ToPointeeType, ConvertedType,
IncompatibleObjC)) {
-
+
ConvertedType = Context.getPointerType(ConvertedType);
ConvertedType = AdoptQualifiers(Context, ConvertedType, FromQualifiers);
return true;
@@ -2526,46 +2526,46 @@ bool Sema::isObjCPointerConversion(QualType FromType, QualType ToType,
/// this conversion.
bool Sema::isObjCWritebackConversion(QualType FromType, QualType ToType,
QualType &ConvertedType) {
- if (!getLangOpts().ObjCAutoRefCount ||
+ if (!getLangOpts().ObjCAutoRefCount ||
Context.hasSameUnqualifiedType(FromType, ToType))
return false;
-
+
// Parameter must be a pointer to __autoreleasing (with no other qualifiers).
QualType ToPointee;
if (const PointerType *ToPointer = ToType->getAs<PointerType>())
ToPointee = ToPointer->getPointeeType();
else
return false;
-
+
Qualifiers ToQuals = ToPointee.getQualifiers();
- if (!ToPointee->isObjCLifetimeType() ||
+ if (!ToPointee->isObjCLifetimeType() ||
ToQuals.getObjCLifetime() != Qualifiers::OCL_Autoreleasing ||
!ToQuals.withoutObjCLifetime().empty())
return false;
-
+
// Argument must be a pointer to __strong to __weak.
QualType FromPointee;
if (const PointerType *FromPointer = FromType->getAs<PointerType>())
FromPointee = FromPointer->getPointeeType();
else
return false;
-
+
Qualifiers FromQuals = FromPointee.getQualifiers();
if (!FromPointee->isObjCLifetimeType() ||
(FromQuals.getObjCLifetime() != Qualifiers::OCL_Strong &&
FromQuals.getObjCLifetime() != Qualifiers::OCL_Weak))
return false;
-
+
// Make sure that we have compatible qualifiers.
FromQuals.setObjCLifetime(Qualifiers::OCL_Autoreleasing);
if (!ToQuals.compatiblyIncludes(FromQuals))
return false;
-
+
// Remove qualifiers from the pointee type we're converting from; they
// aren't used in the compatibility check belong, and we'll be adding back
// qualifiers (with __autoreleasing) if the compatibility check succeeds.
FromPointee = FromPointee.getUnqualifiedType();
-
+
// The unqualified form of the pointee types must be compatible.
ToPointee = ToPointee.getUnqualifiedType();
bool IncompatibleObjC;
@@ -2574,7 +2574,7 @@ bool Sema::isObjCWritebackConversion(QualType FromType, QualType ToType,
else if (!isObjCPointerConversion(FromPointee, ToPointee, FromPointee,
IncompatibleObjC))
return false;
-
+
/// \brief Construct the type we're converting to, which is a pointer to
/// __autoreleasing pointee.
FromPointee = Context.getQualifiedType(FromPointee, FromQuals);
@@ -2590,7 +2590,7 @@ bool Sema::IsBlockPointerConversion(QualType FromType, QualType ToType,
ToPointeeType = ToBlockPtr->getPointeeType();
else
return false;
-
+
QualType FromPointeeType;
if (const BlockPointerType *FromBlockPtr =
FromType->getAs<BlockPointerType>())
@@ -2600,24 +2600,24 @@ bool Sema::IsBlockPointerConversion(QualType FromType, QualType ToType,
// We have pointer to blocks, check whether the only
// differences in the argument and result types are in Objective-C
// pointer conversions. If so, we permit the conversion.
-
+
const FunctionProtoType *FromFunctionType
= FromPointeeType->getAs<FunctionProtoType>();
const FunctionProtoType *ToFunctionType
= ToPointeeType->getAs<FunctionProtoType>();
-
+
if (!FromFunctionType || !ToFunctionType)
return false;
if (Context.hasSameType(FromPointeeType, ToPointeeType))
return true;
-
+
// Perform the quick checks that will tell us whether these
// function types are obviously different.
if (FromFunctionType->getNumParams() != ToFunctionType->getNumParams() ||
FromFunctionType->isVariadic() != ToFunctionType->isVariadic())
return false;
-
+
FunctionType::ExtInfo FromEInfo = FromFunctionType->getExtInfo();
FunctionType::ExtInfo ToEInfo = ToFunctionType->getExtInfo();
if (FromEInfo != ToEInfo)
@@ -2645,7 +2645,7 @@ bool Sema::IsBlockPointerConversion(QualType FromType, QualType ToType,
else
return false;
}
-
+
// Check argument types.
for (unsigned ArgIdx = 0, NumArgs = FromFunctionType->getNumParams();
ArgIdx != NumArgs; ++ArgIdx) {
@@ -2666,7 +2666,7 @@ bool Sema::IsBlockPointerConversion(QualType FromType, QualType ToType,
if (!Context.doFunctionTypesMatchOnExtParameterInfos(FromFunctionType,
ToFunctionType))
return false;
-
+
ConvertedType = ToType;
return true;
}
@@ -3012,7 +3012,7 @@ bool Sema::CheckMemberPointerConversion(Expr *From, QualType ToType,
static bool isNonTrivialObjCLifetimeConversion(Qualifiers FromQuals,
Qualifiers ToQuals) {
// Converting anything to const __unsafe_unretained is trivial.
- if (ToQuals.hasConst() &&
+ if (ToQuals.hasConst() &&
ToQuals.getObjCLifetime() == Qualifiers::OCL_ExplicitNone)
return false;
@@ -3032,7 +3032,7 @@ Sema::IsQualificationConversion(QualType FromType, QualType ToType,
FromType = Context.getCanonicalType(FromType);
ToType = Context.getCanonicalType(ToType);
ObjCLifetimeConversion = false;
-
+
// If FromType and ToType are the same type, this is not a
// qualification conversion.
if (FromType.getUnqualifiedType() == ToType.getUnqualifiedType())
@@ -3058,7 +3058,7 @@ Sema::IsQualificationConversion(QualType FromType, QualType ToType,
// Ignore __unaligned qualifier if this type is void.
if (ToType.getUnqualifiedType()->isVoidType())
FromQuals.removeUnaligned();
-
+
// Objective-C ARC:
// Check Objective-C lifetime conversions.
if (FromQuals.getObjCLifetime() != ToQuals.getObjCLifetime() &&
@@ -3074,14 +3074,14 @@ Sema::IsQualificationConversion(QualType FromType, QualType ToType,
return false;
}
}
-
+
// Allow addition/removal of GC attributes but not changing GC attributes.
if (FromQuals.getObjCGCAttr() != ToQuals.getObjCGCAttr() &&
(!FromQuals.hasObjCGCAttr() || !ToQuals.hasObjCGCAttr())) {
FromQuals.removeObjCGCAttr();
ToQuals.removeObjCGCAttr();
}
-
+
// -- for every j > 0, if const is in cv 1,j then const is in cv
// 2,j, and similarly for volatile.
if (!CStyle && !ToQuals.compatiblyIncludes(FromQuals))
@@ -3119,13 +3119,13 @@ static bool tryAtomicConversion(Sema &S, Expr *From, QualType ToType,
const AtomicType *ToAtomic = ToType->getAs<AtomicType>();
if (!ToAtomic)
return false;
-
+
StandardConversionSequence InnerSCS;
- if (!IsStandardConversion(S, From, ToAtomic->getValueType(),
+ if (!IsStandardConversion(S, From, ToAtomic->getValueType(),
InOverloadResolution, InnerSCS,
CStyle, /*AllowObjCWritebackConversion=*/false))
return false;
-
+
SCS.Second = InnerSCS.Second;
SCS.setToType(1, InnerSCS.getToType(1));
SCS.Third = InnerSCS.Third;
@@ -3180,8 +3180,8 @@ IsInitializerListConstructorConversion(Sema &S, Expr *From, QualType ToType,
bool HadMultipleCandidates = (CandidateSet.size() > 1);
OverloadCandidateSet::iterator Best;
- switch (auto Result =
- CandidateSet.BestViableFunction(S, From->getLocStart(),
+ switch (auto Result =
+ CandidateSet.BestViableFunction(S, From->getLocStart(),
Best, true)) {
case OR_Deleted:
case OR_Success: {
@@ -3552,7 +3552,7 @@ CompareImplicitConversionSequences(Sema &S, SourceLocation Loc,
// Two implicit conversion sequences of the same form are
// indistinguishable conversion sequences unless one of the
// following rules apply: (C++ 13.3.3.2p3):
-
+
// List-initialization sequence L1 is a better conversion sequence than
// list-initialization sequence L2 if:
// - L1 converts to std::initializer_list<X> for some X and L2 does not, or,
@@ -3587,7 +3587,7 @@ CompareImplicitConversionSequences(Sema &S, SourceLocation Loc,
ICS1.UserDefined.After,
ICS2.UserDefined.After);
else
- Result = compareConversionFunctions(S,
+ Result = compareConversionFunctions(S,
ICS1.UserDefined.ConversionFunction,
ICS2.UserDefined.ConversionFunction);
}
@@ -3769,9 +3769,9 @@ CompareStandardConversionSequences(Sema &S, SourceLocation Loc,
const ObjCObjectPointerType* FromObjCPtr2
= FromType2->getAs<ObjCObjectPointerType>();
if (FromObjCPtr1 && FromObjCPtr2) {
- bool AssignLeft = S.Context.canAssignObjCInterfaces(FromObjCPtr1,
+ bool AssignLeft = S.Context.canAssignObjCInterfaces(FromObjCPtr1,
FromObjCPtr2);
- bool AssignRight = S.Context.canAssignObjCInterfaces(FromObjCPtr2,
+ bool AssignRight = S.Context.canAssignObjCInterfaces(FromObjCPtr2,
FromObjCPtr1);
if (AssignLeft != AssignRight) {
return AssignLeft? ImplicitConversionSequence::Better
@@ -3809,13 +3809,13 @@ CompareStandardConversionSequences(Sema &S, SourceLocation Loc,
if (UnqualT1 == UnqualT2) {
// Objective-C++ ARC: If the references refer to objects with different
// lifetimes, prefer bindings that don't change lifetime.
- if (SCS1.ObjCLifetimeConversionBinding !=
+ if (SCS1.ObjCLifetimeConversionBinding !=
SCS2.ObjCLifetimeConversionBinding) {
return SCS1.ObjCLifetimeConversionBinding
? ImplicitConversionSequence::Worse
: ImplicitConversionSequence::Better;
}
-
+
// If the type is an array type, promote the element qualifiers to the
// type for comparison.
if (isa<ArrayType>(T1) && T1Quals)
@@ -3825,7 +3825,7 @@ CompareStandardConversionSequences(Sema &S, SourceLocation Loc,
if (T2.isMoreQualifiedThan(T1))
return ImplicitConversionSequence::Better;
else if (T1.isMoreQualifiedThan(T2))
- return ImplicitConversionSequence::Worse;
+ return ImplicitConversionSequence::Worse;
}
}
@@ -3891,17 +3891,17 @@ CompareQualificationConversions(Sema &S,
ImplicitConversionSequence::CompareKind Result
= ImplicitConversionSequence::Indistinguishable;
-
+
// Objective-C++ ARC:
// Prefer qualification conversions not involving a change in lifetime
// to qualification conversions that do not change lifetime.
- if (SCS1.QualificationIncludesObjCLifetime !=
+ if (SCS1.QualificationIncludesObjCLifetime !=
SCS2.QualificationIncludesObjCLifetime) {
Result = SCS1.QualificationIncludesObjCLifetime
? ImplicitConversionSequence::Worse
: ImplicitConversionSequence::Better;
}
-
+
while (S.Context.UnwrapSimilarPointerTypes(T1, T2)) {
// Within each iteration of the loop, we check the qualifiers to
// determine if this still looks like a qualification
@@ -4033,7 +4033,7 @@ CompareDerivedToBaseConversions(Sema &S, SourceLocation Loc,
= ToType1->getAs<ObjCObjectPointerType>();
const ObjCObjectPointerType *ToPtr2
= ToType2->getAs<ObjCObjectPointerType>();
-
+
if (FromPtr1 && FromPtr2 && ToPtr1 && ToPtr2) {
// Apply the same conversion ranking rules for Objective-C pointer types
// that we do for C++ pointers to class types. However, we employ the
@@ -4048,7 +4048,7 @@ CompareDerivedToBaseConversions(Sema &S, SourceLocation Loc,
bool ToAssignRight
= S.Context.canAssignObjCInterfaces(ToPtr2, ToPtr1);
- // A conversion to an a non-id object pointer type or qualified 'id'
+ // A conversion to an a non-id object pointer type or qualified 'id'
// type is better than a conversion to 'id'.
if (ToPtr1->isObjCIdType() &&
(ToPtr2->isObjCQualifiedIdType() || ToPtr2->getInterfaceDecl()))
@@ -4056,15 +4056,15 @@ CompareDerivedToBaseConversions(Sema &S, SourceLocation Loc,
if (ToPtr2->isObjCIdType() &&
(ToPtr1->isObjCQualifiedIdType() || ToPtr1->getInterfaceDecl()))
return ImplicitConversionSequence::Better;
-
- // A conversion to a non-id object pointer type is better than a
- // conversion to a qualified 'id' type
+
+ // A conversion to a non-id object pointer type is better than a
+ // conversion to a qualified 'id' type
if (ToPtr1->isObjCQualifiedIdType() && ToPtr2->getInterfaceDecl())
return ImplicitConversionSequence::Worse;
if (ToPtr2->isObjCQualifiedIdType() && ToPtr1->getInterfaceDecl())
return ImplicitConversionSequence::Better;
-
- // A conversion to an a non-Class object pointer type or qualified 'Class'
+
+ // A conversion to an a non-Class object pointer type or qualified 'Class'
// type is better than a conversion to 'Class'.
if (ToPtr1->isObjCClassType() &&
(ToPtr2->isObjCQualifiedClassType() || ToPtr2->getInterfaceDecl()))
@@ -4072,8 +4072,8 @@ CompareDerivedToBaseConversions(Sema &S, SourceLocation Loc,
if (ToPtr2->isObjCClassType() &&
(ToPtr1->isObjCQualifiedClassType() || ToPtr1->getInterfaceDecl()))
return ImplicitConversionSequence::Better;
-
- // A conversion to a non-Class object pointer type is better than a
+
+ // A conversion to a non-Class object pointer type is better than a
// conversion to a qualified 'Class' type.
if (ToPtr1->isObjCQualifiedClassType() && ToPtr2->getInterfaceDecl())
return ImplicitConversionSequence::Worse;
@@ -4108,7 +4108,7 @@ CompareDerivedToBaseConversions(Sema &S, SourceLocation Loc,
: ImplicitConversionSequence::Worse;
}
}
-
+
// Ranking of member-pointer types.
if (SCS1.Second == ICK_Pointer_Member && SCS2.Second == ICK_Pointer_Member &&
FromType1->isMemberPointerType() && FromType2->isMemberPointerType() &&
@@ -4264,9 +4264,9 @@ Sema::CompareReferenceRelationship(SourceLocation Loc,
ObjCLifetimeConversion = true;
T1Quals.removeObjCLifetime();
- T2Quals.removeObjCLifetime();
+ T2Quals.removeObjCLifetime();
}
-
+
// MS compiler ignores __unaligned qualifier for references; do the same.
T1Quals.removeUnaligned();
T2Quals.removeUnaligned();
@@ -4313,7 +4313,7 @@ FindConversionForRefInit(Sema &S, ImplicitConversionSequence &ICS,
bool DerivedToBase = false;
bool ObjCConversion = false;
bool ObjCLifetimeConversion = false;
-
+
// If we are initializing an rvalue reference, don't permit conversion
// functions that return lvalues.
if (!ConvTemplate && DeclType->isRValueReferenceType()) {
@@ -4322,7 +4322,7 @@ FindConversionForRefInit(Sema &S, ImplicitConversionSequence &ICS,
if (RefType && !RefType->getPointeeType()->isFunctionType())
continue;
}
-
+
if (!ConvTemplate &&
S.CompareReferenceRelationship(
DeclLoc,
@@ -6051,24 +6051,24 @@ Sema::SelectBestMethod(Selector Sel, MultiExprArg Args, bool IsInstance,
NumNamedArgs = Method->param_size();
if (Args.size() < NumNamedArgs)
continue;
-
+
for (unsigned i = 0; i < NumNamedArgs; i++) {
// We can't do any type-checking on a type-dependent argument.
if (Args[i]->isTypeDependent()) {
Match = false;
break;
}
-
+
ParmVarDecl *param = Method->parameters()[i];
Expr *argExpr = Args[i];
assert(argExpr && "SelectBestMethod(): missing expression");
-
+
// Strip the unbridged-cast placeholder expression off unless it's
// a consumed argument.
if (argExpr->hasPlaceholderType(BuiltinType::ARCUnbridgedCast) &&
!param->hasAttr<CFConsumedAttr>())
argExpr = stripARCUnbridgedCast(argExpr);
-
+
// If the parameter is __unknown_anytype, move on to the next method.
if (param->getType() == Context.UnknownAnyTy) {
Match = false;
@@ -6754,7 +6754,7 @@ static bool isAllowableExplicitConversion(Sema &S,
return S.isObjCPointerConversion(ConvType, ToNonRefType, ConvertedType,
IncompatibleObjC);
}
-
+
/// AddConversionCandidate - Add a C++ conversion function as a
/// candidate in the candidate set (C++ [over.match.conv],
/// C++ [over.match.copy]). From is the expression we're converting from,
@@ -6785,8 +6785,8 @@ Sema::AddConversionCandidate(CXXConversionDecl *Conversion,
// Per C++ [over.match.conv]p1, [over.match.ref]p1, an explicit conversion
// operator is only a candidate if its return type is the target type or
// can be converted to the target type with a qualification conversion.
- if (Conversion->isExplicit() &&
- !isAllowableExplicitConversion(*this, ConvType, ToType,
+ if (Conversion->isExplicit() &&
+ !isAllowableExplicitConversion(*this, ConvType, ToType,
AllowObjCConversionOnExplicit))
return;
@@ -7230,7 +7230,7 @@ class BuiltinCandidateTypeSet {
/// \brief A flag indicating whether the nullptr type was present in the
/// candidate set.
bool HasNullPtrType;
-
+
/// Sema - The semantic analysis instance where we are building the
/// candidate type set.
Sema &SemaRef;
@@ -7314,14 +7314,14 @@ BuiltinCandidateTypeSet::AddPointerWithMoreQualifiedTypeVariants(QualType Ty,
} else {
PointeeTy = PointerTy->getPointeeType();
}
-
+
// Don't add qualified variants of arrays. For one, they're not allowed
// (the qualifier would sink to the element type), and for another, the
// only overload situation where it matters is subscript or pointer +- int,
// and those shouldn't have qualifier variants anyway.
if (PointeeTy->isArrayType())
return true;
-
+
unsigned BaseCVR = PointeeTy.getCVRQualifiers();
bool hasVolatile = VisibleQuals.hasVolatile();
bool hasRestrict = VisibleQuals.hasRestrict();
@@ -7331,24 +7331,24 @@ BuiltinCandidateTypeSet::AddPointerWithMoreQualifiedTypeVariants(QualType Ty,
if ((CVR | BaseCVR) != CVR) continue;
// Skip over volatile if no volatile found anywhere in the types.
if ((CVR & Qualifiers::Volatile) && !hasVolatile) continue;
-
+
// Skip over restrict if no restrict found anywhere in the types, or if
// the type cannot be restrict-qualified.
if ((CVR & Qualifiers::Restrict) &&
(!hasRestrict ||
(!(PointeeTy->isAnyPointerType() || PointeeTy->isReferenceType()))))
continue;
-
+
// Build qualified pointee type.
QualType QPointeeTy = Context.getCVRQualifiedType(PointeeTy, CVR);
-
+
// Build qualified pointer type.
QualType QPointerTy;
if (!buildObjCPtr)
QPointerTy = Context.getPointerType(QPointeeTy);
else
QPointerTy = Context.getObjCObjectPointerType(QPointeeTy);
-
+
// Insert qualified pointer type.
PointerTypes.insert(QPointerTy);
}
@@ -7705,7 +7705,7 @@ class BuiltinOperatorOverloadBuilder {
else
S.AddBuiltinCandidate(CandidateTy, ParamTypes, Args, CandidateSet);
}
-
+
// Add restrict version only if there are conversions to a restrict type
// and our candidate type is a non-restrict-qualified pointer.
if (HasRestrict && CandidateTy->isAnyPointerType() &&
@@ -7717,7 +7717,7 @@ class BuiltinOperatorOverloadBuilder {
S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, CandidateSet);
else
S.AddBuiltinCandidate(CandidateTy, ParamTypes, Args, CandidateSet);
-
+
if (HasVolatile) {
ParamTypes[0]
= S.Context.getLValueReferenceType(
@@ -8274,7 +8274,7 @@ public:
S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, CandidateSet,
/*IsAssigmentOperator=*/isEqualOp);
}
-
+
if (!(*Ptr).isRestrictQualified() &&
VisibleTypeConversionsQuals.hasRestrict()) {
// restrict version
@@ -8282,7 +8282,7 @@ public:
= S.Context.getLValueReferenceType(S.Context.getRestrictType(*Ptr));
S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, CandidateSet,
/*IsAssigmentOperator=*/isEqualOp);
-
+
if (NeedVolatile) {
// volatile restrict version
ParamTypes[0]
@@ -8323,7 +8323,7 @@ public:
S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, CandidateSet,
/*IsAssigmentOperator=*/true);
}
-
+
if (!(*Ptr).isRestrictQualified() &&
VisibleTypeConversionsQuals.hasRestrict()) {
// restrict version
@@ -8331,7 +8331,7 @@ public:
= S.Context.getLValueReferenceType(S.Context.getRestrictType(*Ptr));
S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, CandidateSet,
/*IsAssigmentOperator=*/true);
-
+
if (NeedVolatile) {
// volatile restrict version
ParamTypes[0]
@@ -9424,13 +9424,13 @@ void Sema::NoteAllOverloadCandidates(Expr *OverloadedExpr, QualType DestType,
OverloadExpr *OvlExpr = Ovl.Expression;
for (UnresolvedSetIterator I = OvlExpr->decls_begin(),
- IEnd = OvlExpr->decls_end();
+ IEnd = OvlExpr->decls_end();
I != IEnd; ++I) {
- if (FunctionTemplateDecl *FunTmpl =
+ if (FunctionTemplateDecl *FunTmpl =
dyn_cast<FunctionTemplateDecl>((*I)->getUnderlyingDecl()) ) {
NoteOverloadCandidate(*I, FunTmpl->getTemplatedDecl(), DestType,
TakingAddress);
- } else if (FunctionDecl *Fun
+ } else if (FunctionDecl *Fun
= dyn_cast<FunctionDecl>((*I)->getUnderlyingDecl()) ) {
NoteOverloadCandidate(*I, Fun, DestType, TakingAddress);
}
@@ -9608,7 +9608,7 @@ static void DiagnoseBadConversion(Sema &S, OverloadCandidate *Cand,
<< (FromExpr ? FromExpr->getSourceRange() : SourceRange())
<< FromTy << ToTy << (unsigned) isObjectArgument << I+1
<< (unsigned) (Cand->Fix.Kind);
-
+
MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl);
return;
}
@@ -9711,7 +9711,7 @@ static bool CheckArityMismatch(Sema &S, OverloadCandidate *Cand,
// right number of arguments, because only overloaded operators have
// the weird behavior of overloading member and non-member functions.
// Just don't report anything.
- if (Fn->isInvalidDecl() &&
+ if (Fn->isInvalidDecl() &&
Fn->getDeclName().getNameKind() == DeclarationName::CXXOperatorName)
return true;
@@ -9735,9 +9735,9 @@ static void DiagnoseArityMismatch(Sema &S, NamedDecl *Found, Decl *D,
"The templated declaration should at least be a function"
" when diagnosing bad template argument deduction due to too many"
" or too few arguments");
-
+
FunctionDecl *Fn = cast<FunctionDecl>(D);
-
+
// TODO: treat calls to a missing default constructor as a special case
const FunctionProtoType *FnTy = Fn->getType()->getAs<FunctionProtoType>();
unsigned MinParams = Fn->getMinRequiredArguments();
@@ -9993,8 +9993,8 @@ static void DiagnoseBadDeduction(Sema &S, NamedDecl *Found, Decl *Templated,
return;
// FIXME: For generic lambda parameters, check if the function is a lambda
- // call operator, and if so, emit a prettier and more informative
- // diagnostic that mentions 'auto' and lambda in addition to
+ // call operator, and if so, emit a prettier and more informative
+ // diagnostic that mentions 'auto' and lambda in addition to
// (or instead of?) the canonical template type parameters.
S.Diag(Templated->getLocation(),
diag::note_ovl_candidate_non_deduced_mismatch)
@@ -10692,16 +10692,16 @@ void TemplateSpecCandidateSet::NoteCandidates(Sema &S, SourceLocation Loc) {
// R (S::*)(A) --> R (A)
QualType Sema::ExtractUnqualifiedFunctionType(QualType PossiblyAFunctionType) {
QualType Ret = PossiblyAFunctionType;
- if (const PointerType *ToTypePtr =
+ if (const PointerType *ToTypePtr =
PossiblyAFunctionType->getAs<PointerType>())
Ret = ToTypePtr->getPointeeType();
- else if (const ReferenceType *ToTypeRef =
+ else if (const ReferenceType *ToTypeRef =
PossiblyAFunctionType->getAs<ReferenceType>())
Ret = ToTypeRef->getPointeeType();
else if (const MemberPointerType *MemTypePtr =
- PossiblyAFunctionType->getAs<MemberPointerType>())
- Ret = MemTypePtr->getPointeeType();
- Ret =
+ PossiblyAFunctionType->getAs<MemberPointerType>())
+ Ret = MemTypePtr->getPointeeType();
+ Ret =
Context.getCanonicalType(Ret).getUnqualifiedType();
return Ret;
}
@@ -10727,9 +10727,9 @@ namespace {
class AddressOfFunctionResolver {
Sema& S;
Expr* SourceExpr;
- const QualType& TargetType;
- QualType TargetFunctionType; // Extracted function type from target type
-
+ const QualType& TargetType;
+ QualType TargetFunctionType; // Extracted function type from target type
+
bool Complain;
//DeclAccessPair& ResultFunctionAccessPair;
ASTContext& Context;
@@ -10739,7 +10739,7 @@ class AddressOfFunctionResolver {
bool StaticMemberFunctionFromBoundPointer;
bool HasComplained;
- OverloadExpr::FindResult OvlExprInfo;
+ OverloadExpr::FindResult OvlExprInfo;
OverloadExpr *OvlExpr;
TemplateArgumentListInfo OvlExplicitTemplateArgs;
SmallVector<std::pair<DeclAccessPair, FunctionDecl*>, 4> Matches;
@@ -10786,7 +10786,7 @@ public:
}
return;
}
-
+
if (OvlExpr->hasExplicitTemplateArgs())
OvlExpr->copyTemplateArgumentsInto(OvlExplicitTemplateArgs);
@@ -10864,7 +10864,7 @@ private:
}
// return true if any matching specializations were found
- bool AddMatchingTemplateFunction(FunctionTemplateDecl* FunctionTemplate,
+ bool AddMatchingTemplateFunction(FunctionTemplateDecl* FunctionTemplate,
const DeclAccessPair& CurAccessFunPair) {
if (CXXMethodDecl *Method
= dyn_cast<CXXMethodDecl>(FunctionTemplate->getTemplatedDecl())) {
@@ -10872,7 +10872,7 @@ private:
// static when converting to member pointer.
if (Method->isStatic() == TargetTypeIsNonStaticMemberFunction)
return false;
- }
+ }
else if (TargetTypeIsNonStaticMemberFunction)
return false;
@@ -10885,17 +10885,17 @@ private:
FunctionDecl *Specialization = nullptr;
TemplateDeductionInfo Info(FailedCandidates.getLocation());
if (Sema::TemplateDeductionResult Result
- = S.DeduceTemplateArguments(FunctionTemplate,
+ = S.DeduceTemplateArguments(FunctionTemplate,
&OvlExplicitTemplateArgs,
- TargetFunctionType, Specialization,
+ TargetFunctionType, Specialization,
Info, /*IsAddressOfFunction*/true)) {
// Make a note of the failed deduction for diagnostics.
FailedCandidates.addCandidate()
.set(CurAccessFunPair, FunctionTemplate->getTemplatedDecl(),
MakeDeductionFailureInfo(Context, Result, Info));
return false;
- }
-
+ }
+
// Template argument deduction ensures that we have an exact match or
// compatible pointer-to-function arguments that would be adjusted by ICS.
// This function template specicalization works.
@@ -10909,15 +10909,15 @@ private:
Matches.push_back(std::make_pair(CurAccessFunPair, Specialization));
return true;
}
-
- bool AddMatchingNonTemplateFunction(NamedDecl* Fn,
+
+ bool AddMatchingNonTemplateFunction(NamedDecl* Fn,
const DeclAccessPair& CurAccessFunPair) {
if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Fn)) {
// Skip non-static functions when converting to pointer, and static
// when converting to member pointer.
if (Method->isStatic() == TargetTypeIsNonStaticMemberFunction)
return false;
- }
+ }
else if (TargetTypeIsNonStaticMemberFunction)
return false;
@@ -10947,20 +10947,20 @@ private:
return true;
}
}
-
+
return false;
}
-
+
bool FindAllFunctionsThatMatchTargetTypeExactly() {
bool Ret = false;
-
+
// If the overload expression doesn't have the form of a pointer to
// member, don't try to convert it to a pointer-to-member type.
if (IsInvalidFormOfPointerToMemberFunction())
return false;
for (UnresolvedSetIterator I = OvlExpr->decls_begin(),
- E = OvlExpr->decls_end();
+ E = OvlExpr->decls_end();
I != E; ++I) {
// Look through any using declarations to find the underlying function.
NamedDecl *Fn = (*I)->getUnderlyingDecl();
@@ -11103,12 +11103,12 @@ public:
bool hadMultipleCandidates() const { return (OvlExpr->getNumDecls() > 1); }
int getNumMatches() const { return Matches.size(); }
-
+
FunctionDecl* getMatchingFunctionDecl() const {
if (Matches.size() != 1) return nullptr;
return Matches[0].second;
}
-
+
const DeclAccessPair* getMatchingFunctionAccessPair() const {
if (Matches.size() != 1) return nullptr;
return &Matches[0].first;
@@ -11248,7 +11248,7 @@ bool Sema::resolveAndFixAddressOfOnlyViableOverloadCandidate(
/// If no template-ids are found, no diagnostics are emitted and NULL is
/// returned.
FunctionDecl *
-Sema::ResolveSingleFunctionTemplateSpecialization(OverloadExpr *ovl,
+Sema::ResolveSingleFunctionTemplateSpecialization(OverloadExpr *ovl,
bool Complain,
DeclAccessPair *FoundResult) {
// C++ [over.over]p1:
@@ -11311,9 +11311,9 @@ Sema::ResolveSingleFunctionTemplateSpecialization(OverloadExpr *ovl,
}
return nullptr;
}
-
+
Matched = Specialization;
- if (FoundResult) *FoundResult = I.getPair();
+ if (FoundResult) *FoundResult = I.getPair();
}
if (Matched &&
@@ -11336,8 +11336,8 @@ Sema::ResolveSingleFunctionTemplateSpecialization(OverloadExpr *ovl,
// returns true if 'complain' is set.
bool Sema::ResolveAndFixSingleFunctionTemplateSpecialization(
ExprResult &SrcExpr, bool doFunctionPointerConverion,
- bool complain, SourceRange OpRangeForComplaining,
- QualType DestTypeForComplaining,
+ bool complain, SourceRange OpRangeForComplaining,
+ QualType DestTypeForComplaining,
unsigned DiagIDForComplaining) {
assert(SrcExpr.get()->getType() == Context.OverloadTy);
@@ -11394,7 +11394,7 @@ bool Sema::ResolveAndFixSingleFunctionTemplateSpecialization(
Diag(OpRangeForComplaining.getBegin(), DiagIDForComplaining)
<< ovl.Expression->getName()
<< DestTypeForComplaining
- << OpRangeForComplaining
+ << OpRangeForComplaining
<< ovl.Expression->getQualifierLoc().getSourceRange();
NoteAllOverloadCandidates(SrcExpr.get());
@@ -12183,8 +12183,8 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
// TODO: provide better source location info in DNLoc component.
DeclarationNameInfo OpNameInfo(OpName, OpLoc);
UnresolvedLookupExpr *Fn
- = UnresolvedLookupExpr::Create(Context, NamingClass,
- NestedNameSpecifierLoc(), OpNameInfo,
+ = UnresolvedLookupExpr::Create(Context, NamingClass,
+ NestedNameSpecifierLoc(), OpNameInfo,
/*ADL*/ true, IsOverloaded(Fns),
Fns.begin(), Fns.end());
return new (Context)
@@ -12747,12 +12747,12 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE,
if (DiagnoseUseOfDecl(Best->FoundDecl, UnresExpr->getNameLoc()))
return ExprError();
// If FoundDecl is different from Method (such as if one is a template
- // and the other a specialization), make sure DiagnoseUseOfDecl is
+ // and the other a specialization), make sure DiagnoseUseOfDecl is
// called on both.
// FIXME: This would be more comprehensively addressed by modifying
// DiagnoseUseOfDecl to accept both the FoundDecl and the decl
// being used.
- if (Method != FoundDecl.getDecl() &&
+ if (Method != FoundDecl.getDecl() &&
DiagnoseUseOfDecl(Method, UnresExpr->getNameLoc()))
return ExprError();
break;
@@ -12775,7 +12775,7 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE,
case OR_Deleted:
Diag(UnresExpr->getMemberLoc(), diag::err_ovl_deleted_member_call)
<< Best->Function->isDeleted()
- << DeclName
+ << DeclName
<< getDeletedOrUnavailableSuffix(Best->Function)
<< MemExprE->getSourceRange();
CandidateSet.NoteCandidates(*this, OCD_AllCandidates, Args);
@@ -12848,8 +12848,8 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE,
}
}
- if ((isa<CXXConstructorDecl>(CurContext) ||
- isa<CXXDestructorDecl>(CurContext)) &&
+ if ((isa<CXXConstructorDecl>(CurContext) ||
+ isa<CXXDestructorDecl>(CurContext)) &&
TheCall->getMethodDecl()->isPure()) {
const CXXMethodDecl *MD = TheCall->getMethodDecl();
@@ -12929,7 +12929,7 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Obj,
}
// C++ [over.call.object]p2:
- // In addition, for each (non-explicit in C++0x) conversion function
+ // In addition, for each (non-explicit in C++0x) conversion function
// declared in T of the form
//
// operator conversion-type-id () cv-qualifier;
@@ -13008,7 +13008,7 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Obj,
Diag(Object.get()->getLocStart(),
diag::err_ovl_deleted_object_call)
<< Best->Function->isDeleted()
- << Object.get()->getType()
+ << Object.get()->getType()
<< getDeletedOrUnavailableSuffix(Best->Function)
<< Object.get()->getSourceRange();
CandidateSet.NoteCandidates(*this, OCD_AllCandidates, Args);
@@ -13031,7 +13031,7 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Obj,
Best->FoundDecl);
if (DiagnoseUseOfDecl(Best->FoundDecl, LParenLoc))
return ExprError();
- assert(Conv == Best->FoundDecl.getDecl() &&
+ assert(Conv == Best->FoundDecl.getDecl() &&
"Found Decl & conversion-to-functionptr should be same, right?!");
// We selected one of the surrogate functions that converts the
// object parameter to a function pointer. Perform the conversion
@@ -13242,7 +13242,7 @@ Sema::BuildOverloadedArrowExpr(Scope *S, Expr *Base, SourceLocation OpLoc,
case OR_Deleted:
Diag(OpLoc, diag::err_ovl_deleted_oper)
<< Best->Function->isDeleted()
- << "->"
+ << "->"
<< getDeletedOrUnavailableSuffix(Best->Function)
<< Base->getSourceRange();
CandidateSet.NoteCandidates(*this, OCD_AllCandidates, Base);
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaType.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaType.cpp
index f8970744389b..e7315934b515 100644
--- a/contrib/llvm/tools/clang/lib/Sema/SemaType.cpp
+++ b/contrib/llvm/tools/clang/lib/Sema/SemaType.cpp
@@ -3175,11 +3175,7 @@ getCCForDeclaratorChunk(Sema &S, Declarator &D,
for (const AttributeList *Attr = D.getDeclSpec().getAttributes().getList();
Attr; Attr = Attr->getNext()) {
if (Attr->getKind() == AttributeList::AT_OpenCLKernel) {
- llvm::Triple::ArchType arch = S.Context.getTargetInfo().getTriple().getArch();
- if (arch == llvm::Triple::spir || arch == llvm::Triple::spir64 ||
- arch == llvm::Triple::amdgcn || arch == llvm::Triple::r600) {
- CC = CC_OpenCLKernel;
- }
+ CC = CC_OpenCLKernel;
break;
}
}
diff --git a/contrib/llvm/tools/clang/lib/Serialization/ASTWriter.cpp b/contrib/llvm/tools/clang/lib/Serialization/ASTWriter.cpp
index c931b13f65f3..95cb54f944e4 100644
--- a/contrib/llvm/tools/clang/lib/Serialization/ASTWriter.cpp
+++ b/contrib/llvm/tools/clang/lib/Serialization/ASTWriter.cpp
@@ -1422,8 +1422,8 @@ void ASTWriter::WriteControlBlock(Preprocessor &PP, ASTContext &Context,
Stream.EmitRecordWithBlob(MetadataAbbrevCode, Record,
getClangFullRepositoryVersion());
}
- if (WritingModule) {
+ if (WritingModule) {
// Module name
auto Abbrev = std::make_shared<BitCodeAbbrev>();
Abbrev->Add(BitCodeAbbrevOp(MODULE_NAME));
@@ -1466,9 +1466,10 @@ void ASTWriter::WriteControlBlock(Preprocessor &PP, ASTContext &Context,
Record.clear();
auto &Map = PP.getHeaderSearchInfo().getModuleMap();
-
- // Primary module map file.
- AddPath(Map.getModuleMapFileForUniquing(WritingModule)->getName(), Record);
+ AddPath(WritingModule->PresumedModuleMapFile.empty()
+ ? Map.getModuleMapFileForUniquing(WritingModule)->getName()
+ : StringRef(WritingModule->PresumedModuleMapFile),
+ Record);
// Additional module map files.
if (auto *AdditionalModMaps =
diff --git a/contrib/llvm/tools/clang/utils/TableGen/ClangAttrEmitter.cpp b/contrib/llvm/tools/clang/utils/TableGen/ClangAttrEmitter.cpp
index edd3e38471be..b6d2988964b4 100644
--- a/contrib/llvm/tools/clang/utils/TableGen/ClangAttrEmitter.cpp
+++ b/contrib/llvm/tools/clang/utils/TableGen/ClangAttrEmitter.cpp
@@ -718,9 +718,9 @@ namespace {
};
// Unique the enums, but maintain the original declaration ordering.
- std::vector<std::string>
- uniqueEnumsInOrder(const std::vector<std::string> &enums) {
- std::vector<std::string> uniques;
+ std::vector<StringRef>
+ uniqueEnumsInOrder(const std::vector<StringRef> &enums) {
+ std::vector<StringRef> uniques;
SmallDenseSet<StringRef, 8> unique_set;
for (const auto &i : enums) {
if (unique_set.insert(i).second)
@@ -731,7 +731,8 @@ namespace {
class EnumArgument : public Argument {
std::string type;
- std::vector<std::string> values, enums, uniques;
+ std::vector<StringRef> values, enums, uniques;
+
public:
EnumArgument(const Record &Arg, StringRef Attr)
: Argument(Arg, Attr), type(Arg.getValueAsString("Type")),
@@ -850,7 +851,7 @@ namespace {
class VariadicEnumArgument: public VariadicArgument {
std::string type, QualifiedTypeName;
- std::vector<std::string> values, enums, uniques;
+ std::vector<StringRef> values, enums, uniques;
protected:
void writeValueImpl(raw_ostream &OS) const override {
@@ -1591,8 +1592,9 @@ struct AttributeSubjectMatchRule {
}
std::string getEnumValueName() const {
- std::string Result =
- "SubjectMatchRule_" + MetaSubject->getValueAsString("Name");
+ SmallString<128> Result;
+ Result += "SubjectMatchRule_";
+ Result += MetaSubject->getValueAsString("Name");
if (isSubRule()) {
Result += "_";
if (isNegatedSubRule())
@@ -1601,7 +1603,7 @@ struct AttributeSubjectMatchRule {
}
if (isAbstractRule())
Result += "_abstract";
- return Result;
+ return Result.str();
}
std::string getEnumValue() const { return "attr::" + getEnumValueName(); }
@@ -2603,7 +2605,7 @@ void EmitClangAttrPCHWrite(RecordKeeper &Records, raw_ostream &OS) {
// append a unique suffix to distinguish this set of target checks from other
// TargetSpecificAttr records.
static void GenerateTargetSpecificAttrChecks(const Record *R,
- std::vector<std::string> &Arches,
+ std::vector<StringRef> &Arches,
std::string &Test,
std::string *FnName) {
// It is assumed that there will be an llvm::Triple object
@@ -2613,8 +2615,9 @@ static void GenerateTargetSpecificAttrChecks(const Record *R,
Test += "(";
for (auto I = Arches.begin(), E = Arches.end(); I != E; ++I) {
- std::string Part = *I;
- Test += "T.getArch() == llvm::Triple::" + Part;
+ StringRef Part = *I;
+ Test += "T.getArch() == llvm::Triple::";
+ Test += Part;
if (I + 1 != E)
Test += " || ";
if (FnName)
@@ -2627,11 +2630,12 @@ static void GenerateTargetSpecificAttrChecks(const Record *R,
// We know that there was at least one arch test, so we need to and in the
// OS tests.
Test += " && (";
- std::vector<std::string> OSes = R->getValueAsListOfStrings("OSes");
+ std::vector<StringRef> OSes = R->getValueAsListOfStrings("OSes");
for (auto I = OSes.begin(), E = OSes.end(); I != E; ++I) {
- std::string Part = *I;
+ StringRef Part = *I;
- Test += "T.getOS() == llvm::Triple::" + Part;
+ Test += "T.getOS() == llvm::Triple::";
+ Test += Part;
if (I + 1 != E)
Test += " || ";
if (FnName)
@@ -2643,10 +2647,11 @@ static void GenerateTargetSpecificAttrChecks(const Record *R,
// If one or more CXX ABIs are specified, check those as well.
if (!R->isValueUnset("CXXABIs")) {
Test += " && (";
- std::vector<std::string> CXXABIs = R->getValueAsListOfStrings("CXXABIs");
+ std::vector<StringRef> CXXABIs = R->getValueAsListOfStrings("CXXABIs");
for (auto I = CXXABIs.begin(), E = CXXABIs.end(); I != E; ++I) {
- std::string Part = *I;
- Test += "Target.getCXXABI().getKind() == TargetCXXABI::" + Part;
+ StringRef Part = *I;
+ Test += "Target.getCXXABI().getKind() == TargetCXXABI::";
+ Test += Part;
if (I + 1 != E)
Test += " || ";
if (FnName)
@@ -2684,7 +2689,7 @@ static void GenerateHasAttrSpellingStringSwitch(
std::string Test;
if (Attr->isSubClassOf("TargetSpecificAttr")) {
const Record *R = Attr->getValueAsDef("Target");
- std::vector<std::string> Arches = R->getValueAsListOfStrings("Arches");
+ std::vector<StringRef> Arches = R->getValueAsListOfStrings("Arches");
GenerateTargetSpecificAttrChecks(R, Arches, Test, nullptr);
// If this is the C++11 variety, also add in the LangOpts test.
@@ -3323,7 +3328,7 @@ static std::string GenerateTargetRequirements(const Record &Attr,
// Get the list of architectures to be tested for.
const Record *R = Attr.getValueAsDef("Target");
- std::vector<std::string> Arches = R->getValueAsListOfStrings("Arches");
+ std::vector<StringRef> Arches = R->getValueAsListOfStrings("Arches");
if (Arches.empty()) {
PrintError(Attr.getLoc(), "Empty list of target architectures for a "
"target-specific attr");
@@ -3340,9 +3345,10 @@ static std::string GenerateTargetRequirements(const Record &Attr,
std::string APK = Attr.getValueAsString("ParseKind");
for (const auto &I : Dupes) {
if (I.first == APK) {
- std::vector<std::string> DA = I.second->getValueAsDef("Target")
- ->getValueAsListOfStrings("Arches");
- std::move(DA.begin(), DA.end(), std::back_inserter(Arches));
+ std::vector<StringRef> DA =
+ I.second->getValueAsDef("Target")->getValueAsListOfStrings(
+ "Arches");
+ Arches.insert(Arches.end(), DA.begin(), DA.end());
}
}
}
diff --git a/contrib/llvm/tools/clang/utils/TableGen/ClangDiagnosticsEmitter.cpp b/contrib/llvm/tools/clang/utils/TableGen/ClangDiagnosticsEmitter.cpp
index cad08afd846f..d9d99e0bb002 100644
--- a/contrib/llvm/tools/clang/utils/TableGen/ClangDiagnosticsEmitter.cpp
+++ b/contrib/llvm/tools/clang/utils/TableGen/ClangDiagnosticsEmitter.cpp
@@ -1277,8 +1277,8 @@ void EmitClangDiagDocs(RecordKeeper &Records, raw_ostream &OS) {
bool IsSynonym = GroupInfo.DiagsInGroup.empty() &&
GroupInfo.SubGroups.size() == 1;
- writeHeader((IsRemarkGroup ? "-R" : "-W") +
- G->getValueAsString("GroupName"),
+ writeHeader(((IsRemarkGroup ? "-R" : "-W") +
+ G->getValueAsString("GroupName")).str(),
OS);
if (!IsSynonym) {
diff --git a/contrib/llvm/tools/clang/utils/TableGen/ClangOptionDocEmitter.cpp b/contrib/llvm/tools/clang/utils/TableGen/ClangOptionDocEmitter.cpp
index aa7502e2c850..59314510e0ad 100644
--- a/contrib/llvm/tools/clang/utils/TableGen/ClangOptionDocEmitter.cpp
+++ b/contrib/llvm/tools/clang/utils/TableGen/ClangOptionDocEmitter.cpp
@@ -83,7 +83,7 @@ Documentation extractDocumentation(RecordKeeper &Records) {
}
// Pretend no-X and Xno-Y options are aliases of X and XY.
- auto Name = R->getValueAsString("Name");
+ std::string Name = R->getValueAsString("Name");
if (Name.size() >= 4) {
if (Name.substr(0, 3) == "no-" && OptionsByName[Name.substr(3)]) {
Aliases[OptionsByName[Name.substr(3)]].push_back(R);
@@ -229,7 +229,7 @@ std::string getRSTStringWithTextFallback(const Record *R, StringRef Primary,
}
void emitOptionWithArgs(StringRef Prefix, const Record *Option,
- ArrayRef<std::string> Args, raw_ostream &OS) {
+ ArrayRef<StringRef> Args, raw_ostream &OS) {
OS << Prefix << escapeRST(Option->getValueAsString("Name"));
std::pair<StringRef, StringRef> Separators =
@@ -261,14 +261,15 @@ void emitOptionName(StringRef Prefix, const Record *Option, raw_ostream &OS) {
}
}
- emitOptionWithArgs(Prefix, Option, Args, OS);
+ emitOptionWithArgs(Prefix, Option, std::vector<StringRef>(Args.begin(), Args.end()), OS);
auto AliasArgs = Option->getValueAsListOfStrings("AliasArgs");
if (!AliasArgs.empty()) {
Record *Alias = Option->getValueAsDef("Alias");
OS << " (equivalent to ";
- emitOptionWithArgs(Alias->getValueAsListOfStrings("Prefixes").front(),
- Alias, Option->getValueAsListOfStrings("AliasArgs"), OS);
+ emitOptionWithArgs(
+ Alias->getValueAsListOfStrings("Prefixes").front(), Alias,
+ AliasArgs, OS);
OS << ")";
}
}
@@ -310,7 +311,7 @@ void emitOption(const DocumentedOption &Option, const Record *DocInfo,
forEachOptionName(Option, DocInfo, [&](const Record *Option) {
for (auto &Prefix : Option->getValueAsListOfStrings("Prefixes"))
SphinxOptionIDs.push_back(
- getSphinxOptionID(Prefix + Option->getValueAsString("Name")));
+ getSphinxOptionID((Prefix + Option->getValueAsString("Name")).str()));
});
assert(!SphinxOptionIDs.empty() && "no flags for option");
static std::map<std::string, int> NextSuffix;
diff --git a/contrib/llvm/tools/clang/utils/TableGen/ClangSACheckersEmitter.cpp b/contrib/llvm/tools/clang/utils/TableGen/ClangSACheckersEmitter.cpp
index 115527ae3303..8f3de0b67d77 100644
--- a/contrib/llvm/tools/clang/utils/TableGen/ClangSACheckersEmitter.cpp
+++ b/contrib/llvm/tools/clang/utils/TableGen/ClangSACheckersEmitter.cpp
@@ -51,7 +51,8 @@ static std::string getParentPackageFullName(const Record *R) {
static std::string getPackageFullName(const Record *R) {
std::string name = getParentPackageFullName(R);
if (!name.empty()) name += ".";
- return name + R->getValueAsString("PackageName");
+ name += R->getValueAsString("PackageName");
+ return name;
}
static std::string getCheckerFullName(const Record *R) {
diff --git a/contrib/llvm/tools/lld/ELF/InputSection.cpp b/contrib/llvm/tools/lld/ELF/InputSection.cpp
index 466656efbf08..4af05c1a187b 100644
--- a/contrib/llvm/tools/lld/ELF/InputSection.cpp
+++ b/contrib/llvm/tools/lld/ELF/InputSection.cpp
@@ -139,21 +139,24 @@ uint64_t SectionBase::getOffset(uint64_t Offset) const {
return Offset;
case Merge:
const MergeInputSection *MS = cast<MergeInputSection>(this);
- if (MS->MergeSec)
- return MS->MergeSec->OutSecOff + MS->getOffset(Offset);
+ if (InputSection *IS = MS->getParent())
+ return IS->OutSecOff + MS->getOffset(Offset);
return MS->getOffset(Offset);
}
llvm_unreachable("invalid section kind");
}
OutputSection *SectionBase::getOutputSection() {
+ InputSection *Sec;
if (auto *IS = dyn_cast<InputSection>(this))
- return IS->OutSec;
- if (auto *MS = dyn_cast<MergeInputSection>(this))
- return MS->MergeSec ? MS->MergeSec->OutSec : nullptr;
- if (auto *EH = dyn_cast<EhInputSection>(this))
- return EH->EHSec->OutSec;
- return cast<OutputSection>(this);
+ Sec = IS;
+ else if (auto *MS = dyn_cast<MergeInputSection>(this))
+ Sec = MS->getParent();
+ else if (auto *EH = dyn_cast<EhInputSection>(this))
+ Sec = EH->getParent();
+ else
+ return cast<OutputSection>(this);
+ return Sec ? Sec->getParent() : nullptr;
}
// Uncompress section contents. Note that this function is called
@@ -181,9 +184,15 @@ uint64_t SectionBase::getOffset(const DefinedRegular &Sym) const {
return getOffset(Sym.Value);
}
-InputSectionBase *InputSectionBase::getLinkOrderDep() const {
- if ((Flags & SHF_LINK_ORDER) && Link != 0)
- return File->getSections()[Link];
+InputSection *InputSectionBase::getLinkOrderDep() const {
+ if ((Flags & SHF_LINK_ORDER) && Link != 0) {
+ InputSectionBase *L = File->getSections()[Link];
+ if (auto *IS = dyn_cast<InputSection>(L))
+ return IS;
+ error(
+ "Merge and .eh_frame sections are not supported with SHF_LINK_ORDER " +
+ toString(L));
+ }
return nullptr;
}
@@ -295,6 +304,10 @@ bool InputSectionBase::classof(const SectionBase *S) {
return S->kind() != Output;
}
+OutputSection *InputSection::getParent() const {
+ return cast_or_null<OutputSection>(Parent);
+}
+
void InputSection::copyShtGroup(uint8_t *Buf) {
assert(this->Type == SHT_GROUP);
@@ -309,7 +322,8 @@ void InputSection::copyShtGroup(uint8_t *Buf) {
ArrayRef<InputSectionBase *> Sections = this->File->getSections();
for (uint32_t Val : From.slice(1)) {
uint32_t Index = read32(&Val, Config->Endianness);
- write32(To++, Sections[Index]->OutSec->SectionIndex, Config->Endianness);
+ write32(To++, Sections[Index]->getOutputSection()->SectionIndex,
+ Config->Endianness);
}
}
@@ -342,7 +356,7 @@ void InputSection::copyRelocations(uint8_t *Buf, ArrayRef<RelTy> Rels) {
// Output section VA is zero for -r, so r_offset is an offset within the
// section, but for --emit-relocs it is an virtual address.
- P->r_offset = RelocatedSection->OutSec->Addr +
+ P->r_offset = RelocatedSection->getOutputSection()->Addr +
RelocatedSection->getOffset(Rel.r_offset);
P->setSymbolAndType(InX::SymTab->getSymbolIndex(&Body), Type,
Config->IsMips64EL);
@@ -596,7 +610,7 @@ void InputSection::relocateNonAlloc(uint8_t *Buf, ArrayRef<RelTy> Rels) {
return;
}
- uint64_t AddrLoc = this->OutSec->Addr + Offset;
+ uint64_t AddrLoc = getParent()->Addr + Offset;
uint64_t SymVA = 0;
if (!Sym.isTls() || Out::TlsPhdr)
SymVA = SignExtend64<sizeof(typename ELFT::uint) * 8>(
@@ -729,6 +743,10 @@ EhInputSection::EhInputSection(elf::ObjectFile<ELFT> *F,
this->Live = true;
}
+SyntheticSection *EhInputSection::getParent() const {
+ return cast_or_null<SyntheticSection>(Parent);
+}
+
bool EhInputSection::classof(const SectionBase *S) {
return S->kind() == InputSectionBase::EHFrame;
}
@@ -797,6 +815,10 @@ static size_t findNull(ArrayRef<uint8_t> A, size_t EntSize) {
return StringRef::npos;
}
+SyntheticSection *MergeInputSection::getParent() const {
+ return cast_or_null<SyntheticSection>(Parent);
+}
+
// Split SHF_STRINGS section. Such section is a sequence of
// null-terminated strings.
void MergeInputSection::splitStrings(ArrayRef<uint8_t> Data, size_t EntSize) {
diff --git a/contrib/llvm/tools/lld/ELF/InputSection.h b/contrib/llvm/tools/lld/ELF/InputSection.h
index 4ef4328e8a5d..97ca2133f905 100644
--- a/contrib/llvm/tools/lld/ELF/InputSection.h
+++ b/contrib/llvm/tools/lld/ELF/InputSection.h
@@ -120,7 +120,12 @@ public:
uint64_t Entsize, uint32_t Link, uint32_t Info,
uint32_t Alignment, ArrayRef<uint8_t> Data, StringRef Name,
Kind SectionKind);
- OutputSection *OutSec = nullptr;
+
+ // Input sections are part of an output section. Special sections
+ // like .eh_frame and merge sections are first combined into a
+ // synthetic section that is then added to an output section. In all
+ // cases this points one level up.
+ SectionBase *Parent = nullptr;
// Relocations that refer to this section.
const void *FirstRelocation = nullptr;
@@ -158,7 +163,7 @@ public:
return getFile<ELFT>()->getObj();
}
- InputSectionBase *getLinkOrderDep() const;
+ InputSection *getLinkOrderDep() const;
void uncompress();
@@ -237,10 +242,7 @@ public:
SectionPiece *getSectionPiece(uint64_t Offset);
const SectionPiece *getSectionPiece(uint64_t Offset) const;
- // MergeInputSections are aggregated to a synthetic input sections,
- // and then added to an OutputSection. This pointer points to a
- // synthetic MergeSyntheticSection which this section belongs to.
- MergeSyntheticSection *MergeSec = nullptr;
+ SyntheticSection *getParent() const;
private:
void splitStrings(ArrayRef<uint8_t> A, size_t Size);
@@ -280,7 +282,8 @@ public:
// Splittable sections are handled as a sequence of data
// rather than a single large blob of data.
std::vector<EhSectionPiece> Pieces;
- SyntheticSection *EHSec = nullptr;
+
+ SyntheticSection *getParent() const;
};
// This is a section that is added directly to an output section
@@ -299,6 +302,8 @@ public:
// beginning of the output section.
template <class ELFT> void writeTo(uint8_t *Buf);
+ OutputSection *getParent() const;
+
// The offset from beginning of the output sections this section was assigned
// to. The writer sets a value.
uint64_t OutSecOff = 0;
diff --git a/contrib/llvm/tools/lld/ELF/LinkerScript.cpp b/contrib/llvm/tools/lld/ELF/LinkerScript.cpp
index 99c464e3714c..75df2cd4bd5c 100644
--- a/contrib/llvm/tools/lld/ELF/LinkerScript.cpp
+++ b/contrib/llvm/tools/lld/ELF/LinkerScript.cpp
@@ -26,6 +26,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Casting.h"
+#include "llvm/Support/Compression.h"
#include "llvm/Support/ELF.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/ErrorHandling.h"
@@ -51,9 +52,8 @@ LinkerScript *elf::Script;
uint64_t ExprValue::getValue() const {
if (Sec) {
- if (Sec->getOutputSection())
- return alignTo(Sec->getOffset(Val) + Sec->getOutputSection()->Addr,
- Alignment);
+ if (OutputSection *OS = Sec->getOutputSection())
+ return alignTo(Sec->getOffset(Val) + OS->Addr, Alignment);
error("unable to evaluate expression: input section " + Sec->Name +
" has no output section assigned");
}
@@ -85,29 +85,28 @@ template <class ELFT> static SymbolBody *addRegular(SymbolAssignment *Cmd) {
return Sym->body();
}
-OutputSection *LinkerScript::getOutputSection(const Twine &Loc,
- StringRef Name) {
- for (OutputSection *Sec : *OutputSections)
- if (Sec->Name == Name)
- return Sec;
-
- static OutputSection Dummy("", 0, 0);
- if (ErrorOnMissingSection)
- error(Loc + ": undefined section " + Name);
- return &Dummy;
+OutputSectionCommand *
+LinkerScript::createOutputSectionCommand(StringRef Name, StringRef Location) {
+ OutputSectionCommand *&CmdRef = NameToOutputSectionCommand[Name];
+ OutputSectionCommand *Cmd;
+ if (CmdRef && CmdRef->Location.empty()) {
+ // There was a forward reference.
+ Cmd = CmdRef;
+ } else {
+ Cmd = make<OutputSectionCommand>(Name);
+ if (!CmdRef)
+ CmdRef = Cmd;
+ }
+ Cmd->Location = Location;
+ return Cmd;
}
-// This function is essentially the same as getOutputSection(Name)->Size,
-// but it won't print out an error message if a given section is not found.
-//
-// Linker script does not create an output section if its content is empty.
-// We want to allow SIZEOF(.foo) where .foo is a section which happened to
-// be empty. That is why this function is different from getOutputSection().
-uint64_t LinkerScript::getOutputSectionSize(StringRef Name) {
- for (OutputSection *Sec : *OutputSections)
- if (Sec->Name == Name)
- return Sec->Size;
- return 0;
+OutputSectionCommand *
+LinkerScript::getOrCreateOutputSectionCommand(StringRef Name) {
+ OutputSectionCommand *&CmdRef = NameToOutputSectionCommand[Name];
+ if (!CmdRef)
+ CmdRef = make<OutputSectionCommand>(Name);
+ return CmdRef;
}
void LinkerScript::setDot(Expr E, const Twine &Loc, bool InSec) {
@@ -291,11 +290,13 @@ LinkerScript::computeInputSections(const InputSectionDescription *Cmd) {
size_t SizeBefore = Ret.size();
for (InputSectionBase *Sec : InputSections) {
- if (!isa<InputSection>(Sec))
+ if (Sec->Assigned)
continue;
- if (Sec->Assigned)
+ if (!Sec->Live) {
+ reportDiscarded(Sec);
continue;
+ }
// For -emit-relocs we have to ignore entries like
// .rela.dyn : { *(.rela.data) }
@@ -455,7 +456,7 @@ void LinkerScript::fabricateDefaultCommands() {
// For each OutputSection that needs a VA fabricate an OutputSectionCommand
// with an InputSectionDescription describing the InputSections
for (OutputSection *Sec : *OutputSections) {
- auto *OSCmd = make<OutputSectionCommand>(Sec->Name);
+ auto *OSCmd = createOutputSectionCommand(Sec->Name, "<internal>");
OSCmd->Sec = Sec;
SecToCommand[Sec] = OSCmd;
@@ -487,7 +488,7 @@ void LinkerScript::fabricateDefaultCommands() {
// Add sections that didn't match any sections command.
void LinkerScript::addOrphanSections(OutputSectionFactory &Factory) {
for (InputSectionBase *S : InputSections) {
- if (!S->Live || S->OutSec)
+ if (!S->Live || S->Parent)
continue;
StringRef Name = getOutputSectionName(S->Name);
auto I = std::find_if(
@@ -590,7 +591,7 @@ void LinkerScript::process(BaseCommand &Base) {
// It calculates and assigns the offsets for each section and also
// updates the output section size.
auto &Cmd = cast<InputSectionDescription>(Base);
- for (InputSectionBase *Sec : Cmd.Sections) {
+ for (InputSection *Sec : Cmd.Sections) {
// We tentatively added all synthetic sections at the beginning and removed
// empty ones afterwards (because there is no way to know whether they were
// going be empty or not other than actually running linker scripts.)
@@ -601,8 +602,8 @@ void LinkerScript::process(BaseCommand &Base) {
if (!Sec->Live)
continue;
- assert(CurOutSec == Sec->OutSec);
- output(cast<InputSection>(Sec));
+ assert(CurOutSec == Sec->getParent());
+ output(Sec);
}
}
@@ -842,7 +843,7 @@ void LinkerScript::placeOrphanSections() {
// representations agree on which input sections to use.
OutputSectionCommand *Cmd = getCmd(Sec);
if (!Cmd) {
- Cmd = make<OutputSectionCommand>(Name);
+ Cmd = createOutputSectionCommand(Name, "<internal>");
Opt.Commands.insert(CmdIter, Cmd);
++CmdIndex;
@@ -919,9 +920,10 @@ void LinkerScript::synchronize() {
}
}
-static bool allocateHeaders(std::vector<PhdrEntry> &Phdrs,
- ArrayRef<OutputSection *> OutputSections,
- uint64_t Min) {
+static bool
+allocateHeaders(std::vector<PhdrEntry> &Phdrs,
+ ArrayRef<OutputSectionCommand *> OutputSectionCommands,
+ uint64_t Min) {
auto FirstPTLoad =
std::find_if(Phdrs.begin(), Phdrs.end(),
[](const PhdrEntry &E) { return E.p_type == PT_LOAD; });
@@ -938,16 +940,19 @@ static bool allocateHeaders(std::vector<PhdrEntry> &Phdrs,
assert(FirstPTLoad->First == Out::ElfHeader);
OutputSection *ActualFirst = nullptr;
- for (OutputSection *Sec : OutputSections) {
+ for (OutputSectionCommand *Cmd : OutputSectionCommands) {
+ OutputSection *Sec = Cmd->Sec;
if (Sec->FirstInPtLoad == Out::ElfHeader) {
ActualFirst = Sec;
break;
}
}
if (ActualFirst) {
- for (OutputSection *Sec : OutputSections)
+ for (OutputSectionCommand *Cmd : OutputSectionCommands) {
+ OutputSection *Sec = Cmd->Sec;
if (Sec->FirstInPtLoad == Out::ElfHeader)
Sec->FirstInPtLoad = ActualFirst;
+ }
FirstPTLoad->First = ActualFirst;
} else {
Phdrs.erase(FirstPTLoad);
@@ -961,7 +966,9 @@ static bool allocateHeaders(std::vector<PhdrEntry> &Phdrs,
return false;
}
-void LinkerScript::assignAddresses(std::vector<PhdrEntry> &Phdrs) {
+void LinkerScript::assignAddresses(
+ std::vector<PhdrEntry> &Phdrs,
+ ArrayRef<OutputSectionCommand *> OutputSectionCommands) {
// Assign addresses as instructed by linker script SECTIONS sub-commands.
Dot = 0;
ErrorOnMissingSection = true;
@@ -983,14 +990,15 @@ void LinkerScript::assignAddresses(std::vector<PhdrEntry> &Phdrs) {
}
uint64_t MinVA = std::numeric_limits<uint64_t>::max();
- for (OutputSection *Sec : *OutputSections) {
+ for (OutputSectionCommand *Cmd : OutputSectionCommands) {
+ OutputSection *Sec = Cmd->Sec;
if (Sec->Flags & SHF_ALLOC)
MinVA = std::min<uint64_t>(MinVA, Sec->Addr);
else
Sec->Addr = 0;
}
- allocateHeaders(Phdrs, *OutputSections, MinVA);
+ allocateHeaders(Phdrs, OutputSectionCommands, MinVA);
}
// Creates program headers as instructed by PHDRS linker script command.
@@ -1068,6 +1076,33 @@ static void writeInt(uint8_t *Buf, uint64_t Data, uint64_t Size) {
llvm_unreachable("unsupported Size argument");
}
+// Compress section contents if this section contains debug info.
+template <class ELFT> void OutputSectionCommand::maybeCompress() {
+ typedef typename ELFT::Chdr Elf_Chdr;
+
+ // Compress only DWARF debug sections.
+ if (!Config->CompressDebugSections || (Sec->Flags & SHF_ALLOC) ||
+ !Name.startswith(".debug_"))
+ return;
+
+ // Create a section header.
+ Sec->ZDebugHeader.resize(sizeof(Elf_Chdr));
+ auto *Hdr = reinterpret_cast<Elf_Chdr *>(Sec->ZDebugHeader.data());
+ Hdr->ch_type = ELFCOMPRESS_ZLIB;
+ Hdr->ch_size = Sec->Size;
+ Hdr->ch_addralign = Sec->Alignment;
+
+ // Write section contents to a temporary buffer and compress it.
+ std::vector<uint8_t> Buf(Sec->Size);
+ writeTo<ELFT>(Buf.data());
+ if (Error E = zlib::compress(toStringRef(Buf), Sec->CompressedData))
+ fatal("compress failed: " + llvm::toString(std::move(E)));
+
+ // Update section headers.
+ Sec->Size = sizeof(Elf_Chdr) + Sec->CompressedData.size();
+ Sec->Flags |= SHF_COMPRESSED;
+}
+
template <class ELFT> void OutputSectionCommand::writeTo(uint8_t *Buf) {
Sec->Loc = Buf;
@@ -1084,7 +1119,12 @@ template <class ELFT> void OutputSectionCommand::writeTo(uint8_t *Buf) {
return;
// Write leading padding.
- ArrayRef<InputSection *> Sections = Sec->Sections;
+ std::vector<InputSection *> Sections;
+ for (BaseCommand *Cmd : Commands)
+ if (auto *ISD = dyn_cast<InputSectionDescription>(Cmd))
+ for (InputSection *IS : ISD->Sections)
+ if (IS->Live)
+ Sections.push_back(IS);
uint32_t Filler = getFiller();
if (Filler)
fill(Buf, Sections.empty() ? Sec->Size : Sections[0]->OutSecOff, Filler);
@@ -1161,3 +1201,8 @@ template void OutputSectionCommand::writeTo<ELF32LE>(uint8_t *Buf);
template void OutputSectionCommand::writeTo<ELF32BE>(uint8_t *Buf);
template void OutputSectionCommand::writeTo<ELF64LE>(uint8_t *Buf);
template void OutputSectionCommand::writeTo<ELF64BE>(uint8_t *Buf);
+
+template void OutputSectionCommand::maybeCompress<ELF32LE>();
+template void OutputSectionCommand::maybeCompress<ELF32BE>();
+template void OutputSectionCommand::maybeCompress<ELF64LE>();
+template void OutputSectionCommand::maybeCompress<ELF64BE>();
diff --git a/contrib/llvm/tools/lld/ELF/LinkerScript.h b/contrib/llvm/tools/lld/ELF/LinkerScript.h
index 08f60f4517a7..a708ea7f61d5 100644
--- a/contrib/llvm/tools/lld/ELF/LinkerScript.h
+++ b/contrib/llvm/tools/lld/ELF/LinkerScript.h
@@ -137,6 +137,7 @@ struct OutputSectionCommand : BaseCommand {
std::string MemoryRegionName;
template <class ELFT> void writeTo(uint8_t *Buf);
+ template <class ELFT> void maybeCompress();
uint32_t getFiller();
};
@@ -221,6 +222,8 @@ struct ScriptConfiguration {
class LinkerScript final {
llvm::DenseMap<OutputSection *, OutputSectionCommand *> SecToCommand;
+ llvm::DenseMap<StringRef, OutputSectionCommand *> NameToOutputSectionCommand;
+
void assignSymbol(SymbolAssignment *Cmd, bool InSec);
void setDot(Expr E, const Twine &Loc, bool InSec);
@@ -241,7 +244,6 @@ class LinkerScript final {
void process(BaseCommand &Base);
OutputSection *Aether;
- bool ErrorOnMissingSection = false;
uint64_t Dot;
uint64_t ThreadBssOffset = 0;
@@ -251,11 +253,14 @@ class LinkerScript final {
MemoryRegion *CurMemRegion = nullptr;
public:
+ bool ErrorOnMissingSection = false;
+ OutputSectionCommand *createOutputSectionCommand(StringRef Name,
+ StringRef Location);
+ OutputSectionCommand *getOrCreateOutputSectionCommand(StringRef Name);
+
OutputSectionCommand *getCmd(OutputSection *Sec) const;
bool hasPhdrsCommands() { return !Opt.PhdrsCommands.empty(); }
uint64_t getDot() { return Dot; }
- OutputSection *getOutputSection(const Twine &Loc, StringRef S);
- uint64_t getOutputSectionSize(StringRef S);
void discard(ArrayRef<InputSectionBase *> V);
ExprValue getSymbolValue(const Twine &Loc, StringRef S);
@@ -277,7 +282,8 @@ public:
void placeOrphanSections();
void processNonSectionCommands();
void synchronize();
- void assignAddresses(std::vector<PhdrEntry> &Phdrs);
+ void assignAddresses(std::vector<PhdrEntry> &Phdrs,
+ ArrayRef<OutputSectionCommand *> OutputSectionCommands);
void addSymbol(SymbolAssignment *Cmd);
void processCommands(OutputSectionFactory &Factory);
diff --git a/contrib/llvm/tools/lld/ELF/MarkLive.cpp b/contrib/llvm/tools/lld/ELF/MarkLive.cpp
index ee499265886e..b77c84ff75a0 100644
--- a/contrib/llvm/tools/lld/ELF/MarkLive.cpp
+++ b/contrib/llvm/tools/lld/ELF/MarkLive.cpp
@@ -220,7 +220,8 @@ template <class ELFT> void elf::markLive() {
auto MarkSymbol = [&](const SymbolBody *Sym) {
if (auto *D = dyn_cast_or_null<DefinedRegular>(Sym))
- Enqueue({cast<InputSectionBase>(D->Section), D->Value});
+ if (auto *IS = cast_or_null<InputSectionBase>(D->Section))
+ Enqueue({IS, D->Value});
};
// Add GC root symbols.
diff --git a/contrib/llvm/tools/lld/ELF/OutputSections.cpp b/contrib/llvm/tools/lld/ELF/OutputSections.cpp
index f117690c3828..4f8906a32081 100644
--- a/contrib/llvm/tools/lld/ELF/OutputSections.cpp
+++ b/contrib/llvm/tools/lld/ELF/OutputSections.cpp
@@ -16,7 +16,6 @@
#include "SyntheticSections.h"
#include "Target.h"
#include "Threads.h"
-#include "llvm/Support/Compression.h"
#include "llvm/Support/Dwarf.h"
#include "llvm/Support/MD5.h"
#include "llvm/Support/MathExtras.h"
@@ -76,46 +75,19 @@ static bool compareByFilePosition(InputSection *A, InputSection *B) {
if (A->kind() == InputSectionBase::Synthetic ||
B->kind() == InputSectionBase::Synthetic)
return false;
- auto *LA = cast<InputSection>(A->getLinkOrderDep());
- auto *LB = cast<InputSection>(B->getLinkOrderDep());
- OutputSection *AOut = LA->OutSec;
- OutputSection *BOut = LB->OutSec;
+ InputSection *LA = A->getLinkOrderDep();
+ InputSection *LB = B->getLinkOrderDep();
+ OutputSection *AOut = LA->getParent();
+ OutputSection *BOut = LB->getParent();
if (AOut != BOut)
return AOut->SectionIndex < BOut->SectionIndex;
return LA->OutSecOff < LB->OutSecOff;
}
-// Compress section contents if this section contains debug info.
-template <class ELFT> void OutputSection::maybeCompress() {
- typedef typename ELFT::Chdr Elf_Chdr;
-
- // Compress only DWARF debug sections.
- if (!Config->CompressDebugSections || (Flags & SHF_ALLOC) ||
- !Name.startswith(".debug_"))
- return;
-
- // Create a section header.
- ZDebugHeader.resize(sizeof(Elf_Chdr));
- auto *Hdr = reinterpret_cast<Elf_Chdr *>(ZDebugHeader.data());
- Hdr->ch_type = ELFCOMPRESS_ZLIB;
- Hdr->ch_size = Size;
- Hdr->ch_addralign = Alignment;
-
- // Write section contents to a temporary buffer and compress it.
- std::vector<uint8_t> Buf(Size);
- Script->getCmd(this)->writeTo<ELFT>(Buf.data());
- if (Error E = zlib::compress(toStringRef(Buf), CompressedData))
- fatal("compress failed: " + llvm::toString(std::move(E)));
-
- // Update section headers.
- Size = sizeof(Elf_Chdr) + CompressedData.size();
- Flags |= SHF_COMPRESSED;
-}
-
template <class ELFT> static void finalizeShtGroup(OutputSection *Sec) {
// sh_link field for SHT_GROUP sections should contain the section index of
// the symbol table.
- Sec->Link = InX::SymTab->OutSec->SectionIndex;
+ Sec->Link = InX::SymTab->getParent()->SectionIndex;
// sh_info then contain index of an entry in symbol table section which
// provides signature of the section group.
@@ -135,7 +107,7 @@ template <class ELFT> void OutputSection::finalize() {
// need to translate the InputSection sh_link to the OutputSection sh_link,
// all InputSections in the OutputSection have the same dependency.
if (auto *D = this->Sections.front()->getLinkOrderDep())
- this->Link = D->OutSec->SectionIndex;
+ this->Link = D->getParent()->SectionIndex;
}
uint32_t Type = this->Type;
@@ -151,11 +123,11 @@ template <class ELFT> void OutputSection::finalize() {
if (isa<SyntheticSection>(First))
return;
- this->Link = InX::SymTab->OutSec->SectionIndex;
+ this->Link = InX::SymTab->getParent()->SectionIndex;
// sh_info for SHT_REL[A] sections should contain the section header index of
// the section to which the relocation applies.
InputSectionBase *S = First->getRelocatedSection();
- this->Info = S->OutSec->SectionIndex;
+ Info = S->getOutputSection()->SectionIndex;
}
static uint64_t updateOffset(uint64_t Off, InputSection *S) {
@@ -167,7 +139,7 @@ static uint64_t updateOffset(uint64_t Off, InputSection *S) {
void OutputSection::addSection(InputSection *S) {
assert(S->Live);
Sections.push_back(S);
- S->OutSec = this;
+ S->Parent = this;
this->updateAlignment(S->Alignment);
// The actual offsets will be computed by assignAddresses. For now, use
@@ -351,7 +323,7 @@ static bool canMergeToProgbits(unsigned Type) {
Type == SHT_NOTE;
}
-static void reportDiscarded(InputSectionBase *IS) {
+void elf::reportDiscarded(InputSectionBase *IS) {
if (!Config->PrintGcSections)
return;
message("removing unused section from '" + IS->Name + "' in file '" +
@@ -437,8 +409,3 @@ template void OutputSection::finalize<ELF32LE>();
template void OutputSection::finalize<ELF32BE>();
template void OutputSection::finalize<ELF64LE>();
template void OutputSection::finalize<ELF64BE>();
-
-template void OutputSection::maybeCompress<ELF32LE>();
-template void OutputSection::maybeCompress<ELF32BE>();
-template void OutputSection::maybeCompress<ELF64LE>();
-template void OutputSection::maybeCompress<ELF64BE>();
diff --git a/contrib/llvm/tools/lld/ELF/OutputSections.h b/contrib/llvm/tools/lld/ELF/OutputSections.h
index 08655a9ed67b..326348cd5a20 100644
--- a/contrib/llvm/tools/lld/ELF/OutputSections.h
+++ b/contrib/llvm/tools/lld/ELF/OutputSections.h
@@ -83,7 +83,6 @@ public:
void sortInitFini();
void sortCtorsDtors();
template <class ELFT> void finalize();
- template <class ELFT> void maybeCompress();
void assignOffsets();
std::vector<InputSection *> Sections;
@@ -149,6 +148,7 @@ private:
};
uint64_t getHeaderSize();
+void reportDiscarded(InputSectionBase *IS);
} // namespace elf
} // namespace lld
diff --git a/contrib/llvm/tools/lld/ELF/Relocations.cpp b/contrib/llvm/tools/lld/ELF/Relocations.cpp
index 5564ea246eeb..54cc6dd89d46 100644
--- a/contrib/llvm/tools/lld/ELF/Relocations.cpp
+++ b/contrib/llvm/tools/lld/ELF/Relocations.cpp
@@ -360,9 +360,9 @@ static bool isStaticLinkTimeConstant(RelExpr E, uint32_t Type,
// These expressions always compute a constant
if (isRelExprOneOf<R_SIZE, R_GOT_FROM_END, R_GOT_OFF, R_MIPS_GOT_LOCAL_PAGE,
R_MIPS_GOT_OFF, R_MIPS_GOT_OFF32, R_MIPS_GOT_GP_PC,
- R_MIPS_TLSGD, R_GOT_PAGE_PC, R_GOT_PC, R_PLT_PC,
- R_TLSGD_PC, R_TLSGD, R_PPC_PLT_OPD, R_TLSDESC_CALL,
- R_TLSDESC_PAGE, R_HINT>(E))
+ R_MIPS_TLSGD, R_GOT_PAGE_PC, R_GOT_PC,
+ R_GOTONLY_PC_FROM_END, R_PLT_PC, R_TLSGD_PC, R_TLSGD,
+ R_PPC_PLT_OPD, R_TLSDESC_CALL, R_TLSDESC_PAGE, R_HINT>(E))
return true;
// These never do, except if the entire file is position dependent or if
@@ -1015,7 +1015,7 @@ ThunkSection *ThunkCreator::getISThunkSec(InputSection *IS, OutputSection *OS) {
ThunkSection *TS = ThunkedSections.lookup(IS);
if (TS)
return TS;
- auto *TOS = cast<OutputSection>(IS->OutSec);
+ auto *TOS = IS->getParent();
TS = make<ThunkSection>(TOS, IS->OutSecOff);
ThunkSections[TOS].push_back(TS);
ThunkedSections[IS] = TS;
diff --git a/contrib/llvm/tools/lld/ELF/ScriptParser.cpp b/contrib/llvm/tools/lld/ELF/ScriptParser.cpp
index 4b77e35b9bae..02212fa8ba14 100644
--- a/contrib/llvm/tools/lld/ELF/ScriptParser.cpp
+++ b/contrib/llvm/tools/lld/ELF/ScriptParser.cpp
@@ -55,6 +55,7 @@ public:
private:
void addFile(StringRef Path);
+ OutputSection *checkSection(OutputSectionCommand *Cmd, StringRef Loccation);
void readAsNeeded();
void readEntry();
@@ -564,8 +565,8 @@ uint32_t ScriptParser::readFill() {
OutputSectionCommand *
ScriptParser::readOutputSectionDescription(StringRef OutSec) {
- OutputSectionCommand *Cmd = make<OutputSectionCommand>(OutSec);
- Cmd->Location = getCurrentLocation();
+ OutputSectionCommand *Cmd =
+ Script->createOutputSectionCommand(OutSec, getCurrentLocation());
// Read an address expression.
// https://sourceware.org/binutils/docs/ld/Output-Section-Address.html
@@ -819,6 +820,16 @@ StringRef ScriptParser::readParenLiteral() {
return Tok;
}
+OutputSection *ScriptParser::checkSection(OutputSectionCommand *Cmd,
+ StringRef Location) {
+ if (Cmd->Location.empty() && Script->ErrorOnMissingSection)
+ error(Location + ": undefined section " + Cmd->Name);
+ if (Cmd->Sec)
+ return Cmd->Sec;
+ static OutputSection Dummy("", 0, 0);
+ return &Dummy;
+}
+
Expr ScriptParser::readPrimary() {
if (peek() == "(")
return readParenExpr();
@@ -847,9 +858,8 @@ Expr ScriptParser::readPrimary() {
}
if (Tok == "ADDR") {
StringRef Name = readParenLiteral();
- return [=]() -> ExprValue {
- return {Script->getOutputSection(Location, Name), 0};
- };
+ OutputSectionCommand *Cmd = Script->getOrCreateOutputSectionCommand(Name);
+ return [=]() -> ExprValue { return {checkSection(Cmd, Location), 0}; };
}
if (Tok == "ALIGN") {
expect("(");
@@ -867,7 +877,8 @@ Expr ScriptParser::readPrimary() {
}
if (Tok == "ALIGNOF") {
StringRef Name = readParenLiteral();
- return [=] { return Script->getOutputSection(Location, Name)->Alignment; };
+ OutputSectionCommand *Cmd = Script->getOrCreateOutputSectionCommand(Name);
+ return [=] { return checkSection(Cmd, Location)->Alignment; };
}
if (Tok == "ASSERT")
return readAssertExpr();
@@ -912,7 +923,8 @@ Expr ScriptParser::readPrimary() {
}
if (Tok == "LOADADDR") {
StringRef Name = readParenLiteral();
- return [=] { return Script->getOutputSection(Location, Name)->getLMA(); };
+ OutputSectionCommand *Cmd = Script->getOrCreateOutputSectionCommand(Name);
+ return [=] { return checkSection(Cmd, Location)->getLMA(); };
}
if (Tok == "ORIGIN") {
StringRef Name = readParenLiteral();
@@ -930,7 +942,11 @@ Expr ScriptParser::readPrimary() {
}
if (Tok == "SIZEOF") {
StringRef Name = readParenLiteral();
- return [=] { return Script->getOutputSectionSize(Name); };
+ OutputSectionCommand *Cmd = Script->getOrCreateOutputSectionCommand(Name);
+ // Linker script does not create an output section if its content is empty.
+ // We want to allow SIZEOF(.foo) where .foo is a section which happened to
+ // be empty.
+ return [=] { return Cmd->Sec ? Cmd->Sec->Size : 0; };
}
if (Tok == "SIZEOF_HEADERS")
return [=] { return elf::getHeaderSize(); };
diff --git a/contrib/llvm/tools/lld/ELF/Symbols.cpp b/contrib/llvm/tools/lld/ELF/Symbols.cpp
index 7ce1f5354b1b..67e57d9c8f00 100644
--- a/contrib/llvm/tools/lld/ELF/Symbols.cpp
+++ b/contrib/llvm/tools/lld/ELF/Symbols.cpp
@@ -101,12 +101,12 @@ static uint64_t getSymVA(const SymbolBody &Body, int64_t &Addend) {
case SymbolBody::DefinedCommonKind:
if (!Config->DefineCommon)
return 0;
- return InX::Common->OutSec->Addr + InX::Common->OutSecOff +
+ return InX::Common->getParent()->Addr + InX::Common->OutSecOff +
cast<DefinedCommon>(Body).Offset;
case SymbolBody::SharedKind: {
auto &SS = cast<SharedSymbol>(Body);
if (SS.NeedsCopy)
- return SS.CopyRelSec->OutSec->Addr + SS.CopyRelSec->OutSecOff +
+ return SS.CopyRelSec->getParent()->Addr + SS.CopyRelSec->OutSecOff +
SS.CopyRelSecOff;
if (SS.NeedsPltAddr)
return Body.getPltVA();
@@ -207,13 +207,13 @@ OutputSection *SymbolBody::getOutputSection() const {
if (auto *S = dyn_cast<SharedSymbol>(this)) {
if (S->NeedsCopy)
- return S->CopyRelSec->OutSec;
+ return S->CopyRelSec->getParent();
return nullptr;
}
if (isa<DefinedCommon>(this)) {
if (Config->DefineCommon)
- return InX::Common->OutSec;
+ return InX::Common->getParent();
return nullptr;
}
diff --git a/contrib/llvm/tools/lld/ELF/SyntheticSections.cpp b/contrib/llvm/tools/lld/ELF/SyntheticSections.cpp
index d3db32613a8a..223fc9a0fd07 100644
--- a/contrib/llvm/tools/lld/ELF/SyntheticSections.cpp
+++ b/contrib/llvm/tools/lld/ELF/SyntheticSections.cpp
@@ -48,8 +48,8 @@ using namespace lld;
using namespace lld::elf;
uint64_t SyntheticSection::getVA() const {
- if (this->OutSec)
- return this->OutSec->Addr + this->OutSecOff;
+ if (OutputSection *Sec = getParent())
+ return Sec->Addr + OutSecOff;
return 0;
}
@@ -367,8 +367,8 @@ BssSection::BssSection(StringRef Name)
: SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_NOBITS, 0, Name) {}
size_t BssSection::reserveSpace(uint64_t Size, uint32_t Alignment) {
- if (OutSec)
- OutSec->updateAlignment(Alignment);
+ if (OutputSection *Sec = getParent())
+ Sec->updateAlignment(Alignment);
this->Size = alignTo(this->Size, Alignment) + Size;
this->Alignment = std::max(this->Alignment, Alignment);
return this->Size - Size;
@@ -494,7 +494,7 @@ void EhFrameSection<ELFT>::addSectionAux(EhInputSection *Sec,
template <class ELFT>
void EhFrameSection<ELFT>::addSection(InputSectionBase *C) {
auto *Sec = cast<EhInputSection>(C);
- Sec->EHSec = this;
+ Sec->Parent = this;
updateAlignment(Sec->Alignment);
Sections.push_back(Sec);
for (auto *DS : Sec->DependentSections)
@@ -579,7 +579,7 @@ uint64_t EhFrameSection<ELFT>::getFdePc(uint8_t *Buf, size_t FdeOff,
if ((Enc & 0x70) == DW_EH_PE_absptr)
return Addr;
if ((Enc & 0x70) == DW_EH_PE_pcrel)
- return Addr + this->OutSec->Addr + Off;
+ return Addr + getParent()->Addr + Off;
fatal("unknown FDE size relative encoding");
}
@@ -610,7 +610,7 @@ template <class ELFT> void EhFrameSection<ELFT>::writeTo(uint8_t *Buf) {
uint8_t Enc = getFdeEncoding<ELFT>(Cie->Piece);
for (SectionPiece *Fde : Cie->FdePieces) {
uint64_t Pc = getFdePc(Buf, Fde->OutputOff, Enc);
- uint64_t FdeVA = this->OutSec->Addr + Fde->OutputOff;
+ uint64_t FdeVA = getParent()->Addr + Fde->OutputOff;
In<ELFT>::EhFrameHdr->addFde(Pc, FdeVA);
}
}
@@ -698,8 +698,7 @@ void MipsGotSection::addEntry(SymbolBody &Sym, int64_t Addend, RelExpr Expr) {
// sections referenced by GOT relocations. Then later in the `finalize`
// method calculate number of "pages" required to cover all saved output
// section and allocate appropriate number of GOT entries.
- auto *DefSym = cast<DefinedRegular>(&Sym);
- PageIndexMap.insert({DefSym->Section->getOutputSection(), 0});
+ PageIndexMap.insert({Sym.getOutputSection(), 0});
return;
}
if (Sym.isTls()) {
@@ -766,8 +765,7 @@ static uint64_t getMipsPageCount(uint64_t Size) {
uint64_t MipsGotSection::getPageEntryOffset(const SymbolBody &B,
int64_t Addend) const {
- const OutputSection *OutSec =
- cast<DefinedRegular>(&B)->Section->getOutputSection();
+ const OutputSection *OutSec = B.getOutputSection();
uint64_t SecAddr = getMipsPageAddr(OutSec->Addr);
uint64_t SymAddr = getMipsPageAddr(B.getVA(Addend));
uint64_t Index = PageIndexMap.lookup(OutSec) + (SymAddr - SecAddr) / 0xffff;
@@ -1071,11 +1069,11 @@ template <class ELFT> void DynamicSection<ELFT>::finalizeContents() {
if (this->Size)
return; // Already finalized.
- this->Link = InX::DynStrTab->OutSec->SectionIndex;
- if (In<ELFT>::RelaDyn->OutSec->Size > 0) {
+ this->Link = InX::DynStrTab->getParent()->SectionIndex;
+ if (In<ELFT>::RelaDyn->getParent()->Size > 0) {
bool IsRela = Config->IsRela;
add({IsRela ? DT_RELA : DT_REL, In<ELFT>::RelaDyn});
- add({IsRela ? DT_RELASZ : DT_RELSZ, In<ELFT>::RelaDyn->OutSec->Size});
+ add({IsRela ? DT_RELASZ : DT_RELSZ, In<ELFT>::RelaDyn->getParent()->Size});
add({IsRela ? DT_RELAENT : DT_RELENT,
uint64_t(IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel))});
@@ -1088,9 +1086,9 @@ template <class ELFT> void DynamicSection<ELFT>::finalizeContents() {
add({IsRela ? DT_RELACOUNT : DT_RELCOUNT, NumRelativeRels});
}
}
- if (In<ELFT>::RelaPlt->OutSec->Size > 0) {
+ if (In<ELFT>::RelaPlt->getParent()->Size > 0) {
add({DT_JMPREL, In<ELFT>::RelaPlt});
- add({DT_PLTRELSZ, In<ELFT>::RelaPlt->OutSec->Size});
+ add({DT_PLTRELSZ, In<ELFT>::RelaPlt->getParent()->Size});
add({Config->EMachine == EM_MIPS ? DT_MIPS_PLTGOT : DT_PLTGOT,
InX::GotPlt});
add({DT_PLTREL, uint64_t(Config->IsRela ? DT_RELA : DT_REL)});
@@ -1152,7 +1150,7 @@ template <class ELFT> void DynamicSection<ELFT>::finalizeContents() {
add({DT_MIPS_RLD_MAP, InX::MipsRldMap});
}
- this->OutSec->Link = this->Link;
+ getParent()->Link = this->Link;
// +1 for DT_NULL
this->Size = (Entries.size() + 1) * this->Entsize;
@@ -1168,7 +1166,7 @@ template <class ELFT> void DynamicSection<ELFT>::writeTo(uint8_t *Buf) {
P->d_un.d_ptr = E.OutSec->Addr;
break;
case Entry::InSecAddr:
- P->d_un.d_ptr = E.InSec->OutSec->Addr + E.InSec->OutSecOff;
+ P->d_un.d_ptr = E.InSec->getParent()->Addr + E.InSec->OutSecOff;
break;
case Entry::SecSize:
P->d_un.d_val = E.OutSec->Size;
@@ -1185,7 +1183,7 @@ template <class ELFT> void DynamicSection<ELFT>::writeTo(uint8_t *Buf) {
}
uint64_t DynamicReloc::getOffset() const {
- return InputSec->OutSec->Addr + InputSec->getOffset(OffsetInSec);
+ return InputSec->getOutputSection()->Addr + InputSec->getOffset(OffsetInSec);
}
int64_t DynamicReloc::getAddend() const {
@@ -1258,11 +1256,11 @@ template <class ELFT> unsigned RelocationSection<ELFT>::getRelocOffset() {
}
template <class ELFT> void RelocationSection<ELFT>::finalizeContents() {
- this->Link = InX::DynSymTab ? InX::DynSymTab->OutSec->SectionIndex
- : InX::SymTab->OutSec->SectionIndex;
+ this->Link = InX::DynSymTab ? InX::DynSymTab->getParent()->SectionIndex
+ : InX::SymTab->getParent()->SectionIndex;
// Set required output section properties.
- this->OutSec->Link = this->Link;
+ getParent()->Link = this->Link;
}
SymbolTableBaseSection::SymbolTableBaseSection(StringTableSection &StrTabSec)
@@ -1293,14 +1291,14 @@ static bool sortMipsSymbols(const SymbolTableEntry &L,
// function. (For .dynsym, we don't do that because symbols for
// dynamic linking are inherently all globals.)
void SymbolTableBaseSection::finalizeContents() {
- this->OutSec->Link = StrTabSec.OutSec->SectionIndex;
+ getParent()->Link = StrTabSec.getParent()->SectionIndex;
// If it is a .dynsym, there should be no local symbols, but we need
// to do a few things for the dynamic linker.
if (this->Type == SHT_DYNSYM) {
// Section's Info field has the index of the first non-local symbol.
// Because the first symbol entry is a null entry, 1 is the first.
- this->OutSec->Info = 1;
+ getParent()->Info = 1;
if (InX::GnuHashTab) {
// NB: It also sorts Symbols to meet the GNU hash table requirements.
@@ -1326,7 +1324,7 @@ void SymbolTableBaseSection::postThunkContents() {
S.Symbol->symbol()->computeBinding() == STB_LOCAL;
});
size_t NumLocals = It - Symbols.begin();
- this->OutSec->Info = NumLocals + 1;
+ getParent()->Info = NumLocals + 1;
}
void SymbolTableBaseSection::addSymbol(SymbolBody *B) {
@@ -1344,8 +1342,7 @@ size_t SymbolTableBaseSection::getSymbolIndex(SymbolBody *Body) {
// This is used for -r, so we have to handle multiple section
// symbols being combined.
if (Body->Type == STT_SECTION && E.Symbol->Type == STT_SECTION)
- return cast<DefinedRegular>(Body)->Section->getOutputSection() ==
- cast<DefinedRegular>(E.Symbol)->Section->getOutputSection();
+ return Body->getOutputSection() == E.Symbol->getOutputSection();
return false;
});
if (I == Symbols.end())
@@ -1456,7 +1453,7 @@ GnuHashTableSection::GnuHashTableSection()
}
void GnuHashTableSection::finalizeContents() {
- this->OutSec->Link = InX::DynSymTab->OutSec->SectionIndex;
+ getParent()->Link = InX::DynSymTab->getParent()->SectionIndex;
// Computes bloom filter size in word size. We want to allocate 8
// bits for each symbol. It must be a power of two.
@@ -1590,7 +1587,7 @@ HashTableSection<ELFT>::HashTableSection()
}
template <class ELFT> void HashTableSection<ELFT>::finalizeContents() {
- this->OutSec->Link = InX::DynSymTab->OutSec->SectionIndex;
+ getParent()->Link = InX::DynSymTab->getParent()->SectionIndex;
unsigned NumEntries = 2; // nbucket and nchain.
NumEntries += InX::DynSymTab->getNumSymbols(); // The chain entries.
@@ -1801,7 +1798,7 @@ void GdbIndexSection::finalizeContents() {
for (InputSectionBase *S : InputSections)
if (InputSection *IS = dyn_cast<InputSection>(S))
- if (IS->OutSec && IS->Name == ".debug_info")
+ if (IS->getParent() && IS->Name == ".debug_info")
readDwarf(IS);
SymbolTable.finalizeContents();
@@ -1846,7 +1843,7 @@ void GdbIndexSection::writeTo(uint8_t *Buf) {
// Write the address area.
for (AddressEntry &E : AddressArea) {
- uint64_t BaseAddr = E.Section->OutSec->Addr + E.Section->getOffset(0);
+ uint64_t BaseAddr = E.Section->getParent()->Addr + E.Section->getOffset(0);
write64le(Buf, BaseAddr + E.LowAddress);
write64le(Buf + 8, BaseAddr + E.HighAddress);
write32le(Buf + 16, E.CuIndex);
@@ -1906,7 +1903,7 @@ template <class ELFT> void EhFrameHeader<ELFT>::writeTo(uint8_t *Buf) {
Buf[1] = DW_EH_PE_pcrel | DW_EH_PE_sdata4;
Buf[2] = DW_EH_PE_udata4;
Buf[3] = DW_EH_PE_datarel | DW_EH_PE_sdata4;
- write32<E>(Buf + 4, In<ELFT>::EhFrame->OutSec->Addr - this->getVA() - 4);
+ write32<E>(Buf + 4, In<ELFT>::EhFrame->getParent()->Addr - this->getVA() - 4);
write32<E>(Buf + 8, Fdes.size());
Buf += 12;
@@ -1948,12 +1945,12 @@ template <class ELFT> void VersionDefinitionSection<ELFT>::finalizeContents() {
for (VersionDefinition &V : Config->VersionDefinitions)
V.NameOff = InX::DynStrTab->addString(V.Name);
- this->OutSec->Link = InX::DynStrTab->OutSec->SectionIndex;
+ getParent()->Link = InX::DynStrTab->getParent()->SectionIndex;
// sh_info should be set to the number of definitions. This fact is missed in
// documentation, but confirmed by binutils community:
// https://sourceware.org/ml/binutils/2014-11/msg00355.html
- this->OutSec->Info = getVerDefNum();
+ getParent()->Info = getVerDefNum();
}
template <class ELFT>
@@ -2001,7 +1998,7 @@ VersionTableSection<ELFT>::VersionTableSection()
template <class ELFT> void VersionTableSection<ELFT>::finalizeContents() {
// At the moment of june 2016 GNU docs does not mention that sh_link field
// should be set, but Sun docs do. Also readelf relies on this field.
- this->OutSec->Link = InX::DynSymTab->OutSec->SectionIndex;
+ getParent()->Link = InX::DynSymTab->getParent()->SectionIndex;
}
template <class ELFT> size_t VersionTableSection<ELFT>::getSize() const {
@@ -2093,8 +2090,8 @@ template <class ELFT> void VersionNeedSection<ELFT>::writeTo(uint8_t *Buf) {
}
template <class ELFT> void VersionNeedSection<ELFT>::finalizeContents() {
- this->OutSec->Link = InX::DynStrTab->OutSec->SectionIndex;
- this->OutSec->Info = Needed.size();
+ getParent()->Link = InX::DynStrTab->getParent()->SectionIndex;
+ getParent()->Info = Needed.size();
}
template <class ELFT> size_t VersionNeedSection<ELFT>::getSize() const {
@@ -2115,7 +2112,7 @@ MergeSyntheticSection::MergeSyntheticSection(StringRef Name, uint32_t Type,
void MergeSyntheticSection::addSection(MergeInputSection *MS) {
assert(!Finalized);
- MS->MergeSec = this;
+ MS->Parent = this;
Sections.push_back(MS);
}
@@ -2186,13 +2183,23 @@ ARMExidxSentinelSection::ARMExidxSentinelSection()
// This section will have been sorted last in the .ARM.exidx table.
// This table entry will have the form:
// | PREL31 upper bound of code that has exception tables | EXIDX_CANTUNWIND |
+// The sentinel must have the PREL31 value of an address higher than any
+// address described by any other table entry.
void ARMExidxSentinelSection::writeTo(uint8_t *Buf) {
- // Get the InputSection before us, we are by definition last
- auto RI = this->OutSec->Sections.rbegin();
- InputSection *LE = *(++RI);
- InputSection *LC = cast<InputSection>(LE->getLinkOrderDep());
- uint64_t S = LC->OutSec->Addr + LC->getOffset(LC->getSize());
- uint64_t P = this->getVA();
+ // The Sections are sorted in order of ascending PREL31 address with the
+ // sentinel last. We need to find the InputSection that precedes the
+ // sentinel. By construction the Sentinel is in the last
+ // InputSectionDescription as the InputSection that precedes it.
+ OutputSectionCommand *C = Script->getCmd(getParent());
+ auto ISD = std::find_if(C->Commands.rbegin(), C->Commands.rend(),
+ [](const BaseCommand *Base) {
+ return isa<InputSectionDescription>(Base);
+ });
+ auto L = cast<InputSectionDescription>(*ISD);
+ InputSection *Highest = L->Sections[L->Sections.size() - 2];
+ InputSection *LS = Highest->getLinkOrderDep();
+ uint64_t S = LS->getParent()->Addr + LS->getOffset(LS->getSize());
+ uint64_t P = getVA();
Target->relocateOne(Buf, R_ARM_PREL31, S - P);
write32le(Buf + 4, 0x1);
}
@@ -2200,7 +2207,7 @@ void ARMExidxSentinelSection::writeTo(uint8_t *Buf) {
ThunkSection::ThunkSection(OutputSection *OS, uint64_t Off)
: SyntheticSection(SHF_ALLOC | SHF_EXECINSTR, SHT_PROGBITS,
Config->Wordsize, ".text.thunk") {
- this->OutSec = OS;
+ this->Parent = OS;
this->OutSecOff = Off;
}
diff --git a/contrib/llvm/tools/lld/ELF/SyntheticSections.h b/contrib/llvm/tools/lld/ELF/SyntheticSections.h
index 61cc03de222e..b47d2fab24ec 100644
--- a/contrib/llvm/tools/lld/ELF/SyntheticSections.h
+++ b/contrib/llvm/tools/lld/ELF/SyntheticSections.h
@@ -53,7 +53,7 @@ public:
virtual bool empty() const { return false; }
uint64_t getVA() const;
- static bool classof(const InputSectionBase *D) {
+ static bool classof(const SectionBase *D) {
return D->kind() == InputSectionBase::Synthetic;
}
};
diff --git a/contrib/llvm/tools/lld/ELF/Target.cpp b/contrib/llvm/tools/lld/ELF/Target.cpp
index cf7d912ad829..b6c6e7089365 100644
--- a/contrib/llvm/tools/lld/ELF/Target.cpp
+++ b/contrib/llvm/tools/lld/ELF/Target.cpp
@@ -62,10 +62,10 @@ static void or32be(uint8_t *P, int32_t V) { write32be(P, read32be(P) | V); }
template <class ELFT> static std::string getErrorLoc(const uint8_t *Loc) {
for (InputSectionBase *D : InputSections) {
auto *IS = dyn_cast_or_null<InputSection>(D);
- if (!IS || !IS->OutSec)
+ if (!IS || !IS->getParent())
continue;
- uint8_t *ISLoc = cast<OutputSection>(IS->OutSec)->Loc + IS->OutSecOff;
+ uint8_t *ISLoc = IS->getParent()->Loc + IS->OutSecOff;
if (ISLoc <= Loc && Loc < ISLoc + IS->getSize())
return IS->template getLocation<ELFT>(Loc - ISLoc) + ": ";
}
diff --git a/contrib/llvm/tools/lld/ELF/Writer.cpp b/contrib/llvm/tools/lld/ELF/Writer.cpp
index 77ffe055b2de..0464bff348da 100644
--- a/contrib/llvm/tools/lld/ELF/Writer.cpp
+++ b/contrib/llvm/tools/lld/ELF/Writer.cpp
@@ -261,23 +261,26 @@ template <class ELFT> void Writer<ELFT>::run() {
if (!Config->Relocatable)
fixSectionAlignments();
Script->fabricateDefaultCommands();
+ } else {
+ Script->synchronize();
}
for (BaseCommand *Base : Script->Opt.Commands)
if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base))
OutputSectionCommands.push_back(Cmd);
+ clearOutputSections();
// If -compressed-debug-sections is specified, we need to compress
// .debug_* sections. Do it right now because it changes the size of
// output sections.
- parallelForEach(OutputSections.begin(), OutputSections.end(),
- [](OutputSection *S) { S->maybeCompress<ELFT>(); });
+ parallelForEach(
+ OutputSectionCommands.begin(), OutputSectionCommands.end(),
+ [](OutputSectionCommand *Cmd) { Cmd->maybeCompress<ELFT>(); });
if (Config->Relocatable) {
assignFileOffsets();
} else {
- Script->synchronize();
- Script->assignAddresses(Phdrs);
+ Script->assignAddresses(Phdrs, OutputSectionCommands);
// Remove empty PT_LOAD to avoid causing the dynamic linker to try to mmap a
// 0 sized region. This has to be done late since only after assignAddresses
@@ -300,13 +303,13 @@ template <class ELFT> void Writer<ELFT>::run() {
openFile();
if (ErrorCount)
return;
+
if (!Config->OFormatBinary) {
writeHeader();
writeSections();
} else {
writeSectionsBinary();
}
- clearOutputSections();
// Backfill .note.gnu.build-id section content. This is done at last
// because the content is usually a hash value of the entire output file.
@@ -613,27 +616,27 @@ bool elf::isRelroSection(const OutputSection *Sec) {
// .got contains pointers to external symbols. They are resolved by
// the dynamic linker when a module is loaded into memory, and after
// that they are not expected to change. So, it can be in RELRO.
- if (InX::Got && Sec == InX::Got->OutSec)
+ if (InX::Got && Sec == InX::Got->getParent())
return true;
// .got.plt contains pointers to external function symbols. They are
// by default resolved lazily, so we usually cannot put it into RELRO.
// However, if "-z now" is given, the lazy symbol resolution is
// disabled, which enables us to put it into RELRO.
- if (Sec == InX::GotPlt->OutSec)
+ if (Sec == InX::GotPlt->getParent())
return Config->ZNow;
// .dynamic section contains data for the dynamic linker, and
// there's no need to write to it at runtime, so it's better to put
// it into RELRO.
- if (Sec == InX::Dynamic->OutSec)
+ if (Sec == InX::Dynamic->getParent())
return true;
// .bss.rel.ro is used for copy relocations for read-only symbols.
// Since the dynamic linker needs to process copy relocations, the
// section cannot be read-only, but once initialized, they shouldn't
// change.
- if (Sec == InX::BssRelRo->OutSec)
+ if (Sec == InX::BssRelRo->getParent())
return true;
// Sections with some special names are put into RELRO. This is a
@@ -1112,9 +1115,9 @@ template <class ELFT> void Writer<ELFT>::sortSections() {
static void applySynthetic(const std::vector<SyntheticSection *> &Sections,
std::function<void(SyntheticSection *)> Fn) {
for (SyntheticSection *SS : Sections)
- if (SS && SS->OutSec && !SS->empty()) {
+ if (SS && SS->getParent() && !SS->empty()) {
Fn(SS);
- SS->OutSec->assignOffsets();
+ SS->getParent()->assignOffsets();
}
}
@@ -1130,16 +1133,15 @@ static void removeUnusedSyntheticSections(std::vector<OutputSection *> &V) {
SyntheticSection *SS = dyn_cast<SyntheticSection>(S);
if (!SS)
return;
- if (!SS->empty() || !SS->OutSec)
+ OutputSection *OS = SS->getParent();
+ if (!SS->empty() || !OS)
continue;
-
- SS->OutSec->Sections.erase(std::find(SS->OutSec->Sections.begin(),
- SS->OutSec->Sections.end(), SS));
+ OS->Sections.erase(std::find(OS->Sections.begin(), OS->Sections.end(), SS));
SS->Live = false;
// If there are no other sections in the output section, remove it from the
// output.
- if (SS->OutSec->Sections.empty())
- V.erase(std::find(V.begin(), V.end(), SS->OutSec));
+ if (OS->Sections.empty())
+ V.erase(std::find(V.begin(), V.end(), OS));
}
}
@@ -1427,8 +1429,8 @@ template <class ELFT> std::vector<PhdrEntry> Writer<ELFT>::createPhdrs() {
// Add an entry for .dynamic.
if (InX::DynSymTab)
- AddHdr(PT_DYNAMIC, InX::Dynamic->OutSec->getPhdrFlags())
- ->add(InX::Dynamic->OutSec);
+ AddHdr(PT_DYNAMIC, InX::Dynamic->getParent()->getPhdrFlags())
+ ->add(InX::Dynamic->getParent());
// PT_GNU_RELRO includes all sections that should be marked as
// read-only by dynamic linker after proccessing relocations.
@@ -1441,9 +1443,9 @@ template <class ELFT> std::vector<PhdrEntry> Writer<ELFT>::createPhdrs() {
// PT_GNU_EH_FRAME is a special section pointing on .eh_frame_hdr.
if (!In<ELFT>::EhFrame->empty() && In<ELFT>::EhFrameHdr &&
- In<ELFT>::EhFrame->OutSec && In<ELFT>::EhFrameHdr->OutSec)
- AddHdr(PT_GNU_EH_FRAME, In<ELFT>::EhFrameHdr->OutSec->getPhdrFlags())
- ->add(In<ELFT>::EhFrameHdr->OutSec);
+ In<ELFT>::EhFrame->getParent() && In<ELFT>::EhFrameHdr->getParent())
+ AddHdr(PT_GNU_EH_FRAME, In<ELFT>::EhFrameHdr->getParent()->getPhdrFlags())
+ ->add(In<ELFT>::EhFrameHdr->getParent());
// PT_OPENBSD_RANDOMIZE is an OpenBSD-specific feature. That makes
// the dynamic linker fill the segment with random data.
@@ -1556,9 +1558,11 @@ static uint64_t setOffset(OutputSection *Sec, uint64_t Off) {
template <class ELFT> void Writer<ELFT>::assignFileOffsetsBinary() {
uint64_t Off = 0;
- for (OutputSection *Sec : OutputSections)
+ for (OutputSectionCommand *Cmd : OutputSectionCommands) {
+ OutputSection *Sec = Cmd->Sec;
if (Sec->Flags & SHF_ALLOC)
Off = setOffset(Sec, Off);
+ }
FileSize = alignTo(Off, Config->Wordsize);
}
@@ -1568,11 +1572,12 @@ template <class ELFT> void Writer<ELFT>::assignFileOffsets() {
Off = setOffset(Out::ElfHeader, Off);
Off = setOffset(Out::ProgramHeaders, Off);
- for (OutputSection *Sec : OutputSections)
- Off = setOffset(Sec, Off);
+ for (OutputSectionCommand *Cmd : OutputSectionCommands)
+ Off = setOffset(Cmd->Sec, Off);
SectionHeaderOff = alignTo(Off, Config->Wordsize);
- FileSize = SectionHeaderOff + (OutputSections.size() + 1) * sizeof(Elf_Shdr);
+ FileSize =
+ SectionHeaderOff + (OutputSectionCommands.size() + 1) * sizeof(Elf_Shdr);
}
// Finalize the program headers. We call this function after we assign
@@ -1690,16 +1695,15 @@ template <class ELFT> void Writer<ELFT>::fixPredefinedSymbols() {
// Setup MIPS _gp_disp/__gnu_local_gp symbols which should
// be equal to the _gp symbol's value.
- if (Config->EMachine == EM_MIPS) {
- if (!ElfSym::MipsGp->Value) {
- // Find GP-relative section with the lowest address
- // and use this address to calculate default _gp value.
- uint64_t Gp = -1;
- for (const OutputSection *OS : OutputSections)
- if ((OS->Flags & SHF_MIPS_GPREL) && OS->Addr < Gp)
- Gp = OS->Addr;
- if (Gp != (uint64_t)-1)
- ElfSym::MipsGp->Value = Gp + 0x7ff0;
+ if (Config->EMachine == EM_MIPS && !ElfSym::MipsGp->Value) {
+ // Find GP-relative section with the lowest address
+ // and use this address to calculate default _gp value.
+ for (const OutputSectionCommand *Cmd : OutputSectionCommands) {
+ OutputSection *OS = Cmd->Sec;
+ if (OS->Flags & SHF_MIPS_GPREL) {
+ ElfSym::MipsGp->Value = OS->Addr + 0x7ff0;
+ break;
+ }
}
}
}
@@ -1723,7 +1727,7 @@ template <class ELFT> void Writer<ELFT>::writeHeader() {
EHdr->e_phnum = Phdrs.size();
EHdr->e_shentsize = sizeof(Elf_Shdr);
EHdr->e_shnum = OutputSectionCommands.size() + 1;
- EHdr->e_shstrndx = InX::ShStrTab->OutSec->SectionIndex;
+ EHdr->e_shstrndx = InX::ShStrTab->getParent()->SectionIndex;
if (Config->EMachine == EM_ARM)
// We don't currently use any features incompatible with EF_ARM_EABI_VER5,
@@ -1799,7 +1803,7 @@ template <class ELFT> void Writer<ELFT>::writeSections() {
OutputSection *EhFrameHdr =
(In<ELFT>::EhFrameHdr && !In<ELFT>::EhFrameHdr->empty())
- ? In<ELFT>::EhFrameHdr->OutSec
+ ? In<ELFT>::EhFrameHdr->getParent()
: nullptr;
// In -r or -emit-relocs mode, write the relocation sections first as in
@@ -1827,7 +1831,7 @@ template <class ELFT> void Writer<ELFT>::writeSections() {
}
template <class ELFT> void Writer<ELFT>::writeBuildId() {
- if (!InX::BuildId || !InX::BuildId->OutSec)
+ if (!InX::BuildId || !InX::BuildId->getParent())
return;
// Compute a hash of all sections of the output file.
diff --git a/contrib/llvm/tools/lldb/tools/lldb-mi/MICmdCmdVar.cpp b/contrib/llvm/tools/lldb/tools/lldb-mi/MICmdCmdVar.cpp
index 3396b7231c5c..66b392be6bed 100644
--- a/contrib/llvm/tools/lldb/tools/lldb-mi/MICmdCmdVar.cpp
+++ b/contrib/llvm/tools/lldb/tools/lldb-mi/MICmdCmdVar.cpp
@@ -510,22 +510,20 @@ bool CMICmdCmdVarUpdate::ExamineSBValueForChange(lldb::SBValue &vrwValue,
}
lldb::SBType valueType = vrwValue.GetType();
- if (!valueType.IsPointerType() && !valueType.IsReferenceType()) {
- const MIuint nChildren = vrwValue.GetNumChildren();
- for (MIuint i = 0; i < nChildren; ++i) {
- lldb::SBValue member = vrwValue.GetChildAtIndex(i);
- if (!member.IsValid())
- continue;
-
- if (member.GetValueDidChange()) {
- vrwbChanged = true;
- return MIstatus::success;
- } else if (ExamineSBValueForChange(member, vrwbChanged) && vrwbChanged)
- // Handle composite types (i.e. struct or arrays)
- return MIstatus::success;
- }
- }
+ const MIuint nChildren = vrwValue.GetNumChildren();
+ for (MIuint i = 0; i < nChildren; ++i) {
+ lldb::SBValue member = vrwValue.GetChildAtIndex(i);
+ if (!member.IsValid())
+ continue;
+
+ if (member.GetValueDidChange()) {
+ vrwbChanged = true;
+ return MIstatus::success;
+ } else if (ExamineSBValueForChange(member, vrwbChanged) && vrwbChanged)
+ // Handle composite types (i.e. struct or arrays)
+ return MIstatus::success;
+ }
vrwbChanged = false;
return MIstatus::success;
}
diff --git a/contrib/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp b/contrib/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
index 8ecf18480994..2b5babe79824 100644
--- a/contrib/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
+++ b/contrib/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
@@ -95,8 +95,12 @@ static void DumpObjectFile(ObjectFile &Obj, Twine Filename) {
outs() << Filename.str() << ":\tfile format " << Obj.getFileFormatName()
<< "\n\n";
+
// Dump the complete DWARF structure.
- DICtx->dump(outs(), DumpType, false, SummarizeTypes);
+ DIDumpOptions DumpOpts;
+ DumpOpts.DumpType = DumpType;
+ DumpOpts.SummarizeTypes = SummarizeTypes;
+ DICtx->dump(outs(), DumpOpts);
}
static void DumpInput(StringRef Filename) {
diff --git a/contrib/llvm/tools/llvm-objdump/MachODump.cpp b/contrib/llvm/tools/llvm-objdump/MachODump.cpp
index 9e02951a4a93..a260d6ff42c5 100644
--- a/contrib/llvm/tools/llvm-objdump/MachODump.cpp
+++ b/contrib/llvm/tools/llvm-objdump/MachODump.cpp
@@ -1271,7 +1271,10 @@ static void ProcessMachO(StringRef Name, MachOObjectFile *MachOOF,
if (DwarfDumpType != DIDT_Null) {
std::unique_ptr<DIContext> DICtx(new DWARFContextInMemory(*MachOOF));
// Dump the complete DWARF structure.
- DICtx->dump(outs(), DwarfDumpType, true /* DumpEH */);
+ DIDumpOptions DumpOpts;
+ DumpOpts.DumpType = DwarfDumpType;
+ DumpOpts.DumpEH = true;
+ DICtx->dump(outs(), DumpOpts);
}
}
diff --git a/contrib/llvm/tools/llvm-objdump/llvm-objdump.cpp b/contrib/llvm/tools/llvm-objdump/llvm-objdump.cpp
index 18fa0e074084..6a9151570908 100644
--- a/contrib/llvm/tools/llvm-objdump/llvm-objdump.cpp
+++ b/contrib/llvm/tools/llvm-objdump/llvm-objdump.cpp
@@ -2064,7 +2064,10 @@ static void DumpObject(ObjectFile *o, const Archive *a = nullptr) {
if (DwarfDumpType != DIDT_Null) {
std::unique_ptr<DIContext> DICtx(new DWARFContextInMemory(*o));
// Dump the complete DWARF structure.
- DICtx->dump(outs(), DwarfDumpType, true /* DumpEH */);
+ DIDumpOptions DumpOpts;
+ DumpOpts.DumpType = DwarfDumpType;
+ DumpOpts.DumpEH = true;
+ DICtx->dump(outs(), DumpOpts);
}
}
diff --git a/contrib/llvm/tools/llvm-pdbdump/Analyze.cpp b/contrib/llvm/tools/llvm-pdbdump/Analyze.cpp
index 3a026e5d2451..b503cdcbf1ea 100644
--- a/contrib/llvm/tools/llvm-pdbdump/Analyze.cpp
+++ b/contrib/llvm/tools/llvm-pdbdump/Analyze.cpp
@@ -35,7 +35,7 @@ static StringRef getLeafTypeName(TypeLeafKind LT) {
#define TYPE_RECORD(ename, value, name) \
case ename: \
return #name;
-#include "llvm/DebugInfo/CodeView/TypeRecords.def"
+#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
default:
break;
}
diff --git a/contrib/llvm/tools/llvm-pdbdump/CompactTypeDumpVisitor.cpp b/contrib/llvm/tools/llvm-pdbdump/CompactTypeDumpVisitor.cpp
index 3b609ae50c1c..6dd54e0dbec1 100644
--- a/contrib/llvm/tools/llvm-pdbdump/CompactTypeDumpVisitor.cpp
+++ b/contrib/llvm/tools/llvm-pdbdump/CompactTypeDumpVisitor.cpp
@@ -18,7 +18,7 @@ using namespace llvm::pdb;
static const EnumEntry<TypeLeafKind> LeafTypeNames[] = {
#define CV_TYPE(enum, val) {#enum, enum},
-#include "llvm/DebugInfo/CodeView/TypeRecords.def"
+#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
};
static StringRef getLeafName(TypeLeafKind K) {
diff --git a/contrib/llvm/tools/llvm-pdbdump/PdbYaml.cpp b/contrib/llvm/tools/llvm-pdbdump/PdbYaml.cpp
index dd32eca14c1d..e288063e2afa 100644
--- a/contrib/llvm/tools/llvm-pdbdump/PdbYaml.cpp
+++ b/contrib/llvm/tools/llvm-pdbdump/PdbYaml.cpp
@@ -9,22 +9,19 @@
#include "PdbYaml.h"
-#include "YamlSerializationContext.h"
-#include "YamlSymbolDumper.h"
-#include "YamlTypeDumper.h"
-
#include "llvm/ADT/StringExtras.h"
#include "llvm/DebugInfo/CodeView/CVSymbolVisitor.h"
#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
-#include "llvm/DebugInfo/CodeView/SymbolSerializer.h"
#include "llvm/DebugInfo/CodeView/SymbolVisitorCallbackPipeline.h"
#include "llvm/DebugInfo/CodeView/TypeSerializer.h"
#include "llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h"
#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
+#include "llvm/DebugInfo/PDB/Native/RawTypes.h"
#include "llvm/DebugInfo/PDB/Native/TpiHashing.h"
#include "llvm/DebugInfo/PDB/PDBExtras.h"
#include "llvm/DebugInfo/PDB/PDBTypes.h"
+#include "llvm/ObjectYAML/CodeViewYAMLTypes.h"
using namespace llvm;
using namespace llvm::pdb;
@@ -35,15 +32,6 @@ LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(uint32_t)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::StringRef)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::pdb::yaml::NamedStreamMapping)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::pdb::yaml::PdbDbiModuleInfo)
-LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::pdb::yaml::PdbSourceFileChecksumEntry)
-LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::pdb::yaml::PdbSourceLineEntry)
-LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::pdb::yaml::PdbSourceColumnEntry)
-LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::pdb::yaml::PdbSourceLineBlock)
-LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::pdb::yaml::PdbSourceLineInfo)
-LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::pdb::yaml::PdbInlineeSite)
-LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::pdb::yaml::PdbInlineeInfo)
-LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::pdb::yaml::PdbSymbolRecord)
-LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::pdb::yaml::PdbTpiRecord)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::pdb::yaml::StreamBlockList)
LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(llvm::pdb::PdbRaw_FeatureSig)
@@ -152,57 +140,18 @@ template <> struct ScalarEnumerationTraits<llvm::pdb::PdbRaw_FeatureSig> {
io.enumCase(Features, "VC140", PdbRaw_FeatureSig::VC140);
}
};
-
-template <> struct ScalarEnumerationTraits<llvm::codeview::FileChecksumKind> {
- static void enumeration(IO &io, llvm::codeview::FileChecksumKind &Kind) {
- io.enumCase(Kind, "None", llvm::codeview::FileChecksumKind::None);
- io.enumCase(Kind, "MD5", llvm::codeview::FileChecksumKind::MD5);
- io.enumCase(Kind, "SHA1", llvm::codeview::FileChecksumKind::SHA1);
- io.enumCase(Kind, "SHA256", llvm::codeview::FileChecksumKind::SHA256);
- }
-};
-
-template <> struct ScalarBitSetTraits<llvm::codeview::LineFlags> {
- static void bitset(IO &io, llvm::codeview::LineFlags &Flags) {
- io.bitSetCase(Flags, "HasColumnInfo", llvm::codeview::LF_HaveColumns);
- io.enumFallback<Hex16>(Flags);
- }
-};
-}
-}
-
-void ScalarTraits<HexFormattedString>::output(const HexFormattedString &Value,
- void *ctx, raw_ostream &Out) {
- StringRef Bytes(reinterpret_cast<const char *>(Value.Bytes.data()),
- Value.Bytes.size());
- Out << toHex(Bytes);
}
-
-StringRef ScalarTraits<HexFormattedString>::input(StringRef Scalar, void *ctxt,
- HexFormattedString &Value) {
- std::string H = fromHex(Scalar);
- Value.Bytes.assign(H.begin(), H.end());
- return StringRef();
}
void MappingTraits<PdbObject>::mapping(IO &IO, PdbObject &Obj) {
- // Create a single serialization context that will be passed through the
- // entire process of serializing / deserializing a Tpi Stream. This is
- // especially important when we are going from Pdb -> Yaml because we need
- // to maintain state in a TypeTableBuilder across mappings, and at the end of
- // the entire process, we need to have one TypeTableBuilder that has every
- // record.
- pdb::yaml::SerializationContext Context(IO, Obj.Allocator);
-
-
IO.mapOptional("MSF", Obj.Headers);
IO.mapOptional("StreamSizes", Obj.StreamSizes);
IO.mapOptional("StreamMap", Obj.StreamMap);
IO.mapOptional("StringTable", Obj.StringTable);
IO.mapOptional("PdbStream", Obj.PdbStream);
- IO.mapOptionalWithContext("DbiStream", Obj.DbiStream, Context);
- IO.mapOptionalWithContext("TpiStream", Obj.TpiStream, Context);
- IO.mapOptionalWithContext("IpiStream", Obj.IpiStream, Context);
+ IO.mapOptional("DbiStream", Obj.DbiStream);
+ IO.mapOptional("TpiStream", Obj.TpiStream);
+ IO.mapOptional("IpiStream", Obj.IpiStream);
}
void MappingTraits<MSFHeaders>::mapping(IO &IO, MSFHeaders &Obj) {
@@ -239,7 +188,7 @@ void MappingTraits<PdbInfoStream>::mapping(IO &IO, PdbInfoStream &Obj) {
IO.mapOptional("Version", Obj.Version, PdbImplVC70);
}
-void MappingContextTraits<PdbDbiStream, pdb::yaml::SerializationContext>::mapping(IO &IO, PdbDbiStream &Obj, pdb::yaml::SerializationContext &Context) {
+void MappingTraits<PdbDbiStream>::mapping(IO &IO, PdbDbiStream &Obj) {
IO.mapOptional("VerHeader", Obj.VerHeader, PdbDbiV70);
IO.mapOptional("Age", Obj.Age, 1U);
IO.mapOptional("BuildNumber", Obj.BuildNumber, uint16_t(0U));
@@ -247,13 +196,13 @@ void MappingContextTraits<PdbDbiStream, pdb::yaml::SerializationContext>::mappin
IO.mapOptional("PdbDllRbld", Obj.PdbDllRbld, uint16_t(0U));
IO.mapOptional("Flags", Obj.Flags, uint16_t(1U));
IO.mapOptional("MachineType", Obj.MachineType, PDB_Machine::x86);
- IO.mapOptionalWithContext("Modules", Obj.ModInfos, Context);
+ IO.mapOptional("Modules", Obj.ModInfos);
}
-void MappingContextTraits<PdbTpiStream, pdb::yaml::SerializationContext>::mapping(
- IO &IO, pdb::yaml::PdbTpiStream &Obj, pdb::yaml::SerializationContext &Context) {
+void MappingTraits<PdbTpiStream>::mapping(IO &IO,
+ pdb::yaml::PdbTpiStream &Obj) {
IO.mapOptional("Version", Obj.Version, PdbTpiV80);
- IO.mapRequired("Records", Obj.Records, Context);
+ IO.mapRequired("Records", Obj.Records);
}
void MappingTraits<NamedStreamMapping>::mapping(IO &IO,
@@ -262,134 +211,15 @@ void MappingTraits<NamedStreamMapping>::mapping(IO &IO,
IO.mapRequired("StreamNum", Obj.StreamNumber);
}
-void MappingContextTraits<PdbSymbolRecord, pdb::yaml::SerializationContext>::mapping(IO &IO, PdbSymbolRecord &Obj, pdb::yaml::SerializationContext &Context) {
- codeview::SymbolVisitorCallbackPipeline Pipeline;
- codeview::SymbolSerializer Serializer(Context.Allocator);
- codeview::SymbolDeserializer Deserializer(nullptr);
- codeview::yaml::YamlSymbolDumper Dumper(IO);
-
- if (IO.outputting()) {
- // For PDB to Yaml, deserialize into a high level record type, then dump it.
- Pipeline.addCallbackToPipeline(Deserializer);
- Pipeline.addCallbackToPipeline(Dumper);
- } else {
- // For the other way around, dump it into a concrete structure, and then
- // serialize it into the CVRecord.
- Pipeline.addCallbackToPipeline(Dumper);
- Pipeline.addCallbackToPipeline(Serializer);
- }
-
- codeview::CVSymbolVisitor Visitor(Pipeline);
- consumeError(Visitor.visitSymbolRecord(Obj.Record));
-}
-
-void MappingContextTraits<PdbModiStream, pdb::yaml::SerializationContext>::mapping(IO &IO, PdbModiStream &Obj, pdb::yaml::SerializationContext &Context) {
+void MappingTraits<PdbModiStream>::mapping(IO &IO, PdbModiStream &Obj) {
IO.mapOptional("Signature", Obj.Signature, 4U);
- IO.mapRequired("Records", Obj.Symbols, Context);
+ IO.mapRequired("Records", Obj.Symbols);
}
-void MappingContextTraits<PdbDbiModuleInfo, pdb::yaml::SerializationContext>::mapping(IO &IO, PdbDbiModuleInfo &Obj, pdb::yaml::SerializationContext &Context) {
+void MappingTraits<PdbDbiModuleInfo>::mapping(IO &IO, PdbDbiModuleInfo &Obj) {
IO.mapRequired("Module", Obj.Mod);
IO.mapOptional("ObjFile", Obj.Obj, Obj.Mod);
IO.mapOptional("SourceFiles", Obj.SourceFiles);
- IO.mapOptionalWithContext("LineInfo", Obj.FileLineInfo, Context);
- IO.mapOptionalWithContext("Modi", Obj.Modi, Context);
-}
-
-void MappingContextTraits<pdb::yaml::PdbSourceLineEntry,
- pdb::yaml::SerializationContext>::
- mapping(IO &IO, PdbSourceLineEntry &Obj,
- pdb::yaml::SerializationContext &Context) {
- IO.mapRequired("Offset", Obj.Offset);
- IO.mapRequired("LineStart", Obj.LineStart);
- IO.mapRequired("IsStatement", Obj.IsStatement);
- IO.mapRequired("EndDelta", Obj.EndDelta);
-}
-
-void MappingContextTraits<pdb::yaml::PdbSourceColumnEntry,
- pdb::yaml::SerializationContext>::
- mapping(IO &IO, PdbSourceColumnEntry &Obj,
- pdb::yaml::SerializationContext &Context) {
- IO.mapRequired("StartColumn", Obj.StartColumn);
- IO.mapRequired("EndColumn", Obj.EndColumn);
-}
-
-void MappingContextTraits<pdb::yaml::PdbSourceLineBlock,
- pdb::yaml::SerializationContext>::
- mapping(IO &IO, PdbSourceLineBlock &Obj,
- pdb::yaml::SerializationContext &Context) {
- IO.mapRequired("FileName", Obj.FileName);
- IO.mapRequired("Lines", Obj.Lines, Context);
- IO.mapRequired("Columns", Obj.Columns, Context);
-}
-
-void MappingContextTraits<pdb::yaml::PdbSourceFileChecksumEntry,
- pdb::yaml::SerializationContext>::
- mapping(IO &IO, PdbSourceFileChecksumEntry &Obj,
- pdb::yaml::SerializationContext &Context) {
- IO.mapRequired("FileName", Obj.FileName);
- IO.mapRequired("Kind", Obj.Kind);
- IO.mapRequired("Checksum", Obj.ChecksumBytes);
-}
-
-void MappingContextTraits<pdb::yaml::PdbSourceLineInfo,
- pdb::yaml::SerializationContext>::
- mapping(IO &IO, PdbSourceLineInfo &Obj,
- pdb::yaml::SerializationContext &Context) {
- IO.mapRequired("CodeSize", Obj.CodeSize);
-
- IO.mapRequired("Flags", Obj.Flags);
- IO.mapRequired("RelocOffset", Obj.RelocOffset);
- IO.mapRequired("RelocSegment", Obj.RelocSegment);
- IO.mapRequired("Blocks", Obj.Blocks, Context);
-}
-
-void MappingContextTraits<pdb::yaml::PdbSourceFileInfo,
- pdb::yaml::SerializationContext>::
- mapping(IO &IO, PdbSourceFileInfo &Obj,
- pdb::yaml::SerializationContext &Context) {
- IO.mapOptionalWithContext("Checksums", Obj.FileChecksums, Context);
- IO.mapOptionalWithContext("Lines", Obj.LineFragments, Context);
- IO.mapOptionalWithContext("InlineeLines", Obj.Inlinees, Context);
-}
-
-void MappingContextTraits<PdbInlineeSite, SerializationContext>::mapping(
- IO &IO, PdbInlineeSite &Obj, SerializationContext &Context) {
- IO.mapRequired("FileName", Obj.FileName);
- IO.mapRequired("LineNum", Obj.SourceLineNum);
- IO.mapRequired("Inlinee", Obj.Inlinee);
- IO.mapOptional("ExtraFiles", Obj.ExtraFiles);
-}
-
-void MappingContextTraits<PdbInlineeInfo, SerializationContext>::mapping(
- IO &IO, PdbInlineeInfo &Obj, SerializationContext &Context) {
- IO.mapRequired("HasExtraFiles", Obj.HasExtraFiles);
- IO.mapRequired("Sites", Obj.Sites, Context);
-}
-
-void MappingContextTraits<PdbTpiRecord, pdb::yaml::SerializationContext>::
- mapping(IO &IO, pdb::yaml::PdbTpiRecord &Obj,
- pdb::yaml::SerializationContext &Context) {
- if (IO.outputting()) {
- // For PDB to Yaml, deserialize into a high level record type, then dump it.
- consumeError(codeview::visitTypeRecord(Obj.Record, Context.Dumper));
- } else {
- codeview::TypeVisitorCallbackPipeline Pipeline;
- codeview::TypeSerializer Serializer(Context.Allocator);
- pdb::TpiHashUpdater Hasher;
- // For Yaml to PDB, extract from the high level record type, then write it
- // to bytes.
-
- // This might be interpreted as a hack, but serializing FieldList
- // sub-records requires having access to the same serializer being used by
- // the FieldList itself.
- Context.ActiveSerializer = &Serializer;
- Pipeline.addCallbackToPipeline(Context.Dumper);
- Pipeline.addCallbackToPipeline(Serializer);
- Pipeline.addCallbackToPipeline(Hasher);
- consumeError(codeview::visitTypeRecord(Obj.Record, Pipeline,
- codeview::VDS_BytesExternal));
- }
-
- Context.ActiveSerializer = nullptr;
+ IO.mapOptional("LineInfo", Obj.FileLineInfo);
+ IO.mapOptional("Modi", Obj.Modi);
}
diff --git a/contrib/llvm/tools/llvm-pdbdump/PdbYaml.h b/contrib/llvm/tools/llvm-pdbdump/PdbYaml.h
index 423845caeb31..deb500ec2074 100644
--- a/contrib/llvm/tools/llvm-pdbdump/PdbYaml.h
+++ b/contrib/llvm/tools/llvm-pdbdump/PdbYaml.h
@@ -19,6 +19,9 @@
#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
#include "llvm/DebugInfo/PDB/Native/RawConstants.h"
#include "llvm/DebugInfo/PDB/PDBTypes.h"
+#include "llvm/ObjectYAML/CodeViewYAMLDebugSections.h"
+#include "llvm/ObjectYAML/CodeViewYAMLSymbols.h"
+#include "llvm/ObjectYAML/CodeViewYAMLTypes.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/YAMLTraits.h"
@@ -56,75 +59,16 @@ struct PdbInfoStream {
std::vector<NamedStreamMapping> NamedStreams;
};
-struct PdbSymbolRecord {
- codeview::CVSymbol Record;
-};
-
struct PdbModiStream {
uint32_t Signature;
- std::vector<PdbSymbolRecord> Symbols;
-};
-
-struct PdbSourceLineEntry {
- uint32_t Offset;
- uint32_t LineStart;
- uint32_t EndDelta;
- bool IsStatement;
-};
-
-struct PdbSourceColumnEntry {
- uint16_t StartColumn;
- uint16_t EndColumn;
-};
-
-struct PdbSourceLineBlock {
- StringRef FileName;
- std::vector<PdbSourceLineEntry> Lines;
- std::vector<PdbSourceColumnEntry> Columns;
-};
-
-struct HexFormattedString {
- std::vector<uint8_t> Bytes;
-};
-
-struct PdbSourceFileChecksumEntry {
- StringRef FileName;
- codeview::FileChecksumKind Kind;
- HexFormattedString ChecksumBytes;
-};
-
-struct PdbSourceLineInfo {
- uint32_t RelocOffset;
- uint32_t RelocSegment;
- codeview::LineFlags Flags;
- uint32_t CodeSize;
-
- std::vector<PdbSourceLineBlock> Blocks;
-};
-
-struct PdbInlineeSite {
- codeview::TypeIndex Inlinee;
- StringRef FileName;
- uint32_t SourceLineNum;
- std::vector<StringRef> ExtraFiles;
-};
-
-struct PdbInlineeInfo {
- bool HasExtraFiles;
- std::vector<PdbInlineeSite> Sites;
-};
-
-struct PdbSourceFileInfo {
- std::vector<PdbSourceFileChecksumEntry> FileChecksums;
- std::vector<PdbSourceLineInfo> LineFragments;
- std::vector<PdbInlineeInfo> Inlinees;
+ std::vector<CodeViewYAML::SymbolRecord> Symbols;
};
struct PdbDbiModuleInfo {
StringRef Obj;
StringRef Mod;
std::vector<StringRef> SourceFiles;
- Optional<PdbSourceFileInfo> FileLineInfo;
+ Optional<CodeViewYAML::SourceFileInfo> FileLineInfo;
Optional<PdbModiStream> Modi;
};
@@ -140,17 +84,9 @@ struct PdbDbiStream {
std::vector<PdbDbiModuleInfo> ModInfos;
};
-struct PdbTpiRecord {
- codeview::CVType Record;
-};
-
-struct PdbTpiFieldListRecord {
- codeview::CVMemberRecord Record;
-};
-
struct PdbTpiStream {
PdbRaw_TpiVer Version = PdbTpiV80;
- std::vector<PdbTpiRecord> Records;
+ std::vector<CodeViewYAML::LeafRecord> Records;
};
struct PdbObject {
@@ -172,126 +108,15 @@ struct PdbObject {
}
}
-namespace llvm {
-namespace yaml {
-
-template <> struct MappingTraits<pdb::yaml::PdbObject> {
- static void mapping(IO &IO, pdb::yaml::PdbObject &Obj);
-};
-
-template <> struct MappingTraits<pdb::yaml::MSFHeaders> {
- static void mapping(IO &IO, pdb::yaml::MSFHeaders &Obj);
-};
-
-template <> struct MappingTraits<msf::SuperBlock> {
- static void mapping(IO &IO, msf::SuperBlock &SB);
-};
-
-template <> struct MappingTraits<pdb::yaml::StreamBlockList> {
- static void mapping(IO &IO, pdb::yaml::StreamBlockList &SB);
-};
-
-template <> struct MappingTraits<pdb::yaml::PdbInfoStream> {
- static void mapping(IO &IO, pdb::yaml::PdbInfoStream &Obj);
-};
-
-template <> struct MappingContextTraits<pdb::yaml::PdbDbiStream, pdb::yaml::SerializationContext> {
- static void mapping(IO &IO, pdb::yaml::PdbDbiStream &Obj, pdb::yaml::SerializationContext &Context);
-};
-
-template <>
-struct MappingContextTraits<pdb::yaml::PdbTpiStream, pdb::yaml::SerializationContext> {
- static void mapping(IO &IO, pdb::yaml::PdbTpiStream &Obj,
- pdb::yaml::SerializationContext &Context);
-};
-
-template <> struct MappingTraits<pdb::yaml::NamedStreamMapping> {
- static void mapping(IO &IO, pdb::yaml::NamedStreamMapping &Obj);
-};
-
-template <> struct MappingContextTraits<pdb::yaml::PdbSymbolRecord, pdb::yaml::SerializationContext> {
- static void mapping(IO &IO, pdb::yaml::PdbSymbolRecord &Obj, pdb::yaml::SerializationContext &Context);
-};
-
-template <> struct MappingContextTraits<pdb::yaml::PdbModiStream, pdb::yaml::SerializationContext> {
- static void mapping(IO &IO, pdb::yaml::PdbModiStream &Obj, pdb::yaml::SerializationContext &Context);
-};
-
-template <> struct MappingContextTraits<pdb::yaml::PdbDbiModuleInfo, pdb::yaml::SerializationContext> {
- static void mapping(IO &IO, pdb::yaml::PdbDbiModuleInfo &Obj, pdb::yaml::SerializationContext &Context);
-};
-
-template <>
-struct MappingContextTraits<pdb::yaml::PdbSourceLineEntry,
- pdb::yaml::SerializationContext> {
- static void mapping(IO &IO, pdb::yaml::PdbSourceLineEntry &Obj,
- pdb::yaml::SerializationContext &Context);
-};
-
-template <>
-struct MappingContextTraits<pdb::yaml::PdbSourceColumnEntry,
- pdb::yaml::SerializationContext> {
- static void mapping(IO &IO, pdb::yaml::PdbSourceColumnEntry &Obj,
- pdb::yaml::SerializationContext &Context);
-};
-
-template <>
-struct MappingContextTraits<pdb::yaml::PdbSourceLineBlock,
- pdb::yaml::SerializationContext> {
- static void mapping(IO &IO, pdb::yaml::PdbSourceLineBlock &Obj,
- pdb::yaml::SerializationContext &Context);
-};
-
-template <>
-struct MappingContextTraits<pdb::yaml::PdbSourceFileChecksumEntry,
- pdb::yaml::SerializationContext> {
- static void mapping(IO &IO, pdb::yaml::PdbSourceFileChecksumEntry &Obj,
- pdb::yaml::SerializationContext &Context);
-};
-
-template <> struct ScalarTraits<pdb::yaml::HexFormattedString> {
- static void output(const pdb::yaml::HexFormattedString &Value, void *ctx,
- llvm::raw_ostream &Out);
- static StringRef input(StringRef Scalar, void *ctxt,
- pdb::yaml::HexFormattedString &Value);
- static bool mustQuote(StringRef) { return false; }
-};
-
-template <>
-struct MappingContextTraits<pdb::yaml::PdbSourceLineInfo,
- pdb::yaml::SerializationContext> {
- static void mapping(IO &IO, pdb::yaml::PdbSourceLineInfo &Obj,
- pdb::yaml::SerializationContext &Context);
-};
-
-template <>
-struct MappingContextTraits<pdb::yaml::PdbSourceFileInfo,
- pdb::yaml::SerializationContext> {
- static void mapping(IO &IO, pdb::yaml::PdbSourceFileInfo &Obj,
- pdb::yaml::SerializationContext &Context);
-};
-
-template <>
-struct MappingContextTraits<pdb::yaml::PdbInlineeInfo,
- pdb::yaml::SerializationContext> {
- static void mapping(IO &IO, pdb::yaml::PdbInlineeInfo &Obj,
- pdb::yaml::SerializationContext &Context);
-};
-
-template <>
-struct MappingContextTraits<pdb::yaml::PdbInlineeSite,
- pdb::yaml::SerializationContext> {
- static void mapping(IO &IO, pdb::yaml::PdbInlineeSite &Obj,
- pdb::yaml::SerializationContext &Context);
-};
-
-template <>
-struct MappingContextTraits<pdb::yaml::PdbTpiRecord,
- pdb::yaml::SerializationContext> {
- static void mapping(IO &IO, pdb::yaml::PdbTpiRecord &Obj,
- pdb::yaml::SerializationContext &Context);
-};
-}
-}
+LLVM_YAML_DECLARE_MAPPING_TRAITS(pdb::yaml::PdbObject)
+LLVM_YAML_DECLARE_MAPPING_TRAITS(pdb::yaml::MSFHeaders)
+LLVM_YAML_DECLARE_MAPPING_TRAITS(msf::SuperBlock)
+LLVM_YAML_DECLARE_MAPPING_TRAITS(pdb::yaml::StreamBlockList)
+LLVM_YAML_DECLARE_MAPPING_TRAITS(pdb::yaml::PdbInfoStream)
+LLVM_YAML_DECLARE_MAPPING_TRAITS(pdb::yaml::PdbDbiStream)
+LLVM_YAML_DECLARE_MAPPING_TRAITS(pdb::yaml::PdbTpiStream)
+LLVM_YAML_DECLARE_MAPPING_TRAITS(pdb::yaml::NamedStreamMapping)
+LLVM_YAML_DECLARE_MAPPING_TRAITS(pdb::yaml::PdbModiStream)
+LLVM_YAML_DECLARE_MAPPING_TRAITS(pdb::yaml::PdbDbiModuleInfo)
#endif // LLVM_TOOLS_LLVMPDBDUMP_PDBYAML_H
diff --git a/contrib/llvm/tools/llvm-pdbdump/YAMLOutputStyle.cpp b/contrib/llvm/tools/llvm-pdbdump/YAMLOutputStyle.cpp
index 7aa68dee7d47..18839a7679d3 100644
--- a/contrib/llvm/tools/llvm-pdbdump/YAMLOutputStyle.cpp
+++ b/contrib/llvm/tools/llvm-pdbdump/YAMLOutputStyle.cpp
@@ -104,12 +104,12 @@ Error YAMLOutputStyle::dump() {
namespace {
class C13YamlVisitor : public C13DebugFragmentVisitor {
public:
- C13YamlVisitor(llvm::pdb::yaml::PdbSourceFileInfo &Info, PDBFile &F)
+ C13YamlVisitor(CodeViewYAML::SourceFileInfo &Info, PDBFile &F)
: C13DebugFragmentVisitor(F), Info(Info) {}
Error handleFileChecksums() override {
for (const auto &C : *Checksums) {
- llvm::pdb::yaml::PdbSourceFileChecksumEntry Entry;
+ CodeViewYAML::SourceFileChecksumEntry Entry;
if (auto Result = getNameFromStringTable(C.FileNameOffset))
Entry.FileName = *Result;
else
@@ -143,7 +143,7 @@ public:
return Result.takeError();
for (const auto &N : L.LineNumbers) {
- llvm::pdb::yaml::PdbSourceLineEntry Line;
+ CodeViewYAML::SourceLineEntry Line;
Line.Offset = N.Offset;
codeview::LineInfo LI(N.Flags);
Line.LineStart = LI.getStartLine();
@@ -154,7 +154,7 @@ public:
if (LF.hasColumnInfo()) {
for (const auto &C : L.Columns) {
- llvm::pdb::yaml::PdbSourceColumnEntry Column;
+ CodeViewYAML::SourceColumnEntry Column;
Column.StartColumn = C.StartColumn;
Column.EndColumn = C.EndColumn;
Block.Columns.push_back(Column);
@@ -179,7 +179,7 @@ public:
else
return Result.takeError();
- Site.Inlinee = IL.Header->Inlinee;
+ Site.Inlinee = IL.Header->Inlinee.getIndex();
Site.SourceLineNum = IL.Header->SourceLineNum;
if (ILF.hasExtraFiles()) {
for (const auto &EF : IL.ExtraFiles) {
@@ -195,17 +195,16 @@ public:
}
private:
-
- llvm::pdb::yaml::PdbSourceFileInfo &Info;
+ CodeViewYAML::SourceFileInfo &Info;
};
}
-Expected<Optional<llvm::pdb::yaml::PdbSourceFileInfo>>
+Expected<Optional<CodeViewYAML::SourceFileInfo>>
YAMLOutputStyle::getFileLineInfo(const pdb::ModuleDebugStreamRef &ModS) {
if (!ModS.hasLineInfo())
return None;
- yaml::PdbSourceFileInfo Info;
+ CodeViewYAML::SourceFileInfo Info;
C13YamlVisitor Visitor(Info, File);
if (auto EC =
codeview::visitDebugSubsections(ModS.linesAndChecksums(), Visitor))
@@ -357,8 +356,11 @@ Error YAMLOutputStyle::dumpDbiStream() {
DMI.Modi->Signature = ModS.signature();
bool HadError = false;
for (auto &Sym : ModS.symbols(&HadError)) {
- pdb::yaml::PdbSymbolRecord Record{Sym};
- DMI.Modi->Symbols.push_back(Record);
+ auto ES = CodeViewYAML::SymbolRecord::fromCodeViewSymbol(Sym);
+ if (!ES)
+ return ES.takeError();
+
+ DMI.Modi->Symbols.push_back(*ES);
}
}
}
@@ -378,13 +380,10 @@ Error YAMLOutputStyle::dumpTpiStream() {
Obj.TpiStream.emplace();
Obj.TpiStream->Version = TS.getTpiVersion();
for (auto &Record : TS.types(nullptr)) {
- yaml::PdbTpiRecord R;
- // It's not necessary to set R.RecordData here. That only exists as a
- // way to have the `PdbTpiRecord` structure own the memory that `R.Record`
- // references. In the case of reading an existing PDB though, that memory
- // is owned by the backing stream.
- R.Record = Record;
- Obj.TpiStream->Records.push_back(R);
+ auto ExpectedRecord = CodeViewYAML::LeafRecord::fromCodeViewRecord(Record);
+ if (!ExpectedRecord)
+ return ExpectedRecord.takeError();
+ Obj.TpiStream->Records.push_back(*ExpectedRecord);
}
return Error::success();
@@ -402,9 +401,11 @@ Error YAMLOutputStyle::dumpIpiStream() {
Obj.IpiStream.emplace();
Obj.IpiStream->Version = IS.getTpiVersion();
for (auto &Record : IS.types(nullptr)) {
- yaml::PdbTpiRecord R;
- R.Record = Record;
- Obj.IpiStream->Records.push_back(R);
+ auto ExpectedRecord = CodeViewYAML::LeafRecord::fromCodeViewRecord(Record);
+ if (!ExpectedRecord)
+ return ExpectedRecord.takeError();
+
+ Obj.IpiStream->Records.push_back(*ExpectedRecord);
}
return Error::success();
diff --git a/contrib/llvm/tools/llvm-pdbdump/YAMLOutputStyle.h b/contrib/llvm/tools/llvm-pdbdump/YAMLOutputStyle.h
index 068312aec450..6e4067c48f88 100644
--- a/contrib/llvm/tools/llvm-pdbdump/YAMLOutputStyle.h
+++ b/contrib/llvm/tools/llvm-pdbdump/YAMLOutputStyle.h
@@ -27,7 +27,7 @@ public:
Error dump() override;
private:
- Expected<Optional<llvm::pdb::yaml::PdbSourceFileInfo>>
+ Expected<Optional<CodeViewYAML::SourceFileInfo>>
getFileLineInfo(const pdb::ModuleDebugStreamRef &ModS);
Error dumpStringTable();
diff --git a/contrib/llvm/tools/llvm-pdbdump/YamlSerializationContext.h b/contrib/llvm/tools/llvm-pdbdump/YamlSerializationContext.h
deleted file mode 100644
index dcf29d249d60..000000000000
--- a/contrib/llvm/tools/llvm-pdbdump/YamlSerializationContext.h
+++ /dev/null
@@ -1,39 +0,0 @@
-//===- YamlSerializationContext.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_TOOLS_LLVMPDBDUMP_YAMLSERIALIZATIONCONTEXT_H
-#define LLVM_TOOLS_LLVMPDBDUMP_YAMLSERIALIZATIONCONTEXT_H
-
-#include "PdbYaml.h"
-#include "YamlTypeDumper.h"
-#include "llvm/Support/Allocator.h"
-
-namespace llvm {
-namespace codeview {
-class TypeSerializer;
-}
-namespace yaml {
-class IO;
-}
-
-namespace pdb {
-namespace yaml {
-struct SerializationContext {
- explicit SerializationContext(llvm::yaml::IO &IO, BumpPtrAllocator &Allocator)
- : Dumper(IO, *this), Allocator(Allocator) {}
-
- codeview::yaml::YamlTypeDumperCallbacks Dumper;
- BumpPtrAllocator &Allocator;
- codeview::TypeSerializer *ActiveSerializer = nullptr;
-};
-}
-}
-}
-
-#endif \ No newline at end of file
diff --git a/contrib/llvm/tools/llvm-pdbdump/YamlSymbolDumper.cpp b/contrib/llvm/tools/llvm-pdbdump/YamlSymbolDumper.cpp
deleted file mode 100644
index 431bf404fb04..000000000000
--- a/contrib/llvm/tools/llvm-pdbdump/YamlSymbolDumper.cpp
+++ /dev/null
@@ -1,413 +0,0 @@
-//===- YamlSymbolDumper.cpp ----------------------------------- *- C++ --*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "YamlSymbolDumper.h"
-#include "PdbYaml.h"
-#include "YamlTypeDumper.h"
-
-#include "llvm/DebugInfo/CodeView/CVSymbolVisitor.h"
-#include "llvm/DebugInfo/CodeView/EnumTables.h"
-#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
-#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
-#include "llvm/DebugInfo/CodeView/SymbolVisitorCallbackPipeline.h"
-
-using namespace llvm;
-using namespace llvm::codeview;
-using namespace llvm::codeview::yaml;
-
-LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(TypeIndex)
-LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(uint64_t)
-LLVM_YAML_IS_SEQUENCE_VECTOR(OneMethodRecord)
-LLVM_YAML_IS_SEQUENCE_VECTOR(VFTableSlotKind)
-LLVM_YAML_IS_SEQUENCE_VECTOR(StringRef)
-LLVM_YAML_IS_SEQUENCE_VECTOR(CVType)
-LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::pdb::yaml::PdbTpiFieldListRecord)
-
-namespace llvm {
-namespace yaml {
-void ScalarEnumerationTraits<SymbolKind>::enumeration(IO &io,
- SymbolKind &Value) {
- auto SymbolNames = getSymbolTypeNames();
- for (const auto &E : SymbolNames)
- io.enumCase(Value, E.Name.str().c_str(), E.Value);
-}
-
-template <> struct ScalarBitSetTraits<CompileSym2Flags> {
- static void bitset(IO &io, CompileSym2Flags &Flags) {
- auto FlagNames = getCompileSym2FlagNames();
- for (const auto &E : FlagNames) {
- io.bitSetCase(Flags, E.Name.str().c_str(),
- static_cast<CompileSym2Flags>(E.Value));
- }
- }
-};
-
-template <> struct ScalarBitSetTraits<CompileSym3Flags> {
- static void bitset(IO &io, CompileSym3Flags &Flags) {
- auto FlagNames = getCompileSym3FlagNames();
- for (const auto &E : FlagNames) {
- io.bitSetCase(Flags, E.Name.str().c_str(),
- static_cast<CompileSym3Flags>(E.Value));
- }
- }
-};
-
-template <> struct ScalarBitSetTraits<ExportFlags> {
- static void bitset(IO &io, ExportFlags &Flags) {
- auto FlagNames = getExportSymFlagNames();
- for (const auto &E : FlagNames) {
- io.bitSetCase(Flags, E.Name.str().c_str(),
- static_cast<ExportFlags>(E.Value));
- }
- }
-};
-
-template <> struct ScalarBitSetTraits<LocalSymFlags> {
- static void bitset(IO &io, LocalSymFlags &Flags) {
- auto FlagNames = getLocalFlagNames();
- for (const auto &E : FlagNames) {
- io.bitSetCase(Flags, E.Name.str().c_str(),
- static_cast<LocalSymFlags>(E.Value));
- }
- }
-};
-
-template <> struct ScalarBitSetTraits<ProcSymFlags> {
- static void bitset(IO &io, ProcSymFlags &Flags) {
- auto FlagNames = getProcSymFlagNames();
- for (const auto &E : FlagNames) {
- io.bitSetCase(Flags, E.Name.str().c_str(),
- static_cast<ProcSymFlags>(E.Value));
- }
- }
-};
-
-template <> struct ScalarBitSetTraits<FrameProcedureOptions> {
- static void bitset(IO &io, FrameProcedureOptions &Flags) {
- auto FlagNames = getFrameProcSymFlagNames();
- for (const auto &E : FlagNames) {
- io.bitSetCase(Flags, E.Name.str().c_str(),
- static_cast<FrameProcedureOptions>(E.Value));
- }
- }
-};
-
-template <> struct ScalarEnumerationTraits<CPUType> {
- static void enumeration(IO &io, CPUType &Cpu) {
- auto CpuNames = getCPUTypeNames();
- for (const auto &E : CpuNames) {
- io.enumCase(Cpu, E.Name.str().c_str(), static_cast<CPUType>(E.Value));
- }
- }
-};
-
-template <> struct ScalarEnumerationTraits<RegisterId> {
- static void enumeration(IO &io, RegisterId &Reg) {
- auto RegNames = getRegisterNames();
- for (const auto &E : RegNames) {
- io.enumCase(Reg, E.Name.str().c_str(), static_cast<RegisterId>(E.Value));
- }
- io.enumFallback<Hex16>(Reg);
- }
-};
-
-template <> struct ScalarEnumerationTraits<TrampolineType> {
- static void enumeration(IO &io, TrampolineType &Tramp) {
- auto TrampNames = getTrampolineNames();
- for (const auto &E : TrampNames) {
- io.enumCase(Tramp, E.Name.str().c_str(),
- static_cast<TrampolineType>(E.Value));
- }
- }
-};
-
-template <> struct ScalarEnumerationTraits<ThunkOrdinal> {
- static void enumeration(IO &io, ThunkOrdinal &Ord) {
- auto ThunkNames = getThunkOrdinalNames();
- for (const auto &E : ThunkNames) {
- io.enumCase(Ord, E.Name.str().c_str(),
- static_cast<ThunkOrdinal>(E.Value));
- }
- }
-};
-
-void MappingTraits<ScopeEndSym>::mapping(IO &IO, ScopeEndSym &Obj) {}
-
-void MappingTraits<Thunk32Sym>::mapping(IO &IO, Thunk32Sym &Thunk) {
- IO.mapRequired("Parent", Thunk.Parent);
- IO.mapRequired("End", Thunk.End);
- IO.mapRequired("Next", Thunk.Next);
- IO.mapRequired("Off", Thunk.Offset);
- IO.mapRequired("Seg", Thunk.Segment);
- IO.mapRequired("Len", Thunk.Length);
- IO.mapRequired("Ordinal", Thunk.Thunk);
-}
-
-void MappingTraits<TrampolineSym>::mapping(IO &IO, TrampolineSym &Tramp) {
- IO.mapRequired("Type", Tramp.Type);
- IO.mapRequired("Size", Tramp.Size);
- IO.mapRequired("ThunkOff", Tramp.ThunkOffset);
- IO.mapRequired("TargetOff", Tramp.TargetOffset);
- IO.mapRequired("ThunkSection", Tramp.ThunkSection);
- IO.mapRequired("TargetSection", Tramp.TargetSection);
-}
-
-void MappingTraits<SectionSym>::mapping(IO &IO, SectionSym &Section) {
- IO.mapRequired("SectionNumber", Section.SectionNumber);
- IO.mapRequired("Alignment", Section.Alignment);
- IO.mapRequired("Rva", Section.Rva);
- IO.mapRequired("Length", Section.Length);
- IO.mapRequired("Characteristics", Section.Characteristics);
- IO.mapRequired("Name", Section.Name);
-}
-
-void MappingTraits<CoffGroupSym>::mapping(IO &IO, CoffGroupSym &CoffGroup) {
- IO.mapRequired("Size", CoffGroup.Size);
- IO.mapRequired("Characteristics", CoffGroup.Characteristics);
- IO.mapRequired("Offset", CoffGroup.Offset);
- IO.mapRequired("Segment", CoffGroup.Segment);
- IO.mapRequired("Name", CoffGroup.Name);
-}
-
-void MappingTraits<ExportSym>::mapping(IO &IO, ExportSym &Export) {
- IO.mapRequired("Ordinal", Export.Ordinal);
- IO.mapRequired("Flags", Export.Flags);
- IO.mapRequired("Name", Export.Name);
-}
-
-void MappingTraits<ProcSym>::mapping(IO &IO, ProcSym &Proc) {
- // TODO: Print the linkage name
-
- IO.mapRequired("PtrParent", Proc.Parent);
- IO.mapRequired("PtrEnd", Proc.End);
- IO.mapRequired("PtrNext", Proc.Next);
- IO.mapRequired("CodeSize", Proc.CodeSize);
- IO.mapRequired("DbgStart", Proc.DbgStart);
- IO.mapRequired("DbgEnd", Proc.DbgEnd);
- IO.mapRequired("FunctionType", Proc.FunctionType);
- IO.mapRequired("Segment", Proc.Segment);
- IO.mapRequired("Flags", Proc.Flags);
- IO.mapRequired("DisplayName", Proc.Name);
-}
-
-void MappingTraits<RegisterSym>::mapping(IO &IO, RegisterSym &Register) {
- IO.mapRequired("Type", Register.Index);
- IO.mapRequired("Seg", Register.Register);
- IO.mapRequired("Name", Register.Name);
-}
-
-void MappingTraits<PublicSym32>::mapping(IO &IO, PublicSym32 &Public) {
- IO.mapRequired("Type", Public.Index);
- IO.mapRequired("Seg", Public.Segment);
- IO.mapRequired("Off", Public.Offset);
- IO.mapRequired("Name", Public.Name);
-}
-
-void MappingTraits<ProcRefSym>::mapping(IO &IO, ProcRefSym &ProcRef) {
- IO.mapRequired("SumName", ProcRef.SumName);
- IO.mapRequired("SymOffset", ProcRef.SymOffset);
- IO.mapRequired("Mod", ProcRef.Module);
- IO.mapRequired("Name", ProcRef.Name);
-}
-
-void MappingTraits<EnvBlockSym>::mapping(IO &IO, EnvBlockSym &EnvBlock) {
- IO.mapRequired("Entries", EnvBlock.Fields);
-}
-
-void MappingTraits<InlineSiteSym>::mapping(IO &IO, InlineSiteSym &InlineSite) {
- IO.mapRequired("PtrParent", InlineSite.Parent);
- IO.mapRequired("PtrEnd", InlineSite.End);
- IO.mapRequired("Inlinee", InlineSite.Inlinee);
- // TODO: The binary annotations
-}
-
-void MappingTraits<LocalSym>::mapping(IO &IO, LocalSym &Local) {
- IO.mapRequired("Type", Local.Type);
- IO.mapRequired("Flags", Local.Flags);
- IO.mapRequired("VarName", Local.Name);
-}
-
-void MappingTraits<DefRangeSym>::mapping(IO &IO, DefRangeSym &Obj) {
- // TODO: Print the subfields
-}
-
-void MappingTraits<DefRangeSubfieldSym>::mapping(IO &IO,
- DefRangeSubfieldSym &Obj) {
- // TODO: Print the subfields
-}
-
-void MappingTraits<DefRangeRegisterSym>::mapping(IO &IO,
- DefRangeRegisterSym &Obj) {
- // TODO: Print the subfields
-}
-
-void MappingTraits<DefRangeFramePointerRelSym>::mapping(
- IO &IO, DefRangeFramePointerRelSym &Obj) {
- // TODO: Print the subfields
-}
-
-void MappingTraits<DefRangeSubfieldRegisterSym>::mapping(
- IO &IO, DefRangeSubfieldRegisterSym &Obj) {
- // TODO: Print the subfields
-}
-
-void MappingTraits<DefRangeFramePointerRelFullScopeSym>::mapping(
- IO &IO, DefRangeFramePointerRelFullScopeSym &Obj) {
- // TODO: Print the subfields
-}
-
-void MappingTraits<DefRangeRegisterRelSym>::mapping(
- IO &IO, DefRangeRegisterRelSym &Obj) {
- // TODO: Print the subfields
-}
-
-void MappingTraits<BlockSym>::mapping(IO &IO, BlockSym &Block) {
- // TODO: Print the linkage name
- IO.mapRequired("PtrParent", Block.Parent);
- IO.mapRequired("PtrEnd", Block.End);
- IO.mapRequired("CodeSize", Block.CodeSize);
- IO.mapRequired("Segment", Block.Segment);
- IO.mapRequired("BlockName", Block.Name);
-}
-
-void MappingTraits<LabelSym>::mapping(IO &IO, LabelSym &Label) {
- // TODO: Print the linkage name
- IO.mapRequired("Segment", Label.Segment);
- IO.mapRequired("Flags", Label.Flags);
- IO.mapRequired("Flags", Label.Flags);
- IO.mapRequired("DisplayName", Label.Name);
-}
-
-void MappingTraits<ObjNameSym>::mapping(IO &IO, ObjNameSym &ObjName) {
- IO.mapRequired("Signature", ObjName.Signature);
- IO.mapRequired("ObjectName", ObjName.Name);
-}
-
-void MappingTraits<Compile2Sym>::mapping(IO &IO, Compile2Sym &Compile2) {
- IO.mapRequired("Flags", Compile2.Flags);
- IO.mapRequired("Machine", Compile2.Machine);
- IO.mapRequired("FrontendMajor", Compile2.VersionFrontendMajor);
- IO.mapRequired("FrontendMinor", Compile2.VersionFrontendMinor);
- IO.mapRequired("FrontendBuild", Compile2.VersionFrontendBuild);
- IO.mapRequired("BackendMajor", Compile2.VersionBackendMajor);
- IO.mapRequired("BackendMinor", Compile2.VersionBackendMinor);
- IO.mapRequired("BackendBuild", Compile2.VersionBackendBuild);
- IO.mapRequired("Version", Compile2.Version);
-}
-
-void MappingTraits<Compile3Sym>::mapping(IO &IO, Compile3Sym &Compile3) {
- IO.mapRequired("Flags", Compile3.Flags);
- IO.mapRequired("Machine", Compile3.Machine);
- IO.mapRequired("FrontendMajor", Compile3.VersionFrontendMajor);
- IO.mapRequired("FrontendMinor", Compile3.VersionFrontendMinor);
- IO.mapRequired("FrontendBuild", Compile3.VersionFrontendBuild);
- IO.mapRequired("FrontendQFE", Compile3.VersionFrontendQFE);
- IO.mapRequired("BackendMajor", Compile3.VersionBackendMajor);
- IO.mapRequired("BackendMinor", Compile3.VersionBackendMinor);
- IO.mapRequired("BackendBuild", Compile3.VersionBackendBuild);
- IO.mapRequired("BackendQFE", Compile3.VersionBackendQFE);
- IO.mapRequired("Version", Compile3.Version);
-}
-
-void MappingTraits<FrameProcSym>::mapping(IO &IO, FrameProcSym &FrameProc) {
- IO.mapRequired("TotalFrameBytes", FrameProc.TotalFrameBytes);
- IO.mapRequired("PaddingFrameBytes", FrameProc.PaddingFrameBytes);
- IO.mapRequired("OffsetToPadding", FrameProc.OffsetToPadding);
- IO.mapRequired("BytesOfCalleeSavedRegisters",
- FrameProc.BytesOfCalleeSavedRegisters);
- IO.mapRequired("OffsetOfExceptionHandler",
- FrameProc.OffsetOfExceptionHandler);
- IO.mapRequired("SectionIdOfExceptionHandler",
- FrameProc.SectionIdOfExceptionHandler);
- IO.mapRequired("Flags", FrameProc.Flags);
-}
-
-void MappingTraits<CallSiteInfoSym>::mapping(IO &IO,
- CallSiteInfoSym &CallSiteInfo) {
- // TODO: Map Linkage Name
- IO.mapRequired("Segment", CallSiteInfo.Segment);
- IO.mapRequired("Type", CallSiteInfo.Type);
-}
-
-void MappingTraits<FileStaticSym>::mapping(IO &IO, FileStaticSym &FileStatic) {
- IO.mapRequired("Index", FileStatic.Index);
- IO.mapRequired("ModFilenameOffset", FileStatic.ModFilenameOffset);
- IO.mapRequired("Flags", FileStatic.Flags);
- IO.mapRequired("Name", FileStatic.Name);
-}
-
-void MappingTraits<HeapAllocationSiteSym>::mapping(
- IO &IO, HeapAllocationSiteSym &HeapAllocSite) {
- // TODO: Map Linkage Name
- IO.mapRequired("Segment", HeapAllocSite.Segment);
- IO.mapRequired("CallInstructionSize", HeapAllocSite.CallInstructionSize);
- IO.mapRequired("Type", HeapAllocSite.Type);
-}
-
-void MappingTraits<FrameCookieSym>::mapping(IO &IO,
- FrameCookieSym &FrameCookie) {
- // TODO: Map Linkage Name
- IO.mapRequired("Register", FrameCookie.Register);
- IO.mapRequired("CookieKind", FrameCookie.CookieKind);
- IO.mapRequired("Flags", FrameCookie.Flags);
-}
-
-void MappingTraits<CallerSym>::mapping(IO &IO, CallerSym &Caller) {
- // TODO: Correctly handle the ArrayRef in here.
- std::vector<TypeIndex> Indices(Caller.Indices);
- IO.mapRequired("FuncID", Indices);
-}
-
-void MappingTraits<UDTSym>::mapping(IO &IO, UDTSym &UDT) {
- IO.mapRequired("Type", UDT.Type);
- IO.mapRequired("UDTName", UDT.Name);
-}
-
-void MappingTraits<BuildInfoSym>::mapping(IO &IO, BuildInfoSym &BuildInfo) {
- IO.mapRequired("BuildId", BuildInfo.BuildId);
-}
-
-void MappingTraits<BPRelativeSym>::mapping(IO &IO, BPRelativeSym &BPRel) {
- IO.mapRequired("Offset", BPRel.Offset);
- IO.mapRequired("Type", BPRel.Type);
- IO.mapRequired("VarName", BPRel.Name);
-}
-
-void MappingTraits<RegRelativeSym>::mapping(IO &IO, RegRelativeSym &RegRel) {
- IO.mapRequired("Offset", RegRel.Offset);
- IO.mapRequired("Type", RegRel.Type);
- IO.mapRequired("Register", RegRel.Register);
- IO.mapRequired("VarName", RegRel.Name);
-}
-
-void MappingTraits<ConstantSym>::mapping(IO &IO, ConstantSym &Constant) {
- IO.mapRequired("Type", Constant.Type);
- IO.mapRequired("Value", Constant.Value);
- IO.mapRequired("Name", Constant.Name);
-}
-
-void MappingTraits<DataSym>::mapping(IO &IO, DataSym &Data) {
- // TODO: Map linkage name
- IO.mapRequired("Type", Data.Type);
- IO.mapRequired("DisplayName", Data.Name);
-}
-
-void MappingTraits<ThreadLocalDataSym>::mapping(IO &IO,
- ThreadLocalDataSym &Data) {
- // TODO: Map linkage name
- IO.mapRequired("Type", Data.Type);
- IO.mapRequired("DisplayName", Data.Name);
-}
-}
-}
-
-Error llvm::codeview::yaml::YamlSymbolDumper::visitSymbolBegin(CVSymbol &CVR) {
- YamlIO.mapRequired("Kind", CVR.Type);
- return Error::success();
-}
diff --git a/contrib/llvm/tools/llvm-pdbdump/YamlSymbolDumper.h b/contrib/llvm/tools/llvm-pdbdump/YamlSymbolDumper.h
deleted file mode 100644
index 61e63f96719a..000000000000
--- a/contrib/llvm/tools/llvm-pdbdump/YamlSymbolDumper.h
+++ /dev/null
@@ -1,66 +0,0 @@
-//===- YamlSymbolDumper.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_TOOLS_LLVMPDBDUMP_YAMLSYMBOLDUMPER_H
-#define LLVM_TOOLS_LLVMPDBDUMP_YAMLSYMBOLDUMPER_H
-
-#include "llvm/DebugInfo/CodeView/CodeView.h"
-#include "llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h"
-#include "llvm/Support/YAMLTraits.h"
-
-namespace llvm {
-namespace pdb {
-namespace yaml {
-struct SerializationContext;
-}
-}
-namespace codeview {
-namespace yaml {
-class YamlSymbolDumper : public SymbolVisitorCallbacks {
-public:
- YamlSymbolDumper(llvm::yaml::IO &IO) : YamlIO(IO) {}
-
- virtual Error visitSymbolBegin(CVSymbol &Record) override;
-
-#define SYMBOL_RECORD(EnumName, EnumVal, Name) \
- Error visitKnownRecord(CVSymbol &CVR, Name &Record) override { \
- visitKnownRecordImpl(#Name, CVR, Record); \
- return Error::success(); \
- }
-#define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
-#include "llvm/DebugInfo/CodeView/CVSymbolTypes.def"
-
-private:
- template <typename T>
- void visitKnownRecordImpl(const char *Name, CVSymbol &Type, T &Record) {
- YamlIO.mapRequired(Name, Record);
- }
-
- llvm::yaml::IO &YamlIO;
-};
-}
-}
-}
-
-namespace llvm {
-namespace yaml {
-template <> struct ScalarEnumerationTraits<codeview::SymbolKind> {
- static void enumeration(IO &io, codeview::SymbolKind &Value);
-};
-
-#define SYMBOL_RECORD(EnumName, EnumVal, Name) \
- template <> struct MappingTraits<codeview::Name> { \
- static void mapping(IO &IO, codeview::Name &Obj); \
- };
-#define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
-#include "llvm/DebugInfo/CodeView/CVSymbolTypes.def"
-}
-}
-
-#endif
diff --git a/contrib/llvm/tools/llvm-pdbdump/YamlTypeDumper.cpp b/contrib/llvm/tools/llvm-pdbdump/YamlTypeDumper.cpp
deleted file mode 100644
index beb700720954..000000000000
--- a/contrib/llvm/tools/llvm-pdbdump/YamlTypeDumper.cpp
+++ /dev/null
@@ -1,589 +0,0 @@
-//===- YamlTypeDumper.cpp ------------------------------------- *- C++ --*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "YamlTypeDumper.h"
-#include "PdbYaml.h"
-#include "YamlSerializationContext.h"
-
-#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
-#include "llvm/DebugInfo/CodeView/EnumTables.h"
-#include "llvm/DebugInfo/CodeView/TypeRecord.h"
-#include "llvm/DebugInfo/CodeView/TypeSerializer.h"
-#include "llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h"
-#include "llvm/DebugInfo/PDB/Native/TpiHashing.h"
-
-using namespace llvm;
-using namespace llvm::codeview;
-using namespace llvm::codeview::yaml;
-
-LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(TypeIndex)
-LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(uint64_t)
-LLVM_YAML_IS_SEQUENCE_VECTOR(OneMethodRecord)
-LLVM_YAML_IS_SEQUENCE_VECTOR(VFTableSlotKind)
-LLVM_YAML_IS_SEQUENCE_VECTOR(StringRef)
-LLVM_YAML_IS_SEQUENCE_VECTOR(CVType)
-LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::pdb::yaml::PdbTpiFieldListRecord)
-
-namespace {
-struct FieldListRecordSplitter : public TypeVisitorCallbacks {
-public:
- explicit FieldListRecordSplitter(
- std::vector<llvm::pdb::yaml::PdbTpiFieldListRecord> &Records)
- : Records(Records) {}
-
-#define TYPE_RECORD(EnumName, EnumVal, Name)
-#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
-#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
-#define MEMBER_RECORD(EnumName, EnumVal, Name) \
- Error visitKnownMember(CVMemberRecord &CVT, Name##Record &Record) override { \
- visitKnownMemberImpl(CVT); \
- return Error::success(); \
- }
-#include "llvm/DebugInfo/CodeView/TypeRecords.def"
-
-private:
- void visitKnownMemberImpl(CVMemberRecord &CVT) {
- llvm::pdb::yaml::PdbTpiFieldListRecord R;
- R.Record = CVT;
- Records.push_back(std::move(R));
- }
-
- std::vector<llvm::pdb::yaml::PdbTpiFieldListRecord> &Records;
-};
-}
-
-namespace llvm {
-namespace yaml {
-template <> struct ScalarEnumerationTraits<PointerToMemberRepresentation> {
- static void enumeration(IO &IO, PointerToMemberRepresentation &Value) {
- IO.enumCase(Value, "Unknown", PointerToMemberRepresentation::Unknown);
- IO.enumCase(Value, "SingleInheritanceData",
- PointerToMemberRepresentation::SingleInheritanceData);
- IO.enumCase(Value, "MultipleInheritanceData",
- PointerToMemberRepresentation::MultipleInheritanceData);
- IO.enumCase(Value, "VirtualInheritanceData",
- PointerToMemberRepresentation::VirtualInheritanceData);
- IO.enumCase(Value, "GeneralData",
- PointerToMemberRepresentation::GeneralData);
- IO.enumCase(Value, "SingleInheritanceFunction",
- PointerToMemberRepresentation::SingleInheritanceFunction);
- IO.enumCase(Value, "MultipleInheritanceFunction",
- PointerToMemberRepresentation::MultipleInheritanceFunction);
- IO.enumCase(Value, "VirtualInheritanceFunction",
- PointerToMemberRepresentation::VirtualInheritanceFunction);
- IO.enumCase(Value, "GeneralFunction",
- PointerToMemberRepresentation::GeneralFunction);
- }
-};
-
-template <> struct ScalarEnumerationTraits<VFTableSlotKind> {
- static void enumeration(IO &IO, VFTableSlotKind &Kind) {
- IO.enumCase(Kind, "Near16", VFTableSlotKind::Near16);
- IO.enumCase(Kind, "Far16", VFTableSlotKind::Far16);
- IO.enumCase(Kind, "This", VFTableSlotKind::This);
- IO.enumCase(Kind, "Outer", VFTableSlotKind::Outer);
- IO.enumCase(Kind, "Meta", VFTableSlotKind::Meta);
- IO.enumCase(Kind, "Near", VFTableSlotKind::Near);
- IO.enumCase(Kind, "Far", VFTableSlotKind::Far);
- }
-};
-
-template <> struct ScalarEnumerationTraits<CallingConvention> {
- static void enumeration(IO &IO, CallingConvention &Value) {
- IO.enumCase(Value, "NearC", CallingConvention::NearC);
- IO.enumCase(Value, "FarC", CallingConvention::FarC);
- IO.enumCase(Value, "NearPascal", CallingConvention::NearPascal);
- IO.enumCase(Value, "FarPascal", CallingConvention::FarPascal);
- IO.enumCase(Value, "NearFast", CallingConvention::NearFast);
- IO.enumCase(Value, "FarFast", CallingConvention::FarFast);
- IO.enumCase(Value, "NearStdCall", CallingConvention::NearStdCall);
- IO.enumCase(Value, "FarStdCall", CallingConvention::FarStdCall);
- IO.enumCase(Value, "NearSysCall", CallingConvention::NearSysCall);
- IO.enumCase(Value, "FarSysCall", CallingConvention::FarSysCall);
- IO.enumCase(Value, "ThisCall", CallingConvention::ThisCall);
- IO.enumCase(Value, "MipsCall", CallingConvention::MipsCall);
- IO.enumCase(Value, "Generic", CallingConvention::Generic);
- IO.enumCase(Value, "AlphaCall", CallingConvention::AlphaCall);
- IO.enumCase(Value, "PpcCall", CallingConvention::PpcCall);
- IO.enumCase(Value, "SHCall", CallingConvention::SHCall);
- IO.enumCase(Value, "ArmCall", CallingConvention::ArmCall);
- IO.enumCase(Value, "AM33Call", CallingConvention::AM33Call);
- IO.enumCase(Value, "TriCall", CallingConvention::TriCall);
- IO.enumCase(Value, "SH5Call", CallingConvention::SH5Call);
- IO.enumCase(Value, "M32RCall", CallingConvention::M32RCall);
- IO.enumCase(Value, "ClrCall", CallingConvention::ClrCall);
- IO.enumCase(Value, "Inline", CallingConvention::Inline);
- IO.enumCase(Value, "NearVector", CallingConvention::NearVector);
- }
-};
-
-template <> struct ScalarEnumerationTraits<PointerKind> {
- static void enumeration(IO &IO, PointerKind &Kind) {
- IO.enumCase(Kind, "Near16", PointerKind::Near16);
- IO.enumCase(Kind, "Far16", PointerKind::Far16);
- IO.enumCase(Kind, "Huge16", PointerKind::Huge16);
- IO.enumCase(Kind, "BasedOnSegment", PointerKind::BasedOnSegment);
- IO.enumCase(Kind, "BasedOnValue", PointerKind::BasedOnValue);
- IO.enumCase(Kind, "BasedOnSegmentValue", PointerKind::BasedOnSegmentValue);
- IO.enumCase(Kind, "BasedOnAddress", PointerKind::BasedOnAddress);
- IO.enumCase(Kind, "BasedOnSegmentAddress",
- PointerKind::BasedOnSegmentAddress);
- IO.enumCase(Kind, "BasedOnType", PointerKind::BasedOnType);
- IO.enumCase(Kind, "BasedOnSelf", PointerKind::BasedOnSelf);
- IO.enumCase(Kind, "Near32", PointerKind::Near32);
- IO.enumCase(Kind, "Far32", PointerKind::Far32);
- IO.enumCase(Kind, "Near64", PointerKind::Near64);
- }
-};
-
-template <> struct ScalarEnumerationTraits<PointerMode> {
- static void enumeration(IO &IO, PointerMode &Mode) {
- IO.enumCase(Mode, "Pointer", PointerMode::Pointer);
- IO.enumCase(Mode, "LValueReference", PointerMode::LValueReference);
- IO.enumCase(Mode, "PointerToDataMember", PointerMode::PointerToDataMember);
- IO.enumCase(Mode, "PointerToMemberFunction",
- PointerMode::PointerToMemberFunction);
- IO.enumCase(Mode, "RValueReference", PointerMode::RValueReference);
- }
-};
-
-template <> struct ScalarEnumerationTraits<HfaKind> {
- static void enumeration(IO &IO, HfaKind &Value) {
- IO.enumCase(Value, "None", HfaKind::None);
- IO.enumCase(Value, "Float", HfaKind::Float);
- IO.enumCase(Value, "Double", HfaKind::Double);
- IO.enumCase(Value, "Other", HfaKind::Other);
- }
-};
-
-template <> struct ScalarEnumerationTraits<MemberAccess> {
- static void enumeration(IO &IO, MemberAccess &Access) {
- IO.enumCase(Access, "None", MemberAccess::None);
- IO.enumCase(Access, "Private", MemberAccess::Private);
- IO.enumCase(Access, "Protected", MemberAccess::Protected);
- IO.enumCase(Access, "Public", MemberAccess::Public);
- }
-};
-
-template <> struct ScalarEnumerationTraits<MethodKind> {
- static void enumeration(IO &IO, MethodKind &Kind) {
- IO.enumCase(Kind, "Vanilla", MethodKind::Vanilla);
- IO.enumCase(Kind, "Virtual", MethodKind::Virtual);
- IO.enumCase(Kind, "Static", MethodKind::Static);
- IO.enumCase(Kind, "Friend", MethodKind::Friend);
- IO.enumCase(Kind, "IntroducingVirtual", MethodKind::IntroducingVirtual);
- IO.enumCase(Kind, "PureVirtual", MethodKind::PureVirtual);
- IO.enumCase(Kind, "PureIntroducingVirtual",
- MethodKind::PureIntroducingVirtual);
- }
-};
-
-template <> struct ScalarEnumerationTraits<WindowsRTClassKind> {
- static void enumeration(IO &IO, WindowsRTClassKind &Value) {
- IO.enumCase(Value, "None", WindowsRTClassKind::None);
- IO.enumCase(Value, "Ref", WindowsRTClassKind::RefClass);
- IO.enumCase(Value, "Value", WindowsRTClassKind::ValueClass);
- IO.enumCase(Value, "Interface", WindowsRTClassKind::Interface);
- }
-};
-
-template <> struct ScalarEnumerationTraits<LabelType> {
- static void enumeration(IO &IO, LabelType &Value) {
- IO.enumCase(Value, "Near", LabelType::Near);
- IO.enumCase(Value, "Far", LabelType::Far);
- }
-};
-
-template <> struct ScalarBitSetTraits<PointerOptions> {
- static void bitset(IO &IO, PointerOptions &Options) {
- IO.bitSetCase(Options, "None", PointerOptions::None);
- IO.bitSetCase(Options, "Flat32", PointerOptions::Flat32);
- IO.bitSetCase(Options, "Volatile", PointerOptions::Volatile);
- IO.bitSetCase(Options, "Const", PointerOptions::Const);
- IO.bitSetCase(Options, "Unaligned", PointerOptions::Unaligned);
- IO.bitSetCase(Options, "Restrict", PointerOptions::Restrict);
- IO.bitSetCase(Options, "WinRTSmartPointer",
- PointerOptions::WinRTSmartPointer);
- }
-};
-
-template <> struct ScalarBitSetTraits<ModifierOptions> {
- static void bitset(IO &IO, ModifierOptions &Options) {
- IO.bitSetCase(Options, "None", ModifierOptions::None);
- IO.bitSetCase(Options, "Const", ModifierOptions::Const);
- IO.bitSetCase(Options, "Volatile", ModifierOptions::Volatile);
- IO.bitSetCase(Options, "Unaligned", ModifierOptions::Unaligned);
- }
-};
-
-template <> struct ScalarBitSetTraits<FunctionOptions> {
- static void bitset(IO &IO, FunctionOptions &Options) {
- IO.bitSetCase(Options, "None", FunctionOptions::None);
- IO.bitSetCase(Options, "CxxReturnUdt", FunctionOptions::CxxReturnUdt);
- IO.bitSetCase(Options, "Constructor", FunctionOptions::Constructor);
- IO.bitSetCase(Options, "ConstructorWithVirtualBases",
- FunctionOptions::ConstructorWithVirtualBases);
- }
-};
-
-template <> struct ScalarBitSetTraits<ClassOptions> {
- static void bitset(IO &IO, ClassOptions &Options) {
- IO.bitSetCase(Options, "None", ClassOptions::None);
- IO.bitSetCase(Options, "HasConstructorOrDestructor",
- ClassOptions::HasConstructorOrDestructor);
- IO.bitSetCase(Options, "HasOverloadedOperator",
- ClassOptions::HasOverloadedOperator);
- IO.bitSetCase(Options, "Nested", ClassOptions::Nested);
- IO.bitSetCase(Options, "ContainsNestedClass",
- ClassOptions::ContainsNestedClass);
- IO.bitSetCase(Options, "HasOverloadedAssignmentOperator",
- ClassOptions::HasOverloadedAssignmentOperator);
- IO.bitSetCase(Options, "HasConversionOperator",
- ClassOptions::HasConversionOperator);
- IO.bitSetCase(Options, "ForwardReference", ClassOptions::ForwardReference);
- IO.bitSetCase(Options, "Scoped", ClassOptions::Scoped);
- IO.bitSetCase(Options, "HasUniqueName", ClassOptions::HasUniqueName);
- IO.bitSetCase(Options, "Sealed", ClassOptions::Sealed);
- IO.bitSetCase(Options, "Intrinsic", ClassOptions::Intrinsic);
- }
-};
-
-template <> struct ScalarBitSetTraits<MethodOptions> {
- static void bitset(IO &IO, MethodOptions &Options) {
- IO.bitSetCase(Options, "None", MethodOptions::None);
- IO.bitSetCase(Options, "Pseudo", MethodOptions::Pseudo);
- IO.bitSetCase(Options, "NoInherit", MethodOptions::NoInherit);
- IO.bitSetCase(Options, "NoConstruct", MethodOptions::NoConstruct);
- IO.bitSetCase(Options, "CompilerGenerated",
- MethodOptions::CompilerGenerated);
- IO.bitSetCase(Options, "Sealed", MethodOptions::Sealed);
- }
-};
-
-void ScalarTraits<APSInt>::output(const APSInt &S, void *,
- llvm::raw_ostream &OS) {
- S.print(OS, true);
-}
-StringRef ScalarTraits<APSInt>::input(StringRef Scalar, void *Ctx, APSInt &S) {
- S = APSInt(Scalar);
- return "";
-}
-
-bool ScalarTraits<APSInt>::mustQuote(StringRef Scalar) { return false; }
-
-void MappingContextTraits<CVType, pdb::yaml::SerializationContext>::mapping(
- IO &IO, CVType &Record, pdb::yaml::SerializationContext &Context) {
- if (IO.outputting())
- consumeError(codeview::visitTypeRecord(Record, Context.Dumper));
-}
-
-void MappingTraits<StringIdRecord>::mapping(IO &IO, StringIdRecord &String) {
- IO.mapRequired("Id", String.Id);
- IO.mapRequired("String", String.String);
-}
-
-void MappingTraits<ArgListRecord>::mapping(IO &IO, ArgListRecord &Args) {
- IO.mapRequired("ArgIndices", Args.ArgIndices);
-}
-
-void MappingTraits<StringListRecord>::mapping(IO &IO, StringListRecord &Strings) {
- IO.mapRequired("StringIndices", Strings.StringIndices);
-}
-
-void MappingTraits<ClassRecord>::mapping(IO &IO, ClassRecord &Class) {
- IO.mapRequired("MemberCount", Class.MemberCount);
- IO.mapRequired("Options", Class.Options);
- IO.mapRequired("FieldList", Class.FieldList);
- IO.mapRequired("Name", Class.Name);
- IO.mapRequired("UniqueName", Class.UniqueName);
- IO.mapRequired("DerivationList", Class.DerivationList);
- IO.mapRequired("VTableShape", Class.VTableShape);
- IO.mapRequired("Size", Class.Size);
-}
-
-void MappingTraits<UnionRecord>::mapping(IO &IO, UnionRecord &Union) {
- IO.mapRequired("MemberCount", Union.MemberCount);
- IO.mapRequired("Options", Union.Options);
- IO.mapRequired("FieldList", Union.FieldList);
- IO.mapRequired("Name", Union.Name);
- IO.mapRequired("UniqueName", Union.UniqueName);
- IO.mapRequired("Size", Union.Size);
-}
-
-void MappingTraits<EnumRecord>::mapping(IO &IO, EnumRecord &Enum) {
- IO.mapRequired("NumEnumerators", Enum.MemberCount);
- IO.mapRequired("Options", Enum.Options);
- IO.mapRequired("FieldList", Enum.FieldList);
- IO.mapRequired("Name", Enum.Name);
- IO.mapRequired("UniqueName", Enum.UniqueName);
- IO.mapRequired("UnderlyingType", Enum.UnderlyingType);
-}
-
-void MappingTraits<ArrayRecord>::mapping(IO &IO, ArrayRecord &AT) {
- IO.mapRequired("ElementType", AT.ElementType);
- IO.mapRequired("IndexType", AT.IndexType);
- IO.mapRequired("Size", AT.Size);
- IO.mapRequired("Name", AT.Name);
-}
-
-void MappingTraits<VFTableRecord>::mapping(IO &IO, VFTableRecord &VFT) {
- IO.mapRequired("CompleteClass", VFT.CompleteClass);
- IO.mapRequired("OverriddenVFTable", VFT.OverriddenVFTable);
- IO.mapRequired("VFPtrOffset", VFT.VFPtrOffset);
- IO.mapRequired("MethodNames", VFT.MethodNames);
-}
-
-void MappingTraits<MemberFuncIdRecord>::mapping(IO &IO,
- MemberFuncIdRecord &Id) {
- IO.mapRequired("ClassType", Id.ClassType);
- IO.mapRequired("FunctionType", Id.FunctionType);
- IO.mapRequired("Name", Id.Name);
-}
-
-void MappingTraits<ProcedureRecord>::mapping(IO &IO, ProcedureRecord &Proc) {
- IO.mapRequired("ReturnType", Proc.ReturnType);
- IO.mapRequired("CallConv", Proc.CallConv);
- IO.mapRequired("Options", Proc.Options);
- IO.mapRequired("ParameterCount", Proc.ParameterCount);
- IO.mapRequired("ArgumentList", Proc.ArgumentList);
-}
-
-void MappingTraits<MemberFunctionRecord>::mapping(IO &IO,
- MemberFunctionRecord &MF) {
- IO.mapRequired("ReturnType", MF.ReturnType);
- IO.mapRequired("ClassType", MF.ClassType);
- IO.mapRequired("ThisType", MF.ThisType);
- IO.mapRequired("CallConv", MF.CallConv);
- IO.mapRequired("Options", MF.Options);
- IO.mapRequired("ParameterCount", MF.ParameterCount);
- IO.mapRequired("ArgumentList", MF.ArgumentList);
- IO.mapRequired("ThisPointerAdjustment", MF.ThisPointerAdjustment);
-}
-
-void MappingTraits<MethodOverloadListRecord>::mapping(
- IO &IO, MethodOverloadListRecord &MethodList) {
- IO.mapRequired("Methods", MethodList.Methods);
-}
-
-void MappingTraits<FuncIdRecord>::mapping(IO &IO, FuncIdRecord &Func) {
- IO.mapRequired("ParentScope", Func.ParentScope);
- IO.mapRequired("FunctionType", Func.FunctionType);
- IO.mapRequired("Name", Func.Name);
-}
-
-void MappingTraits<TypeServer2Record>::mapping(IO &IO, TypeServer2Record &TS) {
- IO.mapRequired("Guid", TS.Guid);
- IO.mapRequired("Age", TS.Age);
- IO.mapRequired("Name", TS.Name);
-}
-
-void MappingTraits<PointerRecord>::mapping(IO &IO, PointerRecord &Ptr) {
- IO.mapRequired("ReferentType", Ptr.ReferentType);
- IO.mapRequired("Attrs", Ptr.Attrs);
- IO.mapOptional("MemberInfo", Ptr.MemberInfo);
-}
-
-void MappingTraits<MemberPointerInfo>::mapping(IO &IO, MemberPointerInfo &MPI) {
- IO.mapRequired("ContainingType", MPI.ContainingType);
- IO.mapRequired("Representation", MPI.Representation);
-}
-
-void MappingTraits<ModifierRecord>::mapping(IO &IO, ModifierRecord &Mod) {
- IO.mapRequired("ModifiedType", Mod.ModifiedType);
- IO.mapRequired("Modifiers", Mod.Modifiers);
-}
-
-void MappingTraits<BitFieldRecord>::mapping(IO &IO, BitFieldRecord &BitField) {
- IO.mapRequired("Type", BitField.Type);
- IO.mapRequired("BitSize", BitField.BitSize);
- IO.mapRequired("BitOffset", BitField.BitOffset);
-}
-
-void MappingTraits<VFTableShapeRecord>::mapping(IO &IO,
- VFTableShapeRecord &Shape) {
- IO.mapRequired("Slots", Shape.Slots);
-}
-
-void MappingTraits<UdtSourceLineRecord>::mapping(IO &IO,
- UdtSourceLineRecord &Line) {
- IO.mapRequired("UDT", Line.UDT);
- IO.mapRequired("SourceFile", Line.SourceFile);
- IO.mapRequired("LineNumber", Line.LineNumber);
-}
-
-void MappingTraits<UdtModSourceLineRecord>::mapping(
- IO &IO, UdtModSourceLineRecord &Line) {
- IO.mapRequired("UDT", Line.UDT);
- IO.mapRequired("SourceFile", Line.SourceFile);
- IO.mapRequired("LineNumber", Line.LineNumber);
- IO.mapRequired("Module", Line.Module);
-}
-
-void MappingTraits<BuildInfoRecord>::mapping(IO &IO, BuildInfoRecord &Args) {
- IO.mapRequired("ArgIndices", Args.ArgIndices);
-}
-
-void MappingTraits<LabelRecord>::mapping(IO &IO, LabelRecord &R) {
- IO.mapRequired("Mode", R.Mode);
-}
-
-void MappingTraits<NestedTypeRecord>::mapping(IO &IO,
- NestedTypeRecord &Nested) {
- IO.mapRequired("Type", Nested.Type);
- IO.mapRequired("Name", Nested.Name);
-}
-
-void MappingTraits<OneMethodRecord>::mapping(IO &IO, OneMethodRecord &Method) {
- IO.mapRequired("Type", Method.Type);
- IO.mapRequired("Attrs", Method.Attrs.Attrs);
- IO.mapRequired("VFTableOffset", Method.VFTableOffset);
- IO.mapRequired("Name", Method.Name);
-}
-
-void MappingTraits<OverloadedMethodRecord>::mapping(
- IO &IO, OverloadedMethodRecord &Method) {
- IO.mapRequired("NumOverloads", Method.NumOverloads);
- IO.mapRequired("MethodList", Method.MethodList);
- IO.mapRequired("Name", Method.Name);
-}
-
-void MappingTraits<DataMemberRecord>::mapping(IO &IO, DataMemberRecord &Field) {
- IO.mapRequired("Attrs", Field.Attrs.Attrs);
- IO.mapRequired("Type", Field.Type);
- IO.mapRequired("FieldOffset", Field.FieldOffset);
- IO.mapRequired("Name", Field.Name);
-}
-
-void MappingTraits<StaticDataMemberRecord>::mapping(
- IO &IO, StaticDataMemberRecord &Field) {
- IO.mapRequired("Attrs", Field.Attrs.Attrs);
- IO.mapRequired("Type", Field.Type);
- IO.mapRequired("Name", Field.Name);
-}
-
-void MappingTraits<VFPtrRecord>::mapping(IO &IO, VFPtrRecord &VFTable) {
- IO.mapRequired("Type", VFTable.Type);
-}
-
-void MappingTraits<EnumeratorRecord>::mapping(IO &IO, EnumeratorRecord &Enum) {
- IO.mapRequired("Attrs", Enum.Attrs.Attrs);
- IO.mapRequired("Value", Enum.Value);
- IO.mapRequired("Name", Enum.Name);
-}
-
-void MappingTraits<BaseClassRecord>::mapping(IO &IO, BaseClassRecord &Base) {
- IO.mapRequired("Attrs", Base.Attrs.Attrs);
- IO.mapRequired("Type", Base.Type);
- IO.mapRequired("Offset", Base.Offset);
-}
-
-void MappingTraits<VirtualBaseClassRecord>::mapping(
- IO &IO, VirtualBaseClassRecord &Base) {
- IO.mapRequired("Attrs", Base.Attrs.Attrs);
- IO.mapRequired("BaseType", Base.BaseType);
- IO.mapRequired("VBPtrType", Base.VBPtrType);
- IO.mapRequired("VBPtrOffset", Base.VBPtrOffset);
- IO.mapRequired("VTableIndex", Base.VTableIndex);
-}
-
-void MappingTraits<ListContinuationRecord>::mapping(
- IO &IO, ListContinuationRecord &Cont) {
- IO.mapRequired("ContinuationIndex", Cont.ContinuationIndex);
-}
-
-void ScalarTraits<codeview::TypeIndex>::output(const codeview::TypeIndex &S,
- void *, llvm::raw_ostream &OS) {
- OS << S.getIndex();
-}
-StringRef ScalarTraits<codeview::TypeIndex>::input(StringRef Scalar, void *Ctx,
- codeview::TypeIndex &S) {
- uint32_t I;
- StringRef Result = ScalarTraits<uint32_t>::input(Scalar, Ctx, I);
- if (!Result.empty())
- return Result;
- S = TypeIndex(I);
- return "";
-}
-bool ScalarTraits<codeview::TypeIndex>::mustQuote(StringRef Scalar) {
- return false;
-}
-
-void ScalarEnumerationTraits<TypeLeafKind>::enumeration(IO &io,
- TypeLeafKind &Value) {
- auto TypeLeafNames = getTypeLeafNames();
- for (const auto &E : TypeLeafNames)
- io.enumCase(Value, E.Name.str().c_str(), E.Value);
-}
-}
-}
-
-Error llvm::codeview::yaml::YamlTypeDumperCallbacks::visitTypeBegin(
- CVType &CVR) {
- YamlIO.mapRequired("Kind", CVR.Type);
- return Error::success();
-}
-
-Error llvm::codeview::yaml::YamlTypeDumperCallbacks::visitMemberBegin(
- CVMemberRecord &Record) {
- YamlIO.mapRequired("Kind", Record.Kind);
- return Error::success();
-}
-
-void llvm::codeview::yaml::YamlTypeDumperCallbacks::visitKnownRecordImpl(
- const char *Name, CVType &CVR, FieldListRecord &FieldList) {
- std::vector<llvm::pdb::yaml::PdbTpiFieldListRecord> FieldListRecords;
- if (YamlIO.outputting()) {
- // If we are outputting, then `FieldList.Data` contains a huge chunk of data
- // representing the serialized list of members. We need to split it up into
- // individual CVType records where each record represents an individual
- // member. This way, we can simply map the entire thing as a Yaml sequence,
- // which will recurse back to the standard handler for top-level fields
- // (top-level and member fields all have the exact same Yaml syntax so use
- // the same parser).
- FieldListRecordSplitter Splitter(FieldListRecords);
- consumeError(codeview::visitMemberRecordStream(FieldList.Data, Splitter));
- }
- // Note that if we're not outputting (i.e. Yaml -> PDB) the result of this
- // mapping gets lost, as the records are simply stored in this locally scoped
- // vector. What's important though is they are all sharing a single
- // Serializer
- // instance (in `Context.ActiveSerializer`), and that is building up a list of
- // all the types. The fact that we need a throwaway vector here is just to
- // appease the YAML API to treat this as a sequence and do this mapping once
- // for each YAML Sequence element in the input Yaml stream.
- YamlIO.mapRequired("FieldList", FieldListRecords, Context);
-}
-
-namespace llvm {
-namespace yaml {
-template <>
-struct MappingContextTraits<pdb::yaml::PdbTpiFieldListRecord,
- pdb::yaml::SerializationContext> {
- static void mapping(IO &IO, pdb::yaml::PdbTpiFieldListRecord &Obj,
- pdb::yaml::SerializationContext &Context) {
- if (IO.outputting())
- consumeError(codeview::visitMemberRecord(Obj.Record, Context.Dumper));
- else {
- // If we are not outputting, then the array contains no data starting out,
- // and is instead populated from the sequence represented by the yaml --
- // again, using the same logic that we use for top-level records.
- assert(Context.ActiveSerializer && "There is no active serializer!");
- codeview::TypeVisitorCallbackPipeline Pipeline;
- pdb::TpiHashUpdater Hasher;
-
- Pipeline.addCallbackToPipeline(Context.Dumper);
- Pipeline.addCallbackToPipeline(*Context.ActiveSerializer);
- Pipeline.addCallbackToPipeline(Hasher);
- consumeError(
- codeview::visitMemberRecord(Obj.Record, Pipeline, VDS_BytesExternal));
- }
- }
-};
-}
-}
diff --git a/contrib/llvm/tools/llvm-pdbdump/YamlTypeDumper.h b/contrib/llvm/tools/llvm-pdbdump/YamlTypeDumper.h
deleted file mode 100644
index 3f15ba0bf85d..000000000000
--- a/contrib/llvm/tools/llvm-pdbdump/YamlTypeDumper.h
+++ /dev/null
@@ -1,116 +0,0 @@
-//===- YamlTypeDumper.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_TOOLS_LLVMPDBDUMP_YAMLTYPEDUMPER_H
-#define LLVM_TOOLS_LLVMPDBDUMP_YAMLTYPEDUMPER_H
-
-#include "llvm/DebugInfo/CodeView/CodeView.h"
-#include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
-#include "llvm/Support/YAMLTraits.h"
-
-namespace llvm {
-namespace pdb {
-namespace yaml {
-struct SerializationContext;
-}
-}
-namespace codeview {
-namespace yaml {
-class YamlTypeDumperCallbacks : public TypeVisitorCallbacks {
-public:
- YamlTypeDumperCallbacks(llvm::yaml::IO &IO,
- llvm::pdb::yaml::SerializationContext &Context)
- : YamlIO(IO), Context(Context) {}
-
- virtual Error visitTypeBegin(CVType &Record) override;
- virtual Error visitMemberBegin(CVMemberRecord &Record) override;
-
-#define TYPE_RECORD(EnumName, EnumVal, Name) \
- Error visitKnownRecord(CVRecord<TypeLeafKind> &CVR, Name##Record &Record) \
- override { \
- visitKnownRecordImpl(#Name, CVR, Record); \
- return Error::success(); \
- }
-#define MEMBER_RECORD(EnumName, EnumVal, Name) \
- Error visitKnownMember(CVMemberRecord &CVR, Name##Record &Record) override { \
- visitKnownMemberImpl(#Name, Record); \
- return Error::success(); \
- }
-#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
-#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
-#include "llvm/DebugInfo/CodeView/TypeRecords.def"
-
-private:
- template <typename T> void visitKnownMemberImpl(const char *Name, T &Record) {
- YamlIO.mapRequired(Name, Record);
- }
-
- template <typename T>
- void visitKnownRecordImpl(const char *Name, CVType &Type, T &Record) {
- YamlIO.mapRequired(Name, Record);
- }
-
- void visitKnownRecordImpl(const char *Name, CVType &CVR,
- FieldListRecord &FieldList);
-
- llvm::yaml::IO &YamlIO;
- llvm::pdb::yaml::SerializationContext &Context;
-};
-}
-}
-namespace pdb {
-namespace yaml {
-struct SerializationContext;
-}
-}
-}
-
-namespace llvm {
-namespace yaml {
-
-template <> struct ScalarTraits<APSInt> {
- static void output(const APSInt &S, void *, llvm::raw_ostream &OS);
- static StringRef input(StringRef Scalar, void *Ctx, APSInt &S);
- static bool mustQuote(StringRef Scalar);
-};
-
-template <> struct ScalarTraits<codeview::TypeIndex> {
- static void output(const codeview::TypeIndex &S, void *,
- llvm::raw_ostream &OS);
- static StringRef input(StringRef Scalar, void *Ctx, codeview::TypeIndex &S);
- static bool mustQuote(StringRef Scalar);
-};
-
-template <> struct MappingTraits<codeview::MemberPointerInfo> {
- static void mapping(IO &IO, codeview::MemberPointerInfo &Obj);
-};
-
-template <>
-struct MappingContextTraits<codeview::CVType, pdb::yaml::SerializationContext> {
- static void mapping(IO &IO, codeview::CVType &Obj,
- pdb::yaml::SerializationContext &Context);
-};
-
-template <> struct ScalarEnumerationTraits<codeview::TypeLeafKind> {
- static void enumeration(IO &io, codeview::TypeLeafKind &Value);
-};
-
-#define TYPE_RECORD(EnumName, EnumVal, Name) \
- template <> struct MappingTraits<codeview::Name##Record> { \
- static void mapping(IO &IO, codeview::Name##Record &Obj); \
- };
-#define MEMBER_RECORD(EnumName, EnumVal, Name) \
- TYPE_RECORD(EnumName, EnumVal, Name)
-#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
-#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
-#include "llvm/DebugInfo/CodeView/TypeRecords.def"
-}
-}
-
-#endif
diff --git a/contrib/llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp b/contrib/llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp
index baba862ae663..0b2b766a3c52 100644
--- a/contrib/llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp
+++ b/contrib/llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp
@@ -476,6 +476,7 @@ static void yamlToPdb(StringRef Path) {
std::unique_ptr<MemoryBuffer> &Buffer = ErrorOrBuffer.get();
llvm::yaml::Input In(Buffer->getBuffer());
+ In.setContext(&Allocator);
pdb::yaml::PdbObject YamlObj(Allocator);
In >> YamlObj;
@@ -535,7 +536,7 @@ static void yamlToPdb(StringRef Path) {
if (MI.Modi.hasValue()) {
const auto &ModiStream = *MI.Modi;
for (auto Symbol : ModiStream.Symbols)
- ModiBuilder.addSymbol(Symbol.Record);
+ ModiBuilder.addSymbol(Symbol.toCodeViewSymbol(Allocator));
}
if (MI.FileLineInfo.hasValue()) {
const auto &FLI = *MI.FileLineInfo;
@@ -584,7 +585,7 @@ static void yamlToPdb(StringRef Path) {
auto Inlinees = llvm::make_unique<DebugInlineeLinesSubsection>(
ChecksumRef, Inlinee.HasExtraFiles);
for (const auto &Site : Inlinee.Sites) {
- Inlinees->addInlineSite(Site.Inlinee, Site.FileName,
+ Inlinees->addInlineSite(TypeIndex(Site.Inlinee), Site.FileName,
Site.SourceLineNum);
if (!Inlinee.HasExtraFiles)
continue;
@@ -601,14 +602,18 @@ static void yamlToPdb(StringRef Path) {
auto &TpiBuilder = Builder.getTpiBuilder();
const auto &Tpi = YamlObj.TpiStream.getValueOr(DefaultTpiStream);
TpiBuilder.setVersionHeader(Tpi.Version);
- for (const auto &R : Tpi.Records)
- TpiBuilder.addTypeRecord(R.Record.data(), R.Record.Hash);
+ for (const auto &R : Tpi.Records) {
+ CVType Type = R.toCodeViewRecord(Allocator);
+ TpiBuilder.addTypeRecord(Type.RecordData, None);
+ }
const auto &Ipi = YamlObj.IpiStream.getValueOr(DefaultIpiStream);
auto &IpiBuilder = Builder.getIpiBuilder();
IpiBuilder.setVersionHeader(Ipi.Version);
- for (const auto &R : Ipi.Records)
- IpiBuilder.addTypeRecord(R.Record.data(), R.Record.Hash);
+ for (const auto &R : Ipi.Records) {
+ CVType Type = R.toCodeViewRecord(Allocator);
+ IpiBuilder.addTypeRecord(Type.RecordData, None);
+ }
ExitOnErr(Builder.commit(opts::yaml2pdb::YamlPdbOutputFile));
}
diff --git a/contrib/llvm/tools/llvm-readobj/ELFDumper.cpp b/contrib/llvm/tools/llvm-readobj/ELFDumper.cpp
index 2e9e01d9642b..427920569042 100644
--- a/contrib/llvm/tools/llvm-readobj/ELFDumper.cpp
+++ b/contrib/llvm/tools/llvm-readobj/ELFDumper.cpp
@@ -2742,6 +2742,7 @@ std::string GNUStyle<ELFT>::getSymbolSectionNdx(const ELFO *Obj,
case ELF::SHN_XINDEX:
SectionIndex = unwrapOrError(object::getExtendedSymbolTableIndex<ELFT>(
Symbol, FirstSym, this->dumper()->getShndxTable()));
+ LLVM_FALLTHROUGH;
default:
// Find if:
// Processor specific
diff --git a/contrib/llvm/tools/opt/NewPMDriver.cpp b/contrib/llvm/tools/opt/NewPMDriver.cpp
index df467da690e7..58e9caeff0fb 100644
--- a/contrib/llvm/tools/opt/NewPMDriver.cpp
+++ b/contrib/llvm/tools/opt/NewPMDriver.cpp
@@ -29,6 +29,7 @@
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/ToolOutputFile.h"
#include "llvm/Target/TargetMachine.h"
+#include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h"
#include "llvm/Transforms/Scalar/LoopPassManager.h"
using namespace llvm;
@@ -47,8 +48,9 @@ static cl::opt<std::string>
"pipeline for handling managed aliasing queries"),
cl::Hidden);
-bool llvm::runPassPipeline(StringRef Arg0, Module &M,
- TargetMachine *TM, tool_output_file *Out,
+bool llvm::runPassPipeline(StringRef Arg0, Module &M, TargetMachine *TM,
+ tool_output_file *Out,
+ tool_output_file *ThinLTOLinkOut,
StringRef PassPipeline, OutputKind OK,
VerifierKind VK,
bool ShouldPreserveAssemblyUseListOrder,
@@ -104,6 +106,10 @@ bool llvm::runPassPipeline(StringRef Arg0, Module &M,
MPM.addPass(BitcodeWriterPass(Out->os(), ShouldPreserveBitcodeUseListOrder,
EmitSummaryIndex, EmitModuleHash));
break;
+ case OK_OutputThinLTOBitcode:
+ MPM.addPass(ThinLTOBitcodeWriterPass(
+ Out->os(), ThinLTOLinkOut ? &ThinLTOLinkOut->os() : nullptr));
+ break;
}
// Before executing passes, print the final values of the LLVM options.
@@ -113,7 +119,10 @@ bool llvm::runPassPipeline(StringRef Arg0, Module &M,
MPM.run(M, MAM);
// Declare success.
- if (OK != OK_NoOutput)
+ if (OK != OK_NoOutput) {
Out->keep();
+ if (OK == OK_OutputThinLTOBitcode && ThinLTOLinkOut)
+ ThinLTOLinkOut->keep();
+ }
return true;
}
diff --git a/contrib/llvm/tools/opt/NewPMDriver.h b/contrib/llvm/tools/opt/NewPMDriver.h
index 04022e7ec562..8012e0a025c9 100644
--- a/contrib/llvm/tools/opt/NewPMDriver.h
+++ b/contrib/llvm/tools/opt/NewPMDriver.h
@@ -32,7 +32,8 @@ namespace opt_tool {
enum OutputKind {
OK_NoOutput,
OK_OutputAssembly,
- OK_OutputBitcode
+ OK_OutputBitcode,
+ OK_OutputThinLTOBitcode,
};
enum VerifierKind {
VK_NoVerifier,
@@ -47,8 +48,11 @@ enum VerifierKind {
/// inclusion of the new pass manager headers and the old headers into the same
/// file. It's interface is consequentially somewhat ad-hoc, but will go away
/// when the transition finishes.
-bool runPassPipeline(StringRef Arg0, Module &M,
- TargetMachine *TM, tool_output_file *Out,
+///
+/// ThinLTOLinkOut is only used when OK is OK_OutputThinLTOBitcode, and can be
+/// nullptr.
+bool runPassPipeline(StringRef Arg0, Module &M, TargetMachine *TM,
+ tool_output_file *Out, tool_output_file *ThinLinkOut,
StringRef PassPipeline, opt_tool::OutputKind OK,
opt_tool::VerifierKind VK,
bool ShouldPreserveAssemblyUseListOrder,
diff --git a/contrib/llvm/tools/opt/opt.cpp b/contrib/llvm/tools/opt/opt.cpp
index bef197d603ca..9d489ab5a2d2 100644
--- a/contrib/llvm/tools/opt/opt.cpp
+++ b/contrib/llvm/tools/opt/opt.cpp
@@ -518,7 +518,9 @@ int main(int argc, char **argv) {
if (PassPipeline.getNumOccurrences() > 0) {
OutputKind OK = OK_NoOutput;
if (!NoOutput)
- OK = OutputAssembly ? OK_OutputAssembly : OK_OutputBitcode;
+ OK = OutputAssembly
+ ? OK_OutputAssembly
+ : (OutputThinLTOBC ? OK_OutputThinLTOBitcode : OK_OutputBitcode);
VerifierKind VK = VK_VerifyInAndOut;
if (NoVerify)
@@ -529,7 +531,7 @@ int main(int argc, char **argv) {
// The user has asked to use the new pass manager and provided a pipeline
// string. Hand off the rest of the functionality to the new code for that
// layer.
- return runPassPipeline(argv[0], *M, TM.get(), Out.get(),
+ return runPassPipeline(argv[0], *M, TM.get(), Out.get(), ThinLinkOut.get(),
PassPipeline, OK, VK, PreserveAssemblyUseListOrder,
PreserveBitcodeUseListOrder, EmitSummaryIndex,
EmitModuleHash)
diff --git a/contrib/llvm/utils/TableGen/AsmMatcherEmitter.cpp b/contrib/llvm/utils/TableGen/AsmMatcherEmitter.cpp
index 264175ae9677..0980e08f67f7 100644
--- a/contrib/llvm/utils/TableGen/AsmMatcherEmitter.cpp
+++ b/contrib/llvm/utils/TableGen/AsmMatcherEmitter.cpp
@@ -354,11 +354,11 @@ public:
class AsmVariantInfo {
public:
- std::string RegisterPrefix;
- std::string TokenizingCharacters;
- std::string SeparatorCharacters;
- std::string BreakCharacters;
- std::string Name;
+ StringRef RegisterPrefix;
+ StringRef TokenizingCharacters;
+ StringRef SeparatorCharacters;
+ StringRef BreakCharacters;
+ StringRef Name;
int AsmVariantNo;
};
@@ -1438,8 +1438,8 @@ void AsmMatcherInfo::buildInfo() {
unsigned VariantCount = Target.getAsmParserVariantCount();
for (unsigned VC = 0; VC != VariantCount; ++VC) {
Record *AsmVariant = Target.getAsmParserVariant(VC);
- std::string CommentDelimiter =
- AsmVariant->getValueAsString("CommentDelimiter");
+ StringRef CommentDelimiter =
+ AsmVariant->getValueAsString("CommentDelimiter");
AsmVariantInfo Variant;
Variant.RegisterPrefix = AsmVariant->getValueAsString("RegisterPrefix");
Variant.TokenizingCharacters =
@@ -1463,7 +1463,7 @@ void AsmMatcherInfo::buildInfo() {
continue;
// Ignore instructions for different instructions
- const std::string V = CGI->TheDef->getValueAsString("AsmVariantName");
+ StringRef V = CGI->TheDef->getValueAsString("AsmVariantName");
if (!V.empty() && V != Variant.Name)
continue;
@@ -1495,7 +1495,7 @@ void AsmMatcherInfo::buildInfo() {
.startswith( MatchPrefix))
continue;
- const std::string V = Alias->TheDef->getValueAsString("AsmVariantName");
+ StringRef V = Alias->TheDef->getValueAsString("AsmVariantName");
if (!V.empty() && V != Variant.Name)
continue;
@@ -1564,8 +1564,8 @@ void AsmMatcherInfo::buildInfo() {
// If the instruction has a two-operand alias, build up the
// matchable here. We'll add them in bulk at the end to avoid
// confusing this loop.
- std::string Constraint =
- II->TheDef->getValueAsString("TwoOperandAliasConstraint");
+ StringRef Constraint =
+ II->TheDef->getValueAsString("TwoOperandAliasConstraint");
if (Constraint != "") {
// Start by making a copy of the original matchable.
auto AliasII = llvm::make_unique<MatchableInfo>(*II);
@@ -1898,10 +1898,10 @@ static void emitConvertFuncs(CodeGenTarget &Target, StringRef ClassName,
for (auto &II : Infos) {
// Check if we have a custom match function.
- std::string AsmMatchConverter =
- II->getResultInst()->TheDef->getValueAsString("AsmMatchConverter");
+ StringRef AsmMatchConverter =
+ II->getResultInst()->TheDef->getValueAsString("AsmMatchConverter");
if (!AsmMatchConverter.empty() && II->UseInstAsmMatchConverter) {
- std::string Signature = "ConvertCustom_" + AsmMatchConverter;
+ std::string Signature = ("ConvertCustom_" + AsmMatchConverter).str();
II->ConversionFnKind = Signature;
// Check if we have already generated this signature.
@@ -2443,7 +2443,7 @@ static void emitMnemonicAliasVariant(raw_ostream &OS,const AsmMatcherInfo &Info,
for (Record *R : Aliases) {
// FIXME: Allow AssemblerVariantName to be a comma separated list.
- std::string AsmVariantName = R->getValueAsString("AsmVariantName");
+ StringRef AsmVariantName = R->getValueAsString("AsmVariantName");
if (AsmVariantName != AsmParserVariantName)
continue;
AliasesFromMnemonic[R->getValueAsString("FromMnemonic")].push_back(R);
@@ -2486,14 +2486,18 @@ static void emitMnemonicAliasVariant(raw_ostream &OS,const AsmMatcherInfo &Info,
if (!MatchCode.empty())
MatchCode += "else ";
MatchCode += "if ((Features & " + FeatureMask + ") == "+FeatureMask+")\n";
- MatchCode += " Mnemonic = \"" +R->getValueAsString("ToMnemonic")+"\";\n";
+ MatchCode += " Mnemonic = \"";
+ MatchCode += R->getValueAsString("ToMnemonic");
+ MatchCode += "\";\n";
}
if (AliasWithNoPredicate != -1) {
Record *R = ToVec[AliasWithNoPredicate];
if (!MatchCode.empty())
MatchCode += "else\n ";
- MatchCode += "Mnemonic = \"" + R->getValueAsString("ToMnemonic")+"\";\n";
+ MatchCode += "Mnemonic = \"";
+ MatchCode += R->getValueAsString("ToMnemonic");
+ MatchCode += "\";\n";
}
MatchCode += "return;";
@@ -2522,7 +2526,7 @@ static bool emitMnemonicAliases(raw_ostream &OS, const AsmMatcherInfo &Info,
for (unsigned VC = 0; VC != VariantCount; ++VC) {
Record *AsmVariant = Target.getAsmParserVariant(VC);
int AsmParserVariantNo = AsmVariant->getValueAsInt("Variant");
- std::string AsmParserVariantName = AsmVariant->getValueAsString("Name");
+ StringRef AsmParserVariantName = AsmVariant->getValueAsString("Name");
OS << " case " << AsmParserVariantNo << ":\n";
emitMnemonicAliasVariant(OS, Info, Aliases, /*Indent=*/2,
AsmParserVariantName);
@@ -2710,7 +2714,7 @@ static void emitCustomOperandParsing(raw_ostream &OS, CodeGenTarget &Target,
void AsmMatcherEmitter::run(raw_ostream &OS) {
CodeGenTarget Target(Records);
Record *AsmParser = Target.getAsmParser();
- std::string ClassName = AsmParser->getValueAsString("AsmParserClassName");
+ StringRef ClassName = AsmParser->getValueAsString("AsmParserClassName");
// Compute the information on the instructions to match.
AsmMatcherInfo Info(AsmParser, Target, Records);
@@ -3173,8 +3177,7 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
<< " }\n\n";
// Call the post-processing function, if used.
- std::string InsnCleanupFn =
- AsmParser->getValueAsString("AsmParserInstCleanup");
+ StringRef InsnCleanupFn = AsmParser->getValueAsString("AsmParserInstCleanup");
if (!InsnCleanupFn.empty())
OS << " " << InsnCleanupFn << "(Inst);\n";
diff --git a/contrib/llvm/utils/TableGen/AsmWriterEmitter.cpp b/contrib/llvm/utils/TableGen/AsmWriterEmitter.cpp
index 40b7857ab994..30d21984c4d3 100644
--- a/contrib/llvm/utils/TableGen/AsmWriterEmitter.cpp
+++ b/contrib/llvm/utils/TableGen/AsmWriterEmitter.cpp
@@ -272,7 +272,7 @@ static void UnescapeString(std::string &Str) {
/// clearing the Instructions vector.
void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) {
Record *AsmWriter = Target.getAsmWriter();
- std::string ClassName = AsmWriter->getValueAsString("AsmWriterClassName");
+ StringRef ClassName = AsmWriter->getValueAsString("AsmWriterClassName");
bool PassSubtarget = AsmWriter->getValueAsInt("PassSubtarget");
O <<
@@ -523,7 +523,7 @@ emitRegisterNameString(raw_ostream &O, StringRef AltName,
// If the register has an alternate name for this index, use it.
// Otherwise, leave it empty as an error flag.
if (Idx < e) {
- std::vector<std::string> AltNames =
+ std::vector<StringRef> AltNames =
Reg.TheDef->getValueAsListOfStrings("AltNames");
if (AltNames.size() <= Idx)
PrintFatalError(Reg.TheDef->getLoc(),
@@ -553,12 +553,11 @@ emitRegisterNameString(raw_ostream &O, StringRef AltName,
void AsmWriterEmitter::EmitGetRegisterName(raw_ostream &O) {
Record *AsmWriter = Target.getAsmWriter();
- std::string ClassName = AsmWriter->getValueAsString("AsmWriterClassName");
+ StringRef ClassName = AsmWriter->getValueAsString("AsmWriterClassName");
const auto &Registers = Target.getRegBank().getRegisters();
const std::vector<Record*> &AltNameIndices = Target.getRegAltNameIndices();
bool hasAltNames = AltNameIndices.size() > 1;
- std::string Namespace =
- Registers.front().TheDef->getValueAsString("Namespace");
+ StringRef Namespace = Registers.front().TheDef->getValueAsString("Namespace");
O <<
"\n\n/// getRegisterName - This method is automatically generated by tblgen\n"
@@ -583,14 +582,16 @@ void AsmWriterEmitter::EmitGetRegisterName(raw_ostream &O) {
O << " switch(AltIdx) {\n"
<< " default: llvm_unreachable(\"Invalid register alt name index!\");\n";
for (const Record *R : AltNameIndices) {
- const std::string &AltName = R->getName();
- std::string Prefix = !Namespace.empty() ? Namespace + "::" : "";
- O << " case " << Prefix << AltName << ":\n"
- << " assert(*(AsmStrs" << AltName << "+RegAsmOffset"
- << AltName << "[RegNo-1]) &&\n"
+ StringRef AltName = R->getName();
+ O << " case ";
+ if (!Namespace.empty())
+ O << Namespace << "::";
+ O << AltName << ":\n"
+ << " assert(*(AsmStrs" << AltName << "+RegAsmOffset" << AltName
+ << "[RegNo-1]) &&\n"
<< " \"Invalid alt name index for register!\");\n"
- << " return AsmStrs" << AltName << "+RegAsmOffset"
- << AltName << "[RegNo-1];\n";
+ << " return AsmStrs" << AltName << "+RegAsmOffset" << AltName
+ << "[RegNo-1];\n";
}
O << " }\n";
} else {
@@ -762,7 +763,7 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
//////////////////////////////
// Emit the method that prints the alias instruction.
- std::string ClassName = AsmWriter->getValueAsString("AsmWriterClassName");
+ StringRef ClassName = AsmWriter->getValueAsString("AsmWriterClassName");
unsigned Variant = AsmWriter->getValueAsInt("Variant");
bool PassSubtarget = AsmWriter->getValueAsInt("PassSubtarget");
@@ -807,7 +808,7 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
IAPrinter IAP(CGA.Result->getAsString(), CGA.AsmString);
- std::string Namespace = Target.getName();
+ StringRef Namespace = Target.getName();
std::vector<Record *> ReqFeatures;
if (PassSubtarget) {
// We only consider ReqFeatures predicates if PassSubtarget
@@ -845,7 +846,7 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
// code to use.
if (Rec->isSubClassOf("RegisterOperand") ||
Rec->isSubClassOf("Operand")) {
- std::string PrintMethod = Rec->getValueAsString("PrintMethod");
+ StringRef PrintMethod = Rec->getValueAsString("PrintMethod");
if (PrintMethod != "" && PrintMethod != "printOperand") {
PrintMethodIdx =
llvm::find(PrintMethods, PrintMethod) - PrintMethods.begin();
@@ -886,8 +887,9 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
} else
break; // No conditions on this operand at all
}
- Cond = Target.getName().str() + ClassName + "ValidateMCOperand(" +
- Op + ", STI, " + utostr(Entry) + ")";
+ Cond = (Target.getName() + ClassName + "ValidateMCOperand(" + Op +
+ ", STI, " + utostr(Entry) + ")")
+ .str();
}
// for all subcases of ResultOperand::K_Record:
IAP.addCond(Cond);
@@ -923,7 +925,7 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
for (auto I = ReqFeatures.cbegin(); I != ReqFeatures.cend(); I++) {
Record *R = *I;
- std::string AsmCondString = R->getValueAsString("AssemblerCondString");
+ StringRef AsmCondString = R->getValueAsString("AssemblerCondString");
// AsmCondString has syntax [!]F(,[!]F)*
SmallVector<StringRef, 4> Ops;
@@ -933,10 +935,12 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
for (auto &Op : Ops) {
assert(!Op.empty() && "Empty operator");
if (Op[0] == '!')
- Cond = "!STI.getFeatureBits()[" + Namespace + "::" +
- Op.substr(1).str() + "]";
+ Cond = ("!STI.getFeatureBits()[" + Namespace + "::" + Op.substr(1) +
+ "]")
+ .str();
else
- Cond = "STI.getFeatureBits()[" + Namespace + "::" + Op.str() + "]";
+ Cond =
+ ("STI.getFeatureBits()[" + Namespace + "::" + Op + "]").str();
IAP.addCond(Cond);
}
}
diff --git a/contrib/llvm/utils/TableGen/Attributes.cpp b/contrib/llvm/utils/TableGen/Attributes.cpp
index 927f6e0e5b44..d64d30e18c3e 100644
--- a/contrib/llvm/utils/TableGen/Attributes.cpp
+++ b/contrib/llvm/utils/TableGen/Attributes.cpp
@@ -115,7 +115,7 @@ void Attributes::emitFnAttrCompatCheck(raw_ostream &OS, bool IsStringAttr) {
Records.getAllDerivedDefinitions("CompatRule");
for (auto *Rule : CompatRules) {
- std::string FuncName = Rule->getValueAsString("CompatFunc");
+ StringRef FuncName = Rule->getValueAsString("CompatFunc");
OS << " Ret &= " << FuncName << "(Caller, Callee);\n";
}
@@ -129,7 +129,7 @@ void Attributes::emitFnAttrCompatCheck(raw_ostream &OS, bool IsStringAttr) {
<< " const Function &Callee) {\n";
for (auto *Rule : MergeRules) {
- std::string FuncName = Rule->getValueAsString("MergeFunc");
+ StringRef FuncName = Rule->getValueAsString("MergeFunc");
OS << " " << FuncName << "(Caller, Callee);\n";
}
diff --git a/contrib/llvm/utils/TableGen/CodeEmitterGen.cpp b/contrib/llvm/utils/TableGen/CodeEmitterGen.cpp
index 565235d82143..b80dd5daefe0 100644
--- a/contrib/llvm/utils/TableGen/CodeEmitterGen.cpp
+++ b/contrib/llvm/utils/TableGen/CodeEmitterGen.cpp
@@ -218,10 +218,12 @@ std::string CodeEmitterGen::getInstructionCase(Record *R,
AddCodeToMergeInOperand(R, BI, Vals[i].getName(), NumberedOp,
NamedOpIndices, Case, Target);
}
-
- std::string PostEmitter = R->getValueAsString("PostEncoderMethod");
+
+ StringRef PostEmitter = R->getValueAsString("PostEncoderMethod");
if (!PostEmitter.empty()) {
- Case += " Value = " + PostEmitter + "(MI, Value";
+ Case += " Value = ";
+ Case += PostEmitter;
+ Case += "(MI, Value";
Case += ", STI";
Case += ");\n";
}
@@ -278,11 +280,11 @@ void CodeEmitterGen::run(raw_ostream &o) {
if (R->getValueAsString("Namespace") == "TargetOpcode" ||
R->getValueAsBit("isPseudo"))
continue;
- const std::string &InstName = R->getValueAsString("Namespace") + "::"
- + R->getName().str();
+ std::string InstName =
+ (R->getValueAsString("Namespace") + "::" + R->getName()).str();
std::string Case = getInstructionCase(R, Target);
- CaseMap[Case].push_back(InstName);
+ CaseMap[Case].push_back(std::move(InstName));
}
// Emit initial function code
diff --git a/contrib/llvm/utils/TableGen/CodeGenDAGPatterns.cpp b/contrib/llvm/utils/TableGen/CodeGenDAGPatterns.cpp
index ef2cb4208eae..231a6ad5706b 100644
--- a/contrib/llvm/utils/TableGen/CodeGenDAGPatterns.cpp
+++ b/contrib/llvm/utils/TableGen/CodeGenDAGPatterns.cpp
@@ -893,7 +893,9 @@ std::string PatternToMatch::getPredicateCheck() const {
for (Record *Pred : PredicateRecs) {
if (!PredicateCheck.empty())
PredicateCheck += " && ";
- PredicateCheck += "(" + Pred->getValueAsString("CondString") + ")";
+ PredicateCheck += "(";
+ PredicateCheck += Pred->getValueAsString("CondString");
+ PredicateCheck += ")";
}
return PredicateCheck.str();
@@ -2450,7 +2452,7 @@ void CodeGenDAGPatterns::ParseNodeTransforms() {
while (!Xforms.empty()) {
Record *XFormNode = Xforms.back();
Record *SDNode = XFormNode->getValueAsDef("Opcode");
- std::string Code = XFormNode->getValueAsString("XFormFunction");
+ StringRef Code = XFormNode->getValueAsString("XFormFunction");
SDNodeXForms.insert(std::make_pair(XFormNode, NodeXForm(SDNode, Code)));
Xforms.pop_back();
diff --git a/contrib/llvm/utils/TableGen/CodeGenDAGPatterns.h b/contrib/llvm/utils/TableGen/CodeGenDAGPatterns.h
index 189d6e382ee7..5c56fb644e7f 100644
--- a/contrib/llvm/utils/TableGen/CodeGenDAGPatterns.h
+++ b/contrib/llvm/utils/TableGen/CodeGenDAGPatterns.h
@@ -223,8 +223,8 @@ struct SDTypeConstraint {
/// processing.
class SDNodeInfo {
Record *Def;
- std::string EnumName;
- std::string SDClassName;
+ StringRef EnumName;
+ StringRef SDClassName;
unsigned Properties;
unsigned NumResults;
int NumOperands;
@@ -238,8 +238,8 @@ public:
/// variadic.
int getNumOperands() const { return NumOperands; }
Record *getRecord() const { return Def; }
- const std::string &getEnumName() const { return EnumName; }
- const std::string &getSDClassName() const { return SDClassName; }
+ StringRef getEnumName() const { return EnumName; }
+ StringRef getSDClassName() const { return SDClassName; }
const std::vector<SDTypeConstraint> &getTypeConstraints() const {
return TypeConstraints;
diff --git a/contrib/llvm/utils/TableGen/CodeGenRegisters.cpp b/contrib/llvm/utils/TableGen/CodeGenRegisters.cpp
index 627614d991d5..3907336221a4 100644
--- a/contrib/llvm/utils/TableGen/CodeGenRegisters.cpp
+++ b/contrib/llvm/utils/TableGen/CodeGenRegisters.cpp
@@ -679,11 +679,6 @@ CodeGenRegisterClass::CodeGenRegisterClass(CodeGenRegBank &RegBank, Record *R)
Name(R->getName()),
TopoSigs(RegBank.getNumTopoSigs()),
EnumValue(-1) {
- // Rename anonymous register classes.
- if (R->getName().size() > 9 && R->getName()[9] == '.') {
- static unsigned AnonCounter = 0;
- R->setName("AnonRegClass_" + utostr(AnonCounter++));
- }
std::vector<Record*> TypeList = R->getValueAsListOfDefs("RegTypes");
for (unsigned i = 0, e = TypeList.size(); i != e; ++i) {
@@ -867,7 +862,7 @@ std::string CodeGenRegisterClass::getQualifiedName() const {
if (Namespace.empty())
return getName();
else
- return Namespace + "::" + getName();
+ return (Namespace + "::" + getName()).str();
}
// Compute sub-classes of all register classes.
diff --git a/contrib/llvm/utils/TableGen/CodeGenRegisters.h b/contrib/llvm/utils/TableGen/CodeGenRegisters.h
index 9366838c77cd..1fcba8a135d1 100644
--- a/contrib/llvm/utils/TableGen/CodeGenRegisters.h
+++ b/contrib/llvm/utils/TableGen/CodeGenRegisters.h
@@ -308,13 +308,13 @@ namespace llvm {
public:
unsigned EnumValue;
- std::string Namespace;
+ StringRef Namespace;
SmallVector<MVT::SimpleValueType, 4> VTs;
unsigned SpillSize;
unsigned SpillAlignment;
int CopyCost;
bool Allocatable;
- std::string AltOrderSelect;
+ StringRef AltOrderSelect;
uint8_t AllocationPriority;
/// Contains the combination of the lane masks of all subregisters.
LaneBitmask LaneMask;
diff --git a/contrib/llvm/utils/TableGen/CodeGenSchedule.cpp b/contrib/llvm/utils/TableGen/CodeGenSchedule.cpp
index cae1cf4b861e..20f6047052ff 100644
--- a/contrib/llvm/utils/TableGen/CodeGenSchedule.cpp
+++ b/contrib/llvm/utils/TableGen/CodeGenSchedule.cpp
@@ -542,7 +542,7 @@ void CodeGenSchedModels::collectSchedClasses() {
return;
for (const CodeGenInstruction *Inst : Target.getInstructionsByEnumValue()) {
- std::string InstName = Inst->TheDef->getName();
+ StringRef InstName = Inst->TheDef->getName();
unsigned SCIdx = InstrClassMap.lookup(Inst->TheDef);
if (!SCIdx) {
if (!Inst->hasNoSchedulingInfo)
diff --git a/contrib/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp b/contrib/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp
index e1aaeccb08d0..75fd73082b9a 100644
--- a/contrib/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp
+++ b/contrib/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp
@@ -1145,16 +1145,15 @@ bool FilterChooser::emitPredicateMatch(raw_ostream &o, unsigned &Indentation,
if (!Pred->getValue("AssemblerMatcherPredicate"))
continue;
- std::string P = Pred->getValueAsString("AssemblerCondString");
+ StringRef P = Pred->getValueAsString("AssemblerCondString");
- if (!P.length())
+ if (P.empty())
continue;
if (!IsFirstEmission)
o << " && ";
- StringRef SR(P);
- std::pair<StringRef, StringRef> pairs = SR.split(',');
+ std::pair<StringRef, StringRef> pairs = P.split(',');
while (!pairs.second.empty()) {
emitSinglePredicateMatch(o, pairs.first, Emitter->PredicateNamespace);
o << " && ";
@@ -1174,9 +1173,9 @@ bool FilterChooser::doesOpcodeNeedPredicate(unsigned Opc) const {
if (!Pred->getValue("AssemblerMatcherPredicate"))
continue;
- std::string P = Pred->getValueAsString("AssemblerCondString");
+ StringRef P = Pred->getValueAsString("AssemblerCondString");
- if (!P.length())
+ if (P.empty())
continue;
return true;
@@ -1744,7 +1743,7 @@ static bool populateInstruction(CodeGenTarget &Target,
// If the instruction has specified a custom decoding hook, use that instead
// of trying to auto-generate the decoder.
- std::string InstDecoder = Def.getValueAsString("DecoderMethod");
+ StringRef InstDecoder = Def.getValueAsString("DecoderMethod");
if (InstDecoder != "") {
bool HasCompleteInstDecoder = Def.getValueAsBit("hasCompleteDecoder");
InsnOperands.push_back(OperandInfo(InstDecoder, HasCompleteInstDecoder));
@@ -2261,7 +2260,7 @@ void FixedLenDecoderEmitter::run(raw_ostream &o) {
Def->getValueAsBit("isCodeGenOnly"))
continue;
- std::string DecoderNamespace = Def->getValueAsString("DecoderNamespace");
+ StringRef DecoderNamespace = Def->getValueAsString("DecoderNamespace");
if (Size) {
if (populateInstruction(Target, *Inst, i, Operands)) {
diff --git a/contrib/llvm/utils/TableGen/GlobalISelEmitter.cpp b/contrib/llvm/utils/TableGen/GlobalISelEmitter.cpp
index e0303b7b1ab4..88ded1f25ffb 100644
--- a/contrib/llvm/utils/TableGen/GlobalISelEmitter.cpp
+++ b/contrib/llvm/utils/TableGen/GlobalISelEmitter.cpp
@@ -118,7 +118,7 @@ static std::string explainPredicates(const TreePatternNode *N) {
std::string explainOperator(Record *Operator) {
if (Operator->isSubClassOf("SDNode"))
- return " (" + Operator->getValueAsString("Opcode") + ")";
+ return (" (" + Operator->getValueAsString("Opcode") + ")").str();
if (Operator->isSubClassOf("Intrinsic"))
return (" (Operator is an Intrinsic, " + Operator->getName() + ")").str();
diff --git a/contrib/llvm/utils/TableGen/OptParserEmitter.cpp b/contrib/llvm/utils/TableGen/OptParserEmitter.cpp
index c1b5e6510325..04e6537f3d15 100644
--- a/contrib/llvm/utils/TableGen/OptParserEmitter.cpp
+++ b/contrib/llvm/utils/TableGen/OptParserEmitter.cpp
@@ -21,6 +21,8 @@ using namespace llvm;
// Ordering on Info. The logic should match with the consumer-side function in
// llvm/Option/OptTable.h.
+// FIXME: Mmake this take StringRefs instead of null terminated strings to
+// simplify callers.
static int StrCmpOptionName(const char *A, const char *B) {
const char *X = A, *Y = B;
char a = tolower(*A), b = tolower(*B);
@@ -53,22 +55,22 @@ static int CompareOptionRecords(Record *const *Av, Record *const *Bv) {
// Compare options by name, unless they are sentinels.
if (!ASent)
- if (int Cmp = StrCmpOptionName(A->getValueAsString("Name").c_str(),
- B->getValueAsString("Name").c_str()))
+ if (int Cmp = StrCmpOptionName(A->getValueAsString("Name").str().c_str(),
+ B->getValueAsString("Name").str().c_str()))
return Cmp;
if (!ASent) {
- std::vector<std::string> APrefixes = A->getValueAsListOfStrings("Prefixes");
- std::vector<std::string> BPrefixes = B->getValueAsListOfStrings("Prefixes");
-
- for (std::vector<std::string>::const_iterator APre = APrefixes.begin(),
- AEPre = APrefixes.end(),
- BPre = BPrefixes.begin(),
- BEPre = BPrefixes.end();
- APre != AEPre &&
- BPre != BEPre;
- ++APre, ++BPre) {
- if (int Cmp = StrCmpOptionName(APre->c_str(), BPre->c_str()))
+ std::vector<StringRef> APrefixes = A->getValueAsListOfStrings("Prefixes");
+ std::vector<StringRef> BPrefixes = B->getValueAsListOfStrings("Prefixes");
+
+ for (std::vector<StringRef>::const_iterator APre = APrefixes.begin(),
+ AEPre = APrefixes.end(),
+ BPre = BPrefixes.begin(),
+ BEPre = BPrefixes.end();
+ APre != AEPre &&
+ BPre != BEPre;
+ ++APre, ++BPre) {
+ if (int Cmp = StrCmpOptionName(APre->str().c_str(), BPre->str().c_str()))
return Cmp;
}
}
@@ -122,7 +124,7 @@ void EmitOptParser(RecordKeeper &Records, raw_ostream &OS) {
unsigned CurPrefix = 0;
for (unsigned i = 0, e = Opts.size(); i != e; ++i) {
const Record &R = *Opts[i];
- std::vector<std::string> prf = R.getValueAsListOfStrings("Prefixes");
+ std::vector<StringRef> prf = R.getValueAsListOfStrings("Prefixes");
PrefixKeyT prfkey(prf.begin(), prf.end());
unsigned NewPrefix = CurPrefix + 1;
if (Prefixes.insert(std::make_pair(prfkey, (Twine("prefix_") +
@@ -207,7 +209,7 @@ void EmitOptParser(RecordKeeper &Records, raw_ostream &OS) {
OS << "OPTION(";
// The option prefix;
- std::vector<std::string> prf = R.getValueAsListOfStrings("Prefixes");
+ std::vector<StringRef> prf = R.getValueAsListOfStrings("Prefixes");
OS << Prefixes[PrefixKeyT(prf.begin(), prf.end())] << ", ";
// The option string.
@@ -240,7 +242,7 @@ void EmitOptParser(RecordKeeper &Records, raw_ostream &OS) {
// would become "foo\0bar\0". Note that the compiler adds an implicit
// terminating \0 at the end.
OS << ", ";
- std::vector<std::string> AliasArgs = R.getValueAsListOfStrings("AliasArgs");
+ std::vector<StringRef> AliasArgs = R.getValueAsListOfStrings("AliasArgs");
if (AliasArgs.size() == 0) {
OS << "nullptr";
} else {
diff --git a/contrib/llvm/utils/TableGen/RegisterBankEmitter.cpp b/contrib/llvm/utils/TableGen/RegisterBankEmitter.cpp
index bf066412b286..3f11eff1d371 100644
--- a/contrib/llvm/utils/TableGen/RegisterBankEmitter.cpp
+++ b/contrib/llvm/utils/TableGen/RegisterBankEmitter.cpp
@@ -44,7 +44,7 @@ public:
: TheDef(TheDef), RCs(), RCWithLargestRegsSize(nullptr) {}
/// Get the human-readable name for the bank.
- std::string getName() const { return TheDef.getValueAsString("Name"); }
+ StringRef getName() const { return TheDef.getValueAsString("Name"); }
/// Get the name of the enumerator in the ID enumeration.
std::string getEnumeratorName() const { return (TheDef.getName() + "ID").str(); }
diff --git a/contrib/llvm/utils/TableGen/RegisterInfoEmitter.cpp b/contrib/llvm/utils/TableGen/RegisterInfoEmitter.cpp
index 5b56578a64b3..12cfb93a0c4f 100644
--- a/contrib/llvm/utils/TableGen/RegisterInfoEmitter.cpp
+++ b/contrib/llvm/utils/TableGen/RegisterInfoEmitter.cpp
@@ -93,8 +93,7 @@ void RegisterInfoEmitter::runEnums(raw_ostream &OS,
// Register enums are stored as uint16_t in the tables. Make sure we'll fit.
assert(Registers.size() <= 0xffff && "Too many regs to fit in tables");
- std::string Namespace =
- Registers.front().TheDef->getValueAsString("Namespace");
+ StringRef Namespace = Registers.front().TheDef->getValueAsString("Namespace");
emitSourceFileHeader("Target Register Enum Values", OS);
@@ -354,7 +353,7 @@ void RegisterInfoEmitter::EmitRegMappingTables(
for (unsigned i = I->second.size(), e = maxLength; i != e; ++i)
I->second.push_back(-1);
- std::string Namespace = Regs.front().TheDef->getValueAsString("Namespace");
+ StringRef Namespace = Regs.front().TheDef->getValueAsString("Namespace");
OS << "// " << Namespace << " Dwarf<->LLVM register mappings.\n";
@@ -464,7 +463,7 @@ void RegisterInfoEmitter::EmitRegMapping(
if (!maxLength)
return;
- std::string Namespace = Regs.front().TheDef->getValueAsString("Namespace");
+ StringRef Namespace = Regs.front().TheDef->getValueAsString("Namespace");
// Emit reverse information about the dwarf register numbers.
for (unsigned j = 0; j < 2; ++j) {
diff --git a/contrib/llvm/utils/TableGen/SearchableTableEmitter.cpp b/contrib/llvm/utils/TableGen/SearchableTableEmitter.cpp
index 80f0b0d4aaf4..efd4e83eca90 100644
--- a/contrib/llvm/utils/TableGen/SearchableTableEmitter.cpp
+++ b/contrib/llvm/utils/TableGen/SearchableTableEmitter.cpp
@@ -112,8 +112,8 @@ private:
void SearchableTableEmitter::emitMappingEnum(std::vector<Record *> &Items,
Record *InstanceClass,
raw_ostream &OS) {
- std::string EnumNameField = InstanceClass->getValueAsString("EnumNameField");
- std::string EnumValueField;
+ StringRef EnumNameField = InstanceClass->getValueAsString("EnumNameField");
+ StringRef EnumValueField;
if (!InstanceClass->isValueUnset("EnumValueField"))
EnumValueField = InstanceClass->getValueAsString("EnumValueField");
diff --git a/contrib/llvm/utils/TableGen/SubtargetEmitter.cpp b/contrib/llvm/utils/TableGen/SubtargetEmitter.cpp
index 1903f405d859..7e9f552eccc0 100644
--- a/contrib/llvm/utils/TableGen/SubtargetEmitter.cpp
+++ b/contrib/llvm/utils/TableGen/SubtargetEmitter.cpp
@@ -180,9 +180,9 @@ unsigned SubtargetEmitter::FeatureKeyValues(raw_ostream &OS) {
// Next feature
Record *Feature = FeatureList[i];
- const std::string &Name = Feature->getName();
- const std::string &CommandLineName = Feature->getValueAsString("Name");
- const std::string &Desc = Feature->getValueAsString("Desc");
+ StringRef Name = Feature->getName();
+ StringRef CommandLineName = Feature->getValueAsString("Name");
+ StringRef Desc = Feature->getValueAsString("Desc");
if (CommandLineName.empty()) continue;
@@ -237,7 +237,7 @@ unsigned SubtargetEmitter::CPUKeyValues(raw_ostream &OS) {
// Next processor
Record *Processor = ProcessorList[i];
- const std::string &Name = Processor->getValueAsString("Name");
+ StringRef Name = Processor->getValueAsString("Name");
const std::vector<Record*> &FeatureList =
Processor->getValueAsListOfDefs("Features");
@@ -1212,7 +1212,7 @@ void SubtargetEmitter::EmitProcessorLookup(raw_ostream &OS) {
// Next processor
Record *Processor = ProcessorList[i];
- const std::string &Name = Processor->getValueAsString("Name");
+ StringRef Name = Processor->getValueAsString("Name");
const std::string &ProcModelName =
SchedModels.getModelForProc(Processor).ModelName;
@@ -1360,9 +1360,9 @@ void SubtargetEmitter::ParseFeaturesFunction(raw_ostream &OS,
for (Record *R : Features) {
// Next record
- const std::string &Instance = R->getName();
- const std::string &Value = R->getValueAsString("Value");
- const std::string &Attribute = R->getValueAsString("Attribute");
+ StringRef Instance = R->getName();
+ StringRef Value = R->getValueAsString("Value");
+ StringRef Attribute = R->getValueAsString("Attribute");
if (Value=="true" || Value=="false")
OS << " if (Bits[" << Target << "::"
diff --git a/contrib/llvm/utils/TableGen/X86FoldTablesEmitter.cpp b/contrib/llvm/utils/TableGen/X86FoldTablesEmitter.cpp
index 99429c5f96a2..b89cee2ce4bb 100644
--- a/contrib/llvm/utils/TableGen/X86FoldTablesEmitter.cpp
+++ b/contrib/llvm/utils/TableGen/X86FoldTablesEmitter.cpp
@@ -292,7 +292,7 @@ getMemOperandSize(const Record *MemRec, const bool IntrinsicSensitive = false) {
(MemRec->getName() == "sdmem" || MemRec->getName() == "ssmem"))
return 128;
- std::string Name =
+ StringRef Name =
MemRec->getValueAsDef("ParserMatchClass")->getValueAsString("Name");
if (Name == "Mem8")
return 8;
@@ -368,7 +368,7 @@ static inline const CodeGenInstruction *
getAltRegInst(const CodeGenInstruction *I, const RecordKeeper &Records,
const CodeGenTarget &Target) {
- std::string AltRegInstStr = I->TheDef->getValueAsString("FoldGenRegForm");
+ StringRef AltRegInstStr = I->TheDef->getValueAsString("FoldGenRegForm");
Record *AltRegInstRec = Records.getDef(AltRegInstStr);
assert(AltRegInstRec &&
"Alternative register form instruction def not found");