aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-04-26 19:45:00 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-04-26 19:45:00 +0000
commit12f3ca4cdb95b193af905a00e722a4dcb40b3de3 (patch)
treeae1a7fcfc24a8d4b23206c57121c3f361d4b7f84
parentd99dafe2e4a385dd2a6c76da6d8258deb100657b (diff)
downloadsrc-12f3ca4cdb95b193af905a00e722a4dcb40b3de3.tar.gz
src-12f3ca4cdb95b193af905a00e722a4dcb40b3de3.zip
Vendor import of llvm trunk r301441:vendor/llvm/llvm-trunk-r301441
Notes
Notes: svn path=/vendor/llvm/dist/; revision=317461 svn path=/vendor/llvm/llvm-trunk-r301441/; revision=317462; tag=vendor/llvm/llvm-trunk-r301441
-rw-r--r--cmake/modules/HandleLLVMOptions.cmake7
-rw-r--r--docs/AMDGPUUsage.rst5
-rw-r--r--docs/GettingStarted.rst2
-rw-r--r--docs/HowToAddABuilder.rst2
-rw-r--r--docs/LibFuzzer.rst13
-rw-r--r--include/llvm/ADT/APFloat.h14
-rw-r--r--include/llvm/ADT/APInt.h80
-rw-r--r--include/llvm/ADT/APSInt.h13
-rw-r--r--include/llvm/ADT/BitVector.h149
-rw-r--r--include/llvm/ADT/SmallBitVector.h25
-rw-r--r--include/llvm/ADT/StringExtras.h30
-rw-r--r--include/llvm/ADT/Triple.h3
-rw-r--r--include/llvm/Analysis/DemandedBits.h4
-rw-r--r--include/llvm/Analysis/InstructionSimplify.h85
-rw-r--r--include/llvm/Analysis/LoopInfo.h2
-rw-r--r--include/llvm/Analysis/LoopInfoImpl.h6
-rw-r--r--include/llvm/Analysis/RegionInfo.h22
-rw-r--r--include/llvm/Analysis/ScalarEvolution.h41
-rw-r--r--include/llvm/Analysis/ValueTracking.h3
-rw-r--r--include/llvm/CodeGen/DIE.h13
-rw-r--r--include/llvm/CodeGen/GlobalISel/InstructionSelector.h34
-rw-r--r--include/llvm/CodeGen/MachineOperand.h6
-rw-r--r--include/llvm/CodeGen/SelectionDAG.h11
-rw-r--r--include/llvm/DebugInfo/CodeView/CodeView.h2
-rw-r--r--include/llvm/DebugInfo/CodeView/ModuleSubstreamVisitor.h2
-rw-r--r--include/llvm/DebugInfo/CodeView/TypeDumperBase.h0
-rw-r--r--include/llvm/DebugInfo/DWARF/DWARFCompileUnit.h6
-rw-r--r--include/llvm/DebugInfo/DWARF/DWARFContext.h17
-rw-r--r--include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h4
-rw-r--r--include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h6
-rw-r--r--include/llvm/DebugInfo/DWARF/DWARFUnit.h18
-rw-r--r--include/llvm/DebugInfo/PDB/DIA/DIARawSymbol.h3
-rw-r--r--include/llvm/DebugInfo/PDB/IPDBRawSymbol.h2
-rw-r--r--include/llvm/DebugInfo/PDB/Native/ModStream.h2
-rw-r--r--include/llvm/DebugInfo/PDB/Native/NativeRawSymbol.h3
-rw-r--r--include/llvm/DebugInfo/PDB/UDTLayout.h143
-rw-r--r--include/llvm/ExecutionEngine/Orc/RPCSerialization.h65
-rw-r--r--include/llvm/IR/Attributes.h2
-rw-r--r--include/llvm/IR/ConstantRange.h2
-rw-r--r--include/llvm/IR/Dominators.h4
-rw-r--r--include/llvm/IR/IntrinsicsAMDGPU.td2
-rw-r--r--include/llvm/IR/Module.h2
-rw-r--r--include/llvm/IR/Value.h11
-rw-r--r--include/llvm/MC/MCTargetOptions.h1
-rw-r--r--include/llvm/Object/ELF.h68
-rw-r--r--include/llvm/Object/ELFObjectFile.h32
-rw-r--r--include/llvm/Object/ELFTypes.h166
-rw-r--r--include/llvm/Object/IRSymtab.h29
-rw-r--r--include/llvm/Object/MachO.h122
-rw-r--r--include/llvm/Object/ModuleSummaryIndexObjectFile.h25
-rw-r--r--include/llvm/Object/ModuleSymbolTable.h16
-rw-r--r--include/llvm/Object/RelocVisitor.h91
-rw-r--r--include/llvm/Object/StackMapParser.h43
-rw-r--r--include/llvm/Object/Wasm.h13
-rw-r--r--include/llvm/ObjectYAML/WasmYAML.h2
-rw-r--r--include/llvm/ProfileData/InstrProf.h8
-rw-r--r--include/llvm/Support/BranchProbability.h12
-rw-r--r--include/llvm/Support/FileSystem.h4
-rw-r--r--include/llvm/Support/GenericDomTree.h4
-rw-r--r--include/llvm/Support/KnownBits.h43
-rw-r--r--include/llvm/Support/YAMLTraits.h4
-rw-r--r--include/llvm/Target/GlobalISel/Target.td10
-rw-r--r--include/llvm/Target/TargetInstrInfo.h2
-rw-r--r--include/llvm/Target/TargetLowering.h62
-rw-r--r--include/llvm/Target/TargetRegisterInfo.h69
-rw-r--r--include/llvm/Transforms/Instrumentation.h3
-rw-r--r--include/llvm/Transforms/Scalar/ConstantHoisting.h8
-rw-r--r--lib/Analysis/BasicAliasAnalysis.cpp12
-rw-r--r--lib/Analysis/ConstantFolding.cpp17
-rw-r--r--lib/Analysis/DemandedBits.cpp31
-rw-r--r--lib/Analysis/DomPrinter.cpp16
-rw-r--r--lib/Analysis/IVUsers.cpp12
-rw-r--r--lib/Analysis/InlineCost.cpp1
-rw-r--r--lib/Analysis/InstructionSimplify.cpp535
-rw-r--r--lib/Analysis/Lint.cpp14
-rw-r--r--lib/Analysis/MemorySSAUpdater.cpp9
-rw-r--r--lib/Analysis/ScalarEvolution.cpp265
-rw-r--r--lib/Analysis/ScalarEvolutionNormalization.cpp71
-rw-r--r--lib/Analysis/ValueTracking.cpp853
-rw-r--r--lib/Bitcode/Writer/BitcodeWriter.cpp71
-rw-r--r--lib/Bitcode/Writer/ValueEnumerator.cpp12
-rw-r--r--lib/Bitcode/Writer/ValueEnumerator.h31
-rw-r--r--lib/CodeGen/AggressiveAntiDepBreaker.cpp6
-rw-r--r--lib/CodeGen/AntiDepBreaker.h19
-rw-r--r--lib/CodeGen/AsmPrinter/AsmPrinter.cpp74
-rw-r--r--lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp3
-rw-r--r--lib/CodeGen/AsmPrinter/DIE.cpp18
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfCompileUnit.h2
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfDebug.cpp19
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfExpression.cpp12
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfUnit.cpp8
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfUnit.h7
-rw-r--r--lib/CodeGen/CriticalAntiDepBreaker.cpp6
-rw-r--r--lib/CodeGen/GlobalISel/InstructionSelect.cpp4
-rw-r--r--lib/CodeGen/GlobalISel/LegalizerHelper.cpp42
-rw-r--r--lib/CodeGen/GlobalISel/RegisterBank.cpp2
-rw-r--r--lib/CodeGen/GlobalISel/RegisterBankInfo.cpp2
-rw-r--r--lib/CodeGen/MIRPrinter.cpp3
-rw-r--r--lib/CodeGen/MachineInstr.cpp7
-rw-r--r--lib/CodeGen/MachineLICM.cpp10
-rw-r--r--lib/CodeGen/PrologEpilogInserter.cpp8
-rw-r--r--lib/CodeGen/RegAllocFast.cpp5
-rw-r--r--lib/CodeGen/RegisterScavenging.cpp4
-rw-r--r--lib/CodeGen/SelectionDAG/DAGCombiner.cpp110
-rw-r--r--lib/CodeGen/SelectionDAG/InstrEmitter.cpp3
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeDAG.cpp4
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp8
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp12
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp24
-rw-r--r--lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp12
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAG.cpp63
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp45
-rw-r--r--lib/CodeGen/SelectionDAG/TargetLowering.cpp105
-rw-r--r--lib/CodeGen/StackMaps.cpp5
-rw-r--r--lib/CodeGen/TargetInstrInfo.cpp12
-rw-r--r--lib/CodeGen/TargetLoweringBase.cpp11
-rw-r--r--lib/CodeGen/TargetRegisterInfo.cpp16
-rw-r--r--lib/CodeGen/VirtRegMap.cpp5
-rw-r--r--lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp7
-rw-r--r--lib/DebugInfo/DWARF/DWARFContext.cpp19
-rw-r--r--lib/DebugInfo/DWARF/DWARFDebugLine.cpp14
-rw-r--r--lib/DebugInfo/DWARF/DWARFDebugLoc.cpp15
-rw-r--r--lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp11
-rw-r--r--lib/DebugInfo/DWARF/DWARFFormValue.cpp22
-rw-r--r--lib/DebugInfo/DWARF/DWARFUnit.cpp16
-rw-r--r--lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp5
-rw-r--r--lib/DebugInfo/PDB/DIA/DIASession.cpp17
-rw-r--r--lib/DebugInfo/PDB/Native/ModStream.cpp4
-rw-r--r--lib/DebugInfo/PDB/Native/NativeRawSymbol.cpp3
-rw-r--r--lib/DebugInfo/PDB/UDTLayout.cpp355
-rw-r--r--lib/Fuzzer/CMakeLists.txt89
-rw-r--r--lib/Fuzzer/FuzzerDefs.h18
-rw-r--r--lib/Fuzzer/FuzzerMerge.h2
-rw-r--r--lib/IR/AsmWriter.cpp45
-rw-r--r--lib/IR/AttributeImpl.h15
-rw-r--r--lib/IR/Attributes.cpp24
-rw-r--r--lib/IR/GCOV.cpp10
-rw-r--r--lib/IR/Value.cpp19
-rw-r--r--lib/LTO/LTO.cpp3
-rw-r--r--lib/LTO/LTOBackend.cpp18
-rw-r--r--lib/MC/MCParser/AsmParser.cpp13
-rw-r--r--lib/MC/WasmObjectWriter.cpp2
-rw-r--r--lib/Object/ELF.cpp13
-rw-r--r--lib/Object/ELFObjectFile.cpp21
-rw-r--r--lib/Object/IRSymtab.cpp31
-rw-r--r--lib/Object/MachOObjectFile.cpp215
-rw-r--r--lib/Object/ModuleSummaryIndexObjectFile.cpp27
-rw-r--r--lib/Object/ModuleSymbolTable.cpp32
-rw-r--r--lib/Object/RecordStreamer.cpp5
-rw-r--r--lib/Object/RecordStreamer.h23
-rw-r--r--lib/Object/WasmObjectFile.cpp12
-rw-r--r--lib/ObjectYAML/WasmYAML.cpp5
-rw-r--r--lib/Passes/PassBuilder.cpp4
-rw-r--r--lib/Support/APFloat.cpp31
-rw-r--r--lib/Support/APInt.cpp233
-rw-r--r--lib/Support/DynamicLibrary.cpp1
-rw-r--r--lib/Support/Triple.cpp2
-rw-r--r--lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp1
-rw-r--r--lib/Target/AArch64/AArch64FrameLowering.cpp19
-rw-r--r--lib/Target/AArch64/AArch64ISelLowering.cpp305
-rw-r--r--lib/Target/AArch64/AArch64ISelLowering.h15
-rw-r--r--lib/Target/AArch64/AArch64InstrAtomics.td3
-rw-r--r--lib/Target/AArch64/AArch64InstrFormats.td4
-rw-r--r--lib/Target/AArch64/AArch64InstrInfo.cpp12
-rw-r--r--lib/Target/AArch64/AArch64InstrInfo.h2
-rw-r--r--lib/Target/AArch64/AArch64InstructionSelector.cpp41
-rw-r--r--lib/Target/AArch64/AArch64SchedFalkor.td10
-rw-r--r--lib/Target/AArch64/AArch64SchedFalkorDetails.td31
-rw-r--r--lib/Target/AArch64/AArch64SchedFalkorWriteRes.td31
-rw-r--r--lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp12
-rw-r--r--lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp7
-rw-r--r--lib/Target/AArch64/MCTargetDesc/AArch64MCCodeEmitter.cpp3
-rw-r--r--lib/Target/AMDGPU/AMDGPU.td3
-rw-r--r--lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp96
-rw-r--r--lib/Target/AMDGPU/AMDGPUISelLowering.cpp6
-rw-r--r--lib/Target/AMDGPU/AMDGPUISelLowering.h5
-rw-r--r--lib/Target/AMDGPU/AMDGPUInstrInfo.td5
-rw-r--r--lib/Target/AMDGPU/AMDGPUInstructions.td16
-rw-r--r--lib/Target/AMDGPU/AMDGPUMCInstLower.cpp6
-rw-r--r--lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp74
-rw-r--r--lib/Target/AMDGPU/BUFInstructions.td75
-rw-r--r--lib/Target/AMDGPU/GCNRegPressure.cpp4
-rw-r--r--lib/Target/AMDGPU/MCTargetDesc/AMDGPUCodeObjectMetadataStreamer.cpp24
-rw-r--r--lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCAsmInfo.cpp1
-rw-r--r--lib/Target/AMDGPU/SIFixSGPRCopies.cpp185
-rw-r--r--lib/Target/AMDGPU/SIFrameLowering.cpp120
-rw-r--r--lib/Target/AMDGPU/SIFrameLowering.h2
-rw-r--r--lib/Target/AMDGPU/SIISelLowering.cpp132
-rw-r--r--lib/Target/AMDGPU/SIInsertWaitcnts.cpp4
-rw-r--r--lib/Target/AMDGPU/SIInsertWaits.cpp10
-rw-r--r--lib/Target/AMDGPU/SIInstrInfo.cpp58
-rw-r--r--lib/Target/AMDGPU/SIInstrInfo.h4
-rw-r--r--lib/Target/AMDGPU/SIInstrInfo.td3
-rw-r--r--lib/Target/AMDGPU/SIInstructions.td40
-rw-r--r--lib/Target/AMDGPU/SIMachineFunctionInfo.cpp2
-rw-r--r--lib/Target/AMDGPU/SIMachineFunctionInfo.h24
-rw-r--r--lib/Target/AMDGPU/SIRegisterInfo.cpp62
-rw-r--r--lib/Target/AMDGPU/SOPInstructions.td36
-rw-r--r--lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp9
-rw-r--r--lib/Target/ARM/ARMBaseInstrInfo.cpp4
-rw-r--r--lib/Target/ARM/ARMBaseInstrInfo.h4
-rw-r--r--lib/Target/ARM/ARMBaseRegisterInfo.cpp3
-rw-r--r--lib/Target/ARM/ARMCallLowering.cpp3
-rw-r--r--lib/Target/ARM/ARMExpandPseudoInsts.cpp1
-rw-r--r--lib/Target/ARM/ARMFrameLowering.cpp8
-rw-r--r--lib/Target/ARM/ARMISelLowering.cpp13
-rw-r--r--lib/Target/ARM/ARMInstrInfo.cpp4
-rw-r--r--lib/Target/ARM/ARMInstrInfo.h4
-rw-r--r--lib/Target/ARM/ARMInstrInfo.td7
-rw-r--r--lib/Target/ARM/ARMInstrThumb.td3
-rw-r--r--lib/Target/ARM/ARMInstructionSelector.cpp53
-rw-r--r--lib/Target/ARM/ARMLegalizerInfo.cpp59
-rw-r--r--lib/Target/ARM/ARMLegalizerInfo.h3
-rw-r--r--lib/Target/ARM/ARMMCInstLower.cpp4
-rw-r--r--lib/Target/ARM/ARMRegisterBankInfo.cpp3
-rw-r--r--lib/Target/ARM/Thumb1InstrInfo.cpp4
-rw-r--r--lib/Target/ARM/Thumb1InstrInfo.h4
-rw-r--r--lib/Target/ARM/Thumb2InstrInfo.cpp4
-rw-r--r--lib/Target/ARM/Thumb2InstrInfo.h4
-rw-r--r--lib/Target/AVR/AVRAsmPrinter.cpp3
-rw-r--r--lib/Target/AVR/AVRExpandPseudoInsts.cpp130
-rw-r--r--lib/Target/AVR/AVRFrameLowering.cpp4
-rw-r--r--lib/Target/AVR/AVRInstrInfo.cpp8
-rw-r--r--lib/Target/AVR/AVRRegisterInfo.cpp5
-rw-r--r--lib/Target/Hexagon/BitTracker.cpp2
-rw-r--r--lib/Target/Hexagon/HexagonAsmPrinter.cpp6
-rw-r--r--lib/Target/Hexagon/HexagonBitSimplify.cpp30
-rw-r--r--lib/Target/Hexagon/HexagonExpandCondsets.cpp6
-rw-r--r--lib/Target/Hexagon/HexagonFrameLowering.cpp43
-rw-r--r--lib/Target/Hexagon/HexagonLoopIdiomRecognition.cpp8
-rw-r--r--lib/Target/MSP430/MSP430InstrInfo.td2
-rw-r--r--lib/Target/Mips/MipsAsmPrinter.cpp6
-rw-r--r--lib/Target/Mips/MipsCCState.cpp17
-rw-r--r--lib/Target/Mips/MipsCCState.h14
-rw-r--r--lib/Target/Mips/MipsFastISel.cpp6
-rw-r--r--lib/Target/Mips/MipsFrameLowering.cpp2
-rw-r--r--lib/Target/Mips/MipsISelLowering.cpp11
-rw-r--r--lib/Target/Mips/MipsMachineFunction.cpp25
-rw-r--r--lib/Target/Mips/MipsOptimizePICCall.cpp5
-rw-r--r--lib/Target/Mips/MipsSEFrameLowering.cpp22
-rw-r--r--lib/Target/Mips/MipsSEInstrInfo.cpp26
-rw-r--r--lib/Target/Mips/Relocation.txt125
-rw-r--r--lib/Target/NVPTX/NVPTXInstrInfo.cpp2
-rw-r--r--lib/Target/PowerPC/PPCFrameLowering.cpp17
-rw-r--r--lib/Target/PowerPC/PPCISelLowering.cpp4
-rw-r--r--lib/Target/PowerPC/PPCInstrInfo.cpp4
-rw-r--r--lib/Target/PowerPC/PPCInstrInfo.h2
-rw-r--r--lib/Target/Sparc/SparcISelLowering.cpp4
-rw-r--r--lib/Target/SystemZ/SystemZInstrInfo.cpp12
-rw-r--r--lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp3
-rw-r--r--lib/Target/X86/AsmParser/X86AsmParser.cpp2
-rw-r--r--lib/Target/X86/X86.h3
-rw-r--r--lib/Target/X86/X86.td11
-rw-r--r--lib/Target/X86/X86CallLowering.cpp28
-rw-r--r--lib/Target/X86/X86CallLowering.h5
-rw-r--r--lib/Target/X86/X86FastISel.cpp3
-rw-r--r--lib/Target/X86/X86FrameLowering.cpp28
-rw-r--r--lib/Target/X86/X86FrameLowering.h2
-rw-r--r--lib/Target/X86/X86ISelLowering.cpp24
-rw-r--r--lib/Target/X86/X86InstrArithmetic.td10
-rw-r--r--lib/Target/X86/X86InstrInfo.cpp107
-rw-r--r--lib/Target/X86/X86InstrInfo.h2
-rw-r--r--lib/Target/X86/X86InstrInfo.td1
-rw-r--r--lib/Target/X86/X86InstrSSE.td38
-rw-r--r--lib/Target/X86/X86InstructionSelector.cpp33
-rw-r--r--lib/Target/X86/X86RegisterInfo.cpp53
-rw-r--r--lib/Target/X86/X86SelectionDAGInfo.cpp62
-rw-r--r--lib/Target/X86/X86Subtarget.cpp1
-rw-r--r--lib/Target/X86/X86Subtarget.h4
-rw-r--r--lib/Target/X86/X86TargetMachine.cpp2
-rw-r--r--lib/Target/XCore/XCoreFrameLowering.cpp13
-rw-r--r--lib/Target/XCore/XCoreISelLowering.cpp4
-rw-r--r--lib/Target/XCore/XCoreMachineFunctionInfo.cpp24
-rw-r--r--lib/Transforms/IPO/PartialInlining.cpp51
-rw-r--r--lib/Transforms/IPO/PassManagerBuilder.cpp32
-rw-r--r--lib/Transforms/InstCombine/InstCombineAddSub.cpp115
-rw-r--r--lib/Transforms/InstCombine/InstCombineAndOrXor.cpp331
-rw-r--r--lib/Transforms/InstCombine/InstCombineCalls.cpp42
-rw-r--r--lib/Transforms/InstCombine/InstCombineCasts.cpp30
-rw-r--r--lib/Transforms/InstCombine/InstCombineCompares.cpp67
-rw-r--r--lib/Transforms/InstCombine/InstCombineInternal.h22
-rw-r--r--lib/Transforms/InstCombine/InstCombineSelect.cpp9
-rw-r--r--lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp431
-rw-r--r--lib/Transforms/InstCombine/InstructionCombining.cpp43
-rw-r--r--lib/Transforms/Instrumentation/AddressSanitizer.cpp32
-rw-r--r--lib/Transforms/Instrumentation/IndirectCallPromotion.cpp4
-rw-r--r--lib/Transforms/ObjCARC/PtrState.cpp6
-rw-r--r--lib/Transforms/Scalar/ConstantHoisting.cpp212
-rw-r--r--lib/Transforms/Scalar/CorrelatedValuePropagation.cpp30
-rw-r--r--lib/Transforms/Scalar/GuardWidening.cpp7
-rw-r--r--lib/Transforms/Scalar/InferAddressSpaces.cpp41
-rw-r--r--lib/Transforms/Scalar/JumpThreading.cpp30
-rw-r--r--lib/Transforms/Scalar/LoopIdiomRecognize.cpp5
-rw-r--r--lib/Transforms/Scalar/LoopRotation.cpp22
-rw-r--r--lib/Transforms/Scalar/LoopUnswitch.cpp2
-rw-r--r--lib/Transforms/Scalar/StructurizeCFG.cpp14
-rw-r--r--lib/Transforms/Utils/BypassSlowDivision.cpp9
-rw-r--r--lib/Transforms/Utils/CodeExtractor.cpp43
-rw-r--r--lib/Transforms/Utils/Local.cpp54
-rw-r--r--lib/Transforms/Utils/LoopUnroll.cpp14
-rw-r--r--lib/Transforms/Utils/LowerSwitch.cpp8
-rw-r--r--lib/Transforms/Utils/SimplifyCFG.cpp23
-rw-r--r--lib/Transforms/Utils/SimplifyInstructions.cpp18
-rw-r--r--lib/Transforms/Utils/SimplifyLibCalls.cpp38
-rw-r--r--lib/Transforms/Vectorize/LoadStoreVectorizer.cpp32
-rw-r--r--lib/Transforms/Vectorize/LoopVectorize.cpp27
-rw-r--r--test/Analysis/IVUsers/quadradic-exit-value.ll2
-rw-r--r--test/Analysis/ScalarEvolution/exponential-behavior.ll57
-rw-r--r--test/Analysis/ScalarEvolution/or-as-add.ll38
-rw-r--r--test/CMakeLists.txt1
-rw-r--r--test/CodeGen/AArch64/GlobalISel/select-pr32733.mir65
-rw-r--r--test/CodeGen/AArch64/arm64-vmul.ll16
-rw-r--r--test/CodeGen/AArch64/fence-singlethread.ll21
-rw-r--r--test/CodeGen/AArch64/optimize-imm.ll64
-rw-r--r--test/CodeGen/AArch64/swiftself-scavenger.ll82
-rw-r--r--test/CodeGen/AMDGPU/add.v2i16.ll2
-rw-r--r--test/CodeGen/AMDGPU/addrspacecast.ll9
-rw-r--r--test/CodeGen/AMDGPU/ashr.v2i16.ll2
-rw-r--r--test/CodeGen/AMDGPU/code-object-metadata-images.ll80
-rw-r--r--test/CodeGen/AMDGPU/fcanonicalize.f16.ll2
-rw-r--r--test/CodeGen/AMDGPU/fdiv.ll18
-rw-r--r--test/CodeGen/AMDGPU/fence-amdgiz.ll15
-rw-r--r--test/CodeGen/AMDGPU/fmuladd.v2f16.ll18
-rw-r--r--test/CodeGen/AMDGPU/fneg-fabs.f16.ll2
-rw-r--r--test/CodeGen/AMDGPU/immv216.ll2
-rw-r--r--test/CodeGen/AMDGPU/insert_vector_elt.v2i16.ll2
-rw-r--r--test/CodeGen/AMDGPU/llvm.amdgcn.readlane.ll17
-rw-r--r--test/CodeGen/AMDGPU/llvm.amdgcn.unreachable.ll9
-rw-r--r--test/CodeGen/AMDGPU/loop_break.ll2
-rw-r--r--test/CodeGen/AMDGPU/lshr.v2i16.ll2
-rw-r--r--test/CodeGen/AMDGPU/merge-m0.mir132
-rw-r--r--test/CodeGen/AMDGPU/mubuf-offset-private.ll136
-rw-r--r--test/CodeGen/AMDGPU/multi-divergent-exit-region.ll180
-rw-r--r--test/CodeGen/AMDGPU/nested-loop-conditions.ll23
-rw-r--r--test/CodeGen/AMDGPU/private-access-no-objects.ll16
-rw-r--r--test/CodeGen/AMDGPU/readcyclecounter.ll14
-rw-r--r--test/CodeGen/AMDGPU/ret_jump.ll2
-rw-r--r--test/CodeGen/AMDGPU/sext-in-reg.ll2
-rw-r--r--test/CodeGen/AMDGPU/shl.v2i16.ll2
-rw-r--r--test/CodeGen/AMDGPU/sminmax.v2i16.ll2
-rw-r--r--test/CodeGen/AMDGPU/spill-m0.ll22
-rw-r--r--test/CodeGen/AMDGPU/sub.v2i16.ll2
-rw-r--r--test/CodeGen/AMDGPU/trap.ll21
-rw-r--r--test/CodeGen/ARM/GlobalISel/arm-instruction-select.mir127
-rw-r--r--test/CodeGen/ARM/GlobalISel/arm-isel-divmod.ll68
-rw-r--r--test/CodeGen/ARM/GlobalISel/arm-isel.ll32
-rw-r--r--test/CodeGen/ARM/GlobalISel/arm-legalize-divmod.mir230
-rw-r--r--test/CodeGen/ARM/GlobalISel/arm-regbankselect.mir79
-rw-r--r--test/CodeGen/ARM/GlobalISel/arm-unsupported.ll80
-rw-r--r--test/CodeGen/ARM/bool-ext-inc.ll39
-rw-r--r--test/CodeGen/ARM/fence-singlethread.ll16
-rw-r--r--test/CodeGen/ARM/v6m-smul-with-overflow.ll16
-rw-r--r--test/CodeGen/ARM/vpadd.ll20
-rw-r--r--test/CodeGen/AVR/pseudo/LDDWRdPtrQ-same-src-dst.mir35
-rw-r--r--test/CodeGen/AVR/pseudo/LDWRdPtr-same-src-dst.mir29
-rw-r--r--test/CodeGen/AVR/pseudo/expand-lddw-dst-src-same.mir35
-rw-r--r--test/CodeGen/MSP430/select-use-sr.ll21
-rw-r--r--test/CodeGen/Mips/llvm-ir/mul.ll2
-rw-r--r--test/CodeGen/Mips/llvm-ir/sdiv.ll12
-rw-r--r--test/CodeGen/Mips/llvm-ir/srem.ll11
-rw-r--r--test/CodeGen/Mips/llvm-ir/udiv.ll11
-rw-r--r--test/CodeGen/Mips/llvm-ir/urem.ll6
-rw-r--r--test/CodeGen/Mips/micromips-gp-rc.ll2
-rw-r--r--test/CodeGen/Mips/mips64fpldst.ll12
-rw-r--r--test/CodeGen/Mips/tailcall/tailcall.ll4
-rw-r--r--test/CodeGen/PowerPC/empty-functions.ll6
-rw-r--r--test/CodeGen/SPARC/empty-functions.ll10
-rw-r--r--test/CodeGen/SystemZ/splitMove_undefReg_mverifier_2.ll229
-rw-r--r--test/CodeGen/Thumb/long.ll31
-rw-r--r--test/CodeGen/Thumb/optionaldef-scheduling.ll18
-rw-r--r--test/CodeGen/X86/GlobalISel/callingconv.ll133
-rw-r--r--test/CodeGen/X86/GlobalISel/irtranslator-callingconv.ll30
-rw-r--r--test/CodeGen/X86/GlobalISel/irtranslator-callingconv_64bit.ll8
-rw-r--r--test/CodeGen/X86/GlobalISel/memop.ll4
-rw-r--r--test/CodeGen/X86/asm-reg-type-mismatch.ll2
-rw-r--r--test/CodeGen/X86/atomic-non-integer.ll8
-rw-r--r--test/CodeGen/X86/avx-schedule.ll2840
-rw-r--r--test/CodeGen/X86/bitcast2.ll2
-rw-r--r--test/CodeGen/X86/bool-ext-inc.ll88
-rw-r--r--test/CodeGen/X86/clear_upper_vector_element_bits.ll8
-rw-r--r--test/CodeGen/X86/combine-srl.ll9
-rw-r--r--test/CodeGen/X86/combine-udiv.ll47
-rw-r--r--test/CodeGen/X86/combine-urem.ll93
-rw-r--r--test/CodeGen/X86/constant-hoisting-bfi.ll115
-rw-r--r--test/CodeGen/X86/dagcombine-cse.ll2
-rw-r--r--test/CodeGen/X86/dwarf-headers.ll8
-rw-r--r--test/CodeGen/X86/eh-frame-unreachable.ll11
-rw-r--r--test/CodeGen/X86/empty-function.ll22
-rw-r--r--test/CodeGen/X86/empty-functions.ll8
-rw-r--r--test/CodeGen/X86/extractelement-index.ll8
-rw-r--r--test/CodeGen/X86/fold-tied-op.ll1
-rw-r--r--test/CodeGen/X86/gather-addresses.ll4
-rw-r--r--test/CodeGen/X86/i256-add.ll49
-rw-r--r--test/CodeGen/X86/i64-to-float.ll4
-rw-r--r--test/CodeGen/X86/insertelement-duplicates.ll58
-rw-r--r--test/CodeGen/X86/isint.ll8
-rw-r--r--test/CodeGen/X86/lower-bitcast.ll16
-rw-r--r--test/CodeGen/X86/memcpy-struct-by-value.ll48
-rw-r--r--test/CodeGen/X86/merge_store.ll11
-rw-r--r--test/CodeGen/X86/mmx-bitcast.ll2
-rw-r--r--test/CodeGen/X86/mmx-cvt.ll2
-rw-r--r--test/CodeGen/X86/mod128.ll2
-rw-r--r--test/CodeGen/X86/movmsk.ll2
-rw-r--r--test/CodeGen/X86/nontemporal-2.ll4
-rw-r--r--test/CodeGen/X86/post-ra-sched-with-debug.mir322
-rw-r--r--test/CodeGen/X86/pr14657.ll325
-rw-r--r--test/CodeGen/X86/pr18344.ll2
-rw-r--r--test/CodeGen/X86/pr21792.ll2
-rw-r--r--test/CodeGen/X86/pr22970.ll47
-rw-r--r--test/CodeGen/X86/pr30511.ll2
-rw-r--r--test/CodeGen/X86/pshufb-mask-comments.ll2
-rw-r--r--test/CodeGen/X86/ret-mmx.ll2
-rw-r--r--test/CodeGen/X86/sad_variations.ll6
-rw-r--r--test/CodeGen/X86/scalar-int-to-fp.ll2
-rw-r--r--test/CodeGen/X86/setcc-combine.ll181
-rw-r--r--test/CodeGen/X86/setcc-wide-types.ll32
-rw-r--r--test/CodeGen/X86/shrink_vmul.ll4
-rw-r--r--test/CodeGen/X86/sse2-intrinsics-fast-isel-x86_64.ll4
-rw-r--r--test/CodeGen/X86/sse2-intrinsics-fast-isel.ll12
-rw-r--r--test/CodeGen/X86/sse2-schedule.ll58
-rw-r--r--test/CodeGen/X86/sse3-schedule.ll455
-rw-r--r--test/CodeGen/X86/sse41-schedule.ll1938
-rw-r--r--test/CodeGen/X86/sse42-schedule.ll477
-rw-r--r--test/CodeGen/X86/ssse3-schedule.ll754
-rw-r--r--test/CodeGen/X86/statepoint-vector.ll2
-rw-r--r--test/CodeGen/X86/tls-pic.ll38
-rw-r--r--test/CodeGen/X86/tls-pie.ll127
-rw-r--r--test/CodeGen/X86/tls.ll246
-rw-r--r--test/CodeGen/X86/vec_fneg.ll4
-rw-r--r--test/CodeGen/X86/vec_fp_to_int.ll106
-rw-r--r--test/CodeGen/X86/vec_insert-3.ll2
-rw-r--r--test/CodeGen/X86/vec_insert-5.ll2
-rw-r--r--test/CodeGen/X86/vec_insert-mmx.ll2
-rw-r--r--test/CodeGen/X86/vec_int_to_fp.ll112
-rw-r--r--test/CodeGen/X86/vec_set-8.ll2
-rw-r--r--test/CodeGen/X86/vec_set-C.ll2
-rw-r--r--test/CodeGen/X86/vec_shift7.ll2
-rw-r--r--test/CodeGen/X86/vector-compare-all_of.ll8
-rw-r--r--test/CodeGen/X86/vector-compare-any_of.ll8
-rw-r--r--test/CodeGen/X86/vector-idiv-sdiv-128.ll28
-rw-r--r--test/CodeGen/X86/vector-idiv-udiv-128.ll28
-rw-r--r--test/CodeGen/X86/vector-lzcnt-128.ll4
-rw-r--r--test/CodeGen/X86/vector-pcmp.ll27
-rw-r--r--test/CodeGen/X86/vector-sext.ll68
-rw-r--r--test/CodeGen/X86/vector-shuffle-128-v2.ll12
-rw-r--r--test/CodeGen/X86/vector-shuffle-128-v4.ll10
-rw-r--r--test/CodeGen/X86/vector-shuffle-combining-avx2.ll26
-rw-r--r--test/CodeGen/X86/vector-trunc-math.ll10
-rw-r--r--test/CodeGen/X86/vector-trunc.ll14
-rw-r--r--test/CodeGen/X86/vector-tzcnt-128.ll4
-rw-r--r--test/CodeGen/X86/vmovq.ll2
-rw-r--r--test/CodeGen/X86/vshift-1.ll2
-rw-r--r--test/CodeGen/X86/vshift-2.ll2
-rw-r--r--test/CodeGen/X86/vsplit-and.ll10
-rw-r--r--test/CodeGen/X86/widen_cast-5.ll2
-rw-r--r--test/CodeGen/X86/widen_conv-3.ll4
-rw-r--r--test/CodeGen/X86/widen_conv-4.ll4
-rw-r--r--test/DebugInfo/COFF/pieces.ll24
-rw-r--r--test/DebugInfo/Generic/empty.ll2
-rw-r--r--test/DebugInfo/PDB/pdbdump-yaml-lineinfo.test59
-rw-r--r--test/DebugInfo/PowerPC/tls-fission.ll2
-rw-r--r--test/DebugInfo/X86/cu-ranges-odr.ll2
-rw-r--r--test/DebugInfo/X86/cu-ranges.ll4
-rw-r--r--test/DebugInfo/X86/debug-loc-asan.ll4
-rw-r--r--test/DebugInfo/X86/dwarf-pubnames-split.ll2
-rw-r--r--test/DebugInfo/X86/dwarfdump-ranges-unrelocated.s70
-rw-r--r--test/DebugInfo/X86/empty.ll2
-rw-r--r--test/DebugInfo/X86/fission-cu.ll2
-rw-r--r--test/DebugInfo/X86/fission-hash.ll2
-rw-r--r--test/DebugInfo/X86/fission-inline.ll2
-rw-r--r--test/DebugInfo/X86/fission-no-inlining.ll2
-rw-r--r--test/DebugInfo/X86/fission-ranges.ll2
-rw-r--r--test/DebugInfo/X86/generate-odr-hash.ll2
-rw-r--r--test/DebugInfo/X86/op_deref.ll2
-rw-r--r--test/DebugInfo/X86/pieces-4.ll4
-rw-r--r--test/DebugInfo/X86/split-dwarf-cross-unit-reference.ll46
-rw-r--r--test/DebugInfo/X86/sret.ll2
-rw-r--r--test/DebugInfo/X86/stack-value-dwarf2.ll96
-rw-r--r--test/DebugInfo/X86/this-stack_value.ll123
-rw-r--r--test/DebugInfo/X86/tls.ll2
-rw-r--r--test/DebugInfo/X86/type_units_with_addresses.ll4
-rw-r--r--test/DebugInfo/X86/vla.ll2
-rw-r--r--test/Instrumentation/AddressSanitizer/global_metadata_array.ll68
-rw-r--r--test/LTO/Resolution/X86/Inputs/mod-asm-used.ll4
-rw-r--r--test/LTO/Resolution/X86/mod-asm-used.ll10
-rw-r--r--test/MC/AArch64/basic-a64-diagnostics.s12
-rw-r--r--test/MC/AMDGPU/gfx7_asm_all.s7
-rw-r--r--test/MC/AMDGPU/gfx8_asm_all.s1939
-rw-r--r--test/MC/AMDGPU/gfx9_asm_all.s61606
-rw-r--r--test/MC/AMDGPU/sopk-err.s15
-rw-r--r--test/MC/AMDGPU/sopk.s12
-rw-r--r--test/MC/AMDGPU/sopp-err.s18
-rw-r--r--test/MC/AMDGPU/sopp.s38
-rw-r--r--test/MC/Disassembler/AMDGPU/gfx8_dasm_all.txt123398
-rw-r--r--test/MC/Disassembler/X86/x86-64.txt8
-rw-r--r--test/MC/X86/x86-64.s16
-rw-r--r--test/ObjectYAML/wasm/code_section.yaml4
-rw-r--r--test/ObjectYAML/wasm/data_section.yaml32
-rw-r--r--test/ObjectYAML/wasm/elem_section.yaml8
-rw-r--r--test/Other/Inputs/invariant.group.barrier.ll15
-rw-r--r--test/Other/new-pm-defaults.ll1
-rw-r--r--test/Other/pass-pipelines.ll1
-rw-r--r--test/Other/pr32085.ll56
-rw-r--r--test/TableGen/GlobalISelEmitter.td61
-rw-r--r--test/Transforms/CodeExtractor/PartialInlineCallRef.ll56
-rw-r--r--test/Transforms/CodeExtractor/PartialInlineOptRemark.ll73
-rw-r--r--test/Transforms/CodeExtractor/unreachable-block.ll38
-rw-r--r--test/Transforms/ConstantHoisting/X86/ehpad.ll11
-rw-r--r--test/Transforms/GVN/invariant.group.ll12
-rw-r--r--test/Transforms/InferAddressSpaces/AMDGPU/infer-getelementptr.ll48
-rw-r--r--test/Transforms/InstCombine/add-sitofp.ll124
-rw-r--r--test/Transforms/InstCombine/amdgcn-intrinsics.ll6
-rw-r--r--test/Transforms/InstCombine/and-or-icmps.ll4
-rw-r--r--test/Transforms/InstCombine/and-or-not.ll570
-rw-r--r--test/Transforms/InstCombine/and.ll28
-rw-r--r--test/Transforms/InstCombine/apint-shift.ll7
-rw-r--r--test/Transforms/InstCombine/debuginfo-dce.ll42
-rw-r--r--test/Transforms/InstCombine/fsub.ll44
-rw-r--r--test/Transforms/InstCombine/intrinsics.ll26
-rw-r--r--test/Transforms/InstCombine/memset-1.ll9
-rw-r--r--test/Transforms/InstCombine/minmax-fold.ll6
-rw-r--r--test/Transforms/InstCombine/or-to-xor.ll55
-rw-r--r--test/Transforms/InstCombine/or.ll53
-rw-r--r--test/Transforms/InstCombine/pr17827.ll4
-rw-r--r--test/Transforms/InstCombine/shift.ll30
-rw-r--r--test/Transforms/InstCombine/xor2.ll75
-rw-r--r--test/Transforms/InstSimplify/AndOrXor.ll115
-rw-r--r--test/Transforms/InstSimplify/icmp-ranges.ll336
-rw-r--r--test/Transforms/JumpThreading/fold-not-thread.ll135
-rw-r--r--test/Transforms/LoadStoreVectorizer/AMDGPU/gep-bitcast.ll83
-rw-r--r--test/Transforms/LoopIdiom/non-integral-pointers.ll48
-rw-r--r--test/Transforms/LoopUnroll/not-rotated.ll26
-rw-r--r--test/Transforms/LoopVectorize/X86/float-induction-x86.ll63
-rw-r--r--test/Transforms/LoopVectorize/induction.ll24
-rw-r--r--test/Transforms/LoopVectorize/phi-cost.ll86
-rw-r--r--test/Transforms/LowerSwitch/phi-in-dead-block.ll40
-rw-r--r--test/Transforms/Mem2Reg/debug-alloca-phi.ll48
-rw-r--r--test/Transforms/ObjCARC/clang-arc-use-barrier.ll45
-rw-r--r--test/Transforms/ObjCARC/intrinsic-use.ll11
-rw-r--r--test/Transforms/PGOProfile/memop_size_opt.ll21
-rw-r--r--test/Transforms/SimplifyCFG/merge-cond-stores.ll33
-rw-r--r--test/Transforms/StructurizeCFG/invert-compare.ll60
-rw-r--r--test/Transforms/StructurizeCFG/one-loop-multiple-backedges.ll12
-rw-r--r--test/Transforms/StructurizeCFG/post-order-traversal-bug.ll3
-rw-r--r--test/Transforms/Util/libcalls-fast-math-inf-loop.ll60
-rw-r--r--test/tools/gold/X86/asm_undefined2.ll4
-rw-r--r--test/tools/llvm-cov/Inputs/test_-b.output12
-rw-r--r--test/tools/llvm-cov/Inputs/test_-f.output16
-rw-r--r--test/tools/llvm-cov/Inputs/test_long_file_names.output8
-rw-r--r--test/tools/llvm-cov/Inputs/test_long_paths.output8
-rw-r--r--test/tools/llvm-cov/Inputs/test_missing.output8
-rw-r--r--test/tools/llvm-cov/Inputs/test_no_gcda.output8
-rw-r--r--test/tools/llvm-cov/Inputs/test_no_options.output8
-rw-r--r--test/tools/llvm-cov/Inputs/test_no_output.output6
-rw-r--r--test/tools/llvm-cov/Inputs/test_no_preserve_paths.output8
-rw-r--r--test/tools/llvm-cov/Inputs/test_preserve_paths.output8
-rw-r--r--test/tools/llvm-cvtres/basic.test4
-rw-r--r--test/tools/llvm-objdump/X86/Inputs/debug-info-fileinfo.exe.elf-x86_64bin0 -> 1540 bytes
-rw-r--r--test/tools/llvm-objdump/X86/debug-info-fileinfo.test27
-rw-r--r--test/tools/llvm-pdbdump/Inputs/ComplexPaddingTest.cpp48
-rw-r--r--test/tools/llvm-pdbdump/Inputs/ComplexPaddingTest.pdbbin0 -> 118784 bytes
-rw-r--r--test/tools/llvm-pdbdump/Inputs/SimplePaddingTest.cpp1
-rw-r--r--test/tools/llvm-pdbdump/Inputs/SimplePaddingTest.pdbbin118784 -> 118784 bytes
-rw-r--r--test/tools/llvm-pdbdump/class-layout.test8
-rw-r--r--test/tools/llvm-pdbdump/complex-padding-graphical.test53
-rw-r--r--test/tools/llvm-pdbdump/simple-padding-graphical.test18
-rw-r--r--test/tools/llvm-pdbdump/simple-padding-text.test94
-rw-r--r--test/tools/llvm-profdata/overflow-sample.test64
-rw-r--r--test/tools/llvm-profdata/sample-profile-basic.test16
-rw-r--r--test/tools/llvm-profdata/weight-sample.test64
-rw-r--r--test/tools/llvm-xray/X86/Inputs/graph-diff-A.yaml29
-rw-r--r--test/tools/llvm-xray/X86/Inputs/graph-diff-B.yaml30
-rw-r--r--test/tools/llvm-xray/X86/Inputs/simple-instrmap.yaml4
-rw-r--r--test/tools/llvm-xray/X86/graph-diff-simple.txt238
-rw-r--r--tools/LLVMBuild.txt1
-rw-r--r--tools/dsymutil/DwarfLinker.cpp8
-rw-r--r--tools/llc/llc.cpp6
-rw-r--r--tools/llvm-cvtres/CMakeLists.txt13
-rw-r--r--tools/llvm-cvtres/LLVMBuild.txt22
-rw-r--r--tools/llvm-cvtres/Opts.td11
-rw-r--r--tools/llvm-cvtres/llvm-cvtres.cpp86
-rw-r--r--tools/llvm-cvtres/llvm-cvtres.h13
-rw-r--r--tools/llvm-objdump/llvm-objdump.cpp5
-rw-r--r--tools/llvm-pdbdump/CMakeLists.txt1
-rw-r--r--tools/llvm-pdbdump/LinePrinter.cpp2
-rw-r--r--tools/llvm-pdbdump/PdbYaml.cpp92
-rw-r--r--tools/llvm-pdbdump/PdbYaml.h93
-rw-r--r--tools/llvm-pdbdump/PrettyClassDefinitionDumper.cpp67
-rw-r--r--tools/llvm-pdbdump/PrettyClassDefinitionDumper.h2
-rw-r--r--tools/llvm-pdbdump/PrettyClassLayoutGraphicalDumper.cpp142
-rw-r--r--tools/llvm-pdbdump/PrettyClassLayoutGraphicalDumper.h17
-rw-r--r--tools/llvm-pdbdump/PrettyClassLayoutTextDumper.cpp119
-rw-r--r--tools/llvm-pdbdump/PrettyClassLayoutTextDumper.h44
-rw-r--r--tools/llvm-pdbdump/PrettyTypeDumper.cpp44
-rw-r--r--tools/llvm-pdbdump/PrettyVariableDumper.cpp8
-rw-r--r--tools/llvm-pdbdump/PrettyVariableDumper.h1
-rw-r--r--tools/llvm-pdbdump/YAMLOutputStyle.cpp136
-rw-r--r--tools/llvm-pdbdump/YAMLOutputStyle.h5
-rw-r--r--tools/llvm-pdbdump/llvm-pdbdump.cpp45
-rw-r--r--tools/llvm-pdbdump/llvm-pdbdump.h16
-rw-r--r--tools/llvm-xray/CMakeLists.txt1
-rw-r--r--tools/llvm-xray/xray-color-helper.cc34
-rw-r--r--tools/llvm-xray/xray-color-helper.h12
-rw-r--r--tools/llvm-xray/xray-graph-diff.cc484
-rw-r--r--tools/llvm-xray/xray-graph-diff.h74
-rw-r--r--tools/llvm-xray/xray-graph.cc196
-rw-r--r--tools/llvm-xray/xray-graph.h117
-rw-r--r--unittests/ADT/APFloatTest.cpp21
-rw-r--r--unittests/ADT/APIntTest.cpp58
-rw-r--r--unittests/ADT/BitVectorTest.cpp8
-rw-r--r--unittests/ADT/StringExtrasTest.cpp16
-rw-r--r--unittests/ADT/TripleTest.cpp6
-rw-r--r--unittests/Analysis/ScalarEvolutionTest.cpp99
-rw-r--r--unittests/DebugInfo/DWARF/DwarfGenerator.h2
-rw-r--r--unittests/Support/BranchProbabilityTest.cpp48
-rw-r--r--unittests/Support/Path.cpp7
-rw-r--r--utils/TableGen/AsmMatcherEmitter.cpp2
-rw-r--r--utils/TableGen/CodeEmitterGen.cpp2
-rw-r--r--utils/TableGen/GlobalISelEmitter.cpp251
-rw-r--r--utils/TableGen/SubtargetFeatureInfo.cpp32
-rw-r--r--utils/TableGen/SubtargetFeatureInfo.h40
-rw-r--r--utils/TableGen/Types.cpp1
-rwxr-xr-xutils/git-svn/git-llvm69
623 files changed, 150985 insertions, 64518 deletions
diff --git a/cmake/modules/HandleLLVMOptions.cmake b/cmake/modules/HandleLLVMOptions.cmake
index 099d2ebcc437..882d68e6b608 100644
--- a/cmake/modules/HandleLLVMOptions.cmake
+++ b/cmake/modules/HandleLLVMOptions.cmake
@@ -222,6 +222,13 @@ if( CMAKE_SIZEOF_VOID_P EQUAL 8 AND NOT WIN32 )
endif( LLVM_BUILD_32_BITS )
endif( CMAKE_SIZEOF_VOID_P EQUAL 8 AND NOT WIN32 )
+# If building on a GNU specific 32-bit system, make sure off_t is 64 bits
+# so that off_t can stored offset > 2GB
+if( CMAKE_SIZEOF_VOID_P EQUAL 4 )
+ add_definitions( -D_LARGEFILE_SOURCE )
+ add_definitions( -D_FILE_OFFSET_BITS=64 )
+endif()
+
if( XCODE )
# For Xcode enable several build settings that correspond to
# many warnings that are on by default in Clang but are
diff --git a/docs/AMDGPUUsage.rst b/docs/AMDGPUUsage.rst
index 5ff0f207f227..97497057fc96 100644
--- a/docs/AMDGPUUsage.rst
+++ b/docs/AMDGPUUsage.rst
@@ -82,9 +82,8 @@ handler as follows:
=============== ============= ===============================================
Usage Code Sequence Description
=============== ============= ===============================================
- llvm.trap s_endpgm Causes wavefront to be terminated.
- llvm.debugtrap s_nop No operation. Compiler warning generated that
- there is no trap handler installed.
+ llvm.trap s_endpgm Causes wavefront to be terminated.
+ llvm.debugtrap Nothing. Compiler warning generated that there is no trap handler installed.
=============== ============= ===============================================
Assembler
diff --git a/docs/GettingStarted.rst b/docs/GettingStarted.rst
index a88860310f64..d5c8ba4b8214 100644
--- a/docs/GettingStarted.rst
+++ b/docs/GettingStarted.rst
@@ -171,6 +171,8 @@ Linux PowerPC GCC, Clang
Solaris V9 (Ultrasparc) GCC
FreeBSD x86\ :sup:`1` GCC, Clang
FreeBSD amd64 GCC, Clang
+NetBSD x86\ :sup:`1` GCC, Clang
+NetBSD amd64 GCC, Clang
MacOS X\ :sup:`2` PowerPC GCC
MacOS X x86 GCC, Clang
Cygwin/Win32 x86\ :sup:`1, 3` GCC
diff --git a/docs/HowToAddABuilder.rst b/docs/HowToAddABuilder.rst
index fcc2293de052..08cbecdc2a57 100644
--- a/docs/HowToAddABuilder.rst
+++ b/docs/HowToAddABuilder.rst
@@ -83,6 +83,8 @@ Here are the steps you can follow to do so:
* slaves are added to ``buildbot/osuosl/master/config/slaves.py``
* builders are added to ``buildbot/osuosl/master/config/builders.py``
+ Please make sure your builder name and its builddir are unique through the file.
+
It is possible to whitelist email addresses to unconditionally receive notifications
on build failure; for this you'll need to add an ``InformativeMailNotifier`` to
``buildbot/osuosl/master/config/status.py``. This is particularly useful for the
diff --git a/docs/LibFuzzer.rst b/docs/LibFuzzer.rst
index 0b785a325e69..a11baa720ec8 100644
--- a/docs/LibFuzzer.rst
+++ b/docs/LibFuzzer.rst
@@ -87,10 +87,16 @@ Some important things to remember about fuzz targets:
* Usually, the narrower the target the better. E.g. if your target can parse several data formats, split it into several targets, one per format.
-Building
---------
+Fuzzer Usage
+------------
+
+Very recent versions of Clang (> April 20 2017) include libFuzzer,
+and no installation is necessary.
+In order to fuzz your binary, use the `-fsanitize=fuzzer` flag during the compilation::
-Next, build the libFuzzer library as a static archive, without any sanitizer
+ clang -fsanitize=fuzzer,address mytarget.c
+
+Otherwise, build the libFuzzer library as a static archive, without any sanitizer
options. Note that the libFuzzer library contains the ``main()`` function:
.. code-block:: console
@@ -728,6 +734,7 @@ to crash on invalid inputs.
Examples: regular expression matchers, text or binary format parsers, compression,
network, crypto.
+
Trophies
========
* GLIBC: https://sourceware.org/glibc/wiki/FuzzingLibc
diff --git a/include/llvm/ADT/APFloat.h b/include/llvm/ADT/APFloat.h
index e7e5036e6930..bef6efde1f01 100644
--- a/include/llvm/ADT/APFloat.h
+++ b/include/llvm/ADT/APFloat.h
@@ -397,6 +397,12 @@ public:
/// consider inserting before falling back to scientific
/// notation. 0 means to always use scientific notation.
///
+ /// \param TruncateZero Indicate whether to remove the trailing zero in
+ /// fraction part or not. Also setting this parameter to false forcing
+ /// producing of output more similar to default printf behavior.
+ /// Specifically the lower e is used as exponent delimiter and exponent
+ /// always contains no less than two digits.
+ ///
/// Number Precision MaxPadding Result
/// ------ --------- ---------- ------
/// 1.01E+4 5 2 10100
@@ -406,7 +412,7 @@ public:
/// 1.01E-2 4 2 0.0101
/// 1.01E-2 4 1 1.01E-2
void toString(SmallVectorImpl<char> &Str, unsigned FormatPrecision = 0,
- unsigned FormatMaxPadding = 3) const;
+ unsigned FormatMaxPadding = 3, bool TruncateZero = true) const;
/// If this value has an exact multiplicative inverse, store it in inv and
/// return true.
@@ -649,7 +655,7 @@ public:
bool isInteger() const;
void toString(SmallVectorImpl<char> &Str, unsigned FormatPrecision,
- unsigned FormatMaxPadding) const;
+ unsigned FormatMaxPadding, bool TruncateZero = true) const;
bool getExactInverse(APFloat *inv) const;
@@ -1144,9 +1150,9 @@ public:
APFloat &operator=(APFloat &&RHS) = default;
void toString(SmallVectorImpl<char> &Str, unsigned FormatPrecision = 0,
- unsigned FormatMaxPadding = 3) const {
+ unsigned FormatMaxPadding = 3, bool TruncateZero = true) const {
APFLOAT_DISPATCH_ON_SEMANTICS(
- toString(Str, FormatPrecision, FormatMaxPadding));
+ toString(Str, FormatPrecision, FormatMaxPadding, TruncateZero));
}
void print(raw_ostream &) const;
diff --git a/include/llvm/ADT/APInt.h b/include/llvm/ADT/APInt.h
index ceb623d34531..d0104c3f0fa9 100644
--- a/include/llvm/ADT/APInt.h
+++ b/include/llvm/ADT/APInt.h
@@ -78,6 +78,8 @@ public:
APINT_BITS_PER_WORD = APINT_WORD_SIZE * CHAR_BIT
};
+ static const WordType WORD_MAX = ~WordType(0);
+
private:
/// This union is used to store the integer value. When the
/// integer bit-width <= 64, it uses VAL, otherwise it uses pVal.
@@ -90,6 +92,8 @@ private:
friend struct DenseMapAPIntKeyInfo;
+ friend class APSInt;
+
/// \brief Fast internal constructor
///
/// This constructor is used only internally for speed of construction of
@@ -134,15 +138,10 @@ private:
/// zero'd out.
APInt &clearUnusedBits() {
// Compute how many bits are used in the final word
- unsigned wordBits = BitWidth % APINT_BITS_PER_WORD;
- if (wordBits == 0)
- // If all bits are used, we want to leave the value alone. This also
- // avoids the undefined behavior of >> when the shift is the same size as
- // the word size (64).
- return *this;
+ unsigned WordBits = ((BitWidth-1) % APINT_BITS_PER_WORD) + 1;
// Mask out the high bits.
- uint64_t mask = UINT64_MAX >> (APINT_BITS_PER_WORD - wordBits);
+ uint64_t mask = WORD_MAX >> (APINT_BITS_PER_WORD - WordBits);
if (isSingleWord())
VAL &= mask;
else
@@ -194,6 +193,9 @@ private:
/// out-of-line slow case for lshr.
void lshrSlowCase(unsigned ShiftAmt);
+ /// out-of-line slow case for ashr.
+ void ashrSlowCase(unsigned ShiftAmt);
+
/// out-of-line slow case for operator=
void AssignSlowCase(const APInt &RHS);
@@ -230,6 +232,14 @@ private:
/// out-of-line slow case for operator^=.
void XorAssignSlowCase(const APInt& RHS);
+ /// Unsigned comparison. Returns -1, 0, or 1 if this APInt is less than, equal
+ /// to, or greater than RHS.
+ int compare(const APInt &RHS) const LLVM_READONLY;
+
+ /// Signed comparison. Returns -1, 0, or 1 if this APInt is less than, equal
+ /// to, or greater than RHS.
+ int compareSigned(const APInt &RHS) const LLVM_READONLY;
+
public:
/// \name Constructors
/// @{
@@ -363,7 +373,7 @@ public:
/// This checks to see if the value has all bits of the APInt are set or not.
bool isAllOnesValue() const {
if (isSingleWord())
- return VAL == UINT64_MAX >> (APINT_BITS_PER_WORD - BitWidth);
+ return VAL == WORD_MAX >> (APINT_BITS_PER_WORD - BitWidth);
return countPopulationSlowCase() == BitWidth;
}
@@ -445,7 +455,7 @@ public:
assert(numBits != 0 && "numBits must be non-zero");
assert(numBits <= BitWidth && "numBits out of range");
if (isSingleWord())
- return VAL == (UINT64_MAX >> (APINT_BITS_PER_WORD - numBits));
+ return VAL == (WORD_MAX >> (APINT_BITS_PER_WORD - numBits));
unsigned Ones = countTrailingOnesSlowCase();
return (numBits == Ones) &&
((Ones + countLeadingZerosSlowCase()) == BitWidth);
@@ -509,7 +519,7 @@ public:
///
/// \returns the all-ones value for an APInt of the specified bit-width.
static APInt getAllOnesValue(unsigned numBits) {
- return APInt(numBits, UINT64_MAX, true);
+ return APInt(numBits, WORD_MAX, true);
}
/// \brief Get the '0' value.
@@ -886,7 +896,26 @@ public:
/// \brief Arithmetic right-shift function.
///
/// Arithmetic right-shift this APInt by shiftAmt.
- APInt ashr(unsigned shiftAmt) const;
+ APInt ashr(unsigned ShiftAmt) const {
+ APInt R(*this);
+ R.ashrInPlace(ShiftAmt);
+ return R;
+ }
+
+ /// Arithmetic right-shift this APInt by ShiftAmt in place.
+ void ashrInPlace(unsigned ShiftAmt) {
+ assert(ShiftAmt <= BitWidth && "Invalid shift amount");
+ if (isSingleWord()) {
+ int64_t SExtVAL = SignExtend64(VAL, BitWidth);
+ if (ShiftAmt == BitWidth)
+ VAL = SExtVAL >> (APINT_BITS_PER_WORD - 1); // Fill with sign bit.
+ else
+ VAL = SExtVAL >> ShiftAmt;
+ clearUnusedBits();
+ return;
+ }
+ ashrSlowCase(ShiftAmt);
+ }
/// \brief Logical right-shift function.
///
@@ -928,7 +957,14 @@ public:
/// \brief Arithmetic right-shift function.
///
/// Arithmetic right-shift this APInt by shiftAmt.
- APInt ashr(const APInt &shiftAmt) const;
+ APInt ashr(const APInt &ShiftAmt) const {
+ APInt R(*this);
+ R.ashrInPlace(ShiftAmt);
+ return R;
+ }
+
+ /// Arithmetic right-shift this APInt by shiftAmt in place.
+ void ashrInPlace(const APInt &shiftAmt);
/// \brief Logical right-shift function.
///
@@ -1079,7 +1115,7 @@ public:
/// the validity of the less-than relationship.
///
/// \returns true if *this < RHS when both are considered unsigned.
- bool ult(const APInt &RHS) const LLVM_READONLY;
+ bool ult(const APInt &RHS) const { return compare(RHS) < 0; }
/// \brief Unsigned less than comparison
///
@@ -1098,7 +1134,7 @@ public:
/// validity of the less-than relationship.
///
/// \returns true if *this < RHS when both are considered signed.
- bool slt(const APInt &RHS) const LLVM_READONLY;
+ bool slt(const APInt &RHS) const { return compareSigned(RHS) < 0; }
/// \brief Signed less than comparison
///
@@ -1117,7 +1153,7 @@ public:
/// validity of the less-or-equal relationship.
///
/// \returns true if *this <= RHS when both are considered unsigned.
- bool ule(const APInt &RHS) const { return ult(RHS) || eq(RHS); }
+ bool ule(const APInt &RHS) const { return compare(RHS) <= 0; }
/// \brief Unsigned less or equal comparison
///
@@ -1133,7 +1169,7 @@ public:
/// validity of the less-or-equal relationship.
///
/// \returns true if *this <= RHS when both are considered signed.
- bool sle(const APInt &RHS) const { return slt(RHS) || eq(RHS); }
+ bool sle(const APInt &RHS) const { return compareSigned(RHS) <= 0; }
/// \brief Signed less or equal comparison
///
@@ -1149,7 +1185,7 @@ public:
/// the validity of the greater-than relationship.
///
/// \returns true if *this > RHS when both are considered unsigned.
- bool ugt(const APInt &RHS) const { return !ult(RHS) && !eq(RHS); }
+ bool ugt(const APInt &RHS) const { return !ule(RHS); }
/// \brief Unsigned greater than comparison
///
@@ -1168,7 +1204,7 @@ public:
/// validity of the greater-than relationship.
///
/// \returns true if *this > RHS when both are considered signed.
- bool sgt(const APInt &RHS) const { return !slt(RHS) && !eq(RHS); }
+ bool sgt(const APInt &RHS) const { return !sle(RHS); }
/// \brief Signed greater than comparison
///
@@ -1286,7 +1322,7 @@ public:
/// \brief Set every bit to 1.
void setAllBits() {
if (isSingleWord())
- VAL = UINT64_MAX;
+ VAL = WORD_MAX;
else
// Set all the bits in all the words.
memset(pVal, -1, getNumWords() * APINT_WORD_SIZE);
@@ -1316,7 +1352,7 @@ public:
return;
}
if (loBit < APINT_BITS_PER_WORD && hiBit <= APINT_BITS_PER_WORD) {
- uint64_t mask = UINT64_MAX >> (APINT_BITS_PER_WORD - (hiBit - loBit));
+ uint64_t mask = WORD_MAX >> (APINT_BITS_PER_WORD - (hiBit - loBit));
mask <<= loBit;
if (isSingleWord())
VAL |= mask;
@@ -1358,7 +1394,7 @@ public:
/// \brief Toggle every bit to its opposite value.
void flipAllBits() {
if (isSingleWord()) {
- VAL ^= UINT64_MAX;
+ VAL ^= WORD_MAX;
clearUnusedBits();
} else {
flipAllBitsSlowCase();
@@ -1653,7 +1689,7 @@ public:
/// referencing 2 in a space where 2 does no exist.
unsigned nearestLogBase2() const {
// Special case when we have a bitwidth of 1. If VAL is 1, then we
- // get 0. If VAL is 0, we get UINT64_MAX which gets truncated to
+ // get 0. If VAL is 0, we get WORD_MAX which gets truncated to
// UINT32_MAX.
if (BitWidth == 1)
return VAL - 1;
diff --git a/include/llvm/ADT/APSInt.h b/include/llvm/ADT/APSInt.h
index 5b6dfa4a4b64..dabbf3314bd0 100644
--- a/include/llvm/ADT/APSInt.h
+++ b/include/llvm/ADT/APSInt.h
@@ -125,7 +125,10 @@ public:
return IsUnsigned ? APSInt(lshr(Amt), true) : APSInt(ashr(Amt), false);
}
APSInt& operator>>=(unsigned Amt) {
- *this = *this >> Amt;
+ if (IsUnsigned)
+ lshrInPlace(Amt);
+ else
+ ashrInPlace(Amt);
return *this;
}
@@ -179,7 +182,7 @@ public:
return APSInt(static_cast<const APInt&>(*this) << Bits, IsUnsigned);
}
APSInt& operator<<=(unsigned Amt) {
- *this = *this << Amt;
+ static_cast<APInt&>(*this) <<= Amt;
return *this;
}
@@ -285,12 +288,12 @@ public:
/// \brief Compare underlying values of two numbers.
static int compareValues(const APSInt &I1, const APSInt &I2) {
if (I1.getBitWidth() == I2.getBitWidth() && I1.isSigned() == I2.isSigned())
- return I1 == I2 ? 0 : I1 > I2 ? 1 : -1;
+ return I1.IsUnsigned ? I1.compare(I2) : I1.compareSigned(I2);
// Check for a bit-width mismatch.
if (I1.getBitWidth() > I2.getBitWidth())
return compareValues(I1, I2.extend(I1.getBitWidth()));
- else if (I2.getBitWidth() > I1.getBitWidth())
+ if (I2.getBitWidth() > I1.getBitWidth())
return compareValues(I1.extend(I2.getBitWidth()), I2);
// We have a signedness mismatch. Check for negative values and do an
@@ -305,7 +308,7 @@ public:
return 1;
}
- return I1.eq(I2) ? 0 : I1.ugt(I2) ? 1 : -1;
+ return I1.compare(I2);
}
static APSInt get(int64_t X) { return APSInt(APInt(64, X), false); }
diff --git a/include/llvm/ADT/BitVector.h b/include/llvm/ADT/BitVector.h
index e48c023ae7df..5aa101591e6e 100644
--- a/include/llvm/ADT/BitVector.h
+++ b/include/llvm/ADT/BitVector.h
@@ -15,7 +15,6 @@
#define LLVM_ADT_BITVECTOR_H
#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/MathExtras.h"
#include <algorithm>
#include <cassert>
@@ -35,9 +34,8 @@ class BitVector {
static_assert(BITWORD_SIZE == 64 || BITWORD_SIZE == 32,
"Unsupported word size");
- BitWord *Bits; // Actual bits.
- unsigned Size; // Size of bitvector in bits.
- unsigned Capacity; // Number of BitWords allocated in the Bits array.
+ MutableArrayRef<BitWord> Bits; // Actual bits.
+ unsigned Size; // Size of bitvector in bits.
public:
typedef unsigned size_type;
@@ -77,16 +75,14 @@ public:
/// BitVector default ctor - Creates an empty bitvector.
- BitVector() : Size(0), Capacity(0) {
- Bits = nullptr;
- }
+ BitVector() : Size(0) {}
/// BitVector ctor - Creates a bitvector of specified number of bits. All
/// bits are initialized to the specified value.
explicit BitVector(unsigned s, bool t = false) : Size(s) {
- Capacity = NumBitWords(s);
- Bits = (BitWord *)std::malloc(Capacity * sizeof(BitWord));
- init_words(Bits, Capacity, t);
+ size_t Capacity = NumBitWords(s);
+ Bits = allocate(Capacity);
+ init_words(Bits, t);
if (t)
clear_unused_bits();
}
@@ -94,25 +90,21 @@ public:
/// BitVector copy ctor.
BitVector(const BitVector &RHS) : Size(RHS.size()) {
if (Size == 0) {
- Bits = nullptr;
- Capacity = 0;
+ Bits = MutableArrayRef<BitWord>();
return;
}
- Capacity = NumBitWords(RHS.size());
- Bits = (BitWord *)std::malloc(Capacity * sizeof(BitWord));
- std::memcpy(Bits, RHS.Bits, Capacity * sizeof(BitWord));
+ size_t Capacity = NumBitWords(RHS.size());
+ Bits = allocate(Capacity);
+ std::memcpy(Bits.data(), RHS.Bits.data(), Capacity * sizeof(BitWord));
}
- BitVector(BitVector &&RHS)
- : Bits(RHS.Bits), Size(RHS.Size), Capacity(RHS.Capacity) {
- RHS.Bits = nullptr;
- RHS.Size = RHS.Capacity = 0;
+ BitVector(BitVector &&RHS) : Bits(RHS.Bits), Size(RHS.Size) {
+ RHS.Bits = MutableArrayRef<BitWord>();
+ RHS.Size = 0;
}
- ~BitVector() {
- std::free(Bits);
- }
+ ~BitVector() { std::free(Bits.data()); }
/// empty - Tests whether there are no bits in this bitvector.
bool empty() const { return Size == 0; }
@@ -163,6 +155,22 @@ public:
return -1;
}
+ /// find_last - Returns the index of the last set bit, -1 if none of the bits
+ /// are set.
+ int find_last() const {
+ if (Size == 0)
+ return -1;
+
+ unsigned N = NumBitWords(size());
+ assert(N > 0);
+
+ unsigned i = N - 1;
+ while (i > 0 && Bits[i] == BitWord(0))
+ --i;
+
+ return int((i + 1) * BITWORD_SIZE - countLeadingZeros(Bits[i])) - 1;
+ }
+
/// find_first_unset - Returns the index of the first unset bit, -1 if all
/// of the bits are set.
int find_first_unset() const {
@@ -174,6 +182,30 @@ public:
return -1;
}
+ /// find_last_unset - Returns the index of the last unset bit, -1 if all of
+ /// the bits are set.
+ int find_last_unset() const {
+ if (Size == 0)
+ return -1;
+
+ const unsigned N = NumBitWords(size());
+ assert(N > 0);
+
+ unsigned i = N - 1;
+ BitWord W = Bits[i];
+
+ // The last word in the BitVector has some unused bits, so we need to set
+ // them all to 1 first. Set them all to 1 so they don't get treated as
+ // valid unset bits.
+ unsigned UnusedCount = BITWORD_SIZE - size() % BITWORD_SIZE;
+ W |= maskLeadingOnes<BitWord>(UnusedCount);
+
+ while (W == ~BitWord(0) && --i > 0)
+ W = Bits[i];
+
+ return int((i + 1) * BITWORD_SIZE - countLeadingOnes(W)) - 1;
+ }
+
/// find_next - Returns the index of the next set bit following the
/// "Prev" bit. Returns -1 if the next set bit is not found.
int find_next(unsigned Prev) const {
@@ -228,10 +260,10 @@ public:
/// resize - Grow or shrink the bitvector.
void resize(unsigned N, bool t = false) {
- if (N > Capacity * BITWORD_SIZE) {
- unsigned OldCapacity = Capacity;
+ if (N > getBitCapacity()) {
+ unsigned OldCapacity = Bits.size();
grow(N);
- init_words(&Bits[OldCapacity], (Capacity-OldCapacity), t);
+ init_words(Bits.drop_front(OldCapacity), t);
}
// Set any old unused bits that are now included in the BitVector. This
@@ -248,19 +280,19 @@ public:
}
void reserve(unsigned N) {
- if (N > Capacity * BITWORD_SIZE)
+ if (N > getBitCapacity())
grow(N);
}
// Set, reset, flip
BitVector &set() {
- init_words(Bits, Capacity, true);
+ init_words(Bits, true);
clear_unused_bits();
return *this;
}
BitVector &set(unsigned Idx) {
- assert(Bits && "Bits never allocated");
+ assert(Bits.data() && "Bits never allocated");
Bits[Idx / BITWORD_SIZE] |= BitWord(1) << (Idx % BITWORD_SIZE);
return *this;
}
@@ -295,7 +327,7 @@ public:
}
BitVector &reset() {
- init_words(Bits, Capacity, false);
+ init_words(Bits, false);
return *this;
}
@@ -562,21 +594,21 @@ public:
Size = RHS.size();
unsigned RHSWords = NumBitWords(Size);
- if (Size <= Capacity * BITWORD_SIZE) {
+ if (Size <= getBitCapacity()) {
if (Size)
- std::memcpy(Bits, RHS.Bits, RHSWords * sizeof(BitWord));
+ std::memcpy(Bits.data(), RHS.Bits.data(), RHSWords * sizeof(BitWord));
clear_unused_bits();
return *this;
}
// Grow the bitvector to have enough elements.
- Capacity = RHSWords;
- assert(Capacity > 0 && "negative capacity?");
- BitWord *NewBits = (BitWord *)std::malloc(Capacity * sizeof(BitWord));
- std::memcpy(NewBits, RHS.Bits, Capacity * sizeof(BitWord));
+ unsigned NewCapacity = RHSWords;
+ assert(NewCapacity > 0 && "negative capacity?");
+ auto NewBits = allocate(NewCapacity);
+ std::memcpy(NewBits.data(), RHS.Bits.data(), NewCapacity * sizeof(BitWord));
// Destroy the old bits.
- std::free(Bits);
+ std::free(Bits.data());
Bits = NewBits;
return *this;
@@ -585,13 +617,12 @@ public:
const BitVector &operator=(BitVector &&RHS) {
if (this == &RHS) return *this;
- std::free(Bits);
+ std::free(Bits.data());
Bits = RHS.Bits;
Size = RHS.Size;
- Capacity = RHS.Capacity;
- RHS.Bits = nullptr;
- RHS.Size = RHS.Capacity = 0;
+ RHS.Bits = MutableArrayRef<BitWord>();
+ RHS.Size = 0;
return *this;
}
@@ -599,7 +630,6 @@ public:
void swap(BitVector &RHS) {
std::swap(Bits, RHS.Bits);
std::swap(Size, RHS.Size);
- std::swap(Capacity, RHS.Capacity);
}
//===--------------------------------------------------------------------===//
@@ -659,14 +689,14 @@ private:
uint32_t NumWords = NumBitWords(Size);
- auto Src = ArrayRef<BitWord>(Bits, NumWords).drop_back(Count);
- auto Dest = MutableArrayRef<BitWord>(Bits, NumWords).drop_front(Count);
+ auto Src = Bits.take_front(NumWords).drop_back(Count);
+ auto Dest = Bits.take_front(NumWords).drop_front(Count);
// Since we always move Word-sized chunks of data with src and dest both
// aligned to a word-boundary, we don't need to worry about endianness
// here.
std::memmove(Dest.begin(), Src.begin(), Dest.size() * sizeof(BitWord));
- std::memset(Bits, 0, Count * sizeof(BitWord));
+ std::memset(Bits.data(), 0, Count * sizeof(BitWord));
clear_unused_bits();
}
@@ -679,14 +709,19 @@ private:
uint32_t NumWords = NumBitWords(Size);
- auto Src = ArrayRef<BitWord>(Bits, NumWords).drop_front(Count);
- auto Dest = MutableArrayRef<BitWord>(Bits, NumWords).drop_back(Count);
+ auto Src = Bits.take_front(NumWords).drop_front(Count);
+ auto Dest = Bits.take_front(NumWords).drop_back(Count);
assert(Dest.size() == Src.size());
std::memmove(Dest.begin(), Src.begin(), Dest.size() * sizeof(BitWord));
std::memset(Dest.end(), 0, Count * sizeof(BitWord));
}
+ MutableArrayRef<BitWord> allocate(size_t NumWords) {
+ BitWord *RawBits = (BitWord *)std::malloc(NumWords * sizeof(BitWord));
+ return MutableArrayRef<BitWord>(RawBits, NumWords);
+ }
+
int next_unset_in_word(int WordIndex, BitWord Word) const {
unsigned Result = WordIndex * BITWORD_SIZE + countTrailingOnes(Word);
return Result < size() ? Result : -1;
@@ -700,8 +735,8 @@ private:
void set_unused_bits(bool t = true) {
// Set high words first.
unsigned UsedWords = NumBitWords(Size);
- if (Capacity > UsedWords)
- init_words(&Bits[UsedWords], (Capacity-UsedWords), t);
+ if (Bits.size() > UsedWords)
+ init_words(Bits.drop_front(UsedWords), t);
// Then set any stray high bits of the last used word.
unsigned ExtraBits = Size % BITWORD_SIZE;
@@ -720,16 +755,17 @@ private:
}
void grow(unsigned NewSize) {
- Capacity = std::max(NumBitWords(NewSize), Capacity * 2);
- assert(Capacity > 0 && "realloc-ing zero space");
- Bits = (BitWord *)std::realloc(Bits, Capacity * sizeof(BitWord));
-
+ size_t NewCapacity = std::max<size_t>(NumBitWords(NewSize), Bits.size() * 2);
+ assert(NewCapacity > 0 && "realloc-ing zero space");
+ BitWord *NewBits =
+ (BitWord *)std::realloc(Bits.data(), NewCapacity * sizeof(BitWord));
+ Bits = MutableArrayRef<BitWord>(NewBits, NewCapacity);
clear_unused_bits();
}
- void init_words(BitWord *B, unsigned NumWords, bool t) {
- if (NumWords > 0)
- memset(B, 0 - (int)t, NumWords*sizeof(BitWord));
+ void init_words(MutableArrayRef<BitWord> B, bool t) {
+ if (B.size() > 0)
+ memset(B.data(), 0 - (int)t, B.size() * sizeof(BitWord));
}
template<bool AddBits, bool InvertMask>
@@ -761,7 +797,8 @@ private:
public:
/// Return the size (in bytes) of the bit vector.
- size_t getMemorySize() const { return Capacity * sizeof(BitWord); }
+ size_t getMemorySize() const { return Bits.size() * sizeof(BitWord); }
+ size_t getBitCapacity() const { return Bits.size() * BITWORD_SIZE; }
};
static inline size_t capacity_in_bytes(const BitVector &X) {
diff --git a/include/llvm/ADT/SmallBitVector.h b/include/llvm/ADT/SmallBitVector.h
index 607e040a606c..bf16af5933f0 100644
--- a/include/llvm/ADT/SmallBitVector.h
+++ b/include/llvm/ADT/SmallBitVector.h
@@ -117,9 +117,7 @@ private:
}
// Return the size.
- size_t getSmallSize() const {
- return getSmallRawBits() >> SmallNumDataBits;
- }
+ size_t getSmallSize() const { return getSmallRawBits() >> SmallNumDataBits; }
void setSmallSize(size_t Size) {
setSmallRawBits(getSmallBits() | (Size << SmallNumDataBits));
@@ -216,6 +214,16 @@ public:
return getPointer()->find_first();
}
+ int find_last() const {
+ if (isSmall()) {
+ uintptr_t Bits = getSmallBits();
+ if (Bits == 0)
+ return -1;
+ return NumBaseBits - countLeadingZeros(Bits);
+ }
+ return getPointer()->find_last();
+ }
+
/// Returns the index of the first unset bit, -1 if all of the bits are set.
int find_first_unset() const {
if (isSmall()) {
@@ -228,6 +236,17 @@ public:
return getPointer()->find_first_unset();
}
+ int find_last_unset() const {
+ if (isSmall()) {
+ if (count() == getSmallSize())
+ return -1;
+
+ uintptr_t Bits = getSmallBits();
+ return NumBaseBits - countLeadingOnes(Bits);
+ }
+ return getPointer()->find_last_unset();
+ }
+
/// Returns the index of the next set bit following the "Prev" bit.
/// Returns -1 if the next set bit is not found.
int find_next(unsigned Prev) const {
diff --git a/include/llvm/ADT/StringExtras.h b/include/llvm/ADT/StringExtras.h
index 8214782bfe80..26f11924b771 100644
--- a/include/llvm/ADT/StringExtras.h
+++ b/include/llvm/ADT/StringExtras.h
@@ -76,6 +76,36 @@ static inline std::string toHex(StringRef Input) {
return Output;
}
+static inline uint8_t hexFromNibbles(char MSB, char LSB) {
+ unsigned U1 = hexDigitValue(MSB);
+ unsigned U2 = hexDigitValue(LSB);
+ assert(U1 != -1U && U2 != -1U);
+
+ return static_cast<uint8_t>((U1 << 4) | U2);
+}
+
+/// Convert hexadecimal string \p Input to its binary representation.
+/// The return string is half the size of \p Input.
+static inline std::string fromHex(StringRef Input) {
+ if (Input.empty())
+ return std::string();
+
+ std::string Output;
+ Output.reserve((Input.size() + 1) / 2);
+ if (Input.size() % 2 == 1) {
+ Output.push_back(hexFromNibbles('0', Input.front()));
+ Input = Input.drop_front();
+ }
+
+ assert(Input.size() % 2 == 0);
+ while (!Input.empty()) {
+ uint8_t Hex = hexFromNibbles(Input[0], Input[1]);
+ Output.push_back(Hex);
+ Input = Input.drop_front(2);
+ }
+ return Output;
+}
+
static inline std::string utostr(uint64_t X, bool isNeg = false) {
char Buffer[21];
char *BufPtr = std::end(Buffer);
diff --git a/include/llvm/ADT/Triple.h b/include/llvm/ADT/Triple.h
index e271075b7e2a..e3a8a31ba9bc 100644
--- a/include/llvm/ADT/Triple.h
+++ b/include/llvm/ADT/Triple.h
@@ -140,7 +140,8 @@ public:
Myriad,
AMD,
Mesa,
- LastVendorType = Mesa
+ SUSE,
+ LastVendorType = SUSE
};
enum OSType {
UnknownOS,
diff --git a/include/llvm/Analysis/DemandedBits.h b/include/llvm/Analysis/DemandedBits.h
index c603274a7161..e5fd8a0007fe 100644
--- a/include/llvm/Analysis/DemandedBits.h
+++ b/include/llvm/Analysis/DemandedBits.h
@@ -35,6 +35,7 @@ class Function;
class Instruction;
class DominatorTree;
class AssumptionCache;
+struct KnownBits;
class DemandedBits {
public:
@@ -58,8 +59,7 @@ private:
void determineLiveOperandBits(const Instruction *UserI,
const Instruction *I, unsigned OperandNo,
const APInt &AOut, APInt &AB,
- APInt &KnownZero, APInt &KnownOne,
- APInt &KnownZero2, APInt &KnownOne2);
+ KnownBits &Known, KnownBits &Known2);
bool Analyzed;
diff --git a/include/llvm/Analysis/InstructionSimplify.h b/include/llvm/Analysis/InstructionSimplify.h
index b829e995db05..25240dae75e7 100644
--- a/include/llvm/Analysis/InstructionSimplify.h
+++ b/include/llvm/Analysis/InstructionSimplify.h
@@ -47,8 +47,33 @@ namespace llvm {
class Type;
class Value;
+ struct SimplifyQuery {
+ const DataLayout &DL;
+ const TargetLibraryInfo *TLI = nullptr;
+ const DominatorTree *DT = nullptr;
+ AssumptionCache *AC = nullptr;
+ const Instruction *CxtI = nullptr;
+ SimplifyQuery(const DataLayout &DL) : DL(DL) {}
+
+ SimplifyQuery(const DataLayout &DL, const TargetLibraryInfo *TLI,
+ const DominatorTree *DT, AssumptionCache *AC = nullptr,
+ const Instruction *CXTI = nullptr)
+ : DL(DL), TLI(TLI), DT(DT), AC(AC), CxtI(CXTI) {}
+ SimplifyQuery getWithInstruction(Instruction *I) const {
+ SimplifyQuery Copy(*this);
+ Copy.CxtI = I;
+ return Copy;
+ }
+ };
+
+ // NOTE: the explicit multiple argument versions of these functions are
+ // deprecated.
+ // Please use the SimplifyQuery versions in new code.
+
/// Given operands for an Add, fold the result or return null.
Value *SimplifyAddInst(Value *LHS, Value *RHS, bool isNSW, bool isNUW,
+ const SimplifyQuery &Q);
+ Value *SimplifyAddInst(Value *LHS, Value *RHS, bool isNSW, bool isNUW,
const DataLayout &DL,
const TargetLibraryInfo *TLI = nullptr,
const DominatorTree *DT = nullptr,
@@ -57,6 +82,8 @@ namespace llvm {
/// Given operands for a Sub, fold the result or return null.
Value *SimplifySubInst(Value *LHS, Value *RHS, bool isNSW, bool isNUW,
+ const SimplifyQuery &Q);
+ Value *SimplifySubInst(Value *LHS, Value *RHS, bool isNSW, bool isNUW,
const DataLayout &DL,
const TargetLibraryInfo *TLI = nullptr,
const DominatorTree *DT = nullptr,
@@ -65,6 +92,8 @@ namespace llvm {
/// Given operands for an FAdd, fold the result or return null.
Value *SimplifyFAddInst(Value *LHS, Value *RHS, FastMathFlags FMF,
+ const SimplifyQuery &Q);
+ Value *SimplifyFAddInst(Value *LHS, Value *RHS, FastMathFlags FMF,
const DataLayout &DL,
const TargetLibraryInfo *TLI = nullptr,
const DominatorTree *DT = nullptr,
@@ -73,6 +102,8 @@ namespace llvm {
/// Given operands for an FSub, fold the result or return null.
Value *SimplifyFSubInst(Value *LHS, Value *RHS, FastMathFlags FMF,
+ const SimplifyQuery &Q);
+ Value *SimplifyFSubInst(Value *LHS, Value *RHS, FastMathFlags FMF,
const DataLayout &DL,
const TargetLibraryInfo *TLI = nullptr,
const DominatorTree *DT = nullptr,
@@ -81,6 +112,8 @@ namespace llvm {
/// Given operands for an FMul, fold the result or return null.
Value *SimplifyFMulInst(Value *LHS, Value *RHS, FastMathFlags FMF,
+ const SimplifyQuery &Q);
+ Value *SimplifyFMulInst(Value *LHS, Value *RHS, FastMathFlags FMF,
const DataLayout &DL,
const TargetLibraryInfo *TLI = nullptr,
const DominatorTree *DT = nullptr,
@@ -88,6 +121,7 @@ namespace llvm {
const Instruction *CxtI = nullptr);
/// Given operands for a Mul, fold the result or return null.
+ Value *SimplifyMulInst(Value *LHS, Value *RHS, const SimplifyQuery &Q);
Value *SimplifyMulInst(Value *LHS, Value *RHS, const DataLayout &DL,
const TargetLibraryInfo *TLI = nullptr,
const DominatorTree *DT = nullptr,
@@ -95,6 +129,7 @@ namespace llvm {
const Instruction *CxtI = nullptr);
/// Given operands for an SDiv, fold the result or return null.
+ Value *SimplifySDivInst(Value *LHS, Value *RHS, const SimplifyQuery &Q);
Value *SimplifySDivInst(Value *LHS, Value *RHS, const DataLayout &DL,
const TargetLibraryInfo *TLI = nullptr,
const DominatorTree *DT = nullptr,
@@ -102,6 +137,7 @@ namespace llvm {
const Instruction *CxtI = nullptr);
/// Given operands for a UDiv, fold the result or return null.
+ Value *SimplifyUDivInst(Value *LHS, Value *RHS, const SimplifyQuery &Q);
Value *SimplifyUDivInst(Value *LHS, Value *RHS, const DataLayout &DL,
const TargetLibraryInfo *TLI = nullptr,
const DominatorTree *DT = nullptr,
@@ -110,6 +146,8 @@ namespace llvm {
/// Given operands for an FDiv, fold the result or return null.
Value *SimplifyFDivInst(Value *LHS, Value *RHS, FastMathFlags FMF,
+ const SimplifyQuery &Q);
+ Value *SimplifyFDivInst(Value *LHS, Value *RHS, FastMathFlags FMF,
const DataLayout &DL,
const TargetLibraryInfo *TLI = nullptr,
const DominatorTree *DT = nullptr,
@@ -117,6 +155,7 @@ namespace llvm {
const Instruction *CxtI = nullptr);
/// Given operands for an SRem, fold the result or return null.
+ Value *SimplifySRemInst(Value *LHS, Value *RHS, const SimplifyQuery &Q);
Value *SimplifySRemInst(Value *LHS, Value *RHS, const DataLayout &DL,
const TargetLibraryInfo *TLI = nullptr,
const DominatorTree *DT = nullptr,
@@ -124,6 +163,7 @@ namespace llvm {
const Instruction *CxtI = nullptr);
/// Given operands for a URem, fold the result or return null.
+ Value *SimplifyURemInst(Value *LHS, Value *RHS, const SimplifyQuery &Q);
Value *SimplifyURemInst(Value *LHS, Value *RHS, const DataLayout &DL,
const TargetLibraryInfo *TLI = nullptr,
const DominatorTree *DT = nullptr,
@@ -132,6 +172,8 @@ namespace llvm {
/// Given operands for an FRem, fold the result or return null.
Value *SimplifyFRemInst(Value *LHS, Value *RHS, FastMathFlags FMF,
+ const SimplifyQuery &Q);
+ Value *SimplifyFRemInst(Value *LHS, Value *RHS, FastMathFlags FMF,
const DataLayout &DL,
const TargetLibraryInfo *TLI = nullptr,
const DominatorTree *DT = nullptr,
@@ -140,6 +182,8 @@ namespace llvm {
/// Given operands for a Shl, fold the result or return null.
Value *SimplifyShlInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW,
+ const SimplifyQuery &Q);
+ Value *SimplifyShlInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW,
const DataLayout &DL,
const TargetLibraryInfo *TLI = nullptr,
const DominatorTree *DT = nullptr,
@@ -148,6 +192,8 @@ namespace llvm {
/// Given operands for a LShr, fold the result or return null.
Value *SimplifyLShrInst(Value *Op0, Value *Op1, bool isExact,
+ const SimplifyQuery &Q);
+ Value *SimplifyLShrInst(Value *Op0, Value *Op1, bool isExact,
const DataLayout &DL,
const TargetLibraryInfo *TLI = nullptr,
const DominatorTree *DT = nullptr,
@@ -156,6 +202,8 @@ namespace llvm {
/// Given operands for a AShr, fold the result or return nulll.
Value *SimplifyAShrInst(Value *Op0, Value *Op1, bool isExact,
+ const SimplifyQuery &Q);
+ Value *SimplifyAShrInst(Value *Op0, Value *Op1, bool isExact,
const DataLayout &DL,
const TargetLibraryInfo *TLI = nullptr,
const DominatorTree *DT = nullptr,
@@ -163,6 +211,7 @@ namespace llvm {
const Instruction *CxtI = nullptr);
/// Given operands for an And, fold the result or return null.
+ Value *SimplifyAndInst(Value *LHS, Value *RHS, const SimplifyQuery &Q);
Value *SimplifyAndInst(Value *LHS, Value *RHS, const DataLayout &DL,
const TargetLibraryInfo *TLI = nullptr,
const DominatorTree *DT = nullptr,
@@ -170,6 +219,7 @@ namespace llvm {
const Instruction *CxtI = nullptr);
/// Given operands for an Or, fold the result or return null.
+ Value *SimplifyOrInst(Value *LHS, Value *RHS, const SimplifyQuery &Q);
Value *SimplifyOrInst(Value *LHS, Value *RHS, const DataLayout &DL,
const TargetLibraryInfo *TLI = nullptr,
const DominatorTree *DT = nullptr,
@@ -177,6 +227,7 @@ namespace llvm {
const Instruction *CxtI = nullptr);
/// Given operands for an Xor, fold the result or return null.
+ Value *SimplifyXorInst(Value *LHS, Value *RHS, const SimplifyQuery &Q);
Value *SimplifyXorInst(Value *LHS, Value *RHS, const DataLayout &DL,
const TargetLibraryInfo *TLI = nullptr,
const DominatorTree *DT = nullptr,
@@ -185,6 +236,8 @@ namespace llvm {
/// Given operands for an ICmpInst, fold the result or return null.
Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
+ const SimplifyQuery &Q);
+ Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
const DataLayout &DL,
const TargetLibraryInfo *TLI = nullptr,
const DominatorTree *DT = nullptr,
@@ -193,6 +246,8 @@ namespace llvm {
/// Given operands for an FCmpInst, fold the result or return null.
Value *SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
+ FastMathFlags FMF, const SimplifyQuery &Q);
+ Value *SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
FastMathFlags FMF, const DataLayout &DL,
const TargetLibraryInfo *TLI = nullptr,
const DominatorTree *DT = nullptr,
@@ -201,13 +256,17 @@ namespace llvm {
/// Given operands for a SelectInst, fold the result or return null.
Value *SimplifySelectInst(Value *Cond, Value *TrueVal, Value *FalseVal,
+ const SimplifyQuery &Q);
+ Value *SimplifySelectInst(Value *Cond, Value *TrueVal, Value *FalseVal,
const DataLayout &DL,
const TargetLibraryInfo *TLI = nullptr,
const DominatorTree *DT = nullptr,
AssumptionCache *AC = nullptr,
const Instruction *CxtI = nullptr);
- /// Given operands for a GetElementPtrInst, fold the result or return null.
+ /// Given operands for a GetElementPtrInst, fold the result or return null.
+ Value *SimplifyGEPInst(Type *SrcTy, ArrayRef<Value *> Ops,
+ const SimplifyQuery &Q);
Value *SimplifyGEPInst(Type *SrcTy, ArrayRef<Value *> Ops,
const DataLayout &DL,
const TargetLibraryInfo *TLI = nullptr,
@@ -217,6 +276,9 @@ namespace llvm {
/// Given operands for an InsertValueInst, fold the result or return null.
Value *SimplifyInsertValueInst(Value *Agg, Value *Val,
+ ArrayRef<unsigned> Idxs,
+ const SimplifyQuery &Q);
+ Value *SimplifyInsertValueInst(Value *Agg, Value *Val,
ArrayRef<unsigned> Idxs, const DataLayout &DL,
const TargetLibraryInfo *TLI = nullptr,
const DominatorTree *DT = nullptr,
@@ -225,6 +287,8 @@ namespace llvm {
/// Given operands for an ExtractValueInst, fold the result or return null.
Value *SimplifyExtractValueInst(Value *Agg, ArrayRef<unsigned> Idxs,
+ const SimplifyQuery &Q);
+ Value *SimplifyExtractValueInst(Value *Agg, ArrayRef<unsigned> Idxs,
const DataLayout &DL,
const TargetLibraryInfo *TLI = nullptr,
const DominatorTree *DT = nullptr,
@@ -233,6 +297,8 @@ namespace llvm {
/// Given operands for an ExtractElementInst, fold the result or return null.
Value *SimplifyExtractElementInst(Value *Vec, Value *Idx,
+ const SimplifyQuery &Q);
+ Value *SimplifyExtractElementInst(Value *Vec, Value *Idx,
const DataLayout &DL,
const TargetLibraryInfo *TLI = nullptr,
const DominatorTree *DT = nullptr,
@@ -241,6 +307,8 @@ namespace llvm {
/// Given operands for a CastInst, fold the result or return null.
Value *SimplifyCastInst(unsigned CastOpc, Value *Op, Type *Ty,
+ const SimplifyQuery &Q);
+ Value *SimplifyCastInst(unsigned CastOpc, Value *Op, Type *Ty,
const DataLayout &DL,
const TargetLibraryInfo *TLI = nullptr,
const DominatorTree *DT = nullptr,
@@ -249,6 +317,8 @@ namespace llvm {
/// Given operands for a ShuffleVectorInst, fold the result or return null.
Value *SimplifyShuffleVectorInst(Value *Op0, Value *Op1, Constant *Mask,
+ Type *RetTy, const SimplifyQuery &Q);
+ Value *SimplifyShuffleVectorInst(Value *Op0, Value *Op1, Constant *Mask,
Type *RetTy, const DataLayout &DL,
const TargetLibraryInfo *TLI = nullptr,
const DominatorTree *DT = nullptr,
@@ -260,6 +330,8 @@ namespace llvm {
/// Given operands for a CmpInst, fold the result or return null.
Value *SimplifyCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
+ const SimplifyQuery &Q);
+ Value *SimplifyCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
const DataLayout &DL,
const TargetLibraryInfo *TLI = nullptr,
const DominatorTree *DT = nullptr,
@@ -268,6 +340,8 @@ namespace llvm {
/// Given operands for a BinaryOperator, fold the result or return null.
Value *SimplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS,
+ const SimplifyQuery &Q);
+ Value *SimplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS,
const DataLayout &DL,
const TargetLibraryInfo *TLI = nullptr,
const DominatorTree *DT = nullptr,
@@ -278,7 +352,9 @@ namespace llvm {
/// In contrast to SimplifyBinOp, try to use FastMathFlag when folding the
/// result. In case we don't need FastMathFlags, simply fall to SimplifyBinOp.
Value *SimplifyFPBinOp(unsigned Opcode, Value *LHS, Value *RHS,
- const FastMathFlags &FMF, const DataLayout &DL,
+ FastMathFlags FMF, const SimplifyQuery &Q);
+ Value *SimplifyFPBinOp(unsigned Opcode, Value *LHS, Value *RHS,
+ FastMathFlags FMF, const DataLayout &DL,
const TargetLibraryInfo *TLI = nullptr,
const DominatorTree *DT = nullptr,
AssumptionCache *AC = nullptr,
@@ -287,6 +363,8 @@ namespace llvm {
/// Given a function and iterators over arguments, fold the result or return
/// null.
Value *SimplifyCall(Value *V, User::op_iterator ArgBegin,
+ User::op_iterator ArgEnd, const SimplifyQuery &Q);
+ Value *SimplifyCall(Value *V, User::op_iterator ArgBegin,
User::op_iterator ArgEnd, const DataLayout &DL,
const TargetLibraryInfo *TLI = nullptr,
const DominatorTree *DT = nullptr,
@@ -294,6 +372,7 @@ namespace llvm {
const Instruction *CxtI = nullptr);
/// Given a function and set of arguments, fold the result or return null.
+ Value *SimplifyCall(Value *V, ArrayRef<Value *> Args, const SimplifyQuery &Q);
Value *SimplifyCall(Value *V, ArrayRef<Value *> Args, const DataLayout &DL,
const TargetLibraryInfo *TLI = nullptr,
const DominatorTree *DT = nullptr,
@@ -302,6 +381,8 @@ namespace llvm {
/// See if we can compute a simplified version of this instruction. If not,
/// return null.
+ Value *SimplifyInstruction(Instruction *I, const SimplifyQuery &Q,
+ OptimizationRemarkEmitter *ORE = nullptr);
Value *SimplifyInstruction(Instruction *I, const DataLayout &DL,
const TargetLibraryInfo *TLI = nullptr,
const DominatorTree *DT = nullptr,
diff --git a/include/llvm/Analysis/LoopInfo.h b/include/llvm/Analysis/LoopInfo.h
index 2fad1737d1c0..096df1e421a7 100644
--- a/include/llvm/Analysis/LoopInfo.h
+++ b/include/llvm/Analysis/LoopInfo.h
@@ -158,7 +158,7 @@ public:
/// True if terminator in the block can branch to another block that is
/// outside of the current loop.
bool isLoopExiting(const BlockT *BB) const {
- for (const auto Succ : children<const BlockT*>(BB)) {
+ for (const auto &Succ : children<const BlockT*>(BB)) {
if (!contains(Succ))
return true;
}
diff --git a/include/llvm/Analysis/LoopInfoImpl.h b/include/llvm/Analysis/LoopInfoImpl.h
index 6dc0422ce0e9..66c9f68afc60 100644
--- a/include/llvm/Analysis/LoopInfoImpl.h
+++ b/include/llvm/Analysis/LoopInfoImpl.h
@@ -35,7 +35,7 @@ template<class BlockT, class LoopT>
void LoopBase<BlockT, LoopT>::
getExitingBlocks(SmallVectorImpl<BlockT *> &ExitingBlocks) const {
for (const auto BB : blocks())
- for (const auto Succ : children<BlockT*>(BB))
+ for (const auto &Succ : children<BlockT*>(BB))
if (!contains(Succ)) {
// Not in current loop? It must be an exit block.
ExitingBlocks.push_back(BB);
@@ -61,7 +61,7 @@ template<class BlockT, class LoopT>
void LoopBase<BlockT, LoopT>::
getExitBlocks(SmallVectorImpl<BlockT*> &ExitBlocks) const {
for (const auto BB : blocks())
- for (const auto Succ : children<BlockT*>(BB))
+ for (const auto &Succ : children<BlockT*>(BB))
if (!contains(Succ))
// Not in current loop? It must be an exit block.
ExitBlocks.push_back(Succ);
@@ -83,7 +83,7 @@ template<class BlockT, class LoopT>
void LoopBase<BlockT, LoopT>::
getExitEdges(SmallVectorImpl<Edge> &ExitEdges) const {
for (const auto BB : blocks())
- for (const auto Succ : children<BlockT*>(BB))
+ for (const auto &Succ : children<BlockT*>(BB))
if (!contains(Succ))
// Not in current loop? It must be an exit block.
ExitEdges.emplace_back(BB, Succ);
diff --git a/include/llvm/Analysis/RegionInfo.h b/include/llvm/Analysis/RegionInfo.h
index caeb21db613e..16ee07fa3177 100644
--- a/include/llvm/Analysis/RegionInfo.h
+++ b/include/llvm/Analysis/RegionInfo.h
@@ -708,10 +708,24 @@ class RegionInfoBase {
/// The top level region.
RegionT *TopLevelRegion;
-private:
/// Map every BB to the smallest region, that contains BB.
BBtoRegionMap BBtoRegion;
+protected:
+ /// \brief Update refences to a RegionInfoT held by the RegionT managed here
+ ///
+ /// This is a post-move helper. Regions hold references to the owning
+ /// RegionInfo object. After a move these need to be fixed.
+ template<typename TheRegionT>
+ void updateRegionTree(RegionInfoT &RI, TheRegionT *R) {
+ if (!R)
+ return;
+ R->RI = &RI;
+ for (auto &SubR : *R)
+ updateRegionTree(RI, SubR.get());
+ }
+
+private:
/// \brief Wipe this region tree's state without releasing any resources.
///
/// This is essentially a post-move helper only. It leaves the object in an
@@ -879,10 +893,12 @@ public:
~RegionInfo() override;
- RegionInfo(RegionInfo &&Arg)
- : Base(std::move(static_cast<Base &>(Arg))) {}
+ RegionInfo(RegionInfo &&Arg) : Base(std::move(static_cast<Base &>(Arg))) {
+ updateRegionTree(*this, TopLevelRegion);
+ }
RegionInfo &operator=(RegionInfo &&RHS) {
Base::operator=(std::move(static_cast<Base &>(RHS)));
+ updateRegionTree(*this, TopLevelRegion);
return *this;
}
diff --git a/include/llvm/Analysis/ScalarEvolution.h b/include/llvm/Analysis/ScalarEvolution.h
index 91aeae0f728f..54bc4dcfd2cd 100644
--- a/include/llvm/Analysis/ScalarEvolution.h
+++ b/include/llvm/Analysis/ScalarEvolution.h
@@ -877,6 +877,47 @@ private:
bool ControlsExit,
bool AllowPredicates = false);
+ // Helper functions for computeExitLimitFromCond to avoid exponential time
+ // complexity.
+
+ class ExitLimitCache {
+ // It may look like we need key on the whole (L, TBB, FBB, ControlsExit,
+ // AllowPredicates) tuple, but recursive calls to
+ // computeExitLimitFromCondCached from computeExitLimitFromCondImpl only
+ // vary the in \c ExitCond and \c ControlsExit parameters. We remember the
+ // initial values of the other values to assert our assumption.
+ SmallDenseMap<PointerIntPair<Value *, 1>, ExitLimit> TripCountMap;
+
+ const Loop *L;
+ BasicBlock *TBB;
+ BasicBlock *FBB;
+ bool AllowPredicates;
+
+ public:
+ ExitLimitCache(const Loop *L, BasicBlock *TBB, BasicBlock *FBB,
+ bool AllowPredicates)
+ : L(L), TBB(TBB), FBB(FBB), AllowPredicates(AllowPredicates) {}
+
+ Optional<ExitLimit> find(const Loop *L, Value *ExitCond, BasicBlock *TBB,
+ BasicBlock *FBB, bool ControlsExit,
+ bool AllowPredicates);
+
+ void insert(const Loop *L, Value *ExitCond, BasicBlock *TBB,
+ BasicBlock *FBB, bool ControlsExit, bool AllowPredicates,
+ const ExitLimit &EL);
+ };
+
+ typedef ExitLimitCache ExitLimitCacheTy;
+ ExitLimit computeExitLimitFromCondCached(ExitLimitCacheTy &Cache,
+ const Loop *L, Value *ExitCond,
+ BasicBlock *TBB, BasicBlock *FBB,
+ bool ControlsExit,
+ bool AllowPredicates);
+ ExitLimit computeExitLimitFromCondImpl(ExitLimitCacheTy &Cache, const Loop *L,
+ Value *ExitCond, BasicBlock *TBB,
+ BasicBlock *FBB, bool ControlsExit,
+ bool AllowPredicates);
+
/// Compute the number of times the backedge of the specified loop will
/// execute if its exit condition were a conditional branch of the ICmpInst
/// ExitCond, TBB, and FBB. If AllowPredicates is set, this call will try
diff --git a/include/llvm/Analysis/ValueTracking.h b/include/llvm/Analysis/ValueTracking.h
index e3c2f3bed227..764308dceed9 100644
--- a/include/llvm/Analysis/ValueTracking.h
+++ b/include/llvm/Analysis/ValueTracking.h
@@ -29,6 +29,7 @@ template <typename T> class ArrayRef;
class DominatorTree;
class GEPOperator;
class Instruction;
+ struct KnownBits;
class Loop;
class LoopInfo;
class OptimizationRemarkEmitter;
@@ -49,7 +50,7 @@ template <typename T> class ArrayRef;
/// where V is a vector, the known zero and known one values are the
/// same width as the vector element, and the bit is set only if it is true
/// for all of the elements in the vector.
- void computeKnownBits(const Value *V, APInt &KnownZero, APInt &KnownOne,
+ void computeKnownBits(const Value *V, KnownBits &Known,
const DataLayout &DL, unsigned Depth = 0,
AssumptionCache *AC = nullptr,
const Instruction *CxtI = nullptr,
diff --git a/include/llvm/CodeGen/DIE.h b/include/llvm/CodeGen/DIE.h
index 95c4b4248bbd..a40147336fe2 100644
--- a/include/llvm/CodeGen/DIE.h
+++ b/include/llvm/CodeGen/DIE.h
@@ -793,6 +793,9 @@ class DIEUnit {
uint32_t Length; /// The length in bytes of all of the DIEs in this unit.
const uint16_t Version; /// The Dwarf version number for this unit.
const uint8_t AddrSize; /// The size in bytes of an address for this unit.
+protected:
+ ~DIEUnit() = default;
+
public:
DIEUnit(uint16_t Version, uint8_t AddrSize, dwarf::Tag UnitTag);
DIEUnit(const DIEUnit &RHS) = delete;
@@ -808,6 +811,10 @@ public:
this->Section = Section;
}
+ virtual const MCSymbol *getCrossSectionRelativeBaseAddress() const {
+ return nullptr;
+ }
+
/// Return the section that this DIEUnit will be emitted into.
///
/// \returns Section pointer which can be NULL.
@@ -822,7 +829,11 @@ public:
const DIE &getUnitDie() const { return Die; }
};
-
+struct BasicDIEUnit final : DIEUnit {
+ BasicDIEUnit(uint16_t Version, uint8_t AddrSize, dwarf::Tag UnitTag)
+ : DIEUnit(Version, AddrSize, UnitTag) {}
+};
+
//===--------------------------------------------------------------------===//
/// DIELoc - Represents an expression location.
//
diff --git a/include/llvm/CodeGen/GlobalISel/InstructionSelector.h b/include/llvm/CodeGen/GlobalISel/InstructionSelector.h
index 911e8756070b..899563acc330 100644
--- a/include/llvm/CodeGen/GlobalISel/InstructionSelector.h
+++ b/include/llvm/CodeGen/GlobalISel/InstructionSelector.h
@@ -18,20 +18,52 @@
#include "llvm/ADT/Optional.h"
#include <cstdint>
+#include <bitset>
+#include <functional>
namespace llvm {
class MachineInstr;
+class MachineInstrBuilder;
+class MachineFunction;
class MachineOperand;
class MachineRegisterInfo;
class RegisterBankInfo;
class TargetInstrInfo;
class TargetRegisterInfo;
+/// Container class for CodeGen predicate results.
+/// This is convenient because std::bitset does not have a constructor
+/// with an initializer list of set bits.
+///
+/// Each InstructionSelector subclass should define a PredicateBitset class with:
+/// const unsigned MAX_SUBTARGET_PREDICATES = 192;
+/// using PredicateBitset = PredicateBitsetImpl<MAX_SUBTARGET_PREDICATES>;
+/// and updating the constant to suit the target. Tablegen provides a suitable
+/// definition for the predicates in use in <Target>GenGlobalISel.inc when
+/// GET_GLOBALISEL_PREDICATE_BITSET is defined.
+template <std::size_t MaxPredicates>
+class PredicateBitsetImpl : public std::bitset<MaxPredicates> {
+public:
+ // Cannot inherit constructors because it's not supported by VC++..
+ PredicateBitsetImpl() = default;
+
+ PredicateBitsetImpl(const std::bitset<MaxPredicates> &B)
+ : std::bitset<MaxPredicates>(B) {}
+
+ PredicateBitsetImpl(std::initializer_list<unsigned> Init) {
+ for (auto I : Init)
+ std::bitset<MaxPredicates>::set(I);
+ }
+};
+
/// Provides the logic to select generic machine instructions.
class InstructionSelector {
public:
virtual ~InstructionSelector() {}
+ /// This is executed before selecting a function.
+ virtual void beginFunction(const MachineFunction &MF) {}
+
/// Select the (possibly generic) instruction \p I to only use target-specific
/// opcodes. It is OK to insert multiple instructions, but they cannot be
/// generic pre-isel instructions.
@@ -46,6 +78,8 @@ public:
virtual bool select(MachineInstr &I) const = 0;
protected:
+ typedef std::function<void(MachineInstrBuilder &)> ComplexRendererFn;
+
InstructionSelector();
/// Mutate the newly-selected instruction \p I to constrain its (possibly
diff --git a/include/llvm/CodeGen/MachineOperand.h b/include/llvm/CodeGen/MachineOperand.h
index 81b43126adeb..e16354088296 100644
--- a/include/llvm/CodeGen/MachineOperand.h
+++ b/include/llvm/CodeGen/MachineOperand.h
@@ -65,7 +65,6 @@ public:
MO_CFIIndex, ///< MCCFIInstruction index.
MO_IntrinsicID, ///< Intrinsic ID for ISel
MO_Predicate, ///< Generic predicate for ISel
- MO_Placeholder, ///< Placeholder for GlobalISel ComplexPattern result.
};
private:
@@ -768,11 +767,6 @@ public:
return Op;
}
- static MachineOperand CreatePlaceholder() {
- MachineOperand Op(MachineOperand::MO_Placeholder);
- return Op;
- }
-
friend class MachineInstr;
friend class MachineRegisterInfo;
private:
diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h
index 6f0509543e7d..4bb658898fb5 100644
--- a/include/llvm/CodeGen/SelectionDAG.h
+++ b/include/llvm/CodeGen/SelectionDAG.h
@@ -654,6 +654,15 @@ public:
return getNode(ISD::BUILD_VECTOR, DL, VT, Ops);
}
+ /// Return an ISD::BUILD_VECTOR node. The number of elements in VT,
+ /// which must be a vector type, must match the number of operands in Ops.
+ /// The operands must have the same type as (or, for integers, a type wider
+ /// than) VT's element type.
+ SDValue getBuildVector(EVT VT, const SDLoc &DL, ArrayRef<SDUse> Ops) {
+ // VerifySDNode (via InsertNode) checks BUILD_VECTOR later.
+ return getNode(ISD::BUILD_VECTOR, DL, VT, Ops);
+ }
+
/// Return a splat ISD::BUILD_VECTOR node, consisting of Op splatted to all
/// elements. VT must be a vector type. Op's type must be the same as (or,
/// for integers, a type wider than) VT's element type.
@@ -968,7 +977,7 @@ public:
bool IsExpanding = false);
SDValue getMaskedStore(SDValue Chain, const SDLoc &dl, SDValue Val,
SDValue Ptr, SDValue Mask, EVT MemVT,
- MachineMemOperand *MMO, bool IsTruncating = false,
+ MachineMemOperand *MMO, bool IsTruncating = false,
bool IsCompressing = false);
SDValue getMaskedGather(SDVTList VTs, EVT VT, const SDLoc &dl,
ArrayRef<SDValue> Ops, MachineMemOperand *MMO);
diff --git a/include/llvm/DebugInfo/CodeView/CodeView.h b/include/llvm/DebugInfo/CodeView/CodeView.h
index 2791c9dc3746..e599f8a19e34 100644
--- a/include/llvm/DebugInfo/CodeView/CodeView.h
+++ b/include/llvm/DebugInfo/CodeView/CodeView.h
@@ -546,7 +546,7 @@ enum class TrampolineType : uint16_t { TrampIncremental, BranchIsland };
// These values correspond to the CV_SourceChksum_t enumeration.
enum class FileChecksumKind : uint8_t { None, MD5, SHA1, SHA256 };
-enum LineFlags : uint32_t {
+enum LineFlags : uint16_t {
HaveColumns = 1, // CV_LINES_HAVE_COLUMNS
};
}
diff --git a/include/llvm/DebugInfo/CodeView/ModuleSubstreamVisitor.h b/include/llvm/DebugInfo/CodeView/ModuleSubstreamVisitor.h
index 1a40654a3f33..31344a9427db 100644
--- a/include/llvm/DebugInfo/CodeView/ModuleSubstreamVisitor.h
+++ b/include/llvm/DebugInfo/CodeView/ModuleSubstreamVisitor.h
@@ -81,7 +81,7 @@ public:
BinaryStreamReader Reader(Stream);
if (auto EC = Reader.readObject(BlockHeader))
return EC;
- bool HasColumn = Header->Flags & LineFlags::HaveColumns;
+ bool HasColumn = Header->Flags & uint32_t(LineFlags::HaveColumns);
uint32_t LineInfoSize =
BlockHeader->NumLines *
(sizeof(LineNumberEntry) + (HasColumn ? sizeof(ColumnNumberEntry) : 0));
diff --git a/include/llvm/DebugInfo/CodeView/TypeDumperBase.h b/include/llvm/DebugInfo/CodeView/TypeDumperBase.h
deleted file mode 100644
index e69de29bb2d1..000000000000
--- a/include/llvm/DebugInfo/CodeView/TypeDumperBase.h
+++ /dev/null
diff --git a/include/llvm/DebugInfo/DWARF/DWARFCompileUnit.h b/include/llvm/DebugInfo/DWARF/DWARFCompileUnit.h
index b2a4d247ccc6..a46d46a5bff3 100644
--- a/include/llvm/DebugInfo/DWARF/DWARFCompileUnit.h
+++ b/include/llvm/DebugInfo/DWARF/DWARFCompileUnit.h
@@ -18,9 +18,9 @@ namespace llvm {
class DWARFCompileUnit : public DWARFUnit {
public:
DWARFCompileUnit(DWARFContext &Context, const DWARFSection &Section,
- const DWARFDebugAbbrev *DA, StringRef RS, StringRef SS,
- StringRef SOS, StringRef AOS, StringRef LS, bool LE,
- bool IsDWO, const DWARFUnitSectionBase &UnitSection,
+ const DWARFDebugAbbrev *DA, const DWARFSection *RS,
+ StringRef SS, StringRef SOS, StringRef AOS, StringRef LS,
+ bool LE, bool IsDWO, const DWARFUnitSectionBase &UnitSection,
const DWARFUnitIndex::Entry *Entry)
: DWARFUnit(Context, Section, DA, RS, SS, SOS, AOS, LS, LE, IsDWO,
UnitSection, Entry) {}
diff --git a/include/llvm/DebugInfo/DWARF/DWARFContext.h b/include/llvm/DebugInfo/DWARF/DWARFContext.h
index f941cdd1060a..d89e2c684cd3 100644
--- a/include/llvm/DebugInfo/DWARF/DWARFContext.h
+++ b/include/llvm/DebugInfo/DWARF/DWARFContext.h
@@ -50,6 +50,11 @@ class raw_ostream;
// entire size of the debug info sections.
typedef DenseMap<uint64_t, std::pair<uint8_t, int64_t>> RelocAddrMap;
+/// Reads a value from data extractor and applies a relocation to the result if
+/// one exists for the given offset.
+uint64_t getRelocatedValue(const DataExtractor &Data, uint32_t Size,
+ uint32_t *Off, const RelocAddrMap *Relocs);
+
/// DWARFContext
/// This data structure is the top level entity that deals with dwarf debug
/// information parsing. The actual data is supplied through pure virtual
@@ -216,7 +221,7 @@ public:
virtual StringRef getEHFrameSection() = 0;
virtual const DWARFSection &getLineSection() = 0;
virtual StringRef getStringSection() = 0;
- virtual StringRef getRangeSection() = 0;
+ virtual const DWARFSection& getRangeSection() = 0;
virtual StringRef getMacinfoSection() = 0;
virtual StringRef getPubNamesSection() = 0;
virtual StringRef getPubTypesSection() = 0;
@@ -231,7 +236,7 @@ public:
virtual const DWARFSection &getLocDWOSection() = 0;
virtual StringRef getStringDWOSection() = 0;
virtual StringRef getStringOffsetDWOSection() = 0;
- virtual StringRef getRangeDWOSection() = 0;
+ virtual const DWARFSection &getRangeDWOSection() = 0;
virtual StringRef getAddrSection() = 0;
virtual const DWARFSection& getAppleNamesSection() = 0;
virtual const DWARFSection& getAppleTypesSection() = 0;
@@ -271,7 +276,7 @@ class DWARFContextInMemory : public DWARFContext {
StringRef EHFrameSection;
DWARFSection LineSection;
StringRef StringSection;
- StringRef RangeSection;
+ DWARFSection RangeSection;
StringRef MacinfoSection;
StringRef PubNamesSection;
StringRef PubTypesSection;
@@ -286,7 +291,7 @@ class DWARFContextInMemory : public DWARFContext {
DWARFSection LocDWOSection;
StringRef StringDWOSection;
StringRef StringOffsetDWOSection;
- StringRef RangeDWOSection;
+ DWARFSection RangeDWOSection;
StringRef AddrSection;
DWARFSection AppleNamesSection;
DWARFSection AppleTypesSection;
@@ -319,7 +324,7 @@ public:
StringRef getEHFrameSection() override { return EHFrameSection; }
const DWARFSection &getLineSection() override { return LineSection; }
StringRef getStringSection() override { return StringSection; }
- StringRef getRangeSection() override { return RangeSection; }
+ const DWARFSection &getRangeSection() override { return RangeSection; }
StringRef getMacinfoSection() override { return MacinfoSection; }
StringRef getPubNamesSection() override { return PubNamesSection; }
StringRef getPubTypesSection() override { return PubTypesSection; }
@@ -346,7 +351,7 @@ public:
return StringOffsetDWOSection;
}
- StringRef getRangeDWOSection() override { return RangeDWOSection; }
+ const DWARFSection &getRangeDWOSection() override { return RangeDWOSection; }
StringRef getAddrSection() override {
return AddrSection;
diff --git a/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h b/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h
index 018a049a3ed8..9172df5bfac6 100644
--- a/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h
+++ b/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h
@@ -11,6 +11,8 @@
#define LLVM_DEBUGINFO_DWARF_DWARFDEBUGRANGELIST_H
#include "llvm/Support/DataExtractor.h"
+#include "llvm/DebugInfo/DWARF/DWARFRelocMap.h"
+
#include <cassert>
#include <cstdint>
#include <utility>
@@ -71,7 +73,7 @@ public:
void clear();
void dump(raw_ostream &OS) const;
- bool extract(DataExtractor data, uint32_t *offset_ptr);
+ bool extract(DataExtractor data, uint32_t *offset_ptr, const RelocAddrMap& Relocs);
const std::vector<RangeListEntry> &getEntries() { return Entries; }
/// getAbsoluteRanges - Returns absolute address ranges defined by this range
diff --git a/include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h b/include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h
index 703316005887..c9da2c9a3e16 100644
--- a/include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h
+++ b/include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h
@@ -30,9 +30,9 @@ private:
public:
DWARFTypeUnit(DWARFContext &Context, const DWARFSection &Section,
- const DWARFDebugAbbrev *DA, StringRef RS, StringRef SS,
- StringRef SOS, StringRef AOS, StringRef LS, bool LE, bool IsDWO,
- const DWARFUnitSectionBase &UnitSection,
+ const DWARFDebugAbbrev *DA, const DWARFSection *RS,
+ StringRef SS, StringRef SOS, StringRef AOS, StringRef LS,
+ bool LE, bool IsDWO, const DWARFUnitSectionBase &UnitSection,
const DWARFUnitIndex::Entry *Entry)
: DWARFUnit(Context, Section, DA, RS, SS, SOS, AOS, LS, LE, IsDWO,
UnitSection, Entry) {}
diff --git a/include/llvm/DebugInfo/DWARF/DWARFUnit.h b/include/llvm/DebugInfo/DWARF/DWARFUnit.h
index 023a0f7b9fb2..e29ba523238c 100644
--- a/include/llvm/DebugInfo/DWARF/DWARFUnit.h
+++ b/include/llvm/DebugInfo/DWARF/DWARFUnit.h
@@ -56,9 +56,9 @@ protected:
~DWARFUnitSectionBase() = default;
virtual void parseImpl(DWARFContext &Context, const DWARFSection &Section,
- const DWARFDebugAbbrev *DA, StringRef RS, StringRef SS,
- StringRef SOS, StringRef AOS, StringRef LS,
- bool isLittleEndian, bool isDWO) = 0;
+ const DWARFDebugAbbrev *DA, const DWARFSection *RS,
+ StringRef SS, StringRef SOS, StringRef AOS,
+ StringRef LS, bool isLittleEndian, bool isDWO) = 0;
};
const DWARFUnitIndex &getDWARFUnitIndex(DWARFContext &Context,
@@ -88,9 +88,9 @@ public:
private:
void parseImpl(DWARFContext &Context, const DWARFSection &Section,
- const DWARFDebugAbbrev *DA, StringRef RS, StringRef SS,
- StringRef SOS, StringRef AOS, StringRef LS, bool LE,
- bool IsDWO) override {
+ const DWARFDebugAbbrev *DA, const DWARFSection *RS,
+ StringRef SS, StringRef SOS, StringRef AOS, StringRef LS,
+ bool LE, bool IsDWO) override {
if (Parsed)
return;
const auto &Index = getDWARFUnitIndex(Context, UnitType::Section);
@@ -115,7 +115,7 @@ class DWARFUnit {
const DWARFSection &InfoSection;
const DWARFDebugAbbrev *Abbrev;
- StringRef RangeSection;
+ const DWARFSection *RangeSection;
uint32_t RangeSectionBase;
StringRef LineSection;
StringRef StringSection;
@@ -171,7 +171,7 @@ protected:
public:
DWARFUnit(DWARFContext &Context, const DWARFSection &Section,
- const DWARFDebugAbbrev *DA, StringRef RS, StringRef SS,
+ const DWARFDebugAbbrev *DA, const DWARFSection *RS, StringRef SS,
StringRef SOS, StringRef AOS, StringRef LS, bool LE, bool IsDWO,
const DWARFUnitSectionBase &UnitSection,
const DWARFUnitIndex::Entry *IndexEntry = nullptr);
@@ -192,7 +192,7 @@ public:
// Recursively update address to Die map.
void updateAddressDieMap(DWARFDie Die);
- void setRangesSection(StringRef RS, uint32_t Base) {
+ void setRangesSection(const DWARFSection *RS, uint32_t Base) {
RangeSection = RS;
RangeSectionBase = Base;
}
diff --git a/include/llvm/DebugInfo/PDB/DIA/DIARawSymbol.h b/include/llvm/DebugInfo/PDB/DIA/DIARawSymbol.h
index c0633cbdfa52..3710eb29e7f9 100644
--- a/include/llvm/DebugInfo/PDB/DIA/DIARawSymbol.h
+++ b/include/llvm/DebugInfo/PDB/DIA/DIARawSymbol.h
@@ -102,7 +102,8 @@ public:
uint32_t getVirtualBaseDispIndex() const override;
uint32_t getVirtualBaseOffset() const override;
uint32_t getVirtualTableShapeId() const override;
- std::unique_ptr<PDBSymbolTypeVTable> getVirtualBaseTableType() const override;
+ std::unique_ptr<PDBSymbolTypeBuiltin>
+ getVirtualBaseTableType() const override;
PDB_DataKind getDataKind() const override;
PDB_SymType getSymTag() const override;
PDB_UniqueId getGuid() const override;
diff --git a/include/llvm/DebugInfo/PDB/IPDBRawSymbol.h b/include/llvm/DebugInfo/PDB/IPDBRawSymbol.h
index 4c28e194bc70..fab086c62c72 100644
--- a/include/llvm/DebugInfo/PDB/IPDBRawSymbol.h
+++ b/include/llvm/DebugInfo/PDB/IPDBRawSymbol.h
@@ -113,7 +113,7 @@ public:
virtual Variant getValue() const = 0;
virtual uint32_t getVirtualBaseDispIndex() const = 0;
virtual uint32_t getVirtualBaseOffset() const = 0;
- virtual std::unique_ptr<PDBSymbolTypeVTable>
+ virtual std::unique_ptr<PDBSymbolTypeBuiltin>
getVirtualBaseTableType() const = 0;
virtual uint32_t getVirtualTableShapeId() const = 0;
virtual PDB_DataKind getDataKind() const = 0;
diff --git a/include/llvm/DebugInfo/PDB/Native/ModStream.h b/include/llvm/DebugInfo/PDB/Native/ModStream.h
index d65e195dbb95..b12d4ff375f3 100644
--- a/include/llvm/DebugInfo/PDB/Native/ModStream.h
+++ b/include/llvm/DebugInfo/PDB/Native/ModStream.h
@@ -40,6 +40,8 @@ public:
iterator_range<codeview::ModuleSubstreamArray::Iterator>
lines(bool *HadError) const;
+ bool hasLineInfo() const;
+
Error commit();
private:
diff --git a/include/llvm/DebugInfo/PDB/Native/NativeRawSymbol.h b/include/llvm/DebugInfo/PDB/Native/NativeRawSymbol.h
index cffb5d09d225..e1e78035ff38 100644
--- a/include/llvm/DebugInfo/PDB/Native/NativeRawSymbol.h
+++ b/include/llvm/DebugInfo/PDB/Native/NativeRawSymbol.h
@@ -101,7 +101,8 @@ public:
uint32_t getVirtualBaseDispIndex() const override;
uint32_t getVirtualBaseOffset() const override;
uint32_t getVirtualTableShapeId() const override;
- std::unique_ptr<PDBSymbolTypeVTable> getVirtualBaseTableType() const override;
+ std::unique_ptr<PDBSymbolTypeBuiltin>
+ getVirtualBaseTableType() const override;
PDB_DataKind getDataKind() const override;
PDB_SymType getSymTag() const override;
PDB_UniqueId getGuid() const override;
diff --git a/include/llvm/DebugInfo/PDB/UDTLayout.h b/include/llvm/DebugInfo/PDB/UDTLayout.h
index e3dcba50bd1a..6bc3660fbe51 100644
--- a/include/llvm/DebugInfo/PDB/UDTLayout.h
+++ b/include/llvm/DebugInfo/PDB/UDTLayout.h
@@ -15,6 +15,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/BitVector.h"
+#include "llvm/ADT/DenseMap.h"
#include <list>
#include <memory>
@@ -32,40 +33,63 @@ class PDBSymbolTypeVTable;
class ClassLayout;
class BaseClassLayout;
-class StorageItemBase;
+class LayoutItemBase;
class UDTLayoutBase;
-class StorageItemBase {
+class LayoutItemBase {
public:
- StorageItemBase(const UDTLayoutBase &Parent, const PDBSymbol &Symbol,
- const std::string &Name, uint32_t OffsetInParent,
- uint32_t Size);
- virtual ~StorageItemBase() {}
+ LayoutItemBase(const UDTLayoutBase *Parent, const PDBSymbol *Symbol,
+ const std::string &Name, uint32_t OffsetInParent,
+ uint32_t Size, bool IsElided);
+ virtual ~LayoutItemBase() {}
- virtual uint32_t deepPaddingSize() const;
+ uint32_t deepPaddingSize() const;
+ virtual uint32_t immediatePadding() const { return 0; }
+ virtual uint32_t tailPadding() const;
- const UDTLayoutBase &getParent() const { return Parent; }
+ const UDTLayoutBase *getParent() const { return Parent; }
StringRef getName() const { return Name; }
uint32_t getOffsetInParent() const { return OffsetInParent; }
uint32_t getSize() const { return SizeOf; }
- const PDBSymbol &getSymbol() const { return Symbol; }
+ uint32_t getLayoutSize() const { return LayoutSize; }
+ const PDBSymbol *getSymbol() const { return Symbol; }
+ const BitVector &usedBytes() const { return UsedBytes; }
+ bool isElided() const { return IsElided; }
+ virtual bool isVBPtr() const { return false; }
+
+ uint32_t containsOffset(uint32_t Off) const {
+ uint32_t Begin = getOffsetInParent();
+ uint32_t End = Begin + getSize();
+ return (Off >= Begin && Off < End);
+ }
protected:
- const UDTLayoutBase &Parent;
- const PDBSymbol &Symbol;
+ const PDBSymbol *Symbol = nullptr;
+ const UDTLayoutBase *Parent = nullptr;
BitVector UsedBytes;
std::string Name;
uint32_t OffsetInParent = 0;
uint32_t SizeOf = 0;
+ uint32_t LayoutSize = 0;
+ bool IsElided = false;
+};
+
+class VBPtrLayoutItem : public LayoutItemBase {
+public:
+ VBPtrLayoutItem(const UDTLayoutBase &Parent,
+ std::unique_ptr<PDBSymbolTypeBuiltin> Sym, uint32_t Offset,
+ uint32_t Size);
+ virtual bool isVBPtr() const { return true; }
+
+private:
+ std::unique_ptr<PDBSymbolTypeBuiltin> Type;
};
-class DataMemberLayoutItem : public StorageItemBase {
+class DataMemberLayoutItem : public LayoutItemBase {
public:
DataMemberLayoutItem(const UDTLayoutBase &Parent,
std::unique_ptr<PDBSymbolData> DataMember);
- virtual uint32_t deepPaddingSize() const;
-
const PDBSymbolData &getDataMember();
bool hasUDTLayout() const;
const ClassLayout &getUDTLayout() const;
@@ -75,77 +99,73 @@ private:
std::unique_ptr<ClassLayout> UdtLayout;
};
-class VTableLayoutItem : public StorageItemBase {
+class VTableLayoutItem : public LayoutItemBase {
public:
VTableLayoutItem(const UDTLayoutBase &Parent,
std::unique_ptr<PDBSymbolTypeVTable> VTable);
- ArrayRef<PDBSymbolFunc *> funcs() const { return VTableFuncs; }
uint32_t getElementSize() const { return ElementSize; }
- void setFunction(uint32_t Index, PDBSymbolFunc &Func) {
- VTableFuncs[Index] = &Func;
- }
-
private:
uint32_t ElementSize = 0;
- std::unique_ptr<PDBSymbolTypeVTableShape> Shape;
std::unique_ptr<PDBSymbolTypeVTable> VTable;
- std::vector<PDBSymbolFunc *> VTableFuncs;
};
-class UDTLayoutBase {
+class UDTLayoutBase : public LayoutItemBase {
template <typename T> using UniquePtrVector = std::vector<std::unique_ptr<T>>;
public:
- UDTLayoutBase(const PDBSymbol &Symbol, const std::string &Name,
- uint32_t Size);
-
- uint32_t shallowPaddingSize() const;
- uint32_t deepPaddingSize() const;
-
- const BitVector &usedBytes() const { return UsedBytes; }
+ UDTLayoutBase(const UDTLayoutBase *Parent, const PDBSymbol &Sym,
+ const std::string &Name, uint32_t OffsetInParent, uint32_t Size,
+ bool IsElided);
- uint32_t getClassSize() const { return SizeOf; }
+ uint32_t tailPadding() const override;
- ArrayRef<std::unique_ptr<StorageItemBase>> layout_items() const {
- return ChildStorage;
- }
-
- VTableLayoutItem *findVTableAtOffset(uint32_t RelativeOffset);
+ ArrayRef<LayoutItemBase *> layout_items() const { return LayoutItems; }
- StringRef getUDTName() const { return Name; }
+ ArrayRef<BaseClassLayout *> bases() const { return AllBases; }
+ ArrayRef<BaseClassLayout *> regular_bases() const { return NonVirtualBases; }
+ ArrayRef<BaseClassLayout *> virtual_bases() const { return VirtualBases; }
- ArrayRef<BaseClassLayout *> bases() const { return BaseClasses; }
- ArrayRef<std::unique_ptr<PDBSymbolTypeBaseClass>> vbases() const {
- return VirtualBases;
- }
+ uint32_t directVirtualBaseCount() const { return DirectVBaseCount; }
ArrayRef<std::unique_ptr<PDBSymbolFunc>> funcs() const { return Funcs; }
ArrayRef<std::unique_ptr<PDBSymbol>> other_items() const { return Other; }
- const PDBSymbol &getSymbolBase() const { return SymbolBase; }
-
protected:
+ bool hasVBPtrAtOffset(uint32_t Off) const;
void initializeChildren(const PDBSymbol &Sym);
- void addChildToLayout(std::unique_ptr<StorageItemBase> Child);
- void addVirtualOverride(PDBSymbolFunc &Func);
- void addVirtualIntro(PDBSymbolFunc &Func);
+ void addChildToLayout(std::unique_ptr<LayoutItemBase> Child);
- const PDBSymbol &SymbolBase;
- std::string Name;
- uint32_t SizeOf = 0;
+ uint32_t DirectVBaseCount = 0;
- BitVector UsedBytes;
UniquePtrVector<PDBSymbol> Other;
UniquePtrVector<PDBSymbolFunc> Funcs;
- UniquePtrVector<PDBSymbolTypeBaseClass> VirtualBases;
- UniquePtrVector<StorageItemBase> ChildStorage;
- std::vector<std::list<StorageItemBase *>> ChildrenPerByte;
- std::vector<BaseClassLayout *> BaseClasses;
+ UniquePtrVector<LayoutItemBase> ChildStorage;
+ std::vector<LayoutItemBase *> LayoutItems;
+
+ std::vector<BaseClassLayout *> AllBases;
+ ArrayRef<BaseClassLayout *> NonVirtualBases;
+ ArrayRef<BaseClassLayout *> VirtualBases;
+
VTableLayoutItem *VTable = nullptr;
+ VBPtrLayoutItem *VBPtr = nullptr;
+};
+
+class BaseClassLayout : public UDTLayoutBase {
+public:
+ BaseClassLayout(const UDTLayoutBase &Parent, uint32_t OffsetInParent,
+ bool Elide, std::unique_ptr<PDBSymbolTypeBaseClass> Base);
+
+ const PDBSymbolTypeBaseClass &getBase() const { return *Base; }
+ bool isVirtualBase() const { return IsVirtualBase; }
+ bool isEmptyBase() { return SizeOf == 1 && LayoutSize == 0; }
+
+private:
+ std::unique_ptr<PDBSymbolTypeBaseClass> Base;
+ bool IsVirtualBase;
};
class ClassLayout : public UDTLayoutBase {
@@ -156,24 +176,13 @@ public:
ClassLayout(ClassLayout &&Other) = default;
const PDBSymbolTypeUDT &getClass() const { return UDT; }
+ uint32_t immediatePadding() const override;
private:
+ BitVector ImmediateUsedBytes;
std::unique_ptr<PDBSymbolTypeUDT> OwnedStorage;
const PDBSymbolTypeUDT &UDT;
};
-
-class BaseClassLayout : public UDTLayoutBase, public StorageItemBase {
-public:
- BaseClassLayout(const UDTLayoutBase &Parent,
- std::unique_ptr<PDBSymbolTypeBaseClass> Base);
-
- const PDBSymbolTypeBaseClass &getBase() const { return *Base; }
- bool isVirtualBase() const { return IsVirtualBase; }
-
-private:
- std::unique_ptr<PDBSymbolTypeBaseClass> Base;
- bool IsVirtualBase;
-};
}
} // namespace llvm
diff --git a/include/llvm/ExecutionEngine/Orc/RPCSerialization.h b/include/llvm/ExecutionEngine/Orc/RPCSerialization.h
index 84a037b2f998..a3be242b4457 100644
--- a/include/llvm/ExecutionEngine/Orc/RPCSerialization.h
+++ b/include/llvm/ExecutionEngine/Orc/RPCSerialization.h
@@ -348,7 +348,7 @@ public:
// key of the deserializers map to save us from duplicating the string in
// the serializer. This should be changed to use a stringpool if we switch
// to a map type that may move keys in memory.
- std::lock_guard<std::mutex> Lock(DeserializersMutex);
+ std::lock_guard<std::recursive_mutex> Lock(DeserializersMutex);
auto I =
Deserializers.insert(Deserializers.begin(),
std::make_pair(std::move(Name),
@@ -358,7 +358,7 @@ public:
{
assert(KeyName != nullptr && "No keyname pointer");
- std::lock_guard<std::mutex> Lock(SerializersMutex);
+ std::lock_guard<std::recursive_mutex> Lock(SerializersMutex);
// FIXME: Move capture Serialize once we have C++14.
Serializers[ErrorInfoT::classID()] =
[KeyName, Serialize](ChannelT &C, const ErrorInfoBase &EIB) -> Error {
@@ -372,7 +372,8 @@ public:
}
static Error serialize(ChannelT &C, Error &&Err) {
- std::lock_guard<std::mutex> Lock(SerializersMutex);
+ std::lock_guard<std::recursive_mutex> Lock(SerializersMutex);
+
if (!Err)
return serializeSeq(C, std::string());
@@ -386,7 +387,7 @@ public:
}
static Error deserialize(ChannelT &C, Error &Err) {
- std::lock_guard<std::mutex> Lock(DeserializersMutex);
+ std::lock_guard<std::recursive_mutex> Lock(DeserializersMutex);
std::string Key;
if (auto Err = deserializeSeq(C, Key))
@@ -406,8 +407,6 @@ public:
private:
static Error serializeAsStringError(ChannelT &C, const ErrorInfoBase &EIB) {
- assert(EIB.dynamicClassID() != StringError::classID() &&
- "StringError serialization not registered");
std::string ErrMsg;
{
raw_string_ostream ErrMsgStream(ErrMsg);
@@ -417,17 +416,17 @@ private:
inconvertibleErrorCode()));
}
- static std::mutex SerializersMutex;
- static std::mutex DeserializersMutex;
+ static std::recursive_mutex SerializersMutex;
+ static std::recursive_mutex DeserializersMutex;
static std::map<const void*, WrappedErrorSerializer> Serializers;
static std::map<std::string, WrappedErrorDeserializer> Deserializers;
};
template <typename ChannelT>
-std::mutex SerializationTraits<ChannelT, Error>::SerializersMutex;
+std::recursive_mutex SerializationTraits<ChannelT, Error>::SerializersMutex;
template <typename ChannelT>
-std::mutex SerializationTraits<ChannelT, Error>::DeserializersMutex;
+std::recursive_mutex SerializationTraits<ChannelT, Error>::DeserializersMutex;
template <typename ChannelT>
std::map<const void*,
@@ -439,27 +438,39 @@ std::map<std::string,
typename SerializationTraits<ChannelT, Error>::WrappedErrorDeserializer>
SerializationTraits<ChannelT, Error>::Deserializers;
+/// Registers a serializer and deserializer for the given error type on the
+/// given channel type.
+template <typename ChannelT, typename ErrorInfoT, typename SerializeFtor,
+ typename DeserializeFtor>
+void registerErrorSerialization(std::string Name, SerializeFtor &&Serialize,
+ DeserializeFtor &&Deserialize) {
+ SerializationTraits<ChannelT, Error>::template registerErrorType<ErrorInfoT>(
+ std::move(Name),
+ std::forward<SerializeFtor>(Serialize),
+ std::forward<DeserializeFtor>(Deserialize));
+}
+
+/// Registers serialization/deserialization for StringError.
template <typename ChannelT>
void registerStringError() {
static bool AlreadyRegistered = false;
if (!AlreadyRegistered) {
- SerializationTraits<ChannelT, Error>::
- template registerErrorType<StringError>(
- "StringError",
- [](ChannelT &C, const StringError &SE) {
- return serializeSeq(C, SE.getMessage());
- },
- [](ChannelT &C, Error &Err) {
- ErrorAsOutParameter EAO(&Err);
- std::string Msg;
- if (auto E2 = deserializeSeq(C, Msg))
- return E2;
- Err =
- make_error<StringError>(std::move(Msg),
- orcError(
- OrcErrorCode::UnknownErrorCodeFromRemote));
- return Error::success();
- });
+ registerErrorSerialization<ChannelT, StringError>(
+ "StringError",
+ [](ChannelT &C, const StringError &SE) {
+ return serializeSeq(C, SE.getMessage());
+ },
+ [](ChannelT &C, Error &Err) -> Error {
+ ErrorAsOutParameter EAO(&Err);
+ std::string Msg;
+ if (auto E2 = deserializeSeq(C, Msg))
+ return E2;
+ Err =
+ make_error<StringError>(std::move(Msg),
+ orcError(
+ OrcErrorCode::UnknownErrorCodeFromRemote));
+ return Error::success();
+ });
AlreadyRegistered = true;
}
}
diff --git a/include/llvm/IR/Attributes.h b/include/llvm/IR/Attributes.h
index b13f197d25fd..e2cd4c236fcc 100644
--- a/include/llvm/IR/Attributes.h
+++ b/include/llvm/IR/Attributes.h
@@ -509,7 +509,7 @@ public:
unsigned getSlotIndex(unsigned Slot) const;
/// \brief Return the attributes at the given slot.
- AttributeList getSlotAttributes(unsigned Slot) const;
+ AttributeSet getSlotAttributes(unsigned Slot) const;
void dump() const;
};
diff --git a/include/llvm/IR/ConstantRange.h b/include/llvm/IR/ConstantRange.h
index 47004e82cc19..fd7f96abb19e 100644
--- a/include/llvm/IR/ConstantRange.h
+++ b/include/llvm/IR/ConstantRange.h
@@ -93,7 +93,7 @@ public:
///
/// NB! The returned set does *not* contain **all** possible values of X for
/// which "X BinOpC Y" does not wrap -- some viable values of X may be
- /// missing, so you cannot use this to contrain X's range. E.g. in the last
+ /// missing, so you cannot use this to constrain X's range. E.g. in the last
/// example, "(-2) + 1" is both nsw and nuw (so the "X" could be -2), but (-2)
/// is not in the set returned.
///
diff --git a/include/llvm/IR/Dominators.h b/include/llvm/IR/Dominators.h
index cae03d33a7ee..8f6c85f53efc 100644
--- a/include/llvm/IR/Dominators.h
+++ b/include/llvm/IR/Dominators.h
@@ -157,6 +157,10 @@ public:
/// This should only be used for debugging as it aborts the program if the
/// verification fails.
void verifyDomTree() const;
+
+ // Pop up a GraphViz/gv window with the Dominator Tree rendered using `dot`.
+ void viewGraph(const Twine &Name, const Twine &Title);
+ void viewGraph();
};
//===-------------------------------------
diff --git a/include/llvm/IR/IntrinsicsAMDGPU.td b/include/llvm/IR/IntrinsicsAMDGPU.td
index 5415c6b0d151..21d8a15e7e7a 100644
--- a/include/llvm/IR/IntrinsicsAMDGPU.td
+++ b/include/llvm/IR/IntrinsicsAMDGPU.td
@@ -629,6 +629,8 @@ def int_amdgcn_readfirstlane :
GCCBuiltin<"__builtin_amdgcn_readfirstlane">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrNoMem, IntrConvergent]>;
+// The lane argument must be uniform across the currently active threads of the
+// current wave. Otherwise, the result is undefined.
def int_amdgcn_readlane :
GCCBuiltin<"__builtin_amdgcn_readlane">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem, IntrConvergent]>;
diff --git a/include/llvm/IR/Module.h b/include/llvm/IR/Module.h
index 70c57cf90add..67c35cd22b34 100644
--- a/include/llvm/IR/Module.h
+++ b/include/llvm/IR/Module.h
@@ -319,7 +319,7 @@ public:
/// exist, add a prototype for the function and return it. This function
/// guarantees to return a constant of pointer to the specified function type
/// or a ConstantExpr BitCast of that type if the named function has a
- /// different type. This version of the method takes a null terminated list of
+ /// different type. This version of the method takes a list of
/// function arguments, which makes it easier for clients to use.
template<typename... ArgsTy>
Constant *getOrInsertFunction(StringRef Name,
diff --git a/include/llvm/IR/Value.h b/include/llvm/IR/Value.h
index a4b48d7f3539..00f821399257 100644
--- a/include/llvm/IR/Value.h
+++ b/include/llvm/IR/Value.h
@@ -482,6 +482,17 @@ public:
static_cast<const Value *>(this)->stripPointerCasts());
}
+ /// \brief Strip off pointer casts, all-zero GEPs, aliases and barriers.
+ ///
+ /// Returns the original uncasted value. If this is called on a non-pointer
+ /// value, it returns 'this'. This function should be used only in
+ /// Alias analysis.
+ const Value *stripPointerCastsAndBarriers() const;
+ Value *stripPointerCastsAndBarriers() {
+ return const_cast<Value *>(
+ static_cast<const Value *>(this)->stripPointerCastsAndBarriers());
+ }
+
/// \brief Strip off pointer casts and all-zero GEPs.
///
/// Returns the original uncasted value. If this is called on a non-pointer
diff --git a/include/llvm/MC/MCTargetOptions.h b/include/llvm/MC/MCTargetOptions.h
index 06f58d498030..ab027ab27a41 100644
--- a/include/llvm/MC/MCTargetOptions.h
+++ b/include/llvm/MC/MCTargetOptions.h
@@ -54,6 +54,7 @@ public:
int DwarfVersion = 0;
std::string ABIName;
+ std::string SplitDwarfFile;
/// Additional paths to search for `.include` directives when using the
/// integrated assembler.
diff --git a/include/llvm/Object/ELF.h b/include/llvm/Object/ELF.h
index 7a3155b3953e..9c72bd4023d8 100644
--- a/include/llvm/Object/ELF.h
+++ b/include/llvm/Object/ELF.h
@@ -14,9 +14,19 @@
#ifndef LLVM_OBJECT_ELF_H
#define LLVM_OBJECT_ELF_H
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/Object/ELFTypes.h"
-#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Object/Error.h"
+#include "llvm/Support/ELF.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
+#include <limits>
+#include <utility>
namespace llvm {
namespace object {
@@ -41,27 +51,27 @@ template <class ELFT>
class ELFFile {
public:
LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
- typedef typename ELFT::uint uintX_t;
- typedef typename ELFT::Ehdr Elf_Ehdr;
- typedef typename ELFT::Shdr Elf_Shdr;
- typedef typename ELFT::Sym Elf_Sym;
- typedef typename ELFT::Dyn Elf_Dyn;
- typedef typename ELFT::Phdr Elf_Phdr;
- typedef typename ELFT::Rel Elf_Rel;
- typedef typename ELFT::Rela Elf_Rela;
- typedef typename ELFT::Verdef Elf_Verdef;
- typedef typename ELFT::Verdaux Elf_Verdaux;
- typedef typename ELFT::Verneed Elf_Verneed;
- typedef typename ELFT::Vernaux Elf_Vernaux;
- typedef typename ELFT::Versym Elf_Versym;
- typedef typename ELFT::Hash Elf_Hash;
- typedef typename ELFT::GnuHash Elf_GnuHash;
- typedef typename ELFT::DynRange Elf_Dyn_Range;
- typedef typename ELFT::ShdrRange Elf_Shdr_Range;
- typedef typename ELFT::SymRange Elf_Sym_Range;
- typedef typename ELFT::RelRange Elf_Rel_Range;
- typedef typename ELFT::RelaRange Elf_Rela_Range;
- typedef typename ELFT::PhdrRange Elf_Phdr_Range;
+ using uintX_t = typename ELFT::uint;
+ using Elf_Ehdr = typename ELFT::Ehdr;
+ using Elf_Shdr = typename ELFT::Shdr;
+ using Elf_Sym = typename ELFT::Sym;
+ using Elf_Dyn = typename ELFT::Dyn;
+ using Elf_Phdr = typename ELFT::Phdr;
+ using Elf_Rel = typename ELFT::Rel;
+ using Elf_Rela = typename ELFT::Rela;
+ using Elf_Verdef = typename ELFT::Verdef;
+ using Elf_Verdaux = typename ELFT::Verdaux;
+ using Elf_Verneed = typename ELFT::Verneed;
+ using Elf_Vernaux = typename ELFT::Vernaux;
+ using Elf_Versym = typename ELFT::Versym;
+ using Elf_Hash = typename ELFT::Hash;
+ using Elf_GnuHash = typename ELFT::GnuHash;
+ using Elf_Dyn_Range = typename ELFT::DynRange;
+ using Elf_Shdr_Range = typename ELFT::ShdrRange;
+ using Elf_Sym_Range = typename ELFT::SymRange;
+ using Elf_Rel_Range = typename ELFT::RelRange;
+ using Elf_Rela_Range = typename ELFT::RelaRange;
+ using Elf_Phdr_Range = typename ELFT::PhdrRange;
const uint8_t *base() const {
return reinterpret_cast<const uint8_t *>(Buf.data());
@@ -70,7 +80,6 @@ public:
size_t getBufSize() const { return Buf.size(); }
private:
-
StringRef Buf;
public:
@@ -161,10 +170,10 @@ public:
Expected<ArrayRef<uint8_t>> getSectionContents(const Elf_Shdr *Sec) const;
};
-typedef ELFFile<ELFType<support::little, false>> ELF32LEFile;
-typedef ELFFile<ELFType<support::little, true>> ELF64LEFile;
-typedef ELFFile<ELFType<support::big, false>> ELF32BEFile;
-typedef ELFFile<ELFType<support::big, true>> ELF64BEFile;
+using ELF32LEFile = ELFFile<ELFType<support::little, false>>;
+using ELF64LEFile = ELFFile<ELFType<support::little, true>>;
+using ELF32BEFile = ELFFile<ELFType<support::big, false>>;
+using ELF64BEFile = ELFFile<ELFType<support::big, true>>;
template <class ELFT>
inline Expected<const typename ELFT::Shdr *>
@@ -194,7 +203,7 @@ ELFFile<ELFT>::getSectionIndex(const Elf_Sym *Sym, Elf_Sym_Range Syms,
ArrayRef<Elf_Word> ShndxTable) const {
uint32_t Index = Sym->st_shndx;
if (Index == ELF::SHN_XINDEX) {
- auto ErrorOrIndex = object::getExtendedSymbolTableIndex<ELFT>(
+ auto ErrorOrIndex = getExtendedSymbolTableIndex<ELFT>(
Sym, Syms.begin(), ShndxTable);
if (!ErrorOrIndex)
return ErrorOrIndex.takeError();
@@ -519,7 +528,8 @@ inline unsigned hashSysV(StringRef SymbolName) {
}
return h;
}
+
} // end namespace object
} // end namespace llvm
-#endif
+#endif // LLVM_OBJECT_ELF_H
diff --git a/include/llvm/Object/ELFObjectFile.h b/include/llvm/Object/ELFObjectFile.h
index 9e95f2958aa4..d8b58b8079fa 100644
--- a/include/llvm/Object/ELFObjectFile.h
+++ b/include/llvm/Object/ELFObjectFile.h
@@ -27,6 +27,7 @@
#include "llvm/Object/ObjectFile.h"
#include "llvm/Object/SymbolicFile.h"
#include "llvm/Support/ARMAttributeParser.h"
+#include "llvm/Support/ARMBuildAttributes.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/ELF.h"
#include "llvm/Support/Endian.h"
@@ -42,13 +43,11 @@ namespace llvm {
namespace object {
class elf_symbol_iterator;
-class ELFSymbolRef;
-class ELFRelocationRef;
class ELFObjectFileBase : public ObjectFile {
- friend class ELFSymbolRef;
- friend class ELFSectionRef;
friend class ELFRelocationRef;
+ friend class ELFSectionRef;
+ friend class ELFSymbolRef;
protected:
ELFObjectFileBase(unsigned int Type, MemoryBufferRef Source);
@@ -65,7 +64,8 @@ protected:
virtual ErrorOr<int64_t> getRelocationAddend(DataRefImpl Rel) const = 0;
public:
- typedef iterator_range<elf_symbol_iterator> elf_symbol_iterator_range;
+ using elf_symbol_iterator_range = iterator_range<elf_symbol_iterator>;
+
virtual elf_symbol_iterator_range getDynamicSymbolIterators() const = 0;
elf_symbol_iterator_range symbols() const;
@@ -201,14 +201,14 @@ template <class ELFT> class ELFObjectFile : public ELFObjectFileBase {
public:
LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
- typedef typename ELFFile<ELFT>::uintX_t uintX_t;
+ using uintX_t = typename ELFFile<ELFT>::uintX_t;
- typedef typename ELFFile<ELFT>::Elf_Sym Elf_Sym;
- typedef typename ELFFile<ELFT>::Elf_Shdr Elf_Shdr;
- typedef typename ELFFile<ELFT>::Elf_Ehdr Elf_Ehdr;
- typedef typename ELFFile<ELFT>::Elf_Rel Elf_Rel;
- typedef typename ELFFile<ELFT>::Elf_Rela Elf_Rela;
- typedef typename ELFFile<ELFT>::Elf_Dyn Elf_Dyn;
+ using Elf_Sym = typename ELFFile<ELFT>::Elf_Sym;
+ using Elf_Shdr = typename ELFFile<ELFT>::Elf_Shdr;
+ using Elf_Ehdr = typename ELFFile<ELFT>::Elf_Ehdr;
+ using Elf_Rel = typename ELFFile<ELFT>::Elf_Rel;
+ using Elf_Rela = typename ELFFile<ELFT>::Elf_Rela;
+ using Elf_Dyn = typename ELFFile<ELFT>::Elf_Dyn;
protected:
ELFFile<ELFT> EF;
@@ -398,10 +398,10 @@ public:
bool isRelocatableObject() const override;
};
-typedef ELFObjectFile<ELFType<support::little, false>> ELF32LEObjectFile;
-typedef ELFObjectFile<ELFType<support::little, true>> ELF64LEObjectFile;
-typedef ELFObjectFile<ELFType<support::big, false>> ELF32BEObjectFile;
-typedef ELFObjectFile<ELFType<support::big, true>> ELF64BEObjectFile;
+using ELF32LEObjectFile = ELFObjectFile<ELFType<support::little, false>>;
+using ELF64LEObjectFile = ELFObjectFile<ELFType<support::little, true>>;
+using ELF32BEObjectFile = ELFObjectFile<ELFType<support::big, false>>;
+using ELF64BEObjectFile = ELFObjectFile<ELFType<support::big, true>>;
template <class ELFT>
void ELFObjectFile<ELFT>::moveSymbolNext(DataRefImpl &Sym) const {
diff --git a/include/llvm/Object/ELFTypes.h b/include/llvm/Object/ELFTypes.h
index 3e03fd8b980e..99346fe1a882 100644
--- a/include/llvm/Object/ELFTypes.h
+++ b/include/llvm/Object/ELFTypes.h
@@ -11,10 +11,15 @@
#define LLVM_OBJECT_ELFTYPES_H
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/Object/Error.h"
#include "llvm/Support/ELF.h"
#include "llvm/Support/Endian.h"
-#include "llvm/Support/ErrorOr.h"
+#include "llvm/Support/Error.h"
+#include <cassert>
+#include <cstdint>
+#include <cstring>
+#include <type_traits>
namespace llvm {
namespace object {
@@ -45,58 +50,58 @@ public:
static const endianness TargetEndianness = E;
static const bool Is64Bits = Is64;
- typedef typename std::conditional<Is64, uint64_t, uint32_t>::type uint;
- typedef Elf_Ehdr_Impl<ELFType<E, Is64>> Ehdr;
- typedef Elf_Shdr_Impl<ELFType<E, Is64>> Shdr;
- typedef Elf_Sym_Impl<ELFType<E, Is64>> Sym;
- typedef Elf_Dyn_Impl<ELFType<E, Is64>> Dyn;
- typedef Elf_Phdr_Impl<ELFType<E, Is64>> Phdr;
- typedef Elf_Rel_Impl<ELFType<E, Is64>, false> Rel;
- typedef Elf_Rel_Impl<ELFType<E, Is64>, true> Rela;
- typedef Elf_Verdef_Impl<ELFType<E, Is64>> Verdef;
- typedef Elf_Verdaux_Impl<ELFType<E, Is64>> Verdaux;
- typedef Elf_Verneed_Impl<ELFType<E, Is64>> Verneed;
- typedef Elf_Vernaux_Impl<ELFType<E, Is64>> Vernaux;
- typedef Elf_Versym_Impl<ELFType<E, Is64>> Versym;
- typedef Elf_Hash_Impl<ELFType<E, Is64>> Hash;
- typedef Elf_GnuHash_Impl<ELFType<E, Is64>> GnuHash;
- typedef Elf_Chdr_Impl<ELFType<E, Is64>> Chdr;
- typedef ArrayRef<Dyn> DynRange;
- typedef ArrayRef<Shdr> ShdrRange;
- typedef ArrayRef<Sym> SymRange;
- typedef ArrayRef<Rel> RelRange;
- typedef ArrayRef<Rela> RelaRange;
- typedef ArrayRef<Phdr> PhdrRange;
-
- typedef packed<uint16_t> Half;
- typedef packed<uint32_t> Word;
- typedef packed<int32_t> Sword;
- typedef packed<uint64_t> Xword;
- typedef packed<int64_t> Sxword;
- typedef packed<uint> Addr;
- typedef packed<uint> Off;
-};
-
-typedef ELFType<support::little, false> ELF32LE;
-typedef ELFType<support::big, false> ELF32BE;
-typedef ELFType<support::little, true> ELF64LE;
-typedef ELFType<support::big, true> ELF64BE;
+ using uint = typename std::conditional<Is64, uint64_t, uint32_t>::type;
+ using Ehdr = Elf_Ehdr_Impl<ELFType<E, Is64>>;
+ using Shdr = Elf_Shdr_Impl<ELFType<E, Is64>>;
+ using Sym = Elf_Sym_Impl<ELFType<E, Is64>>;
+ using Dyn = Elf_Dyn_Impl<ELFType<E, Is64>>;
+ using Phdr = Elf_Phdr_Impl<ELFType<E, Is64>>;
+ using Rel = Elf_Rel_Impl<ELFType<E, Is64>, false>;
+ using Rela = Elf_Rel_Impl<ELFType<E, Is64>, true>;
+ using Verdef = Elf_Verdef_Impl<ELFType<E, Is64>>;
+ using Verdaux = Elf_Verdaux_Impl<ELFType<E, Is64>>;
+ using Verneed = Elf_Verneed_Impl<ELFType<E, Is64>>;
+ using Vernaux = Elf_Vernaux_Impl<ELFType<E, Is64>>;
+ using Versym = Elf_Versym_Impl<ELFType<E, Is64>>;
+ using Hash = Elf_Hash_Impl<ELFType<E, Is64>>;
+ using GnuHash = Elf_GnuHash_Impl<ELFType<E, Is64>>;
+ using Chdr = Elf_Chdr_Impl<ELFType<E, Is64>>;
+ using DynRange = ArrayRef<Dyn>;
+ using ShdrRange = ArrayRef<Shdr>;
+ using SymRange = ArrayRef<Sym>;
+ using RelRange = ArrayRef<Rel>;
+ using RelaRange = ArrayRef<Rela>;
+ using PhdrRange = ArrayRef<Phdr>;
+
+ using Half = packed<uint16_t>;
+ using Word = packed<uint32_t>;
+ using Sword = packed<int32_t>;
+ using Xword = packed<uint64_t>;
+ using Sxword = packed<int64_t>;
+ using Addr = packed<uint>;
+ using Off = packed<uint>;
+};
+
+using ELF32LE = ELFType<support::little, false>;
+using ELF32BE = ELFType<support::big, false>;
+using ELF64LE = ELFType<support::little, true>;
+using ELF64BE = ELFType<support::big, true>;
// Use an alignment of 2 for the typedefs since that is the worst case for
// ELF files in archives.
// Templates to choose Elf_Addr and Elf_Off depending on is64Bits.
template <endianness target_endianness> struct ELFDataTypeTypedefHelperCommon {
- typedef support::detail::packed_endian_specific_integral<
- uint16_t, target_endianness, 2> Elf_Half;
- typedef support::detail::packed_endian_specific_integral<
- uint32_t, target_endianness, 2> Elf_Word;
- typedef support::detail::packed_endian_specific_integral<
- int32_t, target_endianness, 2> Elf_Sword;
- typedef support::detail::packed_endian_specific_integral<
- uint64_t, target_endianness, 2> Elf_Xword;
- typedef support::detail::packed_endian_specific_integral<
- int64_t, target_endianness, 2> Elf_Sxword;
+ using Elf_Half = support::detail::packed_endian_specific_integral<
+ uint16_t, target_endianness, 2>;
+ using Elf_Word = support::detail::packed_endian_specific_integral<
+ uint32_t, target_endianness, 2>;
+ using Elf_Sword = support::detail::packed_endian_specific_integral<
+ int32_t, target_endianness, 2>;
+ using Elf_Xword = support::detail::packed_endian_specific_integral<
+ uint64_t, target_endianness, 2>;
+ using Elf_Sxword = support::detail::packed_endian_specific_integral<
+ int64_t, target_endianness, 2>;
};
template <class ELFT> struct ELFDataTypeTypedefHelper;
@@ -105,34 +110,34 @@ template <class ELFT> struct ELFDataTypeTypedefHelper;
template <endianness TargetEndianness>
struct ELFDataTypeTypedefHelper<ELFType<TargetEndianness, false>>
: ELFDataTypeTypedefHelperCommon<TargetEndianness> {
- typedef uint32_t value_type;
- typedef support::detail::packed_endian_specific_integral<
- value_type, TargetEndianness, 2> Elf_Addr;
- typedef support::detail::packed_endian_specific_integral<
- value_type, TargetEndianness, 2> Elf_Off;
+ using value_type = uint32_t;
+ using Elf_Addr = support::detail::packed_endian_specific_integral<
+ value_type, TargetEndianness, 2>;
+ using Elf_Off = support::detail::packed_endian_specific_integral<
+ value_type, TargetEndianness, 2>;
};
/// ELF 64bit types.
template <endianness TargetEndianness>
struct ELFDataTypeTypedefHelper<ELFType<TargetEndianness, true>>
: ELFDataTypeTypedefHelperCommon<TargetEndianness> {
- typedef uint64_t value_type;
- typedef support::detail::packed_endian_specific_integral<
- value_type, TargetEndianness, 2> Elf_Addr;
- typedef support::detail::packed_endian_specific_integral<
- value_type, TargetEndianness, 2> Elf_Off;
+ using value_type = uint64_t;
+ using Elf_Addr = support::detail::packed_endian_specific_integral<
+ value_type, TargetEndianness, 2>;
+ using Elf_Off = support::detail::packed_endian_specific_integral<
+ value_type, TargetEndianness, 2>;
};
// I really don't like doing this, but the alternative is copypasta.
#define LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) \
- typedef typename ELFT::Addr Elf_Addr; \
- typedef typename ELFT::Off Elf_Off; \
- typedef typename ELFT::Half Elf_Half; \
- typedef typename ELFT::Word Elf_Word; \
- typedef typename ELFT::Sword Elf_Sword; \
- typedef typename ELFT::Xword Elf_Xword; \
- typedef typename ELFT::Sxword Elf_Sxword;
+ using Elf_Addr = typename ELFT::Addr; \
+ using Elf_Off = typename ELFT::Off; \
+ using Elf_Half = typename ELFT::Half; \
+ using Elf_Word = typename ELFT::Word; \
+ using Elf_Sword = typename ELFT::Sword; \
+ using Elf_Xword = typename ELFT::Xword; \
+ using Elf_Sxword = typename ELFT::Sxword;
#define LLD_ELF_COMMA ,
#define LLVM_ELF_IMPORT_TYPES(E, W) \
@@ -222,6 +227,7 @@ struct Elf_Sym_Impl : Elf_Sym_Base<ELFT> {
uint64_t getValue() const { return st_value; }
void setBinding(unsigned char b) { setBindingAndType(b, getType()); }
void setType(unsigned char t) { setBindingAndType(getBinding(), t); }
+
void setBindingAndType(unsigned char b, unsigned char t) {
st_info = (b << 4) + (t & 0x0f);
}
@@ -238,22 +244,29 @@ struct Elf_Sym_Impl : Elf_Sym_Base<ELFT> {
}
bool isAbsolute() const { return st_shndx == ELF::SHN_ABS; }
+
bool isCommon() const {
return getType() == ELF::STT_COMMON || st_shndx == ELF::SHN_COMMON;
}
+
bool isDefined() const { return !isUndefined(); }
+
bool isProcessorSpecific() const {
return st_shndx >= ELF::SHN_LOPROC && st_shndx <= ELF::SHN_HIPROC;
}
+
bool isOSSpecific() const {
return st_shndx >= ELF::SHN_LOOS && st_shndx <= ELF::SHN_HIOS;
}
+
bool isReserved() const {
// ELF::SHN_HIRESERVE is 0xffff so st_shndx <= ELF::SHN_HIRESERVE is always
// true and some compilers warn about it.
return st_shndx >= ELF::SHN_LORESERVE;
}
+
bool isUndefined() const { return st_shndx == ELF::SHN_UNDEF; }
+
bool isExternal() const {
return getBinding() != ELF::STB_LOCAL;
}
@@ -277,14 +290,12 @@ struct Elf_Versym_Impl {
Elf_Half vs_index; // Version index with flags (e.g. VERSYM_HIDDEN)
};
-template <class ELFT> struct Elf_Verdaux_Impl;
-
/// Elf_Verdef: This is the structure of entries in the SHT_GNU_verdef section
/// (.gnu.version_d). This structure is identical for ELF32 and ELF64.
template <class ELFT>
struct Elf_Verdef_Impl {
LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
- typedef Elf_Verdaux_Impl<ELFT> Elf_Verdaux;
+ using Elf_Verdaux = Elf_Verdaux_Impl<ELFT>;
Elf_Half vd_version; // Version of this structure (e.g. VER_DEF_CURRENT)
Elf_Half vd_flags; // Bitwise flags (VER_DEF_*)
Elf_Half vd_ndx; // Version index, used in .gnu.version entries
@@ -361,10 +372,10 @@ template <class ELFT>
struct Elf_Dyn_Impl : Elf_Dyn_Base<ELFT> {
using Elf_Dyn_Base<ELFT>::d_tag;
using Elf_Dyn_Base<ELFT>::d_un;
- typedef typename std::conditional<ELFT::Is64Bits,
- int64_t, int32_t>::type intX_t;
- typedef typename std::conditional<ELFT::Is64Bits,
- uint64_t, uint32_t>::type uintX_t;
+ using intX_t = typename std::conditional<ELFT::Is64Bits,
+ int64_t, int32_t>::type;
+ using uintX_t = typename std::conditional<ELFT::Is64Bits,
+ uint64_t, uint32_t>::type;
intX_t getTag() const { return d_tag; }
uintX_t getVal() const { return d_un.d_val; }
uintX_t getPtr() const { return d_un.d_ptr; }
@@ -430,6 +441,7 @@ struct Elf_Rel_Impl<ELFType<TargetEndianness, true>, false> {
return (t << 32) | ((t >> 8) & 0xff000000) | ((t >> 24) & 0x00ff0000) |
((t >> 40) & 0x0000ff00) | ((t >> 56) & 0x000000ff);
}
+
void setRInfo(uint64_t R, bool IsMips64EL) {
if (IsMips64EL)
r_info = (R >> 32) | ((R & 0xff000000) << 8) | ((R & 0x00ff0000) << 24) |
@@ -483,15 +495,15 @@ struct Elf_Ehdr_Impl {
Elf_Half e_shnum; // Number of entries in the section header table
Elf_Half e_shstrndx; // Section header table index of section name
// string table
+
bool checkMagic() const {
return (memcmp(e_ident, ELF::ElfMagic, strlen(ELF::ElfMagic))) == 0;
}
+
unsigned char getFileClass() const { return e_ident[ELF::EI_CLASS]; }
unsigned char getDataEncoding() const { return e_ident[ELF::EI_DATA]; }
};
-template <class ELFT> struct Elf_Phdr_Impl;
-
template <endianness TargetEndianness>
struct Elf_Phdr_Impl<ELFType<TargetEndianness, false>> {
LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
@@ -582,7 +594,7 @@ struct Elf_Chdr_Impl<ELFType<TargetEndianness, true>> {
template <class ELFT>
struct Elf_Mips_RegInfo;
-template <llvm::support::endianness TargetEndianness>
+template <support::endianness TargetEndianness>
struct Elf_Mips_RegInfo<ELFType<TargetEndianness, false>> {
LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
Elf_Word ri_gprmask; // bit-mask of used general registers
@@ -590,7 +602,7 @@ struct Elf_Mips_RegInfo<ELFType<TargetEndianness, false>> {
Elf_Addr ri_gp_value; // gp register value
};
-template <llvm::support::endianness TargetEndianness>
+template <support::endianness TargetEndianness>
struct Elf_Mips_RegInfo<ELFType<TargetEndianness, true>> {
LLVM_ELF_IMPORT_TYPES(TargetEndianness, true)
Elf_Word ri_gprmask; // bit-mask of used general registers
@@ -609,7 +621,7 @@ template <class ELFT> struct Elf_Mips_Options {
Elf_Word info; // Kind-specific information
Elf_Mips_RegInfo<ELFT> &getRegInfo() {
- assert(kind == llvm::ELF::ODK_REGINFO);
+ assert(kind == ELF::ODK_REGINFO);
return *reinterpret_cast<Elf_Mips_RegInfo<ELFT> *>(
(uint8_t *)this + sizeof(Elf_Mips_Options));
}
@@ -637,4 +649,4 @@ template <class ELFT> struct Elf_Mips_ABIFlags {
} // end namespace object.
} // end namespace llvm.
-#endif
+#endif // LLVM_OBJECT_ELFTYPES_H
diff --git a/include/llvm/Object/IRSymtab.h b/include/llvm/Object/IRSymtab.h
index be0f02aa7f17..b425543bf637 100644
--- a/include/llvm/Object/IRSymtab.h
+++ b/include/llvm/Object/IRSymtab.h
@@ -25,23 +25,31 @@
#define LLVM_OBJECT_IRSYMTAB_H
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/IR/GlobalValue.h"
#include "llvm/Object/SymbolicFile.h"
#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
+#include <cassert>
+#include <cstdint>
+#include <vector>
namespace llvm {
namespace irsymtab {
+
namespace storage {
// The data structures in this namespace define the low-level serialization
// format. Clients that just want to read a symbol table should use the
// irsymtab::Reader class.
-typedef support::ulittle32_t Word;
+using Word = support::ulittle32_t;
/// A reference to a string in the string table.
struct Str {
Word Offset, Size;
+
StringRef get(StringRef Strtab) const {
return {Strtab.data() + Offset, Size};
}
@@ -50,6 +58,7 @@ struct Str {
/// A reference to a range of objects in the symbol table.
template <typename T> struct Range {
Word Offset, Size;
+
ArrayRef<T> get(StringRef Symtab) const {
return {reinterpret_cast<const T *>(Symtab.data() + Offset), Size};
}
@@ -122,7 +131,7 @@ struct Header {
Str COFFLinkerOpts;
};
-}
+} // end namespace storage
/// Fills in Symtab and Strtab with a valid symbol and string table for Mods.
Error build(ArrayRef<Module *> Mods, SmallVector<char, 0> &Symtab,
@@ -152,18 +161,22 @@ struct Symbol {
int getComdatIndex() const { return ComdatIndex; }
using S = storage::Symbol;
+
GlobalValue::VisibilityTypes getVisibility() const {
return GlobalValue::VisibilityTypes((Flags >> S::FB_visibility) & 3);
}
+
bool isUndefined() const { return (Flags >> S::FB_undefined) & 1; }
bool isWeak() const { return (Flags >> S::FB_weak) & 1; }
bool isCommon() const { return (Flags >> S::FB_common) & 1; }
bool isIndirect() const { return (Flags >> S::FB_indirect) & 1; }
bool isUsed() const { return (Flags >> S::FB_used) & 1; }
bool isTLS() const { return (Flags >> S::FB_tls) & 1; }
+
bool canBeOmittedFromSymbolTable() const {
return (Flags >> S::FB_may_omit) & 1;
}
+
bool isGlobal() const { return (Flags >> S::FB_global) & 1; }
bool isFormatSpecific() const { return (Flags >> S::FB_format_specific) & 1; }
bool isUnnamedAddr() const { return (Flags >> S::FB_unnamed_addr) & 1; }
@@ -173,6 +186,7 @@ struct Symbol {
assert(isCommon());
return CommonSize;
}
+
uint32_t getCommonAlignment() const {
assert(isCommon());
return CommonAlign;
@@ -197,9 +211,11 @@ class Reader {
ArrayRef<storage::Uncommon> Uncommons;
StringRef str(storage::Str S) const { return S.get(Strtab); }
+
template <typename T> ArrayRef<T> range(storage::Range<T> R) const {
return R.get(Symtab);
}
+
const storage::Header &header() const {
return *reinterpret_cast<const storage::Header *>(Symtab.data());
}
@@ -215,7 +231,7 @@ public:
Uncommons = range(header().Uncommons);
}
- typedef iterator_range<object::content_iterator<SymbolRef>> symbol_range;
+ using symbol_range = iterator_range<object::content_iterator<SymbolRef>>;
/// Returns the symbol table for the entire bitcode file.
/// The symbols enumerated by this method are ephemeral, but they can be
@@ -298,8 +314,7 @@ inline Reader::symbol_range Reader::module_symbols(unsigned I) const {
SymbolRef(MEnd, MEnd, nullptr, this)};
}
-}
-
-}
+} // end namespace irsymtab
+} // end namespace llvm
-#endif
+#endif // LLVM_OBJECT_IRSYMTAB_H
diff --git a/include/llvm/Object/MachO.h b/include/llvm/Object/MachO.h
index 1ee571cce738..29553558f72f 100644
--- a/include/llvm/Object/MachO.h
+++ b/include/llvm/Object/MachO.h
@@ -16,10 +16,25 @@
#define LLVM_OBJECT_MACHO_H
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Triple.h"
+#include "llvm/MC/SubtargetFeature.h"
+#include "llvm/Object/Binary.h"
#include "llvm/Object/ObjectFile.h"
+#include "llvm/Object/SymbolicFile.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/Format.h"
#include "llvm/Support/MachO.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cstdint>
+#include <memory>
+#include <string>
+#include <system_error>
namespace llvm {
namespace object {
@@ -28,11 +43,10 @@ namespace object {
/// data in code entry in the table in a Mach-O object file.
class DiceRef {
DataRefImpl DicePimpl;
- const ObjectFile *OwningObject;
+ const ObjectFile *OwningObject = nullptr;
public:
- DiceRef() : OwningObject(nullptr) { }
-
+ DiceRef() = default;
DiceRef(DataRefImpl DiceP, const ObjectFile *Owner);
bool operator==(const DiceRef &Other) const;
@@ -47,7 +61,7 @@ public:
DataRefImpl getRawDataRefImpl() const;
const ObjectFile *getObjectFile() const;
};
-typedef content_iterator<DiceRef> dice_iterator;
+using dice_iterator = content_iterator<DiceRef>;
/// ExportEntry encapsulates the current-state-of-the-walk used when doing a
/// non-recursive walk of the trie data structure. This allows you to iterate
@@ -71,6 +85,7 @@ public:
private:
friend class MachOObjectFile;
+
void moveToFirst();
void moveToEnd();
uint64_t readULEB128(const uint8_t *&p);
@@ -80,25 +95,26 @@ private:
// Represents a node in the mach-o exports trie.
struct NodeState {
NodeState(const uint8_t *Ptr);
+
const uint8_t *Start;
const uint8_t *Current;
- uint64_t Flags;
- uint64_t Address;
- uint64_t Other;
- const char *ImportName;
- unsigned ChildCount;
- unsigned NextChildIndex;
- unsigned ParentStringLength;
- bool IsExportNode;
+ uint64_t Flags = 0;
+ uint64_t Address = 0;
+ uint64_t Other = 0;
+ const char *ImportName = nullptr;
+ unsigned ChildCount = 0;
+ unsigned NextChildIndex = 0;
+ unsigned ParentStringLength = 0;
+ bool IsExportNode = false;
};
ArrayRef<uint8_t> Trie;
SmallString<256> CumulativeString;
SmallVector<NodeState, 16> Stack;
- bool Malformed;
- bool Done;
+ bool Malformed = false;
+ bool Done = false;
};
-typedef content_iterator<ExportEntry> export_iterator;
+using export_iterator = content_iterator<ExportEntry>;
// Segment info so SegIndex/SegOffset pairs in a Mach-O Bind or Rebase entry
// can be checked and translated. Only the SegIndex/SegOffset pairs from
@@ -106,7 +122,7 @@ typedef content_iterator<ExportEntry> export_iterator;
// address() methods below.
class BindRebaseSegInfo {
public:
- BindRebaseSegInfo(const object::MachOObjectFile *Obj);
+ BindRebaseSegInfo(const MachOObjectFile *Obj);
// Used to check a Mach-O Bind or Rebase entry for errors when iterating.
const char *checkSegAndOffset(int32_t SegIndex, uint64_t SegOffset,
@@ -130,6 +146,7 @@ private:
int32_t SegmentIndex;
};
const SectionInfo &findSection(int32_t SegIndex, uint64_t SegOffset);
+
SmallVector<SectionInfo, 32> Sections;
int32_t MaxSegIndex;
};
@@ -159,6 +176,7 @@ public:
private:
friend class MachOObjectFile;
+
void moveToFirst();
void moveToEnd();
uint64_t readULEB128(const char **error);
@@ -167,15 +185,15 @@ private:
const MachOObjectFile *O;
ArrayRef<uint8_t> Opcodes;
const uint8_t *Ptr;
- uint64_t SegmentOffset;
- int32_t SegmentIndex;
- uint64_t RemainingLoopCount;
- uint64_t AdvanceAmount;
- uint8_t RebaseType;
+ uint64_t SegmentOffset = 0;
+ int32_t SegmentIndex = -1;
+ uint64_t RemainingLoopCount = 0;
+ uint64_t AdvanceAmount = 0;
+ uint8_t RebaseType = 0;
uint8_t PointerSize;
- bool Done;
+ bool Done = false;
};
-typedef content_iterator<MachORebaseEntry> rebase_iterator;
+using rebase_iterator = content_iterator<MachORebaseEntry>;
/// MachOBindEntry encapsulates the current state in the decompression of
/// binding opcodes. This allows you to iterate through the compressed table of
@@ -209,6 +227,7 @@ public:
private:
friend class MachOObjectFile;
+
void moveToFirst();
void moveToEnd();
uint64_t readULEB128(const char **error);
@@ -218,21 +237,21 @@ private:
const MachOObjectFile *O;
ArrayRef<uint8_t> Opcodes;
const uint8_t *Ptr;
- uint64_t SegmentOffset;
- int32_t SegmentIndex;
+ uint64_t SegmentOffset = 0;
+ int32_t SegmentIndex = -1;
StringRef SymbolName;
- bool LibraryOrdinalSet;
- int Ordinal;
- uint32_t Flags;
- int64_t Addend;
- uint64_t RemainingLoopCount;
- uint64_t AdvanceAmount;
- uint8_t BindType;
+ bool LibraryOrdinalSet = false;
+ int Ordinal = 0;
+ uint32_t Flags = 0;
+ int64_t Addend = 0;
+ uint64_t RemainingLoopCount = 0;
+ uint64_t AdvanceAmount = 0;
+ uint8_t BindType = 0;
uint8_t PointerSize;
Kind TableKind;
- bool Done;
+ bool Done = false;
};
-typedef content_iterator<MachOBindEntry> bind_iterator;
+using bind_iterator = content_iterator<MachOBindEntry>;
class MachOObjectFile : public ObjectFile {
public:
@@ -240,8 +259,8 @@ public:
const char *Ptr; // Where in memory the load command is.
MachO::load_command C; // The command itself.
};
- typedef SmallVector<LoadCommandInfo, 4> LoadCommandList;
- typedef LoadCommandList::const_iterator load_command_iterator;
+ using LoadCommandList = SmallVector<LoadCommandInfo, 4>;
+ using load_command_iterator = LoadCommandList::const_iterator;
static Expected<std::unique_ptr<MachOObjectFile>>
create(MemoryBufferRef Object, bool IsLittleEndian, bool Is64Bits,
@@ -563,7 +582,7 @@ public:
case MachO::PLATFORM_BRIDGEOS: return "bridgeos";
default:
std::string ret;
- llvm::raw_string_ostream ss(ret);
+ raw_string_ostream ss(ret);
ss << format_hex(platform, 8, true);
return ss.str();
}
@@ -576,7 +595,7 @@ public:
case MachO::TOOL_LD: return "ld";
default:
std::string ret;
- llvm::raw_string_ostream ss(ret);
+ raw_string_ostream ss(ret);
ss << format_hex(tools, 8, true);
return ss.str();
}
@@ -595,7 +614,6 @@ public:
}
private:
-
MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian, bool Is64Bits,
Error &Err, uint32_t UniversalCputype = 0,
uint32_t UniversalIndex = 0);
@@ -606,23 +624,23 @@ private:
MachO::mach_header_64 Header64;
MachO::mach_header Header;
};
- typedef SmallVector<const char*, 1> SectionList;
+ using SectionList = SmallVector<const char*, 1>;
SectionList Sections;
- typedef SmallVector<const char*, 1> LibraryList;
+ using LibraryList = SmallVector<const char*, 1>;
LibraryList Libraries;
LoadCommandList LoadCommands;
- typedef SmallVector<StringRef, 1> LibraryShortName;
+ using LibraryShortName = SmallVector<StringRef, 1>;
using BuildToolList = SmallVector<const char*, 1>;
BuildToolList BuildTools;
mutable LibraryShortName LibrariesShortNames;
std::unique_ptr<BindRebaseSegInfo> BindRebaseSectionTable;
- const char *SymtabLoadCmd;
- const char *DysymtabLoadCmd;
- const char *DataInCodeLoadCmd;
- const char *LinkOptHintsLoadCmd;
- const char *DyldInfoLoadCmd;
- const char *UuidLoadCmd;
- bool HasPageZeroSegment;
+ const char *SymtabLoadCmd = nullptr;
+ const char *DysymtabLoadCmd = nullptr;
+ const char *DataInCodeLoadCmd = nullptr;
+ const char *LinkOptHintsLoadCmd = nullptr;
+ const char *DyldInfoLoadCmd = nullptr;
+ const char *UuidLoadCmd = nullptr;
+ bool HasPageZeroSegment = false;
};
/// DiceRef
@@ -679,7 +697,7 @@ inline const ObjectFile *DiceRef::getObjectFile() const {
return OwningObject;
}
-}
-}
+} // end namespace object
+} // end namespace llvm
-#endif
+#endif // LLVM_OBJECT_MACHO_H
diff --git a/include/llvm/Object/ModuleSummaryIndexObjectFile.h b/include/llvm/Object/ModuleSummaryIndexObjectFile.h
index 713022264ea7..f733f861e2c0 100644
--- a/include/llvm/Object/ModuleSummaryIndexObjectFile.h
+++ b/include/llvm/Object/ModuleSummaryIndexObjectFile.h
@@ -1,4 +1,4 @@
-//===- ModuleSummaryIndexObjectFile.h - Summary index file implementation -=//
+//===- ModuleSummaryIndexObjectFile.h - Summary index file implementation -===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,14 +14,22 @@
#ifndef LLVM_OBJECT_MODULESUMMARYINDEXOBJECTFILE_H
#define LLVM_OBJECT_MODULESUMMARYINDEXOBJECTFILE_H
-#include "llvm/IR/DiagnosticInfo.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Object/Binary.h"
#include "llvm/Object/SymbolicFile.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/ErrorOr.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include <memory>
+#include <system_error>
namespace llvm {
+
class ModuleSummaryIndex;
-class Module;
namespace object {
+
class ObjectFile;
/// This class is used to read just the module summary index related
@@ -41,15 +49,18 @@ public:
void moveSymbolNext(DataRefImpl &Symb) const override {
llvm_unreachable("not implemented");
}
+
std::error_code printSymbolName(raw_ostream &OS,
DataRefImpl Symb) const override {
llvm_unreachable("not implemented");
return std::error_code();
}
+
uint32_t getSymbolFlags(DataRefImpl Symb) const override {
llvm_unreachable("not implemented");
return 0;
}
+
basic_symbol_iterator symbol_begin() const override {
llvm_unreachable("not implemented");
return basic_symbol_iterator(BasicSymbolRef());
@@ -85,7 +96,8 @@ public:
static Expected<std::unique_ptr<ModuleSummaryIndexObjectFile>>
create(MemoryBufferRef Object);
};
-}
+
+} // end namespace object
/// Parse the module summary index out of an IR file and return the module
/// summary index object if found, or nullptr if not. If Identifier is
@@ -94,6 +106,7 @@ public:
/// containing minimized bitcode just for the thin link.
Expected<std::unique_ptr<ModuleSummaryIndex>>
getModuleSummaryIndexForFile(StringRef Path, StringRef Identifier = "");
-}
-#endif
+} // end namespace llvm
+
+#endif // LLVM_OBJECT_MODULESUMMARYINDEXOBJECTFILE_H
diff --git a/include/llvm/Object/ModuleSymbolTable.h b/include/llvm/Object/ModuleSymbolTable.h
index 333301d5b456..9e9322885388 100644
--- a/include/llvm/Object/ModuleSymbolTable.h
+++ b/include/llvm/Object/ModuleSymbolTable.h
@@ -1,4 +1,4 @@
-//===- ModuleSymbolTable.h - symbol table for in-memory IR ----------------===//
+//===- ModuleSymbolTable.h - symbol table for in-memory IR ------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -16,22 +16,24 @@
#ifndef LLVM_OBJECT_MODULESYMBOLTABLE_H
#define LLVM_OBJECT_MODULESYMBOLTABLE_H
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/PointerUnion.h"
-#include "llvm/ADT/Triple.h"
#include "llvm/IR/Mangler.h"
#include "llvm/Object/SymbolicFile.h"
+#include "llvm/Support/Allocator.h"
+#include <cstdint>
#include <string>
#include <utility>
+#include <vector>
namespace llvm {
class GlobalValue;
-class RecordStreamer;
class ModuleSymbolTable {
public:
- typedef std::pair<std::string, uint32_t> AsmSymbol;
- typedef PointerUnion<GlobalValue *, AsmSymbol *> Symbol;
+ using AsmSymbol = std::pair<std::string, uint32_t>;
+ using Symbol = PointerUnion<GlobalValue *, AsmSymbol *>;
private:
Module *FirstMod = nullptr;
@@ -57,6 +59,6 @@ public:
function_ref<void(StringRef, object::BasicSymbolRef::Flags)> AsmSymbol);
};
-}
+} // end namespace llvm
-#endif
+#endif // LLVM_OBJECT_MODULESYMBOLTABLE_H
diff --git a/include/llvm/Object/RelocVisitor.h b/include/llvm/Object/RelocVisitor.h
index 3a0a62d9283b..73c7ce367cb0 100644
--- a/include/llvm/Object/RelocVisitor.h
+++ b/include/llvm/Object/RelocVisitor.h
@@ -1,4 +1,4 @@
-//===-- RelocVisitor.h - Visitor for object file relocations -*- C++ -*-===//
+//===- RelocVisitor.h - Visitor for object file relocations -----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -16,34 +16,38 @@
#ifndef LLVM_OBJECT_RELOCVISITOR_H
#define LLVM_OBJECT_RELOCVISITOR_H
+#include "llvm/ADT/Triple.h"
#include "llvm/Object/COFF.h"
#include "llvm/Object/ELFObjectFile.h"
#include "llvm/Object/MachO.h"
#include "llvm/Object/ObjectFile.h"
-#include "llvm/Support/Debug.h"
+#include "llvm/Support/Casting.h"
#include "llvm/Support/ELF.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/ErrorOr.h"
#include "llvm/Support/MachO.h"
-#include "llvm/Support/raw_ostream.h"
+#include <cstdint>
+#include <system_error>
namespace llvm {
namespace object {
struct RelocToApply {
// The computed value after applying the relevant relocations.
- int64_t Value;
+ int64_t Value = 0;
// The width of the value; how many bytes to touch when applying the
// relocation.
- char Width;
+ char Width = 0;
+
+ RelocToApply() = default;
RelocToApply(int64_t Value, char Width) : Value(Value), Width(Width) {}
- RelocToApply() : Value(0), Width(0) {}
};
/// @brief Base class for object file relocation visitors.
class RelocVisitor {
public:
- explicit RelocVisitor(const ObjectFile &Obj)
- : ObjToVisit(Obj), HasError(false) {}
+ explicit RelocVisitor(const ObjectFile &Obj) : ObjToVisit(Obj) {}
// TODO: Should handle multiple applied relocations via either passing in the
// previously computed value or just count paired relocations as a single
@@ -64,22 +68,22 @@ public:
private:
const ObjectFile &ObjToVisit;
- bool HasError;
+ bool HasError = false;
RelocToApply visitELF(uint32_t RelocType, RelocationRef R, uint64_t Value) {
if (ObjToVisit.getBytesInAddress() == 8) { // 64-bit object file
switch (ObjToVisit.getArch()) {
case Triple::x86_64:
switch (RelocType) {
- case llvm::ELF::R_X86_64_NONE:
+ case ELF::R_X86_64_NONE:
return visitELF_X86_64_NONE(R);
- case llvm::ELF::R_X86_64_64:
+ case ELF::R_X86_64_64:
return visitELF_X86_64_64(R, Value);
- case llvm::ELF::R_X86_64_PC32:
+ case ELF::R_X86_64_PC32:
return visitELF_X86_64_PC32(R, Value);
- case llvm::ELF::R_X86_64_32:
+ case ELF::R_X86_64_32:
return visitELF_X86_64_32(R, Value);
- case llvm::ELF::R_X86_64_32S:
+ case ELF::R_X86_64_32S:
return visitELF_X86_64_32S(R, Value);
default:
HasError = true;
@@ -88,9 +92,9 @@ private:
case Triple::aarch64:
case Triple::aarch64_be:
switch (RelocType) {
- case llvm::ELF::R_AARCH64_ABS32:
+ case ELF::R_AARCH64_ABS32:
return visitELF_AARCH64_ABS32(R, Value);
- case llvm::ELF::R_AARCH64_ABS64:
+ case ELF::R_AARCH64_ABS64:
return visitELF_AARCH64_ABS64(R, Value);
default:
HasError = true;
@@ -99,9 +103,9 @@ private:
case Triple::bpfel:
case Triple::bpfeb:
switch (RelocType) {
- case llvm::ELF::R_BPF_64_64:
+ case ELF::R_BPF_64_64:
return visitELF_BPF_64_64(R, Value);
- case llvm::ELF::R_BPF_64_32:
+ case ELF::R_BPF_64_32:
return visitELF_BPF_64_32(R, Value);
default:
HasError = true;
@@ -110,9 +114,9 @@ private:
case Triple::mips64el:
case Triple::mips64:
switch (RelocType) {
- case llvm::ELF::R_MIPS_32:
+ case ELF::R_MIPS_32:
return visitELF_MIPS64_32(R, Value);
- case llvm::ELF::R_MIPS_64:
+ case ELF::R_MIPS_64:
return visitELF_MIPS64_64(R, Value);
default:
HasError = true;
@@ -121,9 +125,9 @@ private:
case Triple::ppc64le:
case Triple::ppc64:
switch (RelocType) {
- case llvm::ELF::R_PPC64_ADDR32:
+ case ELF::R_PPC64_ADDR32:
return visitELF_PPC64_ADDR32(R, Value);
- case llvm::ELF::R_PPC64_ADDR64:
+ case ELF::R_PPC64_ADDR64:
return visitELF_PPC64_ADDR64(R, Value);
default:
HasError = true;
@@ -131,9 +135,9 @@ private:
}
case Triple::systemz:
switch (RelocType) {
- case llvm::ELF::R_390_32:
+ case ELF::R_390_32:
return visitELF_390_32(R, Value);
- case llvm::ELF::R_390_64:
+ case ELF::R_390_64:
return visitELF_390_64(R, Value);
default:
HasError = true;
@@ -141,11 +145,11 @@ private:
}
case Triple::sparcv9:
switch (RelocType) {
- case llvm::ELF::R_SPARC_32:
- case llvm::ELF::R_SPARC_UA32:
+ case ELF::R_SPARC_32:
+ case ELF::R_SPARC_UA32:
return visitELF_SPARCV9_32(R, Value);
- case llvm::ELF::R_SPARC_64:
- case llvm::ELF::R_SPARC_UA64:
+ case ELF::R_SPARC_64:
+ case ELF::R_SPARC_UA64:
return visitELF_SPARCV9_64(R, Value);
default:
HasError = true;
@@ -153,9 +157,9 @@ private:
}
case Triple::amdgcn:
switch (RelocType) {
- case llvm::ELF::R_AMDGPU_ABS32:
+ case ELF::R_AMDGPU_ABS32:
return visitELF_AMDGPU_ABS32(R, Value);
- case llvm::ELF::R_AMDGPU_ABS64:
+ case ELF::R_AMDGPU_ABS64:
return visitELF_AMDGPU_ABS64(R, Value);
default:
HasError = true;
@@ -169,11 +173,11 @@ private:
switch (ObjToVisit.getArch()) {
case Triple::x86:
switch (RelocType) {
- case llvm::ELF::R_386_NONE:
+ case ELF::R_386_NONE:
return visitELF_386_NONE(R);
- case llvm::ELF::R_386_32:
+ case ELF::R_386_32:
return visitELF_386_32(R, Value);
- case llvm::ELF::R_386_PC32:
+ case ELF::R_386_PC32:
return visitELF_386_PC32(R, Value);
default:
HasError = true;
@@ -181,7 +185,7 @@ private:
}
case Triple::ppc:
switch (RelocType) {
- case llvm::ELF::R_PPC_ADDR32:
+ case ELF::R_PPC_ADDR32:
return visitELF_PPC_ADDR32(R, Value);
default:
HasError = true;
@@ -193,12 +197,12 @@ private:
default:
HasError = true;
return RelocToApply();
- case llvm::ELF::R_ARM_ABS32:
+ case ELF::R_ARM_ABS32:
return visitELF_ARM_ABS32(R, Value);
}
case Triple::lanai:
switch (RelocType) {
- case llvm::ELF::R_LANAI_32:
+ case ELF::R_LANAI_32:
return visitELF_Lanai_32(R, Value);
default:
HasError = true;
@@ -207,7 +211,7 @@ private:
case Triple::mipsel:
case Triple::mips:
switch (RelocType) {
- case llvm::ELF::R_MIPS_32:
+ case ELF::R_MIPS_32:
return visitELF_MIPS_32(R, Value);
default:
HasError = true;
@@ -215,8 +219,8 @@ private:
}
case Triple::sparc:
switch (RelocType) {
- case llvm::ELF::R_SPARC_32:
- case llvm::ELF::R_SPARC_UA32:
+ case ELF::R_SPARC_32:
+ case ELF::R_SPARC_UA32:
return visitELF_SPARC_32(R, Value);
default:
HasError = true;
@@ -224,7 +228,7 @@ private:
}
case Triple::hexagon:
switch (RelocType) {
- case llvm::ELF::R_HEX_32:
+ case ELF::R_HEX_32:
return visitELF_HEX_32(R, Value);
default:
HasError = true;
@@ -483,6 +487,7 @@ private:
}
};
-}
-}
-#endif
+} // end namespace object
+} // end namespace llvm
+
+#endif // LLVM_OBJECT_RELOCVISITOR_H
diff --git a/include/llvm/Object/StackMapParser.h b/include/llvm/Object/StackMapParser.h
index efea62bb3cb3..0c5e1e38cbaa 100644
--- a/include/llvm/Object/StackMapParser.h
+++ b/include/llvm/Object/StackMapParser.h
@@ -1,4 +1,4 @@
-//===-------- StackMapParser.h - StackMap Parsing Support -------*- C++ -*-===//
+//===- StackMapParser.h - StackMap Parsing Support --------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -11,7 +11,11 @@
#define LLVM_CODEGEN_STACKMAPPARSER_H
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/iterator_range.h"
#include "llvm/Support/Endian.h"
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
#include <vector>
namespace llvm {
@@ -19,12 +23,11 @@ namespace llvm {
template <support::endianness Endianness>
class StackMapV2Parser {
public:
-
template <typename AccessorT>
class AccessorIterator {
public:
-
AccessorIterator(AccessorT A) : A(A) {}
+
AccessorIterator& operator++() { A = A.next(); return *this; }
AccessorIterator operator++(int) {
auto tmp = *this;
@@ -48,8 +51,8 @@ public:
/// Accessor for function records.
class FunctionAccessor {
friend class StackMapV2Parser;
- public:
+ public:
/// Get the function address.
uint64_t getFunctionAddress() const {
return read<uint64_t>(P);
@@ -80,13 +83,12 @@ public:
/// Accessor for constants.
class ConstantAccessor {
friend class StackMapV2Parser;
- public:
+ public:
/// Return the value of this constant.
uint64_t getValue() const { return read<uint64_t>(P); }
private:
-
ConstantAccessor(const uint8_t *P) : P(P) {}
const static int ConstantAccessorSize = sizeof(uint64_t);
@@ -98,20 +100,16 @@ public:
const uint8_t *P;
};
- // Forward-declare RecordAccessor so we can friend it below.
- class RecordAccessor;
-
enum class LocationKind : uint8_t {
Register = 1, Direct = 2, Indirect = 3, Constant = 4, ConstantIndex = 5
};
-
/// Accessor for location records.
class LocationAccessor {
friend class StackMapV2Parser;
friend class RecordAccessor;
- public:
+ public:
/// Get the Kind for this location.
LocationKind getKind() const {
return LocationKind(P[KindOffset]);
@@ -144,7 +142,6 @@ public:
}
private:
-
LocationAccessor(const uint8_t *P) : P(P) {}
LocationAccessor next() const {
@@ -163,8 +160,8 @@ public:
class LiveOutAccessor {
friend class StackMapV2Parser;
friend class RecordAccessor;
- public:
+ public:
/// Get the Dwarf register number for this live-out.
uint16_t getDwarfRegNum() const {
return read<uint16_t>(P + DwarfRegNumOffset);
@@ -176,7 +173,6 @@ public:
}
private:
-
LiveOutAccessor(const uint8_t *P) : P(P) {}
LiveOutAccessor next() const {
@@ -194,10 +190,10 @@ public:
/// Accessor for stackmap records.
class RecordAccessor {
friend class StackMapV2Parser;
- public:
- typedef AccessorIterator<LocationAccessor> location_iterator;
- typedef AccessorIterator<LiveOutAccessor> liveout_iterator;
+ public:
+ using location_iterator = AccessorIterator<LocationAccessor>;
+ using liveout_iterator = AccessorIterator<LiveOutAccessor>;
/// Get the patchpoint/stackmap ID for this record.
uint64_t getID() const {
@@ -254,7 +250,6 @@ public:
return liveout_iterator(getLiveOut(0));
}
-
/// End iterator for live-outs.
liveout_iterator liveouts_end() const {
return liveout_iterator(getLiveOut(getNumLiveOuts()));
@@ -266,7 +261,6 @@ public:
}
private:
-
RecordAccessor(const uint8_t *P) : P(P) {}
unsigned getNumLiveOutsOffset() const {
@@ -316,9 +310,9 @@ public:
}
}
- typedef AccessorIterator<FunctionAccessor> function_iterator;
- typedef AccessorIterator<ConstantAccessor> constant_iterator;
- typedef AccessorIterator<RecordAccessor> record_iterator;
+ using function_iterator = AccessorIterator<FunctionAccessor>;
+ using constant_iterator = AccessorIterator<ConstantAccessor>;
+ using record_iterator = AccessorIterator<RecordAccessor>;
/// Get the version number of this stackmap. (Always returns 2).
unsigned getVersion() const { return 2; }
@@ -413,7 +407,6 @@ public:
}
private:
-
template <typename T>
static T read(const uint8_t *P) {
return support::endian::read<T, Endianness, 1>(P);
@@ -441,6 +434,6 @@ private:
std::vector<unsigned> StackMapRecordOffsets;
};
-}
+} // end namespace llvm
-#endif
+#endif // LLVM_CODEGEN_STACKMAPPARSER_H
diff --git a/include/llvm/Object/Wasm.h b/include/llvm/Object/Wasm.h
index 43ad62be68b6..6b6bbe252f65 100644
--- a/include/llvm/Object/Wasm.h
+++ b/include/llvm/Object/Wasm.h
@@ -17,6 +17,8 @@
#ifndef LLVM_OBJECT_WASM_H
#define LLVM_OBJECT_WASM_H
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/Object/Binary.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/Error.h"
@@ -47,10 +49,10 @@ public:
class WasmSection {
public:
- WasmSection() : Type(0), Offset(0) {}
+ WasmSection() = default;
- uint32_t Type; // Section type (See below)
- uint32_t Offset; // Offset with in the file
+ uint32_t Type = 0; // Section type (See below)
+ uint32_t Offset = 0; // Offset with in the file
StringRef Name; // Section name (User-defined sections only)
ArrayRef<uint8_t> Content; // Section content
std::vector<wasm::WasmRelocation> Relocations; // Relocations for this section
@@ -74,12 +76,15 @@ public:
const std::vector<wasm::WasmLimits>& memories() const { return Memories; }
const std::vector<wasm::WasmGlobal>& globals() const { return Globals; }
const std::vector<wasm::WasmExport>& exports() const { return Exports; }
+
const std::vector<wasm::WasmElemSegment>& elements() const {
return ElemSegments;
}
+
const std::vector<wasm::WasmDataSegment>& dataSegments() const {
return DataSegments;
}
+
const std::vector<wasm::WasmFunction>& functions() const { return Functions; }
const ArrayRef<uint8_t>& code() const { return CodeSection; }
uint32_t startFunction() const { return StartFunction; }
@@ -178,7 +183,7 @@ private:
std::vector<WasmSymbol> Symbols;
std::vector<wasm::WasmFunction> Functions;
ArrayRef<uint8_t> CodeSection;
- uint32_t StartFunction;
+ uint32_t StartFunction = -1;
};
} // end namespace object
diff --git a/include/llvm/ObjectYAML/WasmYAML.h b/include/llvm/ObjectYAML/WasmYAML.h
index b1af8bbdfa6e..dfeeb8589f82 100644
--- a/include/llvm/ObjectYAML/WasmYAML.h
+++ b/include/llvm/ObjectYAML/WasmYAML.h
@@ -88,7 +88,7 @@ struct Relocation {
RelocType Type;
uint32_t Index;
yaml::Hex32 Offset;
- yaml::Hex32 Addend;
+ int32_t Addend;
};
struct DataSegment {
diff --git a/include/llvm/ProfileData/InstrProf.h b/include/llvm/ProfileData/InstrProf.h
index c9828858cce3..1b07c33746e7 100644
--- a/include/llvm/ProfileData/InstrProf.h
+++ b/include/llvm/ProfileData/InstrProf.h
@@ -79,14 +79,6 @@ inline StringRef getInstrProfValueRangeProfFuncName() {
return INSTR_PROF_VALUE_RANGE_PROF_FUNC_STR;
}
-/// Return the name of the section containing function coverage mapping
-/// data.
-std::string getInstrProfCoverageSectionName(const Module *M = nullptr);
-/// Similar to the above, but used by host tool (e.g, coverage) which has
-/// object format information. The section name returned is not prefixed
-/// with segment name.
-std::string getInstrProfCoverageSectionNameInObject(bool isCoff);
-
/// Return the name prefix of variables containing instrumented function names.
inline StringRef getInstrProfNameVarPrefix() { return "__profn_"; }
diff --git a/include/llvm/Support/BranchProbability.h b/include/llvm/Support/BranchProbability.h
index e8eb50d53eb6..b403d7fbf117 100644
--- a/include/llvm/Support/BranchProbability.h
+++ b/include/llvm/Support/BranchProbability.h
@@ -112,6 +112,13 @@ public:
return *this;
}
+ BranchProbability &operator*=(uint32_t RHS) {
+ assert(N != UnknownN &&
+ "Unknown probability cannot participate in arithmetics.");
+ N = (uint64_t(N) * RHS > D) ? D : N * RHS;
+ return *this;
+ }
+
BranchProbability &operator/=(uint32_t RHS) {
assert(N != UnknownN &&
"Unknown probability cannot participate in arithmetics.");
@@ -135,6 +142,11 @@ public:
return Prob *= RHS;
}
+ BranchProbability operator*(uint32_t RHS) const {
+ BranchProbability Prob(*this);
+ return Prob *= RHS;
+ }
+
BranchProbability operator/(uint32_t RHS) const {
BranchProbability Prob(*this);
return Prob /= RHS;
diff --git a/include/llvm/Support/FileSystem.h b/include/llvm/Support/FileSystem.h
index 29515c231bc4..e3c5de7fbe64 100644
--- a/include/llvm/Support/FileSystem.h
+++ b/include/llvm/Support/FileSystem.h
@@ -116,7 +116,9 @@ inline perms &operator&=(perms &l, perms r) {
return l;
}
inline perms operator~(perms x) {
- return static_cast<perms>(~static_cast<unsigned short>(x));
+ // Avoid UB by explicitly truncating the (unsigned) ~ result.
+ return static_cast<perms>(
+ static_cast<unsigned short>(~static_cast<unsigned short>(x)));
}
class UniqueID {
diff --git a/include/llvm/Support/GenericDomTree.h b/include/llvm/Support/GenericDomTree.h
index eb7c27d2ffa5..851ff7d80403 100644
--- a/include/llvm/Support/GenericDomTree.h
+++ b/include/llvm/Support/GenericDomTree.h
@@ -286,13 +286,13 @@ protected:
NodeRef NewBBSucc = *GraphT::child_begin(NewBB);
std::vector<NodeRef> PredBlocks;
- for (const auto Pred : children<Inverse<N>>(NewBB))
+ for (const auto &Pred : children<Inverse<N>>(NewBB))
PredBlocks.push_back(Pred);
assert(!PredBlocks.empty() && "No predblocks?");
bool NewBBDominatesNewBBSucc = true;
- for (const auto Pred : children<Inverse<N>>(NewBBSucc)) {
+ for (const auto &Pred : children<Inverse<N>>(NewBBSucc)) {
if (Pred != NewBB && !dominates(NewBBSucc, Pred) &&
isReachableFromEntry(Pred)) {
NewBBDominatesNewBBSucc = false;
diff --git a/include/llvm/Support/KnownBits.h b/include/llvm/Support/KnownBits.h
new file mode 100644
index 000000000000..08d4dedd0ac8
--- /dev/null
+++ b/include/llvm/Support/KnownBits.h
@@ -0,0 +1,43 @@
+//===- llvm/Support/KnownBits.h - Stores known zeros/ones -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains a class for representing known zeros and ones used by
+// computeKnownBits.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_KNOWNBITS_H
+#define LLVM_SUPPORT_KNOWNBITS_H
+
+#include "llvm/ADT/APInt.h"
+
+namespace llvm {
+
+// For now this is a simple wrapper around two APInts.
+struct KnownBits {
+ APInt Zero;
+ APInt One;
+
+ // Default construct Zero and One.
+ KnownBits() {}
+
+ /// Create a known bits object of BitWidth bits initialized to unknown.
+ KnownBits(unsigned BitWidth) : Zero(BitWidth, 0), One(BitWidth, 0) {}
+
+ /// Get the bit width of this value.
+ unsigned getBitWidth() const {
+ assert(Zero.getBitWidth() == One.getBitWidth() &&
+ "Zero and One should have the same width!");
+ return Zero.getBitWidth();
+ }
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/Support/YAMLTraits.h b/include/llvm/Support/YAMLTraits.h
index 6d02e4aba48a..ffea679fab82 100644
--- a/include/llvm/Support/YAMLTraits.h
+++ b/include/llvm/Support/YAMLTraits.h
@@ -606,7 +606,7 @@ public:
template <typename T>
void bitSetCase(T &Val, const char* Str, const T ConstVal) {
if ( bitSetMatch(Str, outputting() && (Val & ConstVal) == ConstVal) ) {
- Val = Val | ConstVal;
+ Val = static_cast<T>(Val | ConstVal);
}
}
@@ -614,7 +614,7 @@ public:
template <typename T>
void bitSetCase(T &Val, const char* Str, const uint32_t ConstVal) {
if ( bitSetMatch(Str, outputting() && (Val & ConstVal) == ConstVal) ) {
- Val = Val | ConstVal;
+ Val = static_cast<T>(Val | ConstVal);
}
}
diff --git a/include/llvm/Target/GlobalISel/Target.td b/include/llvm/Target/GlobalISel/Target.td
index fa1a424b5895..fd2ebca86d60 100644
--- a/include/llvm/Target/GlobalISel/Target.td
+++ b/include/llvm/Target/GlobalISel/Target.td
@@ -30,21 +30,13 @@ def s64 : LLT;
// Definitions that inherit from this may also inherit from
// GIComplexPatternEquiv to enable the import of SelectionDAG patterns involving
// those ComplexPatterns.
-class GIComplexOperandMatcher<LLT type, dag operands, string matcherfn> {
+class GIComplexOperandMatcher<LLT type, string matcherfn> {
// The expected type of the root of the match.
//
// TODO: We should probably support, any-type, any-scalar, and multiple types
// in the future.
LLT Type = type;
- // The operands that result from a successful match
- // Should be of the form '(ops ty1, ty2, ...)' where ty1/ty2 are definitions
- // that inherit from Operand.
- //
- // FIXME: Which definition is used for ty1/ty2 doesn't actually matter at the
- // moment. Only the number of operands is used.
- dag Operands = operands;
-
// The function that determines whether the operand matches. It should be of
// the form:
// bool select(const MatchOperand &Root, MatchOperand &Result1)
diff --git a/include/llvm/Target/TargetInstrInfo.h b/include/llvm/Target/TargetInstrInfo.h
index 0dc9cf70d335..82a682cf1f7e 100644
--- a/include/llvm/Target/TargetInstrInfo.h
+++ b/include/llvm/Target/TargetInstrInfo.h
@@ -1108,7 +1108,7 @@ public:
/// Return the noop instruction to use for a noop.
- virtual void getNoopForMachoTarget(MCInst &NopInst) const;
+ virtual void getNoop(MCInst &NopInst) const;
/// Return true for post-incremented instructions.
virtual bool isPostIncrement(const MachineInstr &MI) const {
diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h
index 24039ea10816..51f11e1a9a25 100644
--- a/include/llvm/Target/TargetLowering.h
+++ b/include/llvm/Target/TargetLowering.h
@@ -236,6 +236,12 @@ public:
return getPointerTy(DL, DL.getAllocaAddrSpace());
}
+ /// Return the type for operands of fence.
+ /// TODO: Let fence operands be of i32 type and remove this.
+ virtual MVT getFenceOperandTy(const DataLayout &DL) const {
+ return getPointerTy(DL);
+ }
+
/// EVT is not used in-tree, but is used by out-of-tree target.
/// A documentation for this function would be nice...
virtual MVT getScalarShiftAmountTy(const DataLayout &, EVT) const;
@@ -2268,7 +2274,8 @@ protected:
/// Return true if the value types that can be represented by the specified
/// register class are all legal.
- bool isLegalRC(const TargetRegisterClass *RC) const;
+ bool isLegalRC(const TargetRegisterInfo &TRI,
+ const TargetRegisterClass &RC) const;
/// Replace/modify any TargetFrameIndex operands with a targte-dependent
/// sequence of memory operands that is recognized by PrologEpilogInserter.
@@ -2388,30 +2395,39 @@ public:
New = N;
return true;
}
-
- /// Check to see if the specified operand of the specified instruction is a
- /// constant integer. If so, check to see if there are any bits set in the
- /// constant that are not demanded. If so, shrink the constant and return
- /// true.
- bool ShrinkDemandedConstant(SDValue Op, const APInt &Demanded);
-
- /// Convert x+y to (VT)((SmallVT)x+(SmallVT)y) if the casts are free. This
- /// uses isZExtFree and ZERO_EXTEND for the widening cast, but it could be
- /// generalized for targets with other types of implicit widening casts.
- bool ShrinkDemandedOp(SDValue Op, unsigned BitWidth, const APInt &Demanded,
- const SDLoc &dl);
-
- /// Helper for SimplifyDemandedBits that can simplify an operation with
- /// multiple uses. This function uses TLI.SimplifyDemandedBits to
- /// simplify Operand \p OpIdx of \p User and then updated \p User with
- /// the simplified version. No other uses of \p OpIdx are updated.
- /// If \p User is the only user of \p OpIdx, this function behaves exactly
- /// like TLI.SimplifyDemandedBits except that it also updates the DAG by
- /// calling DCI.CommitTargetLoweringOpt.
- bool SimplifyDemandedBits(SDNode *User, unsigned OpIdx,
- const APInt &Demanded, DAGCombinerInfo &DCI);
};
+ /// Check to see if the specified operand of the specified instruction is a
+ /// constant integer. If so, check to see if there are any bits set in the
+ /// constant that are not demanded. If so, shrink the constant and return
+ /// true.
+ bool ShrinkDemandedConstant(SDValue Op, const APInt &Demanded,
+ TargetLoweringOpt &TLO) const;
+
+ // Target hook to do target-specific const optimization, which is called by
+ // ShrinkDemandedConstant. This function should return true if the target
+ // doesn't want ShrinkDemandedConstant to further optimize the constant.
+ virtual bool targetShrinkDemandedConstant(SDValue Op, const APInt &Demanded,
+ TargetLoweringOpt &TLO) const {
+ return false;
+ }
+
+ /// Convert x+y to (VT)((SmallVT)x+(SmallVT)y) if the casts are free. This
+ /// uses isZExtFree and ZERO_EXTEND for the widening cast, but it could be
+ /// generalized for targets with other types of implicit widening casts.
+ bool ShrinkDemandedOp(SDValue Op, unsigned BitWidth, const APInt &Demanded,
+ TargetLoweringOpt &TLO) const;
+
+ /// Helper for SimplifyDemandedBits that can simplify an operation with
+ /// multiple uses. This function simplifies operand \p OpIdx of \p User and
+ /// then updates \p User with the simplified version. No other uses of
+ /// \p OpIdx are updated. If \p User is the only user of \p OpIdx, this
+ /// function behaves exactly like function SimplifyDemandedBits declared
+ /// below except that it also updates the DAG by calling
+ /// DCI.CommitTargetLoweringOpt.
+ bool SimplifyDemandedBits(SDNode *User, unsigned OpIdx, const APInt &Demanded,
+ DAGCombinerInfo &DCI, TargetLoweringOpt &TLO) const;
+
/// Look at Op. At this point, we know that only the DemandedMask bits of the
/// result of Op are ever used downstream. If we can use this information to
/// simplify Op, create a new simplified DAG node and return true, returning
diff --git a/include/llvm/Target/TargetRegisterInfo.h b/include/llvm/Target/TargetRegisterInfo.h
index 3f5daea63ab5..4ce6d2ff5e26 100644
--- a/include/llvm/Target/TargetRegisterInfo.h
+++ b/include/llvm/Target/TargetRegisterInfo.h
@@ -40,13 +40,12 @@ class TargetRegisterClass {
public:
typedef const MCPhysReg* iterator;
typedef const MCPhysReg* const_iterator;
- typedef const MVT::SimpleValueType* vt_iterator;
typedef const TargetRegisterClass* const * sc_iterator;
// Instance variables filled by tablegen, do not use!
const MCRegisterClass *MC;
const uint16_t SpillSize, SpillAlignment;
- const vt_iterator VTs;
+ const MVT::SimpleValueType *VTs;
const uint32_t *SubClassMask;
const uint16_t *SuperRegIndices;
const LaneBitmask LaneMask;
@@ -93,13 +92,6 @@ public:
return MC->contains(Reg1, Reg2);
}
- /// Return the size of the register in bytes, which is also the size
- /// of a stack slot allocated to hold a spilled copy of this register.
- unsigned getSize() const { return SpillSize; }
-
- /// Return the minimum required alignment for a register of this class.
- unsigned getAlignment() const { return SpillAlignment; }
-
/// Return the cost of copying a value between two registers in this class.
/// A negative number means the register class is very expensive
/// to copy e.g. status flag register classes.
@@ -109,26 +101,6 @@ public:
/// registers.
bool isAllocatable() const { return MC->isAllocatable(); }
- /// Return true if this TargetRegisterClass has the ValueType vt.
- bool hasType(MVT vt) const {
- for(int i = 0; VTs[i] != MVT::Other; ++i)
- if (MVT(VTs[i]) == vt)
- return true;
- return false;
- }
-
- /// vt_begin / vt_end - Loop over all of the value types that can be
- /// represented by values in this register class.
- vt_iterator vt_begin() const {
- return VTs;
- }
-
- vt_iterator vt_end() const {
- vt_iterator I = VTs;
- while (*I != MVT::Other) ++I;
- return I;
- }
-
/// Return true if the specified TargetRegisterClass
/// is a proper sub-class of this TargetRegisterClass.
bool hasSubClass(const TargetRegisterClass *RC) const {
@@ -246,6 +218,7 @@ struct RegClassWeight {
class TargetRegisterInfo : public MCRegisterInfo {
public:
typedef const TargetRegisterClass * const * regclass_iterator;
+ typedef const MVT::SimpleValueType* vt_iterator;
private:
const TargetRegisterInfoDesc *InfoDesc; // Extra desc array for codegen
const char *const *SubRegIndexNames; // Names of subreg indexes.
@@ -327,6 +300,44 @@ public:
return Index | (1u << 31);
}
+ /// Return the size in bits of a register from class RC.
+ unsigned getRegSizeInBits(const TargetRegisterClass &RC) const {
+ return RC.SpillSize * 8;
+ }
+
+ /// Return the size in bytes of the stack slot allocated to hold a spilled
+ /// copy of a register from class RC.
+ unsigned getSpillSize(const TargetRegisterClass &RC) const {
+ return RC.SpillSize;
+ }
+
+ /// Return the minimum required alignment for a spill slot for a register
+ /// of this class.
+ unsigned getSpillAlignment(const TargetRegisterClass &RC) const {
+ return RC.SpillAlignment;
+ }
+
+ /// Return true if the given TargetRegisterClass has the ValueType T.
+ bool isTypeLegalForClass(const TargetRegisterClass &RC, MVT T) const {
+ for (int i = 0; RC.VTs[i] != MVT::Other; ++i)
+ if (MVT(RC.VTs[i]) == T)
+ return true;
+ return false;
+ }
+
+ /// Loop over all of the value types that can be represented by values
+ // in the given register class.
+ vt_iterator legalclasstypes_begin(const TargetRegisterClass &RC) const {
+ return RC.VTs;
+ }
+
+ vt_iterator legalclasstypes_end(const TargetRegisterClass &RC) const {
+ vt_iterator I = RC.VTs;
+ while (*I != MVT::Other)
+ ++I;
+ return I;
+ }
+
/// Returns the Register Class of a physical register of the given type,
/// picking the most sub register class of the right type that contains this
/// physreg.
diff --git a/include/llvm/Transforms/Instrumentation.h b/include/llvm/Transforms/Instrumentation.h
index 01a3975a4f2c..db6723da1e61 100644
--- a/include/llvm/Transforms/Instrumentation.h
+++ b/include/llvm/Transforms/Instrumentation.h
@@ -131,7 +131,8 @@ FunctionPass *createAddressSanitizerFunctionPass(bool CompileKernel = false,
bool Recover = false,
bool UseAfterScope = false);
ModulePass *createAddressSanitizerModulePass(bool CompileKernel = false,
- bool Recover = false);
+ bool Recover = false,
+ bool UseGlobalsGC = true);
// Insert MemorySanitizer instrumentation (detection of uninitialized reads)
FunctionPass *createMemorySanitizerPass(int TrackOrigins = 0,
diff --git a/include/llvm/Transforms/Scalar/ConstantHoisting.h b/include/llvm/Transforms/Scalar/ConstantHoisting.h
index 3e2b3327a9fe..edc91add7a73 100644
--- a/include/llvm/Transforms/Scalar/ConstantHoisting.h
+++ b/include/llvm/Transforms/Scalar/ConstantHoisting.h
@@ -36,6 +36,7 @@
#ifndef LLVM_TRANSFORMS_SCALAR_CONSTANTHOISTING_H
#define LLVM_TRANSFORMS_SCALAR_CONSTANTHOISTING_H
+#include "llvm/Analysis/BlockFrequencyInfo.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/PassManager.h"
@@ -98,7 +99,7 @@ public:
// Glue for old PM.
bool runImpl(Function &F, TargetTransformInfo &TTI, DominatorTree &DT,
- BasicBlock &Entry);
+ BlockFrequencyInfo *BFI, BasicBlock &Entry);
void releaseMemory() {
ConstantVec.clear();
@@ -112,6 +113,7 @@ private:
const TargetTransformInfo *TTI;
DominatorTree *DT;
+ BlockFrequencyInfo *BFI;
BasicBlock *Entry;
/// Keeps track of constant candidates found in the function.
@@ -124,8 +126,8 @@ private:
SmallVector<consthoist::ConstantInfo, 8> ConstantVec;
Instruction *findMatInsertPt(Instruction *Inst, unsigned Idx = ~0U) const;
- Instruction *findConstantInsertionPoint(
- const consthoist::ConstantInfo &ConstInfo) const;
+ SmallPtrSet<Instruction *, 8>
+ findConstantInsertionPoint(const consthoist::ConstantInfo &ConstInfo) const;
void collectConstantCandidates(ConstCandMapType &ConstCandMap,
Instruction *Inst, unsigned Idx,
ConstantInt *ConstInt);
diff --git a/lib/Analysis/BasicAliasAnalysis.cpp b/lib/Analysis/BasicAliasAnalysis.cpp
index 3db041cc0fa6..537823020301 100644
--- a/lib/Analysis/BasicAliasAnalysis.cpp
+++ b/lib/Analysis/BasicAliasAnalysis.cpp
@@ -924,8 +924,8 @@ static AliasResult aliasSameBasePointerGEPs(const GEPOperator *GEP1,
uint64_t V2Size,
const DataLayout &DL) {
- assert(GEP1->getPointerOperand()->stripPointerCasts() ==
- GEP2->getPointerOperand()->stripPointerCasts() &&
+ assert(GEP1->getPointerOperand()->stripPointerCastsAndBarriers() ==
+ GEP2->getPointerOperand()->stripPointerCastsAndBarriers() &&
GEP1->getPointerOperandType() == GEP2->getPointerOperandType() &&
"Expected GEPs with the same pointer operand");
@@ -1184,8 +1184,8 @@ AliasResult BasicAAResult::aliasGEP(const GEPOperator *GEP1, uint64_t V1Size,
// If we know the two GEPs are based off of the exact same pointer (and not
// just the same underlying object), see if that tells us anything about
// the resulting pointers.
- if (GEP1->getPointerOperand()->stripPointerCasts() ==
- GEP2->getPointerOperand()->stripPointerCasts() &&
+ if (GEP1->getPointerOperand()->stripPointerCastsAndBarriers() ==
+ GEP2->getPointerOperand()->stripPointerCastsAndBarriers() &&
GEP1->getPointerOperandType() == GEP2->getPointerOperandType()) {
AliasResult R = aliasSameBasePointerGEPs(GEP1, V1Size, GEP2, V2Size, DL);
// If we couldn't find anything interesting, don't abandon just yet.
@@ -1500,8 +1500,8 @@ AliasResult BasicAAResult::aliasCheck(const Value *V1, uint64_t V1Size,
return NoAlias;
// Strip off any casts if they exist.
- V1 = V1->stripPointerCasts();
- V2 = V2->stripPointerCasts();
+ V1 = V1->stripPointerCastsAndBarriers();
+ V2 = V2->stripPointerCastsAndBarriers();
// If V1 or V2 is undef, the result is NoAlias because we can always pick a
// value for undef that aliases nothing in the program.
diff --git a/lib/Analysis/ConstantFolding.cpp b/lib/Analysis/ConstantFolding.cpp
index 14176dac2104..863fbdba7e67 100644
--- a/lib/Analysis/ConstantFolding.cpp
+++ b/lib/Analysis/ConstantFolding.cpp
@@ -42,6 +42,7 @@
#include "llvm/IR/Value.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/KnownBits.h"
#include "llvm/Support/MathExtras.h"
#include <cassert>
#include <cerrno>
@@ -687,21 +688,21 @@ Constant *SymbolicallyEvaluateBinop(unsigned Opc, Constant *Op0, Constant *Op1,
if (Opc == Instruction::And) {
unsigned BitWidth = DL.getTypeSizeInBits(Op0->getType()->getScalarType());
- APInt KnownZero0(BitWidth, 0), KnownOne0(BitWidth, 0);
- APInt KnownZero1(BitWidth, 0), KnownOne1(BitWidth, 0);
- computeKnownBits(Op0, KnownZero0, KnownOne0, DL);
- computeKnownBits(Op1, KnownZero1, KnownOne1, DL);
- if ((KnownOne1 | KnownZero0).isAllOnesValue()) {
+ KnownBits Known0(BitWidth);
+ KnownBits Known1(BitWidth);
+ computeKnownBits(Op0, Known0, DL);
+ computeKnownBits(Op1, Known1, DL);
+ if ((Known1.One | Known0.Zero).isAllOnesValue()) {
// All the bits of Op0 that the 'and' could be masking are already zero.
return Op0;
}
- if ((KnownOne0 | KnownZero1).isAllOnesValue()) {
+ if ((Known0.One | Known1.Zero).isAllOnesValue()) {
// All the bits of Op1 that the 'and' could be masking are already zero.
return Op1;
}
- APInt KnownZero = KnownZero0 | KnownZero1;
- APInt KnownOne = KnownOne0 & KnownOne1;
+ APInt KnownZero = Known0.Zero | Known1.Zero;
+ APInt KnownOne = Known0.One & Known1.One;
if ((KnownZero | KnownOne).isAllOnesValue()) {
return ConstantInt::get(Op0->getType(), KnownOne);
}
diff --git a/lib/Analysis/DemandedBits.cpp b/lib/Analysis/DemandedBits.cpp
index 151c0b0e6c93..285339deaaf5 100644
--- a/lib/Analysis/DemandedBits.cpp
+++ b/lib/Analysis/DemandedBits.cpp
@@ -37,6 +37,7 @@
#include "llvm/IR/Operator.h"
#include "llvm/Pass.h"
#include "llvm/Support/Debug.h"
+#include "llvm/Support/KnownBits.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
@@ -72,8 +73,7 @@ static bool isAlwaysLive(Instruction *I) {
void DemandedBits::determineLiveOperandBits(
const Instruction *UserI, const Instruction *I, unsigned OperandNo,
- const APInt &AOut, APInt &AB, APInt &KnownZero, APInt &KnownOne,
- APInt &KnownZero2, APInt &KnownOne2) {
+ const APInt &AOut, APInt &AB, KnownBits &Known, KnownBits &Known2) {
unsigned BitWidth = AB.getBitWidth();
// We're called once per operand, but for some instructions, we need to
@@ -85,15 +85,13 @@ void DemandedBits::determineLiveOperandBits(
auto ComputeKnownBits =
[&](unsigned BitWidth, const Value *V1, const Value *V2) {
const DataLayout &DL = I->getModule()->getDataLayout();
- KnownZero = APInt(BitWidth, 0);
- KnownOne = APInt(BitWidth, 0);
- computeKnownBits(const_cast<Value *>(V1), KnownZero, KnownOne, DL, 0,
+ Known = KnownBits(BitWidth);
+ computeKnownBits(const_cast<Value *>(V1), Known, DL, 0,
&AC, UserI, &DT);
if (V2) {
- KnownZero2 = APInt(BitWidth, 0);
- KnownOne2 = APInt(BitWidth, 0);
- computeKnownBits(const_cast<Value *>(V2), KnownZero2, KnownOne2, DL,
+ Known2 = KnownBits(BitWidth);
+ computeKnownBits(const_cast<Value *>(V2), Known2, DL,
0, &AC, UserI, &DT);
}
};
@@ -120,7 +118,7 @@ void DemandedBits::determineLiveOperandBits(
// known to be one.
ComputeKnownBits(BitWidth, I, nullptr);
AB = APInt::getHighBitsSet(BitWidth,
- std::min(BitWidth, KnownOne.countLeadingZeros()+1));
+ std::min(BitWidth, Known.One.countLeadingZeros()+1));
}
break;
case Intrinsic::cttz:
@@ -130,7 +128,7 @@ void DemandedBits::determineLiveOperandBits(
// known to be one.
ComputeKnownBits(BitWidth, I, nullptr);
AB = APInt::getLowBitsSet(BitWidth,
- std::min(BitWidth, KnownOne.countTrailingZeros()+1));
+ std::min(BitWidth, Known.One.countTrailingZeros()+1));
}
break;
}
@@ -200,11 +198,11 @@ void DemandedBits::determineLiveOperandBits(
// dead).
if (OperandNo == 0) {
ComputeKnownBits(BitWidth, I, UserI->getOperand(1));
- AB &= ~KnownZero2;
+ AB &= ~Known2.Zero;
} else {
if (!isa<Instruction>(UserI->getOperand(0)))
ComputeKnownBits(BitWidth, UserI->getOperand(0), I);
- AB &= ~(KnownZero & ~KnownZero2);
+ AB &= ~(Known.Zero & ~Known2.Zero);
}
break;
case Instruction::Or:
@@ -216,11 +214,11 @@ void DemandedBits::determineLiveOperandBits(
// dead).
if (OperandNo == 0) {
ComputeKnownBits(BitWidth, I, UserI->getOperand(1));
- AB &= ~KnownOne2;
+ AB &= ~Known2.One;
} else {
if (!isa<Instruction>(UserI->getOperand(0)))
ComputeKnownBits(BitWidth, UserI->getOperand(0), I);
- AB &= ~(KnownOne & ~KnownOne2);
+ AB &= ~(Known.One & ~Known2.One);
}
break;
case Instruction::Xor:
@@ -318,7 +316,7 @@ void DemandedBits::performAnalysis() {
if (!UserI->getType()->isIntegerTy())
Visited.insert(UserI);
- APInt KnownZero, KnownOne, KnownZero2, KnownOne2;
+ KnownBits Known, Known2;
// Compute the set of alive bits for each operand. These are anded into the
// existing set, if any, and if that changes the set of alive bits, the
// operand is added to the work-list.
@@ -335,8 +333,7 @@ void DemandedBits::performAnalysis() {
// Bits of each operand that are used to compute alive bits of the
// output are alive, all others are dead.
determineLiveOperandBits(UserI, I, OI.getOperandNo(), AOut, AB,
- KnownZero, KnownOne,
- KnownZero2, KnownOne2);
+ Known, Known2);
}
// If we've added to the set of alive bits (or the operand has not
diff --git a/lib/Analysis/DomPrinter.cpp b/lib/Analysis/DomPrinter.cpp
index 7acfb41500d4..8abc0e7d0df9 100644
--- a/lib/Analysis/DomPrinter.cpp
+++ b/lib/Analysis/DomPrinter.cpp
@@ -80,6 +80,22 @@ struct DOTGraphTraits<PostDominatorTree*>
};
}
+void DominatorTree::viewGraph(const Twine &Name, const Twine &Title) {
+#ifndef NDEBUG
+ ViewGraph(this, Name, false, Title);
+#else
+ errs() << "DomTree dump not available, build with DEBUG\n";
+#endif // NDEBUG
+}
+
+void DominatorTree::viewGraph() {
+#ifndef NDEBUG
+ this->viewGraph("domtree", "Dominator Tree for function");
+#else
+ errs() << "DomTree dump not available, build with DEBUG\n";
+#endif // NDEBUG
+}
+
namespace {
struct DominatorTreeWrapperPassAnalysisGraphTraits {
static DominatorTree *getGraph(DominatorTreeWrapperPass *DTWP) {
diff --git a/lib/Analysis/IVUsers.cpp b/lib/Analysis/IVUsers.cpp
index fde805a5fde5..c30feb973e60 100644
--- a/lib/Analysis/IVUsers.cpp
+++ b/lib/Analysis/IVUsers.cpp
@@ -253,18 +253,8 @@ bool IVUsers::AddUsersImpl(Instruction *I,
const SCEV *OriginalISE = ISE;
auto NormalizePred = [&](const SCEVAddRecExpr *AR) {
- // We only allow affine AddRecs to be normalized, otherwise we would not
- // be able to correctly denormalize.
- // e.g. {1,+,3,+,2} == {-2,+,1,+,2} + {3,+,2}
- // Normalized form: {-2,+,1,+,2}
- // Denormalized form: {1,+,3,+,2}
- //
- // However, denormalization would use a different step expression than
- // normalization (see getPostIncExpr), generating the wrong final
- // expression: {-2,+,1,+,2} + {1,+,2} => {-1,+,3,+,2}
auto *L = AR->getLoop();
- bool Result =
- AR->isAffine() && IVUseShouldUsePostIncValue(User, I, L, DT);
+ bool Result = IVUseShouldUsePostIncValue(User, I, L, DT);
if (Result)
NewUse.PostIncLoops.insert(L);
return Result;
diff --git a/lib/Analysis/InlineCost.cpp b/lib/Analysis/InlineCost.cpp
index 1f8dec2aed80..788f908bafca 100644
--- a/lib/Analysis/InlineCost.cpp
+++ b/lib/Analysis/InlineCost.cpp
@@ -1557,7 +1557,6 @@ InlineParams llvm::getInlineParams(int Threshold) {
Params.ColdCallSiteThreshold = ColdCallSiteThreshold;
// Set the OptMinSizeThreshold and OptSizeThreshold params only if the
- // Set the OptMinSizeThreshold and OptSizeThreshold params only if the
// -inlinehint-threshold commandline option is not explicitly given. If that
// option is present, then its value applies even for callees with size and
// minsize attributes.
diff --git a/lib/Analysis/InstructionSimplify.cpp b/lib/Analysis/InstructionSimplify.cpp
index 2259fbaeb982..e720e3ebecdb 100644
--- a/lib/Analysis/InstructionSimplify.cpp
+++ b/lib/Analysis/InstructionSimplify.cpp
@@ -35,6 +35,7 @@
#include "llvm/IR/Operator.h"
#include "llvm/IR/PatternMatch.h"
#include "llvm/IR/ValueHandle.h"
+#include "llvm/Support/KnownBits.h"
#include <algorithm>
using namespace llvm;
using namespace llvm::PatternMatch;
@@ -46,34 +47,19 @@ enum { RecursionLimit = 3 };
STATISTIC(NumExpand, "Number of expansions");
STATISTIC(NumReassoc, "Number of reassociations");
-namespace {
-struct Query {
- const DataLayout &DL;
- const TargetLibraryInfo *TLI;
- const DominatorTree *DT;
- AssumptionCache *AC;
- const Instruction *CxtI;
-
- Query(const DataLayout &DL, const TargetLibraryInfo *tli,
- const DominatorTree *dt, AssumptionCache *ac = nullptr,
- const Instruction *cxti = nullptr)
- : DL(DL), TLI(tli), DT(dt), AC(ac), CxtI(cxti) {}
-};
-} // end anonymous namespace
-
-static Value *SimplifyAndInst(Value *, Value *, const Query &, unsigned);
-static Value *SimplifyBinOp(unsigned, Value *, Value *, const Query &,
+static Value *SimplifyAndInst(Value *, Value *, const SimplifyQuery &, unsigned);
+static Value *SimplifyBinOp(unsigned, Value *, Value *, const SimplifyQuery &,
unsigned);
static Value *SimplifyFPBinOp(unsigned, Value *, Value *, const FastMathFlags &,
- const Query &, unsigned);
-static Value *SimplifyCmpInst(unsigned, Value *, Value *, const Query &,
+ const SimplifyQuery &, unsigned);
+static Value *SimplifyCmpInst(unsigned, Value *, Value *, const SimplifyQuery &,
unsigned);
static Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
- const Query &Q, unsigned MaxRecurse);
-static Value *SimplifyOrInst(Value *, Value *, const Query &, unsigned);
-static Value *SimplifyXorInst(Value *, Value *, const Query &, unsigned);
+ const SimplifyQuery &Q, unsigned MaxRecurse);
+static Value *SimplifyOrInst(Value *, Value *, const SimplifyQuery &, unsigned);
+static Value *SimplifyXorInst(Value *, Value *, const SimplifyQuery &, unsigned);
static Value *SimplifyCastInst(unsigned, Value *, Type *,
- const Query &, unsigned);
+ const SimplifyQuery &, unsigned);
/// For a boolean type or a vector of boolean type, return false or a vector
/// with every element false.
@@ -138,7 +124,7 @@ static bool ValueDominatesPHI(Value *V, PHINode *P, const DominatorTree *DT) {
/// Also performs the transform "(A op' B) op C" -> "(A op C) op' (B op C)".
/// Returns the simplified value, or null if no simplification was performed.
static Value *ExpandBinOp(Instruction::BinaryOps Opcode, Value *LHS, Value *RHS,
- Instruction::BinaryOps OpcodeToExpand, const Query &Q,
+ Instruction::BinaryOps OpcodeToExpand, const SimplifyQuery &Q,
unsigned MaxRecurse) {
// Recursion is always used, so bail out at once if we already hit the limit.
if (!MaxRecurse--)
@@ -196,7 +182,7 @@ static Value *ExpandBinOp(Instruction::BinaryOps Opcode, Value *LHS, Value *RHS,
/// Generic simplifications for associative binary operations.
/// Returns the simpler value, or null if none was found.
static Value *SimplifyAssociativeBinOp(Instruction::BinaryOps Opcode,
- Value *LHS, Value *RHS, const Query &Q,
+ Value *LHS, Value *RHS, const SimplifyQuery &Q,
unsigned MaxRecurse) {
assert(Instruction::isAssociative(Opcode) && "Not an associative operation!");
@@ -295,7 +281,7 @@ static Value *SimplifyAssociativeBinOp(Instruction::BinaryOps Opcode,
/// of the select results in the same value. Returns the common value if so,
/// otherwise returns null.
static Value *ThreadBinOpOverSelect(Instruction::BinaryOps Opcode, Value *LHS,
- Value *RHS, const Query &Q,
+ Value *RHS, const SimplifyQuery &Q,
unsigned MaxRecurse) {
// Recursion is always used, so bail out at once if we already hit the limit.
if (!MaxRecurse--)
@@ -367,7 +353,7 @@ static Value *ThreadBinOpOverSelect(Instruction::BinaryOps Opcode, Value *LHS,
/// comparison by seeing whether both branches of the select result in the same
/// value. Returns the common value if so, otherwise returns null.
static Value *ThreadCmpOverSelect(CmpInst::Predicate Pred, Value *LHS,
- Value *RHS, const Query &Q,
+ Value *RHS, const SimplifyQuery &Q,
unsigned MaxRecurse) {
// Recursion is always used, so bail out at once if we already hit the limit.
if (!MaxRecurse--)
@@ -449,7 +435,7 @@ static Value *ThreadCmpOverSelect(CmpInst::Predicate Pred, Value *LHS,
/// phi values yields the same result for every value. If so returns the common
/// value, otherwise returns null.
static Value *ThreadBinOpOverPHI(Instruction::BinaryOps Opcode, Value *LHS,
- Value *RHS, const Query &Q,
+ Value *RHS, const SimplifyQuery &Q,
unsigned MaxRecurse) {
// Recursion is always used, so bail out at once if we already hit the limit.
if (!MaxRecurse--)
@@ -492,7 +478,7 @@ static Value *ThreadBinOpOverPHI(Instruction::BinaryOps Opcode, Value *LHS,
/// yields the same result every time. If so returns the common result,
/// otherwise returns null.
static Value *ThreadCmpOverPHI(CmpInst::Predicate Pred, Value *LHS, Value *RHS,
- const Query &Q, unsigned MaxRecurse) {
+ const SimplifyQuery &Q, unsigned MaxRecurse) {
// Recursion is always used, so bail out at once if we already hit the limit.
if (!MaxRecurse--)
return nullptr;
@@ -527,7 +513,7 @@ static Value *ThreadCmpOverPHI(CmpInst::Predicate Pred, Value *LHS, Value *RHS,
static Constant *foldOrCommuteConstant(Instruction::BinaryOps Opcode,
Value *&Op0, Value *&Op1,
- const Query &Q) {
+ const SimplifyQuery &Q) {
if (auto *CLHS = dyn_cast<Constant>(Op0)) {
if (auto *CRHS = dyn_cast<Constant>(Op1))
return ConstantFoldBinaryOpOperands(Opcode, CLHS, CRHS, Q.DL);
@@ -542,7 +528,7 @@ static Constant *foldOrCommuteConstant(Instruction::BinaryOps Opcode,
/// Given operands for an Add, see if we can fold the result.
/// If not, this returns null.
static Value *SimplifyAddInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW,
- const Query &Q, unsigned MaxRecurse) {
+ const SimplifyQuery &Q, unsigned MaxRecurse) {
if (Constant *C = foldOrCommuteConstant(Instruction::Add, Op0, Op1, Q))
return C;
@@ -601,10 +587,15 @@ Value *llvm::SimplifyAddInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW,
const DataLayout &DL, const TargetLibraryInfo *TLI,
const DominatorTree *DT, AssumptionCache *AC,
const Instruction *CxtI) {
- return ::SimplifyAddInst(Op0, Op1, isNSW, isNUW, Query(DL, TLI, DT, AC, CxtI),
+ return ::SimplifyAddInst(Op0, Op1, isNSW, isNUW, {DL, TLI, DT, AC, CxtI},
RecursionLimit);
}
+Value *llvm::SimplifyAddInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW,
+ const SimplifyQuery &Query) {
+ return ::SimplifyAddInst(Op0, Op1, isNSW, isNUW, Query, RecursionLimit);
+}
+
/// \brief Compute the base pointer and cumulative constant offsets for V.
///
/// This strips all constant offsets off of V, leaving it the base pointer, and
@@ -679,7 +670,7 @@ static Constant *computePointerDifference(const DataLayout &DL, Value *LHS,
/// Given operands for a Sub, see if we can fold the result.
/// If not, this returns null.
static Value *SimplifySubInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW,
- const Query &Q, unsigned MaxRecurse) {
+ const SimplifyQuery &Q, unsigned MaxRecurse) {
if (Constant *C = foldOrCommuteConstant(Instruction::Sub, Op0, Op1, Q))
return C;
@@ -703,10 +694,9 @@ static Value *SimplifySubInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW,
return Op0;
unsigned BitWidth = Op1->getType()->getScalarSizeInBits();
- APInt KnownZero(BitWidth, 0);
- APInt KnownOne(BitWidth, 0);
- computeKnownBits(Op1, KnownZero, KnownOne, Q.DL, 0, Q.AC, Q.CxtI, Q.DT);
- if (KnownZero.isMaxSignedValue()) {
+ KnownBits Known(BitWidth);
+ computeKnownBits(Op1, Known, Q.DL, 0, Q.AC, Q.CxtI, Q.DT);
+ if (Known.Zero.isMaxSignedValue()) {
// Op1 is either 0 or the minimum signed value. If the sub is NSW, then
// Op1 must be 0 because negating the minimum signed value is undefined.
if (isNSW)
@@ -813,14 +803,19 @@ Value *llvm::SimplifySubInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW,
const DataLayout &DL, const TargetLibraryInfo *TLI,
const DominatorTree *DT, AssumptionCache *AC,
const Instruction *CxtI) {
- return ::SimplifySubInst(Op0, Op1, isNSW, isNUW, Query(DL, TLI, DT, AC, CxtI),
+ return ::SimplifySubInst(Op0, Op1, isNSW, isNUW, {DL, TLI, DT, AC, CxtI},
RecursionLimit);
}
+Value *llvm::SimplifySubInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW,
+ const SimplifyQuery &Q) {
+ return ::SimplifySubInst(Op0, Op1, isNSW, isNUW, Q, RecursionLimit);
+}
+
/// Given operands for an FAdd, see if we can fold the result. If not, this
/// returns null.
static Value *SimplifyFAddInst(Value *Op0, Value *Op1, FastMathFlags FMF,
- const Query &Q, unsigned MaxRecurse) {
+ const SimplifyQuery &Q, unsigned MaxRecurse) {
if (Constant *C = foldOrCommuteConstant(Instruction::FAdd, Op0, Op1, Q))
return C;
@@ -854,7 +849,7 @@ static Value *SimplifyFAddInst(Value *Op0, Value *Op1, FastMathFlags FMF,
/// Given operands for an FSub, see if we can fold the result. If not, this
/// returns null.
static Value *SimplifyFSubInst(Value *Op0, Value *Op1, FastMathFlags FMF,
- const Query &Q, unsigned MaxRecurse) {
+ const SimplifyQuery &Q, unsigned MaxRecurse) {
if (Constant *C = foldOrCommuteConstant(Instruction::FSub, Op0, Op1, Q))
return C;
@@ -886,7 +881,7 @@ static Value *SimplifyFSubInst(Value *Op0, Value *Op1, FastMathFlags FMF,
/// Given the operands for an FMul, see if we can fold the result
static Value *SimplifyFMulInst(Value *Op0, Value *Op1, FastMathFlags FMF,
- const Query &Q, unsigned MaxRecurse) {
+ const SimplifyQuery &Q, unsigned MaxRecurse) {
if (Constant *C = foldOrCommuteConstant(Instruction::FMul, Op0, Op1, Q))
return C;
@@ -903,7 +898,7 @@ static Value *SimplifyFMulInst(Value *Op0, Value *Op1, FastMathFlags FMF,
/// Given operands for a Mul, see if we can fold the result.
/// If not, this returns null.
-static Value *SimplifyMulInst(Value *Op0, Value *Op1, const Query &Q,
+static Value *SimplifyMulInst(Value *Op0, Value *Op1, const SimplifyQuery &Q,
unsigned MaxRecurse) {
if (Constant *C = foldOrCommuteConstant(Instruction::Mul, Op0, Op1, Q))
return C;
@@ -963,34 +958,52 @@ Value *llvm::SimplifyFAddInst(Value *Op0, Value *Op1, FastMathFlags FMF,
const TargetLibraryInfo *TLI,
const DominatorTree *DT, AssumptionCache *AC,
const Instruction *CxtI) {
- return ::SimplifyFAddInst(Op0, Op1, FMF, Query(DL, TLI, DT, AC, CxtI),
+ return ::SimplifyFAddInst(Op0, Op1, FMF, {DL, TLI, DT, AC, CxtI},
RecursionLimit);
}
+Value *llvm::SimplifyFAddInst(Value *Op0, Value *Op1, FastMathFlags FMF,
+ const SimplifyQuery &Q) {
+ return ::SimplifyFAddInst(Op0, Op1, FMF, Q, RecursionLimit);
+}
+
Value *llvm::SimplifyFSubInst(Value *Op0, Value *Op1, FastMathFlags FMF,
const DataLayout &DL,
const TargetLibraryInfo *TLI,
const DominatorTree *DT, AssumptionCache *AC,
const Instruction *CxtI) {
- return ::SimplifyFSubInst(Op0, Op1, FMF, Query(DL, TLI, DT, AC, CxtI),
+ return ::SimplifyFSubInst(Op0, Op1, FMF, {DL, TLI, DT, AC, CxtI},
RecursionLimit);
}
+Value *llvm::SimplifyFSubInst(Value *Op0, Value *Op1, FastMathFlags FMF,
+ const SimplifyQuery &Q) {
+ return ::SimplifyFSubInst(Op0, Op1, FMF, Q, RecursionLimit);
+}
+
Value *llvm::SimplifyFMulInst(Value *Op0, Value *Op1, FastMathFlags FMF,
const DataLayout &DL,
const TargetLibraryInfo *TLI,
const DominatorTree *DT, AssumptionCache *AC,
const Instruction *CxtI) {
- return ::SimplifyFMulInst(Op0, Op1, FMF, Query(DL, TLI, DT, AC, CxtI),
+ return ::SimplifyFMulInst(Op0, Op1, FMF, {DL, TLI, DT, AC, CxtI},
RecursionLimit);
}
+Value *llvm::SimplifyFMulInst(Value *Op0, Value *Op1, FastMathFlags FMF,
+ const SimplifyQuery &Q) {
+ return ::SimplifyFMulInst(Op0, Op1, FMF, Q, RecursionLimit);
+}
+
Value *llvm::SimplifyMulInst(Value *Op0, Value *Op1, const DataLayout &DL,
const TargetLibraryInfo *TLI,
const DominatorTree *DT, AssumptionCache *AC,
const Instruction *CxtI) {
- return ::SimplifyMulInst(Op0, Op1, Query(DL, TLI, DT, AC, CxtI),
- RecursionLimit);
+ return ::SimplifyMulInst(Op0, Op1, {DL, TLI, DT, AC, CxtI}, RecursionLimit);
+}
+
+Value *llvm::SimplifyMulInst(Value *Op0, Value *Op1, const SimplifyQuery &Q) {
+ return ::SimplifyMulInst(Op0, Op1, Q, RecursionLimit);
}
/// Check for common or similar folds of integer division or integer remainder.
@@ -1047,7 +1060,7 @@ static Value *simplifyDivRem(Value *Op0, Value *Op1, bool IsDiv) {
/// Given operands for an SDiv or UDiv, see if we can fold the result.
/// If not, this returns null.
static Value *SimplifyDiv(Instruction::BinaryOps Opcode, Value *Op0, Value *Op1,
- const Query &Q, unsigned MaxRecurse) {
+ const SimplifyQuery &Q, unsigned MaxRecurse) {
if (Constant *C = foldOrCommuteConstant(Opcode, Op0, Op1, Q))
return C;
@@ -1103,7 +1116,7 @@ static Value *SimplifyDiv(Instruction::BinaryOps Opcode, Value *Op0, Value *Op1,
/// Given operands for an SDiv, see if we can fold the result.
/// If not, this returns null.
-static Value *SimplifySDivInst(Value *Op0, Value *Op1, const Query &Q,
+static Value *SimplifySDivInst(Value *Op0, Value *Op1, const SimplifyQuery &Q,
unsigned MaxRecurse) {
if (Value *V = SimplifyDiv(Instruction::SDiv, Op0, Op1, Q, MaxRecurse))
return V;
@@ -1115,13 +1128,16 @@ Value *llvm::SimplifySDivInst(Value *Op0, Value *Op1, const DataLayout &DL,
const TargetLibraryInfo *TLI,
const DominatorTree *DT, AssumptionCache *AC,
const Instruction *CxtI) {
- return ::SimplifySDivInst(Op0, Op1, Query(DL, TLI, DT, AC, CxtI),
- RecursionLimit);
+ return ::SimplifySDivInst(Op0, Op1, {DL, TLI, DT, AC, CxtI}, RecursionLimit);
+}
+
+Value *llvm::SimplifySDivInst(Value *Op0, Value *Op1, const SimplifyQuery &Q) {
+ return ::SimplifySDivInst(Op0, Op1, Q, RecursionLimit);
}
/// Given operands for a UDiv, see if we can fold the result.
/// If not, this returns null.
-static Value *SimplifyUDivInst(Value *Op0, Value *Op1, const Query &Q,
+static Value *SimplifyUDivInst(Value *Op0, Value *Op1, const SimplifyQuery &Q,
unsigned MaxRecurse) {
if (Value *V = SimplifyDiv(Instruction::UDiv, Op0, Op1, Q, MaxRecurse))
return V;
@@ -1143,12 +1159,15 @@ Value *llvm::SimplifyUDivInst(Value *Op0, Value *Op1, const DataLayout &DL,
const TargetLibraryInfo *TLI,
const DominatorTree *DT, AssumptionCache *AC,
const Instruction *CxtI) {
- return ::SimplifyUDivInst(Op0, Op1, Query(DL, TLI, DT, AC, CxtI),
- RecursionLimit);
+ return ::SimplifyUDivInst(Op0, Op1, {DL, TLI, DT, AC, CxtI}, RecursionLimit);
+}
+
+Value *llvm::SimplifyUDivInst(Value *Op0, Value *Op1, const SimplifyQuery &Q) {
+ return ::SimplifyUDivInst(Op0, Op1, Q, RecursionLimit);
}
static Value *SimplifyFDivInst(Value *Op0, Value *Op1, FastMathFlags FMF,
- const Query &Q, unsigned) {
+ const SimplifyQuery &Q, unsigned) {
if (Constant *C = foldOrCommuteConstant(Instruction::FDiv, Op0, Op1, Q))
return C;
@@ -1193,14 +1212,19 @@ Value *llvm::SimplifyFDivInst(Value *Op0, Value *Op1, FastMathFlags FMF,
const TargetLibraryInfo *TLI,
const DominatorTree *DT, AssumptionCache *AC,
const Instruction *CxtI) {
- return ::SimplifyFDivInst(Op0, Op1, FMF, Query(DL, TLI, DT, AC, CxtI),
+ return ::SimplifyFDivInst(Op0, Op1, FMF, {DL, TLI, DT, AC, CxtI},
RecursionLimit);
}
+Value *llvm::SimplifyFDivInst(Value *Op0, Value *Op1, FastMathFlags FMF,
+ const SimplifyQuery &Q) {
+ return ::SimplifyFDivInst(Op0, Op1, FMF, Q, RecursionLimit);
+}
+
/// Given operands for an SRem or URem, see if we can fold the result.
/// If not, this returns null.
static Value *SimplifyRem(Instruction::BinaryOps Opcode, Value *Op0, Value *Op1,
- const Query &Q, unsigned MaxRecurse) {
+ const SimplifyQuery &Q, unsigned MaxRecurse) {
if (Constant *C = foldOrCommuteConstant(Opcode, Op0, Op1, Q))
return C;
@@ -1231,7 +1255,7 @@ static Value *SimplifyRem(Instruction::BinaryOps Opcode, Value *Op0, Value *Op1,
/// Given operands for an SRem, see if we can fold the result.
/// If not, this returns null.
-static Value *SimplifySRemInst(Value *Op0, Value *Op1, const Query &Q,
+static Value *SimplifySRemInst(Value *Op0, Value *Op1, const SimplifyQuery &Q,
unsigned MaxRecurse) {
if (Value *V = SimplifyRem(Instruction::SRem, Op0, Op1, Q, MaxRecurse))
return V;
@@ -1243,13 +1267,16 @@ Value *llvm::SimplifySRemInst(Value *Op0, Value *Op1, const DataLayout &DL,
const TargetLibraryInfo *TLI,
const DominatorTree *DT, AssumptionCache *AC,
const Instruction *CxtI) {
- return ::SimplifySRemInst(Op0, Op1, Query(DL, TLI, DT, AC, CxtI),
- RecursionLimit);
+ return ::SimplifySRemInst(Op0, Op1, {DL, TLI, DT, AC, CxtI}, RecursionLimit);
+}
+
+Value *llvm::SimplifySRemInst(Value *Op0, Value *Op1, const SimplifyQuery &Q) {
+ return ::SimplifySRemInst(Op0, Op1, Q, RecursionLimit);
}
/// Given operands for a URem, see if we can fold the result.
/// If not, this returns null.
-static Value *SimplifyURemInst(Value *Op0, Value *Op1, const Query &Q,
+static Value *SimplifyURemInst(Value *Op0, Value *Op1, const SimplifyQuery &Q,
unsigned MaxRecurse) {
if (Value *V = SimplifyRem(Instruction::URem, Op0, Op1, Q, MaxRecurse))
return V;
@@ -1271,12 +1298,15 @@ Value *llvm::SimplifyURemInst(Value *Op0, Value *Op1, const DataLayout &DL,
const TargetLibraryInfo *TLI,
const DominatorTree *DT, AssumptionCache *AC,
const Instruction *CxtI) {
- return ::SimplifyURemInst(Op0, Op1, Query(DL, TLI, DT, AC, CxtI),
- RecursionLimit);
+ return ::SimplifyURemInst(Op0, Op1, {DL, TLI, DT, AC, CxtI}, RecursionLimit);
+}
+
+Value *llvm::SimplifyURemInst(Value *Op0, Value *Op1, const SimplifyQuery &Q) {
+ return ::SimplifyURemInst(Op0, Op1, Q, RecursionLimit);
}
static Value *SimplifyFRemInst(Value *Op0, Value *Op1, FastMathFlags FMF,
- const Query &Q, unsigned) {
+ const SimplifyQuery &Q, unsigned) {
if (Constant *C = foldOrCommuteConstant(Instruction::FRem, Op0, Op1, Q))
return C;
@@ -1302,10 +1332,15 @@ Value *llvm::SimplifyFRemInst(Value *Op0, Value *Op1, FastMathFlags FMF,
const TargetLibraryInfo *TLI,
const DominatorTree *DT, AssumptionCache *AC,
const Instruction *CxtI) {
- return ::SimplifyFRemInst(Op0, Op1, FMF, Query(DL, TLI, DT, AC, CxtI),
+ return ::SimplifyFRemInst(Op0, Op1, FMF, {DL, TLI, DT, AC, CxtI},
RecursionLimit);
}
+Value *llvm::SimplifyFRemInst(Value *Op0, Value *Op1, FastMathFlags FMF,
+ const SimplifyQuery &Q) {
+ return ::SimplifyFRemInst(Op0, Op1, FMF, Q, RecursionLimit);
+}
+
/// Returns true if a shift by \c Amount always yields undef.
static bool isUndefShift(Value *Amount) {
Constant *C = dyn_cast<Constant>(Amount);
@@ -1336,7 +1371,7 @@ static bool isUndefShift(Value *Amount) {
/// Given operands for an Shl, LShr or AShr, see if we can fold the result.
/// If not, this returns null.
static Value *SimplifyShift(Instruction::BinaryOps Opcode, Value *Op0,
- Value *Op1, const Query &Q, unsigned MaxRecurse) {
+ Value *Op1, const SimplifyQuery &Q, unsigned MaxRecurse) {
if (Constant *C = foldOrCommuteConstant(Opcode, Op0, Op1, Q))
return C;
@@ -1367,17 +1402,15 @@ static Value *SimplifyShift(Instruction::BinaryOps Opcode, Value *Op0,
// If any bits in the shift amount make that value greater than or equal to
// the number of bits in the type, the shift is undefined.
unsigned BitWidth = Op1->getType()->getScalarSizeInBits();
- APInt KnownZero(BitWidth, 0);
- APInt KnownOne(BitWidth, 0);
- computeKnownBits(Op1, KnownZero, KnownOne, Q.DL, 0, Q.AC, Q.CxtI, Q.DT);
- if (KnownOne.getLimitedValue() >= BitWidth)
+ KnownBits Known(BitWidth);
+ computeKnownBits(Op1, Known, Q.DL, 0, Q.AC, Q.CxtI, Q.DT);
+ if (Known.One.getLimitedValue() >= BitWidth)
return UndefValue::get(Op0->getType());
// If all valid bits in the shift amount are known zero, the first operand is
// unchanged.
unsigned NumValidShiftBits = Log2_32_Ceil(BitWidth);
- APInt ShiftAmountMask = APInt::getLowBitsSet(BitWidth, NumValidShiftBits);
- if ((KnownZero & ShiftAmountMask) == ShiftAmountMask)
+ if (Known.Zero.countTrailingOnes() >= NumValidShiftBits)
return Op0;
return nullptr;
@@ -1386,7 +1419,7 @@ static Value *SimplifyShift(Instruction::BinaryOps Opcode, Value *Op0,
/// \brief Given operands for an Shl, LShr or AShr, see if we can
/// fold the result. If not, this returns null.
static Value *SimplifyRightShift(Instruction::BinaryOps Opcode, Value *Op0,
- Value *Op1, bool isExact, const Query &Q,
+ Value *Op1, bool isExact, const SimplifyQuery &Q,
unsigned MaxRecurse) {
if (Value *V = SimplifyShift(Opcode, Op0, Op1, Q, MaxRecurse))
return V;
@@ -1403,11 +1436,9 @@ static Value *SimplifyRightShift(Instruction::BinaryOps Opcode, Value *Op0,
// The low bit cannot be shifted out of an exact shift if it is set.
if (isExact) {
unsigned BitWidth = Op0->getType()->getScalarSizeInBits();
- APInt Op0KnownZero(BitWidth, 0);
- APInt Op0KnownOne(BitWidth, 0);
- computeKnownBits(Op0, Op0KnownZero, Op0KnownOne, Q.DL, /*Depth=*/0, Q.AC,
- Q.CxtI, Q.DT);
- if (Op0KnownOne[0])
+ KnownBits Op0Known(BitWidth);
+ computeKnownBits(Op0, Op0Known, Q.DL, /*Depth=*/0, Q.AC, Q.CxtI, Q.DT);
+ if (Op0Known.One[0])
return Op0;
}
@@ -1417,7 +1448,7 @@ static Value *SimplifyRightShift(Instruction::BinaryOps Opcode, Value *Op0,
/// Given operands for an Shl, see if we can fold the result.
/// If not, this returns null.
static Value *SimplifyShlInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW,
- const Query &Q, unsigned MaxRecurse) {
+ const SimplifyQuery &Q, unsigned MaxRecurse) {
if (Value *V = SimplifyShift(Instruction::Shl, Op0, Op1, Q, MaxRecurse))
return V;
@@ -1437,14 +1468,19 @@ Value *llvm::SimplifyShlInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW,
const DataLayout &DL, const TargetLibraryInfo *TLI,
const DominatorTree *DT, AssumptionCache *AC,
const Instruction *CxtI) {
- return ::SimplifyShlInst(Op0, Op1, isNSW, isNUW, Query(DL, TLI, DT, AC, CxtI),
+ return ::SimplifyShlInst(Op0, Op1, isNSW, isNUW, {DL, TLI, DT, AC, CxtI},
RecursionLimit);
}
+Value *llvm::SimplifyShlInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW,
+ const SimplifyQuery &Q) {
+ return ::SimplifyShlInst(Op0, Op1, isNSW, isNUW, Q, RecursionLimit);
+}
+
/// Given operands for an LShr, see if we can fold the result.
/// If not, this returns null.
static Value *SimplifyLShrInst(Value *Op0, Value *Op1, bool isExact,
- const Query &Q, unsigned MaxRecurse) {
+ const SimplifyQuery &Q, unsigned MaxRecurse) {
if (Value *V = SimplifyRightShift(Instruction::LShr, Op0, Op1, isExact, Q,
MaxRecurse))
return V;
@@ -1462,14 +1498,19 @@ Value *llvm::SimplifyLShrInst(Value *Op0, Value *Op1, bool isExact,
const TargetLibraryInfo *TLI,
const DominatorTree *DT, AssumptionCache *AC,
const Instruction *CxtI) {
- return ::SimplifyLShrInst(Op0, Op1, isExact, Query(DL, TLI, DT, AC, CxtI),
+ return ::SimplifyLShrInst(Op0, Op1, isExact, {DL, TLI, DT, AC, CxtI},
RecursionLimit);
}
+Value *llvm::SimplifyLShrInst(Value *Op0, Value *Op1, bool isExact,
+ const SimplifyQuery &Q) {
+ return ::SimplifyLShrInst(Op0, Op1, isExact, Q, RecursionLimit);
+}
+
/// Given operands for an AShr, see if we can fold the result.
/// If not, this returns null.
static Value *SimplifyAShrInst(Value *Op0, Value *Op1, bool isExact,
- const Query &Q, unsigned MaxRecurse) {
+ const SimplifyQuery &Q, unsigned MaxRecurse) {
if (Value *V = SimplifyRightShift(Instruction::AShr, Op0, Op1, isExact, Q,
MaxRecurse))
return V;
@@ -1496,10 +1537,15 @@ Value *llvm::SimplifyAShrInst(Value *Op0, Value *Op1, bool isExact,
const TargetLibraryInfo *TLI,
const DominatorTree *DT, AssumptionCache *AC,
const Instruction *CxtI) {
- return ::SimplifyAShrInst(Op0, Op1, isExact, Query(DL, TLI, DT, AC, CxtI),
+ return ::SimplifyAShrInst(Op0, Op1, isExact, {DL, TLI, DT, AC, CxtI},
RecursionLimit);
}
+Value *llvm::SimplifyAShrInst(Value *Op0, Value *Op1, bool isExact,
+ const SimplifyQuery &Q) {
+ return ::SimplifyAShrInst(Op0, Op1, isExact, Q, RecursionLimit);
+}
+
static Value *simplifyUnsignedRangeCheck(ICmpInst *ZeroICmp,
ICmpInst *UnsignedICmp, bool IsAnd) {
Value *X, *Y;
@@ -1575,6 +1621,7 @@ static Value *SimplifyAndOfICmps(ICmpInst *Op0, ICmpInst *Op1) {
if (Value *X = simplifyAndOfICmpsWithSameOperands(Op0, Op1))
return X;
+ // FIXME: This should be shared with or-of-icmps.
// Look for this pattern: (icmp V, C0) & (icmp V, C1)).
Type *ITy = Op0->getType();
ICmpInst::Predicate Pred0, Pred1;
@@ -1584,10 +1631,16 @@ static Value *SimplifyAndOfICmps(ICmpInst *Op0, ICmpInst *Op1) {
match(Op1, m_ICmp(Pred1, m_Specific(V), m_APInt(C1)))) {
// Make a constant range that's the intersection of the two icmp ranges.
// If the intersection is empty, we know that the result is false.
- auto Range0 = ConstantRange::makeAllowedICmpRegion(Pred0, *C0);
- auto Range1 = ConstantRange::makeAllowedICmpRegion(Pred1, *C1);
+ auto Range0 = ConstantRange::makeExactICmpRegion(Pred0, *C0);
+ auto Range1 = ConstantRange::makeExactICmpRegion(Pred1, *C1);
if (Range0.intersectWith(Range1).isEmptySet())
return getFalse(ITy);
+
+ // If a range is a superset of the other, the smaller set is all we need.
+ if (Range0.contains(Range1))
+ return Op1;
+ if (Range1.contains(Range0))
+ return Op0;
}
// (icmp (add V, C0), C1) & (icmp V, C0)
@@ -1633,7 +1686,7 @@ static Value *SimplifyAndOfICmps(ICmpInst *Op0, ICmpInst *Op1) {
/// Given operands for an And, see if we can fold the result.
/// If not, this returns null.
-static Value *SimplifyAndInst(Value *Op0, Value *Op1, const Query &Q,
+static Value *SimplifyAndInst(Value *Op0, Value *Op1, const SimplifyQuery &Q,
unsigned MaxRecurse) {
if (Constant *C = foldOrCommuteConstant(Instruction::And, Op0, Op1, Q))
return C;
@@ -1744,8 +1797,11 @@ Value *llvm::SimplifyAndInst(Value *Op0, Value *Op1, const DataLayout &DL,
const TargetLibraryInfo *TLI,
const DominatorTree *DT, AssumptionCache *AC,
const Instruction *CxtI) {
- return ::SimplifyAndInst(Op0, Op1, Query(DL, TLI, DT, AC, CxtI),
- RecursionLimit);
+ return ::SimplifyAndInst(Op0, Op1, {DL, TLI, DT, AC, CxtI}, RecursionLimit);
+}
+
+Value *llvm::SimplifyAndInst(Value *Op0, Value *Op1, const SimplifyQuery &Q) {
+ return ::SimplifyAndInst(Op0, Op1, Q, RecursionLimit);
}
/// Commuted variants are assumed to be handled by calling this function again
@@ -1830,7 +1886,7 @@ static Value *SimplifyOrOfICmps(ICmpInst *Op0, ICmpInst *Op1) {
/// Given operands for an Or, see if we can fold the result.
/// If not, this returns null.
-static Value *SimplifyOrInst(Value *Op0, Value *Op1, const Query &Q,
+static Value *SimplifyOrInst(Value *Op0, Value *Op1, const SimplifyQuery &Q,
unsigned MaxRecurse) {
if (Constant *C = foldOrCommuteConstant(Instruction::Or, Op0, Op1, Q))
return C;
@@ -1877,6 +1933,25 @@ static Value *SimplifyOrInst(Value *Op0, Value *Op1, const Query &Q,
(A == Op0 || B == Op0))
return Constant::getAllOnesValue(Op0->getType());
+ // (A & ~B) | (A ^ B) -> (A ^ B)
+ // (~B & A) | (A ^ B) -> (A ^ B)
+ // (A & ~B) | (B ^ A) -> (B ^ A)
+ // (~B & A) | (B ^ A) -> (B ^ A)
+ if (match(Op1, m_Xor(m_Value(A), m_Value(B))) &&
+ (match(Op0, m_c_And(m_Specific(A), m_Not(m_Specific(B)))) ||
+ match(Op0, m_c_And(m_Not(m_Specific(A)), m_Specific(B)))))
+ return Op1;
+
+ // Commute the 'or' operands.
+ // (A ^ B) | (A & ~B) -> (A ^ B)
+ // (A ^ B) | (~B & A) -> (A ^ B)
+ // (B ^ A) | (A & ~B) -> (B ^ A)
+ // (B ^ A) | (~B & A) -> (B ^ A)
+ if (match(Op0, m_Xor(m_Value(A), m_Value(B))) &&
+ (match(Op1, m_c_And(m_Specific(A), m_Not(m_Specific(B)))) ||
+ match(Op1, m_c_And(m_Not(m_Specific(A)), m_Specific(B)))))
+ return Op0;
+
if (auto *ICILHS = dyn_cast<ICmpInst>(Op0)) {
if (auto *ICIRHS = dyn_cast<ICmpInst>(Op1)) {
if (Value *V = SimplifyOrOfICmps(ICILHS, ICIRHS))
@@ -1952,13 +2027,16 @@ Value *llvm::SimplifyOrInst(Value *Op0, Value *Op1, const DataLayout &DL,
const TargetLibraryInfo *TLI,
const DominatorTree *DT, AssumptionCache *AC,
const Instruction *CxtI) {
- return ::SimplifyOrInst(Op0, Op1, Query(DL, TLI, DT, AC, CxtI),
- RecursionLimit);
+ return ::SimplifyOrInst(Op0, Op1, {DL, TLI, DT, AC, CxtI}, RecursionLimit);
+}
+
+Value *llvm::SimplifyOrInst(Value *Op0, Value *Op1, const SimplifyQuery &Q) {
+ return ::SimplifyOrInst(Op0, Op1, Q, RecursionLimit);
}
/// Given operands for a Xor, see if we can fold the result.
/// If not, this returns null.
-static Value *SimplifyXorInst(Value *Op0, Value *Op1, const Query &Q,
+static Value *SimplifyXorInst(Value *Op0, Value *Op1, const SimplifyQuery &Q,
unsigned MaxRecurse) {
if (Constant *C = foldOrCommuteConstant(Instruction::Xor, Op0, Op1, Q))
return C;
@@ -2001,10 +2079,14 @@ Value *llvm::SimplifyXorInst(Value *Op0, Value *Op1, const DataLayout &DL,
const TargetLibraryInfo *TLI,
const DominatorTree *DT, AssumptionCache *AC,
const Instruction *CxtI) {
- return ::SimplifyXorInst(Op0, Op1, Query(DL, TLI, DT, AC, CxtI),
- RecursionLimit);
+ return ::SimplifyXorInst(Op0, Op1, {DL, TLI, DT, AC, CxtI}, RecursionLimit);
+}
+
+Value *llvm::SimplifyXorInst(Value *Op0, Value *Op1, const SimplifyQuery &Q) {
+ return ::SimplifyXorInst(Op0, Op1, Q, RecursionLimit);
}
+
static Type *GetCompareTy(Value *Op) {
return CmpInst::makeCmpResultType(Op->getType());
}
@@ -2238,7 +2320,7 @@ computePointerICmp(const DataLayout &DL, const TargetLibraryInfo *TLI,
/// Fold an icmp when its operands have i1 scalar type.
static Value *simplifyICmpOfBools(CmpInst::Predicate Pred, Value *LHS,
- Value *RHS, const Query &Q) {
+ Value *RHS, const SimplifyQuery &Q) {
Type *ITy = GetCompareTy(LHS); // The return type.
Type *OpTy = LHS->getType(); // The operand type.
if (!OpTy->getScalarType()->isIntegerTy(1))
@@ -2301,7 +2383,7 @@ static Value *simplifyICmpOfBools(CmpInst::Predicate Pred, Value *LHS,
/// Try hard to fold icmp with zero RHS because this is a common case.
static Value *simplifyICmpWithZero(CmpInst::Predicate Pred, Value *LHS,
- Value *RHS, const Query &Q) {
+ Value *RHS, const SimplifyQuery &Q) {
if (!match(RHS, m_Zero()))
return nullptr;
@@ -2556,7 +2638,7 @@ static Value *simplifyICmpWithConstant(CmpInst::Predicate Pred, Value *LHS,
}
static Value *simplifyICmpWithBinOp(CmpInst::Predicate Pred, Value *LHS,
- Value *RHS, const Query &Q,
+ Value *RHS, const SimplifyQuery &Q,
unsigned MaxRecurse) {
Type *ITy = GetCompareTy(LHS); // The return type.
@@ -2866,7 +2948,7 @@ static Value *simplifyICmpWithBinOp(CmpInst::Predicate Pred, Value *LHS,
/// Simplify integer comparisons where at least one operand of the compare
/// matches an integer min/max idiom.
static Value *simplifyICmpWithMinMax(CmpInst::Predicate Pred, Value *LHS,
- Value *RHS, const Query &Q,
+ Value *RHS, const SimplifyQuery &Q,
unsigned MaxRecurse) {
Type *ITy = GetCompareTy(LHS); // The return type.
Value *A, *B;
@@ -3070,7 +3152,7 @@ static Value *simplifyICmpWithMinMax(CmpInst::Predicate Pred, Value *LHS,
/// Given operands for an ICmpInst, see if we can fold the result.
/// If not, this returns null.
static Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
- const Query &Q, unsigned MaxRecurse) {
+ const SimplifyQuery &Q, unsigned MaxRecurse) {
CmpInst::Predicate Pred = (CmpInst::Predicate)Predicate;
assert(CmpInst::isIntPredicate(Pred) && "Not an integer compare!");
@@ -3342,11 +3424,10 @@ static Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
const APInt *RHSVal;
if (match(RHS, m_APInt(RHSVal))) {
unsigned BitWidth = RHSVal->getBitWidth();
- APInt LHSKnownZero(BitWidth, 0);
- APInt LHSKnownOne(BitWidth, 0);
- computeKnownBits(LHS, LHSKnownZero, LHSKnownOne, Q.DL, /*Depth=*/0, Q.AC,
- Q.CxtI, Q.DT);
- if (((LHSKnownZero & *RHSVal) != 0) || ((LHSKnownOne & ~(*RHSVal)) != 0))
+ KnownBits LHSKnown(BitWidth);
+ computeKnownBits(LHS, LHSKnown, Q.DL, /*Depth=*/0, Q.AC, Q.CxtI, Q.DT);
+ if (LHSKnown.Zero.intersects(*RHSVal) ||
+ !LHSKnown.One.isSubsetOf(*RHSVal))
return Pred == ICmpInst::ICMP_EQ ? ConstantInt::getFalse(ITy)
: ConstantInt::getTrue(ITy);
}
@@ -3372,14 +3453,19 @@ Value *llvm::SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
const TargetLibraryInfo *TLI,
const DominatorTree *DT, AssumptionCache *AC,
const Instruction *CxtI) {
- return ::SimplifyICmpInst(Predicate, LHS, RHS, Query(DL, TLI, DT, AC, CxtI),
+ return ::SimplifyICmpInst(Predicate, LHS, RHS, {DL, TLI, DT, AC, CxtI},
RecursionLimit);
}
+Value *llvm::SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
+ const SimplifyQuery &Q) {
+ return ::SimplifyICmpInst(Predicate, LHS, RHS, Q, RecursionLimit);
+}
+
/// Given operands for an FCmpInst, see if we can fold the result.
/// If not, this returns null.
static Value *SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
- FastMathFlags FMF, const Query &Q,
+ FastMathFlags FMF, const SimplifyQuery &Q,
unsigned MaxRecurse) {
CmpInst::Predicate Pred = (CmpInst::Predicate)Predicate;
assert(CmpInst::isFPPredicate(Pred) && "Not an FP compare!");
@@ -3505,13 +3591,18 @@ Value *llvm::SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
const TargetLibraryInfo *TLI,
const DominatorTree *DT, AssumptionCache *AC,
const Instruction *CxtI) {
- return ::SimplifyFCmpInst(Predicate, LHS, RHS, FMF,
- Query(DL, TLI, DT, AC, CxtI), RecursionLimit);
+ return ::SimplifyFCmpInst(Predicate, LHS, RHS, FMF, {DL, TLI, DT, AC, CxtI},
+ RecursionLimit);
+}
+
+Value *llvm::SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
+ FastMathFlags FMF, const SimplifyQuery &Q) {
+ return ::SimplifyFCmpInst(Predicate, LHS, RHS, FMF, Q, RecursionLimit);
}
/// See if V simplifies when its operand Op is replaced with RepOp.
static const Value *SimplifyWithOpReplaced(Value *V, Value *Op, Value *RepOp,
- const Query &Q,
+ const SimplifyQuery &Q,
unsigned MaxRecurse) {
// Trivial replacement.
if (V == Op)
@@ -3659,7 +3750,7 @@ static Value *simplifySelectWithFakeICmpEq(Value *CmpLHS, Value *TrueVal,
/// Try to simplify a select instruction when its condition operand is an
/// integer comparison.
static Value *simplifySelectWithICmpCond(Value *CondVal, Value *TrueVal,
- Value *FalseVal, const Query &Q,
+ Value *FalseVal, const SimplifyQuery &Q,
unsigned MaxRecurse) {
ICmpInst::Predicate Pred;
Value *CmpLHS, *CmpRHS;
@@ -3738,7 +3829,7 @@ static Value *simplifySelectWithICmpCond(Value *CondVal, Value *TrueVal,
/// Given operands for a SelectInst, see if we can fold the result.
/// If not, this returns null.
static Value *SimplifySelectInst(Value *CondVal, Value *TrueVal,
- Value *FalseVal, const Query &Q,
+ Value *FalseVal, const SimplifyQuery &Q,
unsigned MaxRecurse) {
// select true, X, Y -> X
// select false, X, Y -> Y
@@ -3775,14 +3866,19 @@ Value *llvm::SimplifySelectInst(Value *Cond, Value *TrueVal, Value *FalseVal,
const TargetLibraryInfo *TLI,
const DominatorTree *DT, AssumptionCache *AC,
const Instruction *CxtI) {
- return ::SimplifySelectInst(Cond, TrueVal, FalseVal,
- Query(DL, TLI, DT, AC, CxtI), RecursionLimit);
+ return ::SimplifySelectInst(Cond, TrueVal, FalseVal, {DL, TLI, DT, AC, CxtI},
+ RecursionLimit);
+}
+
+Value *llvm::SimplifySelectInst(Value *Cond, Value *TrueVal, Value *FalseVal,
+ const SimplifyQuery &Q) {
+ return ::SimplifySelectInst(Cond, TrueVal, FalseVal, Q, RecursionLimit);
}
/// Given operands for an GetElementPtrInst, see if we can fold the result.
/// If not, this returns null.
static Value *SimplifyGEPInst(Type *SrcTy, ArrayRef<Value *> Ops,
- const Query &Q, unsigned) {
+ const SimplifyQuery &Q, unsigned) {
// The type of the GEP pointer operand.
unsigned AS =
cast<PointerType>(Ops[0]->getType()->getScalarType())->getAddressSpace();
@@ -3896,14 +3992,18 @@ Value *llvm::SimplifyGEPInst(Type *SrcTy, ArrayRef<Value *> Ops,
const TargetLibraryInfo *TLI,
const DominatorTree *DT, AssumptionCache *AC,
const Instruction *CxtI) {
- return ::SimplifyGEPInst(SrcTy, Ops,
- Query(DL, TLI, DT, AC, CxtI), RecursionLimit);
+ return ::SimplifyGEPInst(SrcTy, Ops, {DL, TLI, DT, AC, CxtI}, RecursionLimit);
+}
+
+Value *llvm::SimplifyGEPInst(Type *SrcTy, ArrayRef<Value *> Ops,
+ const SimplifyQuery &Q) {
+ return ::SimplifyGEPInst(SrcTy, Ops, Q, RecursionLimit);
}
/// Given operands for an InsertValueInst, see if we can fold the result.
/// If not, this returns null.
static Value *SimplifyInsertValueInst(Value *Agg, Value *Val,
- ArrayRef<unsigned> Idxs, const Query &Q,
+ ArrayRef<unsigned> Idxs, const SimplifyQuery &Q,
unsigned) {
if (Constant *CAgg = dyn_cast<Constant>(Agg))
if (Constant *CVal = dyn_cast<Constant>(Val))
@@ -3933,14 +4033,20 @@ Value *llvm::SimplifyInsertValueInst(
Value *Agg, Value *Val, ArrayRef<unsigned> Idxs, const DataLayout &DL,
const TargetLibraryInfo *TLI, const DominatorTree *DT, AssumptionCache *AC,
const Instruction *CxtI) {
- return ::SimplifyInsertValueInst(Agg, Val, Idxs, Query(DL, TLI, DT, AC, CxtI),
+ return ::SimplifyInsertValueInst(Agg, Val, Idxs, {DL, TLI, DT, AC, CxtI},
RecursionLimit);
}
+Value *llvm::SimplifyInsertValueInst(Value *Agg, Value *Val,
+ ArrayRef<unsigned> Idxs,
+ const SimplifyQuery &Q) {
+ return ::SimplifyInsertValueInst(Agg, Val, Idxs, Q, RecursionLimit);
+}
+
/// Given operands for an ExtractValueInst, see if we can fold the result.
/// If not, this returns null.
static Value *SimplifyExtractValueInst(Value *Agg, ArrayRef<unsigned> Idxs,
- const Query &, unsigned) {
+ const SimplifyQuery &, unsigned) {
if (auto *CAgg = dyn_cast<Constant>(Agg))
return ConstantFoldExtractValueInstruction(CAgg, Idxs);
@@ -3968,13 +4074,18 @@ Value *llvm::SimplifyExtractValueInst(Value *Agg, ArrayRef<unsigned> Idxs,
const DominatorTree *DT,
AssumptionCache *AC,
const Instruction *CxtI) {
- return ::SimplifyExtractValueInst(Agg, Idxs, Query(DL, TLI, DT, AC, CxtI),
+ return ::SimplifyExtractValueInst(Agg, Idxs, {DL, TLI, DT, AC, CxtI},
RecursionLimit);
}
+Value *llvm::SimplifyExtractValueInst(Value *Agg, ArrayRef<unsigned> Idxs,
+ const SimplifyQuery &Q) {
+ return ::SimplifyExtractValueInst(Agg, Idxs, Q, RecursionLimit);
+}
+
/// Given operands for an ExtractElementInst, see if we can fold the result.
/// If not, this returns null.
-static Value *SimplifyExtractElementInst(Value *Vec, Value *Idx, const Query &,
+static Value *SimplifyExtractElementInst(Value *Vec, Value *Idx, const SimplifyQuery &,
unsigned) {
if (auto *CVec = dyn_cast<Constant>(Vec)) {
if (auto *CIdx = dyn_cast<Constant>(Idx))
@@ -4000,12 +4111,17 @@ static Value *SimplifyExtractElementInst(Value *Vec, Value *Idx, const Query &,
Value *llvm::SimplifyExtractElementInst(
Value *Vec, Value *Idx, const DataLayout &DL, const TargetLibraryInfo *TLI,
const DominatorTree *DT, AssumptionCache *AC, const Instruction *CxtI) {
- return ::SimplifyExtractElementInst(Vec, Idx, Query(DL, TLI, DT, AC, CxtI),
+ return ::SimplifyExtractElementInst(Vec, Idx, {DL, TLI, DT, AC, CxtI},
RecursionLimit);
}
+Value *llvm::SimplifyExtractElementInst(Value *Vec, Value *Idx,
+ const SimplifyQuery &Q) {
+ return ::SimplifyExtractElementInst(Vec, Idx, Q, RecursionLimit);
+}
+
/// See if we can fold the given phi. If not, returns null.
-static Value *SimplifyPHINode(PHINode *PN, const Query &Q) {
+static Value *SimplifyPHINode(PHINode *PN, const SimplifyQuery &Q) {
// If all of the PHI's incoming values are the same then replace the PHI node
// with the common value.
Value *CommonValue = nullptr;
@@ -4038,7 +4154,7 @@ static Value *SimplifyPHINode(PHINode *PN, const Query &Q) {
}
static Value *SimplifyCastInst(unsigned CastOpc, Value *Op,
- Type *Ty, const Query &Q, unsigned MaxRecurse) {
+ Type *Ty, const SimplifyQuery &Q, unsigned MaxRecurse) {
if (auto *C = dyn_cast<Constant>(Op))
return ConstantFoldCastOperand(CastOpc, C, Ty, Q.DL);
@@ -4076,10 +4192,15 @@ Value *llvm::SimplifyCastInst(unsigned CastOpc, Value *Op, Type *Ty,
const TargetLibraryInfo *TLI,
const DominatorTree *DT, AssumptionCache *AC,
const Instruction *CxtI) {
- return ::SimplifyCastInst(CastOpc, Op, Ty, Query(DL, TLI, DT, AC, CxtI),
+ return ::SimplifyCastInst(CastOpc, Op, Ty, {DL, TLI, DT, AC, CxtI},
RecursionLimit);
}
+Value *llvm::SimplifyCastInst(unsigned CastOpc, Value *Op, Type *Ty,
+ const SimplifyQuery &Q) {
+ return ::SimplifyCastInst(CastOpc, Op, Ty, Q, RecursionLimit);
+}
+
/// For the given destination element of a shuffle, peek through shuffles to
/// match a root vector source operand that contains that element in the same
/// vector lane (ie, the same mask index), so we can eliminate the shuffle(s).
@@ -4135,7 +4256,7 @@ static Value *foldIdentityShuffles(int DestElt, Value *Op0, Value *Op1,
}
static Value *SimplifyShuffleVectorInst(Value *Op0, Value *Op1, Constant *Mask,
- Type *RetTy, const Query &Q,
+ Type *RetTy, const SimplifyQuery &Q,
unsigned MaxRecurse) {
Type *InVecTy = Op0->getType();
unsigned MaskNumElts = Mask->getType()->getVectorNumElements();
@@ -4207,8 +4328,13 @@ Value *llvm::SimplifyShuffleVectorInst(
Value *Op0, Value *Op1, Constant *Mask, Type *RetTy,
const DataLayout &DL, const TargetLibraryInfo *TLI, const DominatorTree *DT,
AssumptionCache *AC, const Instruction *CxtI) {
- return ::SimplifyShuffleVectorInst(
- Op0, Op1, Mask, RetTy, Query(DL, TLI, DT, AC, CxtI), RecursionLimit);
+ return ::SimplifyShuffleVectorInst(Op0, Op1, Mask, RetTy,
+ {DL, TLI, DT, AC, CxtI}, RecursionLimit);
+}
+
+Value *llvm::SimplifyShuffleVectorInst(Value *Op0, Value *Op1, Constant *Mask,
+ Type *RetTy, const SimplifyQuery &Q) {
+ return ::SimplifyShuffleVectorInst(Op0, Op1, Mask, RetTy, Q, RecursionLimit);
}
//=== Helper functions for higher up the class hierarchy.
@@ -4216,7 +4342,7 @@ Value *llvm::SimplifyShuffleVectorInst(
/// Given operands for a BinaryOperator, see if we can fold the result.
/// If not, this returns null.
static Value *SimplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS,
- const Query &Q, unsigned MaxRecurse) {
+ const SimplifyQuery &Q, unsigned MaxRecurse) {
switch (Opcode) {
case Instruction::Add:
return SimplifyAddInst(LHS, RHS, false, false, Q, MaxRecurse);
@@ -4264,7 +4390,7 @@ static Value *SimplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS,
/// In contrast to SimplifyBinOp, try to use FastMathFlag when folding the
/// result. In case we don't need FastMathFlags, simply fall to SimplifyBinOp.
static Value *SimplifyFPBinOp(unsigned Opcode, Value *LHS, Value *RHS,
- const FastMathFlags &FMF, const Query &Q,
+ const FastMathFlags &FMF, const SimplifyQuery &Q,
unsigned MaxRecurse) {
switch (Opcode) {
case Instruction::FAdd:
@@ -4284,22 +4410,32 @@ Value *llvm::SimplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS,
const DataLayout &DL, const TargetLibraryInfo *TLI,
const DominatorTree *DT, AssumptionCache *AC,
const Instruction *CxtI) {
- return ::SimplifyBinOp(Opcode, LHS, RHS, Query(DL, TLI, DT, AC, CxtI),
+ return ::SimplifyBinOp(Opcode, LHS, RHS, {DL, TLI, DT, AC, CxtI},
RecursionLimit);
}
+Value *llvm::SimplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS,
+ const SimplifyQuery &Q) {
+ return ::SimplifyBinOp(Opcode, LHS, RHS, Q, RecursionLimit);
+}
+
Value *llvm::SimplifyFPBinOp(unsigned Opcode, Value *LHS, Value *RHS,
- const FastMathFlags &FMF, const DataLayout &DL,
+ FastMathFlags FMF, const DataLayout &DL,
const TargetLibraryInfo *TLI,
const DominatorTree *DT, AssumptionCache *AC,
const Instruction *CxtI) {
- return ::SimplifyFPBinOp(Opcode, LHS, RHS, FMF, Query(DL, TLI, DT, AC, CxtI),
+ return ::SimplifyFPBinOp(Opcode, LHS, RHS, FMF, {DL, TLI, DT, AC, CxtI},
RecursionLimit);
}
+Value *llvm::SimplifyFPBinOp(unsigned Opcode, Value *LHS, Value *RHS,
+ FastMathFlags FMF, const SimplifyQuery &Q) {
+ return ::SimplifyFPBinOp(Opcode, LHS, RHS, FMF, Q, RecursionLimit);
+}
+
/// Given operands for a CmpInst, see if we can fold the result.
static Value *SimplifyCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
- const Query &Q, unsigned MaxRecurse) {
+ const SimplifyQuery &Q, unsigned MaxRecurse) {
if (CmpInst::isIntPredicate((CmpInst::Predicate)Predicate))
return SimplifyICmpInst(Predicate, LHS, RHS, Q, MaxRecurse);
return SimplifyFCmpInst(Predicate, LHS, RHS, FastMathFlags(), Q, MaxRecurse);
@@ -4309,10 +4445,15 @@ Value *llvm::SimplifyCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
const DataLayout &DL, const TargetLibraryInfo *TLI,
const DominatorTree *DT, AssumptionCache *AC,
const Instruction *CxtI) {
- return ::SimplifyCmpInst(Predicate, LHS, RHS, Query(DL, TLI, DT, AC, CxtI),
+ return ::SimplifyCmpInst(Predicate, LHS, RHS, {DL, TLI, DT, AC, CxtI},
RecursionLimit);
}
+Value *llvm::SimplifyCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
+ const SimplifyQuery &Q) {
+ return ::SimplifyCmpInst(Predicate, LHS, RHS, Q, RecursionLimit);
+}
+
static bool IsIdempotent(Intrinsic::ID ID) {
switch (ID) {
default: return false;
@@ -4403,7 +4544,7 @@ static bool maskIsAllZeroOrUndef(Value *Mask) {
template <typename IterTy>
static Value *SimplifyIntrinsic(Function *F, IterTy ArgBegin, IterTy ArgEnd,
- const Query &Q, unsigned MaxRecurse) {
+ const SimplifyQuery &Q, unsigned MaxRecurse) {
Intrinsic::ID IID = F->getIntrinsicID();
unsigned NumOperands = std::distance(ArgBegin, ArgEnd);
@@ -4497,7 +4638,7 @@ static Value *SimplifyIntrinsic(Function *F, IterTy ArgBegin, IterTy ArgEnd,
template <typename IterTy>
static Value *SimplifyCall(Value *V, IterTy ArgBegin, IterTy ArgEnd,
- const Query &Q, unsigned MaxRecurse) {
+ const SimplifyQuery &Q, unsigned MaxRecurse) {
Type *Ty = V->getType();
if (PointerType *PTy = dyn_cast<PointerType>(Ty))
Ty = PTy->getElementType();
@@ -4535,16 +4676,26 @@ Value *llvm::SimplifyCall(Value *V, User::op_iterator ArgBegin,
User::op_iterator ArgEnd, const DataLayout &DL,
const TargetLibraryInfo *TLI, const DominatorTree *DT,
AssumptionCache *AC, const Instruction *CxtI) {
- return ::SimplifyCall(V, ArgBegin, ArgEnd, Query(DL, TLI, DT, AC, CxtI),
+ return ::SimplifyCall(V, ArgBegin, ArgEnd, {DL, TLI, DT, AC, CxtI},
RecursionLimit);
}
+Value *llvm::SimplifyCall(Value *V, User::op_iterator ArgBegin,
+ User::op_iterator ArgEnd, const SimplifyQuery &Q) {
+ return ::SimplifyCall(V, ArgBegin, ArgEnd, Q, RecursionLimit);
+}
+
Value *llvm::SimplifyCall(Value *V, ArrayRef<Value *> Args,
const DataLayout &DL, const TargetLibraryInfo *TLI,
const DominatorTree *DT, AssumptionCache *AC,
const Instruction *CxtI) {
- return ::SimplifyCall(V, Args.begin(), Args.end(),
- Query(DL, TLI, DT, AC, CxtI), RecursionLimit);
+ return ::SimplifyCall(V, Args.begin(), Args.end(), {DL, TLI, DT, AC, CxtI},
+ RecursionLimit);
+}
+
+Value *llvm::SimplifyCall(Value *V, ArrayRef<Value *> Args,
+ const SimplifyQuery &Q) {
+ return ::SimplifyCall(V, Args.begin(), Args.end(), Q, RecursionLimit);
}
/// See if we can compute a simplified version of this instruction.
@@ -4553,152 +4704,141 @@ Value *llvm::SimplifyInstruction(Instruction *I, const DataLayout &DL,
const TargetLibraryInfo *TLI,
const DominatorTree *DT, AssumptionCache *AC,
OptimizationRemarkEmitter *ORE) {
+ return SimplifyInstruction(I, {DL, TLI, DT, AC, I}, ORE);
+}
+
+Value *llvm::SimplifyInstruction(Instruction *I, const SimplifyQuery &Q,
+ OptimizationRemarkEmitter *ORE) {
Value *Result;
switch (I->getOpcode()) {
default:
- Result = ConstantFoldInstruction(I, DL, TLI);
+ Result = ConstantFoldInstruction(I, Q.DL, Q.TLI);
break;
case Instruction::FAdd:
Result = SimplifyFAddInst(I->getOperand(0), I->getOperand(1),
- I->getFastMathFlags(), DL, TLI, DT, AC, I);
+ I->getFastMathFlags(), Q);
break;
case Instruction::Add:
Result = SimplifyAddInst(I->getOperand(0), I->getOperand(1),
cast<BinaryOperator>(I)->hasNoSignedWrap(),
- cast<BinaryOperator>(I)->hasNoUnsignedWrap(), DL,
- TLI, DT, AC, I);
+ cast<BinaryOperator>(I)->hasNoUnsignedWrap(), Q);
break;
case Instruction::FSub:
Result = SimplifyFSubInst(I->getOperand(0), I->getOperand(1),
- I->getFastMathFlags(), DL, TLI, DT, AC, I);
+ I->getFastMathFlags(), Q);
break;
case Instruction::Sub:
Result = SimplifySubInst(I->getOperand(0), I->getOperand(1),
cast<BinaryOperator>(I)->hasNoSignedWrap(),
- cast<BinaryOperator>(I)->hasNoUnsignedWrap(), DL,
- TLI, DT, AC, I);
+ cast<BinaryOperator>(I)->hasNoUnsignedWrap(), Q);
break;
case Instruction::FMul:
Result = SimplifyFMulInst(I->getOperand(0), I->getOperand(1),
- I->getFastMathFlags(), DL, TLI, DT, AC, I);
+ I->getFastMathFlags(), Q);
break;
case Instruction::Mul:
- Result =
- SimplifyMulInst(I->getOperand(0), I->getOperand(1), DL, TLI, DT, AC, I);
+ Result = SimplifyMulInst(I->getOperand(0), I->getOperand(1), Q);
break;
case Instruction::SDiv:
- Result = SimplifySDivInst(I->getOperand(0), I->getOperand(1), DL, TLI, DT,
- AC, I);
+ Result = SimplifySDivInst(I->getOperand(0), I->getOperand(1), Q);
break;
case Instruction::UDiv:
- Result = SimplifyUDivInst(I->getOperand(0), I->getOperand(1), DL, TLI, DT,
- AC, I);
+ Result = SimplifyUDivInst(I->getOperand(0), I->getOperand(1), Q);
break;
case Instruction::FDiv:
Result = SimplifyFDivInst(I->getOperand(0), I->getOperand(1),
- I->getFastMathFlags(), DL, TLI, DT, AC, I);
+ I->getFastMathFlags(), Q);
break;
case Instruction::SRem:
- Result = SimplifySRemInst(I->getOperand(0), I->getOperand(1), DL, TLI, DT,
- AC, I);
+ Result = SimplifySRemInst(I->getOperand(0), I->getOperand(1), Q);
break;
case Instruction::URem:
- Result = SimplifyURemInst(I->getOperand(0), I->getOperand(1), DL, TLI, DT,
- AC, I);
+ Result = SimplifyURemInst(I->getOperand(0), I->getOperand(1), Q);
break;
case Instruction::FRem:
Result = SimplifyFRemInst(I->getOperand(0), I->getOperand(1),
- I->getFastMathFlags(), DL, TLI, DT, AC, I);
+ I->getFastMathFlags(), Q);
break;
case Instruction::Shl:
Result = SimplifyShlInst(I->getOperand(0), I->getOperand(1),
cast<BinaryOperator>(I)->hasNoSignedWrap(),
- cast<BinaryOperator>(I)->hasNoUnsignedWrap(), DL,
- TLI, DT, AC, I);
+ cast<BinaryOperator>(I)->hasNoUnsignedWrap(), Q);
break;
case Instruction::LShr:
Result = SimplifyLShrInst(I->getOperand(0), I->getOperand(1),
- cast<BinaryOperator>(I)->isExact(), DL, TLI, DT,
- AC, I);
+ cast<BinaryOperator>(I)->isExact(), Q);
break;
case Instruction::AShr:
Result = SimplifyAShrInst(I->getOperand(0), I->getOperand(1),
- cast<BinaryOperator>(I)->isExact(), DL, TLI, DT,
- AC, I);
+ cast<BinaryOperator>(I)->isExact(), Q);
break;
case Instruction::And:
- Result =
- SimplifyAndInst(I->getOperand(0), I->getOperand(1), DL, TLI, DT, AC, I);
+ Result = SimplifyAndInst(I->getOperand(0), I->getOperand(1), Q);
break;
case Instruction::Or:
- Result =
- SimplifyOrInst(I->getOperand(0), I->getOperand(1), DL, TLI, DT, AC, I);
+ Result = SimplifyOrInst(I->getOperand(0), I->getOperand(1), Q);
break;
case Instruction::Xor:
- Result =
- SimplifyXorInst(I->getOperand(0), I->getOperand(1), DL, TLI, DT, AC, I);
+ Result = SimplifyXorInst(I->getOperand(0), I->getOperand(1), Q);
break;
case Instruction::ICmp:
- Result =
- SimplifyICmpInst(cast<ICmpInst>(I)->getPredicate(), I->getOperand(0),
- I->getOperand(1), DL, TLI, DT, AC, I);
+ Result = SimplifyICmpInst(cast<ICmpInst>(I)->getPredicate(),
+ I->getOperand(0), I->getOperand(1), Q);
break;
case Instruction::FCmp:
- Result = SimplifyFCmpInst(cast<FCmpInst>(I)->getPredicate(),
- I->getOperand(0), I->getOperand(1),
- I->getFastMathFlags(), DL, TLI, DT, AC, I);
+ Result =
+ SimplifyFCmpInst(cast<FCmpInst>(I)->getPredicate(), I->getOperand(0),
+ I->getOperand(1), I->getFastMathFlags(), Q);
break;
case Instruction::Select:
Result = SimplifySelectInst(I->getOperand(0), I->getOperand(1),
- I->getOperand(2), DL, TLI, DT, AC, I);
+ I->getOperand(2), Q);
break;
case Instruction::GetElementPtr: {
- SmallVector<Value*, 8> Ops(I->op_begin(), I->op_end());
+ SmallVector<Value *, 8> Ops(I->op_begin(), I->op_end());
Result = SimplifyGEPInst(cast<GetElementPtrInst>(I)->getSourceElementType(),
- Ops, DL, TLI, DT, AC, I);
+ Ops, Q);
break;
}
case Instruction::InsertValue: {
InsertValueInst *IV = cast<InsertValueInst>(I);
Result = SimplifyInsertValueInst(IV->getAggregateOperand(),
IV->getInsertedValueOperand(),
- IV->getIndices(), DL, TLI, DT, AC, I);
+ IV->getIndices(), Q);
break;
}
case Instruction::ExtractValue: {
auto *EVI = cast<ExtractValueInst>(I);
Result = SimplifyExtractValueInst(EVI->getAggregateOperand(),
- EVI->getIndices(), DL, TLI, DT, AC, I);
+ EVI->getIndices(), Q);
break;
}
case Instruction::ExtractElement: {
auto *EEI = cast<ExtractElementInst>(I);
- Result = SimplifyExtractElementInst(
- EEI->getVectorOperand(), EEI->getIndexOperand(), DL, TLI, DT, AC, I);
+ Result = SimplifyExtractElementInst(EEI->getVectorOperand(),
+ EEI->getIndexOperand(), Q);
break;
}
case Instruction::ShuffleVector: {
auto *SVI = cast<ShuffleVectorInst>(I);
Result = SimplifyShuffleVectorInst(SVI->getOperand(0), SVI->getOperand(1),
- SVI->getMask(), SVI->getType(), DL, TLI,
- DT, AC, I);
+ SVI->getMask(), SVI->getType(), Q);
break;
}
case Instruction::PHI:
- Result = SimplifyPHINode(cast<PHINode>(I), Query(DL, TLI, DT, AC, I));
+ Result = SimplifyPHINode(cast<PHINode>(I), Q);
break;
case Instruction::Call: {
CallSite CS(cast<CallInst>(I));
- Result = SimplifyCall(CS.getCalledValue(), CS.arg_begin(), CS.arg_end(), DL,
- TLI, DT, AC, I);
+ Result = SimplifyCall(CS.getCalledValue(), CS.arg_begin(), CS.arg_end(), Q);
break;
}
#define HANDLE_CAST_INST(num, opc, clas) case Instruction::opc:
#include "llvm/IR/Instruction.def"
#undef HANDLE_CAST_INST
- Result = SimplifyCastInst(I->getOpcode(), I->getOperand(0), I->getType(),
- DL, TLI, DT, AC, I);
+ Result =
+ SimplifyCastInst(I->getOpcode(), I->getOperand(0), I->getType(), Q);
break;
case Instruction::Alloca:
// No simplifications for Alloca and it can't be constant folded.
@@ -4710,11 +4850,10 @@ Value *llvm::SimplifyInstruction(Instruction *I, const DataLayout &DL,
// value even when the operands are not all constants.
if (!Result && I->getType()->isIntOrIntVectorTy()) {
unsigned BitWidth = I->getType()->getScalarSizeInBits();
- APInt KnownZero(BitWidth, 0);
- APInt KnownOne(BitWidth, 0);
- computeKnownBits(I, KnownZero, KnownOne, DL, /*Depth*/0, AC, I, DT, ORE);
- if ((KnownZero | KnownOne).isAllOnesValue())
- Result = ConstantInt::get(I->getType(), KnownOne);
+ KnownBits Known(BitWidth);
+ computeKnownBits(I, Known, Q.DL, /*Depth*/ 0, Q.AC, I, Q.DT, ORE);
+ if ((Known.Zero | Known.One).isAllOnesValue())
+ Result = ConstantInt::get(I->getType(), Known.One);
}
/// If called on unreachable code, the above logic may report that the
diff --git a/lib/Analysis/Lint.cpp b/lib/Analysis/Lint.cpp
index 2ca46b1fe872..0f04af54cdc7 100644
--- a/lib/Analysis/Lint.cpp
+++ b/lib/Analysis/Lint.cpp
@@ -70,6 +70,7 @@
#include "llvm/Pass.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Debug.h"
+#include "llvm/Support/KnownBits.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
#include <cassert>
@@ -534,10 +535,9 @@ static bool isZero(Value *V, const DataLayout &DL, DominatorTree *DT,
VectorType *VecTy = dyn_cast<VectorType>(V->getType());
if (!VecTy) {
unsigned BitWidth = V->getType()->getIntegerBitWidth();
- APInt KnownZero(BitWidth, 0), KnownOne(BitWidth, 0);
- computeKnownBits(V, KnownZero, KnownOne, DL, 0, AC,
- dyn_cast<Instruction>(V), DT);
- return KnownZero.isAllOnesValue();
+ KnownBits Known(BitWidth);
+ computeKnownBits(V, Known, DL, 0, AC, dyn_cast<Instruction>(V), DT);
+ return Known.Zero.isAllOnesValue();
}
// Per-component check doesn't work with zeroinitializer
@@ -556,9 +556,9 @@ static bool isZero(Value *V, const DataLayout &DL, DominatorTree *DT,
if (isa<UndefValue>(Elem))
return true;
- APInt KnownZero(BitWidth, 0), KnownOne(BitWidth, 0);
- computeKnownBits(Elem, KnownZero, KnownOne, DL);
- if (KnownZero.isAllOnesValue())
+ KnownBits Known(BitWidth);
+ computeKnownBits(Elem, Known, DL);
+ if (Known.Zero.isAllOnesValue())
return true;
}
diff --git a/lib/Analysis/MemorySSAUpdater.cpp b/lib/Analysis/MemorySSAUpdater.cpp
index c63677fe5502..da5c79ab6c81 100644
--- a/lib/Analysis/MemorySSAUpdater.cpp
+++ b/lib/Analysis/MemorySSAUpdater.cpp
@@ -29,7 +29,7 @@
#define DEBUG_TYPE "memoryssa"
using namespace llvm;
-namespace llvm {
+
// This is the marker algorithm from "Simple and Efficient Construction of
// Static Single Assignment Form"
// The simple, non-marker algorithm places phi nodes at any join
@@ -211,8 +211,8 @@ void MemorySSAUpdater::insertUse(MemoryUse *MU) {
}
// Set every incoming edge {BB, MP->getBlock()} of MemoryPhi MP to NewDef.
-void setMemoryPhiValueForBlock(MemoryPhi *MP, const BasicBlock *BB,
- MemoryAccess *NewDef) {
+static void setMemoryPhiValueForBlock(MemoryPhi *MP, const BasicBlock *BB,
+ MemoryAccess *NewDef) {
// Replace any operand with us an incoming block with the new defining
// access.
int i = MP->getBasicBlockIndex(BB);
@@ -415,6 +415,7 @@ static MemoryAccess *onlySingleValue(MemoryPhi *MP) {
}
return MA;
}
+
void MemorySSAUpdater::removeMemoryAccess(MemoryAccess *MA) {
assert(!MSSA->isLiveOnEntryDef(MA) &&
"Trying to remove the live on entry def");
@@ -490,5 +491,3 @@ MemoryUseOrDef *MemorySSAUpdater::createMemoryAccessAfter(
++InsertPt->getIterator());
return NewAccess;
}
-
-} // namespace llvm
diff --git a/lib/Analysis/ScalarEvolution.cpp b/lib/Analysis/ScalarEvolution.cpp
index 700c383a9dd4..3ac4bf1276eb 100644
--- a/lib/Analysis/ScalarEvolution.cpp
+++ b/lib/Analysis/ScalarEvolution.cpp
@@ -89,6 +89,7 @@
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/KnownBits.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/SaveAndRestore.h"
@@ -4575,10 +4576,10 @@ uint32_t ScalarEvolution::GetMinTrailingZerosImpl(const SCEV *S) {
if (const SCEVUnknown *U = dyn_cast<SCEVUnknown>(S)) {
// For a SCEVUnknown, ask ValueTracking.
unsigned BitWidth = getTypeSizeInBits(U->getType());
- APInt Zeros(BitWidth, 0), Ones(BitWidth, 0);
- computeKnownBits(U->getValue(), Zeros, Ones, getDataLayout(), 0, &AC,
+ KnownBits Known(BitWidth);
+ computeKnownBits(U->getValue(), Known, getDataLayout(), 0, &AC,
nullptr, &DT);
- return Zeros.countTrailingOnes();
+ return Known.Zero.countTrailingOnes();
}
// SCEVUDivExpr
@@ -4757,11 +4758,12 @@ ScalarEvolution::getRange(const SCEV *S,
const DataLayout &DL = getDataLayout();
if (SignHint == ScalarEvolution::HINT_RANGE_UNSIGNED) {
// For a SCEVUnknown, ask ValueTracking.
- APInt Zeros(BitWidth, 0), Ones(BitWidth, 0);
- computeKnownBits(U->getValue(), Zeros, Ones, DL, 0, &AC, nullptr, &DT);
- if (Ones != ~Zeros + 1)
+ KnownBits Known(BitWidth);
+ computeKnownBits(U->getValue(), Known, DL, 0, &AC, nullptr, &DT);
+ if (Known.One != ~Known.Zero + 1)
ConservativeResult =
- ConservativeResult.intersectWith(ConstantRange(Ones, ~Zeros + 1));
+ ConservativeResult.intersectWith(ConstantRange(Known.One,
+ ~Known.Zero + 1));
} else {
assert(SignHint == ScalarEvolution::HINT_RANGE_SIGNED &&
"generalize as needed!");
@@ -5292,13 +5294,13 @@ const SCEV *ScalarEvolution::createSCEV(Value *V) {
unsigned LZ = A.countLeadingZeros();
unsigned TZ = A.countTrailingZeros();
unsigned BitWidth = A.getBitWidth();
- APInt KnownZero(BitWidth, 0), KnownOne(BitWidth, 0);
- computeKnownBits(BO->LHS, KnownZero, KnownOne, getDataLayout(),
+ KnownBits Known(BitWidth);
+ computeKnownBits(BO->LHS, Known, getDataLayout(),
0, &AC, nullptr, &DT);
APInt EffectiveMask =
APInt::getLowBitsSet(BitWidth, BitWidth - LZ - TZ).shl(TZ);
- if ((LZ != 0 || TZ != 0) && !((~A & ~KnownZero) & EffectiveMask)) {
+ if ((LZ != 0 || TZ != 0) && !((~A & ~Known.Zero) & EffectiveMask)) {
const SCEV *MulCount = getConstant(APInt::getOneBitSet(BitWidth, TZ));
const SCEV *LHS = getSCEV(BO->LHS);
const SCEV *ShiftedLHS = nullptr;
@@ -5328,12 +5330,28 @@ const SCEV *ScalarEvolution::createSCEV(Value *V) {
break;
case Instruction::Or:
- // Use ValueTracking to check whether this is actually an add.
- if (haveNoCommonBitsSet(BO->LHS, BO->RHS, getDataLayout(), &AC,
- nullptr, &DT)) {
- // There aren't any common bits set, so the add can't wrap.
- auto Flags = SCEV::NoWrapFlags(SCEV::FlagNUW | SCEV::FlagNSW);
- return getAddExpr(getSCEV(BO->LHS), getSCEV(BO->RHS), Flags);
+ // If the RHS of the Or is a constant, we may have something like:
+ // X*4+1 which got turned into X*4|1. Handle this as an Add so loop
+ // optimizations will transparently handle this case.
+ //
+ // In order for this transformation to be safe, the LHS must be of the
+ // form X*(2^n) and the Or constant must be less than 2^n.
+ if (ConstantInt *CI = dyn_cast<ConstantInt>(BO->RHS)) {
+ const SCEV *LHS = getSCEV(BO->LHS);
+ const APInt &CIVal = CI->getValue();
+ if (GetMinTrailingZeros(LHS) >=
+ (CIVal.getBitWidth() - CIVal.countLeadingZeros())) {
+ // Build a plain add SCEV.
+ const SCEV *S = getAddExpr(LHS, getSCEV(CI));
+ // If the LHS of the add was an addrec and it has no-wrap flags,
+ // transfer the no-wrap flags, since an or won't introduce a wrap.
+ if (const SCEVAddRecExpr *NewAR = dyn_cast<SCEVAddRecExpr>(S)) {
+ const SCEVAddRecExpr *OldAR = cast<SCEVAddRecExpr>(LHS);
+ const_cast<SCEVAddRecExpr *>(NewAR)->setNoWrapFlags(
+ OldAR->getNoWrapFlags());
+ }
+ return S;
+ }
}
break;
@@ -6063,24 +6081,74 @@ ScalarEvolution::computeExitLimit(const Loop *L, BasicBlock *ExitingBlock,
return getCouldNotCompute();
}
-ScalarEvolution::ExitLimit
-ScalarEvolution::computeExitLimitFromCond(const Loop *L,
- Value *ExitCond,
- BasicBlock *TBB,
- BasicBlock *FBB,
- bool ControlsExit,
- bool AllowPredicates) {
+ScalarEvolution::ExitLimit ScalarEvolution::computeExitLimitFromCond(
+ const Loop *L, Value *ExitCond, BasicBlock *TBB, BasicBlock *FBB,
+ bool ControlsExit, bool AllowPredicates) {
+ ScalarEvolution::ExitLimitCacheTy Cache(L, TBB, FBB, AllowPredicates);
+ return computeExitLimitFromCondCached(Cache, L, ExitCond, TBB, FBB,
+ ControlsExit, AllowPredicates);
+}
+
+Optional<ScalarEvolution::ExitLimit>
+ScalarEvolution::ExitLimitCache::find(const Loop *L, Value *ExitCond,
+ BasicBlock *TBB, BasicBlock *FBB,
+ bool ControlsExit, bool AllowPredicates) {
+ (void)this->L;
+ (void)this->TBB;
+ (void)this->FBB;
+ (void)this->AllowPredicates;
+
+ assert(this->L == L && this->TBB == TBB && this->FBB == FBB &&
+ this->AllowPredicates == AllowPredicates &&
+ "Variance in assumed invariant key components!");
+ auto Itr = TripCountMap.find({ExitCond, ControlsExit});
+ if (Itr == TripCountMap.end())
+ return None;
+ return Itr->second;
+}
+
+void ScalarEvolution::ExitLimitCache::insert(const Loop *L, Value *ExitCond,
+ BasicBlock *TBB, BasicBlock *FBB,
+ bool ControlsExit,
+ bool AllowPredicates,
+ const ExitLimit &EL) {
+ assert(this->L == L && this->TBB == TBB && this->FBB == FBB &&
+ this->AllowPredicates == AllowPredicates &&
+ "Variance in assumed invariant key components!");
+
+ auto InsertResult = TripCountMap.insert({{ExitCond, ControlsExit}, EL});
+ assert(InsertResult.second && "Expected successful insertion!");
+ (void)InsertResult;
+}
+
+ScalarEvolution::ExitLimit ScalarEvolution::computeExitLimitFromCondCached(
+ ExitLimitCacheTy &Cache, const Loop *L, Value *ExitCond, BasicBlock *TBB,
+ BasicBlock *FBB, bool ControlsExit, bool AllowPredicates) {
+
+ if (auto MaybeEL =
+ Cache.find(L, ExitCond, TBB, FBB, ControlsExit, AllowPredicates))
+ return *MaybeEL;
+
+ ExitLimit EL = computeExitLimitFromCondImpl(Cache, L, ExitCond, TBB, FBB,
+ ControlsExit, AllowPredicates);
+ Cache.insert(L, ExitCond, TBB, FBB, ControlsExit, AllowPredicates, EL);
+ return EL;
+}
+
+ScalarEvolution::ExitLimit ScalarEvolution::computeExitLimitFromCondImpl(
+ ExitLimitCacheTy &Cache, const Loop *L, Value *ExitCond, BasicBlock *TBB,
+ BasicBlock *FBB, bool ControlsExit, bool AllowPredicates) {
// Check if the controlling expression for this loop is an And or Or.
if (BinaryOperator *BO = dyn_cast<BinaryOperator>(ExitCond)) {
if (BO->getOpcode() == Instruction::And) {
// Recurse on the operands of the and.
bool EitherMayExit = L->contains(TBB);
- ExitLimit EL0 = computeExitLimitFromCond(L, BO->getOperand(0), TBB, FBB,
- ControlsExit && !EitherMayExit,
- AllowPredicates);
- ExitLimit EL1 = computeExitLimitFromCond(L, BO->getOperand(1), TBB, FBB,
- ControlsExit && !EitherMayExit,
- AllowPredicates);
+ ExitLimit EL0 = computeExitLimitFromCondCached(
+ Cache, L, BO->getOperand(0), TBB, FBB, ControlsExit && !EitherMayExit,
+ AllowPredicates);
+ ExitLimit EL1 = computeExitLimitFromCondCached(
+ Cache, L, BO->getOperand(1), TBB, FBB, ControlsExit && !EitherMayExit,
+ AllowPredicates);
const SCEV *BECount = getCouldNotCompute();
const SCEV *MaxBECount = getCouldNotCompute();
if (EitherMayExit) {
@@ -6124,12 +6192,12 @@ ScalarEvolution::computeExitLimitFromCond(const Loop *L,
if (BO->getOpcode() == Instruction::Or) {
// Recurse on the operands of the or.
bool EitherMayExit = L->contains(FBB);
- ExitLimit EL0 = computeExitLimitFromCond(L, BO->getOperand(0), TBB, FBB,
- ControlsExit && !EitherMayExit,
- AllowPredicates);
- ExitLimit EL1 = computeExitLimitFromCond(L, BO->getOperand(1), TBB, FBB,
- ControlsExit && !EitherMayExit,
- AllowPredicates);
+ ExitLimit EL0 = computeExitLimitFromCondCached(
+ Cache, L, BO->getOperand(0), TBB, FBB, ControlsExit && !EitherMayExit,
+ AllowPredicates);
+ ExitLimit EL1 = computeExitLimitFromCondCached(
+ Cache, L, BO->getOperand(1), TBB, FBB, ControlsExit && !EitherMayExit,
+ AllowPredicates);
const SCEV *BECount = getCouldNotCompute();
const SCEV *MaxBECount = getCouldNotCompute();
if (EitherMayExit) {
@@ -10221,84 +10289,75 @@ void ScalarEvolution::forgetMemoizedResults(const SCEV *S) {
RemoveSCEVFromBackedgeMap(PredicatedBackedgeTakenCounts);
}
-typedef DenseMap<const Loop *, std::string> VerifyMap;
+void ScalarEvolution::verify() const {
+ ScalarEvolution &SE = *const_cast<ScalarEvolution *>(this);
+ ScalarEvolution SE2(F, TLI, AC, DT, LI);
+
+ SmallVector<Loop *, 8> LoopStack(LI.begin(), LI.end());
-/// replaceSubString - Replaces all occurrences of From in Str with To.
-static void replaceSubString(std::string &Str, StringRef From, StringRef To) {
- size_t Pos = 0;
- while ((Pos = Str.find(From, Pos)) != std::string::npos) {
- Str.replace(Pos, From.size(), To.data(), To.size());
- Pos += To.size();
- }
-}
+ // Map's SCEV expressions from one ScalarEvolution "universe" to another.
+ struct SCEVMapper : public SCEVRewriteVisitor<SCEVMapper> {
+ const SCEV *visitConstant(const SCEVConstant *Constant) {
+ return SE.getConstant(Constant->getAPInt());
+ }
+ const SCEV *visitUnknown(const SCEVUnknown *Expr) {
+ return SE.getUnknown(Expr->getValue());
+ }
-/// getLoopBackedgeTakenCounts - Helper method for verifyAnalysis.
-static void
-getLoopBackedgeTakenCounts(Loop *L, VerifyMap &Map, ScalarEvolution &SE) {
- std::string &S = Map[L];
- if (S.empty()) {
- raw_string_ostream OS(S);
- SE.getBackedgeTakenCount(L)->print(OS);
+ const SCEV *visitCouldNotCompute(const SCEVCouldNotCompute *Expr) {
+ return SE.getCouldNotCompute();
+ }
+ SCEVMapper(ScalarEvolution &SE) : SCEVRewriteVisitor<SCEVMapper>(SE) {}
+ };
- // false and 0 are semantically equivalent. This can happen in dead loops.
- replaceSubString(OS.str(), "false", "0");
- // Remove wrap flags, their use in SCEV is highly fragile.
- // FIXME: Remove this when SCEV gets smarter about them.
- replaceSubString(OS.str(), "<nw>", "");
- replaceSubString(OS.str(), "<nsw>", "");
- replaceSubString(OS.str(), "<nuw>", "");
- }
+ SCEVMapper SCM(SE2);
- for (auto *R : reverse(*L))
- getLoopBackedgeTakenCounts(R, Map, SE); // recurse.
-}
+ while (!LoopStack.empty()) {
+ auto *L = LoopStack.pop_back_val();
+ LoopStack.insert(LoopStack.end(), L->begin(), L->end());
-void ScalarEvolution::verify() const {
- ScalarEvolution &SE = *const_cast<ScalarEvolution *>(this);
+ auto *CurBECount = SCM.visit(
+ const_cast<ScalarEvolution *>(this)->getBackedgeTakenCount(L));
+ auto *NewBECount = SE2.getBackedgeTakenCount(L);
- // Gather stringified backedge taken counts for all loops using SCEV's caches.
- // FIXME: It would be much better to store actual values instead of strings,
- // but SCEV pointers will change if we drop the caches.
- VerifyMap BackedgeDumpsOld, BackedgeDumpsNew;
- for (LoopInfo::reverse_iterator I = LI.rbegin(), E = LI.rend(); I != E; ++I)
- getLoopBackedgeTakenCounts(*I, BackedgeDumpsOld, SE);
+ if (CurBECount == SE2.getCouldNotCompute() ||
+ NewBECount == SE2.getCouldNotCompute()) {
+ // NB! This situation is legal, but is very suspicious -- whatever pass
+ // change the loop to make a trip count go from could not compute to
+ // computable or vice-versa *should have* invalidated SCEV. However, we
+ // choose not to assert here (for now) since we don't want false
+ // positives.
+ continue;
+ }
- // Gather stringified backedge taken counts for all loops using a fresh
- // ScalarEvolution object.
- ScalarEvolution SE2(F, TLI, AC, DT, LI);
- for (LoopInfo::reverse_iterator I = LI.rbegin(), E = LI.rend(); I != E; ++I)
- getLoopBackedgeTakenCounts(*I, BackedgeDumpsNew, SE2);
-
- // Now compare whether they're the same with and without caches. This allows
- // verifying that no pass changed the cache.
- assert(BackedgeDumpsOld.size() == BackedgeDumpsNew.size() &&
- "New loops suddenly appeared!");
-
- for (VerifyMap::iterator OldI = BackedgeDumpsOld.begin(),
- OldE = BackedgeDumpsOld.end(),
- NewI = BackedgeDumpsNew.begin();
- OldI != OldE; ++OldI, ++NewI) {
- assert(OldI->first == NewI->first && "Loop order changed!");
-
- // Compare the stringified SCEVs. We don't care if undef backedgetaken count
- // changes.
- // FIXME: We currently ignore SCEV changes from/to CouldNotCompute. This
- // means that a pass is buggy or SCEV has to learn a new pattern but is
- // usually not harmful.
- if (OldI->second != NewI->second &&
- OldI->second.find("undef") == std::string::npos &&
- NewI->second.find("undef") == std::string::npos &&
- OldI->second != "***COULDNOTCOMPUTE***" &&
- NewI->second != "***COULDNOTCOMPUTE***") {
- dbgs() << "SCEVValidator: SCEV for loop '"
- << OldI->first->getHeader()->getName()
- << "' changed from '" << OldI->second
- << "' to '" << NewI->second << "'!\n";
+ if (containsUndefs(CurBECount) || containsUndefs(NewBECount)) {
+ // SCEV treats "undef" as an unknown but consistent value (i.e. it does
+ // not propagate undef aggressively). This means we can (and do) fail
+ // verification in cases where a transform makes the trip count of a loop
+ // go from "undef" to "undef+1" (say). The transform is fine, since in
+ // both cases the loop iterates "undef" times, but SCEV thinks we
+ // increased the trip count of the loop by 1 incorrectly.
+ continue;
+ }
+
+ if (SE.getTypeSizeInBits(CurBECount->getType()) >
+ SE.getTypeSizeInBits(NewBECount->getType()))
+ NewBECount = SE2.getZeroExtendExpr(NewBECount, CurBECount->getType());
+ else if (SE.getTypeSizeInBits(CurBECount->getType()) <
+ SE.getTypeSizeInBits(NewBECount->getType()))
+ CurBECount = SE2.getZeroExtendExpr(CurBECount, NewBECount->getType());
+
+ auto *ConstantDelta =
+ dyn_cast<SCEVConstant>(SE2.getMinusSCEV(CurBECount, NewBECount));
+
+ if (ConstantDelta && ConstantDelta->getAPInt() != 0) {
+ dbgs() << "Trip Count Changed!\n";
+ dbgs() << "Old: " << *CurBECount << "\n";
+ dbgs() << "New: " << *NewBECount << "\n";
+ dbgs() << "Delta: " << *ConstantDelta << "\n";
std::abort();
}
}
-
- // TODO: Verify more things.
}
bool ScalarEvolution::invalidate(
diff --git a/lib/Analysis/ScalarEvolutionNormalization.cpp b/lib/Analysis/ScalarEvolutionNormalization.cpp
index 2aaa4c1ae117..54c44c8e542d 100644
--- a/lib/Analysis/ScalarEvolutionNormalization.cpp
+++ b/lib/Analysis/ScalarEvolutionNormalization.cpp
@@ -51,40 +51,47 @@ NormalizeDenormalizeRewriter::visitAddRecExpr(const SCEVAddRecExpr *AR) {
transform(AR->operands(), std::back_inserter(Operands),
[&](const SCEV *Op) { return visit(Op); });
- // Conservatively use AnyWrap until/unless we need FlagNW.
- const SCEV *Result =
- SE.getAddRecExpr(Operands, AR->getLoop(), SCEV::FlagAnyWrap);
- switch (Kind) {
- case Normalize:
- // We want to normalize step expression, because otherwise we might not be
- // able to denormalize to the original expression.
+ if (!Pred(AR))
+ return SE.getAddRecExpr(Operands, AR->getLoop(), SCEV::FlagAnyWrap);
+
+ // Normalization and denormalization are fancy names for decrementing and
+ // incrementing a SCEV expression with respect to a set of loops. Since
+ // Pred(AR) has returned true, we know we need to normalize or denormalize AR
+ // with respect to its loop.
+
+ if (Kind == Denormalize) {
+ // Denormalization / "partial increment" is essentially the same as \c
+ // SCEVAddRecExpr::getPostIncExpr. Here we use an explicit loop to make the
+ // symmetry with Normalization clear.
+ for (int i = 0, e = Operands.size() - 1; i < e; i++)
+ Operands[i] = SE.getAddExpr(Operands[i], Operands[i + 1]);
+ } else {
+ assert(Kind == Normalize && "Only two possibilities!");
+
+ // Normalization / "partial decrement" is a bit more subtle. Since
+ // incrementing a SCEV expression (in general) changes the step of the SCEV
+ // expression as well, we cannot use the step of the current expression.
+ // Instead, we have to use the step of the very expression we're trying to
+ // compute!
+ //
+ // We solve the issue by recursively building up the result, starting from
+ // the "least significant" operand in the add recurrence:
//
- // Here is an example what will happen if we don't normalize step:
- // ORIGINAL ISE:
- // {(100 /u {1,+,1}<%bb16>),+,(100 /u {1,+,1}<%bb16>)}<%bb25>
- // NORMALIZED ISE:
- // {((-1 * (100 /u {1,+,1}<%bb16>)) + (100 /u {0,+,1}<%bb16>)),+,
- // (100 /u {0,+,1}<%bb16>)}<%bb25>
- // DENORMALIZED BACK ISE:
- // {((2 * (100 /u {1,+,1}<%bb16>)) + (-1 * (100 /u {2,+,1}<%bb16>))),+,
- // (100 /u {1,+,1}<%bb16>)}<%bb25>
- // Note that the initial value changes after normalization +
- // denormalization, which isn't correct.
- if (Pred(AR)) {
- const SCEV *TransformedStep = visit(AR->getStepRecurrence(SE));
- Result = SE.getMinusSCEV(Result, TransformedStep);
- }
- break;
- case Denormalize:
- // Here we want to normalize step expressions for the same reasons, as
- // stated above.
- if (Pred(AR)) {
- const SCEV *TransformedStep = visit(AR->getStepRecurrence(SE));
- Result = SE.getAddExpr(Result, TransformedStep);
- }
- break;
+ // Base case:
+ // Single operand add recurrence. It's its own normalization.
+ //
+ // N-operand case:
+ // {S_{N-1},+,S_{N-2},+,...,+,S_0} = S
+ //
+ // Since the step recurrence of S is {S_{N-2},+,...,+,S_0}, we know its
+ // normalization by induction. We subtract the normalized step
+ // recurrence from S_{N-1} to get the normalization of S.
+
+ for (int i = Operands.size() - 2; i >= 0; i--)
+ Operands[i] = SE.getMinusSCEV(Operands[i], Operands[i + 1]);
}
- return Result;
+
+ return SE.getAddRecExpr(Operands, AR->getLoop(), SCEV::FlagAnyWrap);
}
const SCEV *llvm::normalizeForPostIncUse(const SCEV *S,
diff --git a/lib/Analysis/ValueTracking.cpp b/lib/Analysis/ValueTracking.cpp
index 900a2363e60d..af964b6259bb 100644
--- a/lib/Analysis/ValueTracking.cpp
+++ b/lib/Analysis/ValueTracking.cpp
@@ -38,6 +38,7 @@
#include "llvm/IR/PatternMatch.h"
#include "llvm/IR/Statepoint.h"
#include "llvm/Support/Debug.h"
+#include "llvm/Support/KnownBits.h"
#include "llvm/Support/MathExtras.h"
#include <algorithm>
#include <array>
@@ -130,15 +131,15 @@ static const Instruction *safeCxtI(const Value *V, const Instruction *CxtI) {
return nullptr;
}
-static void computeKnownBits(const Value *V, APInt &KnownZero, APInt &KnownOne,
+static void computeKnownBits(const Value *V, KnownBits &Known,
unsigned Depth, const Query &Q);
-void llvm::computeKnownBits(const Value *V, APInt &KnownZero, APInt &KnownOne,
+void llvm::computeKnownBits(const Value *V, KnownBits &Known,
const DataLayout &DL, unsigned Depth,
AssumptionCache *AC, const Instruction *CxtI,
const DominatorTree *DT,
OptimizationRemarkEmitter *ORE) {
- ::computeKnownBits(V, KnownZero, KnownOne, Depth,
+ ::computeKnownBits(V, Known, Depth,
Query(DL, AC, safeCxtI(V, CxtI), DT, ORE));
}
@@ -151,11 +152,11 @@ bool llvm::haveNoCommonBitsSet(const Value *LHS, const Value *RHS,
assert(LHS->getType()->isIntOrIntVectorTy() &&
"LHS and RHS should be integers");
IntegerType *IT = cast<IntegerType>(LHS->getType()->getScalarType());
- APInt LHSKnownZero(IT->getBitWidth(), 0), LHSKnownOne(IT->getBitWidth(), 0);
- APInt RHSKnownZero(IT->getBitWidth(), 0), RHSKnownOne(IT->getBitWidth(), 0);
- computeKnownBits(LHS, LHSKnownZero, LHSKnownOne, DL, 0, AC, CxtI, DT);
- computeKnownBits(RHS, RHSKnownZero, RHSKnownOne, DL, 0, AC, CxtI, DT);
- return (LHSKnownZero | RHSKnownZero).isAllOnesValue();
+ KnownBits LHSKnown(IT->getBitWidth());
+ KnownBits RHSKnown(IT->getBitWidth());
+ computeKnownBits(LHS, LHSKnown, DL, 0, AC, CxtI, DT);
+ computeKnownBits(RHS, RHSKnown, DL, 0, AC, CxtI, DT);
+ return (LHSKnown.Zero | RHSKnown.Zero).isAllOnesValue();
}
static void ComputeSignBit(const Value *V, bool &KnownZero, bool &KnownOne,
@@ -252,67 +253,65 @@ unsigned llvm::ComputeNumSignBits(const Value *V, const DataLayout &DL,
static void computeKnownBitsAddSub(bool Add, const Value *Op0, const Value *Op1,
bool NSW,
- APInt &KnownZero, APInt &KnownOne,
- APInt &KnownZero2, APInt &KnownOne2,
+ KnownBits &KnownOut, KnownBits &Known2,
unsigned Depth, const Query &Q) {
- unsigned BitWidth = KnownZero.getBitWidth();
+ unsigned BitWidth = KnownOut.getBitWidth();
// If an initial sequence of bits in the result is not needed, the
// corresponding bits in the operands are not needed.
- APInt LHSKnownZero(BitWidth, 0), LHSKnownOne(BitWidth, 0);
- computeKnownBits(Op0, LHSKnownZero, LHSKnownOne, Depth + 1, Q);
- computeKnownBits(Op1, KnownZero2, KnownOne2, Depth + 1, Q);
+ KnownBits LHSKnown(BitWidth);
+ computeKnownBits(Op0, LHSKnown, Depth + 1, Q);
+ computeKnownBits(Op1, Known2, Depth + 1, Q);
// Carry in a 1 for a subtract, rather than a 0.
uint64_t CarryIn = 0;
if (!Add) {
// Sum = LHS + ~RHS + 1
- std::swap(KnownZero2, KnownOne2);
+ std::swap(Known2.Zero, Known2.One);
CarryIn = 1;
}
- APInt PossibleSumZero = ~LHSKnownZero + ~KnownZero2 + CarryIn;
- APInt PossibleSumOne = LHSKnownOne + KnownOne2 + CarryIn;
+ APInt PossibleSumZero = ~LHSKnown.Zero + ~Known2.Zero + CarryIn;
+ APInt PossibleSumOne = LHSKnown.One + Known2.One + CarryIn;
// Compute known bits of the carry.
- APInt CarryKnownZero = ~(PossibleSumZero ^ LHSKnownZero ^ KnownZero2);
- APInt CarryKnownOne = PossibleSumOne ^ LHSKnownOne ^ KnownOne2;
+ APInt CarryKnownZero = ~(PossibleSumZero ^ LHSKnown.Zero ^ Known2.Zero);
+ APInt CarryKnownOne = PossibleSumOne ^ LHSKnown.One ^ Known2.One;
// Compute set of known bits (where all three relevant bits are known).
- APInt LHSKnown = LHSKnownZero | LHSKnownOne;
- APInt RHSKnown = KnownZero2 | KnownOne2;
- APInt CarryKnown = CarryKnownZero | CarryKnownOne;
- APInt Known = LHSKnown & RHSKnown & CarryKnown;
+ APInt LHSKnownUnion = LHSKnown.Zero | LHSKnown.One;
+ APInt RHSKnownUnion = Known2.Zero | Known2.One;
+ APInt CarryKnownUnion = CarryKnownZero | CarryKnownOne;
+ APInt Known = LHSKnownUnion & RHSKnownUnion & CarryKnownUnion;
assert((PossibleSumZero & Known) == (PossibleSumOne & Known) &&
"known bits of sum differ");
// Compute known bits of the result.
- KnownZero = ~PossibleSumOne & Known;
- KnownOne = PossibleSumOne & Known;
+ KnownOut.Zero = ~PossibleSumOne & Known;
+ KnownOut.One = PossibleSumOne & Known;
// Are we still trying to solve for the sign bit?
if (!Known.isSignBitSet()) {
if (NSW) {
// Adding two non-negative numbers, or subtracting a negative number from
// a non-negative one, can't wrap into negative.
- if (LHSKnownZero.isSignBitSet() && KnownZero2.isSignBitSet())
- KnownZero.setSignBit();
+ if (LHSKnown.Zero.isSignBitSet() && Known2.Zero.isSignBitSet())
+ KnownOut.Zero.setSignBit();
// Adding two negative numbers, or subtracting a non-negative number from
// a negative one, can't wrap into non-negative.
- else if (LHSKnownOne.isSignBitSet() && KnownOne2.isSignBitSet())
- KnownOne.setSignBit();
+ else if (LHSKnown.One.isSignBitSet() && Known2.One.isSignBitSet())
+ KnownOut.One.setSignBit();
}
}
}
static void computeKnownBitsMul(const Value *Op0, const Value *Op1, bool NSW,
- APInt &KnownZero, APInt &KnownOne,
- APInt &KnownZero2, APInt &KnownOne2,
+ KnownBits &Known, KnownBits &Known2,
unsigned Depth, const Query &Q) {
- unsigned BitWidth = KnownZero.getBitWidth();
- computeKnownBits(Op1, KnownZero, KnownOne, Depth + 1, Q);
- computeKnownBits(Op0, KnownZero2, KnownOne2, Depth + 1, Q);
+ unsigned BitWidth = Known.getBitWidth();
+ computeKnownBits(Op1, Known, Depth + 1, Q);
+ computeKnownBits(Op0, Known2, Depth + 1, Q);
bool isKnownNegative = false;
bool isKnownNonNegative = false;
@@ -322,10 +321,10 @@ static void computeKnownBitsMul(const Value *Op0, const Value *Op1, bool NSW,
// The product of a number with itself is non-negative.
isKnownNonNegative = true;
} else {
- bool isKnownNonNegativeOp1 = KnownZero.isSignBitSet();
- bool isKnownNonNegativeOp0 = KnownZero2.isSignBitSet();
- bool isKnownNegativeOp1 = KnownOne.isSignBitSet();
- bool isKnownNegativeOp0 = KnownOne2.isSignBitSet();
+ bool isKnownNonNegativeOp1 = Known.Zero.isSignBitSet();
+ bool isKnownNonNegativeOp0 = Known2.Zero.isSignBitSet();
+ bool isKnownNegativeOp1 = Known.One.isSignBitSet();
+ bool isKnownNegativeOp0 = Known2.One.isSignBitSet();
// The product of two numbers with the same sign is non-negative.
isKnownNonNegative = (isKnownNegativeOp1 && isKnownNegativeOp0) ||
(isKnownNonNegativeOp1 && isKnownNonNegativeOp0);
@@ -343,28 +342,28 @@ static void computeKnownBitsMul(const Value *Op0, const Value *Op1, bool NSW,
// Also compute a conservative estimate for high known-0 bits.
// More trickiness is possible, but this is sufficient for the
// interesting case of alignment computation.
- KnownOne.clearAllBits();
- unsigned TrailZ = KnownZero.countTrailingOnes() +
- KnownZero2.countTrailingOnes();
- unsigned LeadZ = std::max(KnownZero.countLeadingOnes() +
- KnownZero2.countLeadingOnes(),
+ Known.One.clearAllBits();
+ unsigned TrailZ = Known.Zero.countTrailingOnes() +
+ Known2.Zero.countTrailingOnes();
+ unsigned LeadZ = std::max(Known.Zero.countLeadingOnes() +
+ Known2.Zero.countLeadingOnes(),
BitWidth) - BitWidth;
TrailZ = std::min(TrailZ, BitWidth);
LeadZ = std::min(LeadZ, BitWidth);
- KnownZero.clearAllBits();
- KnownZero.setLowBits(TrailZ);
- KnownZero.setHighBits(LeadZ);
+ Known.Zero.clearAllBits();
+ Known.Zero.setLowBits(TrailZ);
+ Known.Zero.setHighBits(LeadZ);
// Only make use of no-wrap flags if we failed to compute the sign bit
// directly. This matters if the multiplication always overflows, in
// which case we prefer to follow the result of the direct computation,
// though as the program is invoking undefined behaviour we can choose
// whatever we like here.
- if (isKnownNonNegative && !KnownOne.isSignBitSet())
- KnownZero.setSignBit();
- else if (isKnownNegative && !KnownZero.isSignBitSet())
- KnownOne.setSignBit();
+ if (isKnownNonNegative && !Known.One.isSignBitSet())
+ Known.Zero.setSignBit();
+ else if (isKnownNegative && !Known.Zero.isSignBitSet())
+ Known.One.setSignBit();
}
void llvm::computeKnownBitsFromRangeMetadata(const MDNode &Ranges,
@@ -499,15 +498,14 @@ bool llvm::isValidAssumeForContext(const Instruction *Inv,
return !isEphemeralValueOf(Inv, CxtI);
}
-static void computeKnownBitsFromAssume(const Value *V, APInt &KnownZero,
- APInt &KnownOne, unsigned Depth,
- const Query &Q) {
+static void computeKnownBitsFromAssume(const Value *V, KnownBits &Known,
+ unsigned Depth, const Query &Q) {
// Use of assumptions is context-sensitive. If we don't have a context, we
// cannot use them!
if (!Q.AC || !Q.CxtI)
return;
- unsigned BitWidth = KnownZero.getBitWidth();
+ unsigned BitWidth = Known.getBitWidth();
// Note that the patterns below need to be kept in sync with the code
// in AssumptionCache::updateAffectedValues.
@@ -532,15 +530,15 @@ static void computeKnownBitsFromAssume(const Value *V, APInt &KnownZero,
if (Arg == V && isValidAssumeForContext(I, Q.CxtI, Q.DT)) {
assert(BitWidth == 1 && "assume operand is not i1?");
- KnownZero.clearAllBits();
- KnownOne.setAllBits();
+ Known.Zero.clearAllBits();
+ Known.One.setAllBits();
return;
}
if (match(Arg, m_Not(m_Specific(V))) &&
isValidAssumeForContext(I, Q.CxtI, Q.DT)) {
assert(BitWidth == 1 && "assume operand is not i1?");
- KnownZero.setAllBits();
- KnownOne.clearAllBits();
+ Known.Zero.setAllBits();
+ Known.One.clearAllBits();
return;
}
@@ -558,126 +556,126 @@ static void computeKnownBitsFromAssume(const Value *V, APInt &KnownZero,
// assume(v = a)
if (match(Arg, m_c_ICmp(Pred, m_V, m_Value(A))) &&
Pred == ICmpInst::ICMP_EQ && isValidAssumeForContext(I, Q.CxtI, Q.DT)) {
- APInt RHSKnownZero(BitWidth, 0), RHSKnownOne(BitWidth, 0);
- computeKnownBits(A, RHSKnownZero, RHSKnownOne, Depth+1, Query(Q, I));
- KnownZero |= RHSKnownZero;
- KnownOne |= RHSKnownOne;
+ KnownBits RHSKnown(BitWidth);
+ computeKnownBits(A, RHSKnown, Depth+1, Query(Q, I));
+ Known.Zero |= RHSKnown.Zero;
+ Known.One |= RHSKnown.One;
// assume(v & b = a)
} else if (match(Arg,
m_c_ICmp(Pred, m_c_And(m_V, m_Value(B)), m_Value(A))) &&
Pred == ICmpInst::ICMP_EQ &&
isValidAssumeForContext(I, Q.CxtI, Q.DT)) {
- APInt RHSKnownZero(BitWidth, 0), RHSKnownOne(BitWidth, 0);
- computeKnownBits(A, RHSKnownZero, RHSKnownOne, Depth+1, Query(Q, I));
- APInt MaskKnownZero(BitWidth, 0), MaskKnownOne(BitWidth, 0);
- computeKnownBits(B, MaskKnownZero, MaskKnownOne, Depth+1, Query(Q, I));
+ KnownBits RHSKnown(BitWidth);
+ computeKnownBits(A, RHSKnown, Depth+1, Query(Q, I));
+ KnownBits MaskKnown(BitWidth);
+ computeKnownBits(B, MaskKnown, Depth+1, Query(Q, I));
// For those bits in the mask that are known to be one, we can propagate
// known bits from the RHS to V.
- KnownZero |= RHSKnownZero & MaskKnownOne;
- KnownOne |= RHSKnownOne & MaskKnownOne;
+ Known.Zero |= RHSKnown.Zero & MaskKnown.One;
+ Known.One |= RHSKnown.One & MaskKnown.One;
// assume(~(v & b) = a)
} else if (match(Arg, m_c_ICmp(Pred, m_Not(m_c_And(m_V, m_Value(B))),
m_Value(A))) &&
Pred == ICmpInst::ICMP_EQ &&
isValidAssumeForContext(I, Q.CxtI, Q.DT)) {
- APInt RHSKnownZero(BitWidth, 0), RHSKnownOne(BitWidth, 0);
- computeKnownBits(A, RHSKnownZero, RHSKnownOne, Depth+1, Query(Q, I));
- APInt MaskKnownZero(BitWidth, 0), MaskKnownOne(BitWidth, 0);
- computeKnownBits(B, MaskKnownZero, MaskKnownOne, Depth+1, Query(Q, I));
+ KnownBits RHSKnown(BitWidth);
+ computeKnownBits(A, RHSKnown, Depth+1, Query(Q, I));
+ KnownBits MaskKnown(BitWidth);
+ computeKnownBits(B, MaskKnown, Depth+1, Query(Q, I));
// For those bits in the mask that are known to be one, we can propagate
// inverted known bits from the RHS to V.
- KnownZero |= RHSKnownOne & MaskKnownOne;
- KnownOne |= RHSKnownZero & MaskKnownOne;
+ Known.Zero |= RHSKnown.One & MaskKnown.One;
+ Known.One |= RHSKnown.Zero & MaskKnown.One;
// assume(v | b = a)
} else if (match(Arg,
m_c_ICmp(Pred, m_c_Or(m_V, m_Value(B)), m_Value(A))) &&
Pred == ICmpInst::ICMP_EQ &&
isValidAssumeForContext(I, Q.CxtI, Q.DT)) {
- APInt RHSKnownZero(BitWidth, 0), RHSKnownOne(BitWidth, 0);
- computeKnownBits(A, RHSKnownZero, RHSKnownOne, Depth+1, Query(Q, I));
- APInt BKnownZero(BitWidth, 0), BKnownOne(BitWidth, 0);
- computeKnownBits(B, BKnownZero, BKnownOne, Depth+1, Query(Q, I));
+ KnownBits RHSKnown(BitWidth);
+ computeKnownBits(A, RHSKnown, Depth+1, Query(Q, I));
+ KnownBits BKnown(BitWidth);
+ computeKnownBits(B, BKnown, Depth+1, Query(Q, I));
// For those bits in B that are known to be zero, we can propagate known
// bits from the RHS to V.
- KnownZero |= RHSKnownZero & BKnownZero;
- KnownOne |= RHSKnownOne & BKnownZero;
+ Known.Zero |= RHSKnown.Zero & BKnown.Zero;
+ Known.One |= RHSKnown.One & BKnown.Zero;
// assume(~(v | b) = a)
} else if (match(Arg, m_c_ICmp(Pred, m_Not(m_c_Or(m_V, m_Value(B))),
m_Value(A))) &&
Pred == ICmpInst::ICMP_EQ &&
isValidAssumeForContext(I, Q.CxtI, Q.DT)) {
- APInt RHSKnownZero(BitWidth, 0), RHSKnownOne(BitWidth, 0);
- computeKnownBits(A, RHSKnownZero, RHSKnownOne, Depth+1, Query(Q, I));
- APInt BKnownZero(BitWidth, 0), BKnownOne(BitWidth, 0);
- computeKnownBits(B, BKnownZero, BKnownOne, Depth+1, Query(Q, I));
+ KnownBits RHSKnown(BitWidth);
+ computeKnownBits(A, RHSKnown, Depth+1, Query(Q, I));
+ KnownBits BKnown(BitWidth);
+ computeKnownBits(B, BKnown, Depth+1, Query(Q, I));
// For those bits in B that are known to be zero, we can propagate
// inverted known bits from the RHS to V.
- KnownZero |= RHSKnownOne & BKnownZero;
- KnownOne |= RHSKnownZero & BKnownZero;
+ Known.Zero |= RHSKnown.One & BKnown.Zero;
+ Known.One |= RHSKnown.Zero & BKnown.Zero;
// assume(v ^ b = a)
} else if (match(Arg,
m_c_ICmp(Pred, m_c_Xor(m_V, m_Value(B)), m_Value(A))) &&
Pred == ICmpInst::ICMP_EQ &&
isValidAssumeForContext(I, Q.CxtI, Q.DT)) {
- APInt RHSKnownZero(BitWidth, 0), RHSKnownOne(BitWidth, 0);
- computeKnownBits(A, RHSKnownZero, RHSKnownOne, Depth+1, Query(Q, I));
- APInt BKnownZero(BitWidth, 0), BKnownOne(BitWidth, 0);
- computeKnownBits(B, BKnownZero, BKnownOne, Depth+1, Query(Q, I));
+ KnownBits RHSKnown(BitWidth);
+ computeKnownBits(A, RHSKnown, Depth+1, Query(Q, I));
+ KnownBits BKnown(BitWidth);
+ computeKnownBits(B, BKnown, Depth+1, Query(Q, I));
// For those bits in B that are known to be zero, we can propagate known
// bits from the RHS to V. For those bits in B that are known to be one,
// we can propagate inverted known bits from the RHS to V.
- KnownZero |= RHSKnownZero & BKnownZero;
- KnownOne |= RHSKnownOne & BKnownZero;
- KnownZero |= RHSKnownOne & BKnownOne;
- KnownOne |= RHSKnownZero & BKnownOne;
+ Known.Zero |= RHSKnown.Zero & BKnown.Zero;
+ Known.One |= RHSKnown.One & BKnown.Zero;
+ Known.Zero |= RHSKnown.One & BKnown.One;
+ Known.One |= RHSKnown.Zero & BKnown.One;
// assume(~(v ^ b) = a)
} else if (match(Arg, m_c_ICmp(Pred, m_Not(m_c_Xor(m_V, m_Value(B))),
m_Value(A))) &&
Pred == ICmpInst::ICMP_EQ &&
isValidAssumeForContext(I, Q.CxtI, Q.DT)) {
- APInt RHSKnownZero(BitWidth, 0), RHSKnownOne(BitWidth, 0);
- computeKnownBits(A, RHSKnownZero, RHSKnownOne, Depth+1, Query(Q, I));
- APInt BKnownZero(BitWidth, 0), BKnownOne(BitWidth, 0);
- computeKnownBits(B, BKnownZero, BKnownOne, Depth+1, Query(Q, I));
+ KnownBits RHSKnown(BitWidth);
+ computeKnownBits(A, RHSKnown, Depth+1, Query(Q, I));
+ KnownBits BKnown(BitWidth);
+ computeKnownBits(B, BKnown, Depth+1, Query(Q, I));
// For those bits in B that are known to be zero, we can propagate
// inverted known bits from the RHS to V. For those bits in B that are
// known to be one, we can propagate known bits from the RHS to V.
- KnownZero |= RHSKnownOne & BKnownZero;
- KnownOne |= RHSKnownZero & BKnownZero;
- KnownZero |= RHSKnownZero & BKnownOne;
- KnownOne |= RHSKnownOne & BKnownOne;
+ Known.Zero |= RHSKnown.One & BKnown.Zero;
+ Known.One |= RHSKnown.Zero & BKnown.Zero;
+ Known.Zero |= RHSKnown.Zero & BKnown.One;
+ Known.One |= RHSKnown.One & BKnown.One;
// assume(v << c = a)
} else if (match(Arg, m_c_ICmp(Pred, m_Shl(m_V, m_ConstantInt(C)),
m_Value(A))) &&
Pred == ICmpInst::ICMP_EQ &&
isValidAssumeForContext(I, Q.CxtI, Q.DT)) {
- APInt RHSKnownZero(BitWidth, 0), RHSKnownOne(BitWidth, 0);
- computeKnownBits(A, RHSKnownZero, RHSKnownOne, Depth+1, Query(Q, I));
+ KnownBits RHSKnown(BitWidth);
+ computeKnownBits(A, RHSKnown, Depth+1, Query(Q, I));
// For those bits in RHS that are known, we can propagate them to known
// bits in V shifted to the right by C.
- RHSKnownZero.lshrInPlace(C->getZExtValue());
- KnownZero |= RHSKnownZero;
- RHSKnownOne.lshrInPlace(C->getZExtValue());
- KnownOne |= RHSKnownOne;
+ RHSKnown.Zero.lshrInPlace(C->getZExtValue());
+ Known.Zero |= RHSKnown.Zero;
+ RHSKnown.One.lshrInPlace(C->getZExtValue());
+ Known.One |= RHSKnown.One;
// assume(~(v << c) = a)
} else if (match(Arg, m_c_ICmp(Pred, m_Not(m_Shl(m_V, m_ConstantInt(C))),
m_Value(A))) &&
Pred == ICmpInst::ICMP_EQ &&
isValidAssumeForContext(I, Q.CxtI, Q.DT)) {
- APInt RHSKnownZero(BitWidth, 0), RHSKnownOne(BitWidth, 0);
- computeKnownBits(A, RHSKnownZero, RHSKnownOne, Depth+1, Query(Q, I));
+ KnownBits RHSKnown(BitWidth);
+ computeKnownBits(A, RHSKnown, Depth+1, Query(Q, I));
// For those bits in RHS that are known, we can propagate them inverted
// to known bits in V shifted to the right by C.
- RHSKnownOne.lshrInPlace(C->getZExtValue());
- KnownZero |= RHSKnownOne;
- RHSKnownZero.lshrInPlace(C->getZExtValue());
- KnownOne |= RHSKnownZero;
+ RHSKnown.One.lshrInPlace(C->getZExtValue());
+ Known.Zero |= RHSKnown.One;
+ RHSKnown.Zero.lshrInPlace(C->getZExtValue());
+ Known.One |= RHSKnown.Zero;
// assume(v >> c = a)
} else if (match(Arg,
m_c_ICmp(Pred, m_CombineOr(m_LShr(m_V, m_ConstantInt(C)),
@@ -685,12 +683,12 @@ static void computeKnownBitsFromAssume(const Value *V, APInt &KnownZero,
m_Value(A))) &&
Pred == ICmpInst::ICMP_EQ &&
isValidAssumeForContext(I, Q.CxtI, Q.DT)) {
- APInt RHSKnownZero(BitWidth, 0), RHSKnownOne(BitWidth, 0);
- computeKnownBits(A, RHSKnownZero, RHSKnownOne, Depth+1, Query(Q, I));
+ KnownBits RHSKnown(BitWidth);
+ computeKnownBits(A, RHSKnown, Depth+1, Query(Q, I));
// For those bits in RHS that are known, we can propagate them to known
// bits in V shifted to the right by C.
- KnownZero |= RHSKnownZero << C->getZExtValue();
- KnownOne |= RHSKnownOne << C->getZExtValue();
+ Known.Zero |= RHSKnown.Zero << C->getZExtValue();
+ Known.One |= RHSKnown.One << C->getZExtValue();
// assume(~(v >> c) = a)
} else if (match(Arg, m_c_ICmp(Pred, m_Not(m_CombineOr(
m_LShr(m_V, m_ConstantInt(C)),
@@ -698,78 +696,78 @@ static void computeKnownBitsFromAssume(const Value *V, APInt &KnownZero,
m_Value(A))) &&
Pred == ICmpInst::ICMP_EQ &&
isValidAssumeForContext(I, Q.CxtI, Q.DT)) {
- APInt RHSKnownZero(BitWidth, 0), RHSKnownOne(BitWidth, 0);
- computeKnownBits(A, RHSKnownZero, RHSKnownOne, Depth+1, Query(Q, I));
+ KnownBits RHSKnown(BitWidth);
+ computeKnownBits(A, RHSKnown, Depth+1, Query(Q, I));
// For those bits in RHS that are known, we can propagate them inverted
// to known bits in V shifted to the right by C.
- KnownZero |= RHSKnownOne << C->getZExtValue();
- KnownOne |= RHSKnownZero << C->getZExtValue();
+ Known.Zero |= RHSKnown.One << C->getZExtValue();
+ Known.One |= RHSKnown.Zero << C->getZExtValue();
// assume(v >=_s c) where c is non-negative
} else if (match(Arg, m_ICmp(Pred, m_V, m_Value(A))) &&
Pred == ICmpInst::ICMP_SGE &&
isValidAssumeForContext(I, Q.CxtI, Q.DT)) {
- APInt RHSKnownZero(BitWidth, 0), RHSKnownOne(BitWidth, 0);
- computeKnownBits(A, RHSKnownZero, RHSKnownOne, Depth+1, Query(Q, I));
+ KnownBits RHSKnown(BitWidth);
+ computeKnownBits(A, RHSKnown, Depth+1, Query(Q, I));
- if (RHSKnownZero.isSignBitSet()) {
+ if (RHSKnown.Zero.isSignBitSet()) {
// We know that the sign bit is zero.
- KnownZero.setSignBit();
+ Known.Zero.setSignBit();
}
// assume(v >_s c) where c is at least -1.
} else if (match(Arg, m_ICmp(Pred, m_V, m_Value(A))) &&
Pred == ICmpInst::ICMP_SGT &&
isValidAssumeForContext(I, Q.CxtI, Q.DT)) {
- APInt RHSKnownZero(BitWidth, 0), RHSKnownOne(BitWidth, 0);
- computeKnownBits(A, RHSKnownZero, RHSKnownOne, Depth+1, Query(Q, I));
+ KnownBits RHSKnown(BitWidth);
+ computeKnownBits(A, RHSKnown, Depth+1, Query(Q, I));
- if (RHSKnownOne.isAllOnesValue() || RHSKnownZero.isSignBitSet()) {
+ if (RHSKnown.One.isAllOnesValue() || RHSKnown.Zero.isSignBitSet()) {
// We know that the sign bit is zero.
- KnownZero.setSignBit();
+ Known.Zero.setSignBit();
}
// assume(v <=_s c) where c is negative
} else if (match(Arg, m_ICmp(Pred, m_V, m_Value(A))) &&
Pred == ICmpInst::ICMP_SLE &&
isValidAssumeForContext(I, Q.CxtI, Q.DT)) {
- APInt RHSKnownZero(BitWidth, 0), RHSKnownOne(BitWidth, 0);
- computeKnownBits(A, RHSKnownZero, RHSKnownOne, Depth+1, Query(Q, I));
+ KnownBits RHSKnown(BitWidth);
+ computeKnownBits(A, RHSKnown, Depth+1, Query(Q, I));
- if (RHSKnownOne.isSignBitSet()) {
+ if (RHSKnown.One.isSignBitSet()) {
// We know that the sign bit is one.
- KnownOne.setSignBit();
+ Known.One.setSignBit();
}
// assume(v <_s c) where c is non-positive
} else if (match(Arg, m_ICmp(Pred, m_V, m_Value(A))) &&
Pred == ICmpInst::ICMP_SLT &&
isValidAssumeForContext(I, Q.CxtI, Q.DT)) {
- APInt RHSKnownZero(BitWidth, 0), RHSKnownOne(BitWidth, 0);
- computeKnownBits(A, RHSKnownZero, RHSKnownOne, Depth+1, Query(Q, I));
+ KnownBits RHSKnown(BitWidth);
+ computeKnownBits(A, RHSKnown, Depth+1, Query(Q, I));
- if (RHSKnownZero.isAllOnesValue() || RHSKnownOne.isSignBitSet()) {
+ if (RHSKnown.Zero.isAllOnesValue() || RHSKnown.One.isSignBitSet()) {
// We know that the sign bit is one.
- KnownOne.setSignBit();
+ Known.One.setSignBit();
}
// assume(v <=_u c)
} else if (match(Arg, m_ICmp(Pred, m_V, m_Value(A))) &&
Pred == ICmpInst::ICMP_ULE &&
isValidAssumeForContext(I, Q.CxtI, Q.DT)) {
- APInt RHSKnownZero(BitWidth, 0), RHSKnownOne(BitWidth, 0);
- computeKnownBits(A, RHSKnownZero, RHSKnownOne, Depth+1, Query(Q, I));
+ KnownBits RHSKnown(BitWidth);
+ computeKnownBits(A, RHSKnown, Depth+1, Query(Q, I));
// Whatever high bits in c are zero are known to be zero.
- KnownZero.setHighBits(RHSKnownZero.countLeadingOnes());
+ Known.Zero.setHighBits(RHSKnown.Zero.countLeadingOnes());
// assume(v <_u c)
} else if (match(Arg, m_ICmp(Pred, m_V, m_Value(A))) &&
Pred == ICmpInst::ICMP_ULT &&
isValidAssumeForContext(I, Q.CxtI, Q.DT)) {
- APInt RHSKnownZero(BitWidth, 0), RHSKnownOne(BitWidth, 0);
- computeKnownBits(A, RHSKnownZero, RHSKnownOne, Depth+1, Query(Q, I));
+ KnownBits RHSKnown(BitWidth);
+ computeKnownBits(A, RHSKnown, Depth+1, Query(Q, I));
// Whatever high bits in c are zero are known to be zero (if c is a power
// of 2, then one more).
if (isKnownToBeAPowerOfTwo(A, false, Depth + 1, Query(Q, I)))
- KnownZero.setHighBits(RHSKnownZero.countLeadingOnes()+1);
+ Known.Zero.setHighBits(RHSKnown.Zero.countLeadingOnes()+1);
else
- KnownZero.setHighBits(RHSKnownZero.countLeadingOnes());
+ Known.Zero.setHighBits(RHSKnown.Zero.countLeadingOnes());
}
}
@@ -778,9 +776,9 @@ static void computeKnownBitsFromAssume(const Value *V, APInt &KnownZero,
// so this isn't a real bug. On the other hand, the program may have undefined
// behavior, or we might have a bug in the compiler. We can't assert/crash, so
// clear out the known bits, try to warn the user, and hope for the best.
- if ((KnownZero & KnownOne) != 0) {
- KnownZero.clearAllBits();
- KnownOne.clearAllBits();
+ if (Known.Zero.intersects(Known.One)) {
+ Known.Zero.clearAllBits();
+ Known.One.clearAllBits();
if (Q.ORE) {
auto *CxtI = const_cast<Instruction *>(Q.CxtI);
@@ -793,57 +791,57 @@ static void computeKnownBitsFromAssume(const Value *V, APInt &KnownZero,
}
// Compute known bits from a shift operator, including those with a
-// non-constant shift amount. KnownZero and KnownOne are the outputs of this
-// function. KnownZero2 and KnownOne2 are pre-allocated temporaries with the
-// same bit width as KnownZero and KnownOne. KZF and KOF are operator-specific
-// functors that, given the known-zero or known-one bits respectively, and a
-// shift amount, compute the implied known-zero or known-one bits of the shift
-// operator's result respectively for that shift amount. The results from calling
-// KZF and KOF are conservatively combined for all permitted shift amounts.
+// non-constant shift amount. Known is the outputs of this function. Known2 is a
+// pre-allocated temporary with the/ same bit width as Known. KZF and KOF are
+// operator-specific functors that, given the known-zero or known-one bits
+// respectively, and a shift amount, compute the implied known-zero or known-one
+// bits of the shift operator's result respectively for that shift amount. The
+// results from calling KZF and KOF are conservatively combined for all
+// permitted shift amounts.
static void computeKnownBitsFromShiftOperator(
- const Operator *I, APInt &KnownZero, APInt &KnownOne, APInt &KnownZero2,
- APInt &KnownOne2, unsigned Depth, const Query &Q,
+ const Operator *I, KnownBits &Known, KnownBits &Known2,
+ unsigned Depth, const Query &Q,
function_ref<APInt(const APInt &, unsigned)> KZF,
function_ref<APInt(const APInt &, unsigned)> KOF) {
- unsigned BitWidth = KnownZero.getBitWidth();
+ unsigned BitWidth = Known.getBitWidth();
if (auto *SA = dyn_cast<ConstantInt>(I->getOperand(1))) {
unsigned ShiftAmt = SA->getLimitedValue(BitWidth-1);
- computeKnownBits(I->getOperand(0), KnownZero, KnownOne, Depth + 1, Q);
- KnownZero = KZF(KnownZero, ShiftAmt);
- KnownOne = KOF(KnownOne, ShiftAmt);
- // If there is conflict between KnownZero and KnownOne, this must be an
- // overflowing left shift, so the shift result is undefined. Clear KnownZero
- // and KnownOne bits so that other code could propagate this undef.
- if ((KnownZero & KnownOne) != 0) {
- KnownZero.clearAllBits();
- KnownOne.clearAllBits();
+ computeKnownBits(I->getOperand(0), Known, Depth + 1, Q);
+ Known.Zero = KZF(Known.Zero, ShiftAmt);
+ Known.One = KOF(Known.One, ShiftAmt);
+ // If there is conflict between Known.Zero and Known.One, this must be an
+ // overflowing left shift, so the shift result is undefined. Clear Known
+ // bits so that other code could propagate this undef.
+ if ((Known.Zero & Known.One) != 0) {
+ Known.Zero.clearAllBits();
+ Known.One.clearAllBits();
}
return;
}
- computeKnownBits(I->getOperand(1), KnownZero, KnownOne, Depth + 1, Q);
+ computeKnownBits(I->getOperand(1), Known, Depth + 1, Q);
// If the shift amount could be greater than or equal to the bit-width of the LHS, the
// value could be undef, so we don't know anything about it.
- if ((~KnownZero).uge(BitWidth)) {
- KnownZero.clearAllBits();
- KnownOne.clearAllBits();
+ if ((~Known.Zero).uge(BitWidth)) {
+ Known.Zero.clearAllBits();
+ Known.One.clearAllBits();
return;
}
- // Note: We cannot use KnownZero.getLimitedValue() here, because if
+ // Note: We cannot use Known.Zero.getLimitedValue() here, because if
// BitWidth > 64 and any upper bits are known, we'll end up returning the
// limit value (which implies all bits are known).
- uint64_t ShiftAmtKZ = KnownZero.zextOrTrunc(64).getZExtValue();
- uint64_t ShiftAmtKO = KnownOne.zextOrTrunc(64).getZExtValue();
+ uint64_t ShiftAmtKZ = Known.Zero.zextOrTrunc(64).getZExtValue();
+ uint64_t ShiftAmtKO = Known.One.zextOrTrunc(64).getZExtValue();
// It would be more-clearly correct to use the two temporaries for this
// calculation. Reusing the APInts here to prevent unnecessary allocations.
- KnownZero.clearAllBits();
- KnownOne.clearAllBits();
+ Known.Zero.clearAllBits();
+ Known.One.clearAllBits();
// If we know the shifter operand is nonzero, we can sometimes infer more
// known bits. However this is expensive to compute, so be lazy about it and
@@ -858,9 +856,10 @@ static void computeKnownBitsFromShiftOperator(
return;
}
- computeKnownBits(I->getOperand(0), KnownZero2, KnownOne2, Depth + 1, Q);
+ computeKnownBits(I->getOperand(0), Known2, Depth + 1, Q);
- KnownZero = KnownOne = APInt::getAllOnesValue(BitWidth);
+ Known.Zero.setAllBits();
+ Known.One.setAllBits();
for (unsigned ShiftAmt = 0; ShiftAmt < BitWidth; ++ShiftAmt) {
// Combine the shifted known input bits only for those shift amounts
// compatible with its known constraints.
@@ -879,8 +878,8 @@ static void computeKnownBitsFromShiftOperator(
continue;
}
- KnownZero &= KZF(KnownZero2, ShiftAmt);
- KnownOne &= KOF(KnownOne2, ShiftAmt);
+ Known.Zero &= KZF(Known2.Zero, ShiftAmt);
+ Known.One &= KOF(Known2.One, ShiftAmt);
}
// If there are no compatible shift amounts, then we've proven that the shift
@@ -888,33 +887,32 @@ static void computeKnownBitsFromShiftOperator(
// return anything we'd like, but we need to make sure the sets of known bits
// stay disjoint (it should be better for some other code to actually
// propagate the undef than to pick a value here using known bits).
- if ((KnownZero & KnownOne) != 0) {
- KnownZero.clearAllBits();
- KnownOne.clearAllBits();
+ if (Known.Zero.intersects(Known.One)) {
+ Known.Zero.clearAllBits();
+ Known.One.clearAllBits();
}
}
-static void computeKnownBitsFromOperator(const Operator *I, APInt &KnownZero,
- APInt &KnownOne, unsigned Depth,
- const Query &Q) {
- unsigned BitWidth = KnownZero.getBitWidth();
+static void computeKnownBitsFromOperator(const Operator *I, KnownBits &Known,
+ unsigned Depth, const Query &Q) {
+ unsigned BitWidth = Known.getBitWidth();
- APInt KnownZero2(KnownZero), KnownOne2(KnownOne);
+ KnownBits Known2(Known);
switch (I->getOpcode()) {
default: break;
case Instruction::Load:
if (MDNode *MD = cast<LoadInst>(I)->getMetadata(LLVMContext::MD_range))
- computeKnownBitsFromRangeMetadata(*MD, KnownZero, KnownOne);
+ computeKnownBitsFromRangeMetadata(*MD, Known.Zero, Known.One);
break;
case Instruction::And: {
// If either the LHS or the RHS are Zero, the result is zero.
- computeKnownBits(I->getOperand(1), KnownZero, KnownOne, Depth + 1, Q);
- computeKnownBits(I->getOperand(0), KnownZero2, KnownOne2, Depth + 1, Q);
+ computeKnownBits(I->getOperand(1), Known, Depth + 1, Q);
+ computeKnownBits(I->getOperand(0), Known2, Depth + 1, Q);
// Output known-1 bits are only known if set in both the LHS & RHS.
- KnownOne &= KnownOne2;
+ Known.One &= Known2.One;
// Output known-0 are known to be clear if zero in either the LHS | RHS.
- KnownZero |= KnownZero2;
+ Known.Zero |= Known2.Zero;
// and(x, add (x, -1)) is a common idiom that always clears the low bit;
// here we handle the more general case of adding any odd number by
@@ -922,115 +920,115 @@ static void computeKnownBitsFromOperator(const Operator *I, APInt &KnownZero,
// TODO: This could be generalized to clearing any bit set in y where the
// following bit is known to be unset in y.
Value *Y = nullptr;
- if (!KnownZero[0] && !KnownOne[0] &&
+ if (!Known.Zero[0] && !Known.One[0] &&
(match(I->getOperand(0), m_Add(m_Specific(I->getOperand(1)),
m_Value(Y))) ||
match(I->getOperand(1), m_Add(m_Specific(I->getOperand(0)),
m_Value(Y))))) {
- KnownZero2.clearAllBits(); KnownOne2.clearAllBits();
- computeKnownBits(Y, KnownZero2, KnownOne2, Depth + 1, Q);
- if (KnownOne2.countTrailingOnes() > 0)
- KnownZero.setBit(0);
+ Known2.Zero.clearAllBits(); Known2.One.clearAllBits();
+ computeKnownBits(Y, Known2, Depth + 1, Q);
+ if (Known2.One.countTrailingOnes() > 0)
+ Known.Zero.setBit(0);
}
break;
}
case Instruction::Or: {
- computeKnownBits(I->getOperand(1), KnownZero, KnownOne, Depth + 1, Q);
- computeKnownBits(I->getOperand(0), KnownZero2, KnownOne2, Depth + 1, Q);
+ computeKnownBits(I->getOperand(1), Known, Depth + 1, Q);
+ computeKnownBits(I->getOperand(0), Known2, Depth + 1, Q);
// Output known-0 bits are only known if clear in both the LHS & RHS.
- KnownZero &= KnownZero2;
+ Known.Zero &= Known2.Zero;
// Output known-1 are known to be set if set in either the LHS | RHS.
- KnownOne |= KnownOne2;
+ Known.One |= Known2.One;
break;
}
case Instruction::Xor: {
- computeKnownBits(I->getOperand(1), KnownZero, KnownOne, Depth + 1, Q);
- computeKnownBits(I->getOperand(0), KnownZero2, KnownOne2, Depth + 1, Q);
+ computeKnownBits(I->getOperand(1), Known, Depth + 1, Q);
+ computeKnownBits(I->getOperand(0), Known2, Depth + 1, Q);
// Output known-0 bits are known if clear or set in both the LHS & RHS.
- APInt KnownZeroOut = (KnownZero & KnownZero2) | (KnownOne & KnownOne2);
+ APInt KnownZeroOut = (Known.Zero & Known2.Zero) | (Known.One & Known2.One);
// Output known-1 are known to be set if set in only one of the LHS, RHS.
- KnownOne = (KnownZero & KnownOne2) | (KnownOne & KnownZero2);
- KnownZero = std::move(KnownZeroOut);
+ Known.One = (Known.Zero & Known2.One) | (Known.One & Known2.Zero);
+ Known.Zero = std::move(KnownZeroOut);
break;
}
case Instruction::Mul: {
bool NSW = cast<OverflowingBinaryOperator>(I)->hasNoSignedWrap();
- computeKnownBitsMul(I->getOperand(0), I->getOperand(1), NSW, KnownZero,
- KnownOne, KnownZero2, KnownOne2, Depth, Q);
+ computeKnownBitsMul(I->getOperand(0), I->getOperand(1), NSW, Known,
+ Known2, Depth, Q);
break;
}
case Instruction::UDiv: {
// For the purposes of computing leading zeros we can conservatively
// treat a udiv as a logical right shift by the power of 2 known to
// be less than the denominator.
- computeKnownBits(I->getOperand(0), KnownZero2, KnownOne2, Depth + 1, Q);
- unsigned LeadZ = KnownZero2.countLeadingOnes();
+ computeKnownBits(I->getOperand(0), Known2, Depth + 1, Q);
+ unsigned LeadZ = Known2.Zero.countLeadingOnes();
- KnownOne2.clearAllBits();
- KnownZero2.clearAllBits();
- computeKnownBits(I->getOperand(1), KnownZero2, KnownOne2, Depth + 1, Q);
- unsigned RHSUnknownLeadingOnes = KnownOne2.countLeadingZeros();
+ Known2.One.clearAllBits();
+ Known2.Zero.clearAllBits();
+ computeKnownBits(I->getOperand(1), Known2, Depth + 1, Q);
+ unsigned RHSUnknownLeadingOnes = Known2.One.countLeadingZeros();
if (RHSUnknownLeadingOnes != BitWidth)
LeadZ = std::min(BitWidth,
LeadZ + BitWidth - RHSUnknownLeadingOnes - 1);
- KnownZero.setHighBits(LeadZ);
+ Known.Zero.setHighBits(LeadZ);
break;
}
case Instruction::Select: {
const Value *LHS, *RHS;
SelectPatternFlavor SPF = matchSelectPattern(I, LHS, RHS).Flavor;
if (SelectPatternResult::isMinOrMax(SPF)) {
- computeKnownBits(RHS, KnownZero, KnownOne, Depth + 1, Q);
- computeKnownBits(LHS, KnownZero2, KnownOne2, Depth + 1, Q);
+ computeKnownBits(RHS, Known, Depth + 1, Q);
+ computeKnownBits(LHS, Known2, Depth + 1, Q);
} else {
- computeKnownBits(I->getOperand(2), KnownZero, KnownOne, Depth + 1, Q);
- computeKnownBits(I->getOperand(1), KnownZero2, KnownOne2, Depth + 1, Q);
+ computeKnownBits(I->getOperand(2), Known, Depth + 1, Q);
+ computeKnownBits(I->getOperand(1), Known2, Depth + 1, Q);
}
unsigned MaxHighOnes = 0;
unsigned MaxHighZeros = 0;
if (SPF == SPF_SMAX) {
// If both sides are negative, the result is negative.
- if (KnownOne.isSignBitSet() && KnownOne2.isSignBitSet())
+ if (Known.One.isSignBitSet() && Known2.One.isSignBitSet())
// We can derive a lower bound on the result by taking the max of the
// leading one bits.
- MaxHighOnes =
- std::max(KnownOne.countLeadingOnes(), KnownOne2.countLeadingOnes());
+ MaxHighOnes = std::max(Known.One.countLeadingOnes(),
+ Known2.One.countLeadingOnes());
// If either side is non-negative, the result is non-negative.
- else if (KnownZero.isSignBitSet() || KnownZero2.isSignBitSet())
+ else if (Known.Zero.isSignBitSet() || Known2.Zero.isSignBitSet())
MaxHighZeros = 1;
} else if (SPF == SPF_SMIN) {
// If both sides are non-negative, the result is non-negative.
- if (KnownZero.isSignBitSet() && KnownZero2.isSignBitSet())
+ if (Known.Zero.isSignBitSet() && Known2.Zero.isSignBitSet())
// We can derive an upper bound on the result by taking the max of the
// leading zero bits.
- MaxHighZeros = std::max(KnownZero.countLeadingOnes(),
- KnownZero2.countLeadingOnes());
+ MaxHighZeros = std::max(Known.Zero.countLeadingOnes(),
+ Known2.Zero.countLeadingOnes());
// If either side is negative, the result is negative.
- else if (KnownOne.isSignBitSet() || KnownOne2.isSignBitSet())
+ else if (Known.One.isSignBitSet() || Known2.One.isSignBitSet())
MaxHighOnes = 1;
} else if (SPF == SPF_UMAX) {
// We can derive a lower bound on the result by taking the max of the
// leading one bits.
MaxHighOnes =
- std::max(KnownOne.countLeadingOnes(), KnownOne2.countLeadingOnes());
+ std::max(Known.One.countLeadingOnes(), Known2.One.countLeadingOnes());
} else if (SPF == SPF_UMIN) {
// We can derive an upper bound on the result by taking the max of the
// leading zero bits.
MaxHighZeros =
- std::max(KnownZero.countLeadingOnes(), KnownZero2.countLeadingOnes());
+ std::max(Known.Zero.countLeadingOnes(), Known2.Zero.countLeadingOnes());
}
// Only known if known in both the LHS and RHS.
- KnownOne &= KnownOne2;
- KnownZero &= KnownZero2;
+ Known.One &= Known2.One;
+ Known.Zero &= Known2.Zero;
if (MaxHighOnes > 0)
- KnownOne.setHighBits(MaxHighOnes);
+ Known.One.setHighBits(MaxHighOnes);
if (MaxHighZeros > 0)
- KnownZero.setHighBits(MaxHighZeros);
+ Known.Zero.setHighBits(MaxHighZeros);
break;
}
case Instruction::FPTrunc:
@@ -1054,14 +1052,14 @@ static void computeKnownBitsFromOperator(const Operator *I, APInt &KnownZero,
SrcBitWidth = Q.DL.getTypeSizeInBits(SrcTy->getScalarType());
assert(SrcBitWidth && "SrcBitWidth can't be zero");
- KnownZero = KnownZero.zextOrTrunc(SrcBitWidth);
- KnownOne = KnownOne.zextOrTrunc(SrcBitWidth);
- computeKnownBits(I->getOperand(0), KnownZero, KnownOne, Depth + 1, Q);
- KnownZero = KnownZero.zextOrTrunc(BitWidth);
- KnownOne = KnownOne.zextOrTrunc(BitWidth);
+ Known.Zero = Known.Zero.zextOrTrunc(SrcBitWidth);
+ Known.One = Known.One.zextOrTrunc(SrcBitWidth);
+ computeKnownBits(I->getOperand(0), Known, Depth + 1, Q);
+ Known.Zero = Known.Zero.zextOrTrunc(BitWidth);
+ Known.One = Known.One.zextOrTrunc(BitWidth);
// Any top bits are known to be zero.
if (BitWidth > SrcBitWidth)
- KnownZero.setBitsFrom(SrcBitWidth);
+ Known.Zero.setBitsFrom(SrcBitWidth);
break;
}
case Instruction::BitCast: {
@@ -1070,7 +1068,7 @@ static void computeKnownBitsFromOperator(const Operator *I, APInt &KnownZero,
// TODO: For now, not handling conversions like:
// (bitcast i64 %x to <2 x i32>)
!I->getType()->isVectorTy()) {
- computeKnownBits(I->getOperand(0), KnownZero, KnownOne, Depth + 1, Q);
+ computeKnownBits(I->getOperand(0), Known, Depth + 1, Q);
break;
}
break;
@@ -1079,13 +1077,13 @@ static void computeKnownBitsFromOperator(const Operator *I, APInt &KnownZero,
// Compute the bits in the result that are not present in the input.
unsigned SrcBitWidth = I->getOperand(0)->getType()->getScalarSizeInBits();
- KnownZero = KnownZero.trunc(SrcBitWidth);
- KnownOne = KnownOne.trunc(SrcBitWidth);
- computeKnownBits(I->getOperand(0), KnownZero, KnownOne, Depth + 1, Q);
+ Known.Zero = Known.Zero.trunc(SrcBitWidth);
+ Known.One = Known.One.trunc(SrcBitWidth);
+ computeKnownBits(I->getOperand(0), Known, Depth + 1, Q);
// If the sign bit of the input is known set or clear, then we know the
// top bits of the result.
- KnownZero = KnownZero.sext(BitWidth);
- KnownOne = KnownOne.sext(BitWidth);
+ Known.Zero = Known.Zero.sext(BitWidth);
+ Known.One = Known.One.sext(BitWidth);
break;
}
case Instruction::Shl: {
@@ -1108,9 +1106,7 @@ static void computeKnownBitsFromOperator(const Operator *I, APInt &KnownZero,
return KOResult;
};
- computeKnownBitsFromShiftOperator(I, KnownZero, KnownOne,
- KnownZero2, KnownOne2, Depth, Q, KZF,
- KOF);
+ computeKnownBitsFromShiftOperator(I, Known, Known2, Depth, Q, KZF, KOF);
break;
}
case Instruction::LShr: {
@@ -1126,9 +1122,7 @@ static void computeKnownBitsFromOperator(const Operator *I, APInt &KnownZero,
return KnownOne.lshr(ShiftAmt);
};
- computeKnownBitsFromShiftOperator(I, KnownZero, KnownOne,
- KnownZero2, KnownOne2, Depth, Q, KZF,
- KOF);
+ computeKnownBitsFromShiftOperator(I, Known, Known2, Depth, Q, KZF, KOF);
break;
}
case Instruction::AShr: {
@@ -1141,23 +1135,19 @@ static void computeKnownBitsFromOperator(const Operator *I, APInt &KnownZero,
return KnownOne.ashr(ShiftAmt);
};
- computeKnownBitsFromShiftOperator(I, KnownZero, KnownOne,
- KnownZero2, KnownOne2, Depth, Q, KZF,
- KOF);
+ computeKnownBitsFromShiftOperator(I, Known, Known2, Depth, Q, KZF, KOF);
break;
}
case Instruction::Sub: {
bool NSW = cast<OverflowingBinaryOperator>(I)->hasNoSignedWrap();
computeKnownBitsAddSub(false, I->getOperand(0), I->getOperand(1), NSW,
- KnownZero, KnownOne, KnownZero2, KnownOne2, Depth,
- Q);
+ Known, Known2, Depth, Q);
break;
}
case Instruction::Add: {
bool NSW = cast<OverflowingBinaryOperator>(I)->hasNoSignedWrap();
computeKnownBitsAddSub(true, I->getOperand(0), I->getOperand(1), NSW,
- KnownZero, KnownOne, KnownZero2, KnownOne2, Depth,
- Q);
+ Known, Known2, Depth, Q);
break;
}
case Instruction::SRem:
@@ -1165,34 +1155,33 @@ static void computeKnownBitsFromOperator(const Operator *I, APInt &KnownZero,
APInt RA = Rem->getValue().abs();
if (RA.isPowerOf2()) {
APInt LowBits = RA - 1;
- computeKnownBits(I->getOperand(0), KnownZero2, KnownOne2, Depth + 1,
- Q);
+ computeKnownBits(I->getOperand(0), Known2, Depth + 1, Q);
// The low bits of the first operand are unchanged by the srem.
- KnownZero = KnownZero2 & LowBits;
- KnownOne = KnownOne2 & LowBits;
+ Known.Zero = Known2.Zero & LowBits;
+ Known.One = Known2.One & LowBits;
// If the first operand is non-negative or has all low bits zero, then
// the upper bits are all zero.
- if (KnownZero2.isSignBitSet() || ((KnownZero2 & LowBits) == LowBits))
- KnownZero |= ~LowBits;
+ if (Known2.Zero.isSignBitSet() || ((Known2.Zero & LowBits) == LowBits))
+ Known.Zero |= ~LowBits;
// If the first operand is negative and not all low bits are zero, then
// the upper bits are all one.
- if (KnownOne2.isSignBitSet() && ((KnownOne2 & LowBits) != 0))
- KnownOne |= ~LowBits;
+ if (Known2.One.isSignBitSet() && ((Known2.One & LowBits) != 0))
+ Known.One |= ~LowBits;
- assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
+ assert((Known.Zero & Known.One) == 0 && "Bits known to be one AND zero?");
break;
}
}
// The sign bit is the LHS's sign bit, except when the result of the
// remainder is zero.
- computeKnownBits(I->getOperand(0), KnownZero2, KnownOne2, Depth + 1, Q);
+ computeKnownBits(I->getOperand(0), Known2, Depth + 1, Q);
// If it's known zero, our sign bit is also zero.
- if (KnownZero2.isSignBitSet())
- KnownZero.setSignBit();
+ if (Known2.Zero.isSignBitSet())
+ Known.Zero.setSignBit();
break;
case Instruction::URem: {
@@ -1200,23 +1189,23 @@ static void computeKnownBitsFromOperator(const Operator *I, APInt &KnownZero,
const APInt &RA = Rem->getValue();
if (RA.isPowerOf2()) {
APInt LowBits = (RA - 1);
- computeKnownBits(I->getOperand(0), KnownZero, KnownOne, Depth + 1, Q);
- KnownZero |= ~LowBits;
- KnownOne &= LowBits;
+ computeKnownBits(I->getOperand(0), Known, Depth + 1, Q);
+ Known.Zero |= ~LowBits;
+ Known.One &= LowBits;
break;
}
}
// Since the result is less than or equal to either operand, any leading
// zero bits in either operand must also exist in the result.
- computeKnownBits(I->getOperand(0), KnownZero, KnownOne, Depth + 1, Q);
- computeKnownBits(I->getOperand(1), KnownZero2, KnownOne2, Depth + 1, Q);
-
- unsigned Leaders = std::max(KnownZero.countLeadingOnes(),
- KnownZero2.countLeadingOnes());
- KnownOne.clearAllBits();
- KnownZero.clearAllBits();
- KnownZero.setHighBits(Leaders);
+ computeKnownBits(I->getOperand(0), Known, Depth + 1, Q);
+ computeKnownBits(I->getOperand(1), Known2, Depth + 1, Q);
+
+ unsigned Leaders = std::max(Known.Zero.countLeadingOnes(),
+ Known2.Zero.countLeadingOnes());
+ Known.One.clearAllBits();
+ Known.Zero.clearAllBits();
+ Known.Zero.setHighBits(Leaders);
break;
}
@@ -1227,16 +1216,15 @@ static void computeKnownBitsFromOperator(const Operator *I, APInt &KnownZero,
Align = Q.DL.getABITypeAlignment(AI->getAllocatedType());
if (Align > 0)
- KnownZero.setLowBits(countTrailingZeros(Align));
+ Known.Zero.setLowBits(countTrailingZeros(Align));
break;
}
case Instruction::GetElementPtr: {
// Analyze all of the subscripts of this getelementptr instruction
// to determine if we can prove known low zero bits.
- APInt LocalKnownZero(BitWidth, 0), LocalKnownOne(BitWidth, 0);
- computeKnownBits(I->getOperand(0), LocalKnownZero, LocalKnownOne, Depth + 1,
- Q);
- unsigned TrailZ = LocalKnownZero.countTrailingOnes();
+ KnownBits LocalKnown(BitWidth);
+ computeKnownBits(I->getOperand(0), LocalKnown, Depth + 1, Q);
+ unsigned TrailZ = LocalKnown.Zero.countTrailingOnes();
gep_type_iterator GTI = gep_type_begin(I);
for (unsigned i = 1, e = I->getNumOperands(); i != e; ++i, ++GTI) {
@@ -1266,15 +1254,15 @@ static void computeKnownBitsFromOperator(const Operator *I, APInt &KnownZero,
}
unsigned GEPOpiBits = Index->getType()->getScalarSizeInBits();
uint64_t TypeSize = Q.DL.getTypeAllocSize(IndexedTy);
- LocalKnownZero = LocalKnownOne = APInt(GEPOpiBits, 0);
- computeKnownBits(Index, LocalKnownZero, LocalKnownOne, Depth + 1, Q);
+ LocalKnown.Zero = LocalKnown.One = APInt(GEPOpiBits, 0);
+ computeKnownBits(Index, LocalKnown, Depth + 1, Q);
TrailZ = std::min(TrailZ,
unsigned(countTrailingZeros(TypeSize) +
- LocalKnownZero.countTrailingOnes()));
+ LocalKnown.Zero.countTrailingOnes()));
}
}
- KnownZero.setLowBits(TrailZ);
+ Known.Zero.setLowBits(TrailZ);
break;
}
case Instruction::PHI: {
@@ -1309,14 +1297,14 @@ static void computeKnownBitsFromOperator(const Operator *I, APInt &KnownZero,
break;
// Ok, we have a PHI of the form L op= R. Check for low
// zero bits.
- computeKnownBits(R, KnownZero2, KnownOne2, Depth + 1, Q);
+ computeKnownBits(R, Known2, Depth + 1, Q);
// We need to take the minimum number of known bits
- APInt KnownZero3(KnownZero), KnownOne3(KnownOne);
- computeKnownBits(L, KnownZero3, KnownOne3, Depth + 1, Q);
+ KnownBits Known3(Known);
+ computeKnownBits(L, Known3, Depth + 1, Q);
- KnownZero.setLowBits(std::min(KnownZero2.countTrailingOnes(),
- KnownZero3.countTrailingOnes()));
+ Known.Zero.setLowBits(std::min(Known2.Zero.countTrailingOnes(),
+ Known3.Zero.countTrailingOnes()));
if (DontImproveNonNegativePhiBits)
break;
@@ -1333,25 +1321,25 @@ static void computeKnownBitsFromOperator(const Operator *I, APInt &KnownZero,
// (add non-negative, non-negative) --> non-negative
// (add negative, negative) --> negative
if (Opcode == Instruction::Add) {
- if (KnownZero2.isSignBitSet() && KnownZero3.isSignBitSet())
- KnownZero.setSignBit();
- else if (KnownOne2.isSignBitSet() && KnownOne3.isSignBitSet())
- KnownOne.setSignBit();
+ if (Known2.Zero.isSignBitSet() && Known3.Zero.isSignBitSet())
+ Known.Zero.setSignBit();
+ else if (Known2.One.isSignBitSet() && Known3.One.isSignBitSet())
+ Known.One.setSignBit();
}
// (sub nsw non-negative, negative) --> non-negative
// (sub nsw negative, non-negative) --> negative
else if (Opcode == Instruction::Sub && LL == I) {
- if (KnownZero2.isSignBitSet() && KnownOne3.isSignBitSet())
- KnownZero.setSignBit();
- else if (KnownOne2.isSignBitSet() && KnownZero3.isSignBitSet())
- KnownOne.setSignBit();
+ if (Known2.Zero.isSignBitSet() && Known3.One.isSignBitSet())
+ Known.Zero.setSignBit();
+ else if (Known2.One.isSignBitSet() && Known3.Zero.isSignBitSet())
+ Known.One.setSignBit();
}
// (mul nsw non-negative, non-negative) --> non-negative
- else if (Opcode == Instruction::Mul && KnownZero2.isSignBitSet() &&
- KnownZero3.isSignBitSet())
- KnownZero.setSignBit();
+ else if (Opcode == Instruction::Mul && Known2.Zero.isSignBitSet() &&
+ Known3.Zero.isSignBitSet())
+ Known.Zero.setSignBit();
}
break;
@@ -1365,27 +1353,26 @@ static void computeKnownBitsFromOperator(const Operator *I, APInt &KnownZero,
// Otherwise take the unions of the known bit sets of the operands,
// taking conservative care to avoid excessive recursion.
- if (Depth < MaxDepth - 1 && !KnownZero && !KnownOne) {
+ if (Depth < MaxDepth - 1 && !Known.Zero && !Known.One) {
// Skip if every incoming value references to ourself.
if (dyn_cast_or_null<UndefValue>(P->hasConstantValue()))
break;
- KnownZero.setAllBits();
- KnownOne.setAllBits();
+ Known.Zero.setAllBits();
+ Known.One.setAllBits();
for (Value *IncValue : P->incoming_values()) {
// Skip direct self references.
if (IncValue == P) continue;
- KnownZero2 = APInt(BitWidth, 0);
- KnownOne2 = APInt(BitWidth, 0);
+ Known2 = KnownBits(BitWidth);
// Recurse, but cap the recursion to one level, because we don't
// want to waste time spinning around in loops.
- computeKnownBits(IncValue, KnownZero2, KnownOne2, MaxDepth - 1, Q);
- KnownZero &= KnownZero2;
- KnownOne &= KnownOne2;
+ computeKnownBits(IncValue, Known2, MaxDepth - 1, Q);
+ Known.Zero &= Known2.Zero;
+ Known.One &= Known2.One;
// If all bits have been ruled out, there's no need to check
// more operands.
- if (!KnownZero && !KnownOne)
+ if (!Known.Zero && !Known.One)
break;
}
}
@@ -1397,24 +1384,24 @@ static void computeKnownBitsFromOperator(const Operator *I, APInt &KnownZero,
// and then intersect with known bits based on other properties of the
// function.
if (MDNode *MD = cast<Instruction>(I)->getMetadata(LLVMContext::MD_range))
- computeKnownBitsFromRangeMetadata(*MD, KnownZero, KnownOne);
+ computeKnownBitsFromRangeMetadata(*MD, Known.Zero, Known.One);
if (const Value *RV = ImmutableCallSite(I).getReturnedArgOperand()) {
- computeKnownBits(RV, KnownZero2, KnownOne2, Depth + 1, Q);
- KnownZero |= KnownZero2;
- KnownOne |= KnownOne2;
+ computeKnownBits(RV, Known2, Depth + 1, Q);
+ Known.Zero |= Known2.Zero;
+ Known.One |= Known2.One;
}
if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(I)) {
switch (II->getIntrinsicID()) {
default: break;
case Intrinsic::bitreverse:
- computeKnownBits(I->getOperand(0), KnownZero2, KnownOne2, Depth + 1, Q);
- KnownZero |= KnownZero2.reverseBits();
- KnownOne |= KnownOne2.reverseBits();
+ computeKnownBits(I->getOperand(0), Known2, Depth + 1, Q);
+ Known.Zero |= Known2.Zero.reverseBits();
+ Known.One |= Known2.One.reverseBits();
break;
case Intrinsic::bswap:
- computeKnownBits(I->getOperand(0), KnownZero2, KnownOne2, Depth + 1, Q);
- KnownZero |= KnownZero2.byteSwap();
- KnownOne |= KnownOne2.byteSwap();
+ computeKnownBits(I->getOperand(0), Known2, Depth + 1, Q);
+ Known.Zero |= Known2.Zero.byteSwap();
+ Known.One |= Known2.One.byteSwap();
break;
case Intrinsic::ctlz:
case Intrinsic::cttz: {
@@ -1422,22 +1409,22 @@ static void computeKnownBitsFromOperator(const Operator *I, APInt &KnownZero,
// If this call is undefined for 0, the result will be less than 2^n.
if (II->getArgOperand(1) == ConstantInt::getTrue(II->getContext()))
LowBits -= 1;
- KnownZero.setBitsFrom(LowBits);
+ Known.Zero.setBitsFrom(LowBits);
break;
}
case Intrinsic::ctpop: {
- computeKnownBits(I->getOperand(0), KnownZero2, KnownOne2, Depth + 1, Q);
+ computeKnownBits(I->getOperand(0), Known2, Depth + 1, Q);
// We can bound the space the count needs. Also, bits known to be zero
// can't contribute to the population.
- unsigned BitsPossiblySet = BitWidth - KnownZero2.countPopulation();
+ unsigned BitsPossiblySet = BitWidth - Known2.Zero.countPopulation();
unsigned LowBits = Log2_32(BitsPossiblySet)+1;
- KnownZero.setBitsFrom(LowBits);
+ Known.Zero.setBitsFrom(LowBits);
// TODO: we could bound KnownOne using the lower bound on the number
// of bits which might be set provided by popcnt KnownOne2.
break;
}
case Intrinsic::x86_sse42_crc32_64_64:
- KnownZero.setBitsFrom(32);
+ Known.Zero.setBitsFrom(32);
break;
}
}
@@ -1447,7 +1434,7 @@ static void computeKnownBitsFromOperator(const Operator *I, APInt &KnownZero,
// tracking the specific element. But at least we might find information
// valid for all elements of the vector (for example if vector is sign
// extended, shifted, etc).
- computeKnownBits(I->getOperand(0), KnownZero, KnownOne, Depth + 1, Q);
+ computeKnownBits(I->getOperand(0), Known, Depth + 1, Q);
break;
case Instruction::ExtractValue:
if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(I->getOperand(0))) {
@@ -1459,20 +1446,19 @@ static void computeKnownBitsFromOperator(const Operator *I, APInt &KnownZero,
case Intrinsic::uadd_with_overflow:
case Intrinsic::sadd_with_overflow:
computeKnownBitsAddSub(true, II->getArgOperand(0),
- II->getArgOperand(1), false, KnownZero,
- KnownOne, KnownZero2, KnownOne2, Depth, Q);
+ II->getArgOperand(1), false, Known, Known2,
+ Depth, Q);
break;
case Intrinsic::usub_with_overflow:
case Intrinsic::ssub_with_overflow:
computeKnownBitsAddSub(false, II->getArgOperand(0),
- II->getArgOperand(1), false, KnownZero,
- KnownOne, KnownZero2, KnownOne2, Depth, Q);
+ II->getArgOperand(1), false, Known, Known2,
+ Depth, Q);
break;
case Intrinsic::umul_with_overflow:
case Intrinsic::smul_with_overflow:
computeKnownBitsMul(II->getArgOperand(0), II->getArgOperand(1), false,
- KnownZero, KnownOne, KnownZero2, KnownOne2, Depth,
- Q);
+ Known, Known2, Depth, Q);
break;
}
}
@@ -1481,7 +1467,7 @@ static void computeKnownBitsFromOperator(const Operator *I, APInt &KnownZero,
}
/// Determine which bits of V are known to be either zero or one and return
-/// them in the KnownZero/KnownOne bit sets.
+/// them in the Known bit set.
///
/// NOTE: we cannot consider 'undef' to be "IsZero" here. The problem is that
/// we cannot optimize based on the assumption that it is zero without changing
@@ -1495,11 +1481,11 @@ static void computeKnownBitsFromOperator(const Operator *I, APInt &KnownZero,
/// where V is a vector, known zero, and known one values are the
/// same width as the vector element, and the bit is set only if it is true
/// for all of the elements in the vector.
-void computeKnownBits(const Value *V, APInt &KnownZero, APInt &KnownOne,
- unsigned Depth, const Query &Q) {
+void computeKnownBits(const Value *V, KnownBits &Known, unsigned Depth,
+ const Query &Q) {
assert(V && "No Value?");
assert(Depth <= MaxDepth && "Limit Search Depth");
- unsigned BitWidth = KnownZero.getBitWidth();
+ unsigned BitWidth = Known.getBitWidth();
assert((V->getType()->isIntOrIntVectorTy() ||
V->getType()->getScalarType()->isPointerTy()) &&
@@ -1507,22 +1493,20 @@ void computeKnownBits(const Value *V, APInt &KnownZero, APInt &KnownOne,
assert((Q.DL.getTypeSizeInBits(V->getType()->getScalarType()) == BitWidth) &&
(!V->getType()->isIntOrIntVectorTy() ||
V->getType()->getScalarSizeInBits() == BitWidth) &&
- KnownZero.getBitWidth() == BitWidth &&
- KnownOne.getBitWidth() == BitWidth &&
- "V, KnownOne and KnownZero should have same BitWidth");
+ "V and Known should have same BitWidth");
(void)BitWidth;
const APInt *C;
if (match(V, m_APInt(C))) {
// We know all of the bits for a scalar constant or a splat vector constant!
- KnownOne = *C;
- KnownZero = ~KnownOne;
+ Known.One = *C;
+ Known.Zero = ~Known.One;
return;
}
// Null and aggregate-zero are all-zeros.
if (isa<ConstantPointerNull>(V) || isa<ConstantAggregateZero>(V)) {
- KnownOne.clearAllBits();
- KnownZero.setAllBits();
+ Known.One.clearAllBits();
+ Known.Zero.setAllBits();
return;
}
// Handle a constant vector by taking the intersection of the known bits of
@@ -1530,12 +1514,12 @@ void computeKnownBits(const Value *V, APInt &KnownZero, APInt &KnownOne,
if (const ConstantDataSequential *CDS = dyn_cast<ConstantDataSequential>(V)) {
// We know that CDS must be a vector of integers. Take the intersection of
// each element.
- KnownZero.setAllBits(); KnownOne.setAllBits();
- APInt Elt(KnownZero.getBitWidth(), 0);
+ Known.Zero.setAllBits(); Known.One.setAllBits();
+ APInt Elt(BitWidth, 0);
for (unsigned i = 0, e = CDS->getNumElements(); i != e; ++i) {
Elt = CDS->getElementAsInteger(i);
- KnownZero &= ~Elt;
- KnownOne &= Elt;
+ Known.Zero &= ~Elt;
+ Known.One &= Elt;
}
return;
}
@@ -1543,25 +1527,25 @@ void computeKnownBits(const Value *V, APInt &KnownZero, APInt &KnownOne,
if (const auto *CV = dyn_cast<ConstantVector>(V)) {
// We know that CV must be a vector of integers. Take the intersection of
// each element.
- KnownZero.setAllBits(); KnownOne.setAllBits();
- APInt Elt(KnownZero.getBitWidth(), 0);
+ Known.Zero.setAllBits(); Known.One.setAllBits();
+ APInt Elt(BitWidth, 0);
for (unsigned i = 0, e = CV->getNumOperands(); i != e; ++i) {
Constant *Element = CV->getAggregateElement(i);
auto *ElementCI = dyn_cast_or_null<ConstantInt>(Element);
if (!ElementCI) {
- KnownZero.clearAllBits();
- KnownOne.clearAllBits();
+ Known.Zero.clearAllBits();
+ Known.One.clearAllBits();
return;
}
Elt = ElementCI->getValue();
- KnownZero &= ~Elt;
- KnownOne &= Elt;
+ Known.Zero &= ~Elt;
+ Known.One &= Elt;
}
return;
}
// Start out not knowing anything.
- KnownZero.clearAllBits(); KnownOne.clearAllBits();
+ Known.Zero.clearAllBits(); Known.One.clearAllBits();
// We can't imply anything about undefs.
if (isa<UndefValue>(V))
@@ -1580,27 +1564,27 @@ void computeKnownBits(const Value *V, APInt &KnownZero, APInt &KnownOne,
// the bits of its aliasee.
if (const GlobalAlias *GA = dyn_cast<GlobalAlias>(V)) {
if (!GA->isInterposable())
- computeKnownBits(GA->getAliasee(), KnownZero, KnownOne, Depth + 1, Q);
+ computeKnownBits(GA->getAliasee(), Known, Depth + 1, Q);
return;
}
if (const Operator *I = dyn_cast<Operator>(V))
- computeKnownBitsFromOperator(I, KnownZero, KnownOne, Depth, Q);
+ computeKnownBitsFromOperator(I, Known, Depth, Q);
- // Aligned pointers have trailing zeros - refine KnownZero set
+ // Aligned pointers have trailing zeros - refine Known.Zero set
if (V->getType()->isPointerTy()) {
unsigned Align = V->getPointerAlignment(Q.DL);
if (Align)
- KnownZero.setLowBits(countTrailingZeros(Align));
+ Known.Zero.setLowBits(countTrailingZeros(Align));
}
- // computeKnownBitsFromAssume strictly refines KnownZero and
- // KnownOne. Therefore, we run them after computeKnownBitsFromOperator.
+ // computeKnownBitsFromAssume strictly refines Known.
+ // Therefore, we run them after computeKnownBitsFromOperator.
// Check whether a nearby assume intrinsic can determine some known bits.
- computeKnownBitsFromAssume(V, KnownZero, KnownOne, Depth, Q);
+ computeKnownBitsFromAssume(V, Known, Depth, Q);
- assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
+ assert((Known.Zero & Known.One) == 0 && "Bits known to be one AND zero?");
}
/// Determine whether the sign bit is known to be zero or one.
@@ -1613,11 +1597,10 @@ void ComputeSignBit(const Value *V, bool &KnownZero, bool &KnownOne,
KnownOne = false;
return;
}
- APInt ZeroBits(BitWidth, 0);
- APInt OneBits(BitWidth, 0);
- computeKnownBits(V, ZeroBits, OneBits, Depth, Q);
- KnownOne = OneBits.isSignBitSet();
- KnownZero = ZeroBits.isSignBitSet();
+ KnownBits Bits(BitWidth);
+ computeKnownBits(V, Bits, Depth, Q);
+ KnownOne = Bits.One.isSignBitSet();
+ KnownZero = Bits.Zero.isSignBitSet();
}
/// Return true if the given value is known to have exactly one
@@ -1689,18 +1672,18 @@ bool isKnownToBeAPowerOfTwo(const Value *V, bool OrZero, unsigned Depth,
return true;
unsigned BitWidth = V->getType()->getScalarSizeInBits();
- APInt LHSZeroBits(BitWidth, 0), LHSOneBits(BitWidth, 0);
- computeKnownBits(X, LHSZeroBits, LHSOneBits, Depth, Q);
+ KnownBits LHSBits(BitWidth);
+ computeKnownBits(X, LHSBits, Depth, Q);
- APInt RHSZeroBits(BitWidth, 0), RHSOneBits(BitWidth, 0);
- computeKnownBits(Y, RHSZeroBits, RHSOneBits, Depth, Q);
+ KnownBits RHSBits(BitWidth);
+ computeKnownBits(Y, RHSBits, Depth, Q);
// If i8 V is a power of two or zero:
// ZeroBits: 1 1 1 0 1 1 1 1
// ~ZeroBits: 0 0 0 1 0 0 0 0
- if ((~(LHSZeroBits & RHSZeroBits)).isPowerOf2())
+ if ((~(LHSBits.Zero & RHSBits.Zero)).isPowerOf2())
// If OrZero isn't set, we cannot give back a zero result.
// Make sure either the LHS or RHS has a bit set.
- if (OrZero || RHSOneBits.getBoolValue() || LHSOneBits.getBoolValue())
+ if (OrZero || RHSBits.One.getBoolValue() || LHSBits.One.getBoolValue())
return true;
}
}
@@ -1871,10 +1854,9 @@ bool isKnownNonZero(const Value *V, unsigned Depth, const Query &Q) {
if (BO->hasNoUnsignedWrap())
return isKnownNonZero(X, Depth, Q);
- APInt KnownZero(BitWidth, 0);
- APInt KnownOne(BitWidth, 0);
- computeKnownBits(X, KnownZero, KnownOne, Depth, Q);
- if (KnownOne[0])
+ KnownBits Known(BitWidth);
+ computeKnownBits(X, Known, Depth, Q);
+ if (Known.One[0])
return true;
}
// shr X, Y != 0 if X is negative. Note that the value of the shift is not
@@ -1894,16 +1876,15 @@ bool isKnownNonZero(const Value *V, unsigned Depth, const Query &Q) {
// out are known to be zero, and X is known non-zero then at least one
// non-zero bit must remain.
if (ConstantInt *Shift = dyn_cast<ConstantInt>(Y)) {
- APInt KnownZero(BitWidth, 0);
- APInt KnownOne(BitWidth, 0);
- computeKnownBits(X, KnownZero, KnownOne, Depth, Q);
+ KnownBits Known(BitWidth);
+ computeKnownBits(X, Known, Depth, Q);
auto ShiftVal = Shift->getLimitedValue(BitWidth - 1);
// Is there a known one in the portion not shifted out?
- if (KnownOne.countLeadingZeros() < BitWidth - ShiftVal)
+ if (Known.One.countLeadingZeros() < BitWidth - ShiftVal)
return true;
// Are all the bits to be shifted out known zero?
- if (KnownZero.countTrailingOnes() >= ShiftVal)
+ if (Known.Zero.countTrailingOnes() >= ShiftVal)
return isKnownNonZero(X, Depth, Q);
}
}
@@ -1927,18 +1908,17 @@ bool isKnownNonZero(const Value *V, unsigned Depth, const Query &Q) {
// If X and Y are both negative (as signed values) then their sum is not
// zero unless both X and Y equal INT_MIN.
if (BitWidth && XKnownNegative && YKnownNegative) {
- APInt KnownZero(BitWidth, 0);
- APInt KnownOne(BitWidth, 0);
+ KnownBits Known(BitWidth);
APInt Mask = APInt::getSignedMaxValue(BitWidth);
// The sign bit of X is set. If some other bit is set then X is not equal
// to INT_MIN.
- computeKnownBits(X, KnownZero, KnownOne, Depth, Q);
- if ((KnownOne & Mask) != 0)
+ computeKnownBits(X, Known, Depth, Q);
+ if (Known.One.intersects(Mask))
return true;
// The sign bit of Y is set. If some other bit is set then Y is not equal
// to INT_MIN.
- computeKnownBits(Y, KnownZero, KnownOne, Depth, Q);
- if ((KnownOne & Mask) != 0)
+ computeKnownBits(Y, Known, Depth, Q);
+ if (Known.One.intersects(Mask))
return true;
}
@@ -1993,10 +1973,9 @@ bool isKnownNonZero(const Value *V, unsigned Depth, const Query &Q) {
}
if (!BitWidth) return false;
- APInt KnownZero(BitWidth, 0);
- APInt KnownOne(BitWidth, 0);
- computeKnownBits(V, KnownZero, KnownOne, Depth, Q);
- return KnownOne != 0;
+ KnownBits Known(BitWidth);
+ computeKnownBits(V, Known, Depth, Q);
+ return Known.One != 0;
}
/// Return true if V2 == V1 + X, where X is known non-zero.
@@ -2028,14 +2007,13 @@ static bool isKnownNonEqual(const Value *V1, const Value *V2, const Query &Q) {
// Are any known bits in V1 contradictory to known bits in V2? If V1
// has a known zero where V2 has a known one, they must not be equal.
auto BitWidth = Ty->getBitWidth();
- APInt KnownZero1(BitWidth, 0);
- APInt KnownOne1(BitWidth, 0);
- computeKnownBits(V1, KnownZero1, KnownOne1, 0, Q);
- APInt KnownZero2(BitWidth, 0);
- APInt KnownOne2(BitWidth, 0);
- computeKnownBits(V2, KnownZero2, KnownOne2, 0, Q);
-
- auto OppositeBits = (KnownZero1 & KnownOne2) | (KnownZero2 & KnownOne1);
+ KnownBits Known1(BitWidth);
+ computeKnownBits(V1, Known1, 0, Q);
+ KnownBits Known2(BitWidth);
+ computeKnownBits(V2, Known2, 0, Q);
+
+ APInt OppositeBits = (Known1.Zero & Known2.One) |
+ (Known2.Zero & Known1.One);
if (OppositeBits.getBoolValue())
return true;
}
@@ -2053,9 +2031,9 @@ static bool isKnownNonEqual(const Value *V1, const Value *V2, const Query &Q) {
/// for all of the elements in the vector.
bool MaskedValueIsZero(const Value *V, const APInt &Mask, unsigned Depth,
const Query &Q) {
- APInt KnownZero(Mask.getBitWidth(), 0), KnownOne(Mask.getBitWidth(), 0);
- computeKnownBits(V, KnownZero, KnownOne, Depth, Q);
- return (KnownZero & Mask) == Mask;
+ KnownBits Known(Mask.getBitWidth());
+ computeKnownBits(V, Known, Depth, Q);
+ return Mask.isSubsetOf(Known.Zero);
}
/// For vector constants, loop over the elements and find the constant with the
@@ -2233,17 +2211,17 @@ static unsigned ComputeNumSignBitsImpl(const Value *V, unsigned Depth,
// Special case decrementing a value (ADD X, -1):
if (const auto *CRHS = dyn_cast<Constant>(U->getOperand(1)))
if (CRHS->isAllOnesValue()) {
- APInt KnownZero(TyBits, 0), KnownOne(TyBits, 0);
- computeKnownBits(U->getOperand(0), KnownZero, KnownOne, Depth + 1, Q);
+ KnownBits Known(TyBits);
+ computeKnownBits(U->getOperand(0), Known, Depth + 1, Q);
// If the input is known to be 0 or 1, the output is 0/-1, which is all
// sign bits set.
- if ((KnownZero | APInt(TyBits, 1)).isAllOnesValue())
+ if ((Known.Zero | 1).isAllOnesValue())
return TyBits;
// If we are subtracting one from a positive number, there is no carry
// out of the result.
- if (KnownZero.isSignBitSet())
+ if (Known.Zero.isSignBitSet())
return Tmp;
}
@@ -2258,16 +2236,16 @@ static unsigned ComputeNumSignBitsImpl(const Value *V, unsigned Depth,
// Handle NEG.
if (const auto *CLHS = dyn_cast<Constant>(U->getOperand(0)))
if (CLHS->isNullValue()) {
- APInt KnownZero(TyBits, 0), KnownOne(TyBits, 0);
- computeKnownBits(U->getOperand(1), KnownZero, KnownOne, Depth + 1, Q);
+ KnownBits Known(TyBits);
+ computeKnownBits(U->getOperand(1), Known, Depth + 1, Q);
// If the input is known to be 0 or 1, the output is 0/-1, which is all
// sign bits set.
- if ((KnownZero | APInt(TyBits, 1)).isAllOnesValue())
+ if ((Known.Zero | 1).isAllOnesValue())
return TyBits;
// If the input is known to be positive (the sign bit is known clear),
// the output of the NEG has the same number of sign bits as the input.
- if (KnownZero.isSignBitSet())
+ if (Known.Zero.isSignBitSet())
return Tmp2;
// Otherwise, we treat this like a SUB.
@@ -2319,16 +2297,16 @@ static unsigned ComputeNumSignBitsImpl(const Value *V, unsigned Depth,
if (unsigned VecSignBits = computeNumSignBitsVectorConstant(V, TyBits))
return VecSignBits;
- APInt KnownZero(TyBits, 0), KnownOne(TyBits, 0);
- computeKnownBits(V, KnownZero, KnownOne, Depth, Q);
+ KnownBits Known(TyBits);
+ computeKnownBits(V, Known, Depth, Q);
// If we know that the sign bit is either zero or one, determine the number of
// identical bits in the top of the input value.
- if (KnownZero.isSignBitSet())
- return std::max(FirstAnswer, KnownZero.countLeadingOnes());
+ if (Known.Zero.isSignBitSet())
+ return std::max(FirstAnswer, Known.Zero.countLeadingOnes());
- if (KnownOne.isSignBitSet())
- return std::max(FirstAnswer, KnownOne.countLeadingOnes());
+ if (Known.One.isSignBitSet())
+ return std::max(FirstAnswer, Known.One.countLeadingOnes());
// computeKnownBits gave us no extra information about the top bits.
return FirstAnswer;
@@ -3534,26 +3512,22 @@ OverflowResult llvm::computeOverflowForUnsignedMul(const Value *LHS,
// we can guarantee that the result does not overflow.
// Ref: "Hacker's Delight" by Henry Warren
unsigned BitWidth = LHS->getType()->getScalarSizeInBits();
- APInt LHSKnownZero(BitWidth, 0);
- APInt LHSKnownOne(BitWidth, 0);
- APInt RHSKnownZero(BitWidth, 0);
- APInt RHSKnownOne(BitWidth, 0);
- computeKnownBits(LHS, LHSKnownZero, LHSKnownOne, DL, /*Depth=*/0, AC, CxtI,
- DT);
- computeKnownBits(RHS, RHSKnownZero, RHSKnownOne, DL, /*Depth=*/0, AC, CxtI,
- DT);
+ KnownBits LHSKnown(BitWidth);
+ KnownBits RHSKnown(BitWidth);
+ computeKnownBits(LHS, LHSKnown, DL, /*Depth=*/0, AC, CxtI, DT);
+ computeKnownBits(RHS, RHSKnown, DL, /*Depth=*/0, AC, CxtI, DT);
// Note that underestimating the number of zero bits gives a more
// conservative answer.
- unsigned ZeroBits = LHSKnownZero.countLeadingOnes() +
- RHSKnownZero.countLeadingOnes();
+ unsigned ZeroBits = LHSKnown.Zero.countLeadingOnes() +
+ RHSKnown.Zero.countLeadingOnes();
// First handle the easy case: if we have enough zero bits there's
// definitely no overflow.
if (ZeroBits >= BitWidth)
return OverflowResult::NeverOverflows;
// Get the largest possible values for each operand.
- APInt LHSMax = ~LHSKnownZero;
- APInt RHSMax = ~RHSKnownZero;
+ APInt LHSMax = ~LHSKnown.Zero;
+ APInt RHSMax = ~RHSKnown.Zero;
// We know the multiply operation doesn't overflow if the maximum values for
// each operand will not overflow after we multiply them together.
@@ -3565,7 +3539,7 @@ OverflowResult llvm::computeOverflowForUnsignedMul(const Value *LHS,
// We know it always overflows if multiplying the smallest possible values for
// the operands also results in overflow.
bool MinOverflow;
- (void)LHSKnownOne.umul_ov(RHSKnownOne, MinOverflow);
+ (void)LHSKnown.One.umul_ov(RHSKnown.One, MinOverflow);
if (MinOverflow)
return OverflowResult::AlwaysOverflows;
@@ -4284,11 +4258,10 @@ static bool isTruePredicate(CmpInst::Predicate Pred,
// If X & C == 0 then (X | C) == X +_{nuw} C
if (match(A, m_Or(m_Value(X), m_APInt(CA))) &&
match(B, m_Or(m_Specific(X), m_APInt(CB)))) {
- unsigned BitWidth = CA->getBitWidth();
- APInt KnownZero(BitWidth, 0), KnownOne(BitWidth, 0);
- computeKnownBits(X, KnownZero, KnownOne, DL, Depth + 1, AC, CxtI, DT);
+ KnownBits Known(CA->getBitWidth());
+ computeKnownBits(X, Known, DL, Depth + 1, AC, CxtI, DT);
- if ((KnownZero & *CA) == *CA && (KnownZero & *CB) == *CB)
+ if (CA->isSubsetOf(Known.Zero) && CB->isSubsetOf(Known.Zero))
return true;
}
diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp
index 1d3cde2f5ddb..e5aba03c8dc1 100644
--- a/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ b/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -726,54 +726,50 @@ static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind) {
}
void ModuleBitcodeWriter::writeAttributeGroupTable() {
- const std::vector<AttributeList> &AttrGrps = VE.getAttributeGroups();
+ const std::vector<ValueEnumerator::IndexAndAttrSet> &AttrGrps =
+ VE.getAttributeGroups();
if (AttrGrps.empty()) return;
Stream.EnterSubblock(bitc::PARAMATTR_GROUP_BLOCK_ID, 3);
SmallVector<uint64_t, 64> Record;
- for (unsigned i = 0, e = AttrGrps.size(); i != e; ++i) {
- AttributeList AS = AttrGrps[i];
- for (unsigned i = 0, e = AS.getNumSlots(); i != e; ++i) {
- AttributeList A = AS.getSlotAttributes(i);
-
- Record.push_back(VE.getAttributeGroupID(A));
- Record.push_back(AS.getSlotIndex(i));
-
- for (AttributeList::iterator I = AS.begin(0), E = AS.end(0); I != E;
- ++I) {
- Attribute Attr = *I;
- if (Attr.isEnumAttribute()) {
- Record.push_back(0);
- Record.push_back(getAttrKindEncoding(Attr.getKindAsEnum()));
- } else if (Attr.isIntAttribute()) {
- Record.push_back(1);
- Record.push_back(getAttrKindEncoding(Attr.getKindAsEnum()));
- Record.push_back(Attr.getValueAsInt());
- } else {
- StringRef Kind = Attr.getKindAsString();
- StringRef Val = Attr.getValueAsString();
-
- Record.push_back(Val.empty() ? 3 : 4);
- Record.append(Kind.begin(), Kind.end());
+ for (ValueEnumerator::IndexAndAttrSet Pair : AttrGrps) {
+ unsigned AttrListIndex = Pair.first;
+ AttributeSet AS = Pair.second;
+ Record.push_back(VE.getAttributeGroupID(Pair));
+ Record.push_back(AttrListIndex);
+
+ for (Attribute Attr : AS) {
+ if (Attr.isEnumAttribute()) {
+ Record.push_back(0);
+ Record.push_back(getAttrKindEncoding(Attr.getKindAsEnum()));
+ } else if (Attr.isIntAttribute()) {
+ Record.push_back(1);
+ Record.push_back(getAttrKindEncoding(Attr.getKindAsEnum()));
+ Record.push_back(Attr.getValueAsInt());
+ } else {
+ StringRef Kind = Attr.getKindAsString();
+ StringRef Val = Attr.getValueAsString();
+
+ Record.push_back(Val.empty() ? 3 : 4);
+ Record.append(Kind.begin(), Kind.end());
+ Record.push_back(0);
+ if (!Val.empty()) {
+ Record.append(Val.begin(), Val.end());
Record.push_back(0);
- if (!Val.empty()) {
- Record.append(Val.begin(), Val.end());
- Record.push_back(0);
- }
}
}
-
- Stream.EmitRecord(bitc::PARAMATTR_GRP_CODE_ENTRY, Record);
- Record.clear();
}
+
+ Stream.EmitRecord(bitc::PARAMATTR_GRP_CODE_ENTRY, Record);
+ Record.clear();
}
Stream.ExitBlock();
}
void ModuleBitcodeWriter::writeAttributeTable() {
- const std::vector<AttributeList> &Attrs = VE.getAttributes();
+ const std::vector<AttributeList> &Attrs = VE.getAttributeLists();
if (Attrs.empty()) return;
Stream.EnterSubblock(bitc::PARAMATTR_BLOCK_ID, 3);
@@ -782,7 +778,8 @@ void ModuleBitcodeWriter::writeAttributeTable() {
for (unsigned i = 0, e = Attrs.size(); i != e; ++i) {
const AttributeList &A = Attrs[i];
for (unsigned i = 0, e = A.getNumSlots(); i != e; ++i)
- Record.push_back(VE.getAttributeGroupID(A.getSlotAttributes(i)));
+ Record.push_back(
+ VE.getAttributeGroupID({A.getSlotIndex(i), A.getSlotAttributes(i)}));
Stream.EmitRecord(bitc::PARAMATTR_CODE_ENTRY, Record);
Record.clear();
@@ -1270,7 +1267,7 @@ void ModuleBitcodeWriter::writeModuleInfo() {
Vals.push_back(F.getCallingConv());
Vals.push_back(F.isDeclaration());
Vals.push_back(getEncodedLinkage(F));
- Vals.push_back(VE.getAttributeID(F.getAttributes()));
+ Vals.push_back(VE.getAttributeListID(F.getAttributes()));
Vals.push_back(Log2_32(F.getAlignment())+1);
Vals.push_back(F.hasSection() ? SectionMap[F.getSection()] : 0);
Vals.push_back(getEncodedVisibility(F));
@@ -2616,7 +2613,7 @@ void ModuleBitcodeWriter::writeInstruction(const Instruction &I,
Code = bitc::FUNC_CODE_INST_INVOKE;
- Vals.push_back(VE.getAttributeID(II->getAttributes()));
+ Vals.push_back(VE.getAttributeListID(II->getAttributes()));
Vals.push_back(II->getCallingConv() | 1 << 13);
Vals.push_back(VE.getValueID(II->getNormalDest()));
Vals.push_back(VE.getValueID(II->getUnwindDest()));
@@ -2808,7 +2805,7 @@ void ModuleBitcodeWriter::writeInstruction(const Instruction &I,
Code = bitc::FUNC_CODE_INST_CALL;
- Vals.push_back(VE.getAttributeID(CI.getAttributes()));
+ Vals.push_back(VE.getAttributeListID(CI.getAttributes()));
unsigned Flags = getOptimizationFlags(&I);
Vals.push_back(CI.getCallingConv() << bitc::CALL_CCONV |
diff --git a/lib/Bitcode/Writer/ValueEnumerator.cpp b/lib/Bitcode/Writer/ValueEnumerator.cpp
index 3800d9abd429..861150766986 100644
--- a/lib/Bitcode/Writer/ValueEnumerator.cpp
+++ b/lib/Bitcode/Writer/ValueEnumerator.cpp
@@ -891,19 +891,19 @@ void ValueEnumerator::EnumerateAttributes(AttributeList PAL) {
if (PAL.isEmpty()) return; // null is always 0.
// Do a lookup.
- unsigned &Entry = AttributeMap[PAL];
+ unsigned &Entry = AttributeListMap[PAL];
if (Entry == 0) {
// Never saw this before, add it.
- Attribute.push_back(PAL);
- Entry = Attribute.size();
+ AttributeLists.push_back(PAL);
+ Entry = AttributeLists.size();
}
// Do lookups for all attribute groups.
for (unsigned i = 0, e = PAL.getNumSlots(); i != e; ++i) {
- AttributeList AS = PAL.getSlotAttributes(i);
- unsigned &Entry = AttributeGroupMap[AS];
+ IndexAndAttrSet Pair = {PAL.getSlotIndex(i), PAL.getSlotAttributes(i)};
+ unsigned &Entry = AttributeGroupMap[Pair];
if (Entry == 0) {
- AttributeGroups.push_back(AS);
+ AttributeGroups.push_back(Pair);
Entry = AttributeGroups.size();
}
}
diff --git a/lib/Bitcode/Writer/ValueEnumerator.h b/lib/Bitcode/Writer/ValueEnumerator.h
index 8a82aab29836..e7ccc8df1e5f 100644
--- a/lib/Bitcode/Writer/ValueEnumerator.h
+++ b/lib/Bitcode/Writer/ValueEnumerator.h
@@ -48,6 +48,10 @@ public:
// For each value, we remember its Value* and occurrence frequency.
typedef std::vector<std::pair<const Value*, unsigned> > ValueList;
+ /// Attribute groups as encoded in bitcode are almost AttributeSets, but they
+ /// include the AttributeList index, so we have to track that in our map.
+ typedef std::pair<unsigned, AttributeSet> IndexAndAttrSet;
+
UseListOrderStack UseListOrders;
private:
@@ -102,13 +106,13 @@ private:
bool ShouldPreserveUseListOrder;
- typedef DenseMap<AttributeList, unsigned> AttributeGroupMapType;
+ typedef DenseMap<IndexAndAttrSet, unsigned> AttributeGroupMapType;
AttributeGroupMapType AttributeGroupMap;
- std::vector<AttributeList> AttributeGroups;
+ std::vector<IndexAndAttrSet> AttributeGroups;
- typedef DenseMap<AttributeList, unsigned> AttributeMapType;
- AttributeMapType AttributeMap;
- std::vector<AttributeList> Attribute;
+ typedef DenseMap<AttributeList, unsigned> AttributeListMapType;
+ AttributeListMapType AttributeListMap;
+ std::vector<AttributeList> AttributeLists;
/// GlobalBasicBlockIDs - This map memoizes the basic block ID's referenced by
/// the "getGlobalBasicBlockID" method.
@@ -166,16 +170,17 @@ public:
unsigned getInstructionID(const Instruction *I) const;
void setInstructionID(const Instruction *I);
- unsigned getAttributeID(AttributeList PAL) const {
+ unsigned getAttributeListID(AttributeList PAL) const {
if (PAL.isEmpty()) return 0; // Null maps to zero.
- AttributeMapType::const_iterator I = AttributeMap.find(PAL);
- assert(I != AttributeMap.end() && "Attribute not in ValueEnumerator!");
+ AttributeListMapType::const_iterator I = AttributeListMap.find(PAL);
+ assert(I != AttributeListMap.end() && "Attribute not in ValueEnumerator!");
return I->second;
}
- unsigned getAttributeGroupID(AttributeList PAL) const {
- if (PAL.isEmpty()) return 0; // Null maps to zero.
- AttributeGroupMapType::const_iterator I = AttributeGroupMap.find(PAL);
+ unsigned getAttributeGroupID(IndexAndAttrSet Group) const {
+ if (!Group.second.hasAttributes())
+ return 0; // Null maps to zero.
+ AttributeGroupMapType::const_iterator I = AttributeGroupMap.find(Group);
assert(I != AttributeGroupMap.end() && "Attribute not in ValueEnumerator!");
return I->second;
}
@@ -206,8 +211,8 @@ public:
const std::vector<const BasicBlock*> &getBasicBlocks() const {
return BasicBlocks;
}
- const std::vector<AttributeList> &getAttributes() const { return Attribute; }
- const std::vector<AttributeList> &getAttributeGroups() const {
+ const std::vector<AttributeList> &getAttributeLists() const { return AttributeLists; }
+ const std::vector<IndexAndAttrSet> &getAttributeGroups() const {
return AttributeGroups;
}
diff --git a/lib/CodeGen/AggressiveAntiDepBreaker.cpp b/lib/CodeGen/AggressiveAntiDepBreaker.cpp
index 955524c2a676..3a57772cc7f5 100644
--- a/lib/CodeGen/AggressiveAntiDepBreaker.cpp
+++ b/lib/CodeGen/AggressiveAntiDepBreaker.cpp
@@ -964,10 +964,8 @@ unsigned AggressiveAntiDepBreaker::BreakAntiDependencies(
// sure to update that as well.
const SUnit *SU = MISUnitMap[Q.second.Operand->getParent()];
if (!SU) continue;
- for (DbgValueVector::iterator DVI = DbgValues.begin(),
- DVE = DbgValues.end(); DVI != DVE; ++DVI)
- if (DVI->second == Q.second.Operand->getParent())
- UpdateDbgValue(*DVI->first, AntiDepReg, NewReg);
+ UpdateDbgValues(DbgValues, Q.second.Operand->getParent(),
+ AntiDepReg, NewReg);
}
// We just went back in time and modified history; the
diff --git a/lib/CodeGen/AntiDepBreaker.h b/lib/CodeGen/AntiDepBreaker.h
index 04f7f419f5ea..d14d93100adb 100644
--- a/lib/CodeGen/AntiDepBreaker.h
+++ b/lib/CodeGen/AntiDepBreaker.h
@@ -60,6 +60,25 @@ public:
if (MI.getOperand(0).isReg() && MI.getOperand(0).getReg() == OldReg)
MI.getOperand(0).setReg(NewReg);
}
+
+ /// Update all DBG_VALUE instructions that may be affected by the dependency
+ /// breaker's update of ParentMI to use NewReg.
+ void UpdateDbgValues(const DbgValueVector &DbgValues, MachineInstr *ParentMI,
+ unsigned OldReg, unsigned NewReg) {
+ // The following code is dependent on the order in which the DbgValues are
+ // constructed in ScheduleDAGInstrs::buildSchedGraph.
+ MachineInstr *PrevDbgMI = nullptr;
+ for (const auto &DV : make_range(DbgValues.crbegin(), DbgValues.crend())) {
+ MachineInstr *PrevMI = DV.second;
+ if ((PrevMI == ParentMI) || (PrevMI == PrevDbgMI)) {
+ MachineInstr *DbgMI = DV.first;
+ UpdateDbgValue(*DbgMI, OldReg, NewReg);
+ PrevDbgMI = DbgMI;
+ } else if (PrevDbgMI) {
+ break; // If no match and already found a DBG_VALUE, we're done.
+ }
+ }
+ }
};
}
diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 028c79f3ab6d..d99065b1b67a 100644
--- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -825,41 +825,25 @@ static bool emitDebugValueComment(const MachineInstr *MI, AsmPrinter &AP) {
OS << Name << ":";
}
OS << V->getName();
-
- const DIExpression *Expr = MI->getDebugExpression();
- auto Fragment = Expr->getFragmentInfo();
- if (Fragment)
- OS << " [fragment offset=" << Fragment->OffsetInBits
- << " size=" << Fragment->SizeInBits << "]";
OS << " <- ";
// The second operand is only an offset if it's an immediate.
- bool Deref = false;
bool MemLoc = MI->getOperand(0).isReg() && MI->getOperand(1).isImm();
int64_t Offset = MemLoc ? MI->getOperand(1).getImm() : 0;
- for (unsigned i = 0; i < Expr->getNumElements(); ++i) {
- uint64_t Op = Expr->getElement(i);
- if (Op == dwarf::DW_OP_LLVM_fragment) {
- // There can't be any operands after this in a valid expression
- break;
- } else if (Deref) {
- // We currently don't support extra Offsets or derefs after the first
- // one. Bail out early instead of emitting an incorrect comment.
- OS << " [complex expression]";
- AP.OutStreamer->emitRawComment(OS.str());
- return true;
- } else if (Op == dwarf::DW_OP_deref) {
- Deref = true;
- continue;
- }
-
- uint64_t ExtraOffset = Expr->getElement(i++);
- if (Op == dwarf::DW_OP_plus)
- Offset += ExtraOffset;
- else {
- assert(Op == dwarf::DW_OP_minus);
- Offset -= ExtraOffset;
+ const DIExpression *Expr = MI->getDebugExpression();
+ if (Expr->getNumElements()) {
+ OS << '[';
+ bool NeedSep = false;
+ for (auto Op : Expr->expr_ops()) {
+ if (NeedSep)
+ OS << ", ";
+ else
+ NeedSep = true;
+ OS << dwarf::OperationEncodingString(Op.getOp());
+ for (unsigned I = 0; I < Op.getNumArgs(); ++I)
+ OS << ' ' << Op.getArg(I);
}
+ OS << "] ";
}
// Register or immediate value. Register 0 means undef.
@@ -890,7 +874,7 @@ static bool emitDebugValueComment(const MachineInstr *MI, AsmPrinter &AP) {
const TargetFrameLowering *TFI = AP.MF->getSubtarget().getFrameLowering();
Offset += TFI->getFrameIndexReference(*AP.MF,
MI->getOperand(0).getIndex(), Reg);
- Deref = true;
+ MemLoc = true;
}
if (Reg == 0) {
// Suppress offset, it is not meaningful here.
@@ -899,12 +883,12 @@ static bool emitDebugValueComment(const MachineInstr *MI, AsmPrinter &AP) {
AP.OutStreamer->emitRawComment(OS.str());
return true;
}
- if (MemLoc || Deref)
+ if (MemLoc)
OS << '[';
OS << PrintReg(Reg, AP.MF->getSubtarget().getRegisterInfo());
}
- if (MemLoc || Deref)
+ if (MemLoc)
OS << '+' << Offset << ']';
// NOTE: Want this comment at start of line, don't emit with AddComment.
@@ -936,6 +920,16 @@ void AsmPrinter::emitCFIInstruction(const MachineInstr &MI) {
if (needsCFIMoves() == CFI_M_None)
return;
+ // If there is no "real" instruction following this CFI instruction, skip
+ // emitting it; it would be beyond the end of the function's FDE range.
+ auto *MBB = MI.getParent();
+ auto I = std::next(MI.getIterator());
+ while (I != MBB->end() && I->isTransient())
+ ++I;
+ if (I == MBB->instr_end() &&
+ MBB->getReverseIterator() == MBB->getParent()->rbegin())
+ return;
+
const std::vector<MCCFIInstruction> &Instrs = MF->getFrameInstructions();
unsigned CFIIndex = MI.getOperand(0).getCFIIndex();
const MCCFIInstruction &CFI = Instrs[CFIIndex];
@@ -1046,15 +1040,23 @@ void AsmPrinter::EmitFunctionBody() {
// If the function is empty and the object file uses .subsections_via_symbols,
// then we need to emit *something* to the function body to prevent the
// labels from collapsing together. Just emit a noop.
- if ((MAI->hasSubsectionsViaSymbols() && !HasAnyRealCode)) {
+ // Similarly, don't emit empty functions on Windows either. It can lead to
+ // duplicate entries (two functions with the same RVA) in the Guard CF Table
+ // after linking, causing the kernel not to load the binary:
+ // https://developercommunity.visualstudio.com/content/problem/45366/vc-linker-creates-invalid-dll-with-clang-cl.html
+ // FIXME: Hide this behind some API in e.g. MCAsmInfo or MCTargetStreamer.
+ const Triple &TT = TM.getTargetTriple();
+ if (!HasAnyRealCode && (MAI->hasSubsectionsViaSymbols() ||
+ (TT.isOSWindows() && TT.isOSBinFormatCOFF()))) {
MCInst Noop;
- MF->getSubtarget().getInstrInfo()->getNoopForMachoTarget(Noop);
- OutStreamer->AddComment("avoids zero-length function");
+ MF->getSubtarget().getInstrInfo()->getNoop(Noop);
// Targets can opt-out of emitting the noop here by leaving the opcode
// unspecified.
- if (Noop.getOpcode())
+ if (Noop.getOpcode()) {
+ OutStreamer->AddComment("avoids zero-length function");
OutStreamer->EmitInstruction(Noop, getSubtargetInfo());
+ }
}
const Function *F = MF->getFunction();
diff --git a/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp b/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
index 683e622e3d53..a0bf1632dff3 100644
--- a/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
+++ b/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
@@ -144,6 +144,9 @@ void AsmPrinter::EmitInlineAsm(StringRef Str, const MCSubtargetInfo &STI,
" we don't have an asm parser for this target\n");
Parser->setAssemblerDialect(Dialect);
Parser->setTargetParser(*TAP.get());
+ if (Dialect == InlineAsm::AD_Intel)
+ // We need this flag to be able to parse numbers like "0bH"
+ Parser->setParsingInlineAsm(true);
if (MF) {
const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo();
TAP->SetFrameRegister(TRI->getFrameRegister(*MF));
diff --git a/lib/CodeGen/AsmPrinter/DIE.cpp b/lib/CodeGen/AsmPrinter/DIE.cpp
index 31c2b3b5e752..30bfd7c94e68 100644
--- a/lib/CodeGen/AsmPrinter/DIE.cpp
+++ b/lib/CodeGen/AsmPrinter/DIE.cpp
@@ -655,20 +655,12 @@ void DIEEntry::EmitValue(const AsmPrinter *AP, dwarf::Form Form) const {
case dwarf::DW_FORM_ref_addr: {
// Get the absolute offset for this DIE within the debug info/types section.
unsigned Addr = Entry->getDebugSectionOffset();
- if (AP->MAI->doesDwarfUseRelocationsAcrossSections()) {
- const DwarfDebug *DD = AP->getDwarfDebug();
- if (DD)
- assert(!DD->useSplitDwarf() &&
- "TODO: dwo files can't have relocations.");
- const DIEUnit *Unit = Entry->getUnit();
- assert(Unit && "CUDie should belong to a CU.");
- MCSection *Section = Unit->getSection();
- if (Section) {
- const MCSymbol *SectionSym = Section->getBeginSymbol();
- AP->EmitLabelPlusOffset(SectionSym, Addr, SizeOf(AP, Form), true);
- return;
- }
+ if (const MCSymbol *SectionSym =
+ Entry->getUnit()->getCrossSectionRelativeBaseAddress()) {
+ AP->EmitLabelPlusOffset(SectionSym, Addr, SizeOf(AP, Form), true);
+ return;
}
+
AP->OutStreamer->EmitIntValue(Addr, SizeOf(AP, Form));
return;
}
diff --git a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h
index 9a64b4b76b06..20a415150b4d 100644
--- a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h
+++ b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h
@@ -28,7 +28,7 @@ class DwarfFile;
class MCSymbol;
class LexicalScope;
-class DwarfCompileUnit : public DwarfUnit {
+class DwarfCompileUnit final : public DwarfUnit {
/// A numeric ID unique among all CUs in the module
unsigned UniqueID;
diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index d72656bcc58d..6f442f5c3172 100644
--- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -91,14 +91,6 @@ DwarfAccelTables("dwarf-accel-tables", cl::Hidden,
cl::init(Default));
static cl::opt<DefaultOnOff>
-SplitDwarf("split-dwarf", cl::Hidden,
- cl::desc("Output DWARF5 split debug info."),
- cl::values(clEnumVal(Default, "Default for platform"),
- clEnumVal(Enable, "Enabled"),
- clEnumVal(Disable, "Disabled")),
- cl::init(Default));
-
-static cl::opt<DefaultOnOff>
DwarfPubSections("generate-dwarf-pub-sections", cl::Hidden,
cl::desc("Generate DWARF pubnames and pubtypes sections"),
cl::values(clEnumVal(Default, "Default for platform"),
@@ -253,11 +245,8 @@ DwarfDebug::DwarfDebug(AsmPrinter *A, Module *M)
HasAppleExtensionAttributes = tuneForLLDB();
- // Handle split DWARF. Off by default for now.
- if (SplitDwarf == Default)
- HasSplitDwarf = false;
- else
- HasSplitDwarf = SplitDwarf == Enable;
+ // Handle split DWARF.
+ HasSplitDwarf = !Asm->TM.Options.MCOptions.SplitDwarfFile.empty();
// Pubnames/pubtypes on by default for GDB.
if (DwarfPubSections == Default)
@@ -412,7 +401,7 @@ DwarfDebug::constructDwarfCompileUnit(const DICompileUnit *DIUnit) {
if (useSplitDwarf()) {
NewCU.setSkeleton(constructSkeletonCU(NewCU));
NewCU.addString(Die, dwarf::DW_AT_GNU_dwo_name,
- DIUnit->getSplitDebugFilename());
+ Asm->TM.Options.MCOptions.SplitDwarfFile);
}
// LTO with assembly output shares a single line table amongst multiple CUs.
@@ -1885,7 +1874,7 @@ void DwarfDebug::emitDebugMacinfo() {
void DwarfDebug::initSkeletonUnit(const DwarfUnit &U, DIE &Die,
std::unique_ptr<DwarfCompileUnit> NewU) {
NewU->addString(Die, dwarf::DW_AT_GNU_dwo_name,
- U.getCUNode()->getSplitDebugFilename());
+ Asm->TM.Options.MCOptions.SplitDwarfFile);
if (!CompilationDir.empty())
NewU->addString(Die, dwarf::DW_AT_comp_dir, CompilationDir);
diff --git a/lib/CodeGen/AsmPrinter/DwarfExpression.cpp b/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
index f65dc151f301..ccd326917bfd 100644
--- a/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
@@ -117,8 +117,9 @@ bool DwarfExpression::addMachineReg(const TargetRegisterInfo &TRI,
// Otherwise, attempt to find a covering set of sub-register numbers.
// For example, Q0 on ARM is a composition of D0+D1.
unsigned CurPos = 0;
- // The size of the register in bits, assuming 8 bits per byte.
- unsigned RegSize = TRI.getMinimalPhysRegClass(MachineReg)->getSize() * 8;
+ // The size of the register in bits.
+ const TargetRegisterClass *RC = TRI.getMinimalPhysRegClass(MachineReg);
+ unsigned RegSize = TRI.getRegSizeInBits(*RC);
// Keep track of the bits in the register we already emitted, so we
// can avoid emitting redundant aliasing subregs.
SmallBitVector Coverage(RegSize, false);
@@ -198,8 +199,10 @@ bool DwarfExpression::addMachineRegExpression(const TargetRegisterInfo &TRI,
unsigned MachineReg,
unsigned FragmentOffsetInBits) {
auto Fragment = ExprCursor.getFragmentInfo();
- if (!addMachineReg(TRI, MachineReg, Fragment ? Fragment->SizeInBits : ~1U))
+ if (!addMachineReg(TRI, MachineReg, Fragment ? Fragment->SizeInBits : ~1U)) {
+ LocationKind = Unknown;
return false;
+ }
bool HasComplexExpression = false;
auto Op = ExprCursor.peek();
@@ -212,6 +215,7 @@ bool DwarfExpression::addMachineRegExpression(const TargetRegisterInfo &TRI,
// operation to multiple DW_OP_pieces.
if (HasComplexExpression && DwarfRegs.size() > 1) {
DwarfRegs.clear();
+ LocationKind = Unknown;
return false;
}
@@ -233,6 +237,7 @@ bool DwarfExpression::addMachineRegExpression(const TargetRegisterInfo &TRI,
return Op.getOp() == dwarf::DW_OP_stack_value;
})) {
DwarfRegs.clear();
+ LocationKind = Unknown;
return false;
}
@@ -343,7 +348,6 @@ void DwarfExpression::addExpression(DIExpressionCursor &&ExprCursor,
emitUnsigned(Op->getArg(0));
break;
case dwarf::DW_OP_stack_value:
- assert(LocationKind == Unknown || LocationKind == Implicit);
LocationKind = Implicit;
break;
case dwarf::DW_OP_swap:
diff --git a/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
index bac0c204d04f..16fb20dd7e20 100644
--- a/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
@@ -1595,3 +1595,11 @@ void DwarfTypeUnit::addGlobalType(const DIType *Ty, const DIE &Die,
const DIScope *Context) {
getCU().addGlobalTypeUnitType(Ty, Context);
}
+
+const MCSymbol *DwarfUnit::getCrossSectionRelativeBaseAddress() const {
+ if (!Asm->MAI->doesDwarfUseRelocationsAcrossSections())
+ return nullptr;
+ if (isDwoUnit())
+ return nullptr;
+ return getSection()->getBeginSymbol();
+}
diff --git a/lib/CodeGen/AsmPrinter/DwarfUnit.h b/lib/CodeGen/AsmPrinter/DwarfUnit.h
index d626ef920f95..e84df4650882 100644
--- a/lib/CodeGen/AsmPrinter/DwarfUnit.h
+++ b/lib/CodeGen/AsmPrinter/DwarfUnit.h
@@ -104,8 +104,6 @@ protected:
bool applySubprogramDefinitionAttributes(const DISubprogram *SP, DIE &SPDie);
public:
- virtual ~DwarfUnit();
-
// Accessors.
AsmPrinter* getAsmPrinter() const { return Asm; }
uint16_t getLanguage() const { return CUNode->getSourceLanguage(); }
@@ -289,6 +287,8 @@ public:
void constructTypeDIE(DIE &Buffer, const DICompositeType *CTy);
protected:
+ ~DwarfUnit();
+
/// Create new static data member DIE.
DIE *getOrCreateStaticMemberDIE(const DIDerivedType *DT);
@@ -335,9 +335,10 @@ private:
void setIndexTyDie(DIE *D) { IndexTyDie = D; }
virtual bool isDwoUnit() const = 0;
+ const MCSymbol *getCrossSectionRelativeBaseAddress() const override;
};
-class DwarfTypeUnit : public DwarfUnit {
+class DwarfTypeUnit final : public DwarfUnit {
uint64_t TypeSignature;
const DIE *Ty;
DwarfCompileUnit &CU;
diff --git a/lib/CodeGen/CriticalAntiDepBreaker.cpp b/lib/CodeGen/CriticalAntiDepBreaker.cpp
index e1eeddf0816c..b2d6652b075e 100644
--- a/lib/CodeGen/CriticalAntiDepBreaker.cpp
+++ b/lib/CodeGen/CriticalAntiDepBreaker.cpp
@@ -648,10 +648,8 @@ BreakAntiDependencies(const std::vector<SUnit>& SUnits,
// as well.
const SUnit *SU = MISUnitMap[Q->second->getParent()];
if (!SU) continue;
- for (DbgValueVector::iterator DVI = DbgValues.begin(),
- DVE = DbgValues.end(); DVI != DVE; ++DVI)
- if (DVI->second == Q->second->getParent())
- UpdateDbgValue(*DVI->first, AntiDepReg, NewReg);
+ UpdateDbgValues(DbgValues, Q->second->getParent(),
+ AntiDepReg, NewReg);
}
// We just went back in time and modified history; the
diff --git a/lib/CodeGen/GlobalISel/InstructionSelect.cpp b/lib/CodeGen/GlobalISel/InstructionSelect.cpp
index 26454c1ef00f..cf97c635e79a 100644
--- a/lib/CodeGen/GlobalISel/InstructionSelect.cpp
+++ b/lib/CodeGen/GlobalISel/InstructionSelect.cpp
@@ -145,6 +145,8 @@ bool InstructionSelect::runOnMachineFunction(MachineFunction &MF) {
}
}
+ const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo();
+
// Now that selection is complete, there are no more generic vregs. Verify
// that the size of the now-constrained vreg is unchanged and that it has a
// register class.
@@ -165,7 +167,7 @@ bool InstructionSelect::runOnMachineFunction(MachineFunction &MF) {
continue;
if (VRegToType.second.isValid() &&
- VRegToType.second.getSizeInBits() > (RC->getSize() * 8)) {
+ VRegToType.second.getSizeInBits() > TRI.getRegSizeInBits(*RC)) {
reportGISelFailure(MF, TPC, MORE, "gisel-select",
"VReg has explicit size different from class size",
*MI);
diff --git a/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
index 58778077bc0e..ef5818dabe23 100644
--- a/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
+++ b/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
@@ -76,6 +76,12 @@ void LegalizerHelper::extractParts(unsigned Reg, LLT Ty, int NumParts,
static RTLIB::Libcall getRTLibDesc(unsigned Opcode, unsigned Size) {
switch (Opcode) {
+ case TargetOpcode::G_SDIV:
+ assert(Size == 32 && "Unsupported size");
+ return RTLIB::SDIV_I32;
+ case TargetOpcode::G_UDIV:
+ assert(Size == 32 && "Unsupported size");
+ return RTLIB::UDIV_I32;
case TargetOpcode::G_FADD:
assert((Size == 32 || Size == 64) && "Unsupported size");
return Size == 64 ? RTLIB::ADD_F64 : RTLIB::ADD_F32;
@@ -87,31 +93,43 @@ static RTLIB::Libcall getRTLibDesc(unsigned Opcode, unsigned Size) {
llvm_unreachable("Unknown libcall function");
}
+static LegalizerHelper::LegalizeResult
+simpleLibcall(MachineInstr &MI, MachineIRBuilder &MIRBuilder, unsigned Size,
+ Type *OpType) {
+ auto &CLI = *MIRBuilder.getMF().getSubtarget().getCallLowering();
+ auto &TLI = *MIRBuilder.getMF().getSubtarget().getTargetLowering();
+ auto Libcall = getRTLibDesc(MI.getOpcode(), Size);
+ const char *Name = TLI.getLibcallName(Libcall);
+ MIRBuilder.getMF().getFrameInfo().setHasCalls(true);
+ CLI.lowerCall(MIRBuilder, TLI.getLibcallCallingConv(Libcall),
+ MachineOperand::CreateES(Name),
+ {MI.getOperand(0).getReg(), OpType},
+ {{MI.getOperand(1).getReg(), OpType},
+ {MI.getOperand(2).getReg(), OpType}});
+ MI.eraseFromParent();
+ return LegalizerHelper::Legalized;
+}
+
LegalizerHelper::LegalizeResult
LegalizerHelper::libcall(MachineInstr &MI) {
LLT Ty = MRI.getType(MI.getOperand(0).getReg());
unsigned Size = Ty.getSizeInBits();
+ auto &Ctx = MIRBuilder.getMF().getFunction()->getContext();
MIRBuilder.setInstr(MI);
switch (MI.getOpcode()) {
default:
return UnableToLegalize;
+ case TargetOpcode::G_SDIV:
+ case TargetOpcode::G_UDIV: {
+ Type *Ty = Type::getInt32Ty(Ctx);
+ return simpleLibcall(MI, MIRBuilder, Size, Ty);
+ }
case TargetOpcode::G_FADD:
case TargetOpcode::G_FPOW:
case TargetOpcode::G_FREM: {
- auto &Ctx = MIRBuilder.getMF().getFunction()->getContext();
Type *Ty = Size == 64 ? Type::getDoubleTy(Ctx) : Type::getFloatTy(Ctx);
- auto &CLI = *MIRBuilder.getMF().getSubtarget().getCallLowering();
- auto &TLI = *MIRBuilder.getMF().getSubtarget().getTargetLowering();
- auto Libcall = getRTLibDesc(MI.getOpcode(), Size);
- const char *Name = TLI.getLibcallName(Libcall);
- MIRBuilder.getMF().getFrameInfo().setHasCalls(true);
- CLI.lowerCall(
- MIRBuilder, TLI.getLibcallCallingConv(Libcall),
- MachineOperand::CreateES(Name), {MI.getOperand(0).getReg(), Ty},
- {{MI.getOperand(1).getReg(), Ty}, {MI.getOperand(2).getReg(), Ty}});
- MI.eraseFromParent();
- return Legalized;
+ return simpleLibcall(MI, MIRBuilder, Size, Ty);
}
}
}
diff --git a/lib/CodeGen/GlobalISel/RegisterBank.cpp b/lib/CodeGen/GlobalISel/RegisterBank.cpp
index 940957d02152..83b21e637097 100644
--- a/lib/CodeGen/GlobalISel/RegisterBank.cpp
+++ b/lib/CodeGen/GlobalISel/RegisterBank.cpp
@@ -48,7 +48,7 @@ bool RegisterBank::verify(const TargetRegisterInfo &TRI) const {
// Verify that the Size of the register bank is big enough to cover
// all the register classes it covers.
- assert((getSize() >= SubRC.getSize() * 8) &&
+ assert(getSize() >= TRI.getRegSizeInBits(SubRC) &&
"Size is not big enough for all the subclasses!");
assert(covers(SubRC) && "Not all subclasses are covered");
}
diff --git a/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp b/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp
index b2df2f159676..d5ae9a6776a4 100644
--- a/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp
+++ b/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp
@@ -421,7 +421,7 @@ unsigned RegisterBankInfo::getSizeInBits(unsigned Reg,
RC = MRI.getRegClass(Reg);
}
assert(RC && "Unable to deduce the register class");
- return RC->getSize() * 8;
+ return TRI.getRegSizeInBits(*RC);
}
//------------------------------------------------------------------------------
diff --git a/lib/CodeGen/MIRPrinter.cpp b/lib/CodeGen/MIRPrinter.cpp
index 6da174a53666..b6624b88fe23 100644
--- a/lib/CodeGen/MIRPrinter.cpp
+++ b/lib/CodeGen/MIRPrinter.cpp
@@ -925,9 +925,6 @@ void MIPrinter::print(const MachineOperand &Op, const TargetRegisterInfo *TRI,
<< CmpInst::getPredicateName(Pred) << ')';
break;
}
- case MachineOperand::MO_Placeholder:
- OS << "<placeholder>";
- break;
}
}
diff --git a/lib/CodeGen/MachineInstr.cpp b/lib/CodeGen/MachineInstr.cpp
index 4bd5fbfe38e6..1faf6292a9c1 100644
--- a/lib/CodeGen/MachineInstr.cpp
+++ b/lib/CodeGen/MachineInstr.cpp
@@ -287,8 +287,6 @@ bool MachineOperand::isIdenticalTo(const MachineOperand &Other) const {
return getIntrinsicID() == Other.getIntrinsicID();
case MachineOperand::MO_Predicate:
return getPredicate() == Other.getPredicate();
- case MachineOperand::MO_Placeholder:
- return true;
}
llvm_unreachable("Invalid machine operand type");
}
@@ -337,8 +335,6 @@ hash_code llvm::hash_value(const MachineOperand &MO) {
return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIntrinsicID());
case MachineOperand::MO_Predicate:
return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getPredicate());
- case MachineOperand::MO_Placeholder:
- return hash_combine();
}
llvm_unreachable("Invalid machine operand type");
}
@@ -515,9 +511,6 @@ void MachineOperand::print(raw_ostream &OS, ModuleSlotTracker &MST,
<< CmpInst::getPredicateName(Pred) << '>';
break;
}
- case MachineOperand::MO_Placeholder:
- OS << "<placeholder>";
- break;
}
if (unsigned TF = getTargetFlags())
OS << "[TF=" << TF << ']';
diff --git a/lib/CodeGen/MachineLICM.cpp b/lib/CodeGen/MachineLICM.cpp
index b3d18435985e..7eb991744f01 100644
--- a/lib/CodeGen/MachineLICM.cpp
+++ b/lib/CodeGen/MachineLICM.cpp
@@ -330,7 +330,7 @@ bool MachineLICM::runOnMachineFunction(MachineFunction &MF) {
/// Return true if instruction stores to the specified frame.
static bool InstructionStoresToFI(const MachineInstr *MI, int FI) {
// If we lost memory operands, conservatively assume that the instruction
- // writes to all slots.
+ // writes to all slots.
if (MI->memoperands_empty())
return true;
for (const MachineMemOperand *MemOp : MI->memoperands()) {
@@ -708,7 +708,7 @@ void MachineLICM::SinkIntoLoop() {
for (MachineBasicBlock::instr_iterator I = Preheader->instr_begin();
I != Preheader->instr_end(); ++I) {
// We need to ensure that we can safely move this instruction into the loop.
- // As such, it must not have side-effects, e.g. such as a call has.
+ // As such, it must not have side-effects, e.g. such as a call has.
if (IsLoopInvariantInst(*I) && !HasLoopPHIUse(&*I))
Candidates.push_back(&*I);
}
@@ -837,9 +837,9 @@ MachineLICM::calcRegisterCost(const MachineInstr *MI, bool ConsiderSeen,
/// constant pool.
static bool mayLoadFromGOTOrConstantPool(MachineInstr &MI) {
assert (MI.mayLoad() && "Expected MI that loads!");
-
+
// If we lost memory operands, conservatively assume that the instruction
- // reads from everything..
+ // reads from everything..
if (MI.memoperands_empty())
return true;
@@ -1337,7 +1337,7 @@ bool MachineLICM::Hoist(MachineInstr *MI, MachineBasicBlock *Preheader) {
Preheader->splice(Preheader->getFirstTerminator(),MI->getParent(),MI);
// Since we are moving the instruction out of its basic block, we do not
- // retain its debug location. Doing so would degrade the debugging
+ // retain its debug location. Doing so would degrade the debugging
// experience and adversely affect the accuracy of profiling information.
MI->setDebugLoc(DebugLoc());
diff --git a/lib/CodeGen/PrologEpilogInserter.cpp b/lib/CodeGen/PrologEpilogInserter.cpp
index 1354009794cb..570a0cd0ba90 100644
--- a/lib/CodeGen/PrologEpilogInserter.cpp
+++ b/lib/CodeGen/PrologEpilogInserter.cpp
@@ -373,22 +373,22 @@ static void assignCalleeSavedSpillSlots(MachineFunction &F,
FixedSlot->Reg != Reg)
++FixedSlot;
+ unsigned Size = RegInfo->getSpillSize(*RC);
if (FixedSlot == FixedSpillSlots + NumFixedSpillSlots) {
// Nope, just spill it anywhere convenient.
- unsigned Align = RC->getAlignment();
+ unsigned Align = RegInfo->getSpillAlignment(*RC);
unsigned StackAlign = TFI->getStackAlignment();
// We may not be able to satisfy the desired alignment specification of
// the TargetRegisterClass if the stack alignment is smaller. Use the
// min.
Align = std::min(Align, StackAlign);
- FrameIdx = MFI.CreateStackObject(RC->getSize(), Align, true);
+ FrameIdx = MFI.CreateStackObject(Size, Align, true);
if ((unsigned)FrameIdx < MinCSFrameIndex) MinCSFrameIndex = FrameIdx;
if ((unsigned)FrameIdx > MaxCSFrameIndex) MaxCSFrameIndex = FrameIdx;
} else {
// Spill it to the stack where we must.
- FrameIdx =
- MFI.CreateFixedSpillStackObject(RC->getSize(), FixedSlot->Offset);
+ FrameIdx = MFI.CreateFixedSpillStackObject(Size, FixedSlot->Offset);
}
CS.setFrameIdx(FrameIdx);
diff --git a/lib/CodeGen/RegAllocFast.cpp b/lib/CodeGen/RegAllocFast.cpp
index 283d84629f8e..c606b7b83310 100644
--- a/lib/CodeGen/RegAllocFast.cpp
+++ b/lib/CodeGen/RegAllocFast.cpp
@@ -212,8 +212,9 @@ int RAFast::getStackSpaceFor(unsigned VirtReg, const TargetRegisterClass *RC) {
return SS; // Already has space allocated?
// Allocate a new stack object for this spill location...
- int FrameIdx = MF->getFrameInfo().CreateSpillStackObject(RC->getSize(),
- RC->getAlignment());
+ unsigned Size = TRI->getSpillSize(*RC);
+ unsigned Align = TRI->getSpillAlignment(*RC);
+ int FrameIdx = MF->getFrameInfo().CreateSpillStackObject(Size, Align);
// Assign the slot.
StackSlotForVirtReg[VirtReg] = FrameIdx;
diff --git a/lib/CodeGen/RegisterScavenging.cpp b/lib/CodeGen/RegisterScavenging.cpp
index 6392136fa290..35db30f89976 100644
--- a/lib/CodeGen/RegisterScavenging.cpp
+++ b/lib/CodeGen/RegisterScavenging.cpp
@@ -395,8 +395,8 @@ unsigned RegScavenger::scavengeRegister(const TargetRegisterClass *RC,
// Find an available scavenging slot with size and alignment matching
// the requirements of the class RC.
const MachineFrameInfo &MFI = MF.getFrameInfo();
- unsigned NeedSize = RC->getSize();
- unsigned NeedAlign = RC->getAlignment();
+ unsigned NeedSize = TRI->getSpillSize(*RC);
+ unsigned NeedAlign = TRI->getSpillAlignment(*RC);
unsigned SI = Scavenged.size(), Diff = std::numeric_limits<unsigned>::max();
int FIB = MFI.getObjectIndexBegin(), FIE = MFI.getObjectIndexEnd();
diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 4702d63cb617..1251ae6262b8 100644
--- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -3878,27 +3878,29 @@ static bool isBSwapHWordElement(SDValue N, MutableArrayRef<SDNode *> Parts) {
if (Opc != ISD::AND && Opc != ISD::SHL && Opc != ISD::SRL)
return false;
+ SDValue N0 = N.getOperand(0);
+ unsigned Opc0 = N0.getOpcode();
+
ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N.getOperand(1));
if (!N1C)
return false;
- unsigned Num;
+ unsigned MaskByteOffset;
switch (N1C->getZExtValue()) {
default:
return false;
- case 0xFF: Num = 0; break;
- case 0xFF00: Num = 1; break;
- case 0xFF0000: Num = 2; break;
- case 0xFF000000: Num = 3; break;
+ case 0xFF: MaskByteOffset = 0; break;
+ case 0xFF00: MaskByteOffset = 1; break;
+ case 0xFF0000: MaskByteOffset = 2; break;
+ case 0xFF000000: MaskByteOffset = 3; break;
}
// Look for (x & 0xff) << 8 as well as ((x << 8) & 0xff00).
- SDValue N0 = N.getOperand(0);
if (Opc == ISD::AND) {
- if (Num == 0 || Num == 2) {
+ if (MaskByteOffset == 0 || MaskByteOffset == 2) {
// (x >> 8) & 0xff
// (x >> 8) & 0xff0000
- if (N0.getOpcode() != ISD::SRL)
+ if (Opc0 != ISD::SRL)
return false;
ConstantSDNode *C = dyn_cast<ConstantSDNode>(N0.getOperand(1));
if (!C || C->getZExtValue() != 8)
@@ -3906,7 +3908,7 @@ static bool isBSwapHWordElement(SDValue N, MutableArrayRef<SDNode *> Parts) {
} else {
// (x << 8) & 0xff00
// (x << 8) & 0xff000000
- if (N0.getOpcode() != ISD::SHL)
+ if (Opc0 != ISD::SHL)
return false;
ConstantSDNode *C = dyn_cast<ConstantSDNode>(N0.getOperand(1));
if (!C || C->getZExtValue() != 8)
@@ -3915,7 +3917,7 @@ static bool isBSwapHWordElement(SDValue N, MutableArrayRef<SDNode *> Parts) {
} else if (Opc == ISD::SHL) {
// (x & 0xff) << 8
// (x & 0xff0000) << 8
- if (Num != 0 && Num != 2)
+ if (MaskByteOffset != 0 && MaskByteOffset != 2)
return false;
ConstantSDNode *C = dyn_cast<ConstantSDNode>(N.getOperand(1));
if (!C || C->getZExtValue() != 8)
@@ -3923,17 +3925,17 @@ static bool isBSwapHWordElement(SDValue N, MutableArrayRef<SDNode *> Parts) {
} else { // Opc == ISD::SRL
// (x & 0xff00) >> 8
// (x & 0xff000000) >> 8
- if (Num != 1 && Num != 3)
+ if (MaskByteOffset != 1 && MaskByteOffset != 3)
return false;
ConstantSDNode *C = dyn_cast<ConstantSDNode>(N.getOperand(1));
if (!C || C->getZExtValue() != 8)
return false;
}
- if (Parts[Num])
+ if (Parts[MaskByteOffset])
return false;
- Parts[Num] = N0.getOperand(0).getNode();
+ Parts[MaskByteOffset] = N0.getOperand(0).getNode();
return true;
}
@@ -4198,20 +4200,22 @@ SDValue DAGCombiner::visitOR(SDNode *N) {
// reassociate or
if (SDValue ROR = ReassociateOps(ISD::OR, SDLoc(N), N0, N1))
return ROR;
+
// Canonicalize (or (and X, c1), c2) -> (and (or X, c2), c1|c2)
// iff (c1 & c2) != 0.
- if (N1C && N0.getOpcode() == ISD::AND && N0.getNode()->hasOneUse() &&
- isa<ConstantSDNode>(N0.getOperand(1))) {
- ConstantSDNode *C1 = cast<ConstantSDNode>(N0.getOperand(1));
- if ((C1->getAPIntValue() & N1C->getAPIntValue()) != 0) {
- if (SDValue COR = DAG.FoldConstantArithmetic(ISD::OR, SDLoc(N1), VT,
- N1C, C1))
- return DAG.getNode(
- ISD::AND, SDLoc(N), VT,
- DAG.getNode(ISD::OR, SDLoc(N0), VT, N0.getOperand(0), N1), COR);
- return SDValue();
+ if (N1C && N0.getOpcode() == ISD::AND && N0.getNode()->hasOneUse()) {
+ if (ConstantSDNode *C1 = dyn_cast<ConstantSDNode>(N0.getOperand(1))) {
+ if (C1->getAPIntValue().intersects(N1C->getAPIntValue())) {
+ if (SDValue COR =
+ DAG.FoldConstantArithmetic(ISD::OR, SDLoc(N1), VT, N1C, C1))
+ return DAG.getNode(
+ ISD::AND, SDLoc(N), VT,
+ DAG.getNode(ISD::OR, SDLoc(N0), VT, N0.getOperand(0), N1), COR);
+ return SDValue();
+ }
}
}
+
// Simplify: (or (op x...), (op y...)) -> (op (or x, y))
if (N0.getOpcode() == N1.getOpcode())
if (SDValue Tmp = SimplifyBinOpWithSameOpcodeHands(N))
@@ -5611,24 +5615,24 @@ SDValue DAGCombiner::visitSRL(SDNode *N) {
// fold (srl (trunc (srl x, c1)), c2) -> 0 or (trunc (srl x, (add c1, c2)))
if (N1C && N0.getOpcode() == ISD::TRUNCATE &&
- N0.getOperand(0).getOpcode() == ISD::SRL &&
- isa<ConstantSDNode>(N0.getOperand(0)->getOperand(1))) {
- uint64_t c1 =
- cast<ConstantSDNode>(N0.getOperand(0)->getOperand(1))->getZExtValue();
- uint64_t c2 = N1C->getZExtValue();
- EVT InnerShiftVT = N0.getOperand(0).getValueType();
- EVT ShiftCountVT = N0.getOperand(0)->getOperand(1).getValueType();
- uint64_t InnerShiftSize = InnerShiftVT.getScalarSizeInBits();
- // This is only valid if the OpSizeInBits + c1 = size of inner shift.
- if (c1 + OpSizeInBits == InnerShiftSize) {
- SDLoc DL(N0);
- if (c1 + c2 >= InnerShiftSize)
- return DAG.getConstant(0, DL, VT);
- return DAG.getNode(ISD::TRUNCATE, DL, VT,
- DAG.getNode(ISD::SRL, DL, InnerShiftVT,
- N0.getOperand(0)->getOperand(0),
- DAG.getConstant(c1 + c2, DL,
- ShiftCountVT)));
+ N0.getOperand(0).getOpcode() == ISD::SRL) {
+ if (auto N001C = isConstOrConstSplat(N0.getOperand(0).getOperand(1))) {
+ uint64_t c1 = N001C->getZExtValue();
+ uint64_t c2 = N1C->getZExtValue();
+ EVT InnerShiftVT = N0.getOperand(0).getValueType();
+ EVT ShiftCountVT = N0.getOperand(0).getOperand(1).getValueType();
+ uint64_t InnerShiftSize = InnerShiftVT.getScalarSizeInBits();
+ // This is only valid if the OpSizeInBits + c1 = size of inner shift.
+ if (c1 + OpSizeInBits == InnerShiftSize) {
+ SDLoc DL(N0);
+ if (c1 + c2 >= InnerShiftSize)
+ return DAG.getConstant(0, DL, VT);
+ return DAG.getNode(ISD::TRUNCATE, DL, VT,
+ DAG.getNode(ISD::SRL, DL, InnerShiftVT,
+ N0.getOperand(0).getOperand(0),
+ DAG.getConstant(c1 + c2, DL,
+ ShiftCountVT)));
+ }
}
}
@@ -11641,7 +11645,7 @@ bool DAGCombiner::SliceUpLoad(SDNode *N) {
// Check if this is a trunc(lshr).
if (User->getOpcode() == ISD::SRL && User->hasOneUse() &&
isa<ConstantSDNode>(User->getOperand(1))) {
- Shift = cast<ConstantSDNode>(User->getOperand(1))->getZExtValue();
+ Shift = User->getConstantOperandVal(1);
User = *User->use_begin();
}
@@ -13120,8 +13124,7 @@ SDValue DAGCombiner::visitINSERT_VECTOR_ELT(SDNode *N) {
// do this only if indices are both constants and Idx1 < Idx0.
if (InVec.getOpcode() == ISD::INSERT_VECTOR_ELT && InVec.hasOneUse()
&& isa<ConstantSDNode>(InVec.getOperand(2))) {
- unsigned OtherElt =
- cast<ConstantSDNode>(InVec.getOperand(2))->getZExtValue();
+ unsigned OtherElt = InVec.getConstantOperandVal(2);
if (Elt < OtherElt) {
// Swap nodes.
SDValue NewOp = DAG.getNode(ISD::INSERT_VECTOR_ELT, DL, VT,
@@ -14065,7 +14068,7 @@ static SDValue combineConcatVectorOfExtracts(SDNode *N, SelectionDAG &DAG) {
if (!isa<ConstantSDNode>(Op.getOperand(1)))
return SDValue();
- int ExtIdx = cast<ConstantSDNode>(Op.getOperand(1))->getZExtValue();
+ int ExtIdx = Op.getConstantOperandVal(1);
// Ensure that we are extracting a subvector from a vector the same
// size as the result.
@@ -15049,7 +15052,7 @@ SDValue DAGCombiner::visitINSERT_SUBVECTOR(SDNode *N) {
if (N0.getOpcode() == ISD::INSERT_SUBVECTOR && N0.hasOneUse() &&
N1.getValueType() == N0.getOperand(1).getValueType() &&
isa<ConstantSDNode>(N0.getOperand(2))) {
- unsigned OtherIdx = cast<ConstantSDNode>(N0.getOperand(2))->getZExtValue();
+ unsigned OtherIdx = N0.getConstantOperandVal(2);
if (InsIdx < OtherIdx) {
// Swap nodes.
SDValue NewOp = DAG.getNode(ISD::INSERT_SUBVECTOR, SDLoc(N), VT,
@@ -16088,6 +16091,19 @@ bool DAGCombiner::isAlias(LSBaseSDNode *Op0, LSBaseSDNode *Op1) const {
if (Op1->isInvariant() && Op0->writeMem())
return false;
+ unsigned NumBytes0 = Op0->getMemoryVT().getSizeInBits() >> 3;
+ unsigned NumBytes1 = Op1->getMemoryVT().getSizeInBits() >> 3;
+
+ // Check for BaseIndexOffset matching.
+ BaseIndexOffset BasePtr0 = BaseIndexOffset::match(Op0->getBasePtr(), DAG);
+ BaseIndexOffset BasePtr1 = BaseIndexOffset::match(Op1->getBasePtr(), DAG);
+ if (BasePtr0.equalBaseIndex(BasePtr1))
+ return !((BasePtr0.Offset + NumBytes0 <= BasePtr1.Offset) ||
+ (BasePtr1.Offset + NumBytes1 <= BasePtr0.Offset));
+
+ // FIXME: findBaseOffset and ConstantValue/GlobalValue/FrameIndex analysis
+ // modified to use BaseIndexOffset.
+
// Gather base node and offset information.
SDValue Base0, Base1;
int64_t Offset0, Offset1;
@@ -16099,8 +16115,6 @@ bool DAGCombiner::isAlias(LSBaseSDNode *Op0, LSBaseSDNode *Op1) const {
Base1, Offset1, GV1, CV1);
// If they have the same base address, then check to see if they overlap.
- unsigned NumBytes0 = Op0->getMemoryVT().getSizeInBits() >> 3;
- unsigned NumBytes1 = Op1->getMemoryVT().getSizeInBits() >> 3;
if (Base0 == Base1 || (GV0 && (GV0 == GV1)) || (CV0 && (CV0 == CV1)))
return !((Offset0 + NumBytes0) <= Offset1 ||
(Offset1 + NumBytes1) <= Offset0);
diff --git a/lib/CodeGen/SelectionDAG/InstrEmitter.cpp b/lib/CodeGen/SelectionDAG/InstrEmitter.cpp
index e85d1951e3ae..b235e19aaab2 100644
--- a/lib/CodeGen/SelectionDAG/InstrEmitter.cpp
+++ b/lib/CodeGen/SelectionDAG/InstrEmitter.cpp
@@ -161,7 +161,8 @@ EmitCopyFromReg(SDNode *Node, unsigned ResNo, bool IsClone, bool IsCloned,
if (VRBase) {
DstRC = MRI->getRegClass(VRBase);
} else if (UseRC) {
- assert(UseRC->hasType(VT) && "Incompatible phys register def and uses!");
+ assert(TRI->isTypeLegalForClass(*UseRC, VT) &&
+ "Incompatible phys register def and uses!");
DstRC = UseRC;
} else {
DstRC = TLI->getRegClassFor(VT);
diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
index 3bae3bf9ab7c..fdebb8bd00db 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
@@ -3497,11 +3497,11 @@ bool SelectionDAGLegalize::ExpandNode(SDNode *Node) {
// part.
unsigned LoSize = VT.getSizeInBits();
SDValue HiLHS =
- DAG.getNode(ISD::SRA, dl, VT, RHS,
+ DAG.getNode(ISD::SRA, dl, VT, LHS,
DAG.getConstant(LoSize - 1, dl,
TLI.getPointerTy(DAG.getDataLayout())));
SDValue HiRHS =
- DAG.getNode(ISD::SRA, dl, VT, LHS,
+ DAG.getNode(ISD::SRA, dl, VT, RHS,
DAG.getConstant(LoSize - 1, dl,
TLI.getPointerTy(DAG.getDataLayout())));
diff --git a/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
index 85068e890756..9ed70c9b4db9 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
@@ -3251,7 +3251,7 @@ SDValue DAGTypeLegalizer::PromoteIntRes_EXTRACT_SUBVECTOR(SDNode *N) {
Ops.push_back(Op);
}
- return DAG.getNode(ISD::BUILD_VECTOR, dl, NOutVT, Ops);
+ return DAG.getBuildVector(NOutVT, dl, Ops);
}
@@ -3294,7 +3294,7 @@ SDValue DAGTypeLegalizer::PromoteIntRes_BUILD_VECTOR(SDNode *N) {
Ops.push_back(Op);
}
- return DAG.getNode(ISD::BUILD_VECTOR, dl, NOutVT, Ops);
+ return DAG.getBuildVector(NOutVT, dl, Ops);
}
SDValue DAGTypeLegalizer::PromoteIntRes_SCALAR_TO_VECTOR(SDNode *N) {
@@ -3342,7 +3342,7 @@ SDValue DAGTypeLegalizer::PromoteIntRes_CONCAT_VECTORS(SDNode *N) {
}
}
- return DAG.getNode(ISD::BUILD_VECTOR, dl, NOutVT, Ops);
+ return DAG.getBuildVector(NOutVT, dl, Ops);
}
SDValue DAGTypeLegalizer::PromoteIntRes_EXTEND_VECTOR_INREG(SDNode *N) {
@@ -3445,5 +3445,5 @@ SDValue DAGTypeLegalizer::PromoteIntOp_CONCAT_VECTORS(SDNode *N) {
}
}
- return DAG.getNode(ISD::BUILD_VECTOR, dl, N->getValueType(0), NewOps);
+ return DAG.getBuildVector(N->getValueType(0), dl, NewOps);
}
diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp b/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp
index c02b8960b36c..aa69e0e2adfc 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp
@@ -362,8 +362,8 @@ SDValue DAGTypeLegalizer::ExpandOp_BITCAST(SDNode *N) {
SmallVector<SDValue, 8> Ops;
IntegerToVector(N->getOperand(0), NumElts, Ops, NVT.getVectorElementType());
- SDValue Vec = DAG.getNode(ISD::BUILD_VECTOR, dl, NVT,
- makeArrayRef(Ops.data(), NumElts));
+ SDValue Vec =
+ DAG.getBuildVector(NVT, dl, makeArrayRef(Ops.data(), NumElts));
return DAG.getNode(ISD::BITCAST, dl, N->getValueType(0), Vec);
}
@@ -396,10 +396,8 @@ SDValue DAGTypeLegalizer::ExpandOp_BUILD_VECTOR(SDNode *N) {
NewElts.push_back(Hi);
}
- SDValue NewVec = DAG.getNode(ISD::BUILD_VECTOR, dl,
- EVT::getVectorVT(*DAG.getContext(),
- NewVT, NewElts.size()),
- NewElts);
+ EVT NewVecVT = EVT::getVectorVT(*DAG.getContext(), NewVT, NewElts.size());
+ SDValue NewVec = DAG.getBuildVector(NewVecVT, dl, NewElts);
// Convert the new vector to the old vector type.
return DAG.getNode(ISD::BITCAST, dl, VecVT, NewVec);
@@ -458,7 +456,7 @@ SDValue DAGTypeLegalizer::ExpandOp_SCALAR_TO_VECTOR(SDNode *N) {
SDValue UndefVal = DAG.getUNDEF(Ops[0].getValueType());
for (unsigned i = 1; i < NumElts; ++i)
Ops[i] = UndefVal;
- return DAG.getNode(ISD::BUILD_VECTOR, dl, VT, Ops);
+ return DAG.getBuildVector(VT, dl, Ops);
}
SDValue DAGTypeLegalizer::ExpandOp_NormalStore(SDNode *N, unsigned OpNo) {
diff --git a/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
index 1a7d7b7af5fa..4a3160297d64 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
@@ -512,7 +512,7 @@ SDValue DAGTypeLegalizer::ScalarizeVecOp_UnaryOp(SDNode *N) {
N->getValueType(0).getScalarType(), Elt);
// Revectorize the result so the types line up with what the uses of this
// expression expect.
- return DAG.getNode(ISD::BUILD_VECTOR, SDLoc(N), N->getValueType(0), Op);
+ return DAG.getBuildVector(N->getValueType(0), SDLoc(N), Op);
}
/// The vectors to concatenate have length one - use a BUILD_VECTOR instead.
@@ -523,16 +523,16 @@ SDValue DAGTypeLegalizer::ScalarizeVecOp_CONCAT_VECTORS(SDNode *N) {
return DAG.getBuildVector(N->getValueType(0), SDLoc(N), Ops);
}
-/// If the input is a vector that needs to be scalarized, it must be <1 x ty>,
-/// so just return the element, ignoring the index.
-SDValue DAGTypeLegalizer::ScalarizeVecOp_EXTRACT_VECTOR_ELT(SDNode *N) {
- SDValue Res = GetScalarizedVector(N->getOperand(0));
- if (Res.getValueType() != N->getValueType(0))
- Res = DAG.getNode(ISD::ANY_EXTEND, SDLoc(N), N->getValueType(0),
- Res);
- return Res;
-}
-
+/// If the input is a vector that needs to be scalarized, it must be <1 x ty>,
+/// so just return the element, ignoring the index.
+SDValue DAGTypeLegalizer::ScalarizeVecOp_EXTRACT_VECTOR_ELT(SDNode *N) {
+ EVT VT = N->getValueType(0);
+ SDValue Res = GetScalarizedVector(N->getOperand(0));
+ if (Res.getValueType() != VT)
+ Res = DAG.getNode(ISD::ANY_EXTEND, SDLoc(N), VT, Res);
+ return Res;
+}
+
/// If the input condition is a vector that needs to be scalarized, it must be
/// <1 x i1>, so just convert to a normal ISD::SELECT
@@ -2631,7 +2631,7 @@ SDValue DAGTypeLegalizer::WidenVecRes_BITCAST(SDNode *N) {
if (InVT.isVector())
NewVec = DAG.getNode(ISD::CONCAT_VECTORS, dl, NewInVT, Ops);
else
- NewVec = DAG.getNode(ISD::BUILD_VECTOR, dl, NewInVT, Ops);
+ NewVec = DAG.getBuildVector(NewInVT, dl, Ops);
return DAG.getNode(ISD::BITCAST, dl, WidenVT, NewVec);
}
}
diff --git a/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp b/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
index e923e30e5037..69b76fbe57d2 100644
--- a/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
+++ b/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
@@ -1320,6 +1320,18 @@ DelayForLiveRegsBottomUp(SUnit *SU, SmallVectorImpl<unsigned> &LRegs) {
RegAdded, LRegs);
const MCInstrDesc &MCID = TII->get(Node->getMachineOpcode());
+ if (MCID.hasOptionalDef()) {
+ // Most ARM instructions have an OptionalDef for CPSR, to model the S-bit.
+ // This operand can be either a def of CPSR, if the S bit is set; or a use
+ // of %noreg. When the OptionalDef is set to a valid register, we need to
+ // handle it in the same way as an ImplicitDef.
+ for (unsigned i = 0; i < MCID.getNumDefs(); ++i)
+ if (MCID.OpInfo[i].isOptionalDef()) {
+ const SDValue &OptionalDef = Node->getOperand(i - Node->getNumValues());
+ unsigned Reg = cast<RegisterSDNode>(OptionalDef)->getReg();
+ CheckForLiveRegDef(SU, Reg, LiveRegDefs.get(), RegAdded, LRegs, TRI);
+ }
+ }
if (!MCID.ImplicitDefs)
continue;
for (const MCPhysReg *Reg = MCID.getImplicitDefs(); *Reg; ++Reg)
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 523f409e6b2c..439f67f1e155 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -36,6 +36,7 @@
#include "llvm/IR/Intrinsics.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/KnownBits.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/Mutex.h"
@@ -2868,7 +2869,7 @@ bool SelectionDAG::isKnownToBeAPowerOfTwo(SDValue Val) const {
// A left-shift of a constant one will have exactly one bit set because
// shifting the bit off the end is undefined.
if (Val.getOpcode() == ISD::SHL) {
- auto *C = dyn_cast<ConstantSDNode>(Val.getOperand(0));
+ auto *C = isConstOrConstSplat(Val.getOperand(0));
if (C && C->getAPIntValue() == 1)
return true;
}
@@ -2876,7 +2877,7 @@ bool SelectionDAG::isKnownToBeAPowerOfTwo(SDValue Val) const {
// Similarly, a logical right-shift of a constant sign-bit will have exactly
// one bit set.
if (Val.getOpcode() == ISD::SRL) {
- auto *C = dyn_cast<ConstantSDNode>(Val.getOperand(0));
+ auto *C = isConstOrConstSplat(Val.getOperand(0));
if (C && C->getAPIntValue().isSignMask())
return true;
}
@@ -7539,10 +7540,10 @@ unsigned SelectionDAG::InferPtrAlignment(SDValue Ptr) const {
int64_t GVOffset = 0;
if (TLI->isGAPlusOffset(Ptr.getNode(), GV, GVOffset)) {
unsigned PtrWidth = getDataLayout().getPointerTypeSizeInBits(GV->getType());
- APInt KnownZero(PtrWidth, 0), KnownOne(PtrWidth, 0);
- llvm::computeKnownBits(const_cast<GlobalValue *>(GV), KnownZero, KnownOne,
+ KnownBits Known(PtrWidth);
+ llvm::computeKnownBits(const_cast<GlobalValue *>(GV), Known,
getDataLayout());
- unsigned AlignBits = KnownZero.countTrailingOnes();
+ unsigned AlignBits = Known.Zero.countTrailingOnes();
unsigned Align = AlignBits ? 1 << std::min(31U, AlignBits) : 0;
if (Align)
return MinAlign(Align, GVOffset);
@@ -7629,52 +7630,52 @@ Type *ConstantPoolSDNode::getType() const {
return Val.ConstVal->getType();
}
-bool BuildVectorSDNode::isConstantSplat(APInt &SplatValue,
- APInt &SplatUndef,
+bool BuildVectorSDNode::isConstantSplat(APInt &SplatValue, APInt &SplatUndef,
unsigned &SplatBitSize,
bool &HasAnyUndefs,
unsigned MinSplatBits,
- bool isBigEndian) const {
+ bool IsBigEndian) const {
EVT VT = getValueType(0);
assert(VT.isVector() && "Expected a vector type");
- unsigned sz = VT.getSizeInBits();
- if (MinSplatBits > sz)
+ unsigned VecWidth = VT.getSizeInBits();
+ if (MinSplatBits > VecWidth)
return false;
- SplatValue = APInt(sz, 0);
- SplatUndef = APInt(sz, 0);
+ // FIXME: The widths are based on this node's type, but build vectors can
+ // truncate their operands.
+ SplatValue = APInt(VecWidth, 0);
+ SplatUndef = APInt(VecWidth, 0);
- // Get the bits. Bits with undefined values (when the corresponding element
+ // Get the bits. Bits with undefined values (when the corresponding element
// of the vector is an ISD::UNDEF value) are set in SplatUndef and cleared
- // in SplatValue. If any of the values are not constant, give up and return
+ // in SplatValue. If any of the values are not constant, give up and return
// false.
- unsigned int nOps = getNumOperands();
- assert(nOps > 0 && "isConstantSplat has 0-size build vector");
- unsigned EltBitSize = VT.getScalarSizeInBits();
+ unsigned int NumOps = getNumOperands();
+ assert(NumOps > 0 && "isConstantSplat has 0-size build vector");
+ unsigned EltWidth = VT.getScalarSizeInBits();
- for (unsigned j = 0; j < nOps; ++j) {
- unsigned i = isBigEndian ? nOps-1-j : j;
+ for (unsigned j = 0; j < NumOps; ++j) {
+ unsigned i = IsBigEndian ? NumOps - 1 - j : j;
SDValue OpVal = getOperand(i);
- unsigned BitPos = j * EltBitSize;
+ unsigned BitPos = j * EltWidth;
if (OpVal.isUndef())
- SplatUndef.setBits(BitPos, BitPos + EltBitSize);
- else if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(OpVal))
- SplatValue.insertBits(CN->getAPIntValue().zextOrTrunc(EltBitSize),
- BitPos);
- else if (ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(OpVal))
+ SplatUndef.setBits(BitPos, BitPos + EltWidth);
+ else if (auto *CN = dyn_cast<ConstantSDNode>(OpVal))
+ SplatValue.insertBits(CN->getAPIntValue().zextOrTrunc(EltWidth), BitPos);
+ else if (auto *CN = dyn_cast<ConstantFPSDNode>(OpVal))
SplatValue.insertBits(CN->getValueAPF().bitcastToAPInt(), BitPos);
else
return false;
}
- // The build_vector is all constants or undefs. Find the smallest element
+ // The build_vector is all constants or undefs. Find the smallest element
// size that splats the vector.
-
HasAnyUndefs = (SplatUndef != 0);
- while (sz > 8) {
- unsigned HalfSize = sz / 2;
+ // FIXME: This does not work for vectors with elements less than 8 bits.
+ while (VecWidth > 8) {
+ unsigned HalfSize = VecWidth / 2;
APInt HighValue = SplatValue.lshr(HalfSize).trunc(HalfSize);
APInt LowValue = SplatValue.trunc(HalfSize);
APInt HighUndef = SplatUndef.lshr(HalfSize).trunc(HalfSize);
@@ -7688,10 +7689,10 @@ bool BuildVectorSDNode::isConstantSplat(APInt &SplatValue,
SplatValue = HighValue | LowValue;
SplatUndef = HighUndef & LowUndef;
- sz = HalfSize;
+ VecWidth = HalfSize;
}
- SplatBitSize = sz;
+ SplatBitSize = VecWidth;
return true;
}
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 2c58953ee908..6a737ed84ea4 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -362,11 +362,11 @@ static SDValue getCopyFromPartsVector(SelectionDAG &DAG, const SDLoc &DL,
return DAG.getUNDEF(ValueVT);
}
- if (ValueVT.getVectorNumElements() == 1 &&
- ValueVT.getVectorElementType() != PartEVT)
- Val = DAG.getAnyExtOrTrunc(Val, DL, ValueVT.getScalarType());
+ EVT ValueSVT = ValueVT.getVectorElementType();
+ if (ValueVT.getVectorNumElements() == 1 && ValueSVT != PartEVT)
+ Val = DAG.getAnyExtOrTrunc(Val, DL, ValueSVT);
- return DAG.getNode(ISD::BUILD_VECTOR, DL, ValueVT, Val);
+ return DAG.getBuildVector(ValueVT, DL, Val);
}
static void getCopyToPartsVector(SelectionDAG &DAG, const SDLoc &dl,
@@ -537,7 +537,7 @@ static void getCopyToPartsVector(SelectionDAG &DAG, const SDLoc &DL,
e = PartVT.getVectorNumElements(); i != e; ++i)
Ops.push_back(DAG.getUNDEF(ElementVT));
- Val = DAG.getNode(ISD::BUILD_VECTOR, DL, PartVT, Ops);
+ Val = DAG.getBuildVector(PartVT, DL, Ops);
// FIXME: Use CONCAT for 2x -> 4x.
@@ -1088,8 +1088,7 @@ SDValue SelectionDAGBuilder::getValueImpl(const Value *V) {
if (isa<ArrayType>(CDS->getType()))
return DAG.getMergeValues(Ops, getCurSDLoc());
- return NodeMap[V] = DAG.getNode(ISD::BUILD_VECTOR, getCurSDLoc(),
- VT, Ops);
+ return NodeMap[V] = DAG.getBuildVector(VT, getCurSDLoc(), Ops);
}
if (C->getType()->isStructTy() || C->getType()->isArrayTy()) {
@@ -1141,7 +1140,7 @@ SDValue SelectionDAGBuilder::getValueImpl(const Value *V) {
}
// Create a BUILD_VECTOR node.
- return NodeMap[V] = DAG.getNode(ISD::BUILD_VECTOR, getCurSDLoc(), VT, Ops);
+ return NodeMap[V] = DAG.getBuildVector(VT, getCurSDLoc(), Ops);
}
// If this is a static alloca, generate it as the frameindex instead of
@@ -3147,7 +3146,7 @@ void SelectionDAGBuilder::visitShuffleVector(const User &I) {
Ops.push_back(Res);
}
- setValue(&I, DAG.getNode(ISD::BUILD_VECTOR, DL, VT, Ops));
+ setValue(&I, DAG.getBuildVector(VT, DL, Ops));
}
void SelectionDAGBuilder::visitInsertValue(const InsertValueInst &I) {
@@ -3969,9 +3968,9 @@ void SelectionDAGBuilder::visitFence(const FenceInst &I) {
SDValue Ops[3];
Ops[0] = getRoot();
Ops[1] = DAG.getConstant((unsigned)I.getOrdering(), dl,
- TLI.getPointerTy(DAG.getDataLayout()));
+ TLI.getFenceOperandTy(DAG.getDataLayout()));
Ops[2] = DAG.getConstant(I.getSynchScope(), dl,
- TLI.getPointerTy(DAG.getDataLayout()));
+ TLI.getFenceOperandTy(DAG.getDataLayout()));
DAG.setRoot(DAG.getNode(ISD::ATOMIC_FENCE, dl, MVT::Other, Ops));
}
@@ -4896,11 +4895,11 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) {
Entry.Node = Src;
Args.push_back(Entry);
-
+
Entry.Ty = I.getArgOperand(2)->getType();
Entry.Node = NumElements;
Args.push_back(Entry);
-
+
Entry.Ty = Type::getInt32Ty(*DAG.getContext());
Entry.Node = ElementSize;
Args.push_back(Entry);
@@ -5183,7 +5182,7 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) {
SDValue ShOps[2];
ShOps[0] = ShAmt;
ShOps[1] = DAG.getConstant(0, sdl, MVT::i32);
- ShAmt = DAG.getNode(ISD::BUILD_VECTOR, sdl, ShAmtVT, ShOps);
+ ShAmt = DAG.getBuildVector(ShAmtVT, sdl, ShOps);
EVT DestVT = TLI.getValueType(DAG.getDataLayout(), I.getType());
ShAmt = DAG.getNode(ISD::BITCAST, sdl, DestVT, ShAmt);
Res = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, sdl, DestVT,
@@ -5743,7 +5742,7 @@ void SelectionDAGBuilder::visitConstrainedFPIntrinsic(const CallInst &I,
unsigned Opcode;
switch (Intrinsic) {
default: llvm_unreachable("Impossible intrinsic"); // Can't reach here.
- case Intrinsic::experimental_constrained_fadd:
+ case Intrinsic::experimental_constrained_fadd:
Opcode = ISD::STRICT_FADD;
break;
case Intrinsic::experimental_constrained_fsub:
@@ -6653,12 +6652,12 @@ static void GetRegistersForValue(SelectionDAG &DAG, const TargetLowering &TLI,
MachineFunction &MF = DAG.getMachineFunction();
SmallVector<unsigned, 4> Regs;
+ const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo();
// If this is a constraint for a single physreg, or a constraint for a
// register class, find it.
std::pair<unsigned, const TargetRegisterClass *> PhysReg =
- TLI.getRegForInlineAsmConstraint(MF.getSubtarget().getRegisterInfo(),
- OpInfo.ConstraintCode,
+ TLI.getRegForInlineAsmConstraint(&TRI, OpInfo.ConstraintCode,
OpInfo.ConstraintVT);
unsigned NumRegs = 1;
@@ -6666,12 +6665,12 @@ static void GetRegistersForValue(SelectionDAG &DAG, const TargetLowering &TLI,
// If this is a FP input in an integer register (or visa versa) insert a bit
// cast of the input value. More generally, handle any case where the input
// value disagrees with the register class we plan to stick this in.
- if (OpInfo.Type == InlineAsm::isInput &&
- PhysReg.second && !PhysReg.second->hasType(OpInfo.ConstraintVT)) {
+ if (OpInfo.Type == InlineAsm::isInput && PhysReg.second &&
+ !TRI.isTypeLegalForClass(*PhysReg.second, OpInfo.ConstraintVT)) {
// Try to convert to the first EVT that the reg class contains. If the
// types are identical size, use a bitcast to convert (e.g. two differing
// vector types).
- MVT RegVT = *PhysReg.second->vt_begin();
+ MVT RegVT = *TRI.legalclasstypes_begin(*PhysReg.second);
if (RegVT.getSizeInBits() == OpInfo.CallOperand.getValueSizeInBits()) {
OpInfo.CallOperand = DAG.getNode(ISD::BITCAST, DL,
RegVT, OpInfo.CallOperand);
@@ -6699,12 +6698,12 @@ static void GetRegistersForValue(SelectionDAG &DAG, const TargetLowering &TLI,
if (unsigned AssignedReg = PhysReg.first) {
const TargetRegisterClass *RC = PhysReg.second;
if (OpInfo.ConstraintVT == MVT::Other)
- ValueVT = *RC->vt_begin();
+ ValueVT = *TRI.legalclasstypes_begin(*RC);
// Get the actual register value type. This is important, because the user
// may have asked for (e.g.) the AX register in i32 type. We need to
// remember that AX is actually i16 to get the right extension.
- RegVT = *RC->vt_begin();
+ RegVT = *TRI.legalclasstypes_begin(*RC);
// This is a explicit reference to a physical register.
Regs.push_back(AssignedReg);
@@ -6730,7 +6729,7 @@ static void GetRegistersForValue(SelectionDAG &DAG, const TargetLowering &TLI,
// Otherwise, if this was a reference to an LLVM register class, create vregs
// for this reference.
if (const TargetRegisterClass *RC = PhysReg.second) {
- RegVT = *RC->vt_begin();
+ RegVT = *TRI.legalclasstypes_begin(*RC);
if (OpInfo.ConstraintVT == MVT::Other)
ValueVT = RegVT;
diff --git a/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index 93c6738f650d..136dec873cb8 100644
--- a/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -342,11 +342,16 @@ TargetLowering::isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const {
/// If the specified instruction has a constant integer operand and there are
/// bits set in that constant that are not demanded, then clear those bits and
/// return true.
-bool TargetLowering::TargetLoweringOpt::ShrinkDemandedConstant(
- SDValue Op, const APInt &Demanded) {
+bool TargetLowering::ShrinkDemandedConstant(SDValue Op, const APInt &Demanded,
+ TargetLoweringOpt &TLO) const {
+ SelectionDAG &DAG = TLO.DAG;
SDLoc DL(Op);
unsigned Opcode = Op.getOpcode();
+ // Do target-specific constant optimization.
+ if (targetShrinkDemandedConstant(Op, Demanded, TLO))
+ return TLO.New.getNode();
+
// FIXME: ISD::SELECT, ISD::SELECT_CC
switch (Opcode) {
default:
@@ -367,7 +372,7 @@ bool TargetLowering::TargetLoweringOpt::ShrinkDemandedConstant(
EVT VT = Op.getValueType();
SDValue NewC = DAG.getConstant(Demanded & C, DL, VT);
SDValue NewOp = DAG.getNode(Opcode, DL, VT, Op.getOperand(0), NewC);
- return CombineTo(Op, NewOp);
+ return TLO.CombineTo(Op, NewOp);
}
break;
@@ -380,15 +385,17 @@ bool TargetLowering::TargetLoweringOpt::ShrinkDemandedConstant(
/// Convert x+y to (VT)((SmallVT)x+(SmallVT)y) if the casts are free.
/// This uses isZExtFree and ZERO_EXTEND for the widening cast, but it could be
/// generalized for targets with other types of implicit widening casts.
-bool TargetLowering::TargetLoweringOpt::ShrinkDemandedOp(SDValue Op,
- unsigned BitWidth,
- const APInt &Demanded,
- const SDLoc &dl) {
+bool TargetLowering::ShrinkDemandedOp(SDValue Op, unsigned BitWidth,
+ const APInt &Demanded,
+ TargetLoweringOpt &TLO) const {
assert(Op.getNumOperands() == 2 &&
"ShrinkDemandedOp only supports binary operators!");
assert(Op.getNode()->getNumValues() == 1 &&
"ShrinkDemandedOp only supports nodes with one result!");
+ SelectionDAG &DAG = TLO.DAG;
+ SDLoc dl(Op);
+
// Early return, as this function cannot handle vector types.
if (Op.getValueType().isVector())
return false;
@@ -418,23 +425,22 @@ bool TargetLowering::TargetLoweringOpt::ShrinkDemandedOp(SDValue Op,
bool NeedZext = DemandedSize > SmallVTBits;
SDValue Z = DAG.getNode(NeedZext ? ISD::ZERO_EXTEND : ISD::ANY_EXTEND,
dl, Op.getValueType(), X);
- return CombineTo(Op, Z);
+ return TLO.CombineTo(Op, Z);
}
}
return false;
}
bool
-TargetLowering::TargetLoweringOpt::SimplifyDemandedBits(SDNode *User,
- unsigned OpIdx,
- const APInt &Demanded,
- DAGCombinerInfo &DCI) {
- const TargetLowering &TLI = DAG.getTargetLoweringInfo();
+TargetLowering::SimplifyDemandedBits(SDNode *User, unsigned OpIdx,
+ const APInt &Demanded,
+ DAGCombinerInfo &DCI,
+ TargetLoweringOpt &TLO) const {
SDValue Op = User->getOperand(OpIdx);
APInt KnownZero, KnownOne;
- if (!TLI.SimplifyDemandedBits(Op, Demanded, KnownZero, KnownOne,
- *this, 0, true))
+ if (!SimplifyDemandedBits(Op, Demanded, KnownZero, KnownOne,
+ TLO, 0, true))
return false;
@@ -446,9 +452,9 @@ TargetLowering::TargetLoweringOpt::SimplifyDemandedBits(SDNode *User,
// with the value 'x', which will give us:
// Old = i32 and x, 0xffffff
// New = x
- if (Old.hasOneUse()) {
+ if (TLO.Old.hasOneUse()) {
// For the one use case, we just commit the change.
- DCI.CommitTargetLoweringOpt(*this);
+ DCI.CommitTargetLoweringOpt(TLO);
return true;
}
@@ -456,17 +462,17 @@ TargetLowering::TargetLoweringOpt::SimplifyDemandedBits(SDNode *User,
// AssumeSingleUse flag is not propogated to recursive calls of
// SimplifyDemanded bits, so the only node with multiple use that
// it will attempt to combine will be opt.
- assert(Old == Op);
+ assert(TLO.Old == Op);
SmallVector <SDValue, 4> NewOps;
for (unsigned i = 0, e = User->getNumOperands(); i != e; ++i) {
if (i == OpIdx) {
- NewOps.push_back(New);
+ NewOps.push_back(TLO.New);
continue;
}
NewOps.push_back(User->getOperand(i));
}
- DAG.UpdateNodeOperands(User, NewOps);
+ TLO.DAG.UpdateNodeOperands(User, NewOps);
// Op has less users now, so we may be able to perform additional combines
// with it.
DCI.AddToWorklist(Op.getNode());
@@ -585,7 +591,7 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op,
// If any of the set bits in the RHS are known zero on the LHS, shrink
// the constant.
- if (TLO.ShrinkDemandedConstant(Op, ~LHSZero & NewMask))
+ if (ShrinkDemandedConstant(Op, ~LHSZero & NewMask, TLO))
return true;
// Bitwise-not (xor X, -1) is a special case: we don't usually shrink its
@@ -620,10 +626,10 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op,
if ((NewMask & (KnownZero|KnownZero2)) == NewMask)
return TLO.CombineTo(Op, TLO.DAG.getConstant(0, dl, Op.getValueType()));
// If the RHS is a constant, see if we can simplify it.
- if (TLO.ShrinkDemandedConstant(Op, ~KnownZero2 & NewMask))
+ if (ShrinkDemandedConstant(Op, ~KnownZero2 & NewMask, TLO))
return true;
// If the operation can be done in a smaller type, do so.
- if (TLO.ShrinkDemandedOp(Op, BitWidth, NewMask, dl))
+ if (ShrinkDemandedOp(Op, BitWidth, NewMask, TLO))
return true;
// Output known-1 bits are only known if set in both the LHS & RHS.
@@ -654,10 +660,10 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op,
if ((NewMask & ~KnownZero2 & KnownOne) == (~KnownZero2 & NewMask))
return TLO.CombineTo(Op, Op.getOperand(1));
// If the RHS is a constant, see if we can simplify it.
- if (TLO.ShrinkDemandedConstant(Op, NewMask))
+ if (ShrinkDemandedConstant(Op, NewMask, TLO))
return true;
// If the operation can be done in a smaller type, do so.
- if (TLO.ShrinkDemandedOp(Op, BitWidth, NewMask, dl))
+ if (ShrinkDemandedOp(Op, BitWidth, NewMask, TLO))
return true;
// Output known-0 bits are only known if clear in both the LHS & RHS.
@@ -682,7 +688,7 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op,
if ((KnownZero2 & NewMask) == NewMask)
return TLO.CombineTo(Op, Op.getOperand(1));
// If the operation can be done in a smaller type, do so.
- if (TLO.ShrinkDemandedOp(Op, BitWidth, NewMask, dl))
+ if (ShrinkDemandedOp(Op, BitWidth, NewMask, TLO))
return true;
// If all of the unknown bits are known to be zero on one side or the other
@@ -727,7 +733,7 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op,
}
// If it already has all the bits set, nothing to change
// but don't shrink either!
- } else if (TLO.ShrinkDemandedConstant(Op, NewMask)) {
+ } else if (ShrinkDemandedConstant(Op, NewMask, TLO)) {
return true;
}
}
@@ -746,7 +752,7 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op,
assert((KnownZero2 & KnownOne2) == 0 && "Bits known to be one AND zero?");
// If the operands are constants, see if we can simplify them.
- if (TLO.ShrinkDemandedConstant(Op, NewMask))
+ if (ShrinkDemandedConstant(Op, NewMask, TLO))
return true;
// Only known if known in both the LHS and RHS.
@@ -764,7 +770,7 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op,
assert((KnownZero2 & KnownOne2) == 0 && "Bits known to be one AND zero?");
// If the operands are constants, see if we can simplify them.
- if (TLO.ShrinkDemandedConstant(Op, NewMask))
+ if (ShrinkDemandedConstant(Op, NewMask, TLO))
return true;
// Only known if known in both the LHS and RHS.
@@ -1284,7 +1290,7 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op,
SimplifyDemandedBits(Op.getOperand(1), LoMask, KnownZero2,
KnownOne2, TLO, Depth+1) ||
// See if the operation should be performed at a smaller bit width.
- TLO.ShrinkDemandedOp(Op, BitWidth, NewMask, dl)) {
+ ShrinkDemandedOp(Op, BitWidth, NewMask, TLO)) {
const SDNodeFlags *Flags = Op.getNode()->getFlags();
if (Flags->hasNoSignedWrap() || Flags->hasNoUnsignedWrap()) {
// Disable the nsw and nuw flags. We can no longer guarantee that we
@@ -1358,31 +1364,38 @@ unsigned TargetLowering::ComputeNumSignBitsForTargetNode(SDValue Op,
return 1;
}
+// FIXME: Ideally, this would use ISD::isConstantSplatVector(), but that must
+// work with truncating build vectors and vectors with elements of less than
+// 8 bits.
bool TargetLowering::isConstTrueVal(const SDNode *N) const {
if (!N)
return false;
- const ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N);
- if (!CN) {
- const BuildVectorSDNode *BV = dyn_cast<BuildVectorSDNode>(N);
- if (!BV)
- return false;
-
- // Only interested in constant splats, we don't care about undef
- // elements in identifying boolean constants and getConstantSplatNode
- // returns NULL if all ops are undef;
- CN = BV->getConstantSplatNode();
+ APInt CVal;
+ if (auto *CN = dyn_cast<ConstantSDNode>(N)) {
+ CVal = CN->getAPIntValue();
+ } else if (auto *BV = dyn_cast<BuildVectorSDNode>(N)) {
+ auto *CN = BV->getConstantSplatNode();
if (!CN)
return false;
+
+ // If this is a truncating build vector, truncate the splat value.
+ // Otherwise, we may fail to match the expected values below.
+ unsigned BVEltWidth = BV->getValueType(0).getScalarSizeInBits();
+ CVal = CN->getAPIntValue();
+ if (BVEltWidth < CVal.getBitWidth())
+ CVal = CVal.trunc(BVEltWidth);
+ } else {
+ return false;
}
switch (getBooleanContents(N->getValueType(0))) {
case UndefinedBooleanContent:
- return CN->getAPIntValue()[0];
+ return CVal[0];
case ZeroOrOneBooleanContent:
- return CN->isOne();
+ return CVal == 1;
case ZeroOrNegativeOneBooleanContent:
- return CN->isAllOnesValue();
+ return CVal.isAllOnesValue();
}
llvm_unreachable("Invalid boolean contents");
@@ -2535,7 +2548,7 @@ TargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *RI,
for (const TargetRegisterClass *RC : RI->regclasses()) {
// If none of the value types for this register class are valid, we
// can't use it. For example, 64-bit reg classes on 32-bit targets.
- if (!isLegalRC(RC))
+ if (!isLegalRC(*RI, *RC))
continue;
for (TargetRegisterClass::iterator I = RC->begin(), E = RC->end();
@@ -2547,9 +2560,9 @@ TargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *RI,
// If this register class has the requested value type, return it,
// otherwise keep searching and return the first class found
// if no other is found which explicitly has the requested type.
- if (RC->hasType(VT))
+ if (RI->isTypeLegalForClass(*RC, VT))
return S;
- else if (!R.second)
+ if (!R.second)
R = S;
}
}
diff --git a/lib/CodeGen/StackMaps.cpp b/lib/CodeGen/StackMaps.cpp
index 1a8ec5bff322..315b059c5ac9 100644
--- a/lib/CodeGen/StackMaps.cpp
+++ b/lib/CodeGen/StackMaps.cpp
@@ -161,7 +161,8 @@ StackMaps::parseOperand(MachineInstr::const_mop_iterator MOI,
if (SubRegIdx)
Offset = TRI->getSubRegIdxOffset(SubRegIdx);
- Locs.emplace_back(Location::Register, RC->getSize(), DwarfRegNum, Offset);
+ Locs.emplace_back(Location::Register, TRI->getSpillSize(*RC),
+ DwarfRegNum, Offset);
return ++MOI;
}
@@ -245,7 +246,7 @@ void StackMaps::print(raw_ostream &OS) {
StackMaps::LiveOutReg
StackMaps::createLiveOutReg(unsigned Reg, const TargetRegisterInfo *TRI) const {
unsigned DwarfRegNum = getDwarfRegNum(Reg, TRI);
- unsigned Size = TRI->getMinimalPhysRegClass(Reg)->getSize();
+ unsigned Size = TRI->getSpillSize(*TRI->getMinimalPhysRegClass(Reg));
return LiveOutReg(Reg, DwarfRegNum, Size);
}
diff --git a/lib/CodeGen/TargetInstrInfo.cpp b/lib/CodeGen/TargetInstrInfo.cpp
index 711144a34743..14c5adc0d898 100644
--- a/lib/CodeGen/TargetInstrInfo.cpp
+++ b/lib/CodeGen/TargetInstrInfo.cpp
@@ -345,12 +345,12 @@ bool TargetInstrInfo::getStackSlotRange(const TargetRegisterClass *RC,
unsigned SubIdx, unsigned &Size,
unsigned &Offset,
const MachineFunction &MF) const {
+ const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
if (!SubIdx) {
- Size = RC->getSize();
+ Size = TRI->getSpillSize(*RC);
Offset = 0;
return true;
}
- const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
unsigned BitSize = TRI->getSubRegIdxSize(SubIdx);
// Convert bit size to byte size to be consistent with
// MCRegisterClass::getSize().
@@ -364,10 +364,10 @@ bool TargetInstrInfo::getStackSlotRange(const TargetRegisterClass *RC,
Size = BitSize /= 8;
Offset = (unsigned)BitOffset / 8;
- assert(RC->getSize() >= (Offset + Size) && "bad subregister range");
+ assert(TRI->getSpillSize(*RC) >= (Offset + Size) && "bad subregister range");
if (!MF.getDataLayout().isLittleEndian()) {
- Offset = RC->getSize() - (Offset + Size);
+ Offset = TRI->getSpillSize(*RC) - (Offset + Size);
}
return true;
}
@@ -428,8 +428,8 @@ static const TargetRegisterClass *canFoldCopy(const MachineInstr &MI,
return nullptr;
}
-void TargetInstrInfo::getNoopForMachoTarget(MCInst &NopInst) const {
- llvm_unreachable("Not a MachO target");
+void TargetInstrInfo::getNoop(MCInst &NopInst) const {
+ llvm_unreachable("Not implemented");
}
static MachineInstr *foldPatchpoint(MachineFunction &MF, MachineInstr &MI,
diff --git a/lib/CodeGen/TargetLoweringBase.cpp b/lib/CodeGen/TargetLoweringBase.cpp
index 27630a3055cb..e579922bb69e 100644
--- a/lib/CodeGen/TargetLoweringBase.cpp
+++ b/lib/CodeGen/TargetLoweringBase.cpp
@@ -1184,12 +1184,11 @@ static unsigned getVectorTypeBreakdownMVT(MVT VT, MVT &IntermediateVT,
/// isLegalRC - Return true if the value types that can be represented by the
/// specified register class are all legal.
-bool TargetLoweringBase::isLegalRC(const TargetRegisterClass *RC) const {
- for (TargetRegisterClass::vt_iterator I = RC->vt_begin(), E = RC->vt_end();
- I != E; ++I) {
+bool TargetLoweringBase::isLegalRC(const TargetRegisterInfo &TRI,
+ const TargetRegisterClass &RC) const {
+ for (auto I = TRI.legalclasstypes_begin(RC); *I != MVT::Other; ++I)
if (isTypeLegal(*I))
return true;
- }
return false;
}
@@ -1299,9 +1298,9 @@ TargetLoweringBase::findRepresentativeClass(const TargetRegisterInfo *TRI,
for (int i = SuperRegRC.find_first(); i >= 0; i = SuperRegRC.find_next(i)) {
const TargetRegisterClass *SuperRC = TRI->getRegClass(i);
// We want the largest possible spill size.
- if (SuperRC->getSize() <= BestRC->getSize())
+ if (TRI->getSpillSize(*SuperRC) <= TRI->getSpillSize(*BestRC))
continue;
- if (!isLegalRC(SuperRC))
+ if (!isLegalRC(*TRI, *SuperRC))
continue;
BestRC = SuperRC;
}
diff --git a/lib/CodeGen/TargetRegisterInfo.cpp b/lib/CodeGen/TargetRegisterInfo.cpp
index 66cdad278e8d..f6e4c17d514c 100644
--- a/lib/CodeGen/TargetRegisterInfo.cpp
+++ b/lib/CodeGen/TargetRegisterInfo.cpp
@@ -156,8 +156,8 @@ TargetRegisterInfo::getMinimalPhysRegClass(unsigned reg, MVT VT) const {
// this physreg.
const TargetRegisterClass* BestRC = nullptr;
for (const TargetRegisterClass* RC : regclasses()) {
- if ((VT == MVT::Other || RC->hasType(VT)) && RC->contains(reg) &&
- (!BestRC || BestRC->hasSubClass(RC)))
+ if ((VT == MVT::Other || isTypeLegalForClass(*RC, VT)) &&
+ RC->contains(reg) && (!BestRC || BestRC->hasSubClass(RC)))
BestRC = RC;
}
@@ -207,7 +207,7 @@ const TargetRegisterClass *firstCommonClass(const uint32_t *A,
if (unsigned Common = *A++ & *B++) {
const TargetRegisterClass *RC =
TRI->getRegClass(I + countTrailingZeros(Common));
- if (SVT == MVT::SimpleValueType::Any || RC->hasType(VT))
+ if (SVT == MVT::SimpleValueType::Any || TRI->isTypeLegalForClass(*RC, VT))
return RC;
}
return nullptr;
@@ -265,7 +265,7 @@ getCommonSuperRegClass(const TargetRegisterClass *RCA, unsigned SubA,
const TargetRegisterClass *BestRC = nullptr;
unsigned *BestPreA = &PreA;
unsigned *BestPreB = &PreB;
- if (RCA->getSize() < RCB->getSize()) {
+ if (getRegSizeInBits(*RCA) < getRegSizeInBits(*RCB)) {
std::swap(RCA, RCB);
std::swap(SubA, SubB);
std::swap(BestPreA, BestPreB);
@@ -273,7 +273,7 @@ getCommonSuperRegClass(const TargetRegisterClass *RCA, unsigned SubA,
// Also terminate the search one we have found a register class as small as
// RCA.
- unsigned MinSize = RCA->getSize();
+ unsigned MinSize = getRegSizeInBits(*RCA);
for (SuperRegClassIterator IA(RCA, this, true); IA.isValid(); ++IA) {
unsigned FinalA = composeSubRegIndices(IA.getSubReg(), SubA);
@@ -281,7 +281,7 @@ getCommonSuperRegClass(const TargetRegisterClass *RCA, unsigned SubA,
// Check if a common super-register class exists for this index pair.
const TargetRegisterClass *RC =
firstCommonClass(IA.getMask(), IB.getMask(), this);
- if (!RC || RC->getSize() < MinSize)
+ if (!RC || getRegSizeInBits(*RC) < MinSize)
continue;
// The indexes must compose identically: PreA+SubA == PreB+SubB.
@@ -290,7 +290,7 @@ getCommonSuperRegClass(const TargetRegisterClass *RCA, unsigned SubA,
continue;
// Is RC a better candidate than BestRC?
- if (BestRC && RC->getSize() >= BestRC->getSize())
+ if (BestRC && getRegSizeInBits(*RC) >= getRegSizeInBits(*BestRC))
continue;
// Yes, RC is the smallest super-register seen so far.
@@ -299,7 +299,7 @@ getCommonSuperRegClass(const TargetRegisterClass *RCA, unsigned SubA,
*BestPreB = IB.getSubReg();
// Bail early if we reached MinSize. We won't find a better candidate.
- if (BestRC->getSize() == MinSize)
+ if (getRegSizeInBits(*BestRC) == MinSize)
return BestRC;
}
}
diff --git a/lib/CodeGen/VirtRegMap.cpp b/lib/CodeGen/VirtRegMap.cpp
index c8946010e9d1..d10ca1a7ff91 100644
--- a/lib/CodeGen/VirtRegMap.cpp
+++ b/lib/CodeGen/VirtRegMap.cpp
@@ -73,8 +73,9 @@ void VirtRegMap::grow() {
}
unsigned VirtRegMap::createSpillSlot(const TargetRegisterClass *RC) {
- int SS = MF->getFrameInfo().CreateSpillStackObject(RC->getSize(),
- RC->getAlignment());
+ unsigned Size = TRI->getSpillSize(*RC);
+ unsigned Align = TRI->getSpillAlignment(*RC);
+ int SS = MF->getFrameInfo().CreateSpillStackObject(Size, Align);
++NumSpillSlots;
return SS;
}
diff --git a/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp b/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp
index 85e1eaedfc61..a12f8adfafe5 100644
--- a/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp
+++ b/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp
@@ -9,6 +9,7 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h"
+#include "llvm/DebugInfo/DWARF/DWARFContext.h"
#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
#include "llvm/DebugInfo/DWARF/DWARFRelocMap.h"
#include "llvm/Support/Dwarf.h"
@@ -112,10 +113,8 @@ LLVM_DUMP_METHOD void DWARFAcceleratorTable::dump(raw_ostream &OS) const {
continue;
}
while (AccelSection.isValidOffsetForDataOfSize(DataOffset, 4)) {
- unsigned StringOffset = AccelSection.getU32(&DataOffset);
- RelocAddrMap::const_iterator Reloc = Relocs.find(DataOffset-4);
- if (Reloc != Relocs.end())
- StringOffset += Reloc->second.second;
+ unsigned StringOffset =
+ getRelocatedValue(AccelSection, 4, &DataOffset, &Relocs);
if (!StringOffset)
break;
OS << format(" Name: %08x \"%s\"\n", StringOffset,
diff --git a/lib/DebugInfo/DWARF/DWARFContext.cpp b/lib/DebugInfo/DWARF/DWARFContext.cpp
index bbb19b5e998d..7e8d04672c03 100644
--- a/lib/DebugInfo/DWARF/DWARFContext.cpp
+++ b/lib/DebugInfo/DWARF/DWARFContext.cpp
@@ -56,6 +56,16 @@ typedef DWARFDebugLine::LineTable DWARFLineTable;
typedef DILineInfoSpecifier::FileLineInfoKind FileLineInfoKind;
typedef DILineInfoSpecifier::FunctionNameKind FunctionNameKind;
+uint64_t llvm::getRelocatedValue(const DataExtractor &Data, uint32_t Size,
+ uint32_t *Off, const RelocAddrMap *Relocs) {
+ if (!Relocs)
+ return Data.getUnsigned(Off, Size);
+ RelocAddrMap::const_iterator AI = Relocs->find(*Off);
+ if (AI == Relocs->end())
+ return Data.getUnsigned(Off, Size);
+ return Data.getUnsigned(Off, Size) + AI->second.second;
+}
+
static void dumpAccelSection(raw_ostream &OS, StringRef Name,
const DWARFSection& Section, StringRef StringSection,
bool LittleEndian) {
@@ -212,11 +222,11 @@ void DWARFContext::dump(raw_ostream &OS, DIDumpType DumpType, bool DumpEH,
// sizes, but for simplicity we just use the address byte size of the last
// compile unit (there is no easy and fast way to associate address range
// list and the compile unit it describes).
- DataExtractor rangesData(getRangeSection(), isLittleEndian(),
+ DataExtractor rangesData(getRangeSection().Data, isLittleEndian(),
savedAddressByteSize);
offset = 0;
DWARFDebugRangeList rangeList;
- while (rangeList.extract(rangesData, &offset))
+ while (rangeList.extract(rangesData, &offset, getRangeSection().Relocs))
rangeList.dump(OS);
}
@@ -722,7 +732,7 @@ DWARFContextInMemory::DWARFContextInMemory(const object::ObjectFile &Obj,
*SectionData = data;
if (name == "debug_ranges") {
// FIXME: Use the other dwo range section when we emit it.
- RangeDWOSection = data;
+ RangeDWOSection.Data = data;
}
} else if (name == "debug_types") {
// Find debug_types data by section rather than name as there are
@@ -763,6 +773,7 @@ DWARFContextInMemory::DWARFContextInMemory(const object::ObjectFile &Obj,
.Case("debug_loc", &LocSection.Relocs)
.Case("debug_info.dwo", &InfoDWOSection.Relocs)
.Case("debug_line", &LineSection.Relocs)
+ .Case("debug_ranges", &RangeSection.Relocs)
.Case("apple_names", &AppleNamesSection.Relocs)
.Case("apple_types", &AppleTypesSection.Relocs)
.Case("apple_namespaces", &AppleNamespacesSection.Relocs)
@@ -845,7 +856,7 @@ StringRef *DWARFContextInMemory::MapSectionToMember(StringRef Name) {
.Case("debug_frame", &DebugFrameSection)
.Case("eh_frame", &EHFrameSection)
.Case("debug_str", &StringSection)
- .Case("debug_ranges", &RangeSection)
+ .Case("debug_ranges", &RangeSection.Data)
.Case("debug_macinfo", &MacinfoSection)
.Case("debug_pubnames", &PubNamesSection)
.Case("debug_pubtypes", &PubTypesSection)
diff --git a/lib/DebugInfo/DWARF/DWARFDebugLine.cpp b/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
index e4670519b797..ff6ed9c6741d 100644
--- a/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
+++ b/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
@@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/ADT/SmallString.h"
+#include "llvm/DebugInfo/DWARF/DWARFContext.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
#include "llvm/DebugInfo/DWARF/DWARFRelocMap.h"
#include "llvm/Support/Dwarf.h"
@@ -302,16 +303,9 @@ bool DWARFDebugLine::LineTable::parse(DataExtractor debug_line_data,
// relocatable address. All of the other statement program opcodes
// that affect the address register add a delta to it. This instruction
// stores a relocatable value into it instead.
- {
- // If this address is in our relocation map, apply the relocation.
- RelocAddrMap::const_iterator AI = RMap->find(*offset_ptr);
- if (AI != RMap->end()) {
- const std::pair<uint8_t, int64_t> &R = AI->second;
- State.Row.Address =
- debug_line_data.getAddress(offset_ptr) + R.second;
- } else
- State.Row.Address = debug_line_data.getAddress(offset_ptr);
- }
+ State.Row.Address =
+ getRelocatedValue(debug_line_data, debug_line_data.getAddressSize(),
+ offset_ptr, RMap);
break;
case DW_LNE_define_file:
diff --git a/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp b/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp
index e2799ab2d243..d5c34216ed53 100644
--- a/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp
+++ b/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp
@@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/ADT/StringRef.h"
+#include "llvm/DebugInfo/DWARF/DWARFContext.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
#include "llvm/DebugInfo/DWARF/DWARFRelocMap.h"
#include "llvm/Support/Dwarf.h"
@@ -48,18 +49,10 @@ void DWARFDebugLoc::parse(DataExtractor data, unsigned AddressSize) {
// 2.6.2 Location Lists
// A location list entry consists of:
while (true) {
+ // A beginning and ending address offsets.
Entry E;
- RelocAddrMap::const_iterator AI = RelocMap.find(Offset);
- // 1. A beginning address offset. ...
- E.Begin = data.getUnsigned(&Offset, AddressSize);
- if (AI != RelocMap.end())
- E.Begin += AI->second.second;
-
- AI = RelocMap.find(Offset);
- // 2. An ending address offset. ...
- E.End = data.getUnsigned(&Offset, AddressSize);
- if (AI != RelocMap.end())
- E.End += AI->second.second;
+ E.Begin = getRelocatedValue(data, AddressSize, &Offset, &RelocMap);
+ E.End = getRelocatedValue(data, AddressSize, &Offset, &RelocMap);
// The end of any given location list is marked by an end of list entry,
// which consists of a 0 for the beginning address offset and a 0 for the
diff --git a/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp b/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp
index f1d82fda8c06..9380fe8fe85d 100644
--- a/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp
+++ b/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp
@@ -7,6 +7,7 @@
//
//===----------------------------------------------------------------------===//
+#include "llvm/DebugInfo/DWARF/DWARFContext.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
@@ -22,7 +23,8 @@ void DWARFDebugRangeList::clear() {
Entries.clear();
}
-bool DWARFDebugRangeList::extract(DataExtractor data, uint32_t *offset_ptr) {
+bool DWARFDebugRangeList::extract(DataExtractor data, uint32_t *offset_ptr,
+ const RelocAddrMap &Relocs) {
clear();
if (!data.isValidOffset(*offset_ptr))
return false;
@@ -33,8 +35,11 @@ bool DWARFDebugRangeList::extract(DataExtractor data, uint32_t *offset_ptr) {
while (true) {
RangeListEntry entry;
uint32_t prev_offset = *offset_ptr;
- entry.StartAddress = data.getAddress(offset_ptr);
- entry.EndAddress = data.getAddress(offset_ptr);
+ entry.StartAddress =
+ getRelocatedValue(data, AddressSize, offset_ptr, &Relocs);
+ entry.EndAddress =
+ getRelocatedValue(data, AddressSize, offset_ptr, &Relocs);
+
// Check that both values were extracted correctly.
if (*offset_ptr != prev_offset + 2 * AddressSize) {
clear();
diff --git a/lib/DebugInfo/DWARF/DWARFFormValue.cpp b/lib/DebugInfo/DWARF/DWARFFormValue.cpp
index 6de57b999adc..28592e4dfb65 100644
--- a/lib/DebugInfo/DWARF/DWARFFormValue.cpp
+++ b/lib/DebugInfo/DWARF/DWARFFormValue.cpp
@@ -334,11 +334,8 @@ bool DWARFFormValue::extractValue(const DataExtractor &data,
(Form == DW_FORM_addr)
? U->getAddressByteSize()
: U->getRefAddrByteSize();
- RelocAddrMap::const_iterator AI = U->getRelocMap()->find(*offset_ptr);
- if (AI != U->getRelocMap()->end()) {
- Value.uval = data.getUnsigned(offset_ptr, AddrSize) + AI->second.second;
- } else
- Value.uval = data.getUnsigned(offset_ptr, AddrSize);
+ Value.uval =
+ getRelocatedValue(data, AddrSize, offset_ptr, U->getRelocMap());
break;
}
case DW_FORM_exprloc:
@@ -376,12 +373,8 @@ bool DWARFFormValue::extractValue(const DataExtractor &data,
case DW_FORM_ref_sup4:
case DW_FORM_strx4:
case DW_FORM_addrx4: {
- Value.uval = data.getU32(offset_ptr);
- if (!U)
- break;
- RelocAddrMap::const_iterator AI = U->getRelocMap()->find(*offset_ptr-4);
- if (AI != U->getRelocMap()->end())
- Value.uval += AI->second.second;
+ const RelocAddrMap* RelocMap = U ? U->getRelocMap() : nullptr;
+ Value.uval = getRelocatedValue(data, 4, offset_ptr, RelocMap);
break;
}
case DW_FORM_data8:
@@ -411,11 +404,8 @@ bool DWARFFormValue::extractValue(const DataExtractor &data,
case DW_FORM_strp_sup: {
if (!U)
return false;
- RelocAddrMap::const_iterator AI = U->getRelocMap()->find(*offset_ptr);
- uint8_t Size = U->getDwarfOffsetByteSize();
- Value.uval = data.getUnsigned(offset_ptr, Size);
- if (AI != U->getRelocMap()->end())
- Value.uval += AI->second.second;
+ Value.uval = getRelocatedValue(data, U->getDwarfOffsetByteSize(),
+ offset_ptr, U->getRelocMap());
break;
}
case DW_FORM_flag_present:
diff --git a/lib/DebugInfo/DWARF/DWARFUnit.cpp b/lib/DebugInfo/DWARF/DWARFUnit.cpp
index c3f467745402..f50487fc3ba3 100644
--- a/lib/DebugInfo/DWARF/DWARFUnit.cpp
+++ b/lib/DebugInfo/DWARF/DWARFUnit.cpp
@@ -32,7 +32,7 @@ using namespace llvm;
using namespace dwarf;
void DWARFUnitSectionBase::parse(DWARFContext &C, const DWARFSection &Section) {
- parseImpl(C, Section, C.getDebugAbbrev(), C.getRangeSection(),
+ parseImpl(C, Section, C.getDebugAbbrev(), &C.getRangeSection(),
C.getStringSection(), StringRef(), C.getAddrSection(),
C.getLineSection().Data, C.isLittleEndian(), false);
}
@@ -40,16 +40,17 @@ void DWARFUnitSectionBase::parse(DWARFContext &C, const DWARFSection &Section) {
void DWARFUnitSectionBase::parseDWO(DWARFContext &C,
const DWARFSection &DWOSection,
DWARFUnitIndex *Index) {
- parseImpl(C, DWOSection, C.getDebugAbbrevDWO(), C.getRangeDWOSection(),
+ parseImpl(C, DWOSection, C.getDebugAbbrevDWO(), &C.getRangeDWOSection(),
C.getStringDWOSection(), C.getStringOffsetDWOSection(),
C.getAddrSection(), C.getLineDWOSection().Data, C.isLittleEndian(),
true);
}
DWARFUnit::DWARFUnit(DWARFContext &DC, const DWARFSection &Section,
- const DWARFDebugAbbrev *DA, StringRef RS, StringRef SS,
- StringRef SOS, StringRef AOS, StringRef LS, bool LE,
- bool IsDWO, const DWARFUnitSectionBase &UnitSection,
+ const DWARFDebugAbbrev *DA, const DWARFSection *RS,
+ StringRef SS, StringRef SOS, StringRef AOS, StringRef LS,
+ bool LE, bool IsDWO,
+ const DWARFUnitSectionBase &UnitSection,
const DWARFUnitIndex::Entry *IndexEntry)
: Context(DC), InfoSection(Section), Abbrev(DA), RangeSection(RS),
LineSection(LS), StringSection(SS), StringOffsetSection([&]() {
@@ -142,9 +143,10 @@ bool DWARFUnit::extractRangeList(uint32_t RangeListOffset,
DWARFDebugRangeList &RangeList) const {
// Require that compile unit is extracted.
assert(!DieArray.empty());
- DataExtractor RangesData(RangeSection, isLittleEndian, AddrSize);
+ DataExtractor RangesData(RangeSection->Data, isLittleEndian, AddrSize);
uint32_t ActualRangeListOffset = RangeSectionBase + RangeListOffset;
- return RangeList.extract(RangesData, &ActualRangeListOffset);
+ return RangeList.extract(RangesData, &ActualRangeListOffset,
+ RangeSection->Relocs);
}
void DWARFUnit::clear() {
diff --git a/lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp b/lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp
index 5e8c0bdc171d..4e2474c51cb1 100644
--- a/lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp
+++ b/lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp
@@ -14,6 +14,7 @@
#include "llvm/DebugInfo/PDB/DIA/DIAEnumSymbols.h"
#include "llvm/DebugInfo/PDB/DIA/DIASession.h"
#include "llvm/DebugInfo/PDB/PDBExtras.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypePointer.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeVTable.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeVTableShape.h"
@@ -720,7 +721,7 @@ uint32_t DIARawSymbol::getVirtualTableShapeId() const {
return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_virtualTableShapeId);
}
-std::unique_ptr<PDBSymbolTypeVTable>
+std::unique_ptr<PDBSymbolTypeBuiltin>
DIARawSymbol::getVirtualBaseTableType() const {
CComPtr<IDiaSymbol> TableType;
if (FAILED(Symbol->get_virtualBaseTableType(&TableType)) || !TableType)
@@ -729,7 +730,7 @@ DIARawSymbol::getVirtualBaseTableType() const {
auto RawVT = llvm::make_unique<DIARawSymbol>(Session, TableType);
auto Pointer =
llvm::make_unique<PDBSymbolTypePointer>(Session, std::move(RawVT));
- return unique_dyn_cast<PDBSymbolTypeVTable>(Pointer->getPointeeType());
+ return unique_dyn_cast<PDBSymbolTypeBuiltin>(Pointer->getPointeeType());
}
PDB_DataKind DIARawSymbol::getDataKind() const {
diff --git a/lib/DebugInfo/PDB/DIA/DIASession.cpp b/lib/DebugInfo/PDB/DIA/DIASession.cpp
index 6ecf335812b5..ef47b92b4f2f 100644
--- a/lib/DebugInfo/PDB/DIA/DIASession.cpp
+++ b/lib/DebugInfo/PDB/DIA/DIASession.cpp
@@ -21,12 +21,22 @@
#include "llvm/DebugInfo/PDB/PDBSymbolExe.h"
#include "llvm/Support/ConvertUTF.h"
#include "llvm/Support/Format.h"
+#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
using namespace llvm::pdb;
-static Error ErrorFromHResult(HRESULT Result, StringRef Context) {
+template <typename... Ts>
+static Error ErrorFromHResult(HRESULT Result, const char *Str, Ts &&... Args) {
+ SmallString<64> MessageStorage;
+ StringRef Context;
+ if (sizeof...(Args) > 0) {
+ MessageStorage = formatv(Str, std::forward<Ts>(Args)...).str();
+ Context = MessageStorage;
+ } else
+ Context = Str;
+
switch (Result) {
case E_PDB_NOT_FOUND:
return make_error<GenericError>(generic_error_code::invalid_path, Context);
@@ -95,8 +105,9 @@ Error DIASession::createFromPdb(StringRef Path,
const wchar_t *Path16Str = reinterpret_cast<const wchar_t*>(Path16.data());
HRESULT HR;
- if (FAILED(HR = DiaDataSource->loadDataFromPdb(Path16Str)))
- return ErrorFromHResult(HR, "Calling loadDataFromPdb");
+ if (FAILED(HR = DiaDataSource->loadDataFromPdb(Path16Str))) {
+ return ErrorFromHResult(HR, "Calling loadDataFromPdb {0}", Path);
+ }
if (FAILED(HR = DiaDataSource->openSession(&DiaSession)))
return ErrorFromHResult(HR, "Calling openSession");
diff --git a/lib/DebugInfo/PDB/Native/ModStream.cpp b/lib/DebugInfo/PDB/Native/ModStream.cpp
index 08798cf0ed28..e87e2c407593 100644
--- a/lib/DebugInfo/PDB/Native/ModStream.cpp
+++ b/lib/DebugInfo/PDB/Native/ModStream.cpp
@@ -82,4 +82,8 @@ ModStream::lines(bool *HadError) const {
return make_range(LineInfo.begin(HadError), LineInfo.end());
}
+bool ModStream::hasLineInfo() const {
+ return C13LinesSubstream.getLength() > 0 || LinesSubstream.getLength() > 0;
+}
+
Error ModStream::commit() { return Error::success(); }
diff --git a/lib/DebugInfo/PDB/Native/NativeRawSymbol.cpp b/lib/DebugInfo/PDB/Native/NativeRawSymbol.cpp
index 3aba35adb53f..70968d4330b0 100644
--- a/lib/DebugInfo/PDB/Native/NativeRawSymbol.cpp
+++ b/lib/DebugInfo/PDB/Native/NativeRawSymbol.cpp
@@ -13,6 +13,7 @@
#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
#include "llvm/DebugInfo/PDB/PDBExtras.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeVTable.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeVTableShape.h"
#include "llvm/Support/ConvertUTF.h"
@@ -320,7 +321,7 @@ uint32_t NativeRawSymbol::getVirtualTableShapeId() const {
return 0;
}
-std::unique_ptr<PDBSymbolTypeVTable>
+std::unique_ptr<PDBSymbolTypeBuiltin>
NativeRawSymbol::getVirtualBaseTableType() const {
return nullptr;
}
diff --git a/lib/DebugInfo/PDB/UDTLayout.cpp b/lib/DebugInfo/PDB/UDTLayout.cpp
index 61cef093d4ce..aacefae80c3a 100644
--- a/lib/DebugInfo/PDB/UDTLayout.cpp
+++ b/lib/DebugInfo/PDB/UDTLayout.cpp
@@ -16,6 +16,7 @@
#include "llvm/DebugInfo/PDB/PDBSymbolExe.h"
#include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypePointer.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeVTable.h"
@@ -39,36 +40,47 @@ static uint32_t getTypeLength(const PDBSymbol &Symbol) {
return RawType.getLength();
}
-StorageItemBase::StorageItemBase(const UDTLayoutBase &Parent,
- const PDBSymbol &Symbol,
- const std::string &Name,
- uint32_t OffsetInParent, uint32_t Size)
- : Parent(Parent), Symbol(Symbol), Name(Name),
- OffsetInParent(OffsetInParent), SizeOf(Size) {
+LayoutItemBase::LayoutItemBase(const UDTLayoutBase *Parent,
+ const PDBSymbol *Symbol, const std::string &Name,
+ uint32_t OffsetInParent, uint32_t Size,
+ bool IsElided)
+ : Symbol(Symbol), Parent(Parent), Name(Name),
+ OffsetInParent(OffsetInParent), SizeOf(Size), LayoutSize(Size),
+ IsElided(IsElided) {
UsedBytes.resize(SizeOf, true);
}
-uint32_t StorageItemBase::deepPaddingSize() const {
- // sizeof(Field) - sizeof(typeof(Field)) is trailing padding.
- return SizeOf - getTypeLength(Symbol);
+uint32_t LayoutItemBase::deepPaddingSize() const {
+ return UsedBytes.size() - UsedBytes.count();
+}
+
+uint32_t LayoutItemBase::tailPadding() const {
+ int Last = UsedBytes.find_last();
+
+ return UsedBytes.size() - (Last + 1);
}
DataMemberLayoutItem::DataMemberLayoutItem(
- const UDTLayoutBase &Parent, std::unique_ptr<PDBSymbolData> DataMember)
- : StorageItemBase(Parent, *DataMember, DataMember->getName(),
- DataMember->getOffset(), getTypeLength(*DataMember)),
- DataMember(std::move(DataMember)) {
- auto Type = this->DataMember->getType();
+ const UDTLayoutBase &Parent, std::unique_ptr<PDBSymbolData> Member)
+ : LayoutItemBase(&Parent, Member.get(), Member->getName(),
+ Member->getOffset(), getTypeLength(*Member), false),
+ DataMember(std::move(Member)) {
+ auto Type = DataMember->getType();
if (auto UDT = unique_dyn_cast<PDBSymbolTypeUDT>(Type)) {
- // UDT data members might have padding in between fields, but otherwise
- // a member should occupy its entire storage.
- UsedBytes.resize(SizeOf, false);
UdtLayout = llvm::make_unique<ClassLayout>(std::move(UDT));
+ UsedBytes = UdtLayout->usedBytes();
}
}
+VBPtrLayoutItem::VBPtrLayoutItem(const UDTLayoutBase &Parent,
+ std::unique_ptr<PDBSymbolTypeBuiltin> Sym,
+ uint32_t Offset, uint32_t Size)
+ : LayoutItemBase(&Parent, Sym.get(), "<vbptr>", Offset, Size, false),
+ Type(std::move(Sym)) {
+}
+
const PDBSymbolData &DataMemberLayoutItem::getDataMember() {
- return *dyn_cast<PDBSymbolData>(&Symbol);
+ return *dyn_cast<PDBSymbolData>(Symbol);
}
bool DataMemberLayoutItem::hasUDTLayout() const { return UdtLayout != nullptr; }
@@ -77,60 +89,73 @@ const ClassLayout &DataMemberLayoutItem::getUDTLayout() const {
return *UdtLayout;
}
-uint32_t DataMemberLayoutItem::deepPaddingSize() const {
- uint32_t Result = StorageItemBase::deepPaddingSize();
- if (UdtLayout)
- Result += UdtLayout->deepPaddingSize();
- return Result;
-}
-
VTableLayoutItem::VTableLayoutItem(const UDTLayoutBase &Parent,
- std::unique_ptr<PDBSymbolTypeVTable> VTable)
- : StorageItemBase(Parent, *VTable, "<vtbl>", 0, getTypeLength(*VTable)),
- VTable(std::move(VTable)) {
- auto VTableType = cast<PDBSymbolTypePointer>(this->VTable->getType());
+ std::unique_ptr<PDBSymbolTypeVTable> VT)
+ : LayoutItemBase(&Parent, VT.get(), "<vtbl>", 0, getTypeLength(*VT), false),
+ VTable(std::move(VT)) {
+ auto VTableType = cast<PDBSymbolTypePointer>(VTable->getType());
ElementSize = VTableType->getLength();
+}
- Shape =
- unique_dyn_cast<PDBSymbolTypeVTableShape>(VTableType->getPointeeType());
- if (Shape)
- VTableFuncs.resize(Shape->getCount());
+UDTLayoutBase::UDTLayoutBase(const UDTLayoutBase *Parent, const PDBSymbol &Sym,
+ const std::string &Name, uint32_t OffsetInParent,
+ uint32_t Size, bool IsElided)
+ : LayoutItemBase(Parent, &Sym, Name, OffsetInParent, Size, IsElided) {
+ // UDT storage comes from a union of all the children's storage, so start out
+ // uninitialized.
+ UsedBytes.reset(0, Size);
+
+ initializeChildren(Sym);
+ if (LayoutSize < Size)
+ UsedBytes.resize(LayoutSize);
}
-UDTLayoutBase::UDTLayoutBase(const PDBSymbol &Symbol, const std::string &Name,
- uint32_t Size)
- : SymbolBase(Symbol), Name(Name), SizeOf(Size) {
- UsedBytes.resize(Size);
- ChildrenPerByte.resize(Size);
- initializeChildren(Symbol);
+uint32_t UDTLayoutBase::tailPadding() const {
+ uint32_t Abs = LayoutItemBase::tailPadding();
+ if (!LayoutItems.empty()) {
+ const LayoutItemBase *Back = LayoutItems.back();
+ uint32_t ChildPadding = Back->LayoutItemBase::tailPadding();
+ if (Abs < ChildPadding)
+ Abs = 0;
+ else
+ Abs -= ChildPadding;
+ }
+ return Abs;
}
ClassLayout::ClassLayout(const PDBSymbolTypeUDT &UDT)
- : UDTLayoutBase(UDT, UDT.getName(), UDT.getLength()), UDT(UDT) {}
+ : UDTLayoutBase(nullptr, UDT, UDT.getName(), 0, UDT.getLength(), false),
+ UDT(UDT) {
+ ImmediateUsedBytes.resize(SizeOf, false);
+ for (auto &LI : LayoutItems) {
+ uint32_t Begin = LI->getOffsetInParent();
+ uint32_t End = Begin + LI->getLayoutSize();
+ End = std::min(SizeOf, End);
+ ImmediateUsedBytes.set(Begin, End);
+ }
+}
ClassLayout::ClassLayout(std::unique_ptr<PDBSymbolTypeUDT> UDT)
: ClassLayout(*UDT) {
OwnedStorage = std::move(UDT);
}
-BaseClassLayout::BaseClassLayout(const UDTLayoutBase &Parent,
- std::unique_ptr<PDBSymbolTypeBaseClass> Base)
- : UDTLayoutBase(*Base, Base->getName(), Base->getLength()),
- StorageItemBase(Parent, *Base, Base->getName(), Base->getOffset(),
- Base->getLength()),
- Base(std::move(Base)) {
- IsVirtualBase = this->Base->isVirtualBaseClass();
-}
-
-uint32_t UDTLayoutBase::shallowPaddingSize() const {
- return UsedBytes.size() - UsedBytes.count();
+uint32_t ClassLayout::immediatePadding() const {
+ return SizeOf - ImmediateUsedBytes.count();
}
-uint32_t UDTLayoutBase::deepPaddingSize() const {
- uint32_t Result = shallowPaddingSize();
- for (auto &Child : ChildStorage)
- Result += Child->deepPaddingSize();
- return Result;
+BaseClassLayout::BaseClassLayout(const UDTLayoutBase &Parent,
+ uint32_t OffsetInParent, bool Elide,
+ std::unique_ptr<PDBSymbolTypeBaseClass> B)
+ : UDTLayoutBase(&Parent, *B, B->getName(), OffsetInParent, B->getLength(),
+ Elide),
+ Base(std::move(B)) {
+ if (isEmptyBase()) {
+ // Special case an empty base so that it doesn't get treated as padding.
+ UsedBytes.resize(1);
+ UsedBytes.set(0);
+ }
+ IsVirtualBase = Base->isVirtualBaseClass();
}
void UDTLayoutBase::initializeChildren(const PDBSymbol &Sym) {
@@ -138,15 +163,16 @@ void UDTLayoutBase::initializeChildren(const PDBSymbol &Sym) {
// followed by functions, followed by other. This ordering is necessary
// so that bases and vtables get initialized before any functions which
// may override them.
-
UniquePtrVector<PDBSymbolTypeBaseClass> Bases;
UniquePtrVector<PDBSymbolTypeVTable> VTables;
UniquePtrVector<PDBSymbolData> Members;
+ UniquePtrVector<PDBSymbolTypeBaseClass> VirtualBaseSyms;
+
auto Children = Sym.findAllChildren();
while (auto Child = Children->getNext()) {
if (auto Base = unique_dyn_cast<PDBSymbolTypeBaseClass>(Child)) {
if (Base->isVirtualBaseClass())
- VirtualBases.push_back(std::move(Base));
+ VirtualBaseSyms.push_back(std::move(Base));
else
Bases.push_back(std::move(Base));
}
@@ -164,20 +190,33 @@ void UDTLayoutBase::initializeChildren(const PDBSymbol &Sym) {
Other.push_back(std::move(Child));
}
+ // We don't want to have any re-allocations in the list of bases, so make
+ // sure to reserve enough space so that our ArrayRefs don't get invalidated.
+ AllBases.reserve(Bases.size() + VirtualBaseSyms.size());
+
+ // Only add non-virtual bases to the class first. Only at the end of the
+ // class, after all non-virtual bases and data members have been added do we
+ // add virtual bases. This way the offsets are correctly aligned when we go
+ // to lay out virtual bases.
for (auto &Base : Bases) {
- auto BL = llvm::make_unique<BaseClassLayout>(*this, std::move(Base));
- BaseClasses.push_back(BL.get());
+ uint32_t Offset = Base->getOffset();
+ // Non-virtual bases never get elided.
+ auto BL = llvm::make_unique<BaseClassLayout>(*this, Offset, false,
+ std::move(Base));
+ AllBases.push_back(BL.get());
addChildToLayout(std::move(BL));
}
+ NonVirtualBases = AllBases;
- for (auto &VT : VTables) {
- auto VTLayout = llvm::make_unique<VTableLayoutItem>(*this, std::move(VT));
+ assert(VTables.size() <= 1);
+ if (!VTables.empty()) {
+ auto VTLayout =
+ llvm::make_unique<VTableLayoutItem>(*this, std::move(VTables[0]));
VTable = VTLayout.get();
addChildToLayout(std::move(VTLayout));
- continue;
}
for (auto &Data : Members) {
@@ -186,150 +225,74 @@ void UDTLayoutBase::initializeChildren(const PDBSymbol &Sym) {
addChildToLayout(std::move(DM));
}
- for (auto &Func : Funcs) {
- if (!Func->isVirtual())
- continue;
+ // Make sure add virtual bases before adding functions, since functions may be
+ // overrides of virtual functions declared in a virtual base, so the VTables
+ // and virtual intros need to be correctly initialized.
+ for (auto &VB : VirtualBaseSyms) {
+ int VBPO = VB->getVirtualBasePointerOffset();
+ if (!hasVBPtrAtOffset(VBPO)) {
+ if (auto VBP = VB->getRawSymbol().getVirtualBaseTableType()) {
+ auto VBPL = llvm::make_unique<VBPtrLayoutItem>(*this, std::move(VBP),
+ VBPO, VBP->getLength());
+ VBPtr = VBPL.get();
+ addChildToLayout(std::move(VBPL));
+ }
+ }
- if (Func->isIntroVirtualFunction())
- addVirtualIntro(*Func);
- else
- addVirtualOverride(*Func);
+ // Virtual bases always go at the end. So just look for the last place we
+ // ended when writing something, and put our virtual base there.
+ // Note that virtual bases get elided unless this is a top-most derived
+ // class.
+ uint32_t Offset = UsedBytes.find_last() + 1;
+ bool Elide = (Parent != nullptr);
+ auto BL =
+ llvm::make_unique<BaseClassLayout>(*this, Offset, Elide, std::move(VB));
+ AllBases.push_back(BL.get());
+
+ // Only lay this virtual base out directly inside of *this* class if this
+ // is a top-most derived class. Keep track of it regardless, but only
+ // physically lay it out if it's a topmost derived class.
+ addChildToLayout(std::move(BL));
}
+ VirtualBases = makeArrayRef(AllBases).drop_front(NonVirtualBases.size());
+
+ if (Parent != nullptr)
+ LayoutSize = UsedBytes.find_last() + 1;
}
-void UDTLayoutBase::addVirtualIntro(PDBSymbolFunc &Func) {
- // Kind of a hack, but we prefer the more common destructor name that people
- // are familiar with, e.g. ~ClassName. It seems there are always both and
- // the vector deleting destructor overwrites the nice destructor, so just
- // ignore the vector deleting destructor.
- if (Func.getName() == "__vecDelDtor")
- return;
-
- if (!VTable) {
- // FIXME: Handle this. What's most likely happening is we have an intro
- // virtual in a derived class where the base also has an intro virtual.
- // In this case the vtable lives in the base. What we really need is
- // for each UDTLayoutBase to contain a list of all its vtables, and
- // then propagate this list up the hierarchy so that derived classes have
- // direct access to their bases' vtables.
- return;
+bool UDTLayoutBase::hasVBPtrAtOffset(uint32_t Off) const {
+ if (VBPtr && VBPtr->getOffsetInParent() == Off)
+ return true;
+ for (BaseClassLayout *BL : AllBases) {
+ if (BL->hasVBPtrAtOffset(Off - BL->getOffsetInParent()))
+ return true;
}
-
- uint32_t Stride = VTable->getElementSize();
-
- uint32_t Index = Func.getVirtualBaseOffset();
- assert(Index % Stride == 0);