aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore4
-rwxr-xr-xautoconf/config.guess3
-rw-r--r--bindings/python/llvm/object.py11
-rwxr-xr-xcmake/modules/AddLLVM.cmake31
-rw-r--r--docs/ExceptionHandling.rst12
-rw-r--r--docs/LangRef.rst827
-rw-r--r--docs/ProgrammersManual.rst2
-rw-r--r--docs/StackMaps.rst10
-rw-r--r--include/llvm-c/Core.h14
-rw-r--r--include/llvm-c/Object.h1
-rw-r--r--include/llvm-c/lto.h5
-rw-r--r--include/llvm/ADT/APFloat.h4
-rw-r--r--include/llvm/ADT/Triple.h16
-rw-r--r--include/llvm/ADT/edit_distance.h45
-rw-r--r--include/llvm/Analysis/AliasAnalysis.h12
-rw-r--r--include/llvm/Analysis/ConstantFolding.h11
-rw-r--r--include/llvm/Analysis/DominanceFrontier.h4
-rw-r--r--include/llvm/Analysis/IVUsers.h7
-rw-r--r--include/llvm/Analysis/InstructionSimplify.h20
-rw-r--r--include/llvm/Analysis/JumpInstrTableInfo.h71
-rw-r--r--include/llvm/Analysis/LibCallSemantics.h12
-rw-r--r--include/llvm/Analysis/LoopAccessAnalysis.h201
-rw-r--r--include/llvm/Analysis/LoopInfo.h8
-rw-r--r--include/llvm/Analysis/RegionInfo.h6
-rw-r--r--include/llvm/Analysis/TargetTransformInfo.h8
-rw-r--r--include/llvm/Analysis/TargetTransformInfoImpl.h48
-rw-r--r--include/llvm/Analysis/VectorUtils.h28
-rw-r--r--include/llvm/Bitcode/LLVMBitCodes.h1
-rw-r--r--include/llvm/Bitcode/ReaderWriter.h2
-rw-r--r--include/llvm/CodeGen/Analysis.h2
-rw-r--r--include/llvm/CodeGen/BasicTTIImpl.h56
-rw-r--r--include/llvm/CodeGen/CommandFlags.h4
-rw-r--r--include/llvm/CodeGen/ISDOpcodes.h13
-rw-r--r--include/llvm/CodeGen/LiveIntervalUnion.h5
-rw-r--r--include/llvm/CodeGen/LiveRegMatrix.h5
-rw-r--r--include/llvm/CodeGen/MIRYamlMapping.h163
-rw-r--r--include/llvm/CodeGen/MachineConstantPool.h9
-rw-r--r--include/llvm/CodeGen/MachineDominators.h4
-rw-r--r--include/llvm/CodeGen/MachineFrameInfo.h22
-rw-r--r--include/llvm/CodeGen/MachineFunction.h3
-rw-r--r--include/llvm/CodeGen/MachineLoopInfo.h9
-rw-r--r--include/llvm/CodeGen/MachineModuleInfo.h1
-rw-r--r--include/llvm/CodeGen/MachineRegionInfo.h7
-rw-r--r--include/llvm/CodeGen/MachineRegisterInfo.h61
-rw-r--r--include/llvm/CodeGen/Passes.h32
-rw-r--r--include/llvm/CodeGen/RegisterPressure.h2
-rw-r--r--include/llvm/CodeGen/SelectionDAG.h9
-rw-r--r--include/llvm/CodeGen/SelectionDAGNodes.h16
-rw-r--r--include/llvm/CodeGen/StackMaps.h58
-rw-r--r--include/llvm/CodeGen/WinEHFuncInfo.h4
-rw-r--r--include/llvm/ExecutionEngine/ExecutionEngine.h9
-rw-r--r--include/llvm/ExecutionEngine/RuntimeDyld.h4
-rw-r--r--include/llvm/IR/Attributes.h2
-rw-r--r--include/llvm/IR/CallSite.h9
-rw-r--r--include/llvm/IR/DIBuilder.h633
-rw-r--r--include/llvm/IR/DebugInfoMetadata.h20
-rw-r--r--include/llvm/IR/Dominators.h20
-rw-r--r--include/llvm/IR/Function.h10
-rw-r--r--include/llvm/IR/GlobalValue.h13
-rw-r--r--include/llvm/IR/IRBuilder.h77
-rw-r--r--include/llvm/IR/Instruction.h2
-rw-r--r--include/llvm/IR/Instructions.h26
-rw-r--r--include/llvm/IR/Intrinsics.td19
-rw-r--r--include/llvm/IR/IntrinsicsPowerPC.td15
-rw-r--r--include/llvm/IR/IntrinsicsWebAssembly.td16
-rw-r--r--include/llvm/IR/IntrinsicsX86.td29
-rw-r--r--include/llvm/IR/Operator.h3
-rw-r--r--include/llvm/IR/Value.h4
-rw-r--r--include/llvm/InitializePasses.h2
-rw-r--r--include/llvm/LinkAllPasses.h1
-rw-r--r--include/llvm/MC/MCContext.h2
-rw-r--r--include/llvm/MC/MCDwarf.h27
-rw-r--r--include/llvm/MC/MCInstrDesc.h5
-rw-r--r--include/llvm/MC/MCSchedule.h22
-rw-r--r--include/llvm/MC/MCSubtargetInfo.h43
-rw-r--r--include/llvm/MC/MCSymbol.h4
-rw-r--r--include/llvm/MC/MCSymbolMachO.h2
-rw-r--r--include/llvm/MC/MCTargetOptions.h2
-rw-r--r--include/llvm/Object/Archive.h11
-rw-r--r--include/llvm/Object/ArchiveWriter.h4
-rw-r--r--include/llvm/Object/COFF.h8
-rw-r--r--include/llvm/Object/ELF.h101
-rw-r--r--include/llvm/Object/ELFObjectFile.h58
-rw-r--r--include/llvm/Object/ELFTypes.h18
-rw-r--r--include/llvm/Object/ELFYAML.h16
-rw-r--r--include/llvm/Object/MachO.h9
-rw-r--r--include/llvm/Object/ObjectFile.h19
-rw-r--r--include/llvm/Object/RelocVisitor.h15
-rw-r--r--include/llvm/Object/SymbolicFile.h2
-rw-r--r--include/llvm/Support/COFF.h1
-rw-r--r--include/llvm/Support/CommandLine.h28
-rw-r--r--include/llvm/Support/Compiler.h13
-rw-r--r--include/llvm/Support/OnDiskHashTable.h16
-rw-r--r--include/llvm/Support/TargetRegistry.h44
-rw-r--r--include/llvm/Support/raw_ostream.h6
-rw-r--r--include/llvm/TableGen/Record.h6
-rw-r--r--include/llvm/Target/Target.td4
-rw-r--r--include/llvm/Target/TargetFrameLowering.h17
-rw-r--r--include/llvm/Target/TargetLowering.h75
-rw-r--r--include/llvm/Target/TargetMachine.h8
-rw-r--r--include/llvm/Target/TargetOpcodes.h8
-rw-r--r--include/llvm/Target/TargetSelectionDAGInfo.h9
-rw-r--r--include/llvm/Target/TargetSubtargetInfo.h10
-rw-r--r--include/llvm/Transforms/IPO.h6
-rw-r--r--include/llvm/Transforms/IPO/PassManagerBuilder.h1
-rw-r--r--include/llvm/Transforms/Utils/Cloning.h16
-rw-r--r--include/llvm/Transforms/Utils/LoopVersioning.h100
-rw-r--r--lib/Analysis/AliasAnalysis.cpp5
-rw-r--r--lib/Analysis/AliasDebugger.cpp4
-rw-r--r--lib/Analysis/AliasSetTracker.cpp3
-rw-r--r--lib/Analysis/BasicAliasAnalysis.cpp6
-rw-r--r--lib/Analysis/ConstantFolding.cpp6
-rw-r--r--lib/Analysis/IPA/GlobalsModRef.cpp320
-rw-r--r--lib/Analysis/IPA/InlineCost.cpp6
-rw-r--r--lib/Analysis/IVUsers.cpp17
-rw-r--r--lib/Analysis/InstructionSimplify.cpp114
-rw-r--r--lib/Analysis/LoopAccessAnalysis.cpp447
-rw-r--r--lib/Analysis/NoAliasAnalysis.cpp1
-rw-r--r--lib/Analysis/TargetTransformInfo.cpp6
-rw-r--r--lib/Analysis/ValueTracking.cpp2
-rw-r--r--lib/Analysis/VectorUtils.cpp198
-rw-r--r--lib/AsmParser/LLLexer.cpp1
-rw-r--r--lib/AsmParser/LLParser.cpp98
-rw-r--r--lib/AsmParser/LLToken.h1
-rw-r--r--lib/Bitcode/Reader/BitcodeReader.cpp75
-rw-r--r--lib/Bitcode/Writer/BitcodeWriter.cpp8
-rw-r--r--lib/CodeGen/Analysis.cpp35
-rw-r--r--lib/CodeGen/AsmPrinter/ARMException.cpp38
-rw-r--r--lib/CodeGen/AsmPrinter/AsmPrinter.cpp5
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfCFIException.cpp28
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfDebug.h225
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfUnit.h74
-rw-r--r--lib/CodeGen/AsmPrinter/EHStreamer.cpp2
-rw-r--r--lib/CodeGen/AsmPrinter/WinCodeViewLineTables.cpp30
-rw-r--r--lib/CodeGen/AsmPrinter/WinCodeViewLineTables.h8
-rw-r--r--lib/CodeGen/AsmPrinter/WinException.cpp32
-rw-r--r--lib/CodeGen/BasicTargetTransformInfo.cpp3
-rw-r--r--lib/CodeGen/CodeGenPrepare.cpp146
-rw-r--r--lib/CodeGen/DeadMachineInstructionElim.cpp2
-rw-r--r--lib/CodeGen/ExecutionDepsFix.cpp12
-rw-r--r--lib/CodeGen/GlobalMerge.cpp29
-rw-r--r--lib/CodeGen/ImplicitNullChecks.cpp93
-rw-r--r--lib/CodeGen/LLVMTargetMachine.cpp18
-rw-r--r--lib/CodeGen/LiveRegMatrix.cpp12
-rw-r--r--lib/CodeGen/MIRParser/MILexer.cpp30
-rw-r--r--lib/CodeGen/MIRParser/MILexer.h21
-rw-r--r--lib/CodeGen/MIRParser/MIParser.cpp269
-rw-r--r--lib/CodeGen/MIRParser/MIParser.h16
-rw-r--r--lib/CodeGen/MIRParser/MIRParser.cpp164
-rw-r--r--lib/CodeGen/MIRPrinter.cpp165
-rw-r--r--lib/CodeGen/MachineDominators.cpp4
-rw-r--r--lib/CodeGen/MachineFunction.cpp40
-rw-r--r--lib/CodeGen/MachineModuleInfo.cpp3
-rw-r--r--lib/CodeGen/MachineRegisterInfo.cpp48
-rw-r--r--lib/CodeGen/MachineTraceMetrics.cpp47
-rw-r--r--lib/CodeGen/Passes.cpp12
-rw-r--r--lib/CodeGen/PrologEpilogInserter.cpp57
-rw-r--r--lib/CodeGen/RegAllocFast.cpp14
-rw-r--r--lib/CodeGen/RegAllocGreedy.cpp42
-rw-r--r--lib/CodeGen/RegisterPressure.cpp12
-rw-r--r--lib/CodeGen/SelectionDAG/DAGCombiner.cpp145
-rw-r--r--lib/CodeGen/SelectionDAG/FastISel.cpp36
-rw-r--r--lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp25
-rw-r--r--lib/CodeGen/SelectionDAG/InstrEmitter.cpp4
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeDAG.cpp263
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp30
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp123
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeTypes.cpp8
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeTypes.h6
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp43
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp37
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp198
-rw-r--r--lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp5
-rw-r--r--lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp10
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAG.cpp193
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp555
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h6
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp2
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp50
-rw-r--r--lib/CodeGen/SelectionDAG/StatepointLowering.cpp6
-rw-r--r--lib/CodeGen/SelectionDAG/TargetLowering.cpp178
-rw-r--r--lib/CodeGen/SelectionDAG/TargetSelectionDAGInfo.cpp4
-rw-r--r--lib/CodeGen/SjLjEHPrepare.cpp14
-rw-r--r--lib/CodeGen/StackMapLivenessAnalysis.cpp45
-rw-r--r--lib/CodeGen/StackMaps.cpp165
-rw-r--r--lib/CodeGen/StackProtector.cpp2
-rw-r--r--lib/CodeGen/TargetFrameLoweringImpl.cpp30
-rw-r--r--lib/CodeGen/TargetLoweringBase.cpp49
-rw-r--r--lib/CodeGen/TwoAddressInstructionPass.cpp8
-rw-r--r--lib/CodeGen/VirtRegMap.cpp73
-rw-r--r--lib/CodeGen/WinEHPrepare.cpp75
-rw-r--r--lib/DebugInfo/DWARF/DWARFContext.cpp8
-rw-r--r--lib/ExecutionEngine/IntelJITEvents/CMakeLists.txt4
-rw-r--r--lib/ExecutionEngine/IntelJITEvents/IntelJITEventListener.cpp108
-rw-r--r--lib/ExecutionEngine/IntelJITEvents/LLVMBuild.txt2
-rw-r--r--lib/ExecutionEngine/OProfileJIT/LLVMBuild.txt1
-rw-r--r--lib/ExecutionEngine/OProfileJIT/OProfileJITEventListener.cpp43
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp46
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp4
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp61
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp14
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h1
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOAArch64.h2
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOARM.h2
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOI386.h2
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOX86_64.h2
-rw-r--r--lib/IR/Attributes.cpp8
-rw-r--r--lib/IR/AutoUpgrade.cpp17
-rw-r--r--lib/IR/BasicBlock.cpp51
-rw-r--r--lib/IR/Core.cpp8
-rw-r--r--lib/IR/DIBuilder.cpp58
-rw-r--r--lib/IR/Dominators.cpp20
-rw-r--r--lib/IR/Value.cpp2
-rw-r--r--lib/IR/Verifier.cpp58
-rw-r--r--lib/LTO/LTOModule.cpp3
-rw-r--r--lib/LibDriver/LibDriver.cpp19
-rw-r--r--lib/MC/CMakeLists.txt1
-rw-r--r--lib/MC/MCAsmStreamer.cpp3
-rw-r--r--lib/MC/MCAssembler.cpp2
-rw-r--r--lib/MC/MCDisassembler/MCExternalSymbolizer.cpp6
-rw-r--r--lib/MC/MCInstrDesc.cpp2
-rw-r--r--lib/MC/MCSchedule.cpp34
-rw-r--r--lib/MC/MCSubtargetInfo.cpp49
-rw-r--r--lib/MC/MCSymbol.cpp3
-rw-r--r--lib/Object/Archive.cpp49
-rw-r--r--lib/Object/ArchiveWriter.cpp211
-rw-r--r--lib/Object/COFFObjectFile.cpp36
-rw-r--r--lib/Object/ELFYAML.cpp10
-rw-r--r--lib/Object/MachOObjectFile.cpp43
-rw-r--r--lib/Object/Object.cpp15
-rw-r--r--lib/Object/ObjectFile.cpp9
-rw-r--r--lib/Support/APFloat.cpp23
-rw-r--r--lib/Support/CommandLine.cpp30
-rw-r--r--lib/Support/Triple.cpp116
-rw-r--r--lib/TableGen/Record.cpp2
-rw-r--r--lib/TableGen/SetTheory.cpp2
-rw-r--r--lib/TableGen/TGParser.cpp2
-rw-r--r--lib/Target/AArch64/AArch64A57FPLoadBalancing.cpp15
-rw-r--r--lib/Target/AArch64/AArch64CallingConvention.td5
-rw-r--r--lib/Target/AArch64/AArch64FastISel.cpp43
-rw-r--r--lib/Target/AArch64/AArch64FrameLowering.cpp39
-rw-r--r--lib/Target/AArch64/AArch64FrameLowering.h4
-rw-r--r--lib/Target/AArch64/AArch64ISelDAGToDAG.cpp50
-rw-r--r--lib/Target/AArch64/AArch64ISelLowering.cpp189
-rw-r--r--lib/Target/AArch64/AArch64ISelLowering.h21
-rw-r--r--lib/Target/AArch64/AArch64InstrInfo.td11
-rw-r--r--lib/Target/AArch64/AArch64RegisterInfo.cpp20
-rw-r--r--lib/Target/AArch64/AArch64SelectionDAGInfo.cpp9
-rw-r--r--lib/Target/AArch64/AArch64SelectionDAGInfo.h2
-rw-r--r--lib/Target/AArch64/AArch64Subtarget.cpp12
-rw-r--r--lib/Target/AArch64/AArch64TargetTransformInfo.cpp16
-rw-r--r--lib/Target/AArch64/AArch64TargetTransformInfo.h24
-rw-r--r--lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp2
-rw-r--r--lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp2
-rw-r--r--lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.cpp15
-rw-r--r--lib/Target/AMDGPU/AMDGPU.td10
-rw-r--r--lib/Target/AMDGPU/AMDGPUAlwaysInlinePass.cpp11
-rw-r--r--lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp34
-rw-r--r--lib/Target/AMDGPU/AMDGPUISelLowering.cpp129
-rw-r--r--lib/Target/AMDGPU/AMDGPUISelLowering.h13
-rw-r--r--lib/Target/AMDGPU/AMDGPUSubtarget.cpp1
-rw-r--r--lib/Target/AMDGPU/AMDGPUSubtarget.h5
-rw-r--r--lib/Target/AMDGPU/AMDGPUTargetMachine.cpp9
-rw-r--r--lib/Target/AMDGPU/AMDGPUTargetTransformInfo.h17
-rw-r--r--lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCTargetDesc.cpp13
-rw-r--r--lib/Target/AMDGPU/R600ISelLowering.cpp31
-rw-r--r--lib/Target/AMDGPU/R600ISelLowering.h4
-rw-r--r--lib/Target/AMDGPU/SIFoldOperands.cpp31
-rw-r--r--lib/Target/AMDGPU/SIISelLowering.cpp57
-rw-r--r--lib/Target/AMDGPU/SIISelLowering.h15
-rw-r--r--lib/Target/AMDGPU/SIInstrInfo.cpp64
-rw-r--r--lib/Target/AMDGPU/SIInstrInfo.h4
-rw-r--r--lib/Target/AMDGPU/SIInstrInfo.td9
-rw-r--r--lib/Target/AMDGPU/SIInstructions.td14
-rw-r--r--lib/Target/AMDGPU/SILoadStoreOptimizer.cpp44
-rw-r--r--lib/Target/AMDGPU/SIMachineFunctionInfo.cpp1
-rw-r--r--lib/Target/AMDGPU/SIPrepareScratchRegs.cpp1
-rw-r--r--lib/Target/AMDGPU/SIRegisterInfo.cpp2
-rw-r--r--lib/Target/AMDGPU/SIShrinkInstructions.cpp39
-rw-r--r--lib/Target/ARM/ARM.td4
-rw-r--r--lib/Target/ARM/ARMBaseInstrInfo.cpp3
-rw-r--r--lib/Target/ARM/ARMBaseRegisterInfo.cpp20
-rw-r--r--lib/Target/ARM/ARMCallingConv.td3
-rw-r--r--lib/Target/ARM/ARMFastISel.cpp45
-rw-r--r--lib/Target/ARM/ARMFrameLowering.cpp43
-rw-r--r--lib/Target/ARM/ARMFrameLowering.h4
-rw-r--r--lib/Target/ARM/ARMISelDAGToDAG.cpp47
-rw-r--r--lib/Target/ARM/ARMISelLowering.cpp328
-rw-r--r--lib/Target/ARM/ARMISelLowering.h20
-rw-r--r--lib/Target/ARM/ARMInstrInfo.td4
-rw-r--r--lib/Target/ARM/ARMLoadStoreOptimizer.cpp1453
-rw-r--r--lib/Target/ARM/ARMSelectionDAGInfo.cpp22
-rw-r--r--lib/Target/ARM/ARMSelectionDAGInfo.h2
-rw-r--r--lib/Target/ARM/ARMSubtarget.cpp38
-rw-r--r--lib/Target/ARM/ARMSubtarget.h4
-rw-r--r--lib/Target/ARM/ARMTargetMachine.cpp7
-rw-r--r--lib/Target/ARM/ARMTargetTransformInfo.cpp24
-rw-r--r--lib/Target/ARM/ARMTargetTransformInfo.h15
-rw-r--r--lib/Target/ARM/AsmParser/ARMAsmParser.cpp166
-rw-r--r--lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp2
-rw-r--r--lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp23
-rw-r--r--lib/Target/ARM/Thumb1FrameLowering.cpp2
-rw-r--r--lib/Target/BPF/BPFFrameLowering.cpp16
-rw-r--r--lib/Target/BPF/BPFFrameLowering.h4
-rw-r--r--lib/Target/BPF/BPFISelLowering.cpp11
-rw-r--r--lib/Target/BPF/BPFSubtarget.cpp2
-rw-r--r--lib/Target/BPF/MCTargetDesc/BPFMCTargetDesc.cpp8
-rw-r--r--lib/Target/CppBackend/CPPBackend.cpp4
-rw-r--r--lib/Target/CppBackend/CPPTargetMachine.h3
-rw-r--r--lib/Target/Hexagon/BitTracker.cpp1127
-rw-r--r--lib/Target/Hexagon/BitTracker.h449
-rw-r--r--lib/Target/Hexagon/CMakeLists.txt6
-rw-r--r--lib/Target/Hexagon/HexagonBitTracker.cpp1174
-rw-r--r--lib/Target/Hexagon/HexagonBitTracker.h64
-rw-r--r--lib/Target/Hexagon/HexagonCommonGEP.cpp1325
-rw-r--r--lib/Target/Hexagon/HexagonExpandCondsets.cpp9
-rw-r--r--lib/Target/Hexagon/HexagonFrameLowering.cpp15
-rw-r--r--lib/Target/Hexagon/HexagonFrameLowering.h2
-rw-r--r--lib/Target/Hexagon/HexagonGenExtract.cpp259
-rw-r--r--lib/Target/Hexagon/HexagonGenInsert.cpp1598
-rw-r--r--lib/Target/Hexagon/HexagonGenPredicate.cpp525
-rw-r--r--lib/Target/Hexagon/HexagonISelLowering.cpp83
-rw-r--r--lib/Target/Hexagon/HexagonISelLowering.h29
-rw-r--r--lib/Target/Hexagon/HexagonRegisterInfo.cpp5
-rw-r--r--lib/Target/Hexagon/HexagonSelectionDAGInfo.cpp6
-rw-r--r--lib/Target/Hexagon/HexagonSelectionDAGInfo.h2
-rw-r--r--lib/Target/Hexagon/HexagonSubtarget.cpp2
-rw-r--r--lib/Target/Hexagon/HexagonTargetMachine.cpp56
-rw-r--r--lib/Target/Hexagon/LLVMBuild.txt1
-rw-r--r--lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp9
-rw-r--r--lib/Target/MSP430/CMakeLists.txt1
-rw-r--r--lib/Target/MSP430/MCTargetDesc/MSP430MCTargetDesc.cpp9
-rw-r--r--lib/Target/MSP430/MSP430ISelDAGToDAG.cpp9
-rw-r--r--lib/Target/MSP430/MSP430ISelLowering.cpp74
-rw-r--r--lib/Target/MSP430/MSP430ISelLowering.h9
-rw-r--r--lib/Target/MSP430/MSP430RegisterInfo.cpp9
-rw-r--r--lib/Target/MSP430/MSP430SelectionDAGInfo.cpp23
-rw-r--r--lib/Target/MSP430/MSP430SelectionDAGInfo.h31
-rw-r--r--lib/Target/MSP430/MSP430Subtarget.cpp3
-rw-r--r--lib/Target/MSP430/MSP430Subtarget.h6
-rw-r--r--lib/Target/Mips/AsmParser/MipsAsmParser.cpp167
-rw-r--r--lib/Target/Mips/CMakeLists.txt1
-rw-r--r--lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp8
-rw-r--r--lib/Target/Mips/Mips16FrameLowering.cpp11
-rw-r--r--lib/Target/Mips/Mips16FrameLowering.h4
-rw-r--r--lib/Target/Mips/Mips16ISelDAGToDAG.cpp10
-rw-r--r--lib/Target/Mips/Mips16ISelLowering.cpp3
-rw-r--r--lib/Target/Mips/MipsFastISel.cpp38
-rw-r--r--lib/Target/Mips/MipsISelDAGToDAG.cpp5
-rw-r--r--lib/Target/Mips/MipsISelLowering.cpp91
-rw-r--r--lib/Target/Mips/MipsISelLowering.h24
-rw-r--r--lib/Target/Mips/MipsSEFrameLowering.cpp19
-rw-r--r--lib/Target/Mips/MipsSEFrameLowering.h4
-rw-r--r--lib/Target/Mips/MipsSEISelDAGToDAG.cpp2
-rw-r--r--lib/Target/Mips/MipsSEISelLowering.cpp5
-rw-r--r--lib/Target/Mips/MipsSelectionDAGInfo.cpp23
-rw-r--r--lib/Target/Mips/MipsSelectionDAGInfo.h31
-rw-r--r--lib/Target/Mips/MipsSubtarget.cpp2
-rw-r--r--lib/Target/Mips/MipsSubtarget.h6
-rw-r--r--lib/Target/Mips/MipsTargetMachine.cpp4
-rw-r--r--lib/Target/NVPTX/MCTargetDesc/NVPTXMCTargetDesc.cpp12
-rw-r--r--lib/Target/NVPTX/NVPTXAsmPrinter.cpp14
-rw-r--r--lib/Target/NVPTX/NVPTXISelLowering.cpp202
-rw-r--r--lib/Target/NVPTX/NVPTXISelLowering.h17
-rw-r--r--lib/Target/NVPTX/NVPTXLowerAggrCopies.cpp32
-rw-r--r--lib/Target/NVPTX/NVPTXReplaceImageHandles.cpp4
-rw-r--r--lib/Target/NVPTX/NVPTXSubtarget.cpp2
-rw-r--r--lib/Target/NVPTX/NVPTXTargetMachine.cpp5
-rw-r--r--lib/Target/NVPTX/NVPTXTargetTransformInfo.cpp14
-rw-r--r--lib/Target/NVPTX/NVPTXTargetTransformInfo.h19
-rw-r--r--lib/Target/PowerPC/CMakeLists.txt1
-rw-r--r--lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp23
-rw-r--r--lib/Target/PowerPC/PPCAsmPrinter.cpp50
-rw-r--r--lib/Target/PowerPC/PPCCTRLoops.cpp5
-rw-r--r--lib/Target/PowerPC/PPCCallingConv.td3
-rw-r--r--lib/Target/PowerPC/PPCFastISel.cpp37
-rw-r--r--lib/Target/PowerPC/PPCFrameLowering.cpp20
-rw-r--r--lib/Target/PowerPC/PPCFrameLowering.h4
-rw-r--r--lib/Target/PowerPC/PPCISelDAGToDAG.cpp43
-rw-r--r--lib/Target/PowerPC/PPCISelLowering.cpp260
-rw-r--r--lib/Target/PowerPC/PPCISelLowering.h29
-rw-r--r--lib/Target/PowerPC/PPCInstrInfo.cpp33
-rw-r--r--lib/Target/PowerPC/PPCInstrInfo.h4
-rw-r--r--lib/Target/PowerPC/PPCInstrVSX.td15
-rw-r--r--lib/Target/PowerPC/PPCRegisterInfo.cpp28
-rw-r--r--lib/Target/PowerPC/PPCScheduleP7.td4
-rw-r--r--lib/Target/PowerPC/PPCScheduleP8.td4
-rw-r--r--lib/Target/PowerPC/PPCSelectionDAGInfo.cpp22
-rw-r--r--lib/Target/PowerPC/PPCSelectionDAGInfo.h31
-rw-r--r--lib/Target/PowerPC/PPCSubtarget.cpp2
-rw-r--r--lib/Target/PowerPC/PPCSubtarget.h6
-rw-r--r--lib/Target/PowerPC/PPCTargetMachine.cpp21
-rw-r--r--lib/Target/PowerPC/PPCTargetMachine.h2
-rw-r--r--lib/Target/PowerPC/PPCTargetTransformInfo.cpp2
-rw-r--r--lib/Target/PowerPC/PPCTargetTransformInfo.h15
-rw-r--r--lib/Target/PowerPC/PPCVSXFMAMutate.cpp10
-rw-r--r--lib/Target/PowerPC/PPCVSXSwapRemoval.cpp209
-rw-r--r--lib/Target/Sparc/CMakeLists.txt1
-rw-r--r--lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp12
-rw-r--r--lib/Target/Sparc/SparcFrameLowering.cpp26
-rw-r--r--lib/Target/Sparc/SparcFrameLowering.h4
-rw-r--r--lib/Target/Sparc/SparcISelDAGToDAG.cpp31
-rw-r--r--lib/Target/Sparc/SparcISelLowering.cpp93
-rw-r--r--lib/Target/Sparc/SparcISelLowering.h12
-rw-r--r--lib/Target/Sparc/SparcInstrAliases.td135
-rw-r--r--lib/Target/Sparc/SparcInstrInfo.cpp9
-rw-r--r--lib/Target/Sparc/SparcInstrInfo.td19
-rw-r--r--lib/Target/Sparc/SparcRegisterInfo.td4
-rw-r--r--lib/Target/Sparc/SparcSelectionDAGInfo.cpp24
-rw-r--r--lib/Target/Sparc/SparcSelectionDAGInfo.h31
-rw-r--r--lib/Target/Sparc/SparcSubtarget.cpp2
-rw-r--r--lib/Target/Sparc/SparcSubtarget.h6
-rw-r--r--lib/Target/SystemZ/MCTargetDesc/SystemZMCTargetDesc.cpp9
-rw-r--r--lib/Target/SystemZ/SystemZFrameLowering.cpp19
-rw-r--r--lib/Target/SystemZ/SystemZFrameLowering.h4
-rw-r--r--lib/Target/SystemZ/SystemZISelLowering.cpp52
-rw-r--r--lib/Target/SystemZ/SystemZISelLowering.h17
-rw-r--r--lib/Target/SystemZ/SystemZRegisterInfo.cpp6
-rw-r--r--lib/Target/SystemZ/SystemZSelectionDAGInfo.cpp6
-rw-r--r--lib/Target/SystemZ/SystemZSelectionDAGInfo.h3
-rw-r--r--lib/Target/SystemZ/SystemZSubtarget.cpp2
-rw-r--r--lib/Target/SystemZ/SystemZTargetTransformInfo.h15
-rw-r--r--lib/Target/TargetMachine.cpp5
-rw-r--r--lib/Target/TargetSubtargetInfo.cpp9
-rw-r--r--lib/Target/WebAssembly/CMakeLists.txt1
-rw-r--r--lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.cpp3
-rw-r--r--lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h3
-rw-r--r--lib/Target/WebAssembly/Makefile3
-rw-r--r--lib/Target/WebAssembly/README.txt11
-rw-r--r--lib/Target/WebAssembly/WebAssemblyISelLowering.cpp2
-rw-r--r--lib/Target/WebAssembly/WebAssemblyInstrAtomics.td7
-rw-r--r--lib/Target/WebAssembly/WebAssemblyInstrCall.td21
-rw-r--r--lib/Target/WebAssembly/WebAssemblyInstrConv.td44
-rw-r--r--lib/Target/WebAssembly/WebAssemblyInstrFloat.td44
-rw-r--r--lib/Target/WebAssembly/WebAssemblyInstrFormats.td33
-rw-r--r--lib/Target/WebAssembly/WebAssemblyInstrInfo.td19
-rw-r--r--lib/Target/WebAssembly/WebAssemblyInstrInteger.td45
-rw-r--r--lib/Target/WebAssembly/WebAssemblyInstrMemory.td46
-rw-r--r--lib/Target/WebAssembly/WebAssemblyInstrSIMD.td7
-rw-r--r--lib/Target/WebAssembly/WebAssemblyRegisterInfo.cpp56
-rw-r--r--lib/Target/WebAssembly/WebAssemblyRegisterInfo.h19
-rw-r--r--lib/Target/WebAssembly/WebAssemblyRegisterInfo.td34
-rw-r--r--lib/Target/WebAssembly/WebAssemblySelectionDAGInfo.cpp3
-rw-r--r--lib/Target/WebAssembly/WebAssemblySelectionDAGInfo.h1
-rw-r--r--lib/Target/WebAssembly/WebAssemblySubtarget.cpp4
-rw-r--r--lib/Target/WebAssembly/WebAssemblyTargetTransformInfo.h24
-rw-r--r--lib/Target/X86/InstPrinter/X86InstComments.cpp23
-rw-r--r--lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp1
-rw-r--r--lib/Target/X86/MCTargetDesc/X86ELFRelocationInfo.cpp6
-rw-r--r--lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp32
-rw-r--r--lib/Target/X86/MCTargetDesc/X86MachORelocationInfo.cpp5
-rw-r--r--lib/Target/X86/Utils/X86ShuffleDecode.cpp82
-rw-r--r--lib/Target/X86/Utils/X86ShuffleDecode.h8
-rw-r--r--lib/Target/X86/X86FastISel.cpp69
-rw-r--r--lib/Target/X86/X86FloatingPoint.cpp3
-rw-r--r--lib/Target/X86/X86FrameLowering.cpp29
-rw-r--r--lib/Target/X86/X86FrameLowering.h4
-rw-r--r--lib/Target/X86/X86ISelDAGToDAG.cpp13
-rw-r--r--lib/Target/X86/X86ISelLowering.cpp940
-rw-r--r--lib/Target/X86/X86ISelLowering.h47
-rw-r--r--lib/Target/X86/X86InstrAVX512.td541
-rw-r--r--lib/Target/X86/X86InstrControl.td6
-rw-r--r--lib/Target/X86/X86InstrFragmentsSIMD.td83
-rw-r--r--lib/Target/X86/X86InstrInfo.cpp106
-rw-r--r--lib/Target/X86/X86InstrInfo.td14
-rw-r--r--lib/Target/X86/X86InstrSSE.td65
-rw-r--r--lib/Target/X86/X86IntrinsicsInfo.h157
-rw-r--r--lib/Target/X86/X86MachineFunctionInfo.h83
-rw-r--r--lib/Target/X86/X86RegisterInfo.cpp21
-rw-r--r--lib/Target/X86/X86SelectionDAGInfo.cpp12
-rw-r--r--lib/Target/X86/X86SelectionDAGInfo.h3
-rw-r--r--lib/Target/X86/X86Subtarget.cpp21
-rw-r--r--lib/Target/X86/X86Subtarget.h22
-rw-r--r--lib/Target/X86/X86TargetTransformInfo.cpp37
-rw-r--r--lib/Target/X86/X86TargetTransformInfo.h15
-rw-r--r--lib/Target/X86/X86WinEHState.cpp31
-rw-r--r--lib/Target/XCore/MCTargetDesc/XCoreMCTargetDesc.cpp9
-rw-r--r--lib/Target/XCore/XCoreFrameLowering.cpp13
-rw-r--r--lib/Target/XCore/XCoreFrameLowering.h4
-rw-r--r--lib/Target/XCore/XCoreISelDAGToDAG.cpp7
-rw-r--r--lib/Target/XCore/XCoreISelLowering.cpp97
-rw-r--r--lib/Target/XCore/XCoreISelLowering.h11
-rw-r--r--lib/Target/XCore/XCoreRegisterInfo.cpp8
-rw-r--r--lib/Target/XCore/XCoreSelectionDAGInfo.cpp22
-rw-r--r--lib/Target/XCore/XCoreSelectionDAGInfo.h2
-rw-r--r--lib/Target/XCore/XCoreSubtarget.cpp2
-rw-r--r--lib/Target/XCore/XCoreTargetMachine.cpp5
-rw-r--r--lib/Target/XCore/XCoreTargetTransformInfo.h17
-rw-r--r--lib/Transforms/IPO/ArgumentPromotion.cpp2
-rw-r--r--lib/Transforms/IPO/CMakeLists.txt1
-rw-r--r--lib/Transforms/IPO/DeadArgumentElimination.cpp26
-rw-r--r--lib/Transforms/IPO/ElimAvailExtern.cpp84
-rw-r--r--lib/Transforms/IPO/ExtractGV.cpp10
-rw-r--r--lib/Transforms/IPO/IPO.cpp1
-rw-r--r--lib/Transforms/IPO/PassManagerBuilder.cpp16
-rw-r--r--lib/Transforms/InstCombine/InstCombineCompares.cpp4
-rw-r--r--lib/Transforms/InstCombine/InstCombineInternal.h8
-rw-r--r--lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp17
-rw-r--r--lib/Transforms/InstCombine/InstCombineVectorOps.cpp67
-rw-r--r--lib/Transforms/InstCombine/InstructionCombining.cpp29
-rw-r--r--lib/Transforms/Scalar/GVN.cpp13
-rw-r--r--lib/Transforms/Scalar/IndVarSimplify.cpp56
-rw-r--r--lib/Transforms/Scalar/LICM.cpp13
-rw-r--r--lib/Transforms/Scalar/LoopDistribute.cpp193
-rw-r--r--lib/Transforms/Scalar/LoopIdiomRecognize.cpp2
-rw-r--r--lib/Transforms/Scalar/LoopInterchange.cpp12
-rw-r--r--lib/Transforms/Scalar/LoopUnrollPass.cpp6
-rw-r--r--lib/Transforms/Scalar/MergedLoadStoreMotion.cpp8
-rw-r--r--lib/Transforms/Scalar/PlaceSafepoints.cpp4
-rw-r--r--lib/Transforms/Scalar/SCCP.cpp3
-rw-r--r--lib/Transforms/Scalar/SROA.cpp21
-rw-r--r--lib/Transforms/Utils/BasicBlockUtils.cpp2
-rw-r--r--lib/Transforms/Utils/CMakeLists.txt1
-rw-r--r--lib/Transforms/Utils/CloneFunction.cpp66
-rw-r--r--lib/Transforms/Utils/Local.cpp11
-rw-r--r--lib/Transforms/Utils/LoopSimplify.cpp1
-rw-r--r--lib/Transforms/Utils/LoopVersioning.cpp106
-rw-r--r--lib/Transforms/Vectorize/LoopVectorize.cpp474
-rw-r--r--lib/Transforms/Vectorize/SLPVectorizer.cpp102
-rw-r--r--test/Analysis/BasicAA/modref.ll45
-rw-r--r--test/Analysis/CostModel/X86/testshiftashr.ll56
-rw-r--r--test/Analysis/CostModel/X86/testshiftlshr.ll24
-rw-r--r--test/Analysis/LoopAccessAnalysis/number-of-memchecks.ll236
-rw-r--r--test/Analysis/LoopAccessAnalysis/pointer-with-unknown-bounds.ll42
-rw-r--r--test/Analysis/LoopAccessAnalysis/resort-to-memchecks-only.ll2
-rw-r--r--test/Analysis/LoopAccessAnalysis/unsafe-and-rt-checks.ll6
-rw-r--r--test/Assembler/getelementptr_vec_idx1.ll4
-rw-r--r--test/Assembler/getelementptr_vec_idx2.ll22
-rw-r--r--test/Assembler/getelementptr_vec_idx3.ll4
-rw-r--r--test/Bitcode/attributes.ll11
-rw-r--r--test/Bitcode/fcmp-fast.ll23
-rw-r--r--test/CodeGen/AArch64/aarch64-dynamic-stack-layout.ll60
-rw-r--r--test/CodeGen/AArch64/arm64-nvcast.ll29
-rw-r--r--test/CodeGen/AArch64/arm64-shrink-wrapping.ll39
-rw-r--r--test/CodeGen/AArch64/nest-register.ll23
-rw-r--r--test/CodeGen/AArch64/xbfiz.ll33
-rw-r--r--test/CodeGen/AMDGPU/array-ptr-calc-i64.ll5
-rw-r--r--test/CodeGen/AMDGPU/ds-negative-offset-addressing-mode-loop.ll5
-rw-r--r--test/CodeGen/AMDGPU/ds_read2.ll4
-rw-r--r--test/CodeGen/AMDGPU/ds_read2_offset_order.ll15
-rw-r--r--test/CodeGen/AMDGPU/ds_read2_superreg.ll246
-rw-r--r--test/CodeGen/AMDGPU/ds_read2st64.ll2
-rw-r--r--test/CodeGen/AMDGPU/ds_write2.ll17
-rw-r--r--test/CodeGen/AMDGPU/ds_write2st64.ll4
-rw-r--r--test/CodeGen/AMDGPU/fmuladd.ll30
-rw-r--r--test/CodeGen/AMDGPU/invariant-load-no-alias-store.ll35
-rw-r--r--test/CodeGen/AMDGPU/llvm.amdgpu.lrp.ll2
-rw-r--r--test/CodeGen/AMDGPU/llvm.round.ll4
-rw-r--r--test/CodeGen/AMDGPU/mad-combine.ll25
-rw-r--r--test/CodeGen/AMDGPU/mad-sub.ll6
-rw-r--r--test/CodeGen/AMDGPU/madak.ll12
-rw-r--r--test/CodeGen/AMDGPU/madmk.ll10
-rw-r--r--test/CodeGen/AMDGPU/mul_uint24.ll20
-rw-r--r--test/CodeGen/AMDGPU/select-vectors.ll116
-rw-r--r--test/CodeGen/AMDGPU/select64.ll4
-rw-r--r--test/CodeGen/AMDGPU/shl.ll38
-rw-r--r--test/CodeGen/AMDGPU/sint_to_fp.f64.ll8
-rw-r--r--test/CodeGen/AMDGPU/srl.ll35
-rw-r--r--test/CodeGen/AMDGPU/uint_to_fp.f64.ll10
-rw-r--r--test/CodeGen/AMDGPU/v_mac.ll155
-rw-r--r--test/CodeGen/AMDGPU/vselect.ll34
-rw-r--r--test/CodeGen/AMDGPU/xor.ll4
-rw-r--r--test/CodeGen/ARM/2013-05-02-AAPCS-ByVal-Structs-C4-C5-VFP.ll3
-rw-r--r--test/CodeGen/ARM/2013-05-13-AAPCS-byval-padding2.ll4
-rw-r--r--test/CodeGen/ARM/Windows/hard-float.ll10
-rw-r--r--test/CodeGen/ARM/Windows/long-calls.ll2
-rw-r--r--test/CodeGen/ARM/Windows/no-arm-mode.ll9
-rw-r--r--test/CodeGen/ARM/Windows/pic.ll17
-rw-r--r--test/CodeGen/ARM/Windows/structors.ll12
-rw-r--r--test/CodeGen/ARM/Windows/trivial-gnu-object.ll10
-rw-r--r--test/CodeGen/ARM/arm-returnaddr.ll6
-rw-r--r--test/CodeGen/ARM/byval-align.ll3
-rw-r--r--test/CodeGen/ARM/cttz.ll90
-rw-r--r--test/CodeGen/ARM/cttz_vector.ll383
-rw-r--r--test/CodeGen/ARM/ctz.ll11
-rw-r--r--test/CodeGen/ARM/fast-isel-call.ll6
-rw-r--r--test/CodeGen/ARM/fast-isel-intrinsic.ll6
-rw-r--r--test/CodeGen/ARM/fast-isel-static.ll4
-rw-r--r--test/CodeGen/ARM/ldrd.ll69
-rw-r--r--test/CodeGen/ARM/memset-inline.ll3
-rw-r--r--test/CodeGen/ARM/nest-register.ll21
-rw-r--r--test/CodeGen/ARM/subtarget-features-long-calls.ll49
-rw-r--r--test/CodeGen/ARM/wrong-t2stmia-size-opt.ll16
-rw-r--r--test/CodeGen/Generic/run-pass.ll7
-rw-r--r--test/CodeGen/Hexagon/Atomics.ll71
-rw-r--r--test/CodeGen/Hexagon/common-gep-basic.ll37
-rw-r--r--test/CodeGen/Hexagon/common-gep-icm.ll76
-rw-r--r--test/CodeGen/Hexagon/extract-basic.ll76
-rw-r--r--test/CodeGen/Hexagon/fusedandshift.ll3
-rw-r--r--test/CodeGen/Hexagon/insert-basic.ll66
-rw-r--r--test/CodeGen/Hexagon/predicate-logical.ll30
-rw-r--r--test/CodeGen/Hexagon/predicate-rcmp.ll19
-rw-r--r--test/CodeGen/MIR/X86/basic-block-liveins.mir25
-rw-r--r--test/CodeGen/MIR/X86/dead-register-flag.mir26
-rw-r--r--test/CodeGen/MIR/X86/expected-different-implicit-operand.mir38
-rw-r--r--test/CodeGen/MIR/X86/expected-different-implicit-register-flag.mir38
-rw-r--r--test/CodeGen/MIR/X86/expected-named-register-livein.mir21
-rw-r--r--test/CodeGen/MIR/X86/expected-number-after-bb.mir6
-rw-r--r--test/CodeGen/MIR/X86/expected-register-after-flags.mir22
-rw-r--r--test/CodeGen/MIR/X86/expected-subregister-after-colon.mir29
-rw-r--r--test/CodeGen/MIR/X86/fixed-stack-objects.mir35
-rw-r--r--test/CodeGen/MIR/X86/global-value-operands.mir4
-rw-r--r--test/CodeGen/MIR/X86/implicit-register-flag.mir41
-rw-r--r--test/CodeGen/MIR/X86/killed-register-flag.mir42
-rw-r--r--test/CodeGen/MIR/X86/large-index-number-error.mir6
-rw-r--r--test/CodeGen/MIR/X86/machine-basic-block-operands.mir12
-rw-r--r--test/CodeGen/MIR/X86/machine-instructions.mir4
-rw-r--r--test/CodeGen/MIR/X86/missing-implicit-operand.mir40
-rw-r--r--test/CodeGen/MIR/X86/named-registers.mir2
-rw-r--r--test/CodeGen/MIR/X86/register-mask-operands.mir10
-rw-r--r--test/CodeGen/MIR/X86/spill-slot-fixed-stack-object-aliased.mir32
-rw-r--r--test/CodeGen/MIR/X86/spill-slot-fixed-stack-object-immutable.mir32
-rw-r--r--test/CodeGen/MIR/X86/spill-slot-fixed-stack-objects.mir34
-rw-r--r--test/CodeGen/MIR/X86/stack-objects.mir39
-rw-r--r--test/CodeGen/MIR/X86/subregister-operands.mir33
-rw-r--r--test/CodeGen/MIR/X86/undef-register-flag.mir42
-rw-r--r--test/CodeGen/MIR/X86/undefined-register-class.mir26
-rw-r--r--test/CodeGen/MIR/X86/undefined-virtual-register.mir28
-rw-r--r--test/CodeGen/MIR/X86/unknown-machine-basic-block.mir6
-rw-r--r--test/CodeGen/MIR/X86/unknown-named-machine-basic-block.mir6
-rw-r--r--test/CodeGen/MIR/X86/unknown-subregister-index.mir31
-rw-r--r--test/CodeGen/MIR/X86/variable-sized-stack-object-size-error.mir36
-rw-r--r--test/CodeGen/MIR/X86/variable-sized-stack-objects.mir42
-rw-r--r--test/CodeGen/MIR/X86/virtual-registers.mir105
-rw-r--r--test/CodeGen/MIR/frame-info.mir91
-rw-r--r--test/CodeGen/MIR/llvmIR.mir2
-rw-r--r--test/CodeGen/MIR/llvmIRMissing.mir2
-rw-r--r--test/CodeGen/MIR/machine-basic-block-unknown-name.mir2
-rw-r--r--test/CodeGen/MIR/machine-function-missing-body-error.mir15
-rw-r--r--test/CodeGen/MIR/machine-function-missing-function.mir4
-rw-r--r--test/CodeGen/MIR/machine-function-missing-name.mir4
-rw-r--r--test/CodeGen/MIR/machine-function.mir8
-rw-r--r--test/CodeGen/MIR/register-info.mir4
-rw-r--r--test/CodeGen/NVPTX/loop-vectorize.ll39
-rw-r--r--test/CodeGen/NVPTX/lower-aggr-copies.ll47
-rw-r--r--test/CodeGen/PowerPC/builtins-ppc-elf2-abi.ll30
-rw-r--r--test/CodeGen/PowerPC/ppc-crbits-onoff.ll4
-rw-r--r--test/CodeGen/PowerPC/ppc32-nest.ll26
-rw-r--r--test/CodeGen/PowerPC/ppc64-anyregcc.ll16
-rw-r--r--test/CodeGen/PowerPC/ppc64-fastcc-fast-isel.ll6
-rw-r--r--test/CodeGen/PowerPC/ppc64-fastcc.ll10
-rw-r--r--test/CodeGen/PowerPC/ppc64-nest.ll42
-rw-r--r--test/CodeGen/PowerPC/ppc64-patchpoint.ll20
-rw-r--r--test/CodeGen/PowerPC/ppc64-stackmap.ll14
-rw-r--r--test/CodeGen/PowerPC/recipest.ll15
-rw-r--r--test/CodeGen/PowerPC/sjlj.ll8
-rw-r--r--test/CodeGen/PowerPC/swaps-le-3.ll4
-rw-r--r--test/CodeGen/PowerPC/swaps-le-5.ll70
-rw-r--r--test/CodeGen/PowerPC/tls-store2.ll4
-rw-r--r--test/CodeGen/PowerPC/vsx-elementary-arith.ll31
-rw-r--r--test/CodeGen/PowerPC/vsx-fma-m.ll30
-rw-r--r--test/CodeGen/PowerPC/vsx-fma-sp.ll13
-rw-r--r--test/CodeGen/SPARC/basictest.ll2
-rw-r--r--test/CodeGen/SPARC/multiple-div.ll21
-rw-r--r--test/CodeGen/Thumb2/aapcs.ll6
-rw-r--r--test/CodeGen/WebAssembly/lit.local.cfg2
-rw-r--r--test/CodeGen/WinEH/cppeh-alloca-sink.ll8
-rw-r--r--test/CodeGen/WinEH/cppeh-catch-all-win32.ll86
-rw-r--r--test/CodeGen/WinEH/cppeh-catch-and-throw.ll4
-rw-r--r--test/CodeGen/WinEH/cppeh-catch-scalar.ll4
-rw-r--r--test/CodeGen/WinEH/cppeh-catch-unwind.ll8
-rw-r--r--test/CodeGen/WinEH/cppeh-frame-vars.ll12
-rw-r--r--test/CodeGen/WinEH/cppeh-inalloca.ll12
-rw-r--r--test/CodeGen/WinEH/cppeh-min-unwind.ll4
-rw-r--r--test/CodeGen/WinEH/cppeh-mixed-catch-and-cleanup.ll4
-rw-r--r--test/CodeGen/WinEH/cppeh-multi-catch.ll8
-rw-r--r--test/CodeGen/WinEH/cppeh-nested-1.ll6
-rw-r--r--test/CodeGen/WinEH/cppeh-nested-2.ll10
-rw-r--r--test/CodeGen/WinEH/cppeh-nested-3.ll10
-rw-r--r--test/CodeGen/WinEH/cppeh-nested-rethrow.ll4
-rw-r--r--test/CodeGen/WinEH/cppeh-nonalloca-frame-values.ll16
-rw-r--r--test/CodeGen/WinEH/cppeh-prepared-catch-reordered.ll9
-rw-r--r--test/CodeGen/WinEH/cppeh-prepared-catch.ll130
-rw-r--r--test/CodeGen/WinEH/cppeh-prepared-cleanups.ll14
-rw-r--r--test/CodeGen/WinEH/cppeh-shared-empty-catch.ll2
-rw-r--r--test/CodeGen/WinEH/cppeh-similar-catch-blocks.ll2
-rw-r--r--test/CodeGen/WinEH/cppeh-state-calc-1.ll10
-rw-r--r--test/CodeGen/WinEH/seh-exception-code.ll66
-rw-r--r--test/CodeGen/WinEH/seh-exception-code2.ll91
-rw-r--r--test/CodeGen/WinEH/seh-inlined-finally.ll18
-rw-r--r--test/CodeGen/WinEH/seh-outlined-finally-win32.ll172
-rw-r--r--test/CodeGen/WinEH/seh-outlined-finally.ll10
-rw-r--r--test/CodeGen/WinEH/seh-prepared-basic.ll6
-rw-r--r--test/CodeGen/WinEH/seh-simple.ll34
-rw-r--r--test/CodeGen/X86/avx-vperm2x128.ll20
-rw-r--r--test/CodeGen/X86/avx512-intrinsics.ll50
-rw-r--r--test/CodeGen/X86/avx512bw-intrinsics.ll41
-rw-r--r--test/CodeGen/X86/avx512bwvl-intrinsics.ll80
-rw-r--r--test/CodeGen/X86/cppeh-nounwind.ll35
-rw-r--r--test/CodeGen/X86/eh-nolandingpads.ll12
-rw-r--r--test/CodeGen/X86/fdiv-combine.ll21
-rw-r--r--test/CodeGen/X86/frameescape.ll12
-rw-r--r--test/CodeGen/X86/frameregister.ll30
-rw-r--r--test/CodeGen/X86/implicit-null-check-negative.ll42
-rw-r--r--test/CodeGen/X86/implicit-null-check.ll44
-rw-r--r--test/CodeGen/X86/inline-asm-bad-constraint-n.ll10
-rw-r--r--test/CodeGen/X86/legalize-shl-vec.ll44
-rw-r--r--test/CodeGen/X86/machine-combiner.ll197
-rw-r--r--test/CodeGen/X86/pr13577.ll17
-rw-r--r--test/CodeGen/X86/read-fp-no-frame-pointer.ll12
-rw-r--r--test/CodeGen/X86/seh-catch-all-win32.ll26
-rw-r--r--test/CodeGen/X86/seh-except-finally.ll6
-rw-r--r--test/CodeGen/X86/seh-stack-realign-win32.ll99
-rw-r--r--test/CodeGen/X86/seh-stack-realign.ll101
-rw-r--r--test/CodeGen/X86/sqrt-fastmath.ll8
-rw-r--r--test/CodeGen/X86/sse2-vector-shifts.ll2
-rw-r--r--test/CodeGen/X86/sse3.ll2
-rw-r--r--test/CodeGen/X86/stack-folding-fp-avx1.ll18
-rw-r--r--test/CodeGen/X86/stack-folding-fp-sse42.ll38
-rw-r--r--test/CodeGen/X86/vec_fp_to_int.ll9
-rw-r--r--test/CodeGen/X86/vec_int_to_fp.ll145
-rw-r--r--test/CodeGen/X86/vector-gep.ll22
-rw-r--r--test/CodeGen/X86/vector-sext.ll28
-rw-r--r--test/CodeGen/X86/vector-shift-ashr-128.ll1284
-rw-r--r--test/CodeGen/X86/vector-shift-ashr-256.ll142
-rw-r--r--test/CodeGen/X86/vector-shift-lshr-128.ll791
-rw-r--r--test/CodeGen/X86/vector-shift-lshr-256.ll137
-rw-r--r--test/CodeGen/X86/vector-shift-shl-128.ll550
-rw-r--r--test/CodeGen/X86/vector-shift-shl-256.ll4
-rw-r--r--test/CodeGen/X86/vector-shuffle-sse4a.ll221
-rw-r--r--test/CodeGen/X86/vector-trunc.ll18
-rw-r--r--test/CodeGen/X86/vector-zext.ll80
-rw-r--r--test/CodeGen/X86/vector-zmov.ll34
-rw-r--r--test/CodeGen/X86/visibility.ll6
-rw-r--r--test/CodeGen/X86/vshift-3.ll5
-rw-r--r--test/CodeGen/X86/webkit-jscc.ll18
-rw-r--r--test/CodeGen/X86/widen_conv-2.ll7
-rw-r--r--test/CodeGen/X86/widen_load-2.ll14
-rw-r--r--test/CodeGen/X86/win32-eh.ll44
-rw-r--r--test/CodeGen/X86/win64_frame.ll5
-rw-r--r--test/CodeGen/X86/x86-shrink-wrapping.ll39
-rw-r--r--test/DebugInfo/COFF/asm.ll34
-rw-r--r--test/DebugInfo/COFF/multifile.ll42
-rw-r--r--test/DebugInfo/COFF/multifunction.ll138
-rw-r--r--test/DebugInfo/COFF/simple.ll26
-rw-r--r--test/ExecutionEngine/RuntimeDyld/Mips/ELF_O32R6_relocations.s49
-rw-r--r--test/ExecutionEngine/RuntimeDyld/Mips/ELF_O32_PIC_relocations.s5
-rw-r--r--test/ExecutionEngine/RuntimeDyld/X86/MachO_i386_DynNoPIC_relocations.s5
-rw-r--r--test/ExecutionEngine/RuntimeDyld/X86/MachO_x86-64_PIC_relocations.s13
-rw-r--r--test/LibDriver/infer-output-path.test15
-rw-r--r--test/MC/AArch64/basic-a64-instructions.s3
-rw-r--r--test/MC/ARM/basic-thumb2-instructions.s80
-rw-r--r--test/MC/ARM/thumb2-narrow-dp.ll93
-rw-r--r--test/MC/ARM/thumb_rewrites.s47
-rw-r--r--test/MC/COFF/safeseh.s6
-rw-r--r--test/MC/ELF/relax-arith.s8
-rw-r--r--test/MC/ELF/relax-arith2.s12
-rw-r--r--test/MC/ELF/relax-arith4.s25
-rw-r--r--test/MC/Mips/macro-la-bad.s17
-rw-r--r--test/MC/Mips/macro-la.s263
-rw-r--r--test/MC/Mips/macro-li-bad.s11
-rw-r--r--test/MC/Mips/macro-li.s67
-rw-r--r--test/MC/Mips/micromips-expansions.s6
-rw-r--r--test/MC/Mips/mips-expansions-bad.s12
-rw-r--r--test/MC/Mips/mips-expansions.s89
-rw-r--r--test/MC/Mips/mips64-expansions.s2
-rw-r--r--test/MC/Sparc/sparc-alu-instructions.s4
-rw-r--r--test/MC/Sparc/sparc-mem-instructions.s10
-rw-r--r--test/MC/Sparc/sparc-synthetic-instructions.s130
-rw-r--r--test/MC/X86/AlignedBundling/nesting.s26
-rw-r--r--test/MC/X86/avx512-encodings.s132
-rw-r--r--test/MC/X86/x86-64-avx512bw.s109
-rw-r--r--test/MC/X86/x86-64-avx512bw_vl.s216
-rw-r--r--test/MC/X86/x86-64-avx512dq.s517
-rw-r--r--test/MC/X86/x86-64-avx512dq_vl.s897
-rw-r--r--test/MC/X86/x86-64-avx512f_vl.s1119
-rw-r--r--test/MC/X86/x86_errors.s6
-rw-r--r--test/Object/Inputs/elf-mip64-reloc.obin0 -> 3208 bytes
-rw-r--r--test/Object/Inputs/invalid-bad-section-address.coffbin0 -> 304 bytes
-rw-r--r--test/Object/Inputs/no-section-table.sobin0 -> 2544 bytes
-rw-r--r--test/Object/Inputs/symtab-only.abin0 -> 72 bytes
-rw-r--r--test/Object/Inputs/thin-path.abin0 -> 284 bytes
-rw-r--r--test/Object/Inputs/trivial-object-test2.macho-x86-64bin0 -> 360 bytes
-rw-r--r--test/Object/Mips/elf-mips64-rel.yaml1
-rw-r--r--test/Object/Mips/reloc-visit.test6
-rw-r--r--test/Object/X86/nm-coff.s9
-rw-r--r--test/Object/X86/nm-macho.s9
-rw-r--r--test/Object/X86/nm-print-size.s6
-rw-r--r--test/Object/archive-extract.test (renamed from test/Object/extract.ll)17
-rw-r--r--test/Object/archive-format.test20
-rw-r--r--test/Object/archive-symtab.test35
-rw-r--r--test/Object/archive-toc.test10
-rw-r--r--test/Object/archive-update.test13
-rw-r--r--test/Object/coff-archive.test37
-rw-r--r--test/Object/coff-invalid.test13
-rw-r--r--test/Object/no-section-table.test36
-rw-r--r--test/Object/obj2yaml.test3
-rw-r--r--test/Object/yaml2obj-elf-alignment.yaml53
-rw-r--r--test/Object/yaml2obj-elf-rel-noref.yaml2
-rw-r--r--test/Object/yaml2obj-elf-rel.yaml4
-rw-r--r--test/Object/yaml2obj-elf-section-basic.yaml5
-rw-r--r--test/Object/yaml2obj-elf-symbol-basic.yaml1
-rw-r--r--test/Other/extract.ll7
-rw-r--r--test/Transforms/EliminateAvailableExternally/visibility.ll11
-rw-r--r--test/Transforms/GVN/pre-new-inst.ll29
-rw-r--r--test/Transforms/IndVarSimplify/lrev-existing-umin.ll36
-rw-r--r--test/Transforms/Inline/frameescape.ll12
-rw-r--r--test/Transforms/InstCombine/align-external.ll26
-rw-r--r--test/Transforms/InstCombine/intrinsics.ll22
-rw-r--r--test/Transforms/InstCombine/load-combine-metadata.ll29
-rw-r--r--test/Transforms/InstCombine/load_combine_aa.ll15
-rw-r--r--test/Transforms/InstSimplify/2011-09-05-InsertExtractValue.ll9
-rw-r--r--test/Transforms/InstSimplify/floating-point-compare.ll15
-rw-r--r--test/Transforms/InstSimplify/undef.ll14
-rw-r--r--test/Transforms/LICM/PR24013.ll19
-rw-r--r--test/Transforms/LoopDistribute/basic-with-memchecks.ll8
-rw-r--r--test/Transforms/LoopIdiom/ctpop-multiple-users-crash.ll34
-rw-r--r--test/Transforms/LoopRotate/oz-disable.ll30
-rw-r--r--test/Transforms/LoopStrengthReduce/ephemeral.ll41
-rw-r--r--test/Transforms/LoopUnroll/unroll-pragmas.ll27
-rw-r--r--test/Transforms/LoopVectorize/X86/vectorization-remarks.ll4
-rw-r--r--test/Transforms/PlaceSafepoints/statepoint-frameescape.ll8
-rw-r--r--test/Transforms/SLPVectorizer/AMDGPU/simplebb.ll5
-rw-r--r--test/Transforms/SLPVectorizer/X86/cse.ll31
-rw-r--r--test/Transforms/SLPVectorizer/X86/gep.ll1
-rw-r--r--test/Transforms/SLPVectorizer/X86/loopinvariant.ll18
-rw-r--r--test/Transforms/SLPVectorizer/X86/pr19657.ll102
-rw-r--r--test/Transforms/SROA/basictest.ll11
-rw-r--r--test/Verifier/comdat-decl1.ll5
-rw-r--r--test/Verifier/comdat-decl2.ll5
-rw-r--r--test/Verifier/frameescape.ll40
-rw-r--r--test/tools/llvm-objdump/macho-sections.test2
-rwxr-xr-xtest/tools/llvm-readobj/Inputs/got-plt.exe.elf-mipselbin0 -> 6209 bytes
-rw-r--r--test/tools/llvm-readobj/codeview-linetables.test10
-rw-r--r--test/tools/llvm-readobj/mips-plt.test34
-rw-r--r--tools/dsymutil/DebugMap.cpp4
-rw-r--r--tools/dsymutil/MachODebugMapParser.cpp16
-rw-r--r--tools/llc/llc.cpp39
-rw-r--r--tools/llvm-ar/llvm-ar.cpp101
-rw-r--r--tools/llvm-cxxdump/llvm-cxxdump.cpp5
-rw-r--r--tools/llvm-jitlistener/CMakeLists.txt6
-rw-r--r--tools/llvm-nm/llvm-nm.cpp104
-rw-r--r--tools/llvm-objdump/COFFDump.cpp4
-rw-r--r--tools/llvm-objdump/MachODump.cpp50
-rw-r--r--tools/llvm-objdump/llvm-objdump.cpp132
-rw-r--r--tools/llvm-objdump/llvm-objdump.h3
-rw-r--r--tools/llvm-readobj/ARMWinEHPrinter.cpp20
-rw-r--r--tools/llvm-readobj/COFFDumper.cpp29
-rw-r--r--tools/llvm-readobj/ELFDumper.cpp250
-rw-r--r--tools/llvm-readobj/ObjDumper.h1
-rw-r--r--tools/llvm-readobj/StreamWriter.h4
-rw-r--r--tools/llvm-readobj/Win64EHDumper.cpp4
-rw-r--r--tools/llvm-readobj/llvm-readobj.cpp10
-rw-r--r--tools/llvm-rtdyld/llvm-rtdyld.cpp77
-rw-r--r--tools/llvm-shlib/CMakeLists.txt2
-rw-r--r--tools/llvm-stress/llvm-stress.cpp95
-rw-r--r--tools/llvm-symbolizer/LLVMSymbolize.cpp6
-rw-r--r--tools/obj2yaml/elf2yaml.cpp20
-rw-r--r--tools/opt/opt.cpp1
-rw-r--r--tools/yaml2obj/yaml2elf.cpp28
-rw-r--r--unittests/ADT/TripleTest.cpp78
-rw-r--r--unittests/ExecutionEngine/MCJIT/MCJITTest.cpp82
-rw-r--r--unittests/IR/IRBuilderTest.cpp22
-rw-r--r--utils/TableGen/CodeGenTarget.cpp2
-rw-r--r--utils/TableGen/FixedLenDecoderEmitter.cpp2
-rw-r--r--utils/TableGen/RegisterInfoEmitter.cpp12
-rw-r--r--utils/TableGen/SubtargetEmitter.cpp15
-rw-r--r--utils/TableGen/X86DisassemblerTables.cpp26
-rwxr-xr-xutils/release/test-release.sh130
-rw-r--r--utils/unittest/UnitTestMain/TestMain.cpp5
860 files changed, 32133 insertions, 11025 deletions
diff --git a/.gitignore b/.gitignore
index f3424d231e2d..e3d191dcbcce 100644
--- a/.gitignore
+++ b/.gitignore
@@ -43,7 +43,9 @@ autoconf/autom4te.cache
# Directories to ignore (do not add trailing '/'s, they skip symlinks).
#==============================================================================#
# External projects that are tracked independently.
-projects/*/
+projects/*
+!projects/*.*
+!projects/Makefile
# Clang, which is tracked independently.
tools/clang
# LLDB, which is tracked independently.
diff --git a/autoconf/config.guess b/autoconf/config.guess
index 73d671bc2c6b..b209a1a06c6f 100755
--- a/autoconf/config.guess
+++ b/autoconf/config.guess
@@ -810,6 +810,9 @@ EOF
*:MINGW*:*)
echo ${UNAME_MACHINE}-pc-mingw32
exit ;;
+ *:MSYS*:*)
+ echo ${UNAME_MACHINE}-pc-msys
+ exit ;;
i*:windows32*:*)
# uname -m includes "-pc" on this system.
echo ${UNAME_MACHINE}-mingw32
diff --git a/bindings/python/llvm/object.py b/bindings/python/llvm/object.py
index 4e912ed5da9d..b427113e9cea 100644
--- a/bindings/python/llvm/object.py
+++ b/bindings/python/llvm/object.py
@@ -372,14 +372,6 @@ class Relocation(LLVMObject):
self.expired = False
@CachedProperty
- def address(self):
- """The address of this relocation, in long bytes."""
- if self.expired:
- raise Exception('Relocation instance has expired.')
-
- return lib.LLVMGetRelocationAddress(self)
-
- @CachedProperty
def offset(self):
"""The offset of this relocation, in long bytes."""
if self.expired:
@@ -498,9 +490,6 @@ def register_library(library):
library.LLVMGetSymbolSize.argtypes = [Symbol]
library.LLVMGetSymbolSize.restype = c_uint64
- library.LLVMGetRelocationAddress.argtypes = [c_object_p]
- library.LLVMGetRelocationAddress.restype = c_uint64
-
library.LLVMGetRelocationOffset.argtypes = [c_object_p]
library.LLVMGetRelocationOffset.restype = c_uint64
diff --git a/cmake/modules/AddLLVM.cmake b/cmake/modules/AddLLVM.cmake
index 4f60d9e6e7d6..45f6746948d2 100755
--- a/cmake/modules/AddLLVM.cmake
+++ b/cmake/modules/AddLLVM.cmake
@@ -93,20 +93,9 @@ function(add_llvm_symbol_exports target_name export_file)
else()
set(native_export_file "${target_name}.def")
- set(CAT "cat")
- set(export_file_nativeslashes ${export_file})
- if(WIN32 AND NOT CYGWIN AND NOT MSYS)
- set(CAT "type")
- # Convert ${export_file} to native format (backslashes) for "type"
- # Does not use file(TO_NATIVE_PATH) as it doesn't create a native
- # path but a build-system specific format (see CMake bug
- # http://public.kitware.com/Bug/print_bug_page.php?bug_id=5939 )
- string(REPLACE / \\ export_file_nativeslashes ${export_file})
- endif()
-
add_custom_command(OUTPUT ${native_export_file}
- COMMAND ${CMAKE_COMMAND} -E echo "EXPORTS" > ${native_export_file}
- COMMAND ${CAT} ${export_file_nativeslashes} >> ${native_export_file}
+ COMMAND ${PYTHON_EXECUTABLE} -c "import sys;print(''.join(['EXPORTS\\n']+sys.stdin.readlines(),))"
+ < ${export_file} > ${native_export_file}
DEPENDS ${export_file}
VERBATIM
COMMENT "Creating export file for ${target_name}")
@@ -700,10 +689,18 @@ macro(add_llvm_external_project name)
list(APPEND LLVM_IMPLICIT_PROJECT_IGNORE "${CMAKE_CURRENT_SOURCE_DIR}/${add_llvm_external_dir}")
string(REPLACE "-" "_" nameUNDERSCORE ${name})
string(TOUPPER ${nameUNDERSCORE} nameUPPER)
- set(LLVM_EXTERNAL_${nameUPPER}_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/${add_llvm_external_dir}"
- CACHE PATH "Path to ${name} source directory")
- if (NOT ${LLVM_EXTERNAL_${nameUPPER}_SOURCE_DIR} STREQUAL ""
- AND EXISTS ${LLVM_EXTERNAL_${nameUPPER}_SOURCE_DIR}/CMakeLists.txt)
+ #TODO: Remove this check in a few days once it has circulated through
+ # buildbots and people's checkouts (cbieneman - July 14, 2015)
+ if("${LLVM_EXTERNAL_${nameUPPER}_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}/${add_llvm_external_dir}")
+ unset(LLVM_EXTERNAL_${nameUPPER}_SOURCE_DIR CACHE)
+ endif()
+ if(NOT LLVM_EXTERNAL_${nameUPPER}_SOURCE_DIR)
+ set(LLVM_EXTERNAL_${nameUPPER}_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/${add_llvm_external_dir}")
+ else()
+ set(LLVM_EXTERNAL_${nameUPPER}_SOURCE_DIR
+ CACHE PATH "Path to ${name} source directory")
+ endif()
+ if (EXISTS ${LLVM_EXTERNAL_${nameUPPER}_SOURCE_DIR}/CMakeLists.txt)
option(LLVM_EXTERNAL_${nameUPPER}_BUILD
"Whether to build ${name} as part of LLVM" ON)
if (LLVM_EXTERNAL_${nameUPPER}_BUILD)
diff --git a/docs/ExceptionHandling.rst b/docs/ExceptionHandling.rst
index 72ed78a3c99a..55ffdb45efe9 100644
--- a/docs/ExceptionHandling.rst
+++ b/docs/ExceptionHandling.rst
@@ -339,11 +339,11 @@ original context before code generation.
Catch handlers are called with a pointer to the handler itself as the first
argument and a pointer to the parent function's stack frame as the second
-argument. The catch handler uses the `llvm.recoverframe
-<LangRef.html#llvm-frameallocate-and-llvm-framerecover-intrinsics>`_ to get a
+argument. The catch handler uses the `llvm.localrecover
+<LangRef.html#llvm-localescape-and-llvm-localrecover-intrinsics>`_ to get a
pointer to a frame allocation block that is created in the parent frame using
-the `llvm.allocateframe
-<LangRef.html#llvm-frameallocate-and-llvm-framerecover-intrinsics>`_ intrinsic.
+the `llvm.localescape
+<LangRef.html#llvm-localescape-and-llvm-localrecover-intrinsics>`_ intrinsic.
The ``WinEHPrepare`` pass will have created a structure definition for the
contents of this block. The first two members of the structure will always be
(1) a 32-bit integer that the runtime uses to track the exception state of the
@@ -520,12 +520,12 @@ action.
A code of ``i32 1`` indicates a catch action, which expects three additional
arguments. Different EH schemes give different meanings to the three arguments,
but the first argument indicates whether the catch should fire, the second is
-the frameescape index of the exception object, and the third is the code to run
+the localescape index of the exception object, and the third is the code to run
to catch the exception.
For Windows C++ exception handling, the first argument for a catch handler is a
pointer to the RTTI type descriptor for the object to catch. The second
-argument is an index into the argument list of the ``llvm.frameescape`` call in
+argument is an index into the argument list of the ``llvm.localescape`` call in
the main function. The exception object will be copied into the provided stack
object. If the exception object is not required, this argument should be -1.
The third argument is a pointer to a function implementing the catch. This
diff --git a/docs/LangRef.rst b/docs/LangRef.rst
index 167280f75f7f..e7d6f67c9399 100644
--- a/docs/LangRef.rst
+++ b/docs/LangRef.rst
@@ -1326,6 +1326,14 @@ example:
On an argument, this attribute indicates that the function does not write
through this pointer argument, even though it may write to the memory that
the pointer points to.
+``argmemonly``
+ This attribute indicates that the only memory accesses inside function are
+ loads and stores from objects pointed to by its pointer-typed arguments,
+ with arbitrary offsets. Or in other words, all memory operations in the
+ function can refer to memory only using pointers based on its function
+ arguments.
+ Note that ``argmemonly`` can be used together with ``readonly`` attribute
+ in order to specify that function reads only from its arguments.
``returns_twice``
This attribute indicates that this function can return twice. The C
``setjmp`` is an example of such a function. The compiler disables
@@ -1446,8 +1454,8 @@ The strings can contain any character by escaping non-printable
characters. The escape sequence used is simply "\\xx" where "xx" is the
two digit hex code for the number.
-The inline asm code is simply printed to the machine code .s file when
-assembly code is generated.
+Note that the assembly string *must* be parseable by LLVM's integrated assembler
+(unless it is disabled), even when emitting a ``.s`` file.
.. _langref_datalayout:
@@ -1837,8 +1845,8 @@ Fast-Math Flags
LLVM IR floating-point binary ops (:ref:`fadd <i_fadd>`,
:ref:`fsub <i_fsub>`, :ref:`fmul <i_fmul>`, :ref:`fdiv <i_fdiv>`,
-:ref:`frem <i_frem>`) have the following flags that can be set to enable
-otherwise unsafe floating point operations
+:ref:`frem <i_frem>`, :ref:`fcmp <i_fcmp>`) have the following flags that can
+be set to enable otherwise unsafe floating point operations
``nnan``
No NaNs - Allow optimizations to assume the arguments and result are not
@@ -2800,13 +2808,36 @@ Inline Assembler Expressions
----------------------------
LLVM supports inline assembler expressions (as opposed to :ref:`Module-Level
-Inline Assembly <moduleasm>`) through the use of a special value. This
-value represents the inline assembler as a string (containing the
-instructions to emit), a list of operand constraints (stored as a
-string), a flag that indicates whether or not the inline asm expression
-has side effects, and a flag indicating whether the function containing
-the asm needs to align its stack conservatively. An example inline
-assembler expression is:
+Inline Assembly <moduleasm>`) through the use of a special value. This value
+represents the inline assembler as a template string (containing the
+instructions to emit), a list of operand constraints (stored as a string), a
+flag that indicates whether or not the inline asm expression has side effects,
+and a flag indicating whether the function containing the asm needs to align its
+stack conservatively.
+
+The template string supports argument substitution of the operands using "``$``"
+followed by a number, to indicate substitution of the given register/memory
+location, as specified by the constraint string. "``${NUM:MODIFIER}``" may also
+be used, where ``MODIFIER`` is a target-specific annotation for how to print the
+operand (See :ref:`inline-asm-modifiers`).
+
+A literal "``$``" may be included by using "``$$``" in the template. To include
+other special characters into the output, the usual "``\XX``" escapes may be
+used, just as in other strings. Note that after template substitution, the
+resulting assembly string is parsed by LLVM's integrated assembler unless it is
+disabled -- even when emitting a ``.s`` file -- and thus must contain assembly
+syntax known to LLVM.
+
+LLVM's support for inline asm is modeled closely on the requirements of Clang's
+GCC-compatible inline-asm support. Thus, the feature-set and the constraint and
+modifier codes listed here are similar or identical to those in GCC's inline asm
+support. However, to be clear, the syntax of the template and constraint strings
+described here is *not* the same as the syntax accepted by GCC and Clang, and,
+while most constraint letters are passed through as-is by Clang, some get
+translated to other codes when converting from the C source to the LLVM
+assembly.
+
+An example inline assembler expression is:
.. code-block:: llvm
@@ -2852,6 +2883,596 @@ If multiple keywords appear the '``sideeffect``' keyword must come
first, the '``alignstack``' keyword second and the '``inteldialect``'
keyword last.
+Inline Asm Constraint String
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The constraint list is a comma-separated string, each element containing one or
+more constraint codes.
+
+For each element in the constraint list an appropriate register or memory
+operand will be chosen, and it will be made available to assembly template
+string expansion as ``$0`` for the first constraint in the list, ``$1`` for the
+second, etc.
+
+There are three different types of constraints, which are distinguished by a
+prefix symbol in front of the constraint code: Output, Input, and Clobber. The
+constraints must always be given in that order: outputs first, then inputs, then
+clobbers. They cannot be intermingled.
+
+There are also three different categories of constraint codes:
+
+- Register constraint. This is either a register class, or a fixed physical
+ register. This kind of constraint will allocate a register, and if necessary,
+ bitcast the argument or result to the appropriate type.
+- Memory constraint. This kind of constraint is for use with an instruction
+ taking a memory operand. Different constraints allow for different addressing
+ modes used by the target.
+- Immediate value constraint. This kind of constraint is for an integer or other
+ immediate value which can be rendered directly into an instruction. The
+ various target-specific constraints allow the selection of a value in the
+ proper range for the instruction you wish to use it with.
+
+Output constraints
+""""""""""""""""""
+
+Output constraints are specified by an "``=``" prefix (e.g. "``=r``"). This
+indicates that the assembly will write to this operand, and the operand will
+then be made available as a return value of the ``asm`` expression. Output
+constraints do not consume an argument from the call instruction. (Except, see
+below about indirect outputs).
+
+Normally, it is expected that no output locations are written to by the assembly
+expression until *all* of the inputs have been read. As such, LLVM may assign
+the same register to an output and an input. If this is not safe (e.g. if the
+assembly contains two instructions, where the first writes to one output, and
+the second reads an input and writes to a second output), then the "``&``"
+modifier must be used (e.g. "``=&r``") to specify that the output is an
+"early-clobber" output. Marking an ouput as "early-clobber" ensures that LLVM
+will not use the same register for any inputs (other than an input tied to this
+output).
+
+Input constraints
+"""""""""""""""""
+
+Input constraints do not have a prefix -- just the constraint codes. Each input
+constraint will consume one argument from the call instruction. It is not
+permitted for the asm to write to any input register or memory location (unless
+that input is tied to an output). Note also that multiple inputs may all be
+assigned to the same register, if LLVM can determine that they necessarily all
+contain the same value.
+
+Instead of providing a Constraint Code, input constraints may also "tie"
+themselves to an output constraint, by providing an integer as the constraint
+string. Tied inputs still consume an argument from the call instruction, and
+take up a position in the asm template numbering as is usual -- they will simply
+be constrained to always use the same register as the output they've been tied
+to. For example, a constraint string of "``=r,0``" says to assign a register for
+output, and use that register as an input as well (it being the 0'th
+constraint).
+
+It is permitted to tie an input to an "early-clobber" output. In that case, no
+*other* input may share the same register as the input tied to the early-clobber
+(even when the other input has the same value).
+
+You may only tie an input to an output which has a register constraint, not a
+memory constraint. Only a single input may be tied to an output.
+
+There is also an "interesting" feature which deserves a bit of explanation: if a
+register class constraint allocates a register which is too small for the value
+type operand provided as input, the input value will be split into multiple
+registers, and all of them passed to the inline asm.
+
+However, this feature is often not as useful as you might think.
+
+Firstly, the registers are *not* guaranteed to be consecutive. So, on those
+architectures that have instructions which operate on multiple consecutive
+instructions, this is not an appropriate way to support them. (e.g. the 32-bit
+SparcV8 has a 64-bit load, which instruction takes a single 32-bit register. The
+hardware then loads into both the named register, and the next register. This
+feature of inline asm would not be useful to support that.)
+
+A few of the targets provide a template string modifier allowing explicit access
+to the second register of a two-register operand (e.g. MIPS ``L``, ``M``, and
+``D``). On such an architecture, you can actually access the second allocated
+register (yet, still, not any subsequent ones). But, in that case, you're still
+probably better off simply splitting the value into two separate operands, for
+clarity. (e.g. see the description of the ``A`` constraint on X86, which,
+despite existing only for use with this feature, is not really a good idea to
+use)
+
+Indirect inputs and outputs
+"""""""""""""""""""""""""""
+
+Indirect output or input constraints can be specified by the "``*``" modifier
+(which goes after the "``=``" in case of an output). This indicates that the asm
+will write to or read from the contents of an *address* provided as an input
+argument. (Note that in this way, indirect outputs act more like an *input* than
+an output: just like an input, they consume an argument of the call expression,
+rather than producing a return value. An indirect output constraint is an
+"output" only in that the asm is expected to write to the contents of the input
+memory location, instead of just read from it).
+
+This is most typically used for memory constraint, e.g. "``=*m``", to pass the
+address of a variable as a value.
+
+It is also possible to use an indirect *register* constraint, but only on output
+(e.g. "``=*r``"). This will cause LLVM to allocate a register for an output
+value normally, and then, separately emit a store to the address provided as
+input, after the provided inline asm. (It's not clear what value this
+functionality provides, compared to writing the store explicitly after the asm
+statement, and it can only produce worse code, since it bypasses many
+optimization passes. I would recommend not using it.)
+
+
+Clobber constraints
+"""""""""""""""""""
+
+A clobber constraint is indicated by a "``~``" prefix. A clobber does not
+consume an input operand, nor generate an output. Clobbers cannot use any of the
+general constraint code letters -- they may use only explicit register
+constraints, e.g. "``~{eax}``". The one exception is that a clobber string of
+"``~{memory}``" indicates that the assembly writes to arbitrary undeclared
+memory locations -- not only the memory pointed to by a declared indirect
+output.
+
+
+Constraint Codes
+""""""""""""""""
+After a potential prefix comes constraint code, or codes.
+
+A Constraint Code is either a single letter (e.g. "``r``"), a "``^``" character
+followed by two letters (e.g. "``^wc``"), or "``{``" register-name "``}``"
+(e.g. "``{eax}``").
+
+The one and two letter constraint codes are typically chosen to be the same as
+GCC's constraint codes.
+
+A single constraint may include one or more than constraint code in it, leaving
+it up to LLVM to choose which one to use. This is included mainly for
+compatibility with the translation of GCC inline asm coming from clang.
+
+There are two ways to specify alternatives, and either or both may be used in an
+inline asm constraint list:
+
+1) Append the codes to each other, making a constraint code set. E.g. "``im``"
+ or "``{eax}m``". This means "choose any of the options in the set". The
+ choice of constraint is made independently for each constraint in the
+ constraint list.
+
+2) Use "``|``" between constraint code sets, creating alternatives. Every
+ constraint in the constraint list must have the same number of alternative
+ sets. With this syntax, the same alternative in *all* of the items in the
+ constraint list will be chosen together.
+
+Putting those together, you might have a two operand constraint string like
+``"rm|r,ri|rm"``. This indicates that if operand 0 is ``r`` or ``m``, then
+operand 1 may be one of ``r`` or ``i``. If operand 0 is ``r``, then operand 1
+may be one of ``r`` or ``m``. But, operand 0 and 1 cannot both be of type m.
+
+However, the use of either of the alternatives features is *NOT* recommended, as
+LLVM is not able to make an intelligent choice about which one to use. (At the
+point it currently needs to choose, not enough information is available to do so
+in a smart way.) Thus, it simply tries to make a choice that's most likely to
+compile, not one that will be optimal performance. (e.g., given "``rm``", it'll
+always choose to use memory, not registers). And, if given multiple registers,
+or multiple register classes, it will simply choose the first one. (In fact, it
+doesn't currently even ensure explicitly specified physical registers are
+unique, so specifying multiple physical registers as alternatives, like
+``{r11}{r12},{r11}{r12}``, will assign r11 to both operands, not at all what was
+intended.)
+
+Supported Constraint Code List
+""""""""""""""""""""""""""""""
+
+The constraint codes are, in general, expected to behave the same way they do in
+GCC. LLVM's support is often implemented on an 'as-needed' basis, to support C
+inline asm code which was supported by GCC. A mismatch in behavior between LLVM
+and GCC likely indicates a bug in LLVM.
+
+Some constraint codes are typically supported by all targets:
+
+- ``r``: A register in the target's general purpose register class.
+- ``m``: A memory address operand. It is target-specific what addressing modes
+ are supported, typical examples are register, or register + register offset,
+ or register + immediate offset (of some target-specific size).
+- ``i``: An integer constant (of target-specific width). Allows either a simple
+ immediate, or a relocatable value.
+- ``n``: An integer constant -- *not* including relocatable values.
+- ``s``: An integer constant, but allowing *only* relocatable values.
+- ``X``: Allows an operand of any kind, no constraint whatsoever. Typically
+ useful to pass a label for an asm branch or call.
+
+ .. FIXME: but that surely isn't actually okay to jump out of an asm
+ block without telling llvm about the control transfer???)
+
+- ``{register-name}``: Requires exactly the named physical register.
+
+Other constraints are target-specific:
+
+AArch64:
+
+- ``z``: An immediate integer 0. Outputs ``WZR`` or ``XZR``, as appropriate.
+- ``I``: An immediate integer valid for an ``ADD`` or ``SUB`` instruction,
+ i.e. 0 to 4095 with optional shift by 12.
+- ``J``: An immediate integer that, when negated, is valid for an ``ADD`` or
+ ``SUB`` instruction, i.e. -1 to -4095 with optional left shift by 12.
+- ``K``: An immediate integer that is valid for the 'bitmask immediate 32' of a
+ logical instruction like ``AND``, ``EOR``, or ``ORR`` with a 32-bit register.
+- ``L``: An immediate integer that is valid for the 'bitmask immediate 64' of a
+ logical instruction like ``AND``, ``EOR``, or ``ORR`` with a 64-bit register.
+- ``M``: An immediate integer for use with the ``MOV`` assembly alias on a
+ 32-bit register. This is a superset of ``K``: in addition to the bitmask
+ immediate, also allows immediate integers which can be loaded with a single
+ ``MOVZ`` or ``MOVL`` instruction.
+- ``N``: An immediate integer for use with the ``MOV`` assembly alias on a
+ 64-bit register. This is a superset of ``L``.
+- ``Q``: Memory address operand must be in a single register (no
+ offsets). (However, LLVM currently does this for the ``m`` constraint as
+ well.)
+- ``r``: A 32 or 64-bit integer register (W* or X*).
+- ``w``: A 32, 64, or 128-bit floating-point/SIMD register.
+- ``x``: A lower 128-bit floating-point/SIMD register (``V0`` to ``V15``).
+
+AMDGPU:
+
+- ``r``: A 32 or 64-bit integer register.
+- ``[0-9]v``: The 32-bit VGPR register, number 0-9.
+- ``[0-9]s``: The 32-bit SGPR register, number 0-9.
+
+
+All ARM modes:
+
+- ``Q``, ``Um``, ``Un``, ``Uq``, ``Us``, ``Ut``, ``Uv``, ``Uy``: Memory address
+ operand. Treated the same as operand ``m``, at the moment.
+
+ARM and ARM's Thumb2 mode:
+
+- ``j``: An immediate integer between 0 and 65535 (valid for ``MOVW``)
+- ``I``: An immediate integer valid for a data-processing instruction.
+- ``J``: An immediate integer between -4095 and 4095.
+- ``K``: An immediate integer whose bitwise inverse is valid for a
+ data-processing instruction. (Can be used with template modifier "``B``" to
+ print the inverted value).
+- ``L``: An immediate integer whose negation is valid for a data-processing
+ instruction. (Can be used with template modifier "``n``" to print the negated
+ value).
+- ``M``: A power of two or a integer between 0 and 32.
+- ``N``: Invalid immediate constraint.
+- ``O``: Invalid immediate constraint.
+- ``r``: A general-purpose 32-bit integer register (``r0-r15``).
+- ``l``: In Thumb2 mode, low 32-bit GPR registers (``r0-r7``). In ARM mode, same
+ as ``r``.
+- ``h``: In Thumb2 mode, a high 32-bit GPR register (``r8-r15``). In ARM mode,
+ invalid.
+- ``w``: A 32, 64, or 128-bit floating-point/SIMD register: ``s0-s31``,
+ ``d0-d31``, or ``q0-q15``.
+- ``x``: A 32, 64, or 128-bit floating-point/SIMD register: ``s0-s15``,
+ ``d0-d7``, or ``q0-q3``.
+- ``t``: A floating-point/SIMD register, only supports 32-bit values:
+ ``s0-s31``.
+
+ARM's Thumb1 mode:
+
+- ``I``: An immediate integer between 0 and 255.
+- ``J``: An immediate integer between -255 and -1.
+- ``K``: An immediate integer between 0 and 255, with optional left-shift by
+ some amount.
+- ``L``: An immediate integer between -7 and 7.
+- ``M``: An immediate integer which is a multiple of 4 between 0 and 1020.
+- ``N``: An immediate integer between 0 and 31.
+- ``O``: An immediate integer which is a multiple of 4 between -508 and 508.
+- ``r``: A low 32-bit GPR register (``r0-r7``).
+- ``l``: A low 32-bit GPR register (``r0-r7``).
+- ``h``: A high GPR register (``r0-r7``).
+- ``w``: A 32, 64, or 128-bit floating-point/SIMD register: ``s0-s31``,
+ ``d0-d31``, or ``q0-q15``.
+- ``x``: A 32, 64, or 128-bit floating-point/SIMD register: ``s0-s15``,
+ ``d0-d7``, or ``q0-q3``.
+- ``t``: A floating-point/SIMD register, only supports 32-bit values:
+ ``s0-s31``.
+
+
+Hexagon:
+
+- ``o``, ``v``: A memory address operand, treated the same as constraint ``m``,
+ at the moment.
+- ``r``: A 32 or 64-bit register.
+
+MSP430:
+
+- ``r``: An 8 or 16-bit register.
+
+MIPS:
+
+- ``I``: An immediate signed 16-bit integer.
+- ``J``: An immediate integer zero.
+- ``K``: An immediate unsigned 16-bit integer.
+- ``L``: An immediate 32-bit integer, where the lower 16 bits are 0.
+- ``N``: An immediate integer between -65535 and -1.
+- ``O``: An immediate signed 15-bit integer.
+- ``P``: An immediate integer between 1 and 65535.
+- ``m``: A memory address operand. In MIPS-SE mode, allows a base address
+ register plus 16-bit immediate offset. In MIPS mode, just a base register.
+- ``R``: A memory address operand. In MIPS-SE mode, allows a base address
+ register plus a 9-bit signed offset. In MIPS mode, the same as constraint
+ ``m``.
+- ``ZC``: A memory address operand, suitable for use in a ``pref``, ``ll``, or
+ ``sc`` instruction on the given subtarget (details vary).
+- ``r``, ``d``, ``y``: A 32 or 64-bit GPR register.
+- ``f``: A 32 or 64-bit FPU register (``F0-F31``), or a 128-bit MSA register
+ (``W0-W31``). In the case of MSA registers, it is recommended to use the ``w``
+ argument modifier for compatibility with GCC.
+- ``c``: A 32-bit or 64-bit GPR register suitable for indirect jump (always
+ ``25``).
+- ``l``: The ``lo`` register, 32 or 64-bit.
+- ``x``: Invalid.
+
+NVPTX:
+
+- ``b``: A 1-bit integer register.
+- ``c`` or ``h``: A 16-bit integer register.
+- ``r``: A 32-bit integer register.
+- ``l`` or ``N``: A 64-bit integer register.
+- ``f``: A 32-bit float register.
+- ``d``: A 64-bit float register.
+
+
+PowerPC:
+
+- ``I``: An immediate signed 16-bit integer.
+- ``J``: An immediate unsigned 16-bit integer, shifted left 16 bits.
+- ``K``: An immediate unsigned 16-bit integer.
+- ``L``: An immediate signed 16-bit integer, shifted left 16 bits.
+- ``M``: An immediate integer greater than 31.
+- ``N``: An immediate integer that is an exact power of 2.
+- ``O``: The immediate integer constant 0.
+- ``P``: An immediate integer constant whose negation is a signed 16-bit
+ constant.
+- ``es``, ``o``, ``Q``, ``Z``, ``Zy``: A memory address operand, currently
+ treated the same as ``m``.
+- ``r``: A 32 or 64-bit integer register.
+- ``b``: A 32 or 64-bit integer register, excluding ``R0`` (that is:
+ ``R1-R31``).
+- ``f``: A 32 or 64-bit float register (``F0-F31``), or when QPX is enabled, a
+ 128 or 256-bit QPX register (``Q0-Q31``; aliases the ``F`` registers).
+- ``v``: For ``4 x f32`` or ``4 x f64`` types, when QPX is enabled, a
+ 128 or 256-bit QPX register (``Q0-Q31``), otherwise a 128-bit
+ altivec vector register (``V0-V31``).
+
+ .. FIXME: is this a bug that v accepts QPX registers? I think this
+ is supposed to only use the altivec vector registers?
+
+- ``y``: Condition register (``CR0-CR7``).
+- ``wc``: An individual CR bit in a CR register.
+- ``wa``, ``wd``, ``wf``: Any 128-bit VSX vector register, from the full VSX
+ register set (overlapping both the floating-point and vector register files).
+- ``ws``: A 32 or 64-bit floating point register, from the full VSX register
+ set.
+
+Sparc:
+
+- ``I``: An immediate 13-bit signed integer.
+- ``r``: A 32-bit integer register.
+
+SystemZ:
+
+- ``I``: An immediate unsigned 8-bit integer.
+- ``J``: An immediate unsigned 12-bit integer.
+- ``K``: An immediate signed 16-bit integer.
+- ``L``: An immediate signed 20-bit integer.
+- ``M``: An immediate integer 0x7fffffff.
+- ``Q``, ``R``, ``S``, ``T``: A memory address operand, treated the same as
+ ``m``, at the moment.
+- ``r`` or ``d``: A 32, 64, or 128-bit integer register.
+- ``a``: A 32, 64, or 128-bit integer address register (excludes R0, which in an
+ address context evaluates as zero).
+- ``h``: A 32-bit value in the high part of a 64bit data register
+ (LLVM-specific)
+- ``f``: A 32, 64, or 128-bit floating point register.
+
+X86:
+
+- ``I``: An immediate integer between 0 and 31.
+- ``J``: An immediate integer between 0 and 64.
+- ``K``: An immediate signed 8-bit integer.
+- ``L``: An immediate integer, 0xff or 0xffff or (in 64-bit mode only)
+ 0xffffffff.
+- ``M``: An immediate integer between 0 and 3.
+- ``N``: An immediate unsigned 8-bit integer.
+- ``O``: An immediate integer between 0 and 127.
+- ``e``: An immediate 32-bit signed integer.
+- ``Z``: An immediate 32-bit unsigned integer.
+- ``o``, ``v``: Treated the same as ``m``, at the moment.
+- ``q``: An 8, 16, 32, or 64-bit register which can be accessed as an 8-bit
+ ``l`` integer register. On X86-32, this is the ``a``, ``b``, ``c``, and ``d``
+ registers, and on X86-64, it is all of the integer registers.
+- ``Q``: An 8, 16, 32, or 64-bit register which can be accessed as an 8-bit
+ ``h`` integer register. This is the ``a``, ``b``, ``c``, and ``d`` registers.
+- ``r`` or ``l``: An 8, 16, 32, or 64-bit integer register.
+- ``R``: An 8, 16, 32, or 64-bit "legacy" integer register -- one which has
+ existed since i386, and can be accessed without the REX prefix.
+- ``f``: A 32, 64, or 80-bit '387 FPU stack pseudo-register.
+- ``y``: A 64-bit MMX register, if MMX is enabled.
+- ``x``: If SSE is enabled: a 32 or 64-bit scalar operand, or 128-bit vector
+ operand in a SSE register. If AVX is also enabled, can also be a 256-bit
+ vector operand in an AVX register. If AVX-512 is also enabled, can also be a
+ 512-bit vector operand in an AVX512 register, Otherwise, an error.
+- ``Y``: The same as ``x``, if *SSE2* is enabled, otherwise an error.
+- ``A``: Special case: allocates EAX first, then EDX, for a single operand (in
+ 32-bit mode, a 64-bit integer operand will get split into two registers). It
+ is not recommended to use this constraint, as in 64-bit mode, the 64-bit
+ operand will get allocated only to RAX -- if two 32-bit operands are needed,
+ you're better off splitting it yourself, before passing it to the asm
+ statement.
+
+XCore:
+
+- ``r``: A 32-bit integer register.
+
+
+.. _inline-asm-modifiers:
+
+Asm template argument modifiers
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+In the asm template string, modifiers can be used on the operand reference, like
+"``${0:n}``".
+
+The modifiers are, in general, expected to behave the same way they do in
+GCC. LLVM's support is often implemented on an 'as-needed' basis, to support C
+inline asm code which was supported by GCC. A mismatch in behavior between LLVM
+and GCC likely indicates a bug in LLVM.
+
+Target-independent:
+
+- ``c``: Print an immediate integer constant unadorned, without
+ the target-specific immediate punctuation (e.g. no ``$`` prefix).
+- ``n``: Negate and print immediate integer constant unadorned, without the
+ target-specific immediate punctuation (e.g. no ``$`` prefix).
+- ``l``: Print as an unadorned label, without the target-specific label
+ punctuation (e.g. no ``$`` prefix).
+
+AArch64:
+
+- ``w``: Print a GPR register with a ``w*`` name instead of ``x*`` name. E.g.,
+ instead of ``x30``, print ``w30``.
+- ``x``: Print a GPR register with a ``x*`` name. (this is the default, anyhow).
+- ``b``, ``h``, ``s``, ``d``, ``q``: Print a floating-point/SIMD register with a
+ ``b*``, ``h*``, ``s*``, ``d*``, or ``q*`` name, rather than the default of
+ ``v*``.
+
+AMDGPU:
+
+- ``r``: No effect.
+
+ARM:
+
+- ``a``: Print an operand as an address (with ``[`` and ``]`` surrounding a
+ register).
+- ``P``: No effect.
+- ``q``: No effect.
+- ``y``: Print a VFP single-precision register as an indexed double (e.g. print
+ as ``d4[1]`` instead of ``s9``)
+- ``B``: Bitwise invert and print an immediate integer constant without ``#``
+ prefix.
+- ``L``: Print the low 16-bits of an immediate integer constant.
+- ``M``: Print as a register set suitable for ldm/stm. Also prints *all*
+ register operands subsequent to the specified one (!), so use carefully.
+- ``Q``: Print the low-order register of a register-pair, or the low-order
+ register of a two-register operand.
+- ``R``: Print the high-order register of a register-pair, or the high-order
+ register of a two-register operand.
+- ``H``: Print the second register of a register-pair. (On a big-endian system,
+ ``H`` is equivalent to ``Q``, and on little-endian system, ``H`` is equivalent
+ to ``R``.)
+
+ .. FIXME: H doesn't currently support printing the second register
+ of a two-register operand.
+
+- ``e``: Print the low doubleword register of a NEON quad register.
+- ``f``: Print the high doubleword register of a NEON quad register.
+- ``m``: Print the base register of a memory operand without the ``[`` and ``]``
+ adornment.
+
+Hexagon:
+
+- ``L``: Print the second register of a two-register operand. Requires that it
+ has been allocated consecutively to the first.
+
+ .. FIXME: why is it restricted to consecutive ones? And there's
+ nothing that ensures that happens, is there?
+
+- ``I``: Print the letter 'i' if the operand is an integer constant, otherwise
+ nothing. Used to print 'addi' vs 'add' instructions.
+
+MSP430:
+
+No additional modifiers.
+
+MIPS:
+
+- ``X``: Print an immediate integer as hexadecimal
+- ``x``: Print the low 16 bits of an immediate integer as hexadecimal.
+- ``d``: Print an immediate integer as decimal.
+- ``m``: Subtract one and print an immediate integer as decimal.
+- ``z``: Print $0 if an immediate zero, otherwise print normally.
+- ``L``: Print the low-order register of a two-register operand, or prints the
+ address of the low-order word of a double-word memory operand.
+
+ .. FIXME: L seems to be missing memory operand support.
+
+- ``M``: Print the high-order register of a two-register operand, or prints the
+ address of the high-order word of a double-word memory operand.
+
+ .. FIXME: M seems to be missing memory operand support.
+
+- ``D``: Print the second register of a two-register operand, or prints the
+ second word of a double-word memory operand. (On a big-endian system, ``D`` is
+ equivalent to ``L``, and on little-endian system, ``D`` is equivalent to
+ ``M``.)
+- ``w``: No effect. Provided for compatibility with GCC which requires this
+ modifier in order to print MSA registers (``W0-W31``) with the ``f``
+ constraint.
+
+NVPTX:
+
+- ``r``: No effect.
+
+PowerPC:
+
+- ``L``: Print the second register of a two-register operand. Requires that it
+ has been allocated consecutively to the first.
+
+ .. FIXME: why is it restricted to consecutive ones? And there's
+ nothing that ensures that happens, is there?
+
+- ``I``: Print the letter 'i' if the operand is an integer constant, otherwise
+ nothing. Used to print 'addi' vs 'add' instructions.
+- ``y``: For a memory operand, prints formatter for a two-register X-form
+ instruction. (Currently always prints ``r0,OPERAND``).
+- ``U``: Prints 'u' if the memory operand is an update form, and nothing
+ otherwise. (NOTE: LLVM does not support update form, so this will currently
+ always print nothing)
+- ``X``: Prints 'x' if the memory operand is an indexed form. (NOTE: LLVM does
+ not support indexed form, so this will currently always print nothing)
+
+Sparc:
+
+- ``r``: No effect.
+
+SystemZ:
+
+SystemZ implements only ``n``, and does *not* support any of the other
+target-independent modifiers.
+
+X86:
+
+- ``c``: Print an unadorned integer or symbol name. (The latter is
+ target-specific behavior for this typically target-independent modifier).
+- ``A``: Print a register name with a '``*``' before it.
+- ``b``: Print an 8-bit register name (e.g. ``al``); do nothing on a memory
+ operand.
+- ``h``: Print the upper 8-bit register name (e.g. ``ah``); do nothing on a
+ memory operand.
+- ``w``: Print the 16-bit register name (e.g. ``ax``); do nothing on a memory
+ operand.
+- ``k``: Print the 32-bit register name (e.g. ``eax``); do nothing on a memory
+ operand.
+- ``q``: Print the 64-bit register name (e.g. ``rax``), if 64-bit registers are
+ available, otherwise the 32-bit register name; do nothing on a memory operand.
+- ``n``: Negate and print an unadorned integer, or, for operands other than an
+ immediate integer (e.g. a relocatable symbol expression), print a '-' before
+ the operand. (The behavior for relocatable symbol expressions is a
+ target-specific behavior for this typically target-independent modifier)
+- ``H``: Print a memory reference with additional offset +8.
+- ``P``: Print a memory reference or operand for use as the argument of a call
+ instruction. (E.g. omit ``(rip)``, even though it's PC-relative.)
+
+XCore:
+
+No additional modifiers.
+
+
Inline Asm Metadata
^^^^^^^^^^^^^^^^^^^
@@ -6108,7 +6729,8 @@ Overview:
The '``getelementptr``' instruction is used to get the address of a
subelement of an :ref:`aggregate <t_aggregate>` data structure. It performs
-address calculation only and does not access memory.
+address calculation only and does not access memory. The instruction can also
+be used to calculate a vector of such addresses.
Arguments:
""""""""""
@@ -6234,12 +6856,61 @@ Example:
; yields i32*:iptr
%iptr = getelementptr [10 x i32], [10 x i32]* @arr, i16 0, i16 0
-In cases where the pointer argument is a vector of pointers, each index
-must be a vector with the same number of elements. For example:
+Vector of pointers:
+"""""""""""""""""""
+
+The ``getelementptr`` returns a vector of pointers, instead of a single address,
+when one or more of its arguments is a vector. In such cases, all vector
+arguments should have the same number of elements, and every scalar argument
+will be effectively broadcast into a vector during address calculation.
+
+.. code-block:: llvm
+
+ ; All arguments are vectors:
+ ; A[i] = ptrs[i] + offsets[i]*sizeof(i8)
+ %A = getelementptr i8, <4 x i8*> %ptrs, <4 x i64> %offsets
+
+ ; Add the same scalar offset to each pointer of a vector:
+ ; A[i] = ptrs[i] + offset*sizeof(i8)
+ %A = getelementptr i8, <4 x i8*> %ptrs, i64 %offset
+
+ ; Add distinct offsets to the same pointer:
+ ; A[i] = ptr + offsets[i]*sizeof(i8)
+ %A = getelementptr i8, i8* %ptr, <4 x i64> %offsets
+
+ ; In all cases described above the type of the result is <4 x i8*>
+
+The two following instructions are equivalent:
.. code-block:: llvm
- %A = getelementptr i8, <4 x i8*> %ptrs, <4 x i64> %offsets,
+ getelementptr %struct.ST, <4 x %struct.ST*> %s, <4 x i64> %ind1,
+ <4 x i32> <i32 2, i32 2, i32 2, i32 2>,
+ <4 x i32> <i32 1, i32 1, i32 1, i32 1>,
+ <4 x i32> %ind4,
+ <4 x i64> <i64 13, i64 13, i64 13, i64 13>
+
+ getelementptr %struct.ST, <4 x %struct.ST*> %s, <4 x i64> %ind1,
+ i32 2, i32 1, <4 x i32> %ind4, i64 13
+
+Let's look at the C code, where the vector version of ``getelementptr``
+makes sense:
+
+.. code-block:: c
+
+ // Let's assume that we vectorize the following loop:
+ double *A, B; int *C;
+ for (int i = 0; i < size; ++i) {
+ A[i] = B[C[i]];
+ }
+
+.. code-block:: llvm
+
+ ; get pointers for 8 elements from array B
+ %ptrs = getelementptr double, double* %B, <8 x i32> %C
+ ; load 8 elements from array B into A
+ %A = call <8 x double> @llvm.masked.gather.v8f64(<8 x double*> %ptrs,
+ i32 8, <8 x i1> %mask, <8 x double> %passthru)
Conversion Operations
---------------------
@@ -6913,7 +7584,7 @@ Syntax:
::
- <result> = fcmp <cond> <ty> <op1>, <op2> ; yields i1 or <N x i1>:result
+ <result> = fcmp [fast-math flags]* <cond> <ty> <op1>, <op2> ; yields i1 or <N x i1>:result
Overview:
"""""""""
@@ -6996,6 +7667,15 @@ always yields an :ref:`i1 <t_integer>` result, as follows:
#. ``uno``: yields ``true`` if either operand is a QNAN.
#. ``true``: always yields ``true``, regardless of operands.
+The ``fcmp`` instruction can also optionally take any number of
+:ref:`fast-math flags <fastmath>`, which are optimization hints to enable
+otherwise unsafe floating point optimizations.
+
+Any set of fast-math flags are legal on an ``fcmp`` instruction, but the
+only flags that have any effect on its semantics are those that allow
+assumptions to be made about the values of input arguments; namely
+``nnan``, ``ninf``, and ``nsz``. See :ref:`fastmath` for more information.
+
Example:
""""""""
@@ -7780,7 +8460,7 @@ Note that calling this intrinsic does not prevent function inlining or
other aggressive transformations, so the value returned may not be that
of the obvious source-language caller.
-'``llvm.frameescape``' and '``llvm.framerecover``' Intrinsics
+'``llvm.localescape``' and '``llvm.localrecover``' Intrinsics
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Syntax:
@@ -7788,49 +8468,47 @@ Syntax:
::
- declare void @llvm.frameescape(...)
- declare i8* @llvm.framerecover(i8* %func, i8* %fp, i32 %idx)
+ declare void @llvm.localescape(...)
+ declare i8* @llvm.localrecover(i8* %func, i8* %fp, i32 %idx)
Overview:
"""""""""
-The '``llvm.frameescape``' intrinsic escapes offsets of a collection of static
-allocas, and the '``llvm.framerecover``' intrinsic applies those offsets to a
+The '``llvm.localescape``' intrinsic escapes offsets of a collection of static
+allocas, and the '``llvm.localrecover``' intrinsic applies those offsets to a
live frame pointer to recover the address of the allocation. The offset is
-computed during frame layout of the caller of ``llvm.frameescape``.
+computed during frame layout of the caller of ``llvm.localescape``.
Arguments:
""""""""""
-All arguments to '``llvm.frameescape``' must be pointers to static allocas or
-casts of static allocas. Each function can only call '``llvm.frameescape``'
+All arguments to '``llvm.localescape``' must be pointers to static allocas or
+casts of static allocas. Each function can only call '``llvm.localescape``'
once, and it can only do so from the entry block.
-The ``func`` argument to '``llvm.framerecover``' must be a constant
+The ``func`` argument to '``llvm.localrecover``' must be a constant
bitcasted pointer to a function defined in the current module. The code
generator cannot determine the frame allocation offset of functions defined in
other modules.
-The ``fp`` argument to '``llvm.framerecover``' must be a frame
-pointer of a call frame that is currently live. The return value of
-'``llvm.frameaddress``' is one way to produce such a value, but most platforms
-also expose the frame pointer through stack unwinding mechanisms.
+The ``fp`` argument to '``llvm.localrecover``' must be a frame pointer of a
+call frame that is currently live. The return value of '``llvm.localaddress``'
+is one way to produce such a value, but various runtimes also expose a suitable
+pointer in platform-specific ways.
-The ``idx`` argument to '``llvm.framerecover``' indicates which alloca passed to
-'``llvm.frameescape``' to recover. It is zero-indexed.
+The ``idx`` argument to '``llvm.localrecover``' indicates which alloca passed to
+'``llvm.localescape``' to recover. It is zero-indexed.
Semantics:
""""""""""
-These intrinsics allow a group of functions to access one stack memory
-allocation in an ancestor stack frame. The memory returned from
-'``llvm.frameallocate``' may be allocated prior to stack realignment, so the
-memory is only aligned to the ABI-required stack alignment. Each function may
-only call '``llvm.frameallocate``' one or zero times from the function entry
-block. The frame allocation intrinsic inhibits inlining, as any frame
-allocations in the inlined function frame are likely to be at a different
-offset from the one used by '``llvm.framerecover``' called with the
-uninlined function.
+These intrinsics allow a group of functions to share access to a set of local
+stack allocations of a one parent function. The parent function may call the
+'``llvm.localescape``' intrinsic once from the function entry block, and the
+child functions can use '``llvm.localrecover``' to access the escaped allocas.
+The '``llvm.localescape``' intrinsic blocks inlining, as inlining changes where
+the escaped allocas are allocated, which would break attempts to use
+'``llvm.localrecover``'.
.. _int_read_register:
.. _int_write_register:
@@ -9532,6 +10210,75 @@ Examples:
Specialised Arithmetic Intrinsics
---------------------------------
+'``llvm.canonicalize.*``' Intrinsic
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Syntax:
+"""""""
+
+::
+
+ declare float @llvm.canonicalize.f32(float %a)
+ declare double @llvm.canonicalize.f64(double %b)
+
+Overview:
+"""""""""
+
+The '``llvm.canonicalize.*``' intrinsic returns the platform specific canonical
+encoding of a floating point number. This canonicalization is useful for
+implementing certain numeric primitives such as frexp. The canonical encoding is
+defined by IEEE-754-2008 to be:
+
+::
+
+ 2.1.8 canonical encoding: The preferred encoding of a floating-point
+ representation in a format. Applied to declets, significands of finite
+ numbers, infinities, and NaNs, especially in decimal formats.
+
+This operation can also be considered equivalent to the IEEE-754-2008
+conversion of a floating-point value to the same format. NaNs are handled
+according to section 6.2.
+
+Examples of non-canonical encodings:
+
+- x87 pseudo denormals, pseudo NaNs, pseudo Infinity, Unnormals. These are
+ converted to a canonical representation per hardware-specific protocol.
+- Many normal decimal floating point numbers have non-canonical alternative
+ encodings.
+- Some machines, like GPUs or ARMv7 NEON, do not support subnormal values.
+ These are treated as non-canonical encodings of zero and with be flushed to
+ a zero of the same sign by this operation.
+
+Note that per IEEE-754-2008 6.2, systems that support signaling NaNs with
+default exception handling must signal an invalid exception, and produce a
+quiet NaN result.
+
+This function should always be implementable as multiplication by 1.0, provided
+that the compiler does not constant fold the operation. Likewise, division by
+1.0 and ``llvm.minnum(x, x)`` are possible implementations. Addition with
+-0.0 is also sufficient provided that the rounding mode is not -Infinity.
+
+``@llvm.canonicalize`` must preserve the equality relation. That is:
+
+- ``(@llvm.canonicalize(x) == x)`` is equivalent to ``(x == x)``
+- ``(@llvm.canonicalize(x) == @llvm.canonicalize(y))`` is equivalent to
+ to ``(x == y)``
+
+Additionally, the sign of zero must be conserved:
+``@llvm.canonicalize(-0.0) = -0.0`` and ``@llvm.canonicalize(+0.0) = +0.0``
+
+The payload bits of a NaN must be conserved, with two exceptions.
+First, environments which use only a single canonical representation of NaN
+must perform said canonicalization. Second, SNaNs must be quieted per the
+usual methods.
+
+The canonicalization operation may be optimized away if:
+
+- The input is known to be canonical. For example, it was produced by a
+ floating-point operation that is required by the standard to be canonical.
+- The result is consumed only by (or fused with) other floating-point
+ operations. That is, the bits of the floating point value are not examined.
+
'``llvm.fmuladd.*``' Intrinsic
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/docs/ProgrammersManual.rst b/docs/ProgrammersManual.rst
index ceb39e18efdf..08cc61a187b5 100644
--- a/docs/ProgrammersManual.rst
+++ b/docs/ProgrammersManual.rst
@@ -1868,7 +1868,7 @@ Iterating over predecessors & successors of blocks
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Iterating over the predecessors and successors of a block is quite easy with the
-routines defined in ``"llvm/Support/CFG.h"``. Just use code like this to
+routines defined in ``"llvm/IR/CFG.h"``. Just use code like this to
iterate over all predecessors of BB:
.. code-block:: c++
diff --git a/docs/StackMaps.rst b/docs/StackMaps.rst
index 43c60c9e7850..dbdf78f992ca 100644
--- a/docs/StackMaps.rst
+++ b/docs/StackMaps.rst
@@ -221,12 +221,10 @@ lowered according to the calling convention specified at the
intrinsic's callsite. Variants of the intrinsic with non-void return
type also return a value according to calling convention.
-On PowerPC, note that ``<target>`` must be the actual intended target of
-the indirect call. Specifically, even when compiling for the ELF V1 ABI,
-``<target>`` is not the function-descriptor address normally used as the C/C++
-function-pointer representation. As a result, the call target must be local
-because no adjustment or restoration of the TOC pointer (in register r2) will
-be performed.
+On PowerPC, note that ``<target>`` must be the ABI function pointer for the
+intended target of the indirect call. Specifically, when compiling for the
+ELF V1 ABI, ``<target>`` is the function-descriptor address normally used as
+the C/C++ function-pointer representation.
Requesting zero patch point arguments is valid. In this case, all
variable operands are handled just like
diff --git a/include/llvm-c/Core.h b/include/llvm-c/Core.h
index 713894f57639..15290072abe8 100644
--- a/include/llvm-c/Core.h
+++ b/include/llvm-c/Core.h
@@ -1888,6 +1888,20 @@ LLVMValueRef LLVMAddAlias(LLVMModuleRef M, LLVMTypeRef Ty, LLVMValueRef Aliasee,
void LLVMDeleteFunction(LLVMValueRef Fn);
/**
+ * Obtain the personality function attached to the function.
+ *
+ * @see llvm::Function::getPersonalityFn()
+ */
+LLVMValueRef LLVMGetPersonalityFn(LLVMValueRef Fn);
+
+/**
+ * Set the personality function attached to the function.
+ *
+ * @see llvm::Function::setPersonalityFn()
+ */
+void LLVMSetPersonalityFn(LLVMValueRef Fn, LLVMValueRef PersonalityFn);
+
+/**
* Obtain the ID number from a function instance.
*
* @see llvm::Function::getIntrinsicID()
diff --git a/include/llvm-c/Object.h b/include/llvm-c/Object.h
index 447fcea7bc24..9cab5c426c45 100644
--- a/include/llvm-c/Object.h
+++ b/include/llvm-c/Object.h
@@ -81,7 +81,6 @@ uint64_t LLVMGetSymbolAddress(LLVMSymbolIteratorRef SI);
uint64_t LLVMGetSymbolSize(LLVMSymbolIteratorRef SI);
// RelocationRef accessors
-uint64_t LLVMGetRelocationAddress(LLVMRelocationIteratorRef RI);
uint64_t LLVMGetRelocationOffset(LLVMRelocationIteratorRef RI);
LLVMSymbolIteratorRef LLVMGetRelocationSymbol(LLVMRelocationIteratorRef RI);
uint64_t LLVMGetRelocationType(LLVMRelocationIteratorRef RI);
diff --git a/include/llvm-c/lto.h b/include/llvm-c/lto.h
index 42c05a2fc59e..cb3a69160454 100644
--- a/include/llvm-c/lto.h
+++ b/include/llvm-c/lto.h
@@ -40,7 +40,7 @@ typedef bool lto_bool_t;
* @{
*/
-#define LTO_API_VERSION 16
+#define LTO_API_VERSION 17
/**
* \since prior to LTO_API_VERSION=3
@@ -63,7 +63,8 @@ typedef enum {
LTO_SYMBOL_SCOPE_PROTECTED = 0x00002000,
LTO_SYMBOL_SCOPE_DEFAULT = 0x00001800,
LTO_SYMBOL_SCOPE_DEFAULT_CAN_BE_HIDDEN = 0x00002800,
- LTO_SYMBOL_COMDAT = 0x00004000
+ LTO_SYMBOL_COMDAT = 0x00004000,
+ LTO_SYMBOL_ALIAS = 0x00008000
} lto_symbol_attributes;
/**
diff --git a/include/llvm/ADT/APFloat.h b/include/llvm/ADT/APFloat.h
index 958e3fdaea14..76615affb253 100644
--- a/include/llvm/ADT/APFloat.h
+++ b/include/llvm/ADT/APFloat.h
@@ -276,6 +276,10 @@ public:
/// \param isIEEE - If 128 bit number, select between PPC and IEEE
static APFloat getAllOnesValue(unsigned BitWidth, bool isIEEE = false);
+ /// Returns the size of the floating point number (in bits) in the given
+ /// semantics.
+ static unsigned getSizeInBits(const fltSemantics &Sem);
+
/// @}
/// Used to insert APFloat objects, or objects that contain APFloat objects,
diff --git a/include/llvm/ADT/Triple.h b/include/llvm/ADT/Triple.h
index 06f5870119c8..947812d94ecb 100644
--- a/include/llvm/ADT/Triple.h
+++ b/include/llvm/ADT/Triple.h
@@ -569,6 +569,22 @@ public:
/// architecture if no such variant can be found.
llvm::Triple get64BitArchVariant() const;
+ /// Form a triple with a big endian variant of the current architecture.
+ ///
+ /// This can be used to move across "families" of architectures where useful.
+ ///
+ /// \returns A new triple with a big endian architecture or an unknown
+ /// architecture if no such variant can be found.
+ llvm::Triple getBigEndianArchVariant() const;
+
+ /// Form a triple with a little endian variant of the current architecture.
+ ///
+ /// This can be used to move across "families" of architectures where useful.
+ ///
+ /// \returns A new triple with a little endian architecture or an unknown
+ /// architecture if no such variant can be found.
+ llvm::Triple getLittleEndianArchVariant() const;
+
/// Get the (LLVM) name of the minimum ARM CPU for the arch we are targeting.
///
/// \param Arch the architecture name (e.g., "armv7s"). If it is an empty
diff --git a/include/llvm/ADT/edit_distance.h b/include/llvm/ADT/edit_distance.h
index c2b2041242aa..06a01b18a9fb 100644
--- a/include/llvm/ADT/edit_distance.h
+++ b/include/llvm/ADT/edit_distance.h
@@ -50,50 +50,51 @@ unsigned ComputeEditDistance(ArrayRef<T> FromArray, ArrayRef<T> ToArray,
// http://en.wikipedia.org/wiki/Levenshtein_distance
//
// Although the algorithm is typically described using an m x n
- // array, only two rows are used at a time, so this implementation
- // just keeps two separate vectors for those two rows.
+ // array, only one row plus one element are used at a time, so this
+ // implementation just keeps one vector for the row. To update one entry,
+ // only the entries to the left, top, and top-left are needed. The left
+ // entry is in Row[x-1], the top entry is what's in Row[x] from the last
+ // iteration, and the top-left entry is stored in Previous.
typename ArrayRef<T>::size_type m = FromArray.size();
typename ArrayRef<T>::size_type n = ToArray.size();
const unsigned SmallBufferSize = 64;
unsigned SmallBuffer[SmallBufferSize];
std::unique_ptr<unsigned[]> Allocated;
- unsigned *Previous = SmallBuffer;
- if (2*(n + 1) > SmallBufferSize) {
- Previous = new unsigned [2*(n+1)];
- Allocated.reset(Previous);
+ unsigned *Row = SmallBuffer;
+ if (n + 1 > SmallBufferSize) {
+ Row = new unsigned[n + 1];
+ Allocated.reset(Row);
}
- unsigned *Current = Previous + (n + 1);
- for (unsigned i = 0; i <= n; ++i)
- Previous[i] = i;
+ for (unsigned i = 1; i <= n; ++i)
+ Row[i] = i;
for (typename ArrayRef<T>::size_type y = 1; y <= m; ++y) {
- Current[0] = y;
- unsigned BestThisRow = Current[0];
+ Row[0] = y;
+ unsigned BestThisRow = Row[0];
+ unsigned Previous = y - 1;
for (typename ArrayRef<T>::size_type x = 1; x <= n; ++x) {
+ int OldRow = Row[x];
if (AllowReplacements) {
- Current[x] = std::min(
- Previous[x-1] + (FromArray[y-1] == ToArray[x-1] ? 0u : 1u),
- std::min(Current[x-1], Previous[x])+1);
+ Row[x] = std::min(
+ Previous + (FromArray[y-1] == ToArray[x-1] ? 0u : 1u),
+ std::min(Row[x-1], Row[x])+1);
}
else {
- if (FromArray[y-1] == ToArray[x-1]) Current[x] = Previous[x-1];
- else Current[x] = std::min(Current[x-1], Previous[x]) + 1;
+ if (FromArray[y-1] == ToArray[x-1]) Row[x] = Previous;
+ else Row[x] = std::min(Row[x-1], Row[x]) + 1;
}
- BestThisRow = std::min(BestThisRow, Current[x]);
+ Previous = OldRow;
+ BestThisRow = std::min(BestThisRow, Row[x]);
}
if (MaxEditDistance && BestThisRow > MaxEditDistance)
return MaxEditDistance + 1;
-
- unsigned *tmp = Current;
- Current = Previous;
- Previous = tmp;
}
- unsigned Result = Previous[n];
+ unsigned Result = Row[n];
return Result;
}
diff --git a/include/llvm/Analysis/AliasAnalysis.h b/include/llvm/Analysis/AliasAnalysis.h
index f4c1167314a1..36f8199a0322 100644
--- a/include/llvm/Analysis/AliasAnalysis.h
+++ b/include/llvm/Analysis/AliasAnalysis.h
@@ -211,6 +211,8 @@ public:
/// (if it has any) are non-volatile loads from objects pointed to by its
/// pointer-typed arguments, with arbitrary offsets.
///
+ /// This property corresponds to the LLVM IR 'argmemonly' attribute combined
+ /// with 'readonly' attribute.
/// This property corresponds to the IntrReadArgMem LLVM intrinsic flag.
OnlyReadsArgumentPointees = ArgumentPointees | Ref,
@@ -218,6 +220,7 @@ public:
/// function (if it has any) are non-volatile loads and stores from objects
/// pointed to by its pointer-typed arguments, with arbitrary offsets.
///
+ /// This property corresponds to the LLVM IR 'argmemonly' attribute.
/// This property corresponds to the IntrReadWriteArgMem LLVM intrinsic flag.
OnlyAccessesArgumentPointees = ArgumentPointees | ModRef,
@@ -518,14 +521,6 @@ public:
///
virtual void deleteValue(Value *V);
- /// copyValue - This method should be used whenever a preexisting value in the
- /// program is copied or cloned, introducing a new value. Note that analysis
- /// implementations should tolerate clients that use this method to introduce
- /// the same value multiple times: if the analysis already knows about a
- /// value, it should ignore the request.
- ///
- virtual void copyValue(Value *From, Value *To);
-
/// addEscapingUse - This method should be used whenever an escaping use is
/// added to a pointer value. Analysis implementations may either return
/// conservative responses for that value in the future, or may recompute
@@ -541,7 +536,6 @@ public:
/// above, and it provided as a helper to simplify client code.
///
void replaceWithNewValue(Value *Old, Value *New) {
- copyValue(Old, New);
deleteValue(Old);
}
};
diff --git a/include/llvm/Analysis/ConstantFolding.h b/include/llvm/Analysis/ConstantFolding.h
index 541a2109af6c..e8185b3b6307 100644
--- a/include/llvm/Analysis/ConstantFolding.h
+++ b/include/llvm/Analysis/ConstantFolding.h
@@ -72,6 +72,17 @@ namespace llvm {
Constant *ConstantFoldInsertValueInstruction(Constant *Agg, Constant *Val,
ArrayRef<unsigned> Idxs);
+/// \brief Attempt to constant fold an extractvalue instruction with the
+/// specified operands and indices. The constant result is returned if
+/// successful; if not, null is returned.
+Constant *ConstantFoldExtractValueInstruction(Constant *Agg,
+ ArrayRef<unsigned> Idxs);
+
+/// \brief Attempt to constant fold an extractelement instruction with the
+/// specified operands and indices. The constant result is returned if
+/// successful; if not, null is returned.
+Constant *ConstantFoldExtractElementInstruction(Constant *Val, Constant *Idx);
+
/// ConstantFoldLoadFromConstPtr - Return the value that a load from C would
/// produce if it is constant and determinable. If this is not determinable,
/// return null.
diff --git a/include/llvm/Analysis/DominanceFrontier.h b/include/llvm/Analysis/DominanceFrontier.h
index 996700efdb60..fb730054a8e5 100644
--- a/include/llvm/Analysis/DominanceFrontier.h
+++ b/include/llvm/Analysis/DominanceFrontier.h
@@ -202,8 +202,8 @@ public:
void dump() const;
};
-EXTERN_TEMPLATE_INSTANTIATION(class DominanceFrontierBase<BasicBlock>);
-EXTERN_TEMPLATE_INSTANTIATION(class ForwardDominanceFrontierBase<BasicBlock>);
+extern template class DominanceFrontierBase<BasicBlock>;
+extern template class ForwardDominanceFrontierBase<BasicBlock>;
} // End llvm namespace
diff --git a/include/llvm/Analysis/IVUsers.h b/include/llvm/Analysis/IVUsers.h
index ae9c1f5bd9ac..00dbcbdd7806 100644
--- a/include/llvm/Analysis/IVUsers.h
+++ b/include/llvm/Analysis/IVUsers.h
@@ -21,6 +21,7 @@
namespace llvm {
+class AssumptionCache;
class DominatorTree;
class Instruction;
class Value;
@@ -119,15 +120,19 @@ private:
class IVUsers : public LoopPass {
friend class IVStrideUse;
Loop *L;
+ AssumptionCache *AC;
LoopInfo *LI;
DominatorTree *DT;
ScalarEvolution *SE;
- SmallPtrSet<Instruction*,16> Processed;
+ SmallPtrSet<Instruction*, 16> Processed;
/// IVUses - A list of all tracked IV uses of induction variable expressions
/// we are interested in.
ilist<IVStrideUse> IVUses;
+ // Ephemeral values used by @llvm.assume in this function.
+ SmallPtrSet<const Value *, 32> EphValues;
+
void getAnalysisUsage(AnalysisUsage &AU) const override;
bool runOnLoop(Loop *L, LPPassManager &LPM) override;
diff --git a/include/llvm/Analysis/InstructionSimplify.h b/include/llvm/Analysis/InstructionSimplify.h
index 706bd8000d3a..d44c5ff4078d 100644
--- a/include/llvm/Analysis/InstructionSimplify.h
+++ b/include/llvm/Analysis/InstructionSimplify.h
@@ -212,7 +212,7 @@ namespace llvm {
/// SimplifyFCmpInst - Given operands for an FCmpInst, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
- const DataLayout &DL,
+ FastMathFlags FMF, const DataLayout &DL,
const TargetLibraryInfo *TLI = nullptr,
const DominatorTree *DT = nullptr,
AssumptionCache *AC = nullptr,
@@ -244,6 +244,24 @@ namespace llvm {
AssumptionCache *AC = nullptr,
const Instruction *CxtI = nullptr);
+ /// \brief Given operands for an ExtractValueInst, see if we can fold the
+ /// result. If not, this returns null.
+ Value *SimplifyExtractValueInst(Value *Agg, ArrayRef<unsigned> Idxs,
+ const DataLayout &DL,
+ const TargetLibraryInfo *TLI = nullptr,
+ const DominatorTree *DT = nullptr,
+ AssumptionCache *AC = nullptr,
+ const Instruction *CxtI = nullptr);
+
+ /// \brief Given operands for an ExtractElementInst, see if we can fold the
+ /// result. If not, this returns null.
+ Value *SimplifyExtractElementInst(Value *Vec, Value *Idx,
+ const DataLayout &DL,
+ const TargetLibraryInfo *TLI = nullptr,
+ const DominatorTree *DT = nullptr,
+ AssumptionCache *AC = nullptr,
+ const Instruction *CxtI = nullptr);
+
/// SimplifyTruncInst - Given operands for an TruncInst, see if we can fold
/// the result. If not, this returns null.
Value *SimplifyTruncInst(Value *Op, Type *Ty, const DataLayout &DL,
diff --git a/include/llvm/Analysis/JumpInstrTableInfo.h b/include/llvm/Analysis/JumpInstrTableInfo.h
deleted file mode 100644
index b6dad478cdf2..000000000000
--- a/include/llvm/Analysis/JumpInstrTableInfo.h
+++ /dev/null
@@ -1,71 +0,0 @@
-//===-- JumpInstrTableInfo.h: Info for Jump-Instruction Tables --*- C++ -*-===//
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// \brief Information about jump-instruction tables that have been created by
-/// JumpInstrTables pass.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_ANALYSIS_JUMPINSTRTABLEINFO_H
-#define LLVM_ANALYSIS_JUMPINSTRTABLEINFO_H
-
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/Pass.h"
-#include <vector>
-
-namespace llvm {
-class Function;
-class FunctionType;
-
-/// This class stores information about jump-instruction tables created by the
-/// JumpInstrTables pass (in lib/CodeGen/JumpInstrTables.cpp). Each table is a
-/// map from a function type to a vector of pairs. The first element of each
-/// pair is the function that has the jumptable annotation. The second element
-/// is a function that was declared by JumpInstrTables and used to replace all
-/// address-taking sites for the original function.
-///
-/// The information in this pass is used in AsmPrinter
-/// (lib/CodeGen/AsmPrinter/AsmPrinter.cpp) to generate the required assembly
-/// for the jump-instruction tables.
-class JumpInstrTableInfo : public ImmutablePass {
-public:
- static char ID;
-
- /// The default byte alignment for jump tables is 16, which is large but
- /// usually safe.
- JumpInstrTableInfo(uint64_t ByteAlign = 16);
- ~JumpInstrTableInfo() override;
- const char *getPassName() const override {
- return "Jump-Instruction Table Info";
- }
-
- typedef std::pair<Function *, Function *> JumpPair;
- typedef DenseMap<FunctionType *, std::vector<JumpPair> > JumpTables;
-
- /// Inserts an entry in a table, adding the table if it doesn't exist.
- void insertEntry(FunctionType *TableFunTy, Function *Target, Function *Jump);
-
- /// Gets the tables.
- const JumpTables &getTables() const { return Tables; }
-
- /// Gets the alignment in bytes of a jumptable entry.
- uint64_t entryByteAlignment() const { return ByteAlignment; }
-private:
- JumpTables Tables;
-
- /// A power-of-two alignment of a jumptable entry.
- uint64_t ByteAlignment;
-};
-
-/// Creates a JumpInstrTableInfo pass with the given bound on entry size. This
-/// bound specifies the maximum number of bytes needed to represent an
-/// unconditional jump or a trap instruction in the back end currently in use.
-ModulePass *createJumpInstrTableInfoPass(unsigned Bound);
-}
-
-#endif /* LLVM_ANALYSIS_JUMPINSTRTABLEINFO_H */
diff --git a/include/llvm/Analysis/LibCallSemantics.h b/include/llvm/Analysis/LibCallSemantics.h
index 170e2a49a8ea..b4bef310e590 100644
--- a/include/llvm/Analysis/LibCallSemantics.h
+++ b/include/llvm/Analysis/LibCallSemantics.h
@@ -206,6 +206,18 @@ class InvokeInst;
llvm_unreachable("invalid enum");
}
+ /// \brief Return true if this personality may be safely removed if there
+ /// are no invoke instructions remaining in the current function.
+ inline bool isNoOpWithoutInvoke(EHPersonality Pers) {
+ switch (Pers) {
+ case EHPersonality::Unknown:
+ return false;
+ // All known personalities currently have this behavior
+ default: return true;
+ }
+ llvm_unreachable("invalid enum");
+ }
+
bool canSimplifyInvokeNoUnwind(const Function *F);
} // end namespace llvm
diff --git a/include/llvm/Analysis/LoopAccessAnalysis.h b/include/llvm/Analysis/LoopAccessAnalysis.h
index 7b635a8b4960..476e4b6686bb 100644
--- a/include/llvm/Analysis/LoopAccessAnalysis.h
+++ b/include/llvm/Analysis/LoopAccessAnalysis.h
@@ -292,6 +292,133 @@ private:
bool couldPreventStoreLoadForward(unsigned Distance, unsigned TypeByteSize);
};
+/// \brief Holds information about the memory runtime legality checks to verify
+/// that a group of pointers do not overlap.
+class RuntimePointerChecking {
+public:
+ struct PointerInfo {
+ /// Holds the pointer value that we need to check.
+ TrackingVH<Value> PointerValue;
+ /// Holds the pointer value at the beginning of the loop.
+ const SCEV *Start;
+ /// Holds the pointer value at the end of the loop.
+ const SCEV *End;
+ /// Holds the information if this pointer is used for writing to memory.
+ bool IsWritePtr;
+ /// Holds the id of the set of pointers that could be dependent because of a
+ /// shared underlying object.
+ unsigned DependencySetId;
+ /// Holds the id of the disjoint alias set to which this pointer belongs.
+ unsigned AliasSetId;
+ /// SCEV for the access.
+ const SCEV *Expr;
+
+ PointerInfo(Value *PointerValue, const SCEV *Start, const SCEV *End,
+ bool IsWritePtr, unsigned DependencySetId, unsigned AliasSetId,
+ const SCEV *Expr)
+ : PointerValue(PointerValue), Start(Start), End(End),
+ IsWritePtr(IsWritePtr), DependencySetId(DependencySetId),
+ AliasSetId(AliasSetId), Expr(Expr) {}
+ };
+
+ RuntimePointerChecking(ScalarEvolution *SE) : Need(false), SE(SE) {}
+
+ /// Reset the state of the pointer runtime information.
+ void reset() {
+ Need = false;
+ Pointers.clear();
+ }
+
+ /// Insert a pointer and calculate the start and end SCEVs.
+ void insert(Loop *Lp, Value *Ptr, bool WritePtr, unsigned DepSetId,
+ unsigned ASId, const ValueToValueMap &Strides);
+
+ /// \brief No run-time memory checking is necessary.
+ bool empty() const { return Pointers.empty(); }
+
+ /// A grouping of pointers. A single memcheck is required between
+ /// two groups.
+ struct CheckingPtrGroup {
+ /// \brief Create a new pointer checking group containing a single
+ /// pointer, with index \p Index in RtCheck.
+ CheckingPtrGroup(unsigned Index, RuntimePointerChecking &RtCheck)
+ : RtCheck(RtCheck), High(RtCheck.Pointers[Index].End),
+ Low(RtCheck.Pointers[Index].Start) {
+ Members.push_back(Index);
+ }
+
+ /// \brief Tries to add the pointer recorded in RtCheck at index
+ /// \p Index to this pointer checking group. We can only add a pointer
+ /// to a checking group if we will still be able to get
+ /// the upper and lower bounds of the check. Returns true in case
+ /// of success, false otherwise.
+ bool addPointer(unsigned Index);
+
+ /// Constitutes the context of this pointer checking group. For each
+ /// pointer that is a member of this group we will retain the index
+ /// at which it appears in RtCheck.
+ RuntimePointerChecking &RtCheck;
+ /// The SCEV expression which represents the upper bound of all the
+ /// pointers in this group.
+ const SCEV *High;
+ /// The SCEV expression which represents the lower bound of all the
+ /// pointers in this group.
+ const SCEV *Low;
+ /// Indices of all the pointers that constitute this grouping.
+ SmallVector<unsigned, 2> Members;
+ };
+
+ /// \brief Groups pointers such that a single memcheck is required
+ /// between two different groups. This will clear the CheckingGroups vector
+ /// and re-compute it. We will only group dependecies if \p UseDependencies
+ /// is true, otherwise we will create a separate group for each pointer.
+ void groupChecks(MemoryDepChecker::DepCandidates &DepCands,
+ bool UseDependencies);
+
+ /// \brief Decide if we need to add a check between two groups of pointers,
+ /// according to needsChecking.
+ bool needsChecking(const CheckingPtrGroup &M, const CheckingPtrGroup &N,
+ const SmallVectorImpl<int> *PtrPartition) const;
+
+ /// \brief Return true if any pointer requires run-time checking according
+ /// to needsChecking.
+ bool needsAnyChecking(const SmallVectorImpl<int> *PtrPartition) const;
+
+ /// \brief Returns the number of run-time checks required according to
+ /// needsChecking.
+ unsigned getNumberOfChecks(const SmallVectorImpl<int> *PtrPartition) const;
+
+ /// \brief Print the list run-time memory checks necessary.
+ ///
+ /// If \p PtrPartition is set, it contains the partition number for
+ /// pointers (-1 if the pointer belongs to multiple partitions). In this
+ /// case omit checks between pointers belonging to the same partition.
+ void print(raw_ostream &OS, unsigned Depth = 0,
+ const SmallVectorImpl<int> *PtrPartition = nullptr) const;
+
+ /// This flag indicates if we need to add the runtime check.
+ bool Need;
+
+ /// Information about the pointers that may require checking.
+ SmallVector<PointerInfo, 2> Pointers;
+
+ /// Holds a partitioning of pointers into "check groups".
+ SmallVector<CheckingPtrGroup, 2> CheckingGroups;
+
+private:
+ /// \brief Decide whether we need to issue a run-time check for pointer at
+ /// index \p I and \p J to prove their independence.
+ ///
+ /// If \p PtrPartition is set, it contains the partition number for
+ /// pointers (-1 if the pointer belongs to multiple partitions). In this
+ /// case omit checks between pointers belonging to the same partition.
+ bool needsChecking(unsigned I, unsigned J,
+ const SmallVectorImpl<int> *PtrPartition) const;
+
+ /// Holds a pointer to the ScalarEvolution analysis.
+ ScalarEvolution *SE;
+};
+
/// \brief Drive the analysis of memory accesses in the loop
///
/// This class is responsible for analyzing the memory accesses of a loop. It
@@ -308,72 +435,6 @@ private:
/// RuntimePointerCheck class.
class LoopAccessInfo {
public:
- /// This struct holds information about the memory runtime legality check that
- /// a group of pointers do not overlap.
- struct RuntimePointerCheck {
- RuntimePointerCheck() : Need(false) {}
-
- /// Reset the state of the pointer runtime information.
- void reset() {
- Need = false;
- Pointers.clear();
- Starts.clear();
- Ends.clear();
- IsWritePtr.clear();
- DependencySetId.clear();
- AliasSetId.clear();
- }
-
- /// Insert a pointer and calculate the start and end SCEVs.
- void insert(ScalarEvolution *SE, Loop *Lp, Value *Ptr, bool WritePtr,
- unsigned DepSetId, unsigned ASId,
- const ValueToValueMap &Strides);
-
- /// \brief No run-time memory checking is necessary.
- bool empty() const { return Pointers.empty(); }
-
- /// \brief Decide whether we need to issue a run-time check for pointer at
- /// index \p I and \p J to prove their independence.
- ///
- /// If \p PtrPartition is set, it contains the partition number for
- /// pointers (-1 if the pointer belongs to multiple partitions). In this
- /// case omit checks between pointers belonging to the same partition.
- bool needsChecking(unsigned I, unsigned J,
- const SmallVectorImpl<int> *PtrPartition) const;
-
- /// \brief Return true if any pointer requires run-time checking according
- /// to needsChecking.
- bool needsAnyChecking(const SmallVectorImpl<int> *PtrPartition) const;
-
- /// \brief Returns the number of run-time checks required according to
- /// needsChecking.
- unsigned getNumberOfChecks(const SmallVectorImpl<int> *PtrPartition) const;
-
- /// \brief Print the list run-time memory checks necessary.
- ///
- /// If \p PtrPartition is set, it contains the partition number for
- /// pointers (-1 if the pointer belongs to multiple partitions). In this
- /// case omit checks between pointers belonging to the same partition.
- void print(raw_ostream &OS, unsigned Depth = 0,
- const SmallVectorImpl<int> *PtrPartition = nullptr) const;
-
- /// This flag indicates if we need to add the runtime check.
- bool Need;
- /// Holds the pointers that we need to check.
- SmallVector<TrackingVH<Value>, 2> Pointers;
- /// Holds the pointer value at the beginning of the loop.
- SmallVector<const SCEV*, 2> Starts;
- /// Holds the pointer value at the end of the loop.
- SmallVector<const SCEV*, 2> Ends;
- /// Holds the information if this pointer is used for writing to memory.
- SmallVector<bool, 2> IsWritePtr;
- /// Holds the id of the set of pointers that could be dependent because of a
- /// shared underlying object.
- SmallVector<unsigned, 2> DependencySetId;
- /// Holds the id of the disjoint alias set to which this pointer belongs.
- SmallVector<unsigned, 2> AliasSetId;
- };
-
LoopAccessInfo(Loop *L, ScalarEvolution *SE, const DataLayout &DL,
const TargetLibraryInfo *TLI, AliasAnalysis *AA,
DominatorTree *DT, LoopInfo *LI,
@@ -383,15 +444,15 @@ public:
/// no memory dependence cycles.
bool canVectorizeMemory() const { return CanVecMem; }
- const RuntimePointerCheck *getRuntimePointerCheck() const {
- return &PtrRtCheck;
+ const RuntimePointerChecking *getRuntimePointerChecking() const {
+ return &PtrRtChecking;
}
/// \brief Number of memchecks required to prove independence of otherwise
/// may-alias pointers.
unsigned getNumRuntimePointerChecks(
const SmallVectorImpl<int> *PtrPartition = nullptr) const {
- return PtrRtCheck.getNumberOfChecks(PtrPartition);
+ return PtrRtChecking.getNumberOfChecks(PtrPartition);
}
/// Return true if the block BB needs to be predicated in order for the loop
@@ -461,7 +522,7 @@ private:
/// We need to check that all of the pointers in this list are disjoint
/// at runtime.
- RuntimePointerCheck PtrRtCheck;
+ RuntimePointerChecking PtrRtChecking;
/// \brief the Memory Dependence Checker which can determine the
/// loop-independent and loop-carried dependences between memory accesses.
diff --git a/include/llvm/Analysis/LoopInfo.h b/include/llvm/Analysis/LoopInfo.h
index bbcde8d9721a..3ec83f2c21fd 100644
--- a/include/llvm/Analysis/LoopInfo.h
+++ b/include/llvm/Analysis/LoopInfo.h
@@ -347,9 +347,7 @@ raw_ostream& operator<<(raw_ostream &OS, const LoopBase<BlockT, LoopT> &Loop) {
}
// Implementation in LoopInfoImpl.h
-#ifdef __GNUC__
-__extension__ extern template class LoopBase<BasicBlock, Loop>;
-#endif
+extern template class LoopBase<BasicBlock, Loop>;
class Loop : public LoopBase<BasicBlock, Loop> {
public:
@@ -633,9 +631,7 @@ public:
};
// Implementation in LoopInfoImpl.h
-#ifdef __GNUC__
-__extension__ extern template class LoopInfoBase<BasicBlock, Loop>;
-#endif
+extern template class LoopInfoBase<BasicBlock, Loop>;
class LoopInfo : public LoopInfoBase<BasicBlock, Loop> {
typedef LoopInfoBase<BasicBlock, Loop> BaseT;
diff --git a/include/llvm/Analysis/RegionInfo.h b/include/llvm/Analysis/RegionInfo.h
index 7ceb086ee0a1..8560f1f67160 100644
--- a/include/llvm/Analysis/RegionInfo.h
+++ b/include/llvm/Analysis/RegionInfo.h
@@ -902,9 +902,9 @@ inline raw_ostream &operator<<(raw_ostream &OS,
return OS << Node.template getNodeAs<BlockT>()->getName();
}
-EXTERN_TEMPLATE_INSTANTIATION(class RegionBase<RegionTraits<Function>>);
-EXTERN_TEMPLATE_INSTANTIATION(class RegionNodeBase<RegionTraits<Function>>);
-EXTERN_TEMPLATE_INSTANTIATION(class RegionInfoBase<RegionTraits<Function>>);
+extern template class RegionBase<RegionTraits<Function>>;
+extern template class RegionNodeBase<RegionTraits<Function>>;
+extern template class RegionInfoBase<RegionTraits<Function>>;
} // End llvm namespace
#endif
diff --git a/include/llvm/Analysis/TargetTransformInfo.h b/include/llvm/Analysis/TargetTransformInfo.h
index bb6e266b1f5b..01f00896410e 100644
--- a/include/llvm/Analysis/TargetTransformInfo.h
+++ b/include/llvm/Analysis/TargetTransformInfo.h
@@ -69,7 +69,7 @@ public:
///
/// The TTI implementation will reflect the information in the DataLayout
/// provided if non-null.
- explicit TargetTransformInfo(const DataLayout *DL);
+ explicit TargetTransformInfo(const DataLayout &DL);
// Provide move semantics.
TargetTransformInfo(TargetTransformInfo &&Arg);
@@ -541,7 +541,7 @@ private:
class TargetTransformInfo::Concept {
public:
virtual ~Concept() = 0;
-
+ virtual const DataLayout &getDataLayout() const = 0;
virtual unsigned getOperationCost(unsigned Opcode, Type *Ty, Type *OpTy) = 0;
virtual unsigned getGEPCost(const Value *Ptr,
ArrayRef<const Value *> Operands) = 0;
@@ -636,6 +636,10 @@ public:
Model(T Impl) : Impl(std::move(Impl)) {}
~Model() override {}
+ const DataLayout &getDataLayout() const override {
+ return Impl.getDataLayout();
+ }
+
unsigned getOperationCost(unsigned Opcode, Type *Ty, Type *OpTy) override {
return Impl.getOperationCost(Opcode, Ty, OpTy);
}
diff --git a/include/llvm/Analysis/TargetTransformInfoImpl.h b/include/llvm/Analysis/TargetTransformInfoImpl.h
index 403175acae02..035cb04870a1 100644
--- a/include/llvm/Analysis/TargetTransformInfoImpl.h
+++ b/include/llvm/Analysis/TargetTransformInfoImpl.h
@@ -30,26 +30,17 @@ class TargetTransformInfoImplBase {
protected:
typedef TargetTransformInfo TTI;
- const DataLayout *DL;
+ const DataLayout &DL;
- explicit TargetTransformInfoImplBase(const DataLayout *DL)
- : DL(DL) {}
+ explicit TargetTransformInfoImplBase(const DataLayout &DL) : DL(DL) {}
public:
// Provide value semantics. MSVC requires that we spell all of these out.
TargetTransformInfoImplBase(const TargetTransformInfoImplBase &Arg)
: DL(Arg.DL) {}
- TargetTransformInfoImplBase(TargetTransformInfoImplBase &&Arg)
- : DL(std::move(Arg.DL)) {}
- TargetTransformInfoImplBase &
- operator=(const TargetTransformInfoImplBase &RHS) {
- DL = RHS.DL;
- return *this;
- }
- TargetTransformInfoImplBase &operator=(TargetTransformInfoImplBase &&RHS) {
- DL = std::move(RHS.DL);
- return *this;
- }
+ TargetTransformInfoImplBase(TargetTransformInfoImplBase &&Arg) : DL(Arg.DL) {}
+
+ const DataLayout &getDataLayout() const { return DL; }
unsigned getOperationCost(unsigned Opcode, Type *Ty, Type *OpTy) {
switch (Opcode) {
@@ -70,28 +61,22 @@ public:
return TTI::TCC_Basic;
case Instruction::IntToPtr: {
- if (!DL)
- return TTI::TCC_Basic;
-
// An inttoptr cast is free so long as the input is a legal integer type
// which doesn't contain values outside the range of a pointer.
unsigned OpSize = OpTy->getScalarSizeInBits();
- if (DL->isLegalInteger(OpSize) &&
- OpSize <= DL->getPointerTypeSizeInBits(Ty))
+ if (DL.isLegalInteger(OpSize) &&
+ OpSize <= DL.getPointerTypeSizeInBits(Ty))
return TTI::TCC_Free;
// Otherwise it's not a no-op.
return TTI::TCC_Basic;
}
case Instruction::PtrToInt: {
- if (!DL)
- return TTI::TCC_Basic;
-
// A ptrtoint cast is free so long as the result is large enough to store
// the pointer, and a legal integer type.
unsigned DestSize = Ty->getScalarSizeInBits();
- if (DL->isLegalInteger(DestSize) &&
- DestSize >= DL->getPointerTypeSizeInBits(OpTy))
+ if (DL.isLegalInteger(DestSize) &&
+ DestSize >= DL.getPointerTypeSizeInBits(OpTy))
return TTI::TCC_Free;
// Otherwise it's not a no-op.
@@ -100,7 +85,7 @@ public:
case Instruction::Trunc:
// trunc to a native type is free (assuming the target has compare and
// shift-right of the same width).
- if (DL && DL->isLegalInteger(DL->getTypeSizeInBits(Ty)))
+ if (DL.isLegalInteger(DL.getTypeSizeInBits(Ty)))
return TTI::TCC_Free;
return TTI::TCC_Basic;
@@ -353,8 +338,7 @@ private:
typedef TargetTransformInfoImplBase BaseT;
protected:
- explicit TargetTransformInfoImplCRTPBase(const DataLayout *DL)
- : BaseT(DL) {}
+ explicit TargetTransformInfoImplCRTPBase(const DataLayout &DL) : BaseT(DL) {}
public:
// Provide value semantics. MSVC requires that we spell all of these out.
@@ -362,16 +346,6 @@ public:
: BaseT(static_cast<const BaseT &>(Arg)) {}
TargetTransformInfoImplCRTPBase(TargetTransformInfoImplCRTPBase &&Arg)
: BaseT(std::move(static_cast<BaseT &>(Arg))) {}
- TargetTransformInfoImplCRTPBase &
- operator=(const TargetTransformInfoImplCRTPBase &RHS) {
- BaseT::operator=(static_cast<const BaseT &>(RHS));
- return *this;
- }
- TargetTransformInfoImplCRTPBase &
- operator=(TargetTransformInfoImplCRTPBase &&RHS) {
- BaseT::operator=(std::move(static_cast<BaseT &>(RHS)));
- return *this;
- }
using BaseT::getCallCost;
diff --git a/include/llvm/Analysis/VectorUtils.h b/include/llvm/Analysis/VectorUtils.h
index aa538ecc0137..d8e9ca42e623 100644
--- a/include/llvm/Analysis/VectorUtils.h
+++ b/include/llvm/Analysis/VectorUtils.h
@@ -20,6 +20,12 @@
namespace llvm {
+class GetElementPtrInst;
+class Loop;
+class ScalarEvolution;
+class Type;
+class Value;
+
/// \brief Identify if the intrinsic is trivially vectorizable.
/// This method returns true if the intrinsic's argument types are all
/// scalars for the scalar form of the intrinsic and all vectors for
@@ -51,6 +57,28 @@ Intrinsic::ID checkBinaryFloatSignature(const CallInst &I,
/// its intrinsic ID, in case it does not found it return not_intrinsic.
Intrinsic::ID getIntrinsicIDForCall(CallInst *CI, const TargetLibraryInfo *TLI);
+/// \brief Find the operand of the GEP that should be checked for consecutive
+/// stores. This ignores trailing indices that have no effect on the final
+/// pointer.
+unsigned getGEPInductionOperand(const GetElementPtrInst *Gep);
+
+/// \brief If the argument is a GEP, then returns the operand identified by
+/// getGEPInductionOperand. However, if there is some other non-loop-invariant
+/// operand, it returns that instead.
+Value *stripGetElementPtr(Value *Ptr, ScalarEvolution *SE, Loop *Lp);
+
+/// \brief If a value has only one user that is a CastInst, return it.
+Value *getUniqueCastUse(Value *Ptr, Loop *Lp, Type *Ty);
+
+/// \brief Get the stride of a pointer access in a loop. Looks for symbolic
+/// strides "a[i*stride]". Returns the symbolic stride, or null otherwise.
+Value *getStrideFromPointer(Value *Ptr, ScalarEvolution *SE, Loop *Lp);
+
+/// \brief Given a vector and an element number, see if the scalar value is
+/// already around as a register, for example if it were inserted then extracted
+/// from the vector.
+Value *findScalarElement(Value *V, unsigned EltNo);
+
} // llvm namespace
#endif
diff --git a/include/llvm/Bitcode/LLVMBitCodes.h b/include/llvm/Bitcode/LLVMBitCodes.h
index 605c4172dd87..7130ee755237 100644
--- a/include/llvm/Bitcode/LLVMBitCodes.h
+++ b/include/llvm/Bitcode/LLVMBitCodes.h
@@ -407,6 +407,7 @@ namespace bitc {
ATTR_KIND_DEREFERENCEABLE_OR_NULL = 42,
ATTR_KIND_CONVERGENT = 43,
ATTR_KIND_SAFESTACK = 44,
+ ATTR_KIND_ARGMEMONLY = 45
};
enum ComdatSelectionKindCodes {
diff --git a/include/llvm/Bitcode/ReaderWriter.h b/include/llvm/Bitcode/ReaderWriter.h
index 6797aa133c42..452ec3bd0187 100644
--- a/include/llvm/Bitcode/ReaderWriter.h
+++ b/include/llvm/Bitcode/ReaderWriter.h
@@ -146,7 +146,7 @@ namespace llvm {
}
const std::error_category &BitcodeErrorCategory();
- enum class BitcodeError { InvalidBitcodeSignature, CorruptedBitcode };
+ enum class BitcodeError { InvalidBitcodeSignature = 1, CorruptedBitcode };
inline std::error_code make_error_code(BitcodeError E) {
return std::error_code(static_cast<int>(E), BitcodeErrorCategory());
}
diff --git a/include/llvm/CodeGen/Analysis.h b/include/llvm/CodeGen/Analysis.h
index c4b94ede4f55..82d1e8ada17d 100644
--- a/include/llvm/CodeGen/Analysis.h
+++ b/include/llvm/CodeGen/Analysis.h
@@ -64,7 +64,7 @@ inline unsigned ComputeLinearIndex(Type *Ty,
/// If Offsets is non-null, it points to a vector to be filled in
/// with the in-memory offsets of each of the individual values.
///
-void ComputeValueVTs(const TargetLowering &TLI, Type *Ty,
+void ComputeValueVTs(const TargetLowering &TLI, const DataLayout &DL, Type *Ty,
SmallVectorImpl<EVT> &ValueVTs,
SmallVectorImpl<uint64_t> *Offsets = nullptr,
uint64_t StartingOffset = 0);
diff --git a/include/llvm/CodeGen/BasicTTIImpl.h b/include/llvm/CodeGen/BasicTTIImpl.h
index 3e464f4f1e5a..9ba25169fda6 100644
--- a/include/llvm/CodeGen/BasicTTIImpl.h
+++ b/include/llvm/CodeGen/BasicTTIImpl.h
@@ -91,8 +91,10 @@ private:
}
protected:
- explicit BasicTTIImplBase(const TargetMachine *TM)
- : BaseT(TM->getDataLayout()) {}
+ explicit BasicTTIImplBase(const TargetMachine *TM, const DataLayout &DL)
+ : BaseT(DL) {}
+
+ using TargetTransformInfoImplBase::DL;
public:
// Provide value semantics. MSVC requires that we spell all of these out.
@@ -100,14 +102,6 @@ public:
: BaseT(static_cast<const BaseT &>(Arg)) {}
BasicTTIImplBase(BasicTTIImplBase &&Arg)
: BaseT(std::move(static_cast<BaseT &>(Arg))) {}
- BasicTTIImplBase &operator=(const BasicTTIImplBase &RHS) {
- BaseT::operator=(static_cast<const BaseT &>(RHS));
- return *this;
- }
- BasicTTIImplBase &operator=(BasicTTIImplBase &&RHS) {
- BaseT::operator=(std::move(static_cast<BaseT &>(RHS)));
- return *this;
- }
/// \name Scalar TTI Implementations
/// @{
@@ -132,7 +126,7 @@ public:
AM.BaseOffs = BaseOffset;
AM.HasBaseReg = HasBaseReg;
AM.Scale = Scale;
- return getTLI()->isLegalAddressingMode(AM, Ty, AddrSpace);
+ return getTLI()->isLegalAddressingMode(DL, AM, Ty, AddrSpace);
}
int getScalingFactorCost(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset,
@@ -142,7 +136,7 @@ public:
AM.BaseOffs = BaseOffset;
AM.HasBaseReg = HasBaseReg;
AM.Scale = Scale;
- return getTLI()->getScalingFactorCost(AM, Ty, AddrSpace);
+ return getTLI()->getScalingFactorCost(DL, AM, Ty, AddrSpace);
}
bool isTruncateFree(Type *Ty1, Type *Ty2) {
@@ -154,7 +148,7 @@ public:
}
bool isTypeLegal(Type *Ty) {
- EVT VT = getTLI()->getValueType(Ty);
+ EVT VT = getTLI()->getValueType(DL, Ty);
return getTLI()->isTypeLegal(VT);
}
@@ -192,7 +186,7 @@ public:
bool haveFastSqrt(Type *Ty) {
const TargetLoweringBase *TLI = getTLI();
- EVT VT = TLI->getValueType(Ty);
+ EVT VT = TLI->getValueType(DL, Ty);
return TLI->isTypeLegal(VT) &&
TLI->isOperationLegalOrCustom(ISD::FSQRT, VT);
}
@@ -282,7 +276,7 @@ public:
/// \name Vector TTI Implementations
/// @{
- unsigned getNumberOfRegisters(bool Vector) { return 1; }
+ unsigned getNumberOfRegisters(bool Vector) { return Vector ? 0 : 1; }
unsigned getRegisterBitWidth(bool Vector) { return 32; }
@@ -299,7 +293,7 @@ public:
int ISD = TLI->InstructionOpcodeToISD(Opcode);
assert(ISD && "Invalid opcode");
- std::pair<unsigned, MVT> LT = TLI->getTypeLegalizationCost(Ty);
+ std::pair<unsigned, MVT> LT = TLI->getTypeLegalizationCost(DL, Ty);
bool IsFloat = Ty->getScalarType()->isFloatingPointTy();
// Assume that floating point arithmetic operations cost twice as much as
@@ -349,9 +343,8 @@ public:
const TargetLoweringBase *TLI = getTLI();
int ISD = TLI->InstructionOpcodeToISD(Opcode);
assert(ISD && "Invalid opcode");
-
- std::pair<unsigned, MVT> SrcLT = TLI->getTypeLegalizationCost(Src);
- std::pair<unsigned, MVT> DstLT = TLI->getTypeLegalizationCost(Dst);
+ std::pair<unsigned, MVT> SrcLT = TLI->getTypeLegalizationCost(DL, Src);
+ std::pair<unsigned, MVT> DstLT = TLI->getTypeLegalizationCost(DL, Dst);
// Check for NOOP conversions.
if (SrcLT.first == DstLT.first &&
@@ -455,8 +448,7 @@ public:
if (CondTy->isVectorTy())
ISD = ISD::VSELECT;
}
-
- std::pair<unsigned, MVT> LT = TLI->getTypeLegalizationCost(ValTy);
+ std::pair<unsigned, MVT> LT = TLI->getTypeLegalizationCost(DL, ValTy);
if (!(ValTy->isVectorTy() && !LT.second.isVector()) &&
!TLI->isOperationExpand(ISD, LT.second)) {
@@ -485,7 +477,7 @@ public:
unsigned getVectorInstrCost(unsigned Opcode, Type *Val, unsigned Index) {
std::pair<unsigned, MVT> LT =
- getTLI()->getTypeLegalizationCost(Val->getScalarType());
+ getTLI()->getTypeLegalizationCost(DL, Val->getScalarType());
return LT.first;
}
@@ -493,7 +485,7 @@ public:
unsigned getMemoryOpCost(unsigned Opcode, Type *Src, unsigned Alignment,
unsigned AddressSpace) {
assert(!Src->isVoidTy() && "Invalid type");
- std::pair<unsigned, MVT> LT = getTLI()->getTypeLegalizationCost(Src);
+ std::pair<unsigned, MVT> LT = getTLI()->getTypeLegalizationCost(DL, Src);
// Assuming that all loads of legal types cost 1.
unsigned Cost = LT.first;
@@ -504,7 +496,7 @@ public:
// itself. Unless the corresponding extending load or truncating store is
// legal, then this will scalarize.
TargetLowering::LegalizeAction LA = TargetLowering::Expand;
- EVT MemVT = getTLI()->getValueType(Src, true);
+ EVT MemVT = getTLI()->getValueType(DL, Src, true);
if (MemVT.isSimple() && MemVT != MVT::Other) {
if (Opcode == Instruction::Store)
LA = getTLI()->getTruncStoreAction(LT.second, MemVT.getSimpleVT());
@@ -700,7 +692,7 @@ public:
}
const TargetLoweringBase *TLI = getTLI();
- std::pair<unsigned, MVT> LT = TLI->getTypeLegalizationCost(RetTy);
+ std::pair<unsigned, MVT> LT = TLI->getTypeLegalizationCost(DL, RetTy);
if (TLI->isOperationLegalOrPromote(ISD, LT.second)) {
// The operation is legal. Assume it costs 1.
@@ -771,7 +763,7 @@ public:
}
unsigned getNumberOfParts(Type *Tp) {
- std::pair<unsigned, MVT> LT = getTLI()->getTypeLegalizationCost(Tp);
+ std::pair<unsigned, MVT> LT = getTLI()->getTypeLegalizationCost(DL, Tp);
return LT.first;
}
@@ -816,18 +808,6 @@ public:
BasicTTIImpl(BasicTTIImpl &&Arg)
: BaseT(std::move(static_cast<BaseT &>(Arg))), ST(std::move(Arg.ST)),
TLI(std::move(Arg.TLI)) {}
- BasicTTIImpl &operator=(const BasicTTIImpl &RHS) {
- BaseT::operator=(static_cast<const BaseT &>(RHS));
- ST = RHS.ST;
- TLI = RHS.TLI;
- return *this;
- }
- BasicTTIImpl &operator=(BasicTTIImpl &&RHS) {
- BaseT::operator=(std::move(static_cast<BaseT &>(RHS)));
- ST = std::move(RHS.ST);
- TLI = std::move(RHS.TLI);
- return *this;
- }
};
}
diff --git a/include/llvm/CodeGen/CommandFlags.h b/include/llvm/CodeGen/CommandFlags.h
index 554511d6f4ab..4b2e0b06584c 100644
--- a/include/llvm/CodeGen/CommandFlags.h
+++ b/include/llvm/CodeGen/CommandFlags.h
@@ -206,6 +206,10 @@ cl::opt<std::string> StartAfter("start-after",
cl::value_desc("pass-name"),
cl::init(""));
+cl::opt<std::string>
+ RunPass("run-pass", cl::desc("Run compiler only for one specific pass"),
+ cl::value_desc("pass-name"), cl::init(""));
+
cl::opt<bool> DataSections("data-sections",
cl::desc("Emit data into separate sections"),
cl::init(false));
diff --git a/include/llvm/CodeGen/ISDOpcodes.h b/include/llvm/CodeGen/ISDOpcodes.h
index c7237fd55b27..fa44301a2d4a 100644
--- a/include/llvm/CodeGen/ISDOpcodes.h
+++ b/include/llvm/CodeGen/ISDOpcodes.h
@@ -72,10 +72,13 @@ namespace ISD {
/// the parent's frame or return address, and so on.
FRAMEADDR, RETURNADDR,
- /// FRAME_ALLOC_RECOVER - Represents the llvm.framerecover
- /// intrinsic. Materializes the offset from the frame pointer of another
- /// function to the result of llvm.frameallocate.
- FRAME_ALLOC_RECOVER,
+ /// LOCAL_RECOVER - Represents the llvm.localrecover intrinsic.
+ /// Materializes the offset from the local object pointer of another
+ /// function to a particular local object passed to llvm.localescape. The
+ /// operand is the MCSymbol label used to represent this offset, since
+ /// typically the offset is not known until after code generation of the
+ /// parent.
+ LOCAL_RECOVER,
/// READ_REGISTER, WRITE_REGISTER - This node represents llvm.register on
/// the DAG, which implements the named register global variables extension.
@@ -725,7 +728,7 @@ namespace ISD {
/// which do not reference a specific memory location should be less than
/// this value. Those that do must not be less than this value, and can
/// be used with SelectionDAG::getMemIntrinsicNode.
- static const int FIRST_TARGET_MEMORY_OPCODE = BUILTIN_OP_END+200;
+ static const int FIRST_TARGET_MEMORY_OPCODE = BUILTIN_OP_END+300;
//===--------------------------------------------------------------------===//
/// MemIndexedMode enum - This enum defines the load / store indexed
diff --git a/include/llvm/CodeGen/LiveIntervalUnion.h b/include/llvm/CodeGen/LiveIntervalUnion.h
index 967f0cbac719..f0f1637dc92d 100644
--- a/include/llvm/CodeGen/LiveIntervalUnion.h
+++ b/include/llvm/CodeGen/LiveIntervalUnion.h
@@ -203,6 +203,11 @@ public:
assert(idx < Size && "idx out of bounds");
return LIUs[idx];
}
+
+ const LiveIntervalUnion& operator[](unsigned Idx) const {
+ assert(Idx < Size && "Idx out of bounds");
+ return LIUs[Idx];
+ }
};
};
diff --git a/include/llvm/CodeGen/LiveRegMatrix.h b/include/llvm/CodeGen/LiveRegMatrix.h
index 878b4d9836f2..e169058ca563 100644
--- a/include/llvm/CodeGen/LiveRegMatrix.h
+++ b/include/llvm/CodeGen/LiveRegMatrix.h
@@ -32,13 +32,11 @@ namespace llvm {
class LiveInterval;
class LiveIntervalAnalysis;
-class MachineRegisterInfo;
class TargetRegisterInfo;
class VirtRegMap;
class LiveRegMatrix : public MachineFunctionPass {
const TargetRegisterInfo *TRI;
- MachineRegisterInfo *MRI;
LiveIntervals *LIS;
VirtRegMap *VRM;
@@ -114,6 +112,9 @@ public:
/// the assignment and updates VirtRegMap accordingly.
void unassign(LiveInterval &VirtReg);
+ /// Returns true if the given \p PhysReg has any live intervals assigned.
+ bool isPhysRegUsed(unsigned PhysReg) const;
+
//===--------------------------------------------------------------------===//
// Low-level interface.
//===--------------------------------------------------------------------===//
diff --git a/include/llvm/CodeGen/MIRYamlMapping.h b/include/llvm/CodeGen/MIRYamlMapping.h
index a6ffeb382978..9798e5cef645 100644
--- a/include/llvm/CodeGen/MIRYamlMapping.h
+++ b/include/llvm/CodeGen/MIRYamlMapping.h
@@ -81,15 +81,30 @@ LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(llvm::yaml::FlowStringValue)
namespace llvm {
namespace yaml {
+struct VirtualRegisterDefinition {
+ unsigned ID;
+ StringValue Class;
+ // TODO: Serialize the virtual register hints.
+};
+
+template <> struct MappingTraits<VirtualRegisterDefinition> {
+ static void mapping(IO &YamlIO, VirtualRegisterDefinition &Reg) {
+ YamlIO.mapRequired("id", Reg.ID);
+ YamlIO.mapRequired("class", Reg.Class);
+ }
+
+ static const bool flow = true;
+};
+
struct MachineBasicBlock {
unsigned ID;
- std::string Name;
+ StringValue Name;
unsigned Alignment = 0;
bool IsLandingPad = false;
bool AddressTaken = false;
- // TODO: Serialize the successor weights and liveins.
+ // TODO: Serialize the successor weights.
std::vector<FlowStringValue> Successors;
-
+ std::vector<FlowStringValue> LiveIns;
std::vector<StringValue> Instructions;
};
@@ -97,23 +112,153 @@ template <> struct MappingTraits<MachineBasicBlock> {
static void mapping(IO &YamlIO, MachineBasicBlock &MBB) {
YamlIO.mapRequired("id", MBB.ID);
YamlIO.mapOptional("name", MBB.Name,
- std::string()); // Don't print out an empty name.
+ StringValue()); // Don't print out an empty name.
YamlIO.mapOptional("alignment", MBB.Alignment);
YamlIO.mapOptional("isLandingPad", MBB.IsLandingPad);
YamlIO.mapOptional("addressTaken", MBB.AddressTaken);
YamlIO.mapOptional("successors", MBB.Successors);
+ YamlIO.mapOptional("liveins", MBB.LiveIns);
YamlIO.mapOptional("instructions", MBB.Instructions);
}
};
+/// Serializable representation of stack object from the MachineFrameInfo class.
+///
+/// The flags 'isImmutable' and 'isAliased' aren't serialized, as they are
+/// determined by the object's type and frame information flags.
+/// Dead stack objects aren't serialized.
+///
+/// TODO: Determine isPreallocated flag by mapping between objects and local
+/// objects (Serialize local objects).
+struct MachineStackObject {
+ enum ObjectType { DefaultType, SpillSlot, VariableSized };
+ // TODO: Serialize LLVM alloca reference.
+ unsigned ID;
+ ObjectType Type = DefaultType;
+ int64_t Offset = 0;
+ uint64_t Size = 0;
+ unsigned Alignment = 0;
+};
+
+template <> struct ScalarEnumerationTraits<MachineStackObject::ObjectType> {
+ static void enumeration(yaml::IO &IO, MachineStackObject::ObjectType &Type) {
+ IO.enumCase(Type, "default", MachineStackObject::DefaultType);
+ IO.enumCase(Type, "spill-slot", MachineStackObject::SpillSlot);
+ IO.enumCase(Type, "variable-sized", MachineStackObject::VariableSized);
+ }
+};
+
+template <> struct MappingTraits<MachineStackObject> {
+ static void mapping(yaml::IO &YamlIO, MachineStackObject &Object) {
+ YamlIO.mapRequired("id", Object.ID);
+ YamlIO.mapOptional(
+ "type", Object.Type,
+ MachineStackObject::DefaultType); // Don't print the default type.
+ YamlIO.mapOptional("offset", Object.Offset);
+ if (Object.Type != MachineStackObject::VariableSized)
+ YamlIO.mapRequired("size", Object.Size);
+ YamlIO.mapOptional("alignment", Object.Alignment);
+ }
+
+ static const bool flow = true;
+};
+
+/// Serializable representation of the fixed stack object from the
+/// MachineFrameInfo class.
+struct FixedMachineStackObject {
+ enum ObjectType { DefaultType, SpillSlot };
+ unsigned ID;
+ ObjectType Type = DefaultType;
+ int64_t Offset = 0;
+ uint64_t Size = 0;
+ unsigned Alignment = 0;
+ bool IsImmutable = false;
+ bool IsAliased = false;
+};
+
+template <>
+struct ScalarEnumerationTraits<FixedMachineStackObject::ObjectType> {
+ static void enumeration(yaml::IO &IO,
+ FixedMachineStackObject::ObjectType &Type) {
+ IO.enumCase(Type, "default", FixedMachineStackObject::DefaultType);
+ IO.enumCase(Type, "spill-slot", FixedMachineStackObject::SpillSlot);
+ }
+};
+
+template <> struct MappingTraits<FixedMachineStackObject> {
+ static void mapping(yaml::IO &YamlIO, FixedMachineStackObject &Object) {
+ YamlIO.mapRequired("id", Object.ID);
+ YamlIO.mapOptional(
+ "type", Object.Type,
+ FixedMachineStackObject::DefaultType); // Don't print the default type.
+ YamlIO.mapOptional("offset", Object.Offset);
+ YamlIO.mapOptional("size", Object.Size);
+ YamlIO.mapOptional("alignment", Object.Alignment);
+ if (Object.Type != FixedMachineStackObject::SpillSlot) {
+ YamlIO.mapOptional("isImmutable", Object.IsImmutable);
+ YamlIO.mapOptional("isAliased", Object.IsAliased);
+ }
+ }
+
+ static const bool flow = true;
+};
+
} // end namespace yaml
} // end namespace llvm
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::VirtualRegisterDefinition)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::MachineBasicBlock)
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::MachineStackObject)
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::FixedMachineStackObject)
namespace llvm {
namespace yaml {
+/// Serializable representation of MachineFrameInfo.
+///
+/// Doesn't serialize attributes like 'StackAlignment', 'IsStackRealignable' and
+/// 'RealignOption' as they are determined by the target and LLVM function
+/// attributes.
+/// It also doesn't serialize attributes like 'NumFixedObject' and
+/// 'HasVarSizedObjects' as they are determined by the frame objects themselves.
+struct MachineFrameInfo {
+ bool IsFrameAddressTaken = false;
+ bool IsReturnAddressTaken = false;
+ bool HasStackMap = false;
+ bool HasPatchPoint = false;
+ uint64_t StackSize = 0;
+ int OffsetAdjustment = 0;
+ unsigned MaxAlignment = 0;
+ bool AdjustsStack = false;
+ bool HasCalls = false;
+ // TODO: Serialize StackProtectorIdx and FunctionContextIdx
+ unsigned MaxCallFrameSize = 0;
+ // TODO: Serialize callee saved info.
+ // TODO: Serialize local frame objects.
+ bool HasOpaqueSPAdjustment = false;
+ bool HasVAStart = false;
+ bool HasMustTailInVarArgFunc = false;
+ // TODO: Serialize save and restore MBB references.
+};
+
+template <> struct MappingTraits<MachineFrameInfo> {
+ static void mapping(IO &YamlIO, MachineFrameInfo &MFI) {
+ YamlIO.mapOptional("isFrameAddressTaken", MFI.IsFrameAddressTaken);
+ YamlIO.mapOptional("isReturnAddressTaken", MFI.IsReturnAddressTaken);
+ YamlIO.mapOptional("hasStackMap", MFI.HasStackMap);
+ YamlIO.mapOptional("hasPatchPoint", MFI.HasPatchPoint);
+ YamlIO.mapOptional("stackSize", MFI.StackSize);
+ YamlIO.mapOptional("offsetAdjustment", MFI.OffsetAdjustment);
+ YamlIO.mapOptional("maxAlignment", MFI.MaxAlignment);
+ YamlIO.mapOptional("adjustsStack", MFI.AdjustsStack);
+ YamlIO.mapOptional("hasCalls", MFI.HasCalls);
+ YamlIO.mapOptional("maxCallFrameSize", MFI.MaxCallFrameSize);
+ YamlIO.mapOptional("hasOpaqueSPAdjustment", MFI.HasOpaqueSPAdjustment);
+ YamlIO.mapOptional("hasVAStart", MFI.HasVAStart);
+ YamlIO.mapOptional("hasMustTailInVarArgFunc", MFI.HasMustTailInVarArgFunc);
+ }
+};
+
struct MachineFunction {
StringRef Name;
unsigned Alignment = 0;
@@ -123,9 +268,13 @@ struct MachineFunction {
bool IsSSA = false;
bool TracksRegLiveness = false;
bool TracksSubRegLiveness = false;
- // TODO: Serialize virtual register definitions.
+ std::vector<VirtualRegisterDefinition> VirtualRegisters;
// TODO: Serialize the various register masks.
// TODO: Serialize live in registers.
+ // Frame information
+ MachineFrameInfo FrameInfo;
+ std::vector<FixedMachineStackObject> FixedStackObjects;
+ std::vector<MachineStackObject> StackObjects;
std::vector<MachineBasicBlock> BasicBlocks;
};
@@ -139,6 +288,10 @@ template <> struct MappingTraits<MachineFunction> {
YamlIO.mapOptional("isSSA", MF.IsSSA);
YamlIO.mapOptional("tracksRegLiveness", MF.TracksRegLiveness);
YamlIO.mapOptional("tracksSubRegLiveness", MF.TracksSubRegLiveness);
+ YamlIO.mapOptional("registers", MF.VirtualRegisters);
+ YamlIO.mapOptional("frameInfo", MF.FrameInfo);
+ YamlIO.mapOptional("fixedStack", MF.FixedStackObjects);
+ YamlIO.mapOptional("stack", MF.StackObjects);
YamlIO.mapOptional("body", MF.BasicBlocks);
}
};
diff --git a/include/llvm/CodeGen/MachineConstantPool.h b/include/llvm/CodeGen/MachineConstantPool.h
index c619afb83333..628400322f60 100644
--- a/include/llvm/CodeGen/MachineConstantPool.h
+++ b/include/llvm/CodeGen/MachineConstantPool.h
@@ -135,17 +135,18 @@ public:
/// address of the function constant pool values.
/// @brief The machine constant pool.
class MachineConstantPool {
- const TargetMachine &TM; ///< The target machine.
unsigned PoolAlignment; ///< The alignment for the pool.
std::vector<MachineConstantPoolEntry> Constants; ///< The pool of constants.
/// MachineConstantPoolValues that use an existing MachineConstantPoolEntry.
DenseSet<MachineConstantPoolValue*> MachineCPVsSharingEntries;
+ const DataLayout &DL;
+
+ const DataLayout &getDataLayout() const { return DL; }
- const DataLayout *getDataLayout() const;
public:
/// @brief The only constructor.
- explicit MachineConstantPool(const TargetMachine &TM)
- : TM(TM), PoolAlignment(1) {}
+ explicit MachineConstantPool(const DataLayout &DL)
+ : PoolAlignment(1), DL(DL) {}
~MachineConstantPool();
/// getConstantPoolAlignment - Return the alignment required by
diff --git a/include/llvm/CodeGen/MachineDominators.h b/include/llvm/CodeGen/MachineDominators.h
index 4428fa618fb0..735dd069cf7f 100644
--- a/include/llvm/CodeGen/MachineDominators.h
+++ b/include/llvm/CodeGen/MachineDominators.h
@@ -29,8 +29,8 @@ inline void DominatorTreeBase<MachineBasicBlock>::addRoot(MachineBasicBlock* MBB
this->Roots.push_back(MBB);
}
-EXTERN_TEMPLATE_INSTANTIATION(class DomTreeNodeBase<MachineBasicBlock>);
-EXTERN_TEMPLATE_INSTANTIATION(class DominatorTreeBase<MachineBasicBlock>);
+extern template class DomTreeNodeBase<MachineBasicBlock>;
+extern template class DominatorTreeBase<MachineBasicBlock>;
typedef DomTreeNodeBase<MachineBasicBlock> MachineDomTreeNode;
diff --git a/include/llvm/CodeGen/MachineFrameInfo.h b/include/llvm/CodeGen/MachineFrameInfo.h
index 0f5a4b1b09ec..cbc4e66ccc46 100644
--- a/include/llvm/CodeGen/MachineFrameInfo.h
+++ b/include/llvm/CodeGen/MachineFrameInfo.h
@@ -229,9 +229,9 @@ class MachineFrameInfo {
/// Whether the "realign-stack" option is on.
bool RealignOption;
- /// True if the function includes inline assembly that adjusts the stack
- /// pointer.
- bool HasInlineAsmWithSPAdjust;
+ /// True if the function dynamically adjusts the stack pointer through some
+ /// opaque mechanism like inline assembly or Win32 EH.
+ bool HasOpaqueSPAdjustment;
/// True if the function contains a call to the llvm.vastart intrinsic.
bool HasVAStart;
@@ -269,7 +269,7 @@ public:
LocalFrameSize = 0;
LocalFrameMaxAlign = 0;
UseLocalStackAllocationBlock = false;
- HasInlineAsmWithSPAdjust = false;
+ HasOpaqueSPAdjustment = false;
HasVAStart = false;
HasMustTailInVarArgFunc = false;
Save = nullptr;
@@ -468,9 +468,9 @@ public:
bool hasCalls() const { return HasCalls; }
void setHasCalls(bool V) { HasCalls = V; }
- /// Returns true if the function contains any stack-adjusting inline assembly.
- bool hasInlineAsmWithSPAdjust() const { return HasInlineAsmWithSPAdjust; }
- void setHasInlineAsmWithSPAdjust(bool B) { HasInlineAsmWithSPAdjust = B; }
+ /// Returns true if the function contains opaque dynamic stack adjustments.
+ bool hasOpaqueSPAdjustment() const { return HasOpaqueSPAdjustment; }
+ void setHasOpaqueSPAdjustment(bool B) { HasOpaqueSPAdjustment = B; }
/// Returns true if the function calls the llvm.va_start intrinsic.
bool hasVAStart() const { return HasVAStart; }
@@ -541,6 +541,14 @@ public:
return Objects[ObjectIdx+NumFixedObjects].Size == ~0ULL;
}
+ /// Returns true if the specified index corresponds to a variable sized
+ /// object.
+ bool isVariableSizedObjectIndex(int ObjectIdx) const {
+ assert(unsigned(ObjectIdx + NumFixedObjects) < Objects.size() &&
+ "Invalid Object Idx!");
+ return Objects[ObjectIdx + NumFixedObjects].Size == 0;
+ }
+
/// Create a new statically sized stack object, returning
/// a nonnegative identifier to represent it.
int CreateStackObject(uint64_t Size, unsigned Alignment, bool isSS,
diff --git a/include/llvm/CodeGen/MachineFunction.h b/include/llvm/CodeGen/MachineFunction.h
index 94610cabf566..c15ee1c006cd 100644
--- a/include/llvm/CodeGen/MachineFunction.h
+++ b/include/llvm/CodeGen/MachineFunction.h
@@ -155,6 +155,9 @@ public:
MachineModuleInfo &getMMI() const { return MMI; }
MCContext &getContext() const { return Ctx; }
+ /// Return the DataLayout attached to the Module associated to this MF.
+ const DataLayout &getDataLayout() const;
+
/// getFunction - Return the LLVM function that this machine code represents
///
const Function *getFunction() const { return Fn; }
diff --git a/include/llvm/CodeGen/MachineLoopInfo.h b/include/llvm/CodeGen/MachineLoopInfo.h
index 438ef2e37255..4868b7363f82 100644
--- a/include/llvm/CodeGen/MachineLoopInfo.h
+++ b/include/llvm/CodeGen/MachineLoopInfo.h
@@ -37,10 +37,8 @@
namespace llvm {
// Implementation in LoopInfoImpl.h
-#ifdef __GNUC__
class MachineLoop;
-__extension__ extern template class LoopBase<MachineBasicBlock, MachineLoop>;
-#endif
+extern template class LoopBase<MachineBasicBlock, MachineLoop>;
class MachineLoop : public LoopBase<MachineBasicBlock, MachineLoop> {
public:
@@ -65,10 +63,7 @@ private:
};
// Implementation in LoopInfoImpl.h
-#ifdef __GNUC__
-__extension__ extern template
-class LoopInfoBase<MachineBasicBlock, MachineLoop>;
-#endif
+extern template class LoopInfoBase<MachineBasicBlock, MachineLoop>;
class MachineLoopInfo : public MachineFunctionPass {
LoopInfoBase<MachineBasicBlock, MachineLoop> LI;
diff --git a/include/llvm/CodeGen/MachineModuleInfo.h b/include/llvm/CodeGen/MachineModuleInfo.h
index ccaa83a238a6..4cdfe2463c99 100644
--- a/include/llvm/CodeGen/MachineModuleInfo.h
+++ b/include/llvm/CodeGen/MachineModuleInfo.h
@@ -320,6 +320,7 @@ public:
/// information.
void addPersonality(MachineBasicBlock *LandingPad,
const Function *Personality);
+ void addPersonality(const Function *Personality);
void addWinEHState(MachineBasicBlock *LandingPad, int State);
diff --git a/include/llvm/CodeGen/MachineRegionInfo.h b/include/llvm/CodeGen/MachineRegionInfo.h
index cf49c297c288..df9823f741dc 100644
--- a/include/llvm/CodeGen/MachineRegionInfo.h
+++ b/include/llvm/CodeGen/MachineRegionInfo.h
@@ -172,10 +172,9 @@ template <> struct GraphTraits<MachineRegionInfoPass*>
}
};
-EXTERN_TEMPLATE_INSTANTIATION(class RegionBase<RegionTraits<MachineFunction>>);
-EXTERN_TEMPLATE_INSTANTIATION(class RegionNodeBase<RegionTraits<MachineFunction>>);
-EXTERN_TEMPLATE_INSTANTIATION(class RegionInfoBase<RegionTraits<MachineFunction>>);
-
+extern template class RegionBase<RegionTraits<MachineFunction>>;
+extern template class RegionNodeBase<RegionTraits<MachineFunction>>;
+extern template class RegionInfoBase<RegionTraits<MachineFunction>>;
}
#endif
diff --git a/include/llvm/CodeGen/MachineRegisterInfo.h b/include/llvm/CodeGen/MachineRegisterInfo.h
index e5b837aeea28..67583be616c3 100644
--- a/include/llvm/CodeGen/MachineRegisterInfo.h
+++ b/include/llvm/CodeGen/MachineRegisterInfo.h
@@ -95,20 +95,8 @@ private:
return MO->Contents.Reg.Next;
}
- /// UsedRegUnits - This is a bit vector that is computed and set by the
- /// register allocator, and must be kept up to date by passes that run after
- /// register allocation (though most don't modify this). This is used
- /// so that the code generator knows which callee save registers to save and
- /// for other target specific uses.
- /// This vector has bits set for register units that are modified in the
- /// current function. It doesn't include registers clobbered by function
- /// calls with register mask operands.
- BitVector UsedRegUnits;
-
/// UsedPhysRegMask - Additional used physregs including aliases.
/// This bit vector represents all the registers clobbered by function calls.
- /// It can model things that UsedRegUnits can't, such as function calls that
- /// clobber ymm7 but preserve the low half in xmm7.
BitVector UsedPhysRegMask;
/// ReservedRegs - This is a bit vector of reserved registers. The target
@@ -647,40 +635,11 @@ public:
/// deleted during LiveDebugVariables analysis.
void markUsesInDebugValueAsUndef(unsigned Reg) const;
- //===--------------------------------------------------------------------===//
- // Physical Register Use Info
- //===--------------------------------------------------------------------===//
-
- /// isPhysRegUsed - Return true if the specified register is used in this
- /// function. Also check for clobbered aliases and registers clobbered by
- /// function calls with register mask operands.
- ///
- /// This only works after register allocation. It is primarily used by
- /// PrologEpilogInserter to determine which callee-saved registers need
- /// spilling.
- bool isPhysRegUsed(unsigned Reg) const {
- if (UsedPhysRegMask.test(Reg))
- return true;
- for (MCRegUnitIterator Units(Reg, getTargetRegisterInfo());
- Units.isValid(); ++Units)
- if (UsedRegUnits.test(*Units))
- return true;
- return false;
- }
-
- /// Mark the specified register unit as used in this function.
- /// This should only be called during and after register allocation.
- void setRegUnitUsed(unsigned RegUnit) {
- UsedRegUnits.set(RegUnit);
- }
-
- /// setPhysRegUsed - Mark the specified register used in this function.
- /// This should only be called during and after register allocation.
- void setPhysRegUsed(unsigned Reg) {
- for (MCRegUnitIterator Units(Reg, getTargetRegisterInfo());
- Units.isValid(); ++Units)
- UsedRegUnits.set(*Units);
- }
+ /// Return true if the specified register is modified in this function.
+ /// This checks that no defining machine operands exist for the register or
+ /// any of its aliases. Definitions found on functions marked noreturn are
+ /// ignored.
+ bool isPhysRegModified(unsigned PhysReg) const;
/// addPhysRegsUsedFromRegMask - Mark any registers not in RegMask as used.
/// This corresponds to the bit mask attached to register mask operands.
@@ -688,16 +647,6 @@ public:
UsedPhysRegMask.setBitsNotInMask(RegMask);
}
- /// setPhysRegUnused - Mark the specified register unused in this function.
- /// This should only be called during and after register allocation.
- void setPhysRegUnused(unsigned Reg) {
- UsedPhysRegMask.reset(Reg);
- for (MCRegUnitIterator Units(Reg, getTargetRegisterInfo());
- Units.isValid(); ++Units)
- UsedRegUnits.reset(*Units);
- }
-
-
//===--------------------------------------------------------------------===//
// Reserved Register Info
//===--------------------------------------------------------------------===//
diff --git a/include/llvm/CodeGen/Passes.h b/include/llvm/CodeGen/Passes.h
index 538c995a7b44..5d8292174476 100644
--- a/include/llvm/CodeGen/Passes.h
+++ b/include/llvm/CodeGen/Passes.h
@@ -101,7 +101,7 @@ public:
private:
PassManagerBase *PM;
- AnalysisID StartAfter;
+ AnalysisID StartBefore, StartAfter;
AnalysisID StopAfter;
bool Started;
bool Stopped;
@@ -142,16 +142,24 @@ public:
CodeGenOpt::Level getOptLevel() const { return TM->getOptLevel(); }
- /// setStartStopPasses - Set the StartAfter and StopAfter passes to allow
- /// running only a portion of the normal code-gen pass sequence. If the
- /// Start pass ID is zero, then compilation will begin at the normal point;
- /// otherwise, clear the Started flag to indicate that passes should not be
- /// added until the starting pass is seen. If the Stop pass ID is zero,
- /// then compilation will continue to the end.
- void setStartStopPasses(AnalysisID Start, AnalysisID Stop) {
- StartAfter = Start;
- StopAfter = Stop;
- Started = (StartAfter == nullptr);
+ /// Set the StartAfter, StartBefore and StopAfter passes to allow running only
+ /// a portion of the normal code-gen pass sequence.
+ ///
+ /// If the StartAfter and StartBefore pass ID is zero, then compilation will
+ /// begin at the normal point; otherwise, clear the Started flag to indicate
+ /// that passes should not be added until the starting pass is seen. If the
+ /// Stop pass ID is zero, then compilation will continue to the end.
+ ///
+ /// This function expects that at least one of the StartAfter or the
+ /// StartBefore pass IDs is null.
+ void setStartStopPasses(AnalysisID StartBefore, AnalysisID StartAfter,
+ AnalysisID StopAfter) {
+ if (StartAfter)
+ assert(!StartBefore && "Start after and start before passes are given");
+ this->StartBefore = StartBefore;
+ this->StartAfter = StartAfter;
+ this->StopAfter = StopAfter;
+ Started = (StartAfter == nullptr) && (StartBefore == nullptr);
}
void setDisableVerify(bool Disable) { setOpt(DisableVerify, Disable); }
@@ -597,7 +605,7 @@ namespace llvm {
/// createSjLjEHPreparePass - This pass adapts exception handling code to use
/// the GCC-style builtin setjmp/longjmp (sjlj) to handling EH control flow.
///
- FunctionPass *createSjLjEHPreparePass(const TargetMachine *TM);
+ FunctionPass *createSjLjEHPreparePass();
/// LocalStackSlotAllocation - This pass assigns local frame indices to stack
/// slots relative to one another and allocates base registers to access them
diff --git a/include/llvm/CodeGen/RegisterPressure.h b/include/llvm/CodeGen/RegisterPressure.h
index fcb6feed68ca..9d8843d1d74a 100644
--- a/include/llvm/CodeGen/RegisterPressure.h
+++ b/include/llvm/CodeGen/RegisterPressure.h
@@ -135,6 +135,8 @@ public:
void addPressureChange(unsigned RegUnit, bool IsDec,
const MachineRegisterInfo *MRI);
+
+ LLVM_DUMP_METHOD void dump(const TargetRegisterInfo &TRI) const;
};
/// Array of PressureDiffs.
diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h
index c2b1243ee26e..1ee92380e690 100644
--- a/include/llvm/CodeGen/SelectionDAG.h
+++ b/include/llvm/CodeGen/SelectionDAG.h
@@ -281,6 +281,7 @@ public:
void clear();
MachineFunction &getMachineFunction() const { return *MF; }
+ const DataLayout &getDataLayout() const { return MF->getDataLayout(); }
const TargetMachine &getTarget() const { return TM; }
const TargetSubtargetInfo &getSubtarget() const { return MF->getSubtarget(); }
const TargetLowering &getTargetLoweringInfo() const { return *TLI; }
@@ -322,6 +323,14 @@ public:
return AllNodes.size();
}
+ iterator_range<allnodes_iterator> allnodes() {
+ return iterator_range<allnodes_iterator>(allnodes_begin(), allnodes_end());
+ }
+ iterator_range<allnodes_const_iterator> allnodes() const {
+ return iterator_range<allnodes_const_iterator>(allnodes_begin(),
+ allnodes_end());
+ }
+
/// Return the root tag of the SelectionDAG.
const SDValue &getRoot() const { return Root; }
diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h
index 619119096d20..4821d1aae9e5 100644
--- a/include/llvm/CodeGen/SelectionDAGNodes.h
+++ b/include/llvm/CodeGen/SelectionDAGNodes.h
@@ -140,7 +140,7 @@ public:
}
// Return true if this node is an operand of N.
- bool isOperandOf(SDNode *N) const;
+ bool isOperandOf(const SDNode *N) const;
/// Return the ValueType of the referenced return value.
inline EVT getValueType() const;
@@ -357,9 +357,6 @@ private:
/// The number of entries in the Operand/Value list.
unsigned short NumOperands, NumValues;
- /// Source line information.
- DebugLoc debugLoc;
-
// The ordering of the SDNodes. It roughly corresponds to the ordering of the
// original LLVM instructions.
// This is used for turning off scheduling, because we'll forgo
@@ -367,6 +364,9 @@ private:
// this ordering.
unsigned IROrder;
+ /// Source line information.
+ DebugLoc debugLoc;
+
/// Return a pointer to the specified value type.
static const EVT *getValueTypeList(EVT VT);
@@ -532,10 +532,10 @@ public:
bool hasAnyUseOfValue(unsigned Value) const;
/// Return true if this node is the only use of N.
- bool isOnlyUserOf(SDNode *N) const;
+ bool isOnlyUserOf(const SDNode *N) const;
/// Return true if this node is an operand of N.
- bool isOperandOf(SDNode *N) const;
+ bool isOperandOf(const SDNode *N) const;
/// Return true if this node is a predecessor of N.
/// NOTE: Implemented on top of hasPredecessor and every bit as
@@ -732,7 +732,7 @@ protected:
SubclassData(0), NodeId(-1),
OperandList(Ops.size() ? new SDUse[Ops.size()] : nullptr),
ValueList(VTs.VTs), UseList(nullptr), NumOperands(Ops.size()),
- NumValues(VTs.NumVTs), debugLoc(std::move(dl)), IROrder(Order) {
+ NumValues(VTs.NumVTs), IROrder(Order), debugLoc(std::move(dl)) {
assert(debugLoc.hasTrivialDestructor() && "Expected trivial destructor");
assert(NumOperands == Ops.size() &&
"NumOperands wasn't wide enough for its operands!");
@@ -752,7 +752,7 @@ protected:
: NodeType(Opc), OperandsNeedDelete(false), HasDebugValue(false),
SubclassData(0), NodeId(-1), OperandList(nullptr), ValueList(VTs.VTs),
UseList(nullptr), NumOperands(0), NumValues(VTs.NumVTs),
- debugLoc(std::move(dl)), IROrder(Order) {
+ IROrder(Order), debugLoc(std::move(dl)) {
assert(debugLoc.hasTrivialDestructor() && "Expected trivial destructor");
assert(NumValues == VTs.NumVTs &&
"NumValues wasn't wide enough for its operands!");
diff --git a/include/llvm/CodeGen/StackMaps.h b/include/llvm/CodeGen/StackMaps.h
index 46a773f74aac..fdc1a9143ed2 100644
--- a/include/llvm/CodeGen/StackMaps.h
+++ b/include/llvm/CodeGen/StackMaps.h
@@ -1,5 +1,4 @@
//===------------------- StackMaps.h - StackMaps ----------------*- C++ -*-===//
-
//
// The LLVM Compiler Infrastructure
//
@@ -42,10 +41,12 @@ class PatchPointOpers {
public:
/// Enumerate the meta operands.
enum { IDPos, NBytesPos, TargetPos, NArgPos, CCPos, MetaEnd };
+
private:
const MachineInstr *MI;
bool HasDef;
bool IsAnyReg;
+
public:
explicit PatchPointOpers(const MachineInstr *MI);
@@ -66,8 +67,8 @@ public:
/// Get the operand index of the variable list of non-argument operands.
/// These hold the "live state".
unsigned getVarIdx() const {
- return getMetaIdx() + MetaEnd
- + MI->getOperand(getMetaIdx(NArgPos)).getImm();
+ return getMetaIdx() + MetaEnd +
+ MI->getOperand(getMetaIdx(NArgPos)).getImm();
}
/// Get the index at which stack map locations will be recorded.
@@ -98,15 +99,10 @@ private:
// These values are relative offests from the start of the statepoint meta
// arguments (i.e. the end of the call arguments).
- enum {
- CCOffset = 1,
- FlagsOffset = 3,
- NumVMSArgsOffset = 5
- };
+ enum { CCOffset = 1, FlagsOffset = 3, NumVMSArgsOffset = 5 };
public:
- explicit StatepointOpers(const MachineInstr *MI):
- MI(MI) { }
+ explicit StatepointOpers(const MachineInstr *MI) : MI(MI) {}
/// Get starting index of non call related arguments
/// (calling convention, statepoint flags, vm state and gc state).
@@ -134,31 +130,32 @@ private:
class StackMaps {
public:
struct Location {
- enum LocationType { Unprocessed, Register, Direct, Indirect, Constant,
- ConstantIndex };
- LocationType LocType;
+ enum LocationType {
+ Unprocessed,
+ Register,
+ Direct,
+ Indirect,
+ Constant,
+ ConstantIndex
+ };
+ LocationType Type;
unsigned Size;
unsigned Reg;
int64_t Offset;
- Location() : LocType(Unprocessed), Size(0), Reg(0), Offset(0) {}
- Location(LocationType LocType, unsigned Size, unsigned Reg, int64_t Offset)
- : LocType(LocType), Size(Size), Reg(Reg), Offset(Offset) {}
+ Location() : Type(Unprocessed), Size(0), Reg(0), Offset(0) {}
+ Location(LocationType Type, unsigned Size, unsigned Reg, int64_t Offset)
+ : Type(Type), Size(Size), Reg(Reg), Offset(Offset) {}
};
struct LiveOutReg {
unsigned short Reg;
- unsigned short RegNo;
+ unsigned short DwarfRegNum;
unsigned short Size;
- LiveOutReg() : Reg(0), RegNo(0), Size(0) {}
- LiveOutReg(unsigned short Reg, unsigned short RegNo, unsigned short Size)
- : Reg(Reg), RegNo(RegNo), Size(Size) {}
-
- void MarkInvalid() { Reg = 0; }
-
- // Only sort by the dwarf register number.
- bool operator< (const LiveOutReg &LO) const { return RegNo < LO.RegNo; }
- static bool IsInvalid(const LiveOutReg &LO) { return LO.Reg == 0; }
+ LiveOutReg() : Reg(0), DwarfRegNum(0), Size(0) {}
+ LiveOutReg(unsigned short Reg, unsigned short DwarfRegNum,
+ unsigned short Size)
+ : Reg(Reg), DwarfRegNum(DwarfRegNum), Size(Size) {}
};
// OpTypes are used to encode information about the following logical
@@ -205,8 +202,8 @@ private:
CallsiteInfo() : CSOffsetExpr(nullptr), ID(0) {}
CallsiteInfo(const MCExpr *CSOffsetExpr, uint64_t ID,
LocationVec &&Locations, LiveOutVec &&LiveOuts)
- : CSOffsetExpr(CSOffsetExpr), ID(ID), Locations(std::move(Locations)),
- LiveOuts(std::move(LiveOuts)) {}
+ : CSOffsetExpr(CSOffsetExpr), ID(ID), Locations(std::move(Locations)),
+ LiveOuts(std::move(LiveOuts)) {}
};
typedef std::vector<CallsiteInfo> CallsiteInfoList;
@@ -218,8 +215,8 @@ private:
MachineInstr::const_mop_iterator
parseOperand(MachineInstr::const_mop_iterator MOI,
- MachineInstr::const_mop_iterator MOE,
- LocationVec &Locs, LiveOutVec &LiveOuts) const;
+ MachineInstr::const_mop_iterator MOE, LocationVec &Locs,
+ LiveOutVec &LiveOuts) const;
/// \brief Create a live-out register record for the given register @p Reg.
LiveOutReg createLiveOutReg(unsigned Reg,
@@ -254,7 +251,6 @@ private:
void print(raw_ostream &OS);
void debug() { print(dbgs()); }
};
-
}
#endif
diff --git a/include/llvm/CodeGen/WinEHFuncInfo.h b/include/llvm/CodeGen/WinEHFuncInfo.h
index 291f3905512c..75638a058a30 100644
--- a/include/llvm/CodeGen/WinEHFuncInfo.h
+++ b/include/llvm/CodeGen/WinEHFuncInfo.h
@@ -91,7 +91,7 @@ private:
// When the parseEHActions function is called to populate a vector of
// instances of this class, the ExceptionObjectVar field will be nullptr
// and the ExceptionObjectIndex will be the index of the exception object in
- // the parent function's frameescape block.
+ // the parent function's localescape block.
const Value *ExceptionObjectVar;
int ExceptionObjectIndex;
TinyPtrVector<BasicBlock *> ReturnTargets;
@@ -148,7 +148,7 @@ struct WinEHFuncInfo {
int UnwindHelpFrameOffset = -1;
unsigned NumIPToStateFuncsVisited = 0;
- /// frameescape index of the 32-bit EH registration node. Set by
+ /// localescape index of the 32-bit EH registration node. Set by
/// WinEHStatePass and used indirectly by SEH filter functions of the parent.
int EHRegNodeEscapeIndex = INT_MAX;
diff --git a/include/llvm/ExecutionEngine/ExecutionEngine.h b/include/llvm/ExecutionEngine/ExecutionEngine.h
index e8af601d83b6..821c0181ce83 100644
--- a/include/llvm/ExecutionEngine/ExecutionEngine.h
+++ b/include/llvm/ExecutionEngine/ExecutionEngine.h
@@ -31,6 +31,7 @@
#include <map>
#include <string>
#include <vector>
+#include <functional>
namespace llvm {
@@ -89,6 +90,8 @@ public:
uint64_t RemoveMapping(StringRef Name);
};
+using FunctionCreator = std::function<void *(const std::string &)>;
+
/// \brief Abstract interface for implementation execution of LLVM modules,
/// designed to support both interpreter and just-in-time (JIT) compiler
/// implementations.
@@ -147,7 +150,7 @@ protected:
/// LazyFunctionCreator - If an unknown function is needed, this function
/// pointer is invoked to create it. If this returns null, the JIT will
/// abort.
- void *(*LazyFunctionCreator)(const std::string &);
+ FunctionCreator LazyFunctionCreator;
/// getMangledName - Get mangled name.
std::string getMangledName(const GlobalValue *GV);
@@ -470,8 +473,8 @@ public:
/// InstallLazyFunctionCreator - If an unknown function is needed, the
/// specified function pointer is invoked to create it. If it returns null,
/// the JIT will abort.
- void InstallLazyFunctionCreator(void* (*P)(const std::string &)) {
- LazyFunctionCreator = P;
+ void InstallLazyFunctionCreator(FunctionCreator C) {
+ LazyFunctionCreator = C;
}
protected:
diff --git a/include/llvm/ExecutionEngine/RuntimeDyld.h b/include/llvm/ExecutionEngine/RuntimeDyld.h
index 94c4038e8183..a808d9231167 100644
--- a/include/llvm/ExecutionEngine/RuntimeDyld.h
+++ b/include/llvm/ExecutionEngine/RuntimeDyld.h
@@ -153,6 +153,10 @@ public:
/// This method returns the address of the specified function or variable.
/// It is used to resolve symbols during module linking.
+ ///
+ /// If the returned symbol's address is equal to ~0ULL then RuntimeDyld will
+ /// skip all relocations for that symbol, and the client will be responsible
+ /// for handling them manually.
virtual SymbolInfo findSymbol(const std::string &Name) = 0;
/// This method returns the address of the specified symbol if it exists
diff --git a/include/llvm/IR/Attributes.h b/include/llvm/IR/Attributes.h
index 366bf709ab16..4d6d7da1fa5b 100644
--- a/include/llvm/IR/Attributes.h
+++ b/include/llvm/IR/Attributes.h
@@ -98,6 +98,8 @@ public:
OptimizeNone, ///< Function must not be optimized.
ReadNone, ///< Function does not access memory
ReadOnly, ///< Function only reads from memory
+ ArgMemOnly, ///< Funciton can access memory only using pointers
+ ///< based on its arguments.
Returned, ///< Return value is always equal to this argument
ReturnsTwice, ///< Function can return twice
SExt, ///< Sign extended before/after call
diff --git a/include/llvm/IR/CallSite.h b/include/llvm/IR/CallSite.h
index dd2903e807e1..2841781e8a9e 100644
--- a/include/llvm/IR/CallSite.h
+++ b/include/llvm/IR/CallSite.h
@@ -290,6 +290,15 @@ public:
CALLSITE_DELEGATE_SETTER(setOnlyReadsMemory());
}
+ /// @brief Determine if the call can access memmory only using pointers based
+ /// on its arguments.
+ bool onlyAccessesArgMemory() const {
+ CALLSITE_DELEGATE_GETTER(onlyAccessesArgMemory());
+ }
+ void setOnlyAccessesArgMemory() {
+ CALLSITE_DELEGATE_SETTER(setOnlyAccessesArgMemory());
+ }
+
/// @brief Determine if the call cannot return.
bool doesNotReturn() const {
CALLSITE_DELEGATE_GETTER(doesNotReturn());
diff --git a/include/llvm/IR/DIBuilder.h b/include/llvm/IR/DIBuilder.h
index d6296b622aab..aa43c02d5cd8 100644
--- a/include/llvm/IR/DIBuilder.h
+++ b/include/llvm/IR/DIBuilder.h
@@ -47,7 +47,7 @@ namespace llvm {
SmallVector<Metadata *, 4> AllGVs;
SmallVector<TrackingMDNodeRef, 4> AllImportedModules;
- /// \brief Track nodes that may be unresolved.
+ /// Track nodes that may be unresolved.
SmallVector<TrackingMDNodeRef, 4> UnresolvedNodes;
bool AllowUnresolvedNodes;
@@ -57,49 +57,52 @@ namespace llvm {
DIBuilder(const DIBuilder &) = delete;
void operator=(const DIBuilder &) = delete;
- /// \brief Create a temporary.
+ /// Create a temporary.
///
/// Create an \a temporary node and track it in \a UnresolvedNodes.
void trackIfUnresolved(MDNode *N);
public:
- /// \brief Construct a builder for a module.
+ /// Construct a builder for a module.
///
/// If \c AllowUnresolved, collect unresolved nodes attached to the module
/// in order to resolve cycles during \a finalize().
explicit DIBuilder(Module &M, bool AllowUnresolved = true);
enum DebugEmissionKind { FullDebug=1, LineTablesOnly };
- /// finalize - Construct any deferred debug info descriptors.
+ /// Construct any deferred debug info descriptors.
void finalize();
- /// createCompileUnit - A CompileUnit provides an anchor for all debugging
+ /// A CompileUnit provides an anchor for all debugging
/// information generated during this instance of compilation.
- /// @param Lang Source programming language, eg. dwarf::DW_LANG_C99
- /// @param File File name
- /// @param Dir Directory
- /// @param Producer Identify the producer of debugging information and code.
- /// Usually this is a compiler version string.
- /// @param isOptimized A boolean flag which indicates whether optimization
- /// is ON or not.
- /// @param Flags This string lists command line options. This string is
- /// directly embedded in debug info output which may be used
- /// by a tool analyzing generated debugging information.
- /// @param RV This indicates runtime version for languages like
- /// Objective-C.
- /// @param SplitName The name of the file that we'll split debug info out
- /// into.
- /// @param Kind The kind of debug information to generate.
- /// @param DWOId The DWOId if this is a split skeleton compile unit.
- /// @param EmitDebugInfo A boolean flag which indicates whether debug
- /// information should be written to the final
- /// output or not. When this is false, debug
- /// information annotations will be present in
- /// the IL but they are not written to the final
- /// assembly or object file. This supports tracking
- /// source location information in the back end
- /// without actually changing the output (e.g.,
- /// when using optimization remarks).
+ /// \param Lang Source programming language, eg. dwarf::DW_LANG_C99
+ /// \param File File name
+ /// \param Dir Directory
+ /// \param Producer Identify the producer of debugging information
+ /// and code. Usually this is a compiler
+ /// version string.
+ /// \param isOptimized A boolean flag which indicates whether optimization
+ /// is enabled or not.
+ /// \param Flags This string lists command line options. This
+ /// string is directly embedded in debug info
+ /// output which may be used by a tool
+ /// analyzing generated debugging information.
+ /// \param RV This indicates runtime version for languages like
+ /// Objective-C.
+ /// \param SplitName The name of the file that we'll split debug info
+ /// out into.
+ /// \param Kind The kind of debug information to generate.
+ /// \param DWOId The DWOId if this is a split skeleton compile unit.
+ /// \param EmitDebugInfo A boolean flag which indicates whether
+ /// debug information should be written to
+ /// the final output or not. When this is
+ /// false, debug information annotations will
+ /// be present in the IL but they are not
+ /// written to the final assembly or object
+ /// file. This supports tracking source
+ /// location information in the back end
+ /// without actually changing the output
+ /// (e.g., when using optimization remarks).
DICompileUnit *
createCompileUnit(unsigned Lang, StringRef File, StringRef Dir,
StringRef Producer, bool isOptimized, StringRef Flags,
@@ -107,155 +110,155 @@ namespace llvm {
DebugEmissionKind Kind = FullDebug, uint64_t DWOId = 0,
bool EmitDebugInfo = true);
- /// createFile - Create a file descriptor to hold debugging information
+ /// Create a file descriptor to hold debugging information
/// for a file.
DIFile *createFile(StringRef Filename, StringRef Directory);
- /// createEnumerator - Create a single enumerator value.
+ /// Create a single enumerator value.
DIEnumerator *createEnumerator(StringRef Name, int64_t Val);
- /// \brief Create a DWARF unspecified type.
+ /// Create a DWARF unspecified type.
DIBasicType *createUnspecifiedType(StringRef Name);
- /// \brief Create C++11 nullptr type.
+ /// Create C++11 nullptr type.
DIBasicType *createNullPtrType();
- /// createBasicType - Create debugging information entry for a basic
+ /// Create debugging information entry for a basic
/// type.
- /// @param Name Type name.
- /// @param SizeInBits Size of the type.
- /// @param AlignInBits Type alignment.
- /// @param Encoding DWARF encoding code, e.g. dwarf::DW_ATE_float.
+ /// \param Name Type name.
+ /// \param SizeInBits Size of the type.
+ /// \param AlignInBits Type alignment.
+ /// \param Encoding DWARF encoding code, e.g. dwarf::DW_ATE_float.
DIBasicType *createBasicType(StringRef Name, uint64_t SizeInBits,
uint64_t AlignInBits, unsigned Encoding);
- /// createQualifiedType - Create debugging information entry for a qualified
+ /// Create debugging information entry for a qualified
/// type, e.g. 'const int'.
- /// @param Tag Tag identifing type, e.g. dwarf::TAG_volatile_type
- /// @param FromTy Base Type.
+ /// \param Tag Tag identifing type, e.g. dwarf::TAG_volatile_type
+ /// \param FromTy Base Type.
DIDerivedType *createQualifiedType(unsigned Tag, DIType *FromTy);
- /// createPointerType - Create debugging information entry for a pointer.
- /// @param PointeeTy Type pointed by this pointer.
- /// @param SizeInBits Size.
- /// @param AlignInBits Alignment. (optional)
- /// @param Name Pointer type name. (optional)
+ /// Create debugging information entry for a pointer.
+ /// \param PointeeTy Type pointed by this pointer.
+ /// \param SizeInBits Size.
+ /// \param AlignInBits Alignment. (optional)
+ /// \param Name Pointer type name. (optional)
DIDerivedType *createPointerType(DIType *PointeeTy, uint64_t SizeInBits,
uint64_t AlignInBits = 0,
StringRef Name = "");
- /// \brief Create debugging information entry for a pointer to member.
- /// @param PointeeTy Type pointed to by this pointer.
- /// @param SizeInBits Size.
- /// @param AlignInBits Alignment. (optional)
- /// @param Class Type for which this pointer points to members of.
+ /// Create debugging information entry for a pointer to member.
+ /// \param PointeeTy Type pointed to by this pointer.
+ /// \param SizeInBits Size.
+ /// \param AlignInBits Alignment. (optional)
+ /// \param Class Type for which this pointer points to members of.
DIDerivedType *createMemberPointerType(DIType *PointeeTy, DIType *Class,
uint64_t SizeInBits,
uint64_t AlignInBits = 0);
- /// createReferenceType - Create debugging information entry for a c++
+ /// Create debugging information entry for a c++
/// style reference or rvalue reference type.
DIDerivedType *createReferenceType(unsigned Tag, DIType *RTy);
- /// createTypedef - Create debugging information entry for a typedef.
- /// @param Ty Original type.
- /// @param Name Typedef name.
- /// @param File File where this type is defined.
- /// @param LineNo Line number.
- /// @param Context The surrounding context for the typedef.
+ /// Create debugging information entry for a typedef.
+ /// \param Ty Original type.
+ /// \param Name Typedef name.
+ /// \param File File where this type is defined.
+ /// \param LineNo Line number.
+ /// \param Context The surrounding context for the typedef.
DIDerivedType *createTypedef(DIType *Ty, StringRef Name, DIFile *File,
unsigned LineNo, DIScope *Context);
- /// createFriend - Create debugging information entry for a 'friend'.
+ /// Create debugging information entry for a 'friend'.
DIDerivedType *createFriend(DIType *Ty, DIType *FriendTy);
- /// createInheritance - Create debugging information entry to establish
+ /// Create debugging information entry to establish
/// inheritance relationship between two types.
- /// @param Ty Original type.
- /// @param BaseTy Base type. Ty is inherits from base.
- /// @param BaseOffset Base offset.
- /// @param Flags Flags to describe inheritance attribute,
+ /// \param Ty Original type.
+ /// \param BaseTy Base type. Ty is inherits from base.
+ /// \param BaseOffset Base offset.
+ /// \param Flags Flags to describe inheritance attribute,
/// e.g. private
DIDerivedType *createInheritance(DIType *Ty, DIType *BaseTy,
uint64_t BaseOffset, unsigned Flags);
- /// createMemberType - Create debugging information entry for a member.
- /// @param Scope Member scope.
- /// @param Name Member name.
- /// @param File File where this member is defined.
- /// @param LineNo Line number.
- /// @param SizeInBits Member size.
- /// @param AlignInBits Member alignment.
- /// @param OffsetInBits Member offset.
- /// @param Flags Flags to encode member attribute, e.g. private
- /// @param Ty Parent type.
+ /// Create debugging information entry for a member.
+ /// \param Scope Member scope.
+ /// \param Name Member name.
+ /// \param File File where this member is defined.
+ /// \param LineNo Line number.
+ /// \param SizeInBits Member size.
+ /// \param AlignInBits Member alignment.
+ /// \param OffsetInBits Member offset.
+ /// \param Flags Flags to encode member attribute, e.g. private
+ /// \param Ty Parent type.
DIDerivedType *createMemberType(DIScope *Scope, StringRef Name,
DIFile *File, unsigned LineNo,
uint64_t SizeInBits, uint64_t AlignInBits,
uint64_t OffsetInBits, unsigned Flags,
DIType *Ty);
- /// createStaticMemberType - Create debugging information entry for a
+ /// Create debugging information entry for a
/// C++ static data member.
- /// @param Scope Member scope.
- /// @param Name Member name.
- /// @param File File where this member is declared.
- /// @param LineNo Line number.
- /// @param Ty Type of the static member.
- /// @param Flags Flags to encode member attribute, e.g. private.
- /// @param Val Const initializer of the member.
+ /// \param Scope Member scope.
+ /// \param Name Member name.
+ /// \param File File where this member is declared.
+ /// \param LineNo Line number.
+ /// \param Ty Type of the static member.
+ /// \param Flags Flags to encode member attribute, e.g. private.
+ /// \param Val Const initializer of the member.
DIDerivedType *createStaticMemberType(DIScope *Scope, StringRef Name,
DIFile *File, unsigned LineNo,
DIType *Ty, unsigned Flags,
llvm::Constant *Val);
- /// createObjCIVar - Create debugging information entry for Objective-C
+ /// Create debugging information entry for Objective-C
/// instance variable.
- /// @param Name Member name.
- /// @param File File where this member is defined.
- /// @param LineNo Line number.
- /// @param SizeInBits Member size.
- /// @param AlignInBits Member alignment.
- /// @param OffsetInBits Member offset.
- /// @param Flags Flags to encode member attribute, e.g. private
- /// @param Ty Parent type.
- /// @param PropertyNode Property associated with this ivar.
+ /// \param Name Member name.
+ /// \param File File where this member is defined.
+ /// \param LineNo Line number.
+ /// \param SizeInBits Member size.
+ /// \param AlignInBits Member alignment.
+ /// \param OffsetInBits Member offset.
+ /// \param Flags Flags to encode member attribute, e.g. private
+ /// \param Ty Parent type.
+ /// \param PropertyNode Property associated with this ivar.
DIDerivedType *createObjCIVar(StringRef Name, DIFile *File, unsigned LineNo,
uint64_t SizeInBits, uint64_t AlignInBits,
uint64_t OffsetInBits, unsigned Flags,
DIType *Ty, MDNode *PropertyNode);
- /// createObjCProperty - Create debugging information entry for Objective-C
+ /// Create debugging information entry for Objective-C
/// property.
- /// @param Name Property name.
- /// @param File File where this property is defined.
- /// @param LineNumber Line number.
- /// @param GetterName Name of the Objective C property getter selector.
- /// @param SetterName Name of the Objective C property setter selector.
- /// @param PropertyAttributes Objective C property attributes.
- /// @param Ty Type.
+ /// \param Name Property name.
+ /// \param File File where this property is defined.
+ /// \param LineNumber Line number.
+ /// \param GetterName Name of the Objective C property getter selector.
+ /// \param SetterName Name of the Objective C property setter selector.
+ /// \param PropertyAttributes Objective C property attributes.
+ /// \param Ty Type.
DIObjCProperty *createObjCProperty(StringRef Name, DIFile *File,
unsigned LineNumber,
StringRef GetterName,
StringRef SetterName,
unsigned PropertyAttributes, DIType *Ty);
- /// createClassType - Create debugging information entry for a class.
- /// @param Scope Scope in which this class is defined.
- /// @param Name class name.
- /// @param File File where this member is defined.
- /// @param LineNumber Line number.
- /// @param SizeInBits Member size.
- /// @param AlignInBits Member alignment.
- /// @param OffsetInBits Member offset.
- /// @param Flags Flags to encode member attribute, e.g. private
- /// @param Elements class members.
- /// @param VTableHolder Debug info of the base class that contains vtable
+ /// Create debugging information entry for a class.
+ /// \param Scope Scope in which this class is defined.
+ /// \param Name class name.
+ /// \param File File where this member is defined.
+ /// \param LineNumber Line number.
+ /// \param SizeInBits Member size.
+ /// \param AlignInBits Member alignment.
+ /// \param OffsetInBits Member offset.
+ /// \param Flags Flags to encode member attribute, e.g. private
+ /// \param Elements class members.
+ /// \param VTableHolder Debug info of the base class that contains vtable
/// for this type. This is used in
/// DW_AT_containing_type. See DWARF documentation
/// for more info.
- /// @param TemplateParms Template type parameters.
- /// @param UniqueIdentifier A unique identifier for the class.
+ /// \param TemplateParms Template type parameters.
+ /// \param UniqueIdentifier A unique identifier for the class.
DICompositeType *createClassType(DIScope *Scope, StringRef Name,
DIFile *File, unsigned LineNumber,
uint64_t SizeInBits, uint64_t AlignInBits,
@@ -265,34 +268,34 @@ namespace llvm {
MDNode *TemplateParms = nullptr,
StringRef UniqueIdentifier = "");
- /// createStructType - Create debugging information entry for a struct.
- /// @param Scope Scope in which this struct is defined.
- /// @param Name Struct name.
- /// @param File File where this member is defined.
- /// @param LineNumber Line number.
- /// @param SizeInBits Member size.
- /// @param AlignInBits Member alignment.
- /// @param Flags Flags to encode member attribute, e.g. private
- /// @param Elements Struct elements.
- /// @param RunTimeLang Optional parameter, Objective-C runtime version.
- /// @param UniqueIdentifier A unique identifier for the struct.
+ /// Create debugging information entry for a struct.
+ /// \param Scope Scope in which this struct is defined.
+ /// \param Name Struct name.
+ /// \param File File where this member is defined.
+ /// \param LineNumber Line number.
+ /// \param SizeInBits Member size.
+ /// \param AlignInBits Member alignment.
+ /// \param Flags Flags to encode member attribute, e.g. private
+ /// \param Elements Struct elements.
+ /// \param RunTimeLang Optional parameter, Objective-C runtime version.
+ /// \param UniqueIdentifier A unique identifier for the struct.
DICompositeType *createStructType(
DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNumber,
uint64_t SizeInBits, uint64_t AlignInBits, unsigned Flags,
DIType *DerivedFrom, DINodeArray Elements, unsigned RunTimeLang = 0,
DIType *VTableHolder = nullptr, StringRef UniqueIdentifier = "");
- /// createUnionType - Create debugging information entry for an union.
- /// @param Scope Scope in which this union is defined.
- /// @param Name Union name.
- /// @param File File where this member is defined.
- /// @param LineNumber Line number.
- /// @param SizeInBits Member size.
- /// @param AlignInBits Member alignment.
- /// @param Flags Flags to encode member attribute, e.g. private
- /// @param Elements Union elements.
- /// @param RunTimeLang Optional parameter, Objective-C runtime version.
- /// @param UniqueIdentifier A unique identifier for the union.
+ /// Create debugging information entry for an union.
+ /// \param Scope Scope in which this union is defined.
+ /// \param Name Union name.
+ /// \param File File where this member is defined.
+ /// \param LineNumber Line number.
+ /// \param SizeInBits Member size.
+ /// \param AlignInBits Member alignment.
+ /// \param Flags Flags to encode member attribute, e.g. private
+ /// \param Elements Union elements.
+ /// \param RunTimeLang Optional parameter, Objective-C runtime version.
+ /// \param UniqueIdentifier A unique identifier for the union.
DICompositeType *createUnionType(DIScope *Scope, StringRef Name,
DIFile *File, unsigned LineNumber,
uint64_t SizeInBits, uint64_t AlignInBits,
@@ -300,95 +303,95 @@ namespace llvm {
unsigned RunTimeLang = 0,
StringRef UniqueIdentifier = "");
- /// createTemplateTypeParameter - Create debugging information for template
+ /// Create debugging information for template
/// type parameter.
- /// @param Scope Scope in which this type is defined.
- /// @param Name Type parameter name.
- /// @param Ty Parameter type.
+ /// \param Scope Scope in which this type is defined.
+ /// \param Name Type parameter name.
+ /// \param Ty Parameter type.
DITemplateTypeParameter *
createTemplateTypeParameter(DIScope *Scope, StringRef Name, DIType *Ty);
- /// createTemplateValueParameter - Create debugging information for template
+ /// Create debugging information for template
/// value parameter.
- /// @param Scope Scope in which this type is defined.
- /// @param Name Value parameter name.
- /// @param Ty Parameter type.
- /// @param Val Constant parameter value.
+ /// \param Scope Scope in which this type is defined.
+ /// \param Name Value parameter name.
+ /// \param Ty Parameter type.
+ /// \param Val Constant parameter value.
DITemplateValueParameter *createTemplateValueParameter(DIScope *Scope,
StringRef Name,
DIType *Ty,
Constant *Val);
- /// \brief Create debugging information for a template template parameter.
- /// @param Scope Scope in which this type is defined.
- /// @param Name Value parameter name.
- /// @param Ty Parameter type.
- /// @param Val The fully qualified name of the template.
+ /// Create debugging information for a template template parameter.
+ /// \param Scope Scope in which this type is defined.
+ /// \param Name Value parameter name.
+ /// \param Ty Parameter type.
+ /// \param Val The fully qualified name of the template.
DITemplateValueParameter *createTemplateTemplateParameter(DIScope *Scope,
StringRef Name,
DIType *Ty,
StringRef Val);
- /// \brief Create debugging information for a template parameter pack.
- /// @param Scope Scope in which this type is defined.
- /// @param Name Value parameter name.
- /// @param Ty Parameter type.
- /// @param Val An array of types in the pack.
+ /// Create debugging information for a template parameter pack.
+ /// \param Scope Scope in which this type is defined.
+ /// \param Name Value parameter name.
+ /// \param Ty Parameter type.
+ /// \param Val An array of types in the pack.
DITemplateValueParameter *createTemplateParameterPack(DIScope *Scope,
StringRef Name,
DIType *Ty,
DINodeArray Val);
- /// createArrayType - Create debugging information entry for an array.
- /// @param Size Array size.
- /// @param AlignInBits Alignment.
- /// @param Ty Element type.
- /// @param Subscripts Subscripts.
+ /// Create debugging information entry for an array.
+ /// \param Size Array size.
+ /// \param AlignInBits Alignment.
+ /// \param Ty Element type.
+ /// \param Subscripts Subscripts.
DICompositeType *createArrayType(uint64_t Size, uint64_t AlignInBits,
DIType *Ty, DINodeArray Subscripts);
- /// createVectorType - Create debugging information entry for a vector type.
- /// @param Size Array size.
- /// @param AlignInBits Alignment.
- /// @param Ty Element type.
- /// @param Subscripts Subscripts.
+ /// Create debugging information entry for a vector type.
+ /// \param Size Array size.
+ /// \param AlignInBits Alignment.
+ /// \param Ty Element type.
+ /// \param Subscripts Subscripts.
DICompositeType *createVectorType(uint64_t Size, uint64_t AlignInBits,
DIType *Ty, DINodeArray Subscripts);
- /// createEnumerationType - Create debugging information entry for an
+ /// Create debugging information entry for an
/// enumeration.
- /// @param Scope Scope in which this enumeration is defined.
- /// @param Name Union name.
- /// @param File File where this member is defined.
- /// @param LineNumber Line number.
- /// @param SizeInBits Member size.
- /// @param AlignInBits Member alignment.
- /// @param Elements Enumeration elements.
- /// @param UnderlyingType Underlying type of a C++11/ObjC fixed enum.
- /// @param UniqueIdentifier A unique identifier for the enum.
+ /// \param Scope Scope in which this enumeration is defined.
+ /// \param Name Union name.
+ /// \param File File where this member is defined.
+ /// \param LineNumber Line number.
+ /// \param SizeInBits Member size.
+ /// \param AlignInBits Member alignment.
+ /// \param Elements Enumeration elements.
+ /// \param UnderlyingType Underlying type of a C++11/ObjC fixed enum.
+ /// \param UniqueIdentifier A unique identifier for the enum.
DICompositeType *createEnumerationType(
DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNumber,
uint64_t SizeInBits, uint64_t AlignInBits, DINodeArray Elements,
DIType *UnderlyingType, StringRef UniqueIdentifier = "");
- /// createSubroutineType - Create subroutine type.
- /// @param File File in which this subroutine is defined.
- /// @param ParameterTypes An array of subroutine parameter types. This
+ /// Create subroutine type.
+ /// \param File File in which this subroutine is defined.
+ /// \param ParameterTypes An array of subroutine parameter types. This
/// includes return type at 0th index.
- /// @param Flags E.g.: LValueReference.
+ /// \param Flags E.g.: LValueReference.
/// These flags are used to emit dwarf attributes.
DISubroutineType *createSubroutineType(DIFile *File,
DITypeRefArray ParameterTypes,
unsigned Flags = 0);
- /// createArtificialType - Create a new DIType* with "artificial" flag set.
+ /// Create a new DIType* with "artificial" flag set.
DIType *createArtificialType(DIType *Ty);
- /// createObjectPointerType - Create a new DIType* with the "object pointer"
+ /// Create a new DIType* with the "object pointer"
/// flag set.
DIType *createObjectPointerType(DIType *Ty);
- /// \brief Create a permanent forward-declared type.
+ /// Create a permanent forward-declared type.
DICompositeType *createForwardDecl(unsigned Tag, StringRef Name,
DIScope *Scope, DIFile *F, unsigned Line,
unsigned RuntimeLang = 0,
@@ -396,43 +399,43 @@ namespace llvm {
uint64_t AlignInBits = 0,
StringRef UniqueIdentifier = "");
- /// \brief Create a temporary forward-declared type.
+ /// Create a temporary forward-declared type.
DICompositeType *createReplaceableCompositeType(
unsigned Tag, StringRef Name, DIScope *Scope, DIFile *F, unsigned Line,
unsigned RuntimeLang = 0, uint64_t SizeInBits = 0,
uint64_t AlignInBits = 0, unsigned Flags = DINode::FlagFwdDecl,
StringRef UniqueIdentifier = "");
- /// retainType - Retain DIType* in a module even if it is not referenced
+ /// Retain DIType* in a module even if it is not referenced
/// through debug info anchors.
void retainType(DIType *T);
- /// createUnspecifiedParameter - Create unspecified parameter type
+ /// Create unspecified parameter type
/// for a subroutine type.
DIBasicType *createUnspecifiedParameter();
- /// getOrCreateArray - Get a DINodeArray, create one if required.
+ /// Get a DINodeArray, create one if required.
DINodeArray getOrCreateArray(ArrayRef<Metadata *> Elements);
- /// getOrCreateTypeArray - Get a DITypeRefArray, create one if required.
+ /// Get a DITypeRefArray, create one if required.
DITypeRefArray getOrCreateTypeArray(ArrayRef<Metadata *> Elements);
- /// getOrCreateSubrange - Create a descriptor for a value range. This
+ /// Create a descriptor for a value range. This
/// implicitly uniques the values returned.
DISubrange *getOrCreateSubrange(int64_t Lo, int64_t Count);
- /// createGlobalVariable - Create a new descriptor for the specified
+ /// Create a new descriptor for the specified
/// variable.
- /// @param Context Variable scope.
- /// @param Name Name of the variable.
- /// @param LinkageName Mangled name of the variable.
- /// @param File File where this variable is defined.
- /// @param LineNo Line number.
- /// @param Ty Variable Type.
- /// @param isLocalToUnit Boolean flag indicate whether this variable is
+ /// \param Context Variable scope.
+ /// \param Name Name of the variable.
+ /// \param LinkageName Mangled name of the variable.
+ /// \param File File where this variable is defined.
+ /// \param LineNo Line number.
+ /// \param Ty Variable Type.
+ /// \param isLocalToUnit Boolean flag indicate whether this variable is
/// externally visible or not.
- /// @param Val llvm::Value of the variable.
- /// @param Decl Reference to the corresponding declaration.
+ /// \param Val llvm::Value of the variable.
+ /// \param Decl Reference to the corresponding declaration.
DIGlobalVariable *createGlobalVariable(DIScope *Context, StringRef Name,
StringRef LinkageName, DIFile *File,
unsigned LineNo, DIType *Ty,
@@ -440,26 +443,26 @@ namespace llvm {
llvm::Constant *Val,
MDNode *Decl = nullptr);
- /// createTempGlobalVariableFwdDecl - Identical to createGlobalVariable
+ /// Identical to createGlobalVariable
/// except that the resulting DbgNode is temporary and meant to be RAUWed.
DIGlobalVariable *createTempGlobalVariableFwdDecl(
DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *File,
unsigned LineNo, DIType *Ty, bool isLocalToUnit, llvm::Constant *Val,
MDNode *Decl = nullptr);
- /// createLocalVariable - Create a new descriptor for the specified
+ /// Create a new descriptor for the specified
/// local variable.
- /// @param Tag Dwarf TAG. Usually DW_TAG_auto_variable or
+ /// \param Tag Dwarf TAG. Usually DW_TAG_auto_variable or
/// DW_TAG_arg_variable.
- /// @param Scope Variable scope.
- /// @param Name Variable name.
- /// @param File File where this variable is defined.
- /// @param LineNo Line number.
- /// @param Ty Variable Type
- /// @param AlwaysPreserve Boolean. Set to true if debug info for this
+ /// \param Scope Variable scope.
+ /// \param Name Variable name.
+ /// \param File File where this variable is defined.
+ /// \param LineNo Line number.
+ /// \param Ty Variable Type
+ /// \param AlwaysPreserve Boolean. Set to true if debug info for this
/// variable should be preserved in optimized build.
- /// @param Flags Flags, e.g. artificial variable.
- /// @param ArgNo If this variable is an argument then this argument's
+ /// \param Flags Flags, e.g. artificial variable.
+ /// \param ArgNo If this variable is an argument then this argument's
/// number. 1 indicates 1st argument.
DILocalVariable *createLocalVariable(unsigned Tag, DIScope *Scope,
StringRef Name, DIFile *File,
@@ -468,36 +471,36 @@ namespace llvm {
unsigned Flags = 0,
unsigned ArgNo = 0);
- /// createExpression - Create a new descriptor for the specified
+ /// Create a new descriptor for the specified
/// variable which has a complex address expression for its address.
- /// @param Addr An array of complex address operations.
+ /// \param Addr An array of complex address operations.
DIExpression *createExpression(ArrayRef<uint64_t> Addr = None);
DIExpression *createExpression(ArrayRef<int64_t> Addr);
- /// createBitPieceExpression - Create a descriptor to describe one part
+ /// Create a descriptor to describe one part
/// of aggregate variable that is fragmented across multiple Values.
///
- /// @param OffsetInBits Offset of the piece in bits.
- /// @param SizeInBits Size of the piece in bits.
+ /// \param OffsetInBits Offset of the piece in bits.
+ /// \param SizeInBits Size of the piece in bits.
DIExpression *createBitPieceExpression(unsigned OffsetInBits,
unsigned SizeInBits);
- /// createFunction - Create a new descriptor for the specified subprogram.
+ /// Create a new descriptor for the specified subprogram.
/// See comments in DISubprogram* for descriptions of these fields.
- /// @param Scope Function scope.
- /// @param Name Function name.
- /// @param LinkageName Mangled function name.
- /// @param File File where this variable is defined.
- /// @param LineNo Line number.
- /// @param Ty Function type.
- /// @param isLocalToUnit True if this function is not externally visible.
- /// @param isDefinition True if this is a function definition.
- /// @param ScopeLine Set to the beginning of the scope this starts
- /// @param Flags e.g. is this function prototyped or not.
+ /// \param Scope Function scope.
+ /// \param Name Function name.
+ /// \param LinkageName Mangled function name.
+ /// \param File File where this variable is defined.
+ /// \param LineNo Line number.
+ /// \param Ty Function type.
+ /// \param isLocalToUnit True if this function is not externally visible.
+ /// \param isDefinition True if this is a function definition.
+ /// \param ScopeLine Set to the beginning of the scope this starts
+ /// \param Flags e.g. is this function prototyped or not.
/// These flags are used to emit dwarf attributes.
- /// @param isOptimized True if optimization is ON.
- /// @param Fn llvm::Function pointer.
- /// @param TParam Function template parameters.
+ /// \param isOptimized True if optimization is ON.
+ /// \param Fn llvm::Function pointer.
+ /// \param TParam Function template parameters.
DISubprogram *
createFunction(DIScope *Scope, StringRef Name, StringRef LinkageName,
DIFile *File, unsigned LineNo, DISubroutineType *Ty,
@@ -506,7 +509,7 @@ namespace llvm {
Function *Fn = nullptr, MDNode *TParam = nullptr,
MDNode *Decl = nullptr);
- /// createTempFunctionFwdDecl - Identical to createFunction,
+ /// Identical to createFunction,
/// except that the resulting DbgNode is meant to be RAUWed.
DISubprogram *createTempFunctionFwdDecl(
DIScope *Scope, StringRef Name, StringRef LinkageName, DIFile *File,
@@ -525,25 +528,25 @@ namespace llvm {
Function *Fn = nullptr, MDNode *TParam = nullptr,
MDNode *Decl = nullptr);
- /// createMethod - Create a new descriptor for the specified C++ method.
- /// See comments in DISubprogram* for descriptions of these fields.
- /// @param Scope Function scope.
- /// @param Name Function name.
- /// @param LinkageName Mangled function name.
- /// @param File File where this variable is defined.
- /// @param LineNo Line number.
- /// @param Ty Function type.
- /// @param isLocalToUnit True if this function is not externally visible..
- /// @param isDefinition True if this is a function definition.
- /// @param Virtuality Attributes describing virtualness. e.g. pure
+ /// Create a new descriptor for the specified C++ method.
+ /// See comments in \a DISubprogram* for descriptions of these fields.
+ /// \param Scope Function scope.
+ /// \param Name Function name.
+ /// \param LinkageName Mangled function name.
+ /// \param File File where this variable is defined.
+ /// \param LineNo Line number.
+ /// \param Ty Function type.
+ /// \param isLocalToUnit True if this function is not externally visible..
+ /// \param isDefinition True if this is a function definition.
+ /// \param Virtuality Attributes describing virtualness. e.g. pure
/// virtual function.
- /// @param VTableIndex Index no of this method in virtual table.
- /// @param VTableHolder Type that holds vtable.
- /// @param Flags e.g. is this function prototyped or not.
+ /// \param VTableIndex Index no of this method in virtual table.
+ /// \param VTableHolder Type that holds vtable.
+ /// \param Flags e.g. is this function prototyped or not.
/// This flags are used to emit dwarf attributes.
- /// @param isOptimized True if optimization is ON.
- /// @param Fn llvm::Function pointer.
- /// @param TParam Function template parameters.
+ /// \param isOptimized True if optimization is ON.
+ /// \param Fn llvm::Function pointer.
+ /// \param TParam Function template parameters.
DISubprogram *
createMethod(DIScope *Scope, StringRef Name, StringRef LinkageName,
DIFile *File, unsigned LineNo, DISubroutineType *Ty,
@@ -552,131 +555,131 @@ namespace llvm {
unsigned Flags = 0, bool isOptimized = false,
Function *Fn = nullptr, MDNode *TParam = nullptr);
- /// createNameSpace - This creates new descriptor for a namespace
- /// with the specified parent scope.
- /// @param Scope Namespace scope
- /// @param Name Name of this namespace
- /// @param File Source file
- /// @param LineNo Line number
+ /// This creates new descriptor for a namespace with the specified
+ /// parent scope.
+ /// \param Scope Namespace scope
+ /// \param Name Name of this namespace
+ /// \param File Source file
+ /// \param LineNo Line number
DINamespace *createNameSpace(DIScope *Scope, StringRef Name, DIFile *File,
unsigned LineNo);
- /// createModule - This creates new descriptor for a module
- /// with the specified parent scope.
- /// @param Scope Parent scope
- /// @param Name Name of this module
- /// @param ConfigurationMacros
+ /// This creates new descriptor for a module with the specified
+ /// parent scope.
+ /// \param Scope Parent scope
+ /// \param Name Name of this module
+ /// \param ConfigurationMacros
/// A space-separated shell-quoted list of -D macro
/// definitions as they would appear on a command line.
- /// @param IncludePath The path to the module map file.
- /// @param ISysRoot The clang system root (value of -isysroot).
+ /// \param IncludePath The path to the module map file.
+ /// \param ISysRoot The clang system root (value of -isysroot).
DIModule *createModule(DIScope *Scope, StringRef Name,
StringRef ConfigurationMacros,
StringRef IncludePath,
StringRef ISysRoot);
- /// createLexicalBlockFile - This creates a descriptor for a lexical
- /// block with a new file attached. This merely extends the existing
+ /// This creates a descriptor for a lexical block with a new file
+ /// attached. This merely extends the existing
/// lexical block as it crosses a file.
- /// @param Scope Lexical block.
- /// @param File Source file.
- /// @param Discriminator DWARF path discriminator value.
+ /// \param Scope Lexical block.
+ /// \param File Source file.
+ /// \param Discriminator DWARF path discriminator value.
DILexicalBlockFile *createLexicalBlockFile(DIScope *Scope, DIFile *File,
unsigned Discriminator = 0);
- /// createLexicalBlock - This creates a descriptor for a lexical block
- /// with the specified parent context.
- /// @param Scope Parent lexical scope.
- /// @param File Source file.
- /// @param Line Line number.
- /// @param Col Column number.
+ /// This creates a descriptor for a lexical block with the
+ /// specified parent context.
+ /// \param Scope Parent lexical scope.
+ /// \param File Source file.
+ /// \param Line Line number.
+ /// \param Col Column number.
DILexicalBlock *createLexicalBlock(DIScope *Scope, DIFile *File,
unsigned Line, unsigned Col);
- /// \brief Create a descriptor for an imported module.
- /// @param Context The scope this module is imported into
- /// @param NS The namespace being imported here
- /// @param Line Line number
+ /// Create a descriptor for an imported module.
+ /// \param Context The scope this module is imported into
+ /// \param NS The namespace being imported here
+ /// \param Line Line number
DIImportedEntity *createImportedModule(DIScope *Context, DINamespace *NS,
unsigned Line);
- /// \brief Create a descriptor for an imported module.
- /// @param Context The scope this module is imported into
- /// @param NS An aliased namespace
- /// @param Line Line number
+ /// Create a descriptor for an imported module.
+ /// \param Context The scope this module is imported into
+ /// \param NS An aliased namespace
+ /// \param Line Line number
DIImportedEntity *createImportedModule(DIScope *Context,
DIImportedEntity *NS, unsigned Line);
- /// \brief Create a descriptor for an imported module.
- /// @param Context The scope this module is imported into
- /// @param M The module being imported here
- /// @param Line Line number
+ /// Create a descriptor for an imported module.
+ /// \param Context The scope this module is imported into
+ /// \param M The module being imported here
+ /// \param Line Line number
DIImportedEntity *createImportedModule(DIScope *Context, DIModule *M,
unsigned Line);
- /// \brief Create a descriptor for an imported function.
- /// @param Context The scope this module is imported into
- /// @param Decl The declaration (or definition) of a function, type, or
+ /// Create a descriptor for an imported function.
+ /// \param Context The scope this module is imported into
+ /// \param Decl The declaration (or definition) of a function, type, or
/// variable
- /// @param Line Line number
+ /// \param Line Line number
DIImportedEntity *createImportedDeclaration(DIScope *Context, DINode *Decl,
unsigned Line,
StringRef Name = "");
- /// insertDeclare - Insert a new llvm.dbg.declare intrinsic call.
- /// @param Storage llvm::Value of the variable
- /// @param VarInfo Variable's debug info descriptor.
- /// @param Expr A complex location expression.
- /// @param DL Debug info location.
- /// @param InsertAtEnd Location for the new intrinsic.
+ /// Insert a new llvm.dbg.declare intrinsic call.
+ /// \param Storage llvm::Value of the variable
+ /// \param VarInfo Variable's debug info descriptor.
+ /// \param Expr A complex location expression.
+ /// \param DL Debug info location.
+ /// \param InsertAtEnd Location for the new intrinsic.
Instruction *insertDeclare(llvm::Value *Storage, DILocalVariable *VarInfo,
DIExpression *Expr, const DILocation *DL,
BasicBlock *InsertAtEnd);
- /// insertDeclare - Insert a new llvm.dbg.declare intrinsic call.
- /// @param Storage llvm::Value of the variable
- /// @param VarInfo Variable's debug info descriptor.
- /// @param Expr A complex location expression.
- /// @param DL Debug info location.
- /// @param InsertBefore Location for the new intrinsic.
+ /// Insert a new llvm.dbg.declare intrinsic call.
+ /// \param Storage llvm::Value of the variable
+ /// \param VarInfo Variable's debug info descriptor.
+ /// \param Expr A complex location expression.
+ /// \param DL Debug info location.
+ /// \param InsertBefore Location for the new intrinsic.
Instruction *insertDeclare(llvm::Value *Storage, DILocalVariable *VarInfo,
DIExpression *Expr, const DILocation *DL,
Instruction *InsertBefore);
- /// insertDbgValueIntrinsic - Insert a new llvm.dbg.value intrinsic call.
- /// @param Val llvm::Value of the variable
- /// @param Offset Offset
- /// @param VarInfo Variable's debug info descriptor.
- /// @param Expr A complex location expression.
- /// @param DL Debug info location.
- /// @param InsertAtEnd Location for the new intrinsic.
+ /// Insert a new llvm.dbg.value intrinsic call.
+ /// \param Val llvm::Value of the variable
+ /// \param Offset Offset
+ /// \param VarInfo Variable's debug info descriptor.
+ /// \param Expr A complex location expression.
+ /// \param DL Debug info location.
+ /// \param InsertAtEnd Location for the new intrinsic.
Instruction *insertDbgValueIntrinsic(llvm::Value *Val, uint64_t Offset,
DILocalVariable *VarInfo,
DIExpression *Expr,
const DILocation *DL,
BasicBlock *InsertAtEnd);
- /// insertDbgValueIntrinsic - Insert a new llvm.dbg.value intrinsic call.
- /// @param Val llvm::Value of the variable
- /// @param Offset Offset
- /// @param VarInfo Variable's debug info descriptor.
- /// @param Expr A complex location expression.
- /// @param DL Debug info location.
- /// @param InsertBefore Location for the new intrinsic.
+ /// Insert a new llvm.dbg.value intrinsic call.
+ /// \param Val llvm::Value of the variable
+ /// \param Offset Offset
+ /// \param VarInfo Variable's debug info descriptor.
+ /// \param Expr A complex location expression.
+ /// \param DL Debug info location.
+ /// \param InsertBefore Location for the new intrinsic.
Instruction *insertDbgValueIntrinsic(llvm::Value *Val, uint64_t Offset,
DILocalVariable *VarInfo,
DIExpression *Expr,
const DILocation *DL,
Instruction *InsertBefore);
- /// \brief Replace the vtable holder in the given composite type.
+ /// Replace the vtable holder in the given composite type.
///
/// If this creates a self reference, it may orphan some unresolved cycles
/// in the operands of \c T, so \a DIBuilder needs to track that.
void replaceVTableHolder(DICompositeType *&T,
DICompositeType *VTableHolder);
- /// \brief Replace arrays on a composite type.
+ /// Replace arrays on a composite type.
///
/// If \c T is resolved, but the arrays aren't -- which can happen if \c T
/// has a self-reference -- \a DIBuilder needs to track the array to
@@ -684,7 +687,7 @@ namespace llvm {
void replaceArrays(DICompositeType *&T, DINodeArray Elements,
DINodeArray TParems = DINodeArray());
- /// \brief Replace a temporary node.
+ /// Replace a temporary node.
///
/// Call \a MDNode::replaceAllUsesWith() on \c N, replacing it with \c
/// Replacement.
diff --git a/include/llvm/IR/DebugInfoMetadata.h b/include/llvm/IR/DebugInfoMetadata.h
index 5c99300c35c7..9c5a95721d79 100644
--- a/include/llvm/IR/DebugInfoMetadata.h
+++ b/include/llvm/IR/DebugInfoMetadata.h
@@ -1085,10 +1085,10 @@ public:
/// deleted on a uniquing collision. In practice, uniquing collisions on \a
/// DICompileUnit should be fairly rare.
/// @{
- void replaceEnumTypes(DISubprogramArray N) {
+ void replaceEnumTypes(DICompositeTypeArray N) {
replaceOperandWith(4, N.get());
}
- void replaceRetainedTypes(DISubprogramArray N) {
+ void replaceRetainedTypes(DITypeArray N) {
replaceOperandWith(5, N.get());
}
void replaceSubprograms(DISubprogramArray N) {
@@ -1097,7 +1097,7 @@ public:
void replaceGlobalVariables(DIGlobalVariableArray N) {
replaceOperandWith(7, N.get());
}
- void replaceImportedEntities(DIGlobalVariableArray N) {
+ void replaceImportedEntities(DIImportedEntityArray N) {
replaceOperandWith(8, N.get());
}
/// @}
@@ -1650,14 +1650,14 @@ class DIModule : public DIScope {
StorageType Storage, bool ShouldCreate = true) {
return getImpl(Context, Scope, getCanonicalMDString(Context, Name),
getCanonicalMDString(Context, ConfigurationMacros),
- getCanonicalMDString(Context, IncludePath),
- getCanonicalMDString(Context, ISysRoot),
+ getCanonicalMDString(Context, IncludePath),
+ getCanonicalMDString(Context, ISysRoot),
Storage, ShouldCreate);
}
static DIModule *getImpl(LLVMContext &Context, Metadata *Scope,
MDString *Name, MDString *ConfigurationMacros,
- MDString *IncludePath, MDString *ISysRoot,
- StorageType Storage, bool ShouldCreate = true);
+ MDString *IncludePath, MDString *ISysRoot,
+ StorageType Storage, bool ShouldCreate = true);
TempDIModule cloneImpl() const {
return getTemporary(getContext(), getScope(), getName(),
@@ -1667,12 +1667,12 @@ class DIModule : public DIScope {
public:
DEFINE_MDNODE_GET(DIModule, (DIScope *Scope, StringRef Name,
- StringRef ConfigurationMacros, StringRef IncludePath,
- StringRef ISysRoot),
+ StringRef ConfigurationMacros, StringRef IncludePath,
+ StringRef ISysRoot),
(Scope, Name, ConfigurationMacros, IncludePath, ISysRoot))
DEFINE_MDNODE_GET(DIModule,
(Metadata *Scope, MDString *Name, MDString *ConfigurationMacros,
- MDString *IncludePath, MDString *ISysRoot),
+ MDString *IncludePath, MDString *ISysRoot),
(Scope, Name, ConfigurationMacros, IncludePath, ISysRoot))
TempDIModule clone() const { return cloneImpl(); }
diff --git a/include/llvm/IR/Dominators.h b/include/llvm/IR/Dominators.h
index c1f208e3d72f..27d989b0344c 100644
--- a/include/llvm/IR/Dominators.h
+++ b/include/llvm/IR/Dominators.h
@@ -36,18 +36,14 @@ namespace llvm {
template <typename IRUnitT> class AnalysisManager;
class PreservedAnalyses;
-EXTERN_TEMPLATE_INSTANTIATION(class DomTreeNodeBase<BasicBlock>);
-EXTERN_TEMPLATE_INSTANTIATION(class DominatorTreeBase<BasicBlock>);
-
-#define LLVM_COMMA ,
-EXTERN_TEMPLATE_INSTANTIATION(void Calculate<Function LLVM_COMMA BasicBlock *>(
- DominatorTreeBase<GraphTraits<BasicBlock *>::NodeType> &DT LLVM_COMMA
- Function &F));
-EXTERN_TEMPLATE_INSTANTIATION(
- void Calculate<Function LLVM_COMMA Inverse<BasicBlock *> >(
- DominatorTreeBase<GraphTraits<Inverse<BasicBlock *> >::NodeType> &DT
- LLVM_COMMA Function &F));
-#undef LLVM_COMMA
+extern template class DomTreeNodeBase<BasicBlock>;
+extern template class DominatorTreeBase<BasicBlock>;
+
+extern template void Calculate<Function, BasicBlock *>(
+ DominatorTreeBase<GraphTraits<BasicBlock *>::NodeType> &DT, Function &F);
+extern template void Calculate<Function, Inverse<BasicBlock *>>(
+ DominatorTreeBase<GraphTraits<Inverse<BasicBlock *>>::NodeType> &DT,
+ Function &F);
typedef DomTreeNodeBase<BasicBlock> DomTreeNode;
diff --git a/include/llvm/IR/Function.h b/include/llvm/IR/Function.h
index 02ea056de39b..ec9f4cad094a 100644
--- a/include/llvm/IR/Function.h
+++ b/include/llvm/IR/Function.h
@@ -293,6 +293,16 @@ public:
addFnAttr(Attribute::ReadOnly);
}
+ /// @brief Determine if the call can access memmory only using pointers based
+ /// on its arguments.
+ bool onlyAccessesArgMemory() const {
+ return AttributeSets.hasAttribute(AttributeSet::FunctionIndex,
+ Attribute::ArgMemOnly);
+ }
+ void setOnlyAccessesArgMemory() {
+ addFnAttr(Attribute::ArgMemOnly);
+ }
+
/// @brief Determine if the function cannot return.
bool doesNotReturn() const {
return AttributeSets.hasAttribute(AttributeSet::FunctionIndex,
diff --git a/include/llvm/IR/GlobalValue.h b/include/llvm/IR/GlobalValue.h
index f2379705d460..2961369a7327 100644
--- a/include/llvm/IR/GlobalValue.h
+++ b/include/llvm/IR/GlobalValue.h
@@ -252,10 +252,9 @@ public:
/// mistake: when working at the IR level use mayBeOverridden instead as it
/// knows about ODR semantics.
static bool isWeakForLinker(LinkageTypes Linkage) {
- return Linkage == AvailableExternallyLinkage || Linkage == WeakAnyLinkage ||
- Linkage == WeakODRLinkage || Linkage == LinkOnceAnyLinkage ||
- Linkage == LinkOnceODRLinkage || Linkage == CommonLinkage ||
- Linkage == ExternalWeakLinkage;
+ return Linkage == WeakAnyLinkage || Linkage == WeakODRLinkage ||
+ Linkage == LinkOnceAnyLinkage || Linkage == LinkOnceODRLinkage ||
+ Linkage == CommonLinkage || Linkage == ExternalWeakLinkage;
}
bool hasExternalLinkage() const { return isExternalLinkage(Linkage); }
@@ -349,6 +348,12 @@ public:
return isDeclaration();
}
+ /// Returns true if this global's definition will be the one chosen by the
+ /// linker.
+ bool isStrongDefinitionForLinker() const {
+ return !(isDeclarationForLinker() || isWeakForLinker());
+ }
+
/// This method unlinks 'this' from the containing module, but does not delete
/// it.
virtual void removeFromParent() = 0;
diff --git a/include/llvm/IR/IRBuilder.h b/include/llvm/IR/IRBuilder.h
index e6b5393c3397..6c67c79b6c0e 100644
--- a/include/llvm/IR/IRBuilder.h
+++ b/include/llvm/IR/IRBuilder.h
@@ -1382,47 +1382,61 @@ public:
return CreateICmp(ICmpInst::ICMP_SLE, LHS, RHS, Name);
}
- Value *CreateFCmpOEQ(Value *LHS, Value *RHS, const Twine &Name = "") {
- return CreateFCmp(FCmpInst::FCMP_OEQ, LHS, RHS, Name);
+ Value *CreateFCmpOEQ(Value *LHS, Value *RHS, const Twine &Name = "",
+ MDNode *FPMathTag = nullptr) {
+ return CreateFCmp(FCmpInst::FCMP_OEQ, LHS, RHS, Name, FPMathTag);
}
- Value *CreateFCmpOGT(Value *LHS, Value *RHS, const Twine &Name = "") {
- return CreateFCmp(FCmpInst::FCMP_OGT, LHS, RHS, Name);
+ Value *CreateFCmpOGT(Value *LHS, Value *RHS, const Twine &Name = "",
+ MDNode *FPMathTag = nullptr) {
+ return CreateFCmp(FCmpInst::FCMP_OGT, LHS, RHS, Name, FPMathTag);
}
- Value *CreateFCmpOGE(Value *LHS, Value *RHS, const Twine &Name = "") {
- return CreateFCmp(FCmpInst::FCMP_OGE, LHS, RHS, Name);
+ Value *CreateFCmpOGE(Value *LHS, Value *RHS, const Twine &Name = "",
+ MDNode *FPMathTag = nullptr) {
+ return CreateFCmp(FCmpInst::FCMP_OGE, LHS, RHS, Name, FPMathTag);
}
- Value *CreateFCmpOLT(Value *LHS, Value *RHS, const Twine &Name = "") {
- return CreateFCmp(FCmpInst::FCMP_OLT, LHS, RHS, Name);
+ Value *CreateFCmpOLT(Value *LHS, Value *RHS, const Twine &Name = "",
+ MDNode *FPMathTag = nullptr) {
+ return CreateFCmp(FCmpInst::FCMP_OLT, LHS, RHS, Name, FPMathTag);
}
- Value *CreateFCmpOLE(Value *LHS, Value *RHS, const Twine &Name = "") {
- return CreateFCmp(FCmpInst::FCMP_OLE, LHS, RHS, Name);
+ Value *CreateFCmpOLE(Value *LHS, Value *RHS, const Twine &Name = "",
+ MDNode *FPMathTag = nullptr) {
+ return CreateFCmp(FCmpInst::FCMP_OLE, LHS, RHS, Name, FPMathTag);
}
- Value *CreateFCmpONE(Value *LHS, Value *RHS, const Twine &Name = "") {
- return CreateFCmp(FCmpInst::FCMP_ONE, LHS, RHS, Name);
+ Value *CreateFCmpONE(Value *LHS, Value *RHS, const Twine &Name = "",
+ MDNode *FPMathTag = nullptr) {
+ return CreateFCmp(FCmpInst::FCMP_ONE, LHS, RHS, Name, FPMathTag);
}
- Value *CreateFCmpORD(Value *LHS, Value *RHS, const Twine &Name = "") {
- return CreateFCmp(FCmpInst::FCMP_ORD, LHS, RHS, Name);
+ Value *CreateFCmpORD(Value *LHS, Value *RHS, const Twine &Name = "",
+ MDNode *FPMathTag = nullptr) {
+ return CreateFCmp(FCmpInst::FCMP_ORD, LHS, RHS, Name, FPMathTag);
}
- Value *CreateFCmpUNO(Value *LHS, Value *RHS, const Twine &Name = "") {
- return CreateFCmp(FCmpInst::FCMP_UNO, LHS, RHS, Name);
+ Value *CreateFCmpUNO(Value *LHS, Value *RHS, const Twine &Name = "",
+ MDNode *FPMathTag = nullptr) {
+ return CreateFCmp(FCmpInst::FCMP_UNO, LHS, RHS, Name, FPMathTag);
}
- Value *CreateFCmpUEQ(Value *LHS, Value *RHS, const Twine &Name = "") {
- return CreateFCmp(FCmpInst::FCMP_UEQ, LHS, RHS, Name);
+ Value *CreateFCmpUEQ(Value *LHS, Value *RHS, const Twine &Name = "",
+ MDNode *FPMathTag = nullptr) {
+ return CreateFCmp(FCmpInst::FCMP_UEQ, LHS, RHS, Name, FPMathTag);
}
- Value *CreateFCmpUGT(Value *LHS, Value *RHS, const Twine &Name = "") {
- return CreateFCmp(FCmpInst::FCMP_UGT, LHS, RHS, Name);
+ Value *CreateFCmpUGT(Value *LHS, Value *RHS, const Twine &Name = "",
+ MDNode *FPMathTag = nullptr) {
+ return CreateFCmp(FCmpInst::FCMP_UGT, LHS, RHS, Name, FPMathTag);
}
- Value *CreateFCmpUGE(Value *LHS, Value *RHS, const Twine &Name = "") {
- return CreateFCmp(FCmpInst::FCMP_UGE, LHS, RHS, Name);
+ Value *CreateFCmpUGE(Value *LHS, Value *RHS, const Twine &Name = "",
+ MDNode *FPMathTag = nullptr) {
+ return CreateFCmp(FCmpInst::FCMP_UGE, LHS, RHS, Name, FPMathTag);
}
- Value *CreateFCmpULT(Value *LHS, Value *RHS, const Twine &Name = "") {
- return CreateFCmp(FCmpInst::FCMP_ULT, LHS, RHS, Name);
+ Value *CreateFCmpULT(Value *LHS, Value *RHS, const Twine &Name = "",
+ MDNode *FPMathTag = nullptr) {
+ return CreateFCmp(FCmpInst::FCMP_ULT, LHS, RHS, Name, FPMathTag);
}
- Value *CreateFCmpULE(Value *LHS, Value *RHS, const Twine &Name = "") {
- return CreateFCmp(FCmpInst::FCMP_ULE, LHS, RHS, Name);
+ Value *CreateFCmpULE(Value *LHS, Value *RHS, const Twine &Name = "",
+ MDNode *FPMathTag = nullptr) {
+ return CreateFCmp(FCmpInst::FCMP_ULE, LHS, RHS, Name, FPMathTag);
}
- Value *CreateFCmpUNE(Value *LHS, Value *RHS, const Twine &Name = "") {
- return CreateFCmp(FCmpInst::FCMP_UNE, LHS, RHS, Name);
+ Value *CreateFCmpUNE(Value *LHS, Value *RHS, const Twine &Name = "",
+ MDNode *FPMathTag = nullptr) {
+ return CreateFCmp(FCmpInst::FCMP_UNE, LHS, RHS, Name, FPMathTag);
}
Value *CreateICmp(CmpInst::Predicate P, Value *LHS, Value *RHS,
@@ -1433,11 +1447,12 @@ public:
return Insert(new ICmpInst(P, LHS, RHS), Name);
}
Value *CreateFCmp(CmpInst::Predicate P, Value *LHS, Value *RHS,
- const Twine &Name = "") {
+ const Twine &Name = "", MDNode *FPMathTag = nullptr) {
if (Constant *LC = dyn_cast<Constant>(LHS))
if (Constant *RC = dyn_cast<Constant>(RHS))
return Insert(Folder.CreateFCmp(P, LC, RC), Name);
- return Insert(new FCmpInst(P, LHS, RHS), Name);
+ return Insert(AddFPMathAttributes(new FCmpInst(P, LHS, RHS),
+ FPMathTag, FMF), Name);
}
//===--------------------------------------------------------------------===//
@@ -1449,7 +1464,7 @@ public:
return Insert(PHINode::Create(Ty, NumReservedValues), Name);
}
- CallInst *CreateCall(Value *Callee, ArrayRef<Value *> Args,
+ CallInst *CreateCall(Value *Callee, ArrayRef<Value *> Args = None,
const Twine &Name = "") {
return Insert(CallInst::Create(Callee, Args), Name);
}
diff --git a/include/llvm/IR/Instruction.h b/include/llvm/IR/Instruction.h
index 6e3de1f13545..31f363f70a5b 100644
--- a/include/llvm/IR/Instruction.h
+++ b/include/llvm/IR/Instruction.h
@@ -382,7 +382,7 @@ public:
///
/// Note that this does not consider malloc and alloca to have side
/// effects because the newly allocated memory is completely invisible to
- /// instructions which don't used the returned value. For cases where this
+ /// instructions which don't use the returned value. For cases where this
/// matters, isSafeToSpeculativelyExecute may be more appropriate.
bool mayHaveSideEffects() const {
return mayWriteToMemory() || mayThrow() || !mayReturn();
diff --git a/include/llvm/IR/Instructions.h b/include/llvm/IR/Instructions.h
index c5890f01ea70..07d5f111b9e1 100644
--- a/include/llvm/IR/Instructions.h
+++ b/include/llvm/IR/Instructions.h
@@ -990,10 +990,14 @@ public:
Ptr->getType()->getPointerAddressSpace());
// Vector GEP
if (Ptr->getType()->isVectorTy()) {
- unsigned NumElem = cast<VectorType>(Ptr->getType())->getNumElements();
+ unsigned NumElem = Ptr->getType()->getVectorNumElements();
return VectorType::get(PtrTy, NumElem);
}
-
+ for (Value *Index : IdxList)
+ if (Index->getType()->isVectorTy()) {
+ unsigned NumElem = Index->getType()->getVectorNumElements();
+ return VectorType::get(PtrTy, NumElem);
+ }
// Scalar GEP
return PtrTy;
}
@@ -1591,6 +1595,15 @@ public:
addAttribute(AttributeSet::FunctionIndex, Attribute::ReadOnly);
}
+ /// @brief Determine if the call can access memmory only using pointers based
+ /// on its arguments.
+ bool onlyAccessesArgMemory() const {
+ return hasFnAttr(Attribute::ArgMemOnly);
+ }
+ void setOnlyAccessesArgMemory() {
+ addAttribute(AttributeSet::FunctionIndex, Attribute::ArgMemOnly);
+ }
+
/// \brief Determine if the call cannot return.
bool doesNotReturn() const { return hasFnAttr(Attribute::NoReturn); }
void setDoesNotReturn() {
@@ -3360,6 +3373,15 @@ public:
addAttribute(AttributeSet::FunctionIndex, Attribute::ReadOnly);
}
+ /// @brief Determine if the call access memmory only using it's pointer
+ /// arguments.
+ bool onlyAccessesArgMemory() const {
+ return hasFnAttr(Attribute::ArgMemOnly);
+ }
+ void setOnlyAccessesArgMemory() {
+ addAttribute(AttributeSet::FunctionIndex, Attribute::ArgMemOnly);
+ }
+
/// \brief Determine if the call cannot return.
bool doesNotReturn() const { return hasFnAttr(Attribute::NoReturn); }
void setDoesNotReturn() {
diff --git a/include/llvm/IR/Intrinsics.td b/include/llvm/IR/Intrinsics.td
index e6f6d0ffe8b6..bbae720b4e12 100644
--- a/include/llvm/IR/Intrinsics.td
+++ b/include/llvm/IR/Intrinsics.td
@@ -268,15 +268,23 @@ def int_gcwrite : Intrinsic<[],
//
def int_returnaddress : Intrinsic<[llvm_ptr_ty], [llvm_i32_ty], [IntrNoMem]>;
def int_frameaddress : Intrinsic<[llvm_ptr_ty], [llvm_i32_ty], [IntrNoMem]>;
-def int_frameescape : Intrinsic<[], [llvm_vararg_ty]>;
-def int_framerecover : Intrinsic<[llvm_ptr_ty],
- [llvm_ptr_ty, llvm_ptr_ty, llvm_i32_ty],
- [IntrNoMem]>;
def int_read_register : Intrinsic<[llvm_anyint_ty], [llvm_metadata_ty],
[IntrReadMem], "llvm.read_register">;
def int_write_register : Intrinsic<[], [llvm_metadata_ty, llvm_anyint_ty],
[], "llvm.write_register">;
+// Gets the address of the local variable area. This is typically a copy of the
+// stack, frame, or base pointer depending on the type of prologue.
+def int_localaddress : Intrinsic<[llvm_ptr_ty], [], [IntrNoMem]>;
+
+// Escapes local variables to allow access from other functions.
+def int_localescape : Intrinsic<[], [llvm_vararg_ty]>;
+
+// Given a function and the localaddress of a parent frame, returns a pointer
+// to an escaped allocation indicated by the index.
+def int_localrecover : Intrinsic<[llvm_ptr_ty],
+ [llvm_ptr_ty, llvm_ptr_ty, llvm_i32_ty],
+ [IntrNoMem]>;
// Note: we treat stacksave/stackrestore as writemem because we don't otherwise
// model their dependencies on allocas.
def int_stacksave : Intrinsic<[llvm_ptr_ty]>,
@@ -362,6 +370,8 @@ let Properties = [IntrNoMem] in {
def int_rint : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
def int_nearbyint : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
def int_round : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
+ def int_canonicalize : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>],
+ [IntrNoMem]>;
}
// NOTE: these are internal interfaces.
@@ -638,3 +648,4 @@ include "llvm/IR/IntrinsicsMips.td"
include "llvm/IR/IntrinsicsAMDGPU.td"
include "llvm/IR/IntrinsicsBPF.td"
include "llvm/IR/IntrinsicsSystemZ.td"
+include "llvm/IR/IntrinsicsWebAssembly.td"
diff --git a/include/llvm/IR/IntrinsicsPowerPC.td b/include/llvm/IR/IntrinsicsPowerPC.td
index 05adc5a757be..eb8f1e6cd079 100644
--- a/include/llvm/IR/IntrinsicsPowerPC.td
+++ b/include/llvm/IR/IntrinsicsPowerPC.td
@@ -694,6 +694,18 @@ def int_ppc_vsx_xvrspip :
def int_ppc_vsx_xvrdpip :
Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty], [IntrNoMem]>;
+// Vector reciprocal estimate
+def int_ppc_vsx_xvresp : GCCBuiltin<"__builtin_vsx_xvresp">,
+ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty], [IntrNoMem]>;
+def int_ppc_vsx_xvredp : GCCBuiltin<"__builtin_vsx_xvredp">,
+ Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty], [IntrNoMem]>;
+
+// Vector rsqrte
+def int_ppc_vsx_xvrsqrtesp : GCCBuiltin<"__builtin_vsx_xvrsqrtesp">,
+ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty], [IntrNoMem]>;
+def int_ppc_vsx_xvrsqrtedp : GCCBuiltin<"__builtin_vsx_xvrsqrtedp">,
+ Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty], [IntrNoMem]>;
+
// Vector compare
def int_ppc_vsx_xvcmpeqdp :
PowerPC_VSX_Intrinsic<"xvcmpeqdp", [llvm_v2i64_ty],
@@ -713,6 +725,9 @@ def int_ppc_vsx_xvcmpgtdp :
def int_ppc_vsx_xvcmpgtsp :
PowerPC_VSX_Intrinsic<"xvcmpgtsp", [llvm_v4i32_ty],
[llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>;
+def int_ppc_vsx_xxleqv :
+ PowerPC_VSX_Intrinsic<"xxleqv", [llvm_v4i32_ty],
+ [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>;
}
//===----------------------------------------------------------------------===//
diff --git a/include/llvm/IR/IntrinsicsWebAssembly.td b/include/llvm/IR/IntrinsicsWebAssembly.td
new file mode 100644
index 000000000000..3ccde4742384
--- /dev/null
+++ b/include/llvm/IR/IntrinsicsWebAssembly.td
@@ -0,0 +1,16 @@
+//===- IntrinsicsWebAssembly.td - Defines wasm intrinsics --*- tablegen -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief This file defines all of the WebAssembly-specific intrinsics.
+///
+//===----------------------------------------------------------------------===//
+
+let TargetPrefix = "wasm" in { // All intrinsics start with "llvm.wasm.".
+}
diff --git a/include/llvm/IR/IntrinsicsX86.td b/include/llvm/IR/IntrinsicsX86.td
index b90825db93cd..a3bc4af84308 100644
--- a/include/llvm/IR/IntrinsicsX86.td
+++ b/include/llvm/IR/IntrinsicsX86.td
@@ -28,7 +28,7 @@ let TargetPrefix = "x86" in {
def int_x86_seh_restoreframe : Intrinsic<[], [], []>;
// Given a pointer to the end of an EH registration object, returns the true
- // parent frame address that can be used with llvm.framerecover.
+ // parent frame address that can be used with llvm.localrecover.
def int_x86_seh_recoverfp : Intrinsic<[llvm_ptr_ty],
[llvm_ptr_ty, llvm_ptr_ty],
[IntrNoMem]>;
@@ -2107,6 +2107,15 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
def int_x86_avx2_pmul_hr_sw : GCCBuiltin<"__builtin_ia32_pmulhrsw256">,
Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty,
llvm_v16i16_ty], [IntrNoMem, Commutative]>;
+ def int_x86_avx512_mask_pmul_hr_sw_128 : GCCBuiltin<"__builtin_ia32_pmulhrsw128_mask">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty,
+ llvm_v8i16_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_pmul_hr_sw_256 : GCCBuiltin<"__builtin_ia32_pmulhrsw256_mask">,
+ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty,
+ llvm_v16i16_ty, llvm_i16_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_pmul_hr_sw_512 : GCCBuiltin<"__builtin_ia32_pmulhrsw512_mask">,
+ Intrinsic<[llvm_v32i16_ty], [llvm_v32i16_ty, llvm_v32i16_ty,
+ llvm_v32i16_ty, llvm_i32_ty], [IntrNoMem]>;
}
// Vector sign and zero extend
@@ -4466,6 +4475,24 @@ let TargetPrefix = "x86" in {
def int_x86_avx512_mask_pmull_q_512 : GCCBuiltin<"__builtin_ia32_pmullq512_mask">,
Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty, llvm_v8i64_ty,
llvm_v8i64_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_pmulhu_w_512 : GCCBuiltin<"__builtin_ia32_pmulhuw512_mask">,
+ Intrinsic<[llvm_v32i16_ty], [llvm_v32i16_ty, llvm_v32i16_ty,
+ llvm_v32i16_ty, llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_pmulh_w_512 : GCCBuiltin<"__builtin_ia32_pmulhw512_mask">,
+ Intrinsic<[llvm_v32i16_ty], [llvm_v32i16_ty, llvm_v32i16_ty,
+ llvm_v32i16_ty, llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_pmulhu_w_128 : GCCBuiltin<"__builtin_ia32_pmulhuw128_mask">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty,
+ llvm_v8i16_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_pmulhu_w_256 : GCCBuiltin<"__builtin_ia32_pmulhuw256_mask">,
+ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty,
+ llvm_v16i16_ty, llvm_i16_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_pmulh_w_128 : GCCBuiltin<"__builtin_ia32_pmulhw128_mask">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty,
+ llvm_v8i16_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_pmulh_w_256 : GCCBuiltin<"__builtin_ia32_pmulhw256_mask">,
+ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty,
+ llvm_v16i16_ty, llvm_i16_ty], [IntrNoMem]>;
def int_x86_avx512_mask_pavg_b_512 : GCCBuiltin<"__builtin_ia32_pavgb512_mask">,
Intrinsic<[llvm_v64i8_ty], [llvm_v64i8_ty, llvm_v64i8_ty,
llvm_v64i8_ty, llvm_i64_ty], [IntrNoMem]>;
diff --git a/include/llvm/IR/Operator.h b/include/llvm/IR/Operator.h
index 1b9102ecc7e4..372b254ab183 100644
--- a/include/llvm/IR/Operator.h
+++ b/include/llvm/IR/Operator.h
@@ -305,7 +305,8 @@ public:
float getFPAccuracy() const;
static inline bool classof(const Instruction *I) {
- return I->getType()->isFPOrFPVectorTy();
+ return I->getType()->isFPOrFPVectorTy() ||
+ I->getOpcode() == Instruction::FCmp;
}
static inline bool classof(const Value *V) {
return isa<Instruction>(V) && classof(cast<Instruction>(V));
diff --git a/include/llvm/IR/Value.h b/include/llvm/IR/Value.h
index 484afc6d232c..17a80c82d1bc 100644
--- a/include/llvm/IR/Value.h
+++ b/include/llvm/IR/Value.h
@@ -104,8 +104,8 @@ protected:
///
/// Note, this should *NOT* be used directly by any class other than User.
/// User uses this value to find the Use list.
- static const unsigned NumUserOperandsBits = 29;
- unsigned NumUserOperands : 29;
+ enum : unsigned { NumUserOperandsBits = 29 };
+ unsigned NumUserOperands : NumUserOperandsBits;
bool IsUsedByMD : 1;
bool HasName : 1;
diff --git a/include/llvm/InitializePasses.h b/include/llvm/InitializePasses.h
index 74fbc0f94b03..e3b9a95f0a3d 100644
--- a/include/llvm/InitializePasses.h
+++ b/include/llvm/InitializePasses.h
@@ -130,6 +130,7 @@ void initializeSanitizerCoverageModulePass(PassRegistry&);
void initializeDataFlowSanitizerPass(PassRegistry&);
void initializeScalarizerPass(PassRegistry&);
void initializeEarlyCSELegacyPassPass(PassRegistry &);
+void initializeEliminateAvailableExternallyPass(PassRegistry&);
void initializeExpandISelPseudosPass(PassRegistry&);
void initializeFunctionAttrsPass(PassRegistry&);
void initializeGCMachineCodeAnalysisPass(PassRegistry&);
@@ -302,6 +303,7 @@ void initializePlaceSafepointsPass(PassRegistry&);
void initializeDwarfEHPreparePass(PassRegistry&);
void initializeFloat2IntPass(PassRegistry&);
void initializeLoopDistributePass(PassRegistry&);
+void initializeSjLjEHPreparePass(PassRegistry&);
}
#endif
diff --git a/include/llvm/LinkAllPasses.h b/include/llvm/LinkAllPasses.h
index 8ac1b212ae5f..cea5530db3b8 100644
--- a/include/llvm/LinkAllPasses.h
+++ b/include/llvm/LinkAllPasses.h
@@ -176,6 +176,7 @@ namespace {
(void) llvm::createStraightLineStrengthReducePass();
(void) llvm::createMemDerefPrinter();
(void) llvm::createFloat2IntPass();
+ (void) llvm::createEliminateAvailableExternallyPass();
(void)new llvm::IntervalPartition();
(void)new llvm::ScalarEvolution();
diff --git a/include/llvm/MC/MCContext.h b/include/llvm/MC/MCContext.h
index 52017fda189b..41169e9a12a0 100644
--- a/include/llvm/MC/MCContext.h
+++ b/include/llvm/MC/MCContext.h
@@ -273,7 +273,7 @@ namespace llvm {
/// Gets a symbol that will be defined to the final stack offset of a local
/// variable after codegen.
///
- /// \param Idx - The index of a local variable passed to @llvm.frameescape.
+ /// \param Idx - The index of a local variable passed to @llvm.localescape.
MCSymbol *getOrCreateFrameAllocSymbol(StringRef FuncName, unsigned Idx);
MCSymbol *getOrCreateParentFrameOffsetSymbol(StringRef FuncName);
diff --git a/include/llvm/MC/MCDwarf.h b/include/llvm/MC/MCDwarf.h
index c7bed8eccda9..1e72dfee4ad1 100644
--- a/include/llvm/MC/MCDwarf.h
+++ b/include/llvm/MC/MCDwarf.h
@@ -54,13 +54,13 @@ struct MCDwarfFile {
/// \brief Instances of this class represent the information from a
/// dwarf .loc directive.
class MCDwarfLoc {
- unsigned FileNum;
- unsigned Line;
- unsigned Column;
+ uint32_t FileNum;
+ uint32_t Line;
+ uint16_t Column;
// Flags (see #define's below)
- unsigned Flags;
- unsigned Isa;
- unsigned Discriminator;
+ uint8_t Flags;
+ uint8_t Isa;
+ uint32_t Discriminator;
// Flag that indicates the initial value of the is_stmt_start flag.
#define DWARF2_LINE_DEFAULT_IS_STMT 1
@@ -107,13 +107,22 @@ public:
void setLine(unsigned line) { Line = line; }
/// \brief Set the Column of this MCDwarfLoc.
- void setColumn(unsigned column) { Column = column; }
+ void setColumn(unsigned column) {
+ assert(column <= UINT16_MAX);
+ Column = column;
+ }
/// \brief Set the Flags of this MCDwarfLoc.
- void setFlags(unsigned flags) { Flags = flags; }
+ void setFlags(unsigned flags) {
+ assert(flags <= UINT8_MAX);
+ Flags = flags;
+ }
/// \brief Set the Isa of this MCDwarfLoc.
- void setIsa(unsigned isa) { Isa = isa; }
+ void setIsa(unsigned isa) {
+ assert(isa <= UINT8_MAX);
+ Isa = isa;
+ }
/// \brief Set the Discriminator of this MCDwarfLoc.
void setDiscriminator(unsigned discriminator) {
diff --git a/include/llvm/MC/MCInstrDesc.h b/include/llvm/MC/MCInstrDesc.h
index 3209a2ce0408..6a582e82d00e 100644
--- a/include/llvm/MC/MCInstrDesc.h
+++ b/include/llvm/MC/MCInstrDesc.h
@@ -154,7 +154,8 @@ public:
// A complex method to determine is a certain is deprecated or not, and return
// the reason for deprecation.
- bool (*ComplexDeprecationInfo)(MCInst &, MCSubtargetInfo &, std::string &);
+ bool (*ComplexDeprecationInfo)(MCInst &, const MCSubtargetInfo &,
+ std::string &);
/// \brief Returns the value of the specific constraint if
/// it is set. Returns -1 if it is not set.
@@ -170,7 +171,7 @@ public:
/// \brief Returns true if a certain instruction is deprecated and if so
/// returns the reason in \p Info.
- bool getDeprecatedInfo(MCInst &MI, MCSubtargetInfo &STI,
+ bool getDeprecatedInfo(MCInst &MI, const MCSubtargetInfo &STI,
std::string &Info) const;
/// \brief Return the opcode number for this descriptor.
diff --git a/include/llvm/MC/MCSchedule.h b/include/llvm/MC/MCSchedule.h
index 1adfedd2638a..c09791631056 100644
--- a/include/llvm/MC/MCSchedule.h
+++ b/include/llvm/MC/MCSchedule.h
@@ -224,25 +224,9 @@ struct MCSchedModel {
return &SchedClassTable[SchedClassIdx];
}
- // /\brief Returns a default initialized model. Used for unknown processors.
- static MCSchedModel GetDefaultSchedModel() {
- MCSchedModel Ret = { DefaultIssueWidth,
- DefaultMicroOpBufferSize,
- DefaultLoopMicroOpBufferSize,
- DefaultLoadLatency,
- DefaultHighLatency,
- DefaultMispredictPenalty,
- false,
- true,
- 0,
- nullptr,
- nullptr,
- 0,
- 0,
- nullptr
- };
- return Ret;
- }
+ /// Returns the default initialized model.
+ static const MCSchedModel &GetDefaultSchedModel() { return Default; }
+ static const MCSchedModel Default;
};
} // End llvm namespace
diff --git a/include/llvm/MC/MCSubtargetInfo.h b/include/llvm/MC/MCSubtargetInfo.h
index b8ad02fbe696..d5ad4eebf9ef 100644
--- a/include/llvm/MC/MCSubtargetInfo.h
+++ b/include/llvm/MC/MCSubtargetInfo.h
@@ -37,22 +37,26 @@ class MCSubtargetInfo {
const MCWriteProcResEntry *WriteProcResTable;
const MCWriteLatencyEntry *WriteLatencyTable;
const MCReadAdvanceEntry *ReadAdvanceTable;
- MCSchedModel CPUSchedModel;
+ const MCSchedModel *CPUSchedModel;
const InstrStage *Stages; // Instruction itinerary stages
const unsigned *OperandCycles; // Itinerary operand cycles
const unsigned *ForwardingPaths; // Forwarding paths
FeatureBitset FeatureBits; // Feature bits for current CPU + FS
+ MCSubtargetInfo() = delete;
+ MCSubtargetInfo &operator=(MCSubtargetInfo &&) = delete;
+ MCSubtargetInfo &operator=(const MCSubtargetInfo &) = delete;
+
public:
- void InitMCSubtargetInfo(const Triple &TT, StringRef CPU, StringRef FS,
- ArrayRef<SubtargetFeatureKV> PF,
- ArrayRef<SubtargetFeatureKV> PD,
- const SubtargetInfoKV *ProcSched,
- const MCWriteProcResEntry *WPR,
- const MCWriteLatencyEntry *WL,
- const MCReadAdvanceEntry *RA, const InstrStage *IS,
- const unsigned *OC, const unsigned *FP);
+ MCSubtargetInfo(const MCSubtargetInfo &) = default;
+ MCSubtargetInfo(const Triple &TT, StringRef CPU, StringRef FS,
+ ArrayRef<SubtargetFeatureKV> PF,
+ ArrayRef<SubtargetFeatureKV> PD,
+ const SubtargetInfoKV *ProcSched,
+ const MCWriteProcResEntry *WPR, const MCWriteLatencyEntry *WL,
+ const MCReadAdvanceEntry *RA, const InstrStage *IS,
+ const unsigned *OC, const unsigned *FP);
/// getTargetTriple - Return the target triple string.
const Triple &getTargetTriple() const { return TargetTriple; }
@@ -74,12 +78,16 @@ public:
FeatureBits = FeatureBits_;
}
- /// InitMCProcessorInfo - Set or change the CPU (optionally supplemented with
- /// feature string). Recompute feature bits and scheduling model.
+protected:
+ /// Initialize the scheduling model and feature bits.
+ ///
+ /// FIXME: Find a way to stick this in the constructor, since it should only
+ /// be called during initialization.
void InitMCProcessorInfo(StringRef CPU, StringRef FS);
- /// InitCPUSchedModel - Recompute scheduling model based on CPU.
- void InitCPUSchedModel(StringRef CPU);
+public:
+ /// Set the features to the default for the given CPU.
+ void setDefaultFeatures(StringRef CPU);
/// ToggleFeature - Toggle a feature and returns the re-computed feature
/// bits. This version does not change the implied bits.
@@ -99,11 +107,10 @@ public:
/// getSchedModelForCPU - Get the machine model of a CPU.
///
- MCSchedModel getSchedModelForCPU(StringRef CPU) const;
+ const MCSchedModel &getSchedModelForCPU(StringRef CPU) const;
- /// getSchedModel - Get the machine model for this subtarget's CPU.
- ///
- const MCSchedModel &getSchedModel() const { return CPUSchedModel; }
+ /// Get the machine model for this subtarget's CPU.
+ const MCSchedModel &getSchedModel() const { return *CPUSchedModel; }
/// Return an iterator at the first process resource consumed by the given
/// scheduling class.
@@ -151,7 +158,7 @@ public:
void initInstrItins(InstrItineraryData &InstrItins) const;
/// Check whether the CPU string is valid.
- bool isCPUStringValid(StringRef CPU) {
+ bool isCPUStringValid(StringRef CPU) const {
auto Found = std::find_if(ProcDesc.begin(), ProcDesc.end(),
[=](const SubtargetFeatureKV &KV) {
return CPU == KV.Key;
diff --git a/include/llvm/MC/MCSymbol.h b/include/llvm/MC/MCSymbol.h
index 17e6b857cf20..b2910dfccd63 100644
--- a/include/llvm/MC/MCSymbol.h
+++ b/include/llvm/MC/MCSymbol.h
@@ -114,12 +114,12 @@ protected:
/// The alignment is stored as log2(align) + 1. This allows all values from
/// 0 to 2^31 to be stored which is every power of 2 representable by an
/// unsigned.
- static const unsigned NumCommonAlignmentBits = 5;
+ enum : unsigned { NumCommonAlignmentBits = 5 };
unsigned CommonAlignLog2 : NumCommonAlignmentBits;
/// The Flags field is used by object file implementations to store
/// additional per symbol information which is not easily classified.
- static const unsigned NumFlagsBits = 16;
+ enum : unsigned { NumFlagsBits = 16 };
mutable uint32_t Flags : NumFlagsBits;
/// Index field, for use by the object file implementation.
diff --git a/include/llvm/MC/MCSymbolMachO.h b/include/llvm/MC/MCSymbolMachO.h
index 166ae9e755a1..5b0321fe9f73 100644
--- a/include/llvm/MC/MCSymbolMachO.h
+++ b/include/llvm/MC/MCSymbolMachO.h
@@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_MC_MCSYMBOLMACHO_H
-#define setIsWeakExternal
+#define LLVM_MC_MCSYMBOLMACHO_H
#include "llvm/MC/MCSymbol.h"
diff --git a/include/llvm/MC/MCTargetOptions.h b/include/llvm/MC/MCTargetOptions.h
index ce28a196e974..7f4f23eda27f 100644
--- a/include/llvm/MC/MCTargetOptions.h
+++ b/include/llvm/MC/MCTargetOptions.h
@@ -55,7 +55,7 @@ inline bool operator==(const MCTargetOptions &LHS, const MCTargetOptions &RHS) {
ARE_EQUAL(ShowMCInst) &&
ARE_EQUAL(AsmVerbose) &&
ARE_EQUAL(DwarfVersion) &&
- ARE_EQUAL(ABIName));
+ ARE_EQUAL(ABIName));
#undef ARE_EQUAL
}
diff --git a/include/llvm/Object/Archive.h b/include/llvm/Object/Archive.h
index 8da6919a4655..597f0d48c118 100644
--- a/include/llvm/Object/Archive.h
+++ b/include/llvm/Object/Archive.h
@@ -94,9 +94,7 @@ public:
/// \return the size in the archive header for this member.
uint64_t getRawSize() const;
- StringRef getBuffer() const {
- return StringRef(Data.data() + StartOfFile, getSize());
- }
+ ErrorOr<StringRef> getBuffer() const;
uint64_t getChildOffset() const;
ErrorOr<MemoryBufferRef> getMemoryBufferRef() const;
@@ -183,6 +181,7 @@ public:
};
Kind kind() const { return (Kind)Format; }
+ bool isThin() const { return IsThin; }
child_iterator child_begin(bool SkipInternal = true) const;
child_iterator child_end() const;
@@ -207,6 +206,11 @@ public:
bool hasSymbolTable() const;
child_iterator getSymbolTableChild() const { return SymbolTable; }
+ StringRef getSymbolTable() const {
+ // We know that the symbol table is not an external file,
+ // so we just assert there is no error.
+ return *SymbolTable->getBuffer();
+ }
uint32_t getNumberOfSymbols() const;
private:
@@ -215,6 +219,7 @@ private:
child_iterator FirstRegular;
unsigned Format : 2;
unsigned IsThin : 1;
+ mutable std::vector<std::unique_ptr<MemoryBuffer>> ThinBuffers;
};
}
diff --git a/include/llvm/Object/ArchiveWriter.h b/include/llvm/Object/ArchiveWriter.h
index 1616e46d3e6f..3648d0c77fb5 100644
--- a/include/llvm/Object/ArchiveWriter.h
+++ b/include/llvm/Object/ArchiveWriter.h
@@ -31,7 +31,6 @@ class NewArchiveIterator {
public:
NewArchiveIterator(object::Archive::child_iterator I, StringRef Name);
NewArchiveIterator(StringRef I, StringRef Name);
- NewArchiveIterator();
bool isNewMember() const;
StringRef getName() const;
@@ -44,8 +43,7 @@ public:
std::pair<StringRef, std::error_code>
writeArchive(StringRef ArcName, std::vector<NewArchiveIterator> &NewMembers,
- bool WriteSymtab);
-
+ bool WriteSymtab, object::Archive::Kind Kind, bool Deterministic);
}
#endif
diff --git a/include/llvm/Object/COFF.h b/include/llvm/Object/COFF.h
index fc605826a8b0..025a9dbc6bc0 100644
--- a/include/llvm/Object/COFF.h
+++ b/include/llvm/Object/COFF.h
@@ -474,7 +474,7 @@ struct coff_import_header {
support::ulittle16_t OrdinalHint;
support::ulittle16_t TypeInfo;
int getType() const { return TypeInfo & 0x3; }
- int getNameType() const { return (TypeInfo & 0x7) >> 2; }
+ int getNameType() const { return (TypeInfo >> 2) & 0x7; }
};
struct coff_import_directory_table_entry {
@@ -648,9 +648,8 @@ public:
protected:
void moveSymbolNext(DataRefImpl &Symb) const override;
ErrorOr<StringRef> getSymbolName(DataRefImpl Symb) const override;
- std::error_code getSymbolAddress(DataRefImpl Symb,
- uint64_t &Res) const override;
- uint64_t getSymbolValue(DataRefImpl Symb) const override;
+ ErrorOr<uint64_t> getSymbolAddress(DataRefImpl Symb) const override;
+ uint64_t getSymbolValueImpl(DataRefImpl Symb) const override;
uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override;
uint32_t getSymbolFlags(DataRefImpl Symb) const override;
SymbolRef::Type getSymbolType(DataRefImpl Symb) const override;
@@ -672,7 +671,6 @@ protected:
relocation_iterator section_rel_end(DataRefImpl Sec) const override;
void moveRelocationNext(DataRefImpl &Rel) const override;
- ErrorOr<uint64_t> getRelocationAddress(DataRefImpl Rel) const override;
uint64_t getRelocationOffset(DataRefImpl Rel) const override;
symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override;
uint64_t getRelocationType(DataRefImpl Rel) const override;
diff --git a/include/llvm/Object/ELF.h b/include/llvm/Object/ELF.h
index 3b0c548ffe15..cc271851e6b0 100644
--- a/include/llvm/Object/ELF.h
+++ b/include/llvm/Object/ELF.h
@@ -16,6 +16,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/IntervalMap.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringSwitch.h"
@@ -139,6 +140,7 @@ public:
typedef Elf_Verneed_Impl<ELFT> Elf_Verneed;
typedef Elf_Vernaux_Impl<ELFT> Elf_Vernaux;
typedef Elf_Versym_Impl<ELFT> Elf_Versym;
+ typedef Elf_Hash_Impl<ELFT> Elf_Hash;
typedef ELFEntityIterator<const Elf_Dyn> Elf_Dyn_Iter;
typedef iterator_range<Elf_Dyn_Iter> Elf_Dyn_Range;
typedef ELFEntityIterator<const Elf_Rela> Elf_Rela_Iter;
@@ -174,8 +176,8 @@ private:
StringRef DotShstrtab; // Section header string table.
StringRef DotStrtab; // Symbol header string table.
const Elf_Shdr *dot_symtab_sec = nullptr; // Symbol table section.
- StringRef DynSymStrTab; // Dynnamic symbol string table.
const Elf_Shdr *DotDynSymSec = nullptr; // Dynamic symbol table section.
+ const Elf_Hash *HashTable = nullptr;
const Elf_Shdr *SymbolTableSectionHeaderIndex = nullptr;
DenseMap<const Elf_Sym *, ELF::Elf64_Word> ExtendedSymbolTable;
@@ -197,6 +199,7 @@ private:
DynRegionInfo DynamicRegion;
DynRegionInfo DynHashRegion;
+ DynRegionInfo DynStrRegion;
DynRegionInfo DynRelaRegion;
// Pointer to SONAME entry in dynamic string table
@@ -229,6 +232,8 @@ private:
void LoadVersionNeeds(const Elf_Shdr *ec) const;
void LoadVersionMap() const;
+ void scanDynamicTable();
+
public:
template<typename T>
const T *getEntry(uint32_t Section, uint32_t Entry) const;
@@ -237,6 +242,7 @@ public:
const Elf_Shdr *getDotSymtabSec() const { return dot_symtab_sec; }
const Elf_Shdr *getDotDynSymSec() const { return DotDynSymSec; }
+ const Elf_Hash *getHashTable() const { return HashTable; }
ErrorOr<StringRef> getStringTable(const Elf_Shdr *Section) const;
const char *getDynamicString(uintX_t Offset) const;
@@ -578,8 +584,10 @@ ELFFile<ELFT>::ELFFile(StringRef Object, std::error_code &EC)
Header = reinterpret_cast<const Elf_Ehdr *>(base());
- if (Header->e_shoff == 0)
+ if (Header->e_shoff == 0) {
+ scanDynamicTable();
return;
+ }
const uint64_t SectionTableOffset = Header->e_shoff;
@@ -604,6 +612,13 @@ ELFFile<ELFT>::ELFFile(StringRef Object, std::error_code &EC)
for (const Elf_Shdr &Sec : sections()) {
switch (Sec.sh_type) {
+ case ELF::SHT_HASH:
+ if (HashTable) {
+ EC = object_error::parse_failed;
+ return;
+ }
+ HashTable = reinterpret_cast<const Elf_Hash *>(base() + Sec.sh_offset);
+ break;
case ELF::SHT_SYMTAB_SHNDX:
if (SymbolTableSectionHeaderIndex) {
// More than one .symtab_shndx!
@@ -640,7 +655,9 @@ ELFFile<ELFT>::ELFFile(StringRef Object, std::error_code &EC)
ErrorOr<StringRef> SymtabOrErr = getStringTable(*SectionOrErr);
if ((EC = SymtabOrErr.getError()))
return;
- DynSymStrTab = *SymtabOrErr;
+ DynStrRegion.Addr = SymtabOrErr->data();
+ DynStrRegion.Size = SymtabOrErr->size();
+ DynStrRegion.EntSize = 1;
break;
}
case ELF::SHT_DYNAMIC:
@@ -701,7 +718,23 @@ ELFFile<ELFT>::ELFFile(StringRef Object, std::error_code &EC)
}
}
- // Scan program headers.
+ scanDynamicTable();
+
+ EC = std::error_code();
+}
+
+template <class ELFT>
+void ELFFile<ELFT>::scanDynamicTable() {
+ // Build load-address to file-offset map.
+ typedef IntervalMap<
+ uintX_t, uintptr_t,
+ IntervalMapImpl::NodeSizer<uintX_t, uintptr_t>::LeafSize,
+ IntervalMapHalfOpenInfo<uintX_t>> LoadMapT;
+ typename LoadMapT::Allocator Alloc;
+ // Allocate the IntervalMap on the heap to work around MSVC bug where the
+ // stack doesn't get realigned despite LoadMap having alignment 8 (PR24113).
+ std::unique_ptr<LoadMapT> LoadMap(new LoadMapT(Alloc));
+
for (Elf_Phdr_Iter PhdrI = program_header_begin(),
PhdrE = program_header_end();
PhdrI != PhdrE; ++PhdrI) {
@@ -709,34 +742,44 @@ ELFFile<ELFT>::ELFFile(StringRef Object, std::error_code &EC)
DynamicRegion.Addr = base() + PhdrI->p_offset;
DynamicRegion.Size = PhdrI->p_filesz;
DynamicRegion.EntSize = sizeof(Elf_Dyn);
- break;
+ continue;
}
+ if (PhdrI->p_type != ELF::PT_LOAD)
+ continue;
+ if (PhdrI->p_filesz == 0)
+ continue;
+ LoadMap->insert(PhdrI->p_vaddr, PhdrI->p_vaddr + PhdrI->p_filesz,
+ PhdrI->p_offset);
}
- // Scan dynamic table.
+ auto toMappedAddr = [&](uint64_t VAddr) -> const uint8_t * {
+ auto I = LoadMap->find(VAddr);
+ if (I == LoadMap->end())
+ return nullptr;
+ return this->base() + I.value() + (VAddr - I.start());
+ };
+
for (Elf_Dyn_Iter DynI = dynamic_table_begin(), DynE = dynamic_table_end();
DynI != DynE; ++DynI) {
switch (DynI->d_tag) {
- case ELF::DT_RELA: {
- uint64_t VBase = 0;
- const uint8_t *FBase = nullptr;
- for (Elf_Phdr_Iter PhdrI = program_header_begin(),
- PhdrE = program_header_end();
- PhdrI != PhdrE; ++PhdrI) {
- if (PhdrI->p_type != ELF::PT_LOAD)
- continue;
- if (DynI->getPtr() >= PhdrI->p_vaddr &&
- DynI->getPtr() < PhdrI->p_vaddr + PhdrI->p_memsz) {
- VBase = PhdrI->p_vaddr;
- FBase = base() + PhdrI->p_offset;
- break;
- }
- }
- if (!VBase)
- return;
- DynRelaRegion.Addr = FBase + DynI->getPtr() - VBase;
+ case ELF::DT_HASH:
+ if (HashTable)
+ continue;
+ HashTable =
+ reinterpret_cast<const Elf_Hash *>(toMappedAddr(DynI->getPtr()));
+ break;
+ case ELF::DT_STRTAB:
+ if (!DynStrRegion.Addr)
+ DynStrRegion.Addr = toMappedAddr(DynI->getPtr());
+ break;
+ case ELF::DT_STRSZ:
+ if (!DynStrRegion.Size)
+ DynStrRegion.Size = DynI->getVal();
+ break;
+ case ELF::DT_RELA:
+ if (!DynRelaRegion.Addr)
+ DynRelaRegion.Addr = toMappedAddr(DynI->getPtr());
break;
- }
case ELF::DT_RELASZ:
DynRelaRegion.Size = DynI->getVal();
break;
@@ -744,8 +787,6 @@ ELFFile<ELFT>::ELFFile(StringRef Object, std::error_code &EC)
DynRelaRegion.EntSize = DynI->getVal();
}
}
-
- EC = std::error_code();
}
template <class ELFT>
@@ -868,9 +909,9 @@ ELFFile<ELFT>::getStringTable(const Elf_Shdr *Section) const {
template <class ELFT>
const char *ELFFile<ELFT>::getDynamicString(uintX_t Offset) const {
- if (!DotDynSymSec || Offset >= DynSymStrTab.size())
+ if (Offset >= DynStrRegion.Size)
return nullptr;
- return (const char *)DynSymStrTab.begin() + Offset;
+ return (const char *)DynStrRegion.Addr + Offset;
}
template <class ELFT>
@@ -983,7 +1024,7 @@ ErrorOr<StringRef> ELFFile<ELFT>::getSymbolVersion(const Elf_Shdr *section,
IsDefault = false;
}
- if (name_offset >= DynSymStrTab.size())
+ if (name_offset >= DynStrRegion.Size)
return object_error::parse_failed;
return StringRef(getDynamicString(name_offset));
}
diff --git a/include/llvm/Object/ELFObjectFile.h b/include/llvm/Object/ELFObjectFile.h
index 5b9b113a2f0b..6e8ace427a20 100644
--- a/include/llvm/Object/ELFObjectFile.h
+++ b/include/llvm/Object/ELFObjectFile.h
@@ -196,9 +196,8 @@ protected:
void moveSymbolNext(DataRefImpl &Symb) const override;
ErrorOr<StringRef> getSymbolName(DataRefImpl Symb) const override;
- std::error_code getSymbolAddress(DataRefImpl Symb,
- uint64_t &Res) const override;
- uint64_t getSymbolValue(DataRefImpl Symb) const override;
+ ErrorOr<uint64_t> getSymbolAddress(DataRefImpl Symb) const override;
+ uint64_t getSymbolValueImpl(DataRefImpl Symb) const override;
uint32_t getSymbolAlignment(DataRefImpl Symb) const override;
uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override;
uint32_t getSymbolFlags(DataRefImpl Symb) const override;
@@ -226,7 +225,6 @@ protected:
section_iterator getRelocatedSection(DataRefImpl Sec) const override;
void moveRelocationNext(DataRefImpl &Rel) const override;
- ErrorOr<uint64_t> getRelocationAddress(DataRefImpl Rel) const override;
uint64_t getRelocationOffset(DataRefImpl Rel) const override;
symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override;
uint64_t getRelocationType(DataRefImpl Rel) const override;
@@ -235,7 +233,6 @@ protected:
uint32_t getSectionType(DataRefImpl Sec) const override;
uint64_t getSectionFlags(DataRefImpl Sec) const override;
- uint64_t getROffset(DataRefImpl Rel) const;
StringRef getRelocationTypeName(uint32_t Type) const;
/// \brief Get the relocation section that contains \a Rel.
@@ -276,11 +273,6 @@ protected:
return DRI;
}
- Elf_Dyn_Iter toELFDynIter(DataRefImpl Dyn) const {
- return Elf_Dyn_Iter(EF.begin_dynamic_table().getEntSize(),
- reinterpret_cast<const char *>(Dyn.p));
- }
-
DataRefImpl toDRI(Elf_Dyn_Iter Dyn) const {
DataRefImpl DRI;
DRI.p = reinterpret_cast<uintptr_t>(Dyn.get());
@@ -378,19 +370,13 @@ uint32_t ELFObjectFile<ELFT>::getSectionType(DataRefImpl Sec) const {
}
template <class ELFT>
-uint64_t ELFObjectFile<ELFT>::getSymbolValue(DataRefImpl Symb) const {
+uint64_t ELFObjectFile<ELFT>::getSymbolValueImpl(DataRefImpl Symb) const {
const Elf_Sym *ESym = getSymbol(Symb);
- switch (ESym->st_shndx) {
- case ELF::SHN_COMMON:
- case ELF::SHN_UNDEF:
- return UnknownAddress;
- case ELF::SHN_ABS:
- return ESym->st_value;
- }
-
- const Elf_Ehdr *Header = EF.getHeader();
uint64_t Ret = ESym->st_value;
+ if (ESym->st_shndx == ELF::SHN_ABS)
+ return Ret;
+ const Elf_Ehdr *Header = EF.getHeader();
// Clear the ARM/Thumb or microMIPS indicator flag.
if ((Header->e_machine == ELF::EM_ARM || Header->e_machine == ELF::EM_MIPS) &&
ESym->getType() == ELF::STT_FUNC)
@@ -400,15 +386,15 @@ uint64_t ELFObjectFile<ELFT>::getSymbolValue(DataRefImpl Symb) const {
}
template <class ELFT>
-std::error_code ELFObjectFile<ELFT>::getSymbolAddress(DataRefImpl Symb,
- uint64_t &Result) const {
- Result = getSymbolValue(Symb);
+ErrorOr<uint64_t>
+ELFObjectFile<ELFT>::getSymbolAddress(DataRefImpl Symb) const {
+ uint64_t Result = getSymbolValue(Symb);
const Elf_Sym *ESym = getSymbol(Symb);
switch (ESym->st_shndx) {
case ELF::SHN_COMMON:
case ELF::SHN_UNDEF:
case ELF::SHN_ABS:
- return std::error_code();
+ return Result;
}
const Elf_Ehdr *Header = EF.getHeader();
@@ -422,7 +408,7 @@ std::error_code ELFObjectFile<ELFT>::getSymbolAddress(DataRefImpl Symb,
Result += Section->sh_addr;
}
- return std::error_code();
+ return Result;
}
template <class ELFT>
@@ -689,31 +675,9 @@ ELFObjectFile<ELFT>::getRelocationSymbol(DataRefImpl Rel) const {
}
template <class ELFT>
-ErrorOr<uint64_t>
-ELFObjectFile<ELFT>::getRelocationAddress(DataRefImpl Rel) const {
- uint64_t ROffset = getROffset(Rel);
- const Elf_Ehdr *Header = EF.getHeader();
-
- if (Header->e_type == ELF::ET_REL) {
- const Elf_Shdr *RelocationSec = getRelSection(Rel);
- ErrorOr<const Elf_Shdr *> RelocatedSec =
- EF.getSection(RelocationSec->sh_info);
- if (std::error_code EC = RelocatedSec.getError())
- return EC;
- return ROffset + (*RelocatedSec)->sh_addr;
- }
- return ROffset;
-}
-
-template <class ELFT>
uint64_t ELFObjectFile<ELFT>::getRelocationOffset(DataRefImpl Rel) const {
assert(EF.getHeader()->e_type == ELF::ET_REL &&
"Only relocatable object files have relocation offsets");
- return getROffset(Rel);
-}
-
-template <class ELFT>
-uint64_t ELFObjectFile<ELFT>::getROffset(DataRefImpl Rel) const {
const Elf_Shdr *sec = getRelSection(Rel);
if (sec->sh_type == ELF::SHT_REL)
return getRel(Rel)->r_offset;
diff --git a/include/llvm/Object/ELFTypes.h b/include/llvm/Object/ELFTypes.h
index 63e13909ae5c..27e987ba2852 100644
--- a/include/llvm/Object/ELFTypes.h
+++ b/include/llvm/Object/ELFTypes.h
@@ -10,6 +10,7 @@
#ifndef LLVM_OBJECT_ELFTYPES_H
#define LLVM_OBJECT_ELFTYPES_H
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/Object/Error.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/ELF.h"
@@ -463,6 +464,23 @@ struct Elf_Phdr_Impl<ELFType<TargetEndianness, true>> {
Elf_Xword p_align; // Segment alignment constraint
};
+// ELFT needed for endianess.
+template <class ELFT>
+struct Elf_Hash_Impl {
+ LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
+ Elf_Word nbucket;
+ Elf_Word nchain;
+
+ ArrayRef<Elf_Word> buckets() const {
+ return ArrayRef<Elf_Word>(&nbucket + 2, &nbucket + 2 + nbucket);
+ }
+
+ ArrayRef<Elf_Word> chains() const {
+ return ArrayRef<Elf_Word>(&nbucket + 2 + nbucket,
+ &nbucket + 2 + nbucket + nchain);
+ }
+};
+
// MIPS .reginfo section
template <class ELFT>
struct Elf_Mips_RegInfo;
diff --git a/include/llvm/Object/ELFYAML.h b/include/llvm/Object/ELFYAML.h
index b45507920a9c..df0aa500c8a2 100644
--- a/include/llvm/Object/ELFYAML.h
+++ b/include/llvm/Object/ELFYAML.h
@@ -85,7 +85,13 @@ struct SectionOrType {
};
struct Section {
- enum class SectionKind { Group, RawContent, Relocation, MipsABIFlags };
+ enum class SectionKind {
+ Group,
+ RawContent,
+ Relocation,
+ NoBits,
+ MipsABIFlags
+ };
SectionKind Kind;
StringRef Name;
ELF_SHT Type;
@@ -106,6 +112,14 @@ struct RawContentSection : Section {
}
};
+struct NoBitsSection : Section {
+ llvm::yaml::Hex64 Size;
+ NoBitsSection() : Section(SectionKind::NoBits) {}
+ static bool classof(const Section *S) {
+ return S->Kind == SectionKind::NoBits;
+ }
+};
+
struct Group : Section {
// Members of a group contain a flag and a list of section indices
// that are part of the group.
diff --git a/include/llvm/Object/MachO.h b/include/llvm/Object/MachO.h
index f4edfd057303..489ecef5c996 100644
--- a/include/llvm/Object/MachO.h
+++ b/include/llvm/Object/MachO.h
@@ -205,9 +205,7 @@ public:
std::error_code getIndirectName(DataRefImpl Symb, StringRef &Res) const;
unsigned getSectionType(SectionRef Sec) const;
- std::error_code getSymbolAddress(DataRefImpl Symb,
- uint64_t &Res) const override;
- uint64_t getSymbolValue(DataRefImpl Symb) const override;
+ ErrorOr<uint64_t> getSymbolAddress(DataRefImpl Symb) const override;
uint32_t getSymbolAlignment(DataRefImpl Symb) const override;
uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override;
SymbolRef::Type getSymbolType(DataRefImpl Symb) const override;
@@ -233,7 +231,6 @@ public:
relocation_iterator section_rel_end(DataRefImpl Sec) const override;
void moveRelocationNext(DataRefImpl &Rel) const override;
- ErrorOr<uint64_t> getRelocationAddress(DataRefImpl Rel) const override;
uint64_t getRelocationOffset(DataRefImpl Rel) const override;
symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override;
section_iterator getRelocationSection(DataRefImpl Rel) const;
@@ -245,6 +242,8 @@ public:
// MachO specific.
std::error_code getLibraryShortNameByIndex(unsigned Index, StringRef &) const;
+ section_iterator getRelocationRelocatedSection(relocation_iterator Rel) const;
+
// TODO: Would be useful to have an iterator based version
// of the load command interface too.
@@ -425,6 +424,8 @@ public:
}
private:
+ uint64_t getSymbolValueImpl(DataRefImpl Symb) const override;
+
union {
MachO::mach_header_64 Header64;
MachO::mach_header Header;
diff --git a/include/llvm/Object/ObjectFile.h b/include/llvm/Object/ObjectFile.h
index 62eab1066be5..8dd525626218 100644
--- a/include/llvm/Object/ObjectFile.h
+++ b/include/llvm/Object/ObjectFile.h
@@ -50,7 +50,6 @@ public:
void moveNext();
- ErrorOr<uint64_t> getAddress() const;
uint64_t getOffset() const;
symbol_iterator getSymbol() const;
uint64_t getType() const;
@@ -135,7 +134,7 @@ public:
ErrorOr<StringRef> getName() const;
/// Returns the symbol virtual address (i.e. address at which it will be
/// mapped).
- std::error_code getAddress(uint64_t &Result) const;
+ ErrorOr<uint64_t> getAddress() const;
/// Return the value of the symbol depending on the object this can be an
/// offset or a virtual address.
@@ -198,9 +197,8 @@ protected:
virtual ErrorOr<StringRef> getSymbolName(DataRefImpl Symb) const = 0;
std::error_code printSymbolName(raw_ostream &OS,
DataRefImpl Symb) const override;
- virtual std::error_code getSymbolAddress(DataRefImpl Symb,
- uint64_t &Res) const = 0;
- virtual uint64_t getSymbolValue(DataRefImpl Symb) const = 0;
+ virtual ErrorOr<uint64_t> getSymbolAddress(DataRefImpl Symb) const = 0;
+ virtual uint64_t getSymbolValueImpl(DataRefImpl Symb) const = 0;
virtual uint32_t getSymbolAlignment(DataRefImpl Symb) const;
virtual uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const = 0;
virtual SymbolRef::Type getSymbolType(DataRefImpl Symb) const = 0;
@@ -229,13 +227,14 @@ protected:
// Same as above for RelocationRef.
friend class RelocationRef;
virtual void moveRelocationNext(DataRefImpl &Rel) const = 0;
- virtual ErrorOr<uint64_t> getRelocationAddress(DataRefImpl Rel) const = 0;
virtual uint64_t getRelocationOffset(DataRefImpl Rel) const = 0;
virtual symbol_iterator getRelocationSymbol(DataRefImpl Rel) const = 0;
virtual uint64_t getRelocationType(DataRefImpl Rel) const = 0;
virtual void getRelocationTypeName(DataRefImpl Rel,
SmallVectorImpl<char> &Result) const = 0;
+ uint64_t getSymbolValue(DataRefImpl Symb) const;
+
public:
uint64_t getCommonSymbolSize(DataRefImpl Symb) const {
assert(getSymbolFlags(Symb) & SymbolRef::SF_Common);
@@ -308,8 +307,8 @@ inline ErrorOr<StringRef> SymbolRef::getName() const {
return getObject()->getSymbolName(getRawDataRefImpl());
}
-inline std::error_code SymbolRef::getAddress(uint64_t &Result) const {
- return getObject()->getSymbolAddress(getRawDataRefImpl(), Result);
+inline ErrorOr<uint64_t> SymbolRef::getAddress() const {
+ return getObject()->getSymbolAddress(getRawDataRefImpl());
}
inline uint64_t SymbolRef::getValue() const {
@@ -430,10 +429,6 @@ inline void RelocationRef::moveNext() {
return OwningObject->moveRelocationNext(RelocationPimpl);
}
-inline ErrorOr<uint64_t> RelocationRef::getAddress() const {
- return OwningObject->getRelocationAddress(RelocationPimpl);
-}
-
inline uint64_t RelocationRef::getOffset() const {
return OwningObject->getRelocationOffset(RelocationPimpl);
}
diff --git a/include/llvm/Object/RelocVisitor.h b/include/llvm/Object/RelocVisitor.h
index 950e2ed0e338..d5e4258cb0a7 100644
--- a/include/llvm/Object/RelocVisitor.h
+++ b/include/llvm/Object/RelocVisitor.h
@@ -100,9 +100,9 @@ private:
case Triple::mips64:
switch (RelocType) {
case llvm::ELF::R_MIPS_32:
- return visitELF_MIPS_32(R, Value);
+ return visitELF_MIPS64_32(R, Value);
case llvm::ELF::R_MIPS_64:
- return visitELF_MIPS_64(R, Value);
+ return visitELF_MIPS64_64(R, Value);
default:
HasError = true;
return RelocToApply();
@@ -313,11 +313,18 @@ private:
/// MIPS ELF
RelocToApply visitELF_MIPS_32(RelocationRef R, uint64_t Value) {
- uint32_t Res = (Value)&0xFFFFFFFF;
+ uint32_t Res = Value & 0xFFFFFFFF;
+ return RelocToApply(Res, 4);
+ }
+
+ /// MIPS64 ELF
+ RelocToApply visitELF_MIPS64_32(RelocationRef R, uint64_t Value) {
+ int64_t Addend = getELFAddend(R);
+ uint32_t Res = (Value + Addend) & 0xFFFFFFFF;
return RelocToApply(Res, 4);
}
- RelocToApply visitELF_MIPS_64(RelocationRef R, uint64_t Value) {
+ RelocToApply visitELF_MIPS64_64(RelocationRef R, uint64_t Value) {
int64_t Addend = getELFAddend(R);
uint64_t Res = (Value + Addend);
return RelocToApply(Res, 8);
diff --git a/include/llvm/Object/SymbolicFile.h b/include/llvm/Object/SymbolicFile.h
index 3a3823159c92..537997ac6318 100644
--- a/include/llvm/Object/SymbolicFile.h
+++ b/include/llvm/Object/SymbolicFile.h
@@ -115,8 +115,6 @@ public:
typedef content_iterator<BasicSymbolRef> basic_symbol_iterator;
-const uint64_t UnknownAddress = ~0ULL;
-
class SymbolicFile : public Binary {
public:
~SymbolicFile() override;
diff --git a/include/llvm/Support/COFF.h b/include/llvm/Support/COFF.h
index b26af61a7c70..3c5ee06969d0 100644
--- a/include/llvm/Support/COFF.h
+++ b/include/llvm/Support/COFF.h
@@ -655,6 +655,7 @@ namespace COFF {
};
enum CodeViewIdentifiers {
+ DEBUG_LINE_TABLES_HAVE_COLUMN_RECORDS = 0x1,
DEBUG_SECTION_MAGIC = 0x4,
DEBUG_SYMBOL_SUBSECTION = 0xF1,
DEBUG_LINE_TABLE_SUBSECTION = 0xF2,
diff --git a/include/llvm/Support/CommandLine.h b/include/llvm/Support/CommandLine.h
index ed809211ea97..379d06a65741 100644
--- a/include/llvm/Support/CommandLine.h
+++ b/include/llvm/Support/CommandLine.h
@@ -790,7 +790,7 @@ public:
void anchor() override;
};
-EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<bool>);
+extern template class basic_parser<bool>;
//--------------------------------------------------
// parser<boolOrDefault>
@@ -816,7 +816,7 @@ public:
void anchor() override;
};
-EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<boolOrDefault>);
+extern template class basic_parser<boolOrDefault>;
//--------------------------------------------------
// parser<int>
@@ -838,7 +838,7 @@ public:
void anchor() override;
};
-EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<int>);
+extern template class basic_parser<int>;
//--------------------------------------------------
// parser<unsigned>
@@ -860,7 +860,7 @@ public:
void anchor() override;
};
-EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<unsigned>);
+extern template class basic_parser<unsigned>;
//--------------------------------------------------
// parser<unsigned long long>
@@ -885,7 +885,7 @@ public:
void anchor() override;
};
-EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<unsigned long long>);
+extern template class basic_parser<unsigned long long>;
//--------------------------------------------------
// parser<double>
@@ -907,7 +907,7 @@ public:
void anchor() override;
};
-EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<double>);
+extern template class basic_parser<double>;
//--------------------------------------------------
// parser<float>
@@ -929,7 +929,7 @@ public:
void anchor() override;
};
-EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<float>);
+extern template class basic_parser<float>;
//--------------------------------------------------
// parser<std::string>
@@ -954,7 +954,7 @@ public:
void anchor() override;
};
-EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<std::string>);
+extern template class basic_parser<std::string>;
//--------------------------------------------------
// parser<char>
@@ -979,7 +979,7 @@ public:
void anchor() override;
};
-EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<char>);
+extern template class basic_parser<char>;
//--------------------------------------------------
// PrintOptionDiff
@@ -1254,11 +1254,11 @@ public:
}
};
-EXTERN_TEMPLATE_INSTANTIATION(class opt<unsigned>);
-EXTERN_TEMPLATE_INSTANTIATION(class opt<int>);
-EXTERN_TEMPLATE_INSTANTIATION(class opt<std::string>);
-EXTERN_TEMPLATE_INSTANTIATION(class opt<char>);
-EXTERN_TEMPLATE_INSTANTIATION(class opt<bool>);
+extern template class opt<unsigned>;
+extern template class opt<int>;
+extern template class opt<std::string>;
+extern template class opt<char>;
+extern template class opt<bool>;
//===----------------------------------------------------------------------===//
// list_storage class
diff --git a/include/llvm/Support/Compiler.h b/include/llvm/Support/Compiler.h
index 67ef23d43c99..141639839cc2 100644
--- a/include/llvm/Support/Compiler.h
+++ b/include/llvm/Support/Compiler.h
@@ -174,19 +174,6 @@
#define LLVM_UNLIKELY(EXPR) (EXPR)
#endif
-// C++ doesn't support 'extern template' of template specializations. GCC does,
-// but requires __extension__ before it. In the header, use this:
-// EXTERN_TEMPLATE_INSTANTIATION(class foo<bar>);
-// in the .cpp file, use this:
-// TEMPLATE_INSTANTIATION(class foo<bar>);
-#ifdef __GNUC__
-#define EXTERN_TEMPLATE_INSTANTIATION(X) __extension__ extern template X
-#define TEMPLATE_INSTANTIATION(X) template X
-#else
-#define EXTERN_TEMPLATE_INSTANTIATION(X)
-#define TEMPLATE_INSTANTIATION(X)
-#endif
-
/// LLVM_ATTRIBUTE_NOINLINE - On compilers where we have a directive to do so,
/// mark a method "not for inlining".
#if __has_attribute(noinline) || LLVM_GNUC_PREREQ(3, 4, 0)
diff --git a/include/llvm/Support/OnDiskHashTable.h b/include/llvm/Support/OnDiskHashTable.h
index 0f097f287286..08e277ad5ce1 100644
--- a/include/llvm/Support/OnDiskHashTable.h
+++ b/include/llvm/Support/OnDiskHashTable.h
@@ -280,13 +280,19 @@ public:
};
/// \brief Look up the stored data for a particular key.
- iterator find(const external_key_type &EKey, Info *InfoPtr = 0) {
- if (!InfoPtr)
- InfoPtr = &InfoObj;
-
- using namespace llvm::support;
+ iterator find(const external_key_type &EKey, Info *InfoPtr = nullptr) {
const internal_key_type &IKey = InfoObj.GetInternalKey(EKey);
hash_value_type KeyHash = InfoObj.ComputeHash(IKey);
+ return find_hashed(IKey, KeyHash, InfoPtr);
+ }
+
+ /// \brief Look up the stored data for a particular key with a known hash.
+ iterator find_hashed(const internal_key_type &IKey, hash_value_type KeyHash,
+ Info *InfoPtr = nullptr) {
+ using namespace llvm::support;
+
+ if (!InfoPtr)
+ InfoPtr = &InfoObj;
// Each bucket is just an offset into the hash table file.
offset_type Idx = KeyHash & (NumBuckets - 1);
diff --git a/include/llvm/Support/TargetRegistry.h b/include/llvm/Support/TargetRegistry.h
index d2e8b95d74f3..40bf6fb20c9f 100644
--- a/include/llvm/Support/TargetRegistry.h
+++ b/include/llvm/Support/TargetRegistry.h
@@ -71,7 +71,7 @@ MCStreamer *createMachOStreamer(MCContext &Ctx, MCAsmBackend &TAB,
MCRelocationInfo *createMCRelocationInfo(const Triple &TT, MCContext &Ctx);
-MCSymbolizer *createMCSymbolizer(StringRef TT, LLVMOpInfoCallback GetOpInfo,
+MCSymbolizer *createMCSymbolizer(const Triple &TT, LLVMOpInfoCallback GetOpInfo,
LLVMSymbolLookupCallback SymbolLookUp,
void *DisInfo, MCContext *Ctx,
std::unique_ptr<MCRelocationInfo> &&RelInfo);
@@ -92,17 +92,18 @@ public:
typedef MCAsmInfo *(*MCAsmInfoCtorFnTy)(const MCRegisterInfo &MRI,
const Triple &TT);
- typedef MCCodeGenInfo *(*MCCodeGenInfoCtorFnTy)(StringRef TT, Reloc::Model RM,
+ typedef MCCodeGenInfo *(*MCCodeGenInfoCtorFnTy)(const Triple &TT,
+ Reloc::Model RM,
CodeModel::Model CM,
CodeGenOpt::Level OL);
typedef MCInstrInfo *(*MCInstrInfoCtorFnTy)(void);
typedef MCInstrAnalysis *(*MCInstrAnalysisCtorFnTy)(const MCInstrInfo *Info);
- typedef MCRegisterInfo *(*MCRegInfoCtorFnTy)(StringRef TT);
+ typedef MCRegisterInfo *(*MCRegInfoCtorFnTy)(const Triple &TT);
typedef MCSubtargetInfo *(*MCSubtargetInfoCtorFnTy)(const Triple &TT,
StringRef CPU,
StringRef Features);
typedef TargetMachine *(*TargetMachineCtorTy)(
- const Target &T, StringRef TT, StringRef CPU, StringRef Features,
+ const Target &T, const Triple &TT, StringRef CPU, StringRef Features,
const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM,
CodeGenOpt::Level OL);
// If it weren't for layering issues (this header is in llvm/Support, but
@@ -150,7 +151,7 @@ public:
typedef MCRelocationInfo *(*MCRelocationInfoCtorTy)(const Triple &TT,
MCContext &Ctx);
typedef MCSymbolizer *(*MCSymbolizerCtorTy)(
- StringRef TT, LLVMOpInfoCallback GetOpInfo,
+ const Triple &TT, LLVMOpInfoCallback GetOpInfo,
LLVMSymbolLookupCallback SymbolLookUp, void *DisInfo, MCContext *Ctx,
std::unique_ptr<MCRelocationInfo> &&RelInfo);
@@ -300,12 +301,12 @@ public:
/// createMCCodeGenInfo - Create a MCCodeGenInfo implementation.
///
- MCCodeGenInfo *createMCCodeGenInfo(StringRef Triple, Reloc::Model RM,
+ MCCodeGenInfo *createMCCodeGenInfo(StringRef TT, Reloc::Model RM,
CodeModel::Model CM,
CodeGenOpt::Level OL) const {
if (!MCCodeGenInfoCtorFn)
return nullptr;
- return MCCodeGenInfoCtorFn(Triple, RM, CM, OL);
+ return MCCodeGenInfoCtorFn(Triple(TT), RM, CM, OL);
}
/// createMCInstrInfo - Create a MCInstrInfo implementation.
@@ -326,10 +327,10 @@ public:
/// createMCRegInfo - Create a MCRegisterInfo implementation.
///
- MCRegisterInfo *createMCRegInfo(StringRef Triple) const {
+ MCRegisterInfo *createMCRegInfo(StringRef TT) const {
if (!MCRegInfoCtorFn)
return nullptr;
- return MCRegInfoCtorFn(Triple);
+ return MCRegInfoCtorFn(Triple(TT));
}
/// createMCSubtargetInfo - Create a MCSubtargetInfo implementation.
@@ -351,20 +352,20 @@ public:
/// createTargetMachine - Create a target specific machine implementation
/// for the specified \p Triple.
///
- /// \param Triple This argument is used to determine the target machine
+ /// \param TT This argument is used to determine the target machine
/// feature set; it should always be provided. Generally this should be
/// either the target triple from the module, or the target triple of the
/// host if that does not exist.
TargetMachine *
- createTargetMachine(StringRef Triple, StringRef CPU, StringRef Features,
+ createTargetMachine(StringRef TT, StringRef CPU, StringRef Features,
const TargetOptions &Options,
Reloc::Model RM = Reloc::Default,
CodeModel::Model CM = CodeModel::Default,
CodeGenOpt::Level OL = CodeGenOpt::Default) const {
if (!TargetMachineCtorFn)
return nullptr;
- return TargetMachineCtorFn(*this, Triple, CPU, Features, Options, RM, CM,
- OL);
+ return TargetMachineCtorFn(*this, Triple(TT), CPU, Features, Options, RM,
+ CM, OL);
}
/// createMCAsmBackend - Create a target specific assembly parser.
@@ -529,7 +530,8 @@ public:
std::unique_ptr<MCRelocationInfo> &&RelInfo) const {
MCSymbolizerCtorTy Fn =
MCSymbolizerCtorFn ? MCSymbolizerCtorFn : llvm::createMCSymbolizer;
- return Fn(TT, GetOpInfo, SymbolLookUp, DisInfo, Ctx, std::move(RelInfo));
+ return Fn(Triple(TT), GetOpInfo, SymbolLookUp, DisInfo, Ctx,
+ std::move(RelInfo));
}
/// @}
@@ -924,7 +926,7 @@ template <class MCCodeGenInfoImpl> struct RegisterMCCodeGenInfo {
}
private:
- static MCCodeGenInfo *Allocator(StringRef /*TT*/, Reloc::Model /*RM*/,
+ static MCCodeGenInfo *Allocator(const Triple & /*TT*/, Reloc::Model /*RM*/,
CodeModel::Model /*CM*/,
CodeGenOpt::Level /*OL*/) {
return new MCCodeGenInfoImpl();
@@ -1023,7 +1025,7 @@ template <class MCRegisterInfoImpl> struct RegisterMCRegInfo {
}
private:
- static MCRegisterInfo *Allocator(StringRef /*TT*/) {
+ static MCRegisterInfo *Allocator(const Triple & /*TT*/) {
return new MCRegisterInfoImpl();
}
};
@@ -1090,11 +1092,11 @@ template <class TargetMachineImpl> struct RegisterTargetMachine {
}
private:
- static TargetMachine *Allocator(const Target &T, StringRef TT, StringRef CPU,
- StringRef FS, const TargetOptions &Options,
- Reloc::Model RM, CodeModel::Model CM,
- CodeGenOpt::Level OL) {
- return new TargetMachineImpl(T, Triple(TT), CPU, FS, Options, RM, CM, OL);
+ static TargetMachine *Allocator(const Target &T, const Triple &TT,
+ StringRef CPU, StringRef FS,
+ const TargetOptions &Options, Reloc::Model RM,
+ CodeModel::Model CM, CodeGenOpt::Level OL) {
+ return new TargetMachineImpl(T, TT, CPU, FS, Options, RM, CM, OL);
}
};
diff --git a/include/llvm/Support/raw_ostream.h b/include/llvm/Support/raw_ostream.h
index b59317112c44..28e512c86941 100644
--- a/include/llvm/Support/raw_ostream.h
+++ b/include/llvm/Support/raw_ostream.h
@@ -165,8 +165,10 @@ public:
if (Size > (size_t)(OutBufEnd - OutBufCur))
return write(Str.data(), Size);
- memcpy(OutBufCur, Str.data(), Size);
- OutBufCur += Size;
+ if (Size) {
+ memcpy(OutBufCur, Str.data(), Size);
+ OutBufCur += Size;
+ }
return *this;
}
diff --git a/include/llvm/TableGen/Record.h b/include/llvm/TableGen/Record.h
index 717a2a4ba62a..b4642c991192 100644
--- a/include/llvm/TableGen/Record.h
+++ b/include/llvm/TableGen/Record.h
@@ -1222,11 +1222,11 @@ public:
/// get the corresponding DefInit.
DefInit *getDefInit();
- const std::vector<Init *> &getTemplateArgs() const {
+ ArrayRef<Init *> getTemplateArgs() const {
return TemplateArgs;
}
- const std::vector<RecordVal> &getValues() const { return Values; }
- const std::vector<Record*> &getSuperClasses() const { return SuperClasses; }
+ ArrayRef<RecordVal> getValues() const { return Values; }
+ ArrayRef<Record *> getSuperClasses() const { return SuperClasses; }
ArrayRef<SMRange> getSuperClassRanges() const { return SuperClassRanges; }
bool isTemplateArg(Init *Name) const {
diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td
index 61234991be44..e0aea181a639 100644
--- a/include/llvm/Target/Target.td
+++ b/include/llvm/Target/Target.td
@@ -872,7 +872,7 @@ def LOAD_STACK_GUARD : Instruction {
let hasSideEffects = 0;
bit isPseudo = 1;
}
-def FRAME_ALLOC : Instruction {
+def LOCAL_ESCAPE : Instruction {
// This instruction is really just a label. It has to be part of the chain so
// that it doesn't get dropped from the DAG, but it produces nothing and has
// no side effects.
@@ -1014,7 +1014,7 @@ class InstAlias<string Asm, dag Result, int Emit = 1> {
// Predicates - Predicates that must be true for this to match.
list<Predicate> Predicates = [];
- // If the instruction specified in Result has defined an AsmMatchConverter
+ // If the instruction specified in Result has defined an AsmMatchConverter
// then setting this to 1 will cause the alias to use the AsmMatchConverter
// function when converting the OperandVector into an MCInst instead of the
// function that is generated by the dag Result.
diff --git a/include/llvm/Target/TargetFrameLowering.h b/include/llvm/Target/TargetFrameLowering.h
index 0e317247a59f..3af2227410f7 100644
--- a/include/llvm/Target/TargetFrameLowering.h
+++ b/include/llvm/Target/TargetFrameLowering.h
@@ -19,6 +19,7 @@
#include <vector>
namespace llvm {
+ class BitVector;
class CalleeSavedInfo;
class MachineFunction;
class RegScavenger;
@@ -226,13 +227,15 @@ public:
return 0;
}
- /// processFunctionBeforeCalleeSavedScan - This method is called immediately
- /// before PrologEpilogInserter scans the physical registers used to determine
- /// what callee saved registers should be spilled. This method is optional.
- virtual void processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
- RegScavenger *RS = nullptr) const {
-
- }
+ /// This method determines which of the registers reported by
+ /// TargetRegisterInfo::getCalleeSavedRegs() should actually get saved.
+ /// The default implementation checks populates the \p SavedRegs bitset with
+ /// all registers which are modified in the function, targets may override
+ /// this function to save additional registers.
+ /// This method also sets up the register scavenger ensuring there is a free
+ /// register or a frameindex available.
+ virtual void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs,
+ RegScavenger *RS = nullptr) const;
/// processFunctionBeforeFrameFinalized - This method is called immediately
/// before the specified function's frame layout (MF.getFrameInfo()) is
diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h
index 277487fee6bc..4412d9b3c68e 100644
--- a/include/llvm/Target/TargetLowering.h
+++ b/include/llvm/Target/TargetLowering.h
@@ -161,27 +161,27 @@ protected:
public:
const TargetMachine &getTargetMachine() const { return TM; }
- const DataLayout *getDataLayout() const { return TM.getDataLayout(); }
- bool isBigEndian() const { return !IsLittleEndian; }
- bool isLittleEndian() const { return IsLittleEndian; }
virtual bool useSoftFloat() const { return false; }
/// Return the pointer type for the given address space, defaults to
/// the pointer type from the data layout.
/// FIXME: The default needs to be removed once all the code is updated.
- virtual MVT getPointerTy(uint32_t /*AS*/ = 0) const;
- unsigned getPointerSizeInBits(uint32_t AS = 0) const;
- unsigned getPointerTypeSizeInBits(Type *Ty) const;
- virtual MVT getScalarShiftAmountTy(EVT LHSTy) const;
+ MVT getPointerTy(const DataLayout &DL, uint32_t AS = 0) const {
+ return MVT::getIntegerVT(DL.getPointerSizeInBits(AS));
+ }
+
+ /// 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;
- EVT getShiftAmountTy(EVT LHSTy) const;
+ EVT getShiftAmountTy(EVT LHSTy, const DataLayout &DL) const;
/// Returns the type to be used for the index operand of:
/// ISD::INSERT_VECTOR_ELT, ISD::EXTRACT_VECTOR_ELT,
/// ISD::INSERT_SUBVECTOR, and ISD::EXTRACT_SUBVECTOR
- virtual MVT getVectorIdxTy() const {
- return getPointerTy();
+ virtual MVT getVectorIdxTy(const DataLayout &DL) const {
+ return getPointerTy(DL);
}
/// Return true if the select operation is expensive for this target.
@@ -327,7 +327,8 @@ public:
}
/// Return the ValueType of the result of SETCC operations.
- virtual EVT getSetCCResultType(LLVMContext &Context, EVT VT) const;
+ virtual EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context,
+ EVT VT) const;
/// Return the ValueType for comparison libcalls. Comparions libcalls include
/// floating point comparion calls, and Ordered/Unordered check calls on
@@ -715,17 +716,18 @@ public:
/// operations except for the pointer size. If AllowUnknown is true, this
/// will return MVT::Other for types with no EVT counterpart (e.g. structs),
/// otherwise it will assert.
- EVT getValueType(Type *Ty, bool AllowUnknown = false) const {
+ EVT getValueType(const DataLayout &DL, Type *Ty,
+ bool AllowUnknown = false) const {
// Lower scalar pointers to native pointer types.
if (PointerType *PTy = dyn_cast<PointerType>(Ty))
- return getPointerTy(PTy->getAddressSpace());
+ return getPointerTy(DL, PTy->getAddressSpace());
if (Ty->isVectorTy()) {
VectorType *VTy = cast<VectorType>(Ty);
Type *Elm = VTy->getElementType();
// Lower vectors of pointers to native pointer types.
if (PointerType *PT = dyn_cast<PointerType>(Elm)) {
- EVT PointerTy(getPointerTy(PT->getAddressSpace()));
+ EVT PointerTy(getPointerTy(DL, PT->getAddressSpace()));
Elm = PointerTy.getTypeForEVT(Ty->getContext());
}
@@ -736,14 +738,15 @@ public:
}
/// Return the MVT corresponding to this LLVM type. See getValueType.
- MVT getSimpleValueType(Type *Ty, bool AllowUnknown = false) const {
- return getValueType(Ty, AllowUnknown).getSimpleVT();
+ MVT getSimpleValueType(const DataLayout &DL, Type *Ty,
+ bool AllowUnknown = false) const {
+ return getValueType(DL, Ty, AllowUnknown).getSimpleVT();
}
/// Return the desired alignment for ByVal or InAlloca aggregate function
/// arguments in the caller parameter area. This is the actual alignment, not
/// its logarithm.
- virtual unsigned getByValTypeAlignment(Type *Ty) const;
+ virtual unsigned getByValTypeAlignment(Type *Ty, const DataLayout &DL) const;
/// Return the type of registers that this ValueType will eventually require.
MVT getRegisterType(MVT VT) const {
@@ -818,8 +821,8 @@ public:
/// When splitting a value of the specified type into parts, does the Lo
/// or Hi part come first? This usually follows the endianness, except
/// for ppcf128, where the Hi part always comes first.
- bool hasBigEndianPartOrdering(EVT VT) const {
- return isBigEndian() || VT == MVT::ppcf128;
+ bool hasBigEndianPartOrdering(EVT VT, const DataLayout &DL) const {
+ return DL.isBigEndian() || VT == MVT::ppcf128;
}
/// If true, the target has custom DAG combine transformations that it can
@@ -1006,7 +1009,8 @@ public:
int InstructionOpcodeToISD(unsigned Opcode) const;
/// Estimate the cost of type-legalization and the legalized type.
- std::pair<unsigned, MVT> getTypeLegalizationCost(Type *Ty) const;
+ std::pair<unsigned, MVT> getTypeLegalizationCost(const DataLayout &DL,
+ Type *Ty) const;
/// @}
@@ -1460,8 +1464,8 @@ public:
/// If the address space cannot be determined, it will be -1.
///
/// TODO: Remove default argument
- virtual bool isLegalAddressingMode(const AddrMode &AM, Type *Ty,
- unsigned AddrSpace) const;
+ virtual bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM,
+ Type *Ty, unsigned AddrSpace) const;
/// \brief Return the cost of the scaling factor used in the addressing mode
/// represented by AM for this target, for a load/store of the specified type.
@@ -1470,10 +1474,10 @@ public:
/// If the AM is not supported, it returns a negative value.
/// TODO: Handle pre/postinc as well.
/// TODO: Remove default argument
- virtual int getScalingFactorCost(const AddrMode &AM, Type *Ty,
- unsigned AS = 0) const {
+ virtual int getScalingFactorCost(const DataLayout &DL, const AddrMode &AM,
+ Type *Ty, unsigned AS = 0) const {
// Default: assume that any scaling factor used in a legal AM is free.
- if (isLegalAddressingMode(AM, Ty, AS))
+ if (isLegalAddressingMode(DL, AM, Ty, AS))
return 0;
return -1;
}
@@ -1734,9 +1738,6 @@ public:
private:
const TargetMachine &TM;
- /// True if this is a little endian target.
- bool IsLittleEndian;
-
/// Tells the code generator not to expand operations into sequences that use
/// the select operations if possible.
bool SelectIsExpensive;
@@ -2414,6 +2415,7 @@ public:
ArgListTy &getArgs() {
return Args;
}
+
};
/// This function lowers an abstract call to a function into an actual call.
@@ -2485,7 +2487,8 @@ public:
/// Return the register ID of the name passed in. Used by named register
/// global variables extension. There is no target-independent behaviour
/// so the default action is to bail.
- virtual unsigned getRegisterByName(const char* RegName, EVT VT) const {
+ virtual unsigned getRegisterByName(const char* RegName, EVT VT,
+ SelectionDAG &DAG) const {
report_fatal_error("Named registers not implemented for this target");
}
@@ -2657,7 +2660,8 @@ public:
/// specific constraints and their prefixes, and also tie in the associated
/// operand values. If this returns an empty vector, and if the constraint
/// string itself isn't empty, there was an error parsing.
- virtual AsmOperandInfoVector ParseConstraints(const TargetRegisterInfo *TRI,
+ virtual AsmOperandInfoVector ParseConstraints(const DataLayout &DL,
+ const TargetRegisterInfo *TRI,
ImmutableCallSite CS) const;
/// Examine constraint type and operand type and determine a weight value.
@@ -2679,7 +2683,7 @@ public:
SelectionDAG *DAG = nullptr) const;
/// Given a constraint, return the type of constraint it is for this target.
- virtual ConstraintType getConstraintType(const std::string &Constraint) const;
+ virtual ConstraintType getConstraintType(StringRef Constraint) const;
/// Given a physical register constraint (e.g. {edx}), return the register
/// number and the register class for the register.
@@ -2692,10 +2696,9 @@ public:
/// returns a register number of 0 and a null register class pointer.
virtual std::pair<unsigned, const TargetRegisterClass *>
getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
- const std::string &Constraint, MVT VT) const;
+ StringRef Constraint, MVT VT) const;
- virtual unsigned
- getInlineAsmMemConstraint(const std::string &ConstraintCode) const {
+ virtual unsigned getInlineAsmMemConstraint(StringRef ConstraintCode) const {
if (ConstraintCode == "i")
return InlineAsm::Constraint_i;
else if (ConstraintCode == "m")
@@ -2823,9 +2826,9 @@ public:
/// Given an LLVM IR type and return type attributes, compute the return value
/// EVTs and flags, and optionally also the offsets, if the return value is
/// being lowered to memory.
-void GetReturnInfo(Type* ReturnType, AttributeSet attr,
+void GetReturnInfo(Type *ReturnType, AttributeSet attr,
SmallVectorImpl<ISD::OutputArg> &Outs,
- const TargetLowering &TLI);
+ const TargetLowering &TLI, const DataLayout &DL);
} // end llvm namespace
diff --git a/include/llvm/Target/TargetMachine.h b/include/llvm/Target/TargetMachine.h
index 64a923b80edf..06a2b13836ed 100644
--- a/include/llvm/Target/TargetMachine.h
+++ b/include/llvm/Target/TargetMachine.h
@@ -212,8 +212,8 @@ public:
/// supported, or false on success.
virtual bool addPassesToEmitFile(
PassManagerBase &, raw_pwrite_stream &, CodeGenFileType,
- bool /*DisableVerify*/ = true, AnalysisID /*StartAfter*/ = nullptr,
- AnalysisID /*StopAfter*/ = nullptr,
+ bool /*DisableVerify*/ = true, AnalysisID /*StartBefore*/ = nullptr,
+ AnalysisID /*StartAfter*/ = nullptr, AnalysisID /*StopAfter*/ = nullptr,
MachineFunctionInitializer * /*MFInitializer*/ = nullptr) {
return true;
}
@@ -260,8 +260,8 @@ public:
/// emitted. Typically this will involve several steps of code generation.
bool addPassesToEmitFile(
PassManagerBase &PM, raw_pwrite_stream &Out, CodeGenFileType FileType,
- bool DisableVerify = true, AnalysisID StartAfter = nullptr,
- AnalysisID StopAfter = nullptr,
+ bool DisableVerify = true, AnalysisID StartBefore = nullptr,
+ AnalysisID StartAfter = nullptr, AnalysisID StopAfter = nullptr,
MachineFunctionInitializer *MFInitializer = nullptr) override;
/// Add passes to the specified pass manager to get machine code emitted with
diff --git a/include/llvm/Target/TargetOpcodes.h b/include/llvm/Target/TargetOpcodes.h
index 1f9a5d4ecaf0..50197191109d 100644
--- a/include/llvm/Target/TargetOpcodes.h
+++ b/include/llvm/Target/TargetOpcodes.h
@@ -118,10 +118,10 @@ enum {
/// collectors and deoptimizations in either the callee or caller.
STATEPOINT = 20,
- /// Instruction that records the offset of a function's frame allocation in a
- /// label. Created by the llvm.frameallocate intrinsic. It has two arguments:
- /// the symbol for the label and the frame index of the stack allocation.
- FRAME_ALLOC = 21,
+ /// Instruction that records the offset of a local stack allocation passed to
+ /// llvm.localescape. It has two arguments: the symbol for the label and the
+ /// frame index of the local stack allocation.
+ LOCAL_ESCAPE = 21,
/// Loading instruction that may page fault, bundled with associated
/// information on how to handle such a page fault. It is intended to support
diff --git a/include/llvm/Target/TargetSelectionDAGInfo.h b/include/llvm/Target/TargetSelectionDAGInfo.h
index bacdd950705b..53db5aa84292 100644
--- a/include/llvm/Target/TargetSelectionDAGInfo.h
+++ b/include/llvm/Target/TargetSelectionDAGInfo.h
@@ -20,8 +20,6 @@
namespace llvm {
-class DataLayout;
-
//===----------------------------------------------------------------------===//
/// TargetSelectionDAGInfo - Targets can subclass this to parameterize the
/// SelectionDAG lowering and instruction selection process.
@@ -30,13 +28,8 @@ class TargetSelectionDAGInfo {
TargetSelectionDAGInfo(const TargetSelectionDAGInfo &) = delete;
void operator=(const TargetSelectionDAGInfo &) = delete;
- const DataLayout *DL;
-
-protected:
- const DataLayout *getDataLayout() const { return DL; }
-
public:
- explicit TargetSelectionDAGInfo(const DataLayout *DL);
+ explicit TargetSelectionDAGInfo() = default;
virtual ~TargetSelectionDAGInfo();
/// EmitTargetCodeForMemcpy - Emit target-specific code that performs a
diff --git a/include/llvm/Target/TargetSubtargetInfo.h b/include/llvm/Target/TargetSubtargetInfo.h
index e42c56add7b1..07c0c66bfa18 100644
--- a/include/llvm/Target/TargetSubtargetInfo.h
+++ b/include/llvm/Target/TargetSubtargetInfo.h
@@ -44,9 +44,17 @@ template <typename T> class SmallVectorImpl;
class TargetSubtargetInfo : public MCSubtargetInfo {
TargetSubtargetInfo(const TargetSubtargetInfo &) = delete;
void operator=(const TargetSubtargetInfo &) = delete;
+ TargetSubtargetInfo() = delete;
protected: // Can only create subclasses...
- TargetSubtargetInfo();
+ TargetSubtargetInfo(const Triple &TT, StringRef CPU, StringRef FS,
+ ArrayRef<SubtargetFeatureKV> PF,
+ ArrayRef<SubtargetFeatureKV> PD,
+ const SubtargetInfoKV *ProcSched,
+ const MCWriteProcResEntry *WPR,
+ const MCWriteLatencyEntry *WL,
+ const MCReadAdvanceEntry *RA, const InstrStage *IS,
+ const unsigned *OC, const unsigned *FP);
public:
// AntiDepBreakMode - Type of anti-dependence breaking that should
diff --git a/include/llvm/Transforms/IPO.h b/include/llvm/Transforms/IPO.h
index fbd999cbc946..2ea47301bb4c 100644
--- a/include/llvm/Transforms/IPO.h
+++ b/include/llvm/Transforms/IPO.h
@@ -71,6 +71,12 @@ ModulePass *createGlobalOptimizerPass();
ModulePass *createGlobalDCEPass();
//===----------------------------------------------------------------------===//
+/// This transform is designed to eliminate available external globals
+/// (functions or global variables)
+///
+ModulePass *createEliminateAvailableExternallyPass();
+
+//===----------------------------------------------------------------------===//
/// createGVExtractionPass - If deleteFn is true, this pass deletes
/// the specified global values. Otherwise, it deletes as much of the module as
/// possible, except for the global values specified.
diff --git a/include/llvm/Transforms/IPO/PassManagerBuilder.h b/include/llvm/Transforms/IPO/PassManagerBuilder.h
index 5d574ae0bf0f..1334dd0da23c 100644
--- a/include/llvm/Transforms/IPO/PassManagerBuilder.h
+++ b/include/llvm/Transforms/IPO/PassManagerBuilder.h
@@ -121,6 +121,7 @@ public:
bool VerifyInput;
bool VerifyOutput;
bool MergeFunctions;
+ bool PrepareForLTO;
private:
/// ExtensionList - This is list of all of the extensions that are registered.
diff --git a/include/llvm/Transforms/Utils/Cloning.h b/include/llvm/Transforms/Utils/Cloning.h
index cb187ec103d0..2caa9a2462df 100644
--- a/include/llvm/Transforms/Utils/Cloning.h
+++ b/include/llvm/Transforms/Utils/Cloning.h
@@ -45,6 +45,7 @@ class LoopInfo;
class AllocaInst;
class AliasAnalysis;
class AssumptionCacheTracker;
+class DominatorTree;
/// CloneModule - Return an exact copy of the specified module
///
@@ -233,6 +234,21 @@ bool InlineFunction(InvokeInst *II, InlineFunctionInfo &IFI,
bool InlineFunction(CallSite CS, InlineFunctionInfo &IFI,
bool InsertLifetime = true);
+/// \brief Clones a loop \p OrigLoop. Returns the loop and the blocks in \p
+/// Blocks.
+///
+/// Updates LoopInfo and DominatorTree assuming the loop is dominated by block
+/// \p LoopDomBB. Insert the new blocks before block specified in \p Before.
+Loop *cloneLoopWithPreheader(BasicBlock *Before, BasicBlock *LoopDomBB,
+ Loop *OrigLoop, ValueToValueMapTy &VMap,
+ const Twine &NameSuffix, LoopInfo *LI,
+ DominatorTree *DT,
+ SmallVectorImpl<BasicBlock *> &Blocks);
+
+/// \brief Remaps instructions in \p Blocks using the mapping in \p VMap.
+void remapInstructionsInBlocks(const SmallVectorImpl<BasicBlock *> &Blocks,
+ ValueToValueMapTy &VMap);
+
} // End llvm namespace
#endif
diff --git a/include/llvm/Transforms/Utils/LoopVersioning.h b/include/llvm/Transforms/Utils/LoopVersioning.h
new file mode 100644
index 000000000000..009fba48c6a3
--- /dev/null
+++ b/include/llvm/Transforms/Utils/LoopVersioning.h
@@ -0,0 +1,100 @@
+//===- LoopVersioning.h - Utility to version a loop -------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines a utility class to perform loop versioning. The versioned
+// loop speculates that otherwise may-aliasing memory accesses don't overlap and
+// emits checks to prove this.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_UTILS_LOOPVERSIONING_H
+#define LLVM_TRANSFORMS_UTILS_LOOPVERSIONING_H
+
+#include "llvm/Transforms/Utils/ValueMapper.h"
+
+namespace llvm {
+
+class Loop;
+class LoopAccessInfo;
+class LoopInfo;
+
+/// \brief This class emits a version of the loop where run-time checks ensure
+/// that may-alias pointers can't overlap.
+///
+/// It currently only supports single-exit loops and assumes that the loop
+/// already has a preheader.
+class LoopVersioning {
+public:
+ LoopVersioning(const LoopAccessInfo &LAI, Loop *L, LoopInfo *LI,
+ DominatorTree *DT,
+ const SmallVector<int, 8> *PtrToPartition = nullptr);
+
+ /// \brief Returns true if we need memchecks to disambiguate may-aliasing
+ /// accesses.
+ bool needsRuntimeChecks() const;
+
+ /// \brief Performs the CFG manipulation part of versioning the loop including
+ /// the DominatorTree and LoopInfo updates.
+ ///
+ /// The loop that was used to construct the class will be the "versioned" loop
+ /// i.e. the loop that will receive control if all the memchecks pass.
+ ///
+ /// This allows the loop transform pass to operate on the same loop regardless
+ /// of whether versioning was necessary or not:
+ ///
+ /// for each loop L:
+ /// analyze L
+ /// if versioning is necessary version L
+ /// transform L
+ void versionLoop(Pass *P);
+
+ /// \brief Adds the necessary PHI nodes for the versioned loops based on the
+ /// loop-defined values used outside of the loop.
+ ///
+ /// This needs to be called after versionLoop if there are defs in the loop
+ /// that are used outside the loop. FIXME: this should be invoked internally
+ /// by versionLoop and made private.
+ void addPHINodes(const SmallVectorImpl<Instruction *> &DefsUsedOutside);
+
+ /// \brief Returns the versioned loop. Control flows here if pointers in the
+ /// loop don't alias (i.e. all memchecks passed). (This loop is actually the
+ /// same as the original loop that we got constructed with.)
+ Loop *getVersionedLoop() { return VersionedLoop; }
+
+ /// \brief Returns the fall-back loop. Control flows here if pointers in the
+ /// loop may alias (i.e. one of the memchecks failed).
+ Loop *getNonVersionedLoop() { return NonVersionedLoop; }
+
+private:
+ /// \brief The original loop. This becomes the "versioned" one. I.e.,
+ /// control flows here if pointers in the loop don't alias.
+ Loop *VersionedLoop;
+ /// \brief The fall-back loop. I.e. control flows here if pointers in the
+ /// loop may alias (memchecks failed).
+ Loop *NonVersionedLoop;
+
+ /// \brief For each memory pointer it contains the partitionId it is used in.
+ /// If nullptr, no partitioning is used.
+ ///
+ /// The I-th entry corresponds to I-th entry in LAI.getRuntimePointerCheck().
+ /// If the pointer is used in multiple partitions the entry is set to -1.
+ const SmallVector<int, 8> *PtrToPartition;
+
+ /// \brief This maps the instructions from VersionedLoop to their counterpart
+ /// in NonVersionedLoop.
+ ValueToValueMapTy VMap;
+
+ /// \brief Analyses used.
+ const LoopAccessInfo &LAI;
+ LoopInfo *LI;
+ DominatorTree *DT;
+};
+}
+
+#endif
diff --git a/lib/Analysis/AliasAnalysis.cpp b/lib/Analysis/AliasAnalysis.cpp
index ad0727a0e0e5..44d137dffd22 100644
--- a/lib/Analysis/AliasAnalysis.cpp
+++ b/lib/Analysis/AliasAnalysis.cpp
@@ -71,11 +71,6 @@ void AliasAnalysis::deleteValue(Value *V) {
AA->deleteValue(V);
}
-void AliasAnalysis::copyValue(Value *From, Value *To) {
- assert(AA && "AA didn't call InitializeAliasAnalysis in its run method!");
- AA->copyValue(From, To);
-}
-
void AliasAnalysis::addEscapingUse(Use &U) {
assert(AA && "AA didn't call InitializeAliasAnalysis in its run method!");
AA->addEscapingUse(U);
diff --git a/lib/Analysis/AliasDebugger.cpp b/lib/Analysis/AliasDebugger.cpp
index 1ef49fc02fef..e5107b3bc827 100644
--- a/lib/Analysis/AliasDebugger.cpp
+++ b/lib/Analysis/AliasDebugger.cpp
@@ -124,10 +124,6 @@ namespace {
assert(Vals.find(V) != Vals.end() && "Never seen value in AA before");
AliasAnalysis::deleteValue(V);
}
- void copyValue(Value *From, Value *To) override {
- Vals.insert(To);
- AliasAnalysis::copyValue(From, To);
- }
};
}
diff --git a/lib/Analysis/AliasSetTracker.cpp b/lib/Analysis/AliasSetTracker.cpp
index bf8cda1ffaec..54d0f4304e1f 100644
--- a/lib/Analysis/AliasSetTracker.cpp
+++ b/lib/Analysis/AliasSetTracker.cpp
@@ -544,9 +544,6 @@ void AliasSetTracker::deleteValue(Value *PtrVal) {
// the tracker already knows about a value, it will ignore the request.
//
void AliasSetTracker::copyValue(Value *From, Value *To) {
- // Notify the alias analysis implementation that this value is copied.
- AA.copyValue(From, To);
-
// First, look up the PointerRec for this pointer.
PointerMapType::iterator I = PointerMap.find_as(From);
if (I == PointerMap.end())
diff --git a/lib/Analysis/BasicAliasAnalysis.cpp b/lib/Analysis/BasicAliasAnalysis.cpp
index 8e812252fdfe..68f766edb301 100644
--- a/lib/Analysis/BasicAliasAnalysis.cpp
+++ b/lib/Analysis/BasicAliasAnalysis.cpp
@@ -685,6 +685,9 @@ BasicAliasAnalysis::getModRefBehavior(ImmutableCallSite CS) {
if (CS.onlyReadsMemory())
Min = OnlyReadsMemory;
+ if (CS.onlyAccessesArgMemory())
+ Min = ModRefBehavior(Min & OnlyAccessesArgumentPointees);
+
// The AliasAnalysis base class has some smarts, lets use them.
return ModRefBehavior(AliasAnalysis::getModRefBehavior(CS) & Min);
}
@@ -710,6 +713,9 @@ BasicAliasAnalysis::getModRefBehavior(const Function *F) {
if (F->onlyReadsMemory())
Min = OnlyReadsMemory;
+ if (F->onlyAccessesArgMemory())
+ Min = ModRefBehavior(Min & OnlyAccessesArgumentPointees);
+
const TargetLibraryInfo &TLI =
getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
if (isMemsetPattern16(F, TLI))
diff --git a/lib/Analysis/ConstantFolding.cpp b/lib/Analysis/ConstantFolding.cpp
index 2f4c6a92f9af..02a5aef03223 100644
--- a/lib/Analysis/ConstantFolding.cpp
+++ b/lib/Analysis/ConstantFolding.cpp
@@ -1234,6 +1234,8 @@ bool llvm::canConstantFoldCallTo(const Function *F) {
case Intrinsic::floor:
case Intrinsic::ceil:
case Intrinsic::sqrt:
+ case Intrinsic::sin:
+ case Intrinsic::cos:
case Intrinsic::pow:
case Intrinsic::powi:
case Intrinsic::bswap:
@@ -1450,6 +1452,10 @@ static Constant *ConstantFoldScalarCall(StringRef Name, unsigned IntrinsicID,
return ConstantFoldFP(floor, V, Ty);
case Intrinsic::ceil:
return ConstantFoldFP(ceil, V, Ty);
+ case Intrinsic::sin:
+ return ConstantFoldFP(sin, V, Ty);
+ case Intrinsic::cos:
+ return ConstantFoldFP(cos, V, Ty);
}
if (!TLI)
diff --git a/lib/Analysis/IPA/GlobalsModRef.cpp b/lib/Analysis/IPA/GlobalsModRef.cpp
index f1ddde252924..18d45dd6a396 100644
--- a/lib/Analysis/IPA/GlobalsModRef.cpp
+++ b/lib/Analysis/IPA/GlobalsModRef.cpp
@@ -42,94 +42,111 @@ STATISTIC(NumReadMemFunctions, "Number of functions that only read memory");
STATISTIC(NumIndirectGlobalVars, "Number of indirect global objects");
namespace {
- /// FunctionRecord - One instance of this structure is stored for every
- /// function in the program. Later, the entries for these functions are
- /// removed if the function is found to call an external function (in which
- /// case we know nothing about it.
- struct FunctionRecord {
- /// GlobalInfo - Maintain mod/ref info for all of the globals without
- /// addresses taken that are read or written (transitively) by this
- /// function.
- std::map<const GlobalValue*, unsigned> GlobalInfo;
-
- /// MayReadAnyGlobal - May read global variables, but it is not known which.
- bool MayReadAnyGlobal;
-
- unsigned getInfoForGlobal(const GlobalValue *GV) const {
- unsigned Effect = MayReadAnyGlobal ? AliasAnalysis::Ref : 0;
- std::map<const GlobalValue*, unsigned>::const_iterator I =
+/// FunctionRecord - One instance of this structure is stored for every
+/// function in the program. Later, the entries for these functions are
+/// removed if the function is found to call an external function (in which
+/// case we know nothing about it.
+struct FunctionRecord {
+ /// GlobalInfo - Maintain mod/ref info for all of the globals without
+ /// addresses taken that are read or written (transitively) by this
+ /// function.
+ std::map<const GlobalValue *, unsigned> GlobalInfo;
+
+ /// MayReadAnyGlobal - May read global variables, but it is not known which.
+ bool MayReadAnyGlobal;
+
+ unsigned getInfoForGlobal(const GlobalValue *GV) const {
+ unsigned Effect = MayReadAnyGlobal ? AliasAnalysis::Ref : 0;
+ std::map<const GlobalValue *, unsigned>::const_iterator I =
GlobalInfo.find(GV);
- if (I != GlobalInfo.end())
- Effect |= I->second;
- return Effect;
- }
+ if (I != GlobalInfo.end())
+ Effect |= I->second;
+ return Effect;
+ }
- /// FunctionEffect - Capture whether or not this function reads or writes to
- /// ANY memory. If not, we can do a lot of aggressive analysis on it.
- unsigned FunctionEffect;
+ /// FunctionEffect - Capture whether or not this function reads or writes to
+ /// ANY memory. If not, we can do a lot of aggressive analysis on it.
+ unsigned FunctionEffect;
- FunctionRecord() : MayReadAnyGlobal (false), FunctionEffect(0) {}
- };
+ FunctionRecord() : MayReadAnyGlobal(false), FunctionEffect(0) {}
+};
- /// GlobalsModRef - The actual analysis pass.
- class GlobalsModRef : public ModulePass, public AliasAnalysis {
- /// NonAddressTakenGlobals - The globals that do not have their addresses
- /// taken.
- std::set<const GlobalValue*> NonAddressTakenGlobals;
+/// GlobalsModRef - The actual analysis pass.
+class GlobalsModRef : public ModulePass, public AliasAnalysis {
+ /// NonAddressTakenGlobals - The globals that do not have their addresses
+ /// taken.
+ std::set<const GlobalValue *> NonAddressTakenGlobals;
- /// IndirectGlobals - The memory pointed to by this global is known to be
- /// 'owned' by the global.
- std::set<const GlobalValue*> IndirectGlobals;
+ /// IndirectGlobals - The memory pointed to by this global is known to be
+ /// 'owned' by the global.
+ std::set<const GlobalValue *> IndirectGlobals;
- /// AllocsForIndirectGlobals - If an instruction allocates memory for an
- /// indirect global, this map indicates which one.
- std::map<const Value*, const GlobalValue*> AllocsForIndirectGlobals;
+ /// AllocsForIndirectGlobals - If an instruction allocates memory for an
+ /// indirect global, this map indicates which one.
+ std::map<const Value *, const GlobalValue *> AllocsForIndirectGlobals;
- /// FunctionInfo - For each function, keep track of what globals are
- /// modified or read.
- std::map<const Function*, FunctionRecord> FunctionInfo;
+ /// FunctionInfo - For each function, keep track of what globals are
+ /// modified or read.
+ std::map<const Function *, FunctionRecord> FunctionInfo;
- public:
- static char ID;
- GlobalsModRef() : ModulePass(ID) {
- initializeGlobalsModRefPass(*PassRegistry::getPassRegistry());
- }
+public:
+ static char ID;
+ GlobalsModRef() : ModulePass(ID) {
+ initializeGlobalsModRefPass(*PassRegistry::getPassRegistry());
+ }
- bool runOnModule(Module &M) override {
- InitializeAliasAnalysis(this, &M.getDataLayout());
+ bool runOnModule(Module &M) override {
+ InitializeAliasAnalysis(this, &M.getDataLayout());
- // Find non-addr taken globals.
- AnalyzeGlobals(M);
+ // Find non-addr taken globals.
+ AnalyzeGlobals(M);
- // Propagate on CG.
- AnalyzeCallGraph(getAnalysis<CallGraphWrapperPass>().getCallGraph(), M);
- return false;
- }
+ // Propagate on CG.
+ AnalyzeCallGraph(getAnalysis<CallGraphWrapperPass>().getCallGraph(), M);
+ return false;
+ }
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- AliasAnalysis::getAnalysisUsage(AU);
- AU.addRequired<CallGraphWrapperPass>();
- AU.setPreservesAll(); // Does not transform code
- }
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
+ AliasAnalysis::getAnalysisUsage(AU);
+ AU.addRequired<CallGraphWrapperPass>();
+ AU.setPreservesAll(); // Does not transform code
+ }
+
+ //------------------------------------------------
+ // Implement the AliasAnalysis API
+ //
+ AliasResult alias(const MemoryLocation &LocA,
+ const MemoryLocation &LocB) override;
+ ModRefResult getModRefInfo(ImmutableCallSite CS,
+ const MemoryLocation &Loc) override;
+ ModRefResult getModRefInfo(ImmutableCallSite CS1,
+ ImmutableCallSite CS2) override {
+ return AliasAnalysis::getModRefInfo(CS1, CS2);
+ }
- //------------------------------------------------
- // Implement the AliasAnalysis API
- //
- AliasResult alias(const MemoryLocation &LocA,
- const MemoryLocation &LocB) override;
- ModRefResult getModRefInfo(ImmutableCallSite CS,
- const MemoryLocation &Loc) override;
- ModRefResult getModRefInfo(ImmutableCallSite CS1,
- ImmutableCallSite CS2) override {
- return AliasAnalysis::getModRefInfo(CS1, CS2);
+ /// getModRefBehavior - Return the behavior of the specified function if
+ /// called from the specified call site. The call site may be null in which
+ /// case the most generic behavior of this function should be returned.
+ ModRefBehavior getModRefBehavior(const Function *F) override {
+ ModRefBehavior Min = UnknownModRefBehavior;
+
+ if (FunctionRecord *FR = getFunctionInfo(F)) {
+ if (FR->FunctionEffect == 0)
+ Min = DoesNotAccessMemory;
+ else if ((FR->FunctionEffect & Mod) == 0)
+ Min = OnlyReadsMemory;
}
- /// getModRefBehavior - Return the behavior of the specified function if
- /// called from the specified call site. The call site may be null in which
- /// case the most generic behavior of this function should be returned.
- ModRefBehavior getModRefBehavior(const Function *F) override {
- ModRefBehavior Min = UnknownModRefBehavior;
+ return ModRefBehavior(AliasAnalysis::getModRefBehavior(F) & Min);
+ }
+
+ /// getModRefBehavior - Return the behavior of the specified function if
+ /// called from the specified call site. The call site may be null in which
+ /// case the most generic behavior of this function should be returned.
+ ModRefBehavior getModRefBehavior(ImmutableCallSite CS) override {
+ ModRefBehavior Min = UnknownModRefBehavior;
+ if (const Function *F = CS.getCalledFunction())
if (FunctionRecord *FR = getFunctionInfo(F)) {
if (FR->FunctionEffect == 0)
Min = DoesNotAccessMemory;
@@ -137,68 +154,50 @@ namespace {
Min = OnlyReadsMemory;
}
- return ModRefBehavior(AliasAnalysis::getModRefBehavior(F) & Min);
- }
-
- /// getModRefBehavior - Return the behavior of the specified function if
- /// called from the specified call site. The call site may be null in which
- /// case the most generic behavior of this function should be returned.
- ModRefBehavior getModRefBehavior(ImmutableCallSite CS) override {
- ModRefBehavior Min = UnknownModRefBehavior;
-
- if (const Function* F = CS.getCalledFunction())
- if (FunctionRecord *FR = getFunctionInfo(F)) {
- if (FR->FunctionEffect == 0)
- Min = DoesNotAccessMemory;
- else if ((FR->FunctionEffect & Mod) == 0)
- Min = OnlyReadsMemory;
- }
+ return ModRefBehavior(AliasAnalysis::getModRefBehavior(CS) & Min);
+ }
- return ModRefBehavior(AliasAnalysis::getModRefBehavior(CS) & Min);
- }
+ void deleteValue(Value *V) override;
+ void addEscapingUse(Use &U) override;
+
+ /// getAdjustedAnalysisPointer - This method is used when a pass implements
+ /// an analysis interface through multiple inheritance. If needed, it
+ /// should override this to adjust the this pointer as needed for the
+ /// specified pass info.
+ void *getAdjustedAnalysisPointer(AnalysisID PI) override {
+ if (PI == &AliasAnalysis::ID)
+ return (AliasAnalysis *)this;
+ return this;
+ }
- void deleteValue(Value *V) override;
- void copyValue(Value *From, Value *To) override;
- void addEscapingUse(Use &U) override;
-
- /// getAdjustedAnalysisPointer - This method is used when a pass implements
- /// an analysis interface through multiple inheritance. If needed, it
- /// should override this to adjust the this pointer as needed for the
- /// specified pass info.
- void *getAdjustedAnalysisPointer(AnalysisID PI) override {
- if (PI == &AliasAnalysis::ID)
- return (AliasAnalysis*)this;
- return this;
- }
-
- private:
- /// getFunctionInfo - Return the function info for the function, or null if
- /// we don't have anything useful to say about it.
- FunctionRecord *getFunctionInfo(const Function *F) {
- std::map<const Function*, FunctionRecord>::iterator I =
+private:
+ /// getFunctionInfo - Return the function info for the function, or null if
+ /// we don't have anything useful to say about it.
+ FunctionRecord *getFunctionInfo(const Function *F) {
+ std::map<const Function *, FunctionRecord>::iterator I =
FunctionInfo.find(F);
- if (I != FunctionInfo.end())
- return &I->second;
- return nullptr;
- }
+ if (I != FunctionInfo.end())
+ return &I->second;
+ return nullptr;
+ }
- void AnalyzeGlobals(Module &M);
- void AnalyzeCallGraph(CallGraph &CG, Module &M);
- bool AnalyzeUsesOfPointer(Value *V, std::vector<Function*> &Readers,
- std::vector<Function*> &Writers,
- GlobalValue *OkayStoreDest = nullptr);
- bool AnalyzeIndirectGlobalMemory(GlobalValue *GV);
- };
+ void AnalyzeGlobals(Module &M);
+ void AnalyzeCallGraph(CallGraph &CG, Module &M);
+ bool AnalyzeUsesOfPointer(Value *V, std::vector<Function *> &Readers,
+ std::vector<Function *> &Writers,
+ GlobalValue *OkayStoreDest = nullptr);
+ bool AnalyzeIndirectGlobalMemory(GlobalValue *GV);
+};
}
char GlobalsModRef::ID = 0;
-INITIALIZE_AG_PASS_BEGIN(GlobalsModRef, AliasAnalysis,
- "globalsmodref-aa", "Simple mod/ref analysis for globals",
- false, true, false)
+INITIALIZE_AG_PASS_BEGIN(GlobalsModRef, AliasAnalysis, "globalsmodref-aa",
+ "Simple mod/ref analysis for globals", false, true,
+ false)
INITIALIZE_PASS_DEPENDENCY(CallGraphWrapperPass)
-INITIALIZE_AG_PASS_END(GlobalsModRef, AliasAnalysis,
- "globalsmodref-aa", "Simple mod/ref analysis for globals",
- false, true, false)
+INITIALIZE_AG_PASS_END(GlobalsModRef, AliasAnalysis, "globalsmodref-aa",
+ "Simple mod/ref analysis for globals", false, true,
+ false)
Pass *llvm::createGlobalsModRefPass() { return new GlobalsModRef(); }
@@ -207,7 +206,7 @@ Pass *llvm::createGlobalsModRefPass() { return new GlobalsModRef(); }
/// (really, their address passed to something nontrivial), record this fact,
/// and record the functions that they are used directly in.
void GlobalsModRef::AnalyzeGlobals(Module &M) {
- std::vector<Function*> Readers, Writers;
+ std::vector<Function *> Readers, Writers;
for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
if (I->hasLocalLinkage()) {
if (!AnalyzeUsesOfPointer(I, Readers, Writers)) {
@@ -215,11 +214,12 @@ void GlobalsModRef::AnalyzeGlobals(Module &M) {
NonAddressTakenGlobals.insert(I);
++NumNonAddrTakenFunctions;
}
- Readers.clear(); Writers.clear();
+ Readers.clear();
+ Writers.clear();
}
- for (Module::global_iterator I = M.global_begin(), E = M.global_end();
- I != E; ++I)
+ for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E;
+ ++I)
if (I->hasLocalLinkage()) {
if (!AnalyzeUsesOfPointer(I, Readers, Writers)) {
// Remember that we are tracking this global, and the mod/ref fns
@@ -228,7 +228,7 @@ void GlobalsModRef::AnalyzeGlobals(Module &M) {
for (unsigned i = 0, e = Readers.size(); i != e; ++i)
FunctionInfo[Readers[i]].GlobalInfo[I] |= Ref;
- if (!I->isConstant()) // No need to keep track of writers to constants
+ if (!I->isConstant()) // No need to keep track of writers to constants
for (unsigned i = 0, e = Writers.size(); i != e; ++i)
FunctionInfo[Writers[i]].GlobalInfo[I] |= Mod;
++NumNonAddrTakenGlobalVars;
@@ -238,7 +238,8 @@ void GlobalsModRef::AnalyzeGlobals(Module &M) {
AnalyzeIndirectGlobalMemory(I))
++NumIndirectGlobalVars;
}
- Readers.clear(); Writers.clear();
+ Readers.clear();
+ Writers.clear();
}
}
@@ -249,10 +250,11 @@ void GlobalsModRef::AnalyzeGlobals(Module &M) {
///
/// If OkayStoreDest is non-null, stores into this global are allowed.
bool GlobalsModRef::AnalyzeUsesOfPointer(Value *V,
- std::vector<Function*> &Readers,
- std::vector<Function*> &Writers,
+ std::vector<Function *> &Readers,
+ std::vector<Function *> &Writers,
GlobalValue *OkayStoreDest) {
- if (!V->getType()->isPointerTy()) return true;
+ if (!V->getType()->isPointerTy())
+ return true;
for (Use &U : V->uses()) {
User *I = U.getUser();
@@ -262,7 +264,7 @@ bool GlobalsModRef::AnalyzeUsesOfPointer(Value *V,
if (V == SI->getOperand(1)) {
Writers.push_back(SI->getParent()->getParent());
} else if (SI->getOperand(1) != OkayStoreDest) {
- return true; // Storing the pointer
+ return true; // Storing the pointer
}
} else if (Operator::getOpcode(I) == Instruction::GetElementPtr) {
if (AnalyzeUsesOfPointer(I, Readers, Writers))
@@ -282,7 +284,7 @@ bool GlobalsModRef::AnalyzeUsesOfPointer(Value *V,
}
} else if (ICmpInst *ICI = dyn_cast<ICmpInst>(I)) {
if (!isa<ConstantPointerNull>(ICI->getOperand(1)))
- return true; // Allow comparison against null.
+ return true; // Allow comparison against null.
} else {
return true;
}
@@ -301,7 +303,7 @@ bool GlobalsModRef::AnalyzeUsesOfPointer(Value *V,
bool GlobalsModRef::AnalyzeIndirectGlobalMemory(GlobalValue *GV) {
// Keep track of values related to the allocation of the memory, f.e. the
// value produced by the malloc call and any casts.
- std::vector<Value*> AllocRelatedValues;
+ std::vector<Value *> AllocRelatedValues;
// Walk the user list of the global. If we find anything other than a direct
// load or store, bail out.
@@ -310,13 +312,14 @@ bool GlobalsModRef::AnalyzeIndirectGlobalMemory(GlobalValue *GV) {
// The pointer loaded from the global can only be used in simple ways:
// we allow addressing of it and loading storing to it. We do *not* allow
// storing the loaded pointer somewhere else or passing to a function.
- std::vector<Function*> ReadersWriters;
+ std::vector<Function *> ReadersWriters;
if (AnalyzeUsesOfPointer(LI, ReadersWriters, ReadersWriters))
- return false; // Loaded pointer escapes.
+ return false; // Loaded pointer escapes.
// TODO: Could try some IP mod/ref of the loaded pointer.
} else if (StoreInst *SI = dyn_cast<StoreInst>(U)) {
// Storing the global itself.
- if (SI->getOperand(0) == GV) return false;
+ if (SI->getOperand(0) == GV)
+ return false;
// If storing the null pointer, ignore it.
if (isa<ConstantPointerNull>(SI->getOperand(0)))
@@ -327,13 +330,13 @@ bool GlobalsModRef::AnalyzeIndirectGlobalMemory(GlobalValue *GV) {
GV->getParent()->getDataLayout());
if (!isAllocLikeFn(Ptr, TLI))
- return false; // Too hard to analyze.
+ return false; // Too hard to analyze.
// Analyze all uses of the allocation. If any of them are used in a
// non-simple way (e.g. stored to another global) bail out.
- std::vector<Function*> ReadersWriters;
+ std::vector<Function *> ReadersWriters;
if (AnalyzeUsesOfPointer(Ptr, ReadersWriters, ReadersWriters, GV))
- return false; // Loaded pointer escapes.
+ return false; // Loaded pointer escapes.
// Remember that this allocation is related to the indirect global.
AllocRelatedValues.push_back(Ptr);
@@ -360,7 +363,7 @@ bool GlobalsModRef::AnalyzeIndirectGlobalMemory(GlobalValue *GV) {
void GlobalsModRef::AnalyzeCallGraph(CallGraph &CG, Module &M) {
// We do a bottom-up SCC traversal of the call graph. In other words, we
// visit all callees before callers (leaf-first).
- for (scc_iterator<CallGraph*> I = scc_begin(&CG); !I.isAtEnd(); ++I) {
+ for (scc_iterator<CallGraph *> I = scc_begin(&CG); !I.isAtEnd(); ++I) {
const std::vector<CallGraphNode *> &SCC = *I;
assert(!SCC.empty() && "SCC with no functions?");
@@ -437,9 +440,10 @@ void GlobalsModRef::AnalyzeCallGraph(CallGraph &CG, Module &M) {
}
// Scan the function bodies for explicit loads or stores.
- for (unsigned i = 0, e = SCC.size(); i != e && FunctionEffect != ModRef;++i)
+ for (unsigned i = 0, e = SCC.size(); i != e && FunctionEffect != ModRef;
+ ++i)
for (inst_iterator II = inst_begin(SCC[i]->getFunction()),
- E = inst_end(SCC[i]->getFunction());
+ E = inst_end(SCC[i]->getFunction());
II != E && FunctionEffect != ModRef; ++II)
if (LoadInst *LI = dyn_cast<LoadInst>(&*II)) {
FunctionEffect |= Ref;
@@ -474,8 +478,6 @@ void GlobalsModRef::AnalyzeCallGraph(CallGraph &CG, Module &M) {
}
}
-
-
/// alias - If one of the pointers is to a global that we are tracking, and the
/// other is some random pointer, we know there cannot be an alias, because the
/// address of the global isn't taken.
@@ -492,8 +494,10 @@ AliasResult GlobalsModRef::alias(const MemoryLocation &LocA,
if (GV1 || GV2) {
// If the global's address is taken, pretend we don't know it's a pointer to
// the global.
- if (GV1 && !NonAddressTakenGlobals.count(GV1)) GV1 = nullptr;
- if (GV2 && !NonAddressTakenGlobals.count(GV2)) GV2 = nullptr;
+ if (GV1 && !NonAddressTakenGlobals.count(GV1))
+ GV1 = nullptr;
+ if (GV2 && !NonAddressTakenGlobals.count(GV2))
+ GV2 = nullptr;
// If the two pointers are derived from two different non-addr-taken
// globals, or if one is and the other isn't, we know these can't alias.
@@ -554,7 +558,6 @@ GlobalsModRef::getModRefInfo(ImmutableCallSite CS, const MemoryLocation &Loc) {
return ModRefResult(Known & AliasAnalysis::getModRefInfo(CS, Loc));
}
-
//===----------------------------------------------------------------------===//
// Methods to update the analysis as a result of the client transformation.
//
@@ -565,9 +568,10 @@ void GlobalsModRef::deleteValue(Value *V) {
// any AllocRelatedValues for it.
if (IndirectGlobals.erase(GV)) {
// Remove any entries in AllocsForIndirectGlobals for this global.
- for (std::map<const Value*, const GlobalValue*>::iterator
- I = AllocsForIndirectGlobals.begin(),
- E = AllocsForIndirectGlobals.end(); I != E; ) {
+ for (std::map<const Value *, const GlobalValue *>::iterator
+ I = AllocsForIndirectGlobals.begin(),
+ E = AllocsForIndirectGlobals.end();
+ I != E;) {
if (I->second == GV) {
AllocsForIndirectGlobals.erase(I++);
} else {
@@ -585,16 +589,12 @@ void GlobalsModRef::deleteValue(Value *V) {
AliasAnalysis::deleteValue(V);
}
-void GlobalsModRef::copyValue(Value *From, Value *To) {
- AliasAnalysis::copyValue(From, To);
-}
-
void GlobalsModRef::addEscapingUse(Use &U) {
// For the purposes of this analysis, it is conservatively correct to treat
// a newly escaping value equivalently to a deleted one. We could perhaps
// be more precise by processing the new use and attempting to update our
// saved analysis results to accommodate it.
deleteValue(U);
-
+
AliasAnalysis::addEscapingUse(U);
}
diff --git a/lib/Analysis/IPA/InlineCost.cpp b/lib/Analysis/IPA/InlineCost.cpp
index 349b9cac2c2d..c0d2e375cb04 100644
--- a/lib/Analysis/IPA/InlineCost.cpp
+++ b/lib/Analysis/IPA/InlineCost.cpp
@@ -783,7 +783,7 @@ bool CallAnalyzer::visitCallSite(CallSite CS) {
case Intrinsic::memmove:
// SROA can usually chew through these intrinsics, but they aren't free.
return false;
- case Intrinsic::frameescape:
+ case Intrinsic::localescape:
HasFrameEscape = true;
return false;
}
@@ -1424,11 +1424,11 @@ bool InlineCostAnalysis::isInlineViable(Function &F) {
cast<CallInst>(CS.getInstruction())->canReturnTwice())
return false;
- // Disallow inlining functions that call @llvm.frameescape. Doing this
+ // Disallow inlining functions that call @llvm.localescape. Doing this
// correctly would require major changes to the inliner.
if (CS.getCalledFunction() &&
CS.getCalledFunction()->getIntrinsicID() ==
- llvm::Intrinsic::frameescape)
+ llvm::Intrinsic::localescape)
return false;
}
}
diff --git a/lib/Analysis/IVUsers.cpp b/lib/Analysis/IVUsers.cpp
index b88b2496b875..926787d3be91 100644
--- a/lib/Analysis/IVUsers.cpp
+++ b/lib/Analysis/IVUsers.cpp
@@ -12,8 +12,10 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/Analysis/IVUsers.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/Analysis/AssumptionCache.h"
+#include "llvm/Analysis/CodeMetrics.h"
+#include "llvm/Analysis/IVUsers.h"
#include "llvm/Analysis/LoopPass.h"
#include "llvm/Analysis/ScalarEvolutionExpressions.h"
#include "llvm/Analysis/ValueTracking.h"
@@ -34,6 +36,7 @@ using namespace llvm;
char IVUsers::ID = 0;
INITIALIZE_PASS_BEGIN(IVUsers, "iv-users",
"Induction Variable Users", false, true)
+INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
INITIALIZE_PASS_DEPENDENCY(ScalarEvolution)
@@ -137,6 +140,11 @@ bool IVUsers::AddUsersImpl(Instruction *I,
if (Width > 64 || !DL.isLegalInteger(Width))
return false;
+ // Don't attempt to promote ephemeral values to indvars. They will be removed
+ // later anyway.
+ if (EphValues.count(I))
+ return false;
+
// Get the symbolic expression for this instruction.
const SCEV *ISE = SE->getSCEV(I);
@@ -244,6 +252,7 @@ IVUsers::IVUsers()
}
void IVUsers::getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.addRequired<AssumptionCacheTracker>();
AU.addRequired<LoopInfoWrapperPass>();
AU.addRequired<DominatorTreeWrapperPass>();
AU.addRequired<ScalarEvolution>();
@@ -253,10 +262,16 @@ void IVUsers::getAnalysisUsage(AnalysisUsage &AU) const {
bool IVUsers::runOnLoop(Loop *l, LPPassManager &LPM) {
L = l;
+ AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(
+ *L->getHeader()->getParent());
LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
SE = &getAnalysis<ScalarEvolution>();
+ // Collect ephemeral values so that AddUsersIfInteresting skips them.
+ EphValues.clear();
+ CodeMetrics::collectEphemeralValues(L, AC, EphValues);
+
// Find all uses of induction variables in this loop, and categorize
// them by stride. Start by finding all of the PHI nodes in the header for
// this loop. If they are induction variables, inspect their uses.
diff --git a/lib/Analysis/InstructionSimplify.cpp b/lib/Analysis/InstructionSimplify.cpp
index 12e406bb1a2d..fa42b48b6cdb 100644
--- a/lib/Analysis/InstructionSimplify.cpp
+++ b/lib/Analysis/InstructionSimplify.cpp
@@ -24,6 +24,7 @@
#include "llvm/Analysis/ConstantFolding.h"
#include "llvm/Analysis/MemoryBuiltins.h"
#include "llvm/Analysis/ValueTracking.h"
+#include "llvm/Analysis/VectorUtils.h"
#include "llvm/IR/ConstantRange.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Dominators.h"
@@ -3046,7 +3047,8 @@ Value *llvm::SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
/// SimplifyFCmpInst - 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,
- const Query &Q, unsigned MaxRecurse) {
+ FastMathFlags FMF, const Query &Q,
+ unsigned MaxRecurse) {
CmpInst::Predicate Pred = (CmpInst::Predicate)Predicate;
assert(CmpInst::isFPPredicate(Pred) && "Not an FP compare!");
@@ -3065,6 +3067,14 @@ static Value *SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
if (Pred == FCmpInst::FCMP_TRUE)
return ConstantInt::get(GetCompareTy(LHS), 1);
+ // UNO/ORD predicates can be trivially folded if NaNs are ignored.
+ if (FMF.noNaNs()) {
+ if (Pred == FCmpInst::FCMP_UNO)
+ return ConstantInt::get(GetCompareTy(LHS), 0);
+ if (Pred == FCmpInst::FCMP_ORD)
+ return ConstantInt::get(GetCompareTy(LHS), 1);
+ }
+
// fcmp pred x, undef and fcmp pred undef, x
// fold to true if unordered, false if ordered
if (isa<UndefValue>(LHS) || isa<UndefValue>(RHS)) {
@@ -3151,12 +3161,12 @@ static Value *SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
}
Value *llvm::SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
- const DataLayout &DL,
+ FastMathFlags FMF, const DataLayout &DL,
const TargetLibraryInfo *TLI,
const DominatorTree *DT, AssumptionCache *AC,
const Instruction *CxtI) {
- return ::SimplifyFCmpInst(Predicate, LHS, RHS, Query(DL, TLI, DT, AC, CxtI),
- RecursionLimit);
+ return ::SimplifyFCmpInst(Predicate, LHS, RHS, FMF,
+ Query(DL, TLI, DT, AC, CxtI), RecursionLimit);
}
/// SimplifyWithOpReplaced - See if V simplifies when its operand Op is
@@ -3511,6 +3521,82 @@ Value *llvm::SimplifyInsertValueInst(
RecursionLimit);
}
+/// SimplifyExtractValueInst - 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) {
+ if (auto *CAgg = dyn_cast<Constant>(Agg))
+ return ConstantFoldExtractValueInstruction(CAgg, Idxs);
+
+ // extractvalue x, (insertvalue y, elt, n), n -> elt
+ unsigned NumIdxs = Idxs.size();
+ for (auto *IVI = dyn_cast<InsertValueInst>(Agg); IVI != nullptr;
+ IVI = dyn_cast<InsertValueInst>(IVI->getAggregateOperand())) {
+ ArrayRef<unsigned> InsertValueIdxs = IVI->getIndices();
+ unsigned NumInsertValueIdxs = InsertValueIdxs.size();
+ unsigned NumCommonIdxs = std::min(NumInsertValueIdxs, NumIdxs);
+ if (InsertValueIdxs.slice(0, NumCommonIdxs) ==
+ Idxs.slice(0, NumCommonIdxs)) {
+ if (NumIdxs == NumInsertValueIdxs)
+ return IVI->getInsertedValueOperand();
+ break;
+ }
+ }
+
+ return nullptr;
+}
+
+Value *llvm::SimplifyExtractValueInst(Value *Agg, ArrayRef<unsigned> Idxs,
+ const DataLayout &DL,
+ const TargetLibraryInfo *TLI,
+ const DominatorTree *DT,
+ AssumptionCache *AC,
+ const Instruction *CxtI) {
+ return ::SimplifyExtractValueInst(Agg, Idxs, Query(DL, TLI, DT, AC, CxtI),
+ RecursionLimit);
+}
+
+/// SimplifyExtractElementInst - 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 &,
+ unsigned) {
+ if (auto *CVec = dyn_cast<Constant>(Vec)) {
+ if (auto *CIdx = dyn_cast<Constant>(Idx))
+ return ConstantFoldExtractElementInstruction(CVec, CIdx);
+
+ // The index is not relevant if our vector is a splat.
+ if (auto *Splat = CVec->getSplatValue())
+ return Splat;
+
+ if (isa<UndefValue>(Vec))
+ return UndefValue::get(Vec->getType()->getVectorElementType());
+ }
+
+ // If extracting a specified index from the vector, see if we can recursively
+ // find a previously computed scalar that was inserted into the vector.
+ if (auto *IdxC = dyn_cast<ConstantInt>(Idx)) {
+ unsigned IndexVal = IdxC->getZExtValue();
+ unsigned VectorWidth = Vec->getType()->getVectorNumElements();
+
+ // If this is extracting an invalid index, turn this into undef, to avoid
+ // crashing the code below.
+ if (IndexVal >= VectorWidth)
+ return UndefValue::get(Vec->getType()->getVectorElementType());
+
+ if (Value *Elt = findScalarElement(Vec, IndexVal))
+ return Elt;
+ }
+
+ return nullptr;
+}
+
+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),
+ RecursionLimit);
+}
+
/// SimplifyPHINode - See if we can fold the given phi. If not, returns null.
static Value *SimplifyPHINode(PHINode *PN, const Query &Q) {
// If all of the PHI's incoming values are the same then replace the PHI node
@@ -3670,7 +3756,7 @@ static Value *SimplifyCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
const Query &Q, unsigned MaxRecurse) {
if (CmpInst::isIntPredicate((CmpInst::Predicate)Predicate))
return SimplifyICmpInst(Predicate, LHS, RHS, Q, MaxRecurse);
- return SimplifyFCmpInst(Predicate, LHS, RHS, Q, MaxRecurse);
+ return SimplifyFCmpInst(Predicate, LHS, RHS, FastMathFlags(), Q, MaxRecurse);
}
Value *llvm::SimplifyCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
@@ -3900,9 +3986,9 @@ Value *llvm::SimplifyInstruction(Instruction *I, const DataLayout &DL,
I->getOperand(1), DL, TLI, DT, AC, I);
break;
case Instruction::FCmp:
- Result =
- SimplifyFCmpInst(cast<FCmpInst>(I)->getPredicate(), I->getOperand(0),
- I->getOperand(1), DL, TLI, DT, AC, I);
+ Result = SimplifyFCmpInst(cast<FCmpInst>(I)->getPredicate(),
+ I->getOperand(0), I->getOperand(1),
+ I->getFastMathFlags(), DL, TLI, DT, AC, I);
break;
case Instruction::Select:
Result = SimplifySelectInst(I->getOperand(0), I->getOperand(1),
@@ -3920,6 +4006,18 @@ Value *llvm::SimplifyInstruction(Instruction *I, const DataLayout &DL,
IV->getIndices(), DL, TLI, DT, AC, I);
break;
}
+ case Instruction::ExtractValue: {
+ auto *EVI = cast<ExtractValueInst>(I);
+ Result = SimplifyExtractValueInst(EVI->getAggregateOperand(),
+ EVI->getIndices(), DL, TLI, DT, AC, I);
+ break;
+ }
+ case Instruction::ExtractElement: {
+ auto *EEI = cast<ExtractElementInst>(I);
+ Result = SimplifyExtractElementInst(
+ EEI->getVectorOperand(), EEI->getIndexOperand(), DL, TLI, DT, AC, I);
+ break;
+ }
case Instruction::PHI:
Result = SimplifyPHINode(cast<PHINode>(I), Query(DL, TLI, DT, AC, I));
break;
diff --git a/lib/Analysis/LoopAccessAnalysis.cpp b/lib/Analysis/LoopAccessAnalysis.cpp
index b11cd7e84a6d..becbae4c5b50 100644
--- a/lib/Analysis/LoopAccessAnalysis.cpp
+++ b/lib/Analysis/LoopAccessAnalysis.cpp
@@ -48,6 +48,13 @@ static cl::opt<unsigned, true> RuntimeMemoryCheckThreshold(
cl::location(VectorizerParams::RuntimeMemoryCheckThreshold), cl::init(8));
unsigned VectorizerParams::RuntimeMemoryCheckThreshold;
+/// \brief The maximum iterations used to merge memory checks
+static cl::opt<unsigned> MemoryCheckMergeThreshold(
+ "memory-check-merge-threshold", cl::Hidden,
+ cl::desc("Maximum number of comparisons done when trying to merge "
+ "runtime memory checks. (default = 100)"),
+ cl::init(100));
+
/// Maximum SIMD width.
const unsigned VectorizerParams::MaxVectorWidth = 64;
@@ -112,35 +119,182 @@ const SCEV *llvm::replaceSymbolicStrideSCEV(ScalarEvolution *SE,
return SE->getSCEV(Ptr);
}
-void LoopAccessInfo::RuntimePointerCheck::insert(
- ScalarEvolution *SE, Loop *Lp, Value *Ptr, bool WritePtr, unsigned DepSetId,
- unsigned ASId, const ValueToValueMap &Strides) {
+void RuntimePointerChecking::insert(Loop *Lp, Value *Ptr, bool WritePtr,
+ unsigned DepSetId, unsigned ASId,
+ const ValueToValueMap &Strides) {
// Get the stride replaced scev.
const SCEV *Sc = replaceSymbolicStrideSCEV(SE, Strides, Ptr);
const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(Sc);
assert(AR && "Invalid addrec expression");
const SCEV *Ex = SE->getBackedgeTakenCount(Lp);
const SCEV *ScEnd = AR->evaluateAtIteration(Ex, *SE);
- Pointers.push_back(Ptr);
- Starts.push_back(AR->getStart());
- Ends.push_back(ScEnd);
- IsWritePtr.push_back(WritePtr);
- DependencySetId.push_back(DepSetId);
- AliasSetId.push_back(ASId);
+ Pointers.emplace_back(Ptr, AR->getStart(), ScEnd, WritePtr, DepSetId, ASId,
+ Sc);
+}
+
+bool RuntimePointerChecking::needsChecking(
+ const CheckingPtrGroup &M, const CheckingPtrGroup &N,
+ const SmallVectorImpl<int> *PtrPartition) const {
+ for (unsigned I = 0, EI = M.Members.size(); EI != I; ++I)
+ for (unsigned J = 0, EJ = N.Members.size(); EJ != J; ++J)
+ if (needsChecking(M.Members[I], N.Members[J], PtrPartition))
+ return true;
+ return false;
+}
+
+/// Compare \p I and \p J and return the minimum.
+/// Return nullptr in case we couldn't find an answer.
+static const SCEV *getMinFromExprs(const SCEV *I, const SCEV *J,
+ ScalarEvolution *SE) {
+ const SCEV *Diff = SE->getMinusSCEV(J, I);
+ const SCEVConstant *C = dyn_cast<const SCEVConstant>(Diff);
+
+ if (!C)
+ return nullptr;
+ if (C->getValue()->isNegative())
+ return J;
+ return I;
+}
+
+bool RuntimePointerChecking::CheckingPtrGroup::addPointer(unsigned Index) {
+ const SCEV *Start = RtCheck.Pointers[Index].Start;
+ const SCEV *End = RtCheck.Pointers[Index].End;
+
+ // Compare the starts and ends with the known minimum and maximum
+ // of this set. We need to know how we compare against the min/max
+ // of the set in order to be able to emit memchecks.
+ const SCEV *Min0 = getMinFromExprs(Start, Low, RtCheck.SE);
+ if (!Min0)
+ return false;
+
+ const SCEV *Min1 = getMinFromExprs(End, High, RtCheck.SE);
+ if (!Min1)
+ return false;
+
+ // Update the low bound expression if we've found a new min value.
+ if (Min0 == Start)
+ Low = Start;
+
+ // Update the high bound expression if we've found a new max value.
+ if (Min1 != End)
+ High = End;
+
+ Members.push_back(Index);
+ return true;
}
-bool LoopAccessInfo::RuntimePointerCheck::needsChecking(
+void RuntimePointerChecking::groupChecks(
+ MemoryDepChecker::DepCandidates &DepCands, bool UseDependencies) {
+ // We build the groups from dependency candidates equivalence classes
+ // because:
+ // - We know that pointers in the same equivalence class share
+ // the same underlying object and therefore there is a chance
+ // that we can compare pointers
+ // - We wouldn't be able to merge two pointers for which we need
+ // to emit a memcheck. The classes in DepCands are already
+ // conveniently built such that no two pointers in the same
+ // class need checking against each other.
+
+ // We use the following (greedy) algorithm to construct the groups
+ // For every pointer in the equivalence class:
+ // For each existing group:
+ // - if the difference between this pointer and the min/max bounds
+ // of the group is a constant, then make the pointer part of the
+ // group and update the min/max bounds of that group as required.
+
+ CheckingGroups.clear();
+
+ // If we don't have the dependency partitions, construct a new
+ // checking pointer group for each pointer.
+ if (!UseDependencies) {
+ for (unsigned I = 0; I < Pointers.size(); ++I)
+ CheckingGroups.push_back(CheckingPtrGroup(I, *this));
+ return;
+ }
+
+ unsigned TotalComparisons = 0;
+
+ DenseMap<Value *, unsigned> PositionMap;
+ for (unsigned Index = 0; Index < Pointers.size(); ++Index)
+ PositionMap[Pointers[Index].PointerValue] = Index;
+
+ // We need to keep track of what pointers we've already seen so we
+ // don't process them twice.
+ SmallSet<unsigned, 2> Seen;
+
+ // Go through all equivalence classes, get the the "pointer check groups"
+ // and add them to the overall solution. We use the order in which accesses
+ // appear in 'Pointers' to enforce determinism.
+ for (unsigned I = 0; I < Pointers.size(); ++I) {
+ // We've seen this pointer before, and therefore already processed
+ // its equivalence class.
+ if (Seen.count(I))
+ continue;
+
+ MemoryDepChecker::MemAccessInfo Access(Pointers[I].PointerValue,
+ Pointers[I].IsWritePtr);
+
+ SmallVector<CheckingPtrGroup, 2> Groups;
+ auto LeaderI = DepCands.findValue(DepCands.getLeaderValue(Access));
+
+ // Because DepCands is constructed by visiting accesses in the order in
+ // which they appear in alias sets (which is deterministic) and the
+ // iteration order within an equivalence class member is only dependent on
+ // the order in which unions and insertions are performed on the
+ // equivalence class, the iteration order is deterministic.
+ for (auto MI = DepCands.member_begin(LeaderI), ME = DepCands.member_end();
+ MI != ME; ++MI) {
+ unsigned Pointer = PositionMap[MI->getPointer()];
+ bool Merged = false;
+ // Mark this pointer as seen.
+ Seen.insert(Pointer);
+
+ // Go through all the existing sets and see if we can find one
+ // which can include this pointer.
+ for (CheckingPtrGroup &Group : Groups) {
+ // Don't perform more than a certain amount of comparisons.
+ // This should limit the cost of grouping the pointers to something
+ // reasonable. If we do end up hitting this threshold, the algorithm
+ // will create separate groups for all remaining pointers.
+ if (TotalComparisons > MemoryCheckMergeThreshold)
+ break;
+
+ TotalComparisons++;
+
+ if (Group.addPointer(Pointer)) {
+ Merged = true;
+ break;
+ }
+ }
+
+ if (!Merged)
+ // We couldn't add this pointer to any existing set or the threshold
+ // for the number of comparisons has been reached. Create a new group
+ // to hold the current pointer.
+ Groups.push_back(CheckingPtrGroup(Pointer, *this));
+ }
+
+ // We've computed the grouped checks for this partition.
+ // Save the results and continue with the next one.
+ std::copy(Groups.begin(), Groups.end(), std::back_inserter(CheckingGroups));
+ }
+}
+
+bool RuntimePointerChecking::needsChecking(
unsigned I, unsigned J, const SmallVectorImpl<int> *PtrPartition) const {
+ const PointerInfo &PointerI = Pointers[I];
+ const PointerInfo &PointerJ = Pointers[J];
+
// No need to check if two readonly pointers intersect.
- if (!IsWritePtr[I] && !IsWritePtr[J])
+ if (!PointerI.IsWritePtr && !PointerJ.IsWritePtr)
return false;
// Only need to check pointers between two different dependency sets.
- if (DependencySetId[I] == DependencySetId[J])
+ if (PointerI.DependencySetId == PointerJ.DependencySetId)
return false;
// Only need to check pointers in the same alias set.
- if (AliasSetId[I] != AliasSetId[J])
+ if (PointerI.AliasSetId != PointerJ.AliasSetId)
return false;
// If PtrPartition is set omit checks between pointers of the same partition.
@@ -153,45 +307,75 @@ bool LoopAccessInfo::RuntimePointerCheck::needsChecking(
return true;
}
-void LoopAccessInfo::RuntimePointerCheck::print(
+void RuntimePointerChecking::print(
raw_ostream &OS, unsigned Depth,
const SmallVectorImpl<int> *PtrPartition) const {
- unsigned NumPointers = Pointers.size();
- if (NumPointers == 0)
- return;
OS.indent(Depth) << "Run-time memory checks:\n";
+
unsigned N = 0;
- for (unsigned I = 0; I < NumPointers; ++I)
- for (unsigned J = I + 1; J < NumPointers; ++J)
- if (needsChecking(I, J, PtrPartition)) {
- OS.indent(Depth) << N++ << ":\n";
- OS.indent(Depth + 2) << *Pointers[I];
- if (PtrPartition)
- OS << " (Partition: " << (*PtrPartition)[I] << ")";
- OS << "\n";
- OS.indent(Depth + 2) << *Pointers[J];
- if (PtrPartition)
- OS << " (Partition: " << (*PtrPartition)[J] << ")";
- OS << "\n";
+ for (unsigned I = 0; I < CheckingGroups.size(); ++I)
+ for (unsigned J = I + 1; J < CheckingGroups.size(); ++J)
+ if (needsChecking(CheckingGroups[I], CheckingGroups[J], PtrPartition)) {
+ OS.indent(Depth) << "Check " << N++ << ":\n";
+ OS.indent(Depth + 2) << "Comparing group " << I << ":\n";
+
+ for (unsigned K = 0; K < CheckingGroups[I].Members.size(); ++K) {
+ OS.indent(Depth + 2)
+ << *Pointers[CheckingGroups[I].Members[K]].PointerValue << "\n";
+ if (PtrPartition)
+ OS << " (Partition: "
+ << (*PtrPartition)[CheckingGroups[I].Members[K]] << ")"
+ << "\n";
+ }
+
+ OS.indent(Depth + 2) << "Against group " << J << ":\n";
+
+ for (unsigned K = 0; K < CheckingGroups[J].Members.size(); ++K) {
+ OS.indent(Depth + 2)
+ << *Pointers[CheckingGroups[J].Members[K]].PointerValue << "\n";
+ if (PtrPartition)
+ OS << " (Partition: "
+ << (*PtrPartition)[CheckingGroups[J].Members[K]] << ")"
+ << "\n";
+ }
}
+
+ OS.indent(Depth) << "Grouped accesses:\n";
+ for (unsigned I = 0; I < CheckingGroups.size(); ++I) {
+ OS.indent(Depth + 2) << "Group " << I << ":\n";
+ OS.indent(Depth + 4) << "(Low: " << *CheckingGroups[I].Low
+ << " High: " << *CheckingGroups[I].High << ")\n";
+ for (unsigned J = 0; J < CheckingGroups[I].Members.size(); ++J) {
+ OS.indent(Depth + 6) << "Member: "
+ << *Pointers[CheckingGroups[I].Members[J]].Expr
+ << "\n";
+ }
+ }
}
-unsigned LoopAccessInfo::RuntimePointerCheck::getNumberOfChecks(
+unsigned RuntimePointerChecking::getNumberOfChecks(
const SmallVectorImpl<int> *PtrPartition) const {
- unsigned NumPointers = Pointers.size();
+
+ unsigned NumPartitions = CheckingGroups.size();
unsigned CheckCount = 0;
- for (unsigned I = 0; I < NumPointers; ++I)
- for (unsigned J = I + 1; J < NumPointers; ++J)
- if (needsChecking(I, J, PtrPartition))
+ for (unsigned I = 0; I < NumPartitions; ++I)
+ for (unsigned J = I + 1; J < NumPartitions; ++J)
+ if (needsChecking(CheckingGroups[I], CheckingGroups[J], PtrPartition))
CheckCount++;
return CheckCount;
}
-bool LoopAccessInfo::RuntimePointerCheck::needsAnyChecking(
+bool RuntimePointerChecking::needsAnyChecking(
const SmallVectorImpl<int> *PtrPartition) const {
- return getNumberOfChecks(PtrPartition) != 0;
+ unsigned NumPointers = Pointers.size();
+
+ for (unsigned I = 0; I < NumPointers; ++I)
+ for (unsigned J = I + 1; J < NumPointers; ++J)
+ if (needsChecking(I, J, PtrPartition))
+ return true;
+ return false;
}
namespace {
@@ -207,7 +391,8 @@ public:
AccessAnalysis(const DataLayout &Dl, AliasAnalysis *AA, LoopInfo *LI,
MemoryDepChecker::DepCandidates &DA)
- : DL(Dl), AST(*AA), LI(LI), DepCands(DA), IsRTCheckNeeded(false) {}
+ : DL(Dl), AST(*AA), LI(LI), DepCands(DA),
+ IsRTCheckAnalysisNeeded(false) {}
/// \brief Register a load and whether it is only read from.
void addLoad(MemoryLocation &Loc, bool IsReadOnly) {
@@ -226,11 +411,12 @@ public:
}
/// \brief Check whether we can check the pointers at runtime for
- /// non-intersection. Returns true when we have 0 pointers
- /// (a check on 0 pointers for non-intersection will always return true).
- bool canCheckPtrAtRT(LoopAccessInfo::RuntimePointerCheck &RtCheck,
- bool &NeedRTCheck, ScalarEvolution *SE, Loop *TheLoop,
- const ValueToValueMap &Strides,
+ /// non-intersection.
+ ///
+ /// Returns true if we need no check or if we do and we can generate them
+ /// (i.e. the pointers have computable bounds).
+ bool canCheckPtrAtRT(RuntimePointerChecking &RtCheck, ScalarEvolution *SE,
+ Loop *TheLoop, const ValueToValueMap &Strides,
bool ShouldCheckStride = false);
/// \brief Goes over all memory accesses, checks whether a RT check is needed
@@ -239,8 +425,11 @@ public:
processMemAccesses();
}
- bool isRTCheckNeeded() { return IsRTCheckNeeded; }
-
+ /// \brief Initial processing of memory accesses determined that we need to
+ /// perform dependency checking.
+ ///
+ /// Note that this can later be cleared if we retry memcheck analysis without
+ /// dependency checking (i.e. ShouldRetryWithRuntimeCheck).
bool isDependencyCheckNeeded() { return !CheckDeps.empty(); }
/// We decided that no dependence analysis would be used. Reset the state.
@@ -255,7 +444,7 @@ private:
typedef SetVector<MemAccessInfo> PtrAccessSet;
/// \brief Go over all memory access and check whether runtime pointer checks
- /// are needed /// and build sets of dependency check candidates.
+ /// are needed and build sets of dependency check candidates.
void processMemAccesses();
/// Set of all accesses.
@@ -280,7 +469,14 @@ private:
/// dependence check.
MemoryDepChecker::DepCandidates &DepCands;
- bool IsRTCheckNeeded;
+ /// \brief Initial processing of memory accesses determined that we may need
+ /// to add memchecks. Perform the analysis to determine the necessary checks.
+ ///
+ /// Note that, this is different from isDependencyCheckNeeded. When we retry
+ /// memcheck analysis without dependency checking
+ /// (i.e. ShouldRetryWithRuntimeCheck), isDependencyCheckNeeded is cleared
+ /// while this remains set if we have potentially dependent accesses.
+ bool IsRTCheckAnalysisNeeded;
};
} // end anonymous namespace
@@ -296,16 +492,16 @@ static bool hasComputableBounds(ScalarEvolution *SE,
return AR->isAffine();
}
-bool AccessAnalysis::canCheckPtrAtRT(
- LoopAccessInfo::RuntimePointerCheck &RtCheck, bool &NeedRTCheck,
- ScalarEvolution *SE, Loop *TheLoop, const ValueToValueMap &StridesMap,
- bool ShouldCheckStride) {
+bool AccessAnalysis::canCheckPtrAtRT(RuntimePointerChecking &RtCheck,
+ ScalarEvolution *SE, Loop *TheLoop,
+ const ValueToValueMap &StridesMap,
+ bool ShouldCheckStride) {
// Find pointers with computable bounds. We are going to use this information
// to place a runtime bound check.
bool CanDoRT = true;
- NeedRTCheck = false;
- if (!IsRTCheckNeeded) return true;
+ bool NeedRTCheck = false;
+ if (!IsRTCheckAnalysisNeeded) return true;
bool IsDepCheckNeeded = isDependencyCheckNeeded();
@@ -313,6 +509,9 @@ bool AccessAnalysis::canCheckPtrAtRT(
// Accesses between different groups doesn't need to be checked.
unsigned ASId = 1;
for (auto &AS : AST) {
+ int NumReadPtrChecks = 0;
+ int NumWritePtrChecks = 0;
+
// We assign consecutive id to access from different dependence sets.
// Accesses within the same set don't need a runtime check.
unsigned RunningDepId = 1;
@@ -323,6 +522,11 @@ bool AccessAnalysis::canCheckPtrAtRT(
bool IsWrite = Accesses.count(MemAccessInfo(Ptr, true));
MemAccessInfo Access(Ptr, IsWrite);
+ if (IsWrite)
+ ++NumWritePtrChecks;
+ else
+ ++NumReadPtrChecks;
+
if (hasComputableBounds(SE, StridesMap, Ptr) &&
// When we run after a failing dependency check we have to make sure
// we don't have wrapping pointers.
@@ -341,7 +545,7 @@ bool AccessAnalysis::canCheckPtrAtRT(
// Each access has its own dependence set.
DepId = RunningDepId++;
- RtCheck.insert(SE, TheLoop, Ptr, IsWrite, DepId, ASId, StridesMap);
+ RtCheck.insert(TheLoop, Ptr, IsWrite, DepId, ASId, StridesMap);
DEBUG(dbgs() << "LAA: Found a runtime check ptr:" << *Ptr << '\n');
} else {
@@ -350,15 +554,21 @@ bool AccessAnalysis::canCheckPtrAtRT(
}
}
+ // If we have at least two writes or one write and a read then we need to
+ // check them. But there is no need to checks if there is only one
+ // dependence set for this alias set.
+ //
+ // Note that this function computes CanDoRT and NeedRTCheck independently.
+ // For example CanDoRT=false, NeedRTCheck=false means that we have a pointer
+ // for which we couldn't find the bounds but we don't actually need to emit
+ // any checks so it does not matter.
+ if (!(IsDepCheckNeeded && CanDoRT && RunningDepId == 2))
+ NeedRTCheck |= (NumWritePtrChecks >= 2 || (NumReadPtrChecks >= 1 &&
+ NumWritePtrChecks >= 1));
+
++ASId;
}
- // We need a runtime check if there are any accesses that need checking.
- // However, some accesses cannot be checked (for example because we
- // can't determine their bounds). In these cases we would need a check
- // but wouldn't be able to add it.
- NeedRTCheck = !CanDoRT || RtCheck.needsAnyChecking(nullptr);
-
// If the pointers that we would use for the bounds comparison have different
// address spaces, assume the values aren't directly comparable, so we can't
// use them for the runtime check. We also have to assume they could
@@ -368,14 +578,15 @@ bool AccessAnalysis::canCheckPtrAtRT(
for (unsigned i = 0; i < NumPointers; ++i) {
for (unsigned j = i + 1; j < NumPointers; ++j) {
// Only need to check pointers between two different dependency sets.
- if (RtCheck.DependencySetId[i] == RtCheck.DependencySetId[j])
+ if (RtCheck.Pointers[i].DependencySetId ==
+ RtCheck.Pointers[j].DependencySetId)
continue;
// Only need to check pointers in the same alias set.
- if (RtCheck.AliasSetId[i] != RtCheck.AliasSetId[j])
+ if (RtCheck.Pointers[i].AliasSetId != RtCheck.Pointers[j].AliasSetId)
continue;
- Value *PtrI = RtCheck.Pointers[i];
- Value *PtrJ = RtCheck.Pointers[j];
+ Value *PtrI = RtCheck.Pointers[i].PointerValue;
+ Value *PtrJ = RtCheck.Pointers[j].PointerValue;
unsigned ASi = PtrI->getType()->getPointerAddressSpace();
unsigned ASj = PtrJ->getType()->getPointerAddressSpace();
@@ -387,7 +598,18 @@ bool AccessAnalysis::canCheckPtrAtRT(
}
}
- return CanDoRT;
+ if (NeedRTCheck && CanDoRT)
+ RtCheck.groupChecks(DepCands, IsDepCheckNeeded);
+
+ DEBUG(dbgs() << "LAA: We need to do " << RtCheck.getNumberOfChecks(nullptr)
+ << " pointer comparisons.\n");
+
+ RtCheck.Need = NeedRTCheck;
+
+ bool CanDoRTIfNeeded = !NeedRTCheck || CanDoRT;
+ if (!CanDoRTIfNeeded)
+ RtCheck.reset();
+ return CanDoRTIfNeeded;
}
void AccessAnalysis::processMemAccesses() {
@@ -470,7 +692,7 @@ void AccessAnalysis::processMemAccesses() {
// catch "a[i] = a[i] + " without having to do a dependence check).
if ((IsWrite || IsReadOnlyPtr) && SetHasWrite) {
CheckDeps.insert(Access);
- IsRTCheckNeeded = true;
+ IsRTCheckAnalysisNeeded = true;
}
if (IsWrite)
@@ -600,7 +822,7 @@ int llvm::isStridedPtr(ScalarEvolution *SE, Value *Ptr, const Loop *Lp,
// Check the step is constant.
const SCEV *Step = AR->getStepRecurrence(*SE);
- // Calculate the pointer stride and check if it is consecutive.
+ // Calculate the pointer stride and check if it is constant.
const SCEVConstant *C = dyn_cast<SCEVConstant>(Step);
if (!C) {
DEBUG(dbgs() << "LAA: Bad stride - Not a constant strided " << *Ptr <<
@@ -805,11 +1027,11 @@ MemoryDepChecker::isDependent(const MemAccessInfo &A, unsigned AIdx,
DEBUG(dbgs() << "LAA: Distance for " << *InstMap[AIdx] << " to "
<< *InstMap[BIdx] << ": " << *Dist << "\n");
- // Need consecutive accesses. We don't want to vectorize
+ // Need accesses with constant stride. We don't want to vectorize
// "A[B[i]] += ..." and similar code or pointer arithmetic that could wrap in
// the address space.
if (!StrideAPtr || !StrideBPtr || StrideAPtr != StrideBPtr){
- DEBUG(dbgs() << "Non-consecutive pointer access\n");
+ DEBUG(dbgs() << "Pointer access with non-constant stride\n");
return Dependence::Unknown;
}
@@ -859,8 +1081,10 @@ MemoryDepChecker::isDependent(const MemAccessInfo &A, unsigned AIdx,
unsigned Stride = std::abs(StrideAPtr);
if (Stride > 1 &&
- areStridedAccessesIndependent(Distance, Stride, TypeByteSize))
+ areStridedAccessesIndependent(Distance, Stride, TypeByteSize)) {
+ DEBUG(dbgs() << "LAA: Strided accesses are independent\n");
return Dependence::NoDep;
+ }
// Bail out early if passed-in parameters make vectorization not feasible.
unsigned ForcedFactor = (VectorizerParams::VectorizationFactor ?
@@ -1098,8 +1322,8 @@ void LoopAccessInfo::analyzeLoop(const ValueToValueMap &Strides) {
unsigned NumReads = 0;
unsigned NumReadWrites = 0;
- PtrRtCheck.Pointers.clear();
- PtrRtCheck.Need = false;
+ PtrRtChecking.Pointers.clear();
+ PtrRtChecking.Need = false;
const bool IsAnnotatedParallel = TheLoop->isAnnotatedParallel();
@@ -1258,28 +1482,17 @@ void LoopAccessInfo::analyzeLoop(const ValueToValueMap &Strides) {
// Find pointers with computable bounds. We are going to use this information
// to place a runtime bound check.
- bool NeedRTCheck;
- bool CanDoRT = Accesses.canCheckPtrAtRT(PtrRtCheck,
- NeedRTCheck, SE,
- TheLoop, Strides);
-
- DEBUG(dbgs() << "LAA: We need to do "
- << PtrRtCheck.getNumberOfChecks(nullptr)
- << " pointer comparisons.\n");
-
- // Check that we found the bounds for the pointer.
- if (CanDoRT)
- DEBUG(dbgs() << "LAA: We can perform a memory runtime check if needed.\n");
- else if (NeedRTCheck) {
+ bool CanDoRTIfNeeded =
+ Accesses.canCheckPtrAtRT(PtrRtChecking, SE, TheLoop, Strides);
+ if (!CanDoRTIfNeeded) {
emitAnalysis(LoopAccessReport() << "cannot identify array bounds");
- DEBUG(dbgs() << "LAA: We can't vectorize because we can't find " <<
- "the array bounds.\n");
- PtrRtCheck.reset();
+ DEBUG(dbgs() << "LAA: We can't vectorize because we can't find "
+ << "the array bounds.\n");
CanVecMem = false;
return;
}
- PtrRtCheck.Need = NeedRTCheck;
+ DEBUG(dbgs() << "LAA: We can perform a memory runtime check if needed.\n");
CanVecMem = true;
if (Accesses.isDependencyCheckNeeded()) {
@@ -1290,23 +1503,21 @@ void LoopAccessInfo::analyzeLoop(const ValueToValueMap &Strides) {
if (!CanVecMem && DepChecker.shouldRetryWithRuntimeCheck()) {
DEBUG(dbgs() << "LAA: Retrying with memory checks\n");
- NeedRTCheck = true;
// Clear the dependency checks. We assume they are not needed.
Accesses.resetDepChecks(DepChecker);
- PtrRtCheck.reset();
- PtrRtCheck.Need = true;
+ PtrRtChecking.reset();
+ PtrRtChecking.Need = true;
- CanDoRT = Accesses.canCheckPtrAtRT(PtrRtCheck, NeedRTCheck, SE,
- TheLoop, Strides, true);
+ CanDoRTIfNeeded =
+ Accesses.canCheckPtrAtRT(PtrRtChecking, SE, TheLoop, Strides, true);
// Check that we found the bounds for the pointer.
- if (NeedRTCheck && !CanDoRT) {
+ if (!CanDoRTIfNeeded) {
emitAnalysis(LoopAccessReport()
<< "cannot check memory dependencies at runtime");
DEBUG(dbgs() << "LAA: Can't vectorize with memory checks\n");
- PtrRtCheck.reset();
CanVecMem = false;
return;
}
@@ -1317,8 +1528,8 @@ void LoopAccessInfo::analyzeLoop(const ValueToValueMap &Strides) {
if (CanVecMem)
DEBUG(dbgs() << "LAA: No unsafe dependent memory operations in loop. We"
- << (NeedRTCheck ? "" : " don't")
- << " need a runtime memory check.\n");
+ << (PtrRtChecking.Need ? "" : " don't")
+ << " need runtime memory checks.\n");
else {
emitAnalysis(LoopAccessReport() <<
"unsafe dependent memory operations in loop");
@@ -1357,35 +1568,38 @@ static Instruction *getFirstInst(Instruction *FirstInst, Value *V,
std::pair<Instruction *, Instruction *> LoopAccessInfo::addRuntimeCheck(
Instruction *Loc, const SmallVectorImpl<int> *PtrPartition) const {
- if (!PtrRtCheck.Need)
+ if (!PtrRtChecking.Need)
return std::make_pair(nullptr, nullptr);
- unsigned NumPointers = PtrRtCheck.Pointers.size();
- SmallVector<TrackingVH<Value> , 2> Starts;
- SmallVector<TrackingVH<Value> , 2> Ends;
+ SmallVector<TrackingVH<Value>, 2> Starts;
+ SmallVector<TrackingVH<Value>, 2> Ends;
LLVMContext &Ctx = Loc->getContext();
SCEVExpander Exp(*SE, DL, "induction");
Instruction *FirstInst = nullptr;
- for (unsigned i = 0; i < NumPointers; ++i) {
- Value *Ptr = PtrRtCheck.Pointers[i];
+ for (unsigned i = 0; i < PtrRtChecking.CheckingGroups.size(); ++i) {
+ const RuntimePointerChecking::CheckingPtrGroup &CG =
+ PtrRtChecking.CheckingGroups[i];
+ Value *Ptr = PtrRtChecking.Pointers[CG.Members[0]].PointerValue;
const SCEV *Sc = SE->getSCEV(Ptr);
if (SE->isLoopInvariant(Sc, TheLoop)) {
- DEBUG(dbgs() << "LAA: Adding RT check for a loop invariant ptr:" <<
- *Ptr <<"\n");
+ DEBUG(dbgs() << "LAA: Adding RT check for a loop invariant ptr:" << *Ptr
+ << "\n");
Starts.push_back(Ptr);
Ends.push_back(Ptr);
} else {
- DEBUG(dbgs() << "LAA: Adding RT check for range:" << *Ptr << '\n');
unsigned AS = Ptr->getType()->getPointerAddressSpace();
// Use this type for pointer arithmetic.
Type *PtrArithTy = Type::getInt8PtrTy(Ctx, AS);
+ Value *Start = nullptr, *End = nullptr;
- Value *Start = Exp.expandCodeFor(PtrRtCheck.Starts[i], PtrArithTy, Loc);
- Value *End = Exp.expandCodeFor(PtrRtCheck.Ends[i], PtrArithTy, Loc);
+ DEBUG(dbgs() << "LAA: Adding RT check for range:\n");
+ Start = Exp.expandCodeFor(CG.Low, PtrArithTy, Loc);
+ End = Exp.expandCodeFor(CG.High, PtrArithTy, Loc);
+ DEBUG(dbgs() << "Start: " << *CG.Low << " End: " << *CG.High << "\n");
Starts.push_back(Start);
Ends.push_back(End);
}
@@ -1394,9 +1608,14 @@ std::pair<Instruction *, Instruction *> LoopAccessInfo::addRuntimeCheck(
IRBuilder<> ChkBuilder(Loc);
// Our instructions might fold to a constant.
Value *MemoryRuntimeCheck = nullptr;
- for (unsigned i = 0; i < NumPointers; ++i) {
- for (unsigned j = i+1; j < NumPointers; ++j) {
- if (!PtrRtCheck.needsChecking(i, j, PtrPartition))
+ for (unsigned i = 0; i < PtrRtChecking.CheckingGroups.size(); ++i) {
+ for (unsigned j = i + 1; j < PtrRtChecking.CheckingGroups.size(); ++j) {
+ const RuntimePointerChecking::CheckingPtrGroup &CGI =
+ PtrRtChecking.CheckingGroups[i];
+ const RuntimePointerChecking::CheckingPtrGroup &CGJ =
+ PtrRtChecking.CheckingGroups[j];
+
+ if (!PtrRtChecking.needsChecking(CGI, CGJ, PtrPartition))
continue;
unsigned AS0 = Starts[i]->getType()->getPointerAddressSpace();
@@ -1447,7 +1666,7 @@ LoopAccessInfo::LoopAccessInfo(Loop *L, ScalarEvolution *SE,
const TargetLibraryInfo *TLI, AliasAnalysis *AA,
DominatorTree *DT, LoopInfo *LI,
const ValueToValueMap &Strides)
- : DepChecker(SE, L), TheLoop(L), SE(SE), DL(DL),
+ : PtrRtChecking(SE), DepChecker(SE, L), TheLoop(L), SE(SE), DL(DL),
TLI(TLI), AA(AA), DT(DT), LI(LI), NumLoads(0), NumStores(0),
MaxSafeDepDistBytes(-1U), CanVecMem(false),
StoreToLoopInvariantAddress(false) {
@@ -1457,7 +1676,7 @@ LoopAccessInfo::LoopAccessInfo(Loop *L, ScalarEvolution *SE,
void LoopAccessInfo::print(raw_ostream &OS, unsigned Depth) const {
if (CanVecMem) {
- if (PtrRtCheck.Need)
+ if (PtrRtChecking.Need)
OS.indent(Depth) << "Memory dependences are safe with run-time checks\n";
else
OS.indent(Depth) << "Memory dependences are safe\n";
@@ -1476,7 +1695,7 @@ void LoopAccessInfo::print(raw_ostream &OS, unsigned Depth) const {
OS.indent(Depth) << "Too many interesting dependences, not recorded\n";
// List the pair of accesses need run-time checks to prove independence.
- PtrRtCheck.print(OS, Depth);
+ PtrRtChecking.print(OS, Depth);
OS << "\n";
OS.indent(Depth) << "Store to invariant address was "
diff --git a/lib/Analysis/NoAliasAnalysis.cpp b/lib/Analysis/NoAliasAnalysis.cpp
index 7617622b9ab6..322a9a80de4c 100644
--- a/lib/Analysis/NoAliasAnalysis.cpp
+++ b/lib/Analysis/NoAliasAnalysis.cpp
@@ -72,7 +72,6 @@ namespace {
}
void deleteValue(Value *V) override {}
- void copyValue(Value *From, Value *To) override {}
void addEscapingUse(Use &U) override {}
/// getAdjustedAnalysisPointer - This method is used when a pass implements
diff --git a/lib/Analysis/TargetTransformInfo.cpp b/lib/Analysis/TargetTransformInfo.cpp
index 520d1e5ef87d..7d1c3fbef68a 100644
--- a/lib/Analysis/TargetTransformInfo.cpp
+++ b/lib/Analysis/TargetTransformInfo.cpp
@@ -28,12 +28,12 @@ namespace {
///
/// This is used when no target specific information is available.
struct NoTTIImpl : TargetTransformInfoImplCRTPBase<NoTTIImpl> {
- explicit NoTTIImpl(const DataLayout *DL)
+ explicit NoTTIImpl(const DataLayout &DL)
: TargetTransformInfoImplCRTPBase<NoTTIImpl>(DL) {}
};
}
-TargetTransformInfo::TargetTransformInfo(const DataLayout *DL)
+TargetTransformInfo::TargetTransformInfo(const DataLayout &DL)
: TTIImpl(new Model<NoTTIImpl>(NoTTIImpl(DL))) {}
TargetTransformInfo::~TargetTransformInfo() {}
@@ -304,7 +304,7 @@ TargetIRAnalysis::Result TargetIRAnalysis::run(Function &F) {
char TargetIRAnalysis::PassID;
TargetIRAnalysis::Result TargetIRAnalysis::getDefaultTTI(Function &F) {
- return Result(&F.getParent()->getDataLayout());
+ return Result(F.getParent()->getDataLayout());
}
// Register the basic pass.
diff --git a/lib/Analysis/ValueTracking.cpp b/lib/Analysis/ValueTracking.cpp
index c45005f343d3..fa0d7798cae9 100644
--- a/lib/Analysis/ValueTracking.cpp
+++ b/lib/Analysis/ValueTracking.cpp
@@ -1464,7 +1464,7 @@ void computeKnownBits(Value *V, APInt &KnownZero, APInt &KnownOne,
// If the object is defined in the current Module, we'll be giving
// it the preferred alignment. Otherwise, we have to assume that it
// may only have the minimum ABI alignment.
- if (!GVar->isDeclaration() && !GVar->isWeakForLinker())
+ if (GVar->isStrongDefinitionForLinker())
Align = DL.getPreferredAlignment(GVar);
else
Align = DL.getABITypeAlignment(ObjectType);
diff --git a/lib/Analysis/VectorUtils.cpp b/lib/Analysis/VectorUtils.cpp
index 96fddd103cc5..67f68dc8391e 100644
--- a/lib/Analysis/VectorUtils.cpp
+++ b/lib/Analysis/VectorUtils.cpp
@@ -11,7 +11,13 @@
//
//===----------------------------------------------------------------------===//
+#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/Analysis/ScalarEvolutionExpressions.h"
+#include "llvm/Analysis/ScalarEvolution.h"
#include "llvm/Analysis/VectorUtils.h"
+#include "llvm/IR/GetElementPtrTypeIterator.h"
+#include "llvm/IR/PatternMatch.h"
+#include "llvm/IR/Value.h"
/// \brief Identify if the intrinsic is trivially vectorizable.
/// This method returns true if the intrinsic's argument types are all
@@ -211,3 +217,195 @@ llvm::Intrinsic::ID llvm::getIntrinsicIDForCall(CallInst *CI,
return Intrinsic::not_intrinsic;
}
+
+/// \brief Find the operand of the GEP that should be checked for consecutive
+/// stores. This ignores trailing indices that have no effect on the final
+/// pointer.
+unsigned llvm::getGEPInductionOperand(const GetElementPtrInst *Gep) {
+ const DataLayout &DL = Gep->getModule()->getDataLayout();
+ unsigned LastOperand = Gep->getNumOperands() - 1;
+ unsigned GEPAllocSize = DL.getTypeAllocSize(
+ cast<PointerType>(Gep->getType()->getScalarType())->getElementType());
+
+ // Walk backwards and try to peel off zeros.
+ while (LastOperand > 1 &&
+ match(Gep->getOperand(LastOperand), llvm::PatternMatch::m_Zero())) {
+ // Find the type we're currently indexing into.
+ gep_type_iterator GEPTI = gep_type_begin(Gep);
+ std::advance(GEPTI, LastOperand - 1);
+
+ // If it's a type with the same allocation size as the result of the GEP we
+ // can peel off the zero index.
+ if (DL.getTypeAllocSize(*GEPTI) != GEPAllocSize)
+ break;
+ --LastOperand;
+ }
+
+ return LastOperand;
+}
+
+/// \brief If the argument is a GEP, then returns the operand identified by
+/// getGEPInductionOperand. However, if there is some other non-loop-invariant
+/// operand, it returns that instead.
+llvm::Value *llvm::stripGetElementPtr(llvm::Value *Ptr, ScalarEvolution *SE,
+ Loop *Lp) {
+ GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(Ptr);
+ if (!GEP)
+ return Ptr;
+
+ unsigned InductionOperand = getGEPInductionOperand(GEP);
+
+ // Check that all of the gep indices are uniform except for our induction
+ // operand.
+ for (unsigned i = 0, e = GEP->getNumOperands(); i != e; ++i)
+ if (i != InductionOperand &&
+ !SE->isLoopInvariant(SE->getSCEV(GEP->getOperand(i)), Lp))
+ return Ptr;
+ return GEP->getOperand(InductionOperand);
+}
+
+/// \brief If a value has only one user that is a CastInst, return it.
+llvm::Value *llvm::getUniqueCastUse(llvm::Value *Ptr, Loop *Lp, Type *Ty) {
+ llvm::Value *UniqueCast = nullptr;
+ for (User *U : Ptr->users()) {
+ CastInst *CI = dyn_cast<CastInst>(U);
+ if (CI && CI->getType() == Ty) {
+ if (!UniqueCast)
+ UniqueCast = CI;
+ else
+ return nullptr;
+ }
+ }
+ return UniqueCast;
+}
+
+/// \brief Get the stride of a pointer access in a loop. Looks for symbolic
+/// strides "a[i*stride]". Returns the symbolic stride, or null otherwise.
+llvm::Value *llvm::getStrideFromPointer(llvm::Value *Ptr, ScalarEvolution *SE,
+ Loop *Lp) {
+ const PointerType *PtrTy = dyn_cast<PointerType>(Ptr->getType());
+ if (!PtrTy || PtrTy->isAggregateType())
+ return nullptr;
+
+ // Try to remove a gep instruction to make the pointer (actually index at this
+ // point) easier analyzable. If OrigPtr is equal to Ptr we are analzying the
+ // pointer, otherwise, we are analyzing the index.
+ llvm::Value *OrigPtr = Ptr;
+
+ // The size of the pointer access.
+ int64_t PtrAccessSize = 1;
+
+ Ptr = stripGetElementPtr(Ptr, SE, Lp);
+ const SCEV *V = SE->getSCEV(Ptr);
+
+ if (Ptr != OrigPtr)
+ // Strip off casts.
+ while (const SCEVCastExpr *C = dyn_cast<SCEVCastExpr>(V))
+ V = C->getOperand();
+
+ const SCEVAddRecExpr *S = dyn_cast<SCEVAddRecExpr>(V);
+ if (!S)
+ return nullptr;
+
+ V = S->getStepRecurrence(*SE);
+ if (!V)
+ return nullptr;
+
+ // Strip off the size of access multiplication if we are still analyzing the
+ // pointer.
+ if (OrigPtr == Ptr) {
+ const DataLayout &DL = Lp->getHeader()->getModule()->getDataLayout();
+ DL.getTypeAllocSize(PtrTy->getElementType());
+ if (const SCEVMulExpr *M = dyn_cast<SCEVMulExpr>(V)) {
+ if (M->getOperand(0)->getSCEVType() != scConstant)
+ return nullptr;
+
+ const APInt &APStepVal =
+ cast<SCEVConstant>(M->getOperand(0))->getValue()->getValue();
+
+ // Huge step value - give up.
+ if (APStepVal.getBitWidth() > 64)
+ return nullptr;
+
+ int64_t StepVal = APStepVal.getSExtValue();
+ if (PtrAccessSize != StepVal)
+ return nullptr;
+ V = M->getOperand(1);
+ }
+ }
+
+ // Strip off casts.
+ Type *StripedOffRecurrenceCast = nullptr;
+ if (const SCEVCastExpr *C = dyn_cast<SCEVCastExpr>(V)) {
+ StripedOffRecurrenceCast = C->getType();
+ V = C->getOperand();
+ }
+
+ // Look for the loop invariant symbolic value.
+ const SCEVUnknown *U = dyn_cast<SCEVUnknown>(V);
+ if (!U)
+ return nullptr;
+
+ llvm::Value *Stride = U->getValue();
+ if (!Lp->isLoopInvariant(Stride))
+ return nullptr;
+
+ // If we have stripped off the recurrence cast we have to make sure that we
+ // return the value that is used in this loop so that we can replace it later.
+ if (StripedOffRecurrenceCast)
+ Stride = getUniqueCastUse(Stride, Lp, StripedOffRecurrenceCast);
+
+ return Stride;
+}
+
+/// \brief Given a vector and an element number, see if the scalar value is
+/// already around as a register, for example if it were inserted then extracted
+/// from the vector.
+llvm::Value *llvm::findScalarElement(llvm::Value *V, unsigned EltNo) {
+ assert(V->getType()->isVectorTy() && "Not looking at a vector?");
+ VectorType *VTy = cast<VectorType>(V->getType());
+ unsigned Width = VTy->getNumElements();
+ if (EltNo >= Width) // Out of range access.
+ return UndefValue::get(VTy->getElementType());
+
+ if (Constant *C = dyn_cast<Constant>(V))
+ return C->getAggregateElement(EltNo);
+
+ if (InsertElementInst *III = dyn_cast<InsertElementInst>(V)) {
+ // If this is an insert to a variable element, we don't know what it is.
+ if (!isa<ConstantInt>(III->getOperand(2)))
+ return nullptr;
+ unsigned IIElt = cast<ConstantInt>(III->getOperand(2))->getZExtValue();
+
+ // If this is an insert to the element we are looking for, return the
+ // inserted value.
+ if (EltNo == IIElt)
+ return III->getOperand(1);
+
+ // Otherwise, the insertelement doesn't modify the value, recurse on its
+ // vector input.
+ return findScalarElement(III->getOperand(0), EltNo);
+ }
+
+ if (ShuffleVectorInst *SVI = dyn_cast<ShuffleVectorInst>(V)) {
+ unsigned LHSWidth = SVI->getOperand(0)->getType()->getVectorNumElements();
+ int InEl = SVI->getMaskValue(EltNo);
+ if (InEl < 0)
+ return UndefValue::get(VTy->getElementType());
+ if (InEl < (int)LHSWidth)
+ return findScalarElement(SVI->getOperand(0), InEl);
+ return findScalarElement(SVI->getOperand(1), InEl - LHSWidth);
+ }
+
+ // Extract a value from a vector add operation with a constant zero.
+ Value *Val = nullptr; Constant *Con = nullptr;
+ if (match(V,
+ llvm::PatternMatch::m_Add(llvm::PatternMatch::m_Value(Val),
+ llvm::PatternMatch::m_Constant(Con)))) {
+ if (Con->getAggregateElement(EltNo)->isNullValue())
+ return findScalarElement(Val, EltNo);
+ }
+
+ // Otherwise, we don't know.
+ return nullptr;
+}
diff --git a/lib/AsmParser/LLLexer.cpp b/lib/AsmParser/LLLexer.cpp
index 88f359d4fd5c..5c4bab734b2b 100644
--- a/lib/AsmParser/LLLexer.cpp
+++ b/lib/AsmParser/LLLexer.cpp
@@ -593,6 +593,7 @@ lltok::Kind LLLexer::LexIdentifier() {
KEYWORD(attributes);
KEYWORD(alwaysinline);
+ KEYWORD(argmemonly);
KEYWORD(builtin);
KEYWORD(byval);
KEYWORD(inalloca);
diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp
index b3c7fa087d40..1c6e7bd18d0e 100644
--- a/lib/AsmParser/LLParser.cpp
+++ b/lib/AsmParser/LLParser.cpp
@@ -946,35 +946,42 @@ bool LLParser::ParseFnAttributeValuePairs(AttrBuilder &B,
B.addStackAlignmentAttr(Alignment);
continue;
}
- case lltok::kw_alwaysinline: B.addAttribute(Attribute::AlwaysInline); break;
- case lltok::kw_builtin: B.addAttribute(Attribute::Builtin); break;
- case lltok::kw_cold: B.addAttribute(Attribute::Cold); break;
- case lltok::kw_convergent: B.addAttribute(Attribute::Convergent); break;
- case lltok::kw_inlinehint: B.addAttribute(Attribute::InlineHint); break;
- case lltok::kw_jumptable: B.addAttribute(Attribute::JumpTable); break;
- case lltok::kw_minsize: B.addAttribute(Attribute::MinSize); break;
- case lltok::kw_naked: B.addAttribute(Attribute::Naked); break;
- case lltok::kw_nobuiltin: B.addAttribute(Attribute::NoBuiltin); break;
- case lltok::kw_noduplicate: B.addAttribute(Attribute::NoDuplicate); break;
- case lltok::kw_noimplicitfloat: B.addAttribute(Attribute::NoImplicitFloat); break;
- case lltok::kw_noinline: B.addAttribute(Attribute::NoInline); break;
- case lltok::kw_nonlazybind: B.addAttribute(Attribute::NonLazyBind); break;
- case lltok::kw_noredzone: B.addAttribute(Attribute::NoRedZone); break;
- case lltok::kw_noreturn: B.addAttribute(Attribute::NoReturn); break;
- case lltok::kw_nounwind: B.addAttribute(Attribute::NoUnwind); break;
- case lltok::kw_optnone: B.addAttribute(Attribute::OptimizeNone); break;
- case lltok::kw_optsize: B.addAttribute(Attribute::OptimizeForSize); break;
- case lltok::kw_readnone: B.addAttribute(Attribute::ReadNone); break;
- case lltok::kw_readonly: B.addAttribute(Attribute::ReadOnly); break;
- case lltok::kw_returns_twice: B.addAttribute(Attribute::ReturnsTwice); break;
- case lltok::kw_ssp: B.addAttribute(Attribute::StackProtect); break;
- case lltok::kw_sspreq: B.addAttribute(Attribute::StackProtectReq); break;
- case lltok::kw_sspstrong: B.addAttribute(Attribute::StackProtectStrong); break;
- case lltok::kw_safestack: B.addAttribute(Attribute::SafeStack); break;
- case lltok::kw_sanitize_address: B.addAttribute(Attribute::SanitizeAddress); break;
- case lltok::kw_sanitize_thread: B.addAttribute(Attribute::SanitizeThread); break;
- case lltok::kw_sanitize_memory: B.addAttribute(Attribute::SanitizeMemory); break;
- case lltok::kw_uwtable: B.addAttribute(Attribute::UWTable); break;
+ case lltok::kw_alwaysinline: B.addAttribute(Attribute::AlwaysInline); break;
+ case lltok::kw_argmemonly: B.addAttribute(Attribute::ArgMemOnly); break;
+ case lltok::kw_builtin: B.addAttribute(Attribute::Builtin); break;
+ case lltok::kw_cold: B.addAttribute(Attribute::Cold); break;
+ case lltok::kw_convergent: B.addAttribute(Attribute::Convergent); break;
+ case lltok::kw_inlinehint: B.addAttribute(Attribute::InlineHint); break;
+ case lltok::kw_jumptable: B.addAttribute(Attribute::JumpTable); break;
+ case lltok::kw_minsize: B.addAttribute(Attribute::MinSize); break;
+ case lltok::kw_naked: B.addAttribute(Attribute::Naked); break;
+ case lltok::kw_nobuiltin: B.addAttribute(Attribute::NoBuiltin); break;
+ case lltok::kw_noduplicate: B.addAttribute(Attribute::NoDuplicate); break;
+ case lltok::kw_noimplicitfloat:
+ B.addAttribute(Attribute::NoImplicitFloat); break;
+ case lltok::kw_noinline: B.addAttribute(Attribute::NoInline); break;
+ case lltok::kw_nonlazybind: B.addAttribute(Attribute::NonLazyBind); break;
+ case lltok::kw_noredzone: B.addAttribute(Attribute::NoRedZone); break;
+ case lltok::kw_noreturn: B.addAttribute(Attribute::NoReturn); break;
+ case lltok::kw_nounwind: B.addAttribute(Attribute::NoUnwind); break;
+ case lltok::kw_optnone: B.addAttribute(Attribute::OptimizeNone); break;
+ case lltok::kw_optsize: B.addAttribute(Attribute::OptimizeForSize); break;
+ case lltok::kw_readnone: B.addAttribute(Attribute::ReadNone); break;
+ case lltok::kw_readonly: B.addAttribute(Attribute::ReadOnly); break;
+ case lltok::kw_returns_twice:
+ B.addAttribute(Attribute::ReturnsTwice); break;
+ case lltok::kw_ssp: B.addAttribute(Attribute::StackProtect); break;
+ case lltok::kw_sspreq: B.addAttribute(Attribute::StackProtectReq); break;
+ case lltok::kw_sspstrong:
+ B.addAttribute(Attribute::StackProtectStrong); break;
+ case lltok::kw_safestack: B.addAttribute(Attribute::SafeStack); break;
+ case lltok::kw_sanitize_address:
+ B.addAttribute(Attribute::SanitizeAddress); break;
+ case lltok::kw_sanitize_thread:
+ B.addAttribute(Attribute::SanitizeThread); break;
+ case lltok::kw_sanitize_memory:
+ B.addAttribute(Attribute::SanitizeMemory); break;
+ case lltok::kw_uwtable: B.addAttribute(Attribute::UWTable); break;
// Error handling.
case lltok::kw_inreg:
@@ -1258,6 +1265,7 @@ bool LLParser::ParseOptionalParamAttrs(AttrBuilder &B) {
case lltok::kw_alignstack:
case lltok::kw_alwaysinline:
+ case lltok::kw_argmemonly:
case lltok::kw_builtin:
case lltok::kw_inlinehint:
case lltok::kw_jumptable:
@@ -1334,6 +1342,7 @@ bool LLParser::ParseOptionalReturnAttrs(AttrBuilder &B) {
case lltok::kw_alignstack:
case lltok::kw_alwaysinline:
+ case lltok::kw_argmemonly:
case lltok::kw_builtin:
case lltok::kw_cold:
case lltok::kw_inlinehint:
@@ -2873,8 +2882,8 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) {
if (ValTy->isVectorTy() != BaseType->isVectorTy())
return Error(ID.Loc, "getelementptr index type missmatch");
if (ValTy->isVectorTy()) {
- unsigned ValNumEl = cast<VectorType>(ValTy)->getNumElements();
- unsigned PtrNumEl = cast<VectorType>(BaseType)->getNumElements();
+ unsigned ValNumEl = ValTy->getVectorNumElements();
+ unsigned PtrNumEl = BaseType->getVectorNumElements();
if (ValNumEl != PtrNumEl)
return Error(
ID.Loc,
@@ -4534,8 +4543,17 @@ int LLParser::ParseInstruction(Instruction *&Inst, BasicBlock *BB,
case lltok::kw_and:
case lltok::kw_or:
case lltok::kw_xor: return ParseLogical(Inst, PFS, KeywordVal);
- case lltok::kw_icmp:
- case lltok::kw_fcmp: return ParseCompare(Inst, PFS, KeywordVal);
+ case lltok::kw_icmp: return ParseCompare(Inst, PFS, KeywordVal);
+ case lltok::kw_fcmp: {
+ FastMathFlags FMF = EatFastMathFlagsIfPresent();
+ int Res = ParseCompare(Inst, PFS, KeywordVal);
+ if (Res != 0)
+ return Res;
+ if (FMF.any())
+ Inst->setFastMathFlags(FMF);
+ return 0;
+ }
+
// Casts.
case lltok::kw_trunc:
case lltok::kw_zext:
@@ -5572,6 +5590,11 @@ int LLParser::ParseGetElementPtr(Instruction *&Inst, PerFunctionState &PFS) {
SmallVector<Value*, 16> Indices;
bool AteExtraComma = false;
+ // GEP returns a vector of pointers if at least one of parameters is a vector.
+ // All vector parameters should have the same vector width.
+ unsigned GEPWidth = BaseType->isVectorTy() ?
+ BaseType->getVectorNumElements() : 0;
+
while (EatIfPresent(lltok::comma)) {
if (Lex.getKind() == lltok::MetadataVar) {
AteExtraComma = true;
@@ -5580,14 +5603,13 @@ int LLParser::ParseGetElementPtr(Instruction *&Inst, PerFunctionState &PFS) {
if (ParseTypeAndValue(Val, EltLoc, PFS)) return true;
if (!Val->getType()->getScalarType()->isIntegerTy())
return Error(EltLoc, "getelementptr index must be an integer");
- if (Val->getType()->isVectorTy() != Ptr->getType()->isVectorTy())
- return Error(EltLoc, "getelementptr index type missmatch");
+
if (Val->getType()->isVectorTy()) {
- unsigned ValNumEl = cast<VectorType>(Val->getType())->getNumElements();
- unsigned PtrNumEl = cast<VectorType>(Ptr->getType())->getNumElements();
- if (ValNumEl != PtrNumEl)
+ unsigned ValNumEl = Val->getType()->getVectorNumElements();
+ if (GEPWidth && GEPWidth != ValNumEl)
return Error(EltLoc,
"getelementptr vector index has a wrong number of elements");
+ GEPWidth = ValNumEl;
}
Indices.push_back(Val);
}
diff --git a/lib/AsmParser/LLToken.h b/lib/AsmParser/LLToken.h
index 2487d1208133..691f085f0c9f 100644
--- a/lib/AsmParser/LLToken.h
+++ b/lib/AsmParser/LLToken.h
@@ -100,6 +100,7 @@ namespace lltok {
// Attributes:
kw_attributes,
kw_alwaysinline,
+ kw_argmemonly,
kw_sanitize_address,
kw_builtin,
kw_byval,
diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp
index 09f0b689bdc3..c04e8b9f1f37 100644
--- a/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -697,6 +697,21 @@ static Comdat::SelectionKind getDecodedComdatSelectionKind(unsigned Val) {
}
}
+static FastMathFlags getDecodedFastMathFlags(unsigned Val) {
+ FastMathFlags FMF;
+ if (0 != (Val & FastMathFlags::UnsafeAlgebra))
+ FMF.setUnsafeAlgebra();
+ if (0 != (Val & FastMathFlags::NoNaNs))
+ FMF.setNoNaNs();
+ if (0 != (Val & FastMathFlags::NoInfs))
+ FMF.setNoInfs();
+ if (0 != (Val & FastMathFlags::NoSignedZeros))
+ FMF.setNoSignedZeros();
+ if (0 != (Val & FastMathFlags::AllowReciprocal))
+ FMF.setAllowReciprocal();
+ return FMF;
+}
+
static void upgradeDLLImportExportLinkage(llvm::GlobalValue *GV, unsigned Val) {
switch (Val) {
case 5: GV->setDLLStorageClass(GlobalValue::DLLImportStorageClass); break;
@@ -1075,6 +1090,8 @@ static Attribute::AttrKind getAttrFromCode(uint64_t Code) {
return Attribute::Alignment;
case bitc::ATTR_KIND_ALWAYS_INLINE:
return Attribute::AlwaysInline;
+ case bitc::ATTR_KIND_ARGMEMONLY:
+ return Attribute::ArgMemOnly;
case bitc::ATTR_KIND_BUILTIN:
return Attribute::Builtin;
case bitc::ATTR_KIND_BY_VAL:
@@ -3472,17 +3489,7 @@ std::error_code BitcodeReader::parseFunctionBody(Function *F) {
if (Record[OpNum] & (1 << bitc::PEO_EXACT))
cast<BinaryOperator>(I)->setIsExact(true);
} else if (isa<FPMathOperator>(I)) {
- FastMathFlags FMF;
- if (0 != (Record[OpNum] & FastMathFlags::UnsafeAlgebra))
- FMF.setUnsafeAlgebra();
- if (0 != (Record[OpNum] & FastMathFlags::NoNaNs))
- FMF.setNoNaNs();
- if (0 != (Record[OpNum] & FastMathFlags::NoInfs))
- FMF.setNoInfs();
- if (0 != (Record[OpNum] & FastMathFlags::NoSignedZeros))
- FMF.setNoSignedZeros();
- if (0 != (Record[OpNum] & FastMathFlags::AllowReciprocal))
- FMF.setAllowReciprocal();
+ FastMathFlags FMF = getDecodedFastMathFlags(Record[OpNum]);
if (FMF.any())
I->setFastMathFlags(FMF);
}
@@ -3739,14 +3746,25 @@ std::error_code BitcodeReader::parseFunctionBody(Function *F) {
unsigned OpNum = 0;
Value *LHS, *RHS;
if (getValueTypePair(Record, OpNum, NextValueNo, LHS) ||
- popValue(Record, OpNum, NextValueNo, LHS->getType(), RHS) ||
- OpNum+1 != Record.size())
+ popValue(Record, OpNum, NextValueNo, LHS->getType(), RHS))
+ return error("Invalid record");
+
+ unsigned PredVal = Record[OpNum];
+ bool IsFP = LHS->getType()->isFPOrFPVectorTy();
+ FastMathFlags FMF;
+ if (IsFP && Record.size() > OpNum+1)
+ FMF = getDecodedFastMathFlags(Record[++OpNum]);
+
+ if (OpNum+1 != Record.size())
return error("Invalid record");
if (LHS->getType()->isFPOrFPVectorTy())
- I = new FCmpInst((FCmpInst::Predicate)Record[OpNum], LHS, RHS);
+ I = new FCmpInst((FCmpInst::Predicate)PredVal, LHS, RHS);
else
- I = new ICmpInst((ICmpInst::Predicate)Record[OpNum], LHS, RHS);
+ I = new ICmpInst((ICmpInst::Predicate)PredVal, LHS, RHS);
+
+ if (FMF.any())
+ I->setFastMathFlags(FMF);
InstructionList.push_back(I);
break;
}
@@ -4458,14 +4476,11 @@ std::error_code BitcodeReader::materialize(GlobalValue *GV) {
// Upgrade any old intrinsic calls in the function.
for (auto &I : UpgradedIntrinsics) {
- if (I.first != I.second) {
- for (auto UI = I.first->user_begin(), UE = I.first->user_end();
- UI != UE;) {
- User *U = *UI;
- ++UI;
- if (CallInst *CI = dyn_cast<CallInst>(U))
- UpgradeIntrinsicCall(CI, I.second);
- }
+ for (auto UI = I.first->user_begin(), UE = I.first->user_end(); UI != UE;) {
+ User *U = *UI;
+ ++UI;
+ if (CallInst *CI = dyn_cast<CallInst>(U))
+ UpgradeIntrinsicCall(CI, I.second);
}
}
@@ -4533,15 +4548,13 @@ std::error_code BitcodeReader::materializeModule(Module *M) {
// module is materialized because there could always be another function body
// with calls to the old function.
for (auto &I : UpgradedIntrinsics) {
- if (I.first != I.second) {
- for (auto *U : I.first->users()) {
- if (CallInst *CI = dyn_cast<CallInst>(U))
- UpgradeIntrinsicCall(CI, I.second);
- }
- if (!I.first->use_empty())
- I.first->replaceAllUsesWith(I.second);
- I.first->eraseFromParent();
+ for (auto *U : I.first->users()) {
+ if (CallInst *CI = dyn_cast<CallInst>(U))
+ UpgradeIntrinsicCall(CI, I.second);
}
+ if (!I.first->use_empty())
+ I.first->replaceAllUsesWith(I.second);
+ I.first->eraseFromParent();
}
UpgradedIntrinsics.clear();
diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp
index 622f7eaf0784..1a70ba5ac127 100644
--- a/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ b/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -162,6 +162,8 @@ static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind) {
return bitc::ATTR_KIND_ALIGNMENT;
case Attribute::AlwaysInline:
return bitc::ATTR_KIND_ALWAYS_INLINE;
+ case Attribute::ArgMemOnly:
+ return bitc::ATTR_KIND_ARGMEMONLY;
case Attribute::Builtin:
return bitc::ATTR_KIND_BUILTIN;
case Attribute::ByVal:
@@ -1759,13 +1761,17 @@ static void WriteInstruction(const Instruction &I, unsigned InstID,
pushValue(I.getOperand(2), InstID, Vals, VE);
break;
case Instruction::ICmp:
- case Instruction::FCmp:
+ case Instruction::FCmp: {
// compare returning Int1Ty or vector of Int1Ty
Code = bitc::FUNC_CODE_INST_CMP2;
PushValueAndType(I.getOperand(0), InstID, Vals, VE);
pushValue(I.getOperand(1), InstID, Vals, VE);
Vals.push_back(cast<CmpInst>(I).getPredicate());
+ uint64_t Flags = GetOptimizationFlags(&I);
+ if (Flags != 0)
+ Vals.push_back(Flags);
break;
+ }
case Instruction::Ret:
{
diff --git a/lib/CodeGen/Analysis.cpp b/lib/CodeGen/Analysis.cpp
index 3224fac25cb4..98d4c8afc7b9 100644
--- a/lib/CodeGen/Analysis.cpp
+++ b/lib/CodeGen/Analysis.cpp
@@ -81,27 +81,27 @@ unsigned llvm::ComputeLinearIndex(Type *Ty,
/// If Offsets is non-null, it points to a vector to be filled in
/// with the in-memory offsets of each of the individual values.
///
-void llvm::ComputeValueVTs(const TargetLowering &TLI, Type *Ty,
- SmallVectorImpl<EVT> &ValueVTs,
+void llvm::ComputeValueVTs(const TargetLowering &TLI, const DataLayout &DL,
+ Type *Ty, SmallVectorImpl<EVT> &ValueVTs,
SmallVectorImpl<uint64_t> *Offsets,
uint64_t StartingOffset) {
// Given a struct type, recursively traverse the elements.
if (StructType *STy = dyn_cast<StructType>(Ty)) {
- const StructLayout *SL = TLI.getDataLayout()->getStructLayout(STy);
+ const StructLayout *SL = DL.getStructLayout(STy);
for (StructType::element_iterator EB = STy->element_begin(),
EI = EB,
EE = STy->element_end();
EI != EE; ++EI)
- ComputeValueVTs(TLI, *EI, ValueVTs, Offsets,
+ ComputeValueVTs(TLI, DL, *EI, ValueVTs, Offsets,
StartingOffset + SL->getElementOffset(EI - EB));
return;
}
// Given an array type, recursively traverse the elements.
if (ArrayType *ATy = dyn_cast<ArrayType>(Ty)) {
Type *EltTy = ATy->getElementType();
- uint64_t EltSize = TLI.getDataLayout()->getTypeAllocSize(EltTy);
+ uint64_t EltSize = DL.getTypeAllocSize(EltTy);
for (unsigned i = 0, e = ATy->getNumElements(); i != e; ++i)
- ComputeValueVTs(TLI, EltTy, ValueVTs, Offsets,
+ ComputeValueVTs(TLI, DL, EltTy, ValueVTs, Offsets,
StartingOffset + i * EltSize);
return;
}
@@ -109,7 +109,7 @@ void llvm::ComputeValueVTs(const TargetLowering &TLI, Type *Ty,
if (Ty->isVoidTy())
return;
// Base case: we can get an EVT for this LLVM IR type.
- ValueVTs.push_back(TLI.getValueType(Ty));
+ ValueVTs.push_back(TLI.getValueType(DL, Ty));
if (Offsets)
Offsets->push_back(StartingOffset);
}
@@ -233,7 +233,8 @@ static bool isNoopBitcast(Type *T1, Type *T2,
static const Value *getNoopInput(const Value *V,
SmallVectorImpl<unsigned> &ValLoc,
unsigned &DataBits,
- const TargetLoweringBase &TLI) {
+ const TargetLoweringBase &TLI,
+ const DataLayout &DL) {
while (true) {
// Try to look through V1; if V1 is not an instruction, it can't be looked
// through.
@@ -255,16 +256,16 @@ static const Value *getNoopInput(const Value *V,
// Make sure this isn't a truncating or extending cast. We could
// support this eventually, but don't bother for now.
if (!isa<VectorType>(I->getType()) &&
- TLI.getPointerTy().getSizeInBits() ==
- cast<IntegerType>(Op->getType())->getBitWidth())
+ DL.getPointerSizeInBits() ==
+ cast<IntegerType>(Op->getType())->getBitWidth())
NoopInput = Op;
} else if (isa<PtrToIntInst>(I)) {
// Look through ptrtoint.
// Make sure this isn't a truncating or extending cast. We could
// support this eventually, but don't bother for now.
if (!isa<VectorType>(I->getType()) &&
- TLI.getPointerTy().getSizeInBits() ==
- cast<IntegerType>(I->getType())->getBitWidth())
+ DL.getPointerSizeInBits() ==
+ cast<IntegerType>(I->getType())->getBitWidth())
NoopInput = Op;
} else if (isa<TruncInst>(I) &&
TLI.allowTruncateForTailCall(Op->getType(), I->getType())) {
@@ -331,14 +332,15 @@ static bool slotOnlyDiscardsData(const Value *RetVal, const Value *CallVal,
SmallVectorImpl<unsigned> &RetIndices,
SmallVectorImpl<unsigned> &CallIndices,
bool AllowDifferingSizes,
- const TargetLoweringBase &TLI) {
+ const TargetLoweringBase &TLI,
+ const DataLayout &DL) {
// Trace the sub-value needed by the return value as far back up the graph as
// possible, in the hope that it will intersect with the value produced by the
// call. In the simple case with no "returned" attribute, the hope is actually
// that we end up back at the tail call instruction itself.
unsigned BitsRequired = UINT_MAX;
- RetVal = getNoopInput(RetVal, RetIndices, BitsRequired, TLI);
+ RetVal = getNoopInput(RetVal, RetIndices, BitsRequired, TLI, DL);
// If this slot in the value returned is undef, it doesn't matter what the
// call puts there, it'll be fine.
@@ -350,7 +352,7 @@ static bool slotOnlyDiscardsData(const Value *RetVal, const Value *CallVal,
// a "returned" attribute, the search will be blocked immediately and the loop
// a Noop.
unsigned BitsProvided = UINT_MAX;
- CallVal = getNoopInput(CallVal, CallIndices, BitsProvided, TLI);
+ CallVal = getNoopInput(CallVal, CallIndices, BitsProvided, TLI, DL);
// There's no hope if we can't actually trace them to (the same part of!) the
// same value.
@@ -606,7 +608,8 @@ bool llvm::returnTypeIsEligibleForTailCall(const Function *F,
// Finally, we can check whether the value produced by the tail call at this
// index is compatible with the value we return.
if (!slotOnlyDiscardsData(RetVal, CallVal, TmpRetPath, TmpCallPath,
- AllowDifferingSizes, TLI))
+ AllowDifferingSizes, TLI,
+ F->getParent()->getDataLayout()))
return false;
CallEmpty = !nextRealType(CallSubTypes, CallPath);
diff --git a/lib/CodeGen/AsmPrinter/ARMException.cpp b/lib/CodeGen/AsmPrinter/ARMException.cpp
index 4cb460a7bbfc..0bad7954b980 100644
--- a/lib/CodeGen/AsmPrinter/ARMException.cpp
+++ b/lib/CodeGen/AsmPrinter/ARMException.cpp
@@ -69,24 +69,32 @@ void ARMException::beginFunction(const MachineFunction *MF) {
///
void ARMException::endFunction(const MachineFunction *MF) {
ARMTargetStreamer &ATS = getTargetStreamer();
+ const Function *F = MF->getFunction();
+ const Function *Per = nullptr;
+ if (F->hasPersonalityFn())
+ Per = dyn_cast<Function>(F->getPersonalityFn()->stripPointerCasts());
+ assert(!MMI->getPersonality() || Per == MMI->getPersonality());
+ bool forceEmitPersonality =
+ F->hasPersonalityFn() && !isNoOpWithoutInvoke(classifyEHPersonality(Per)) &&
+ F->needsUnwindTableEntry();
+ bool shouldEmitPersonality = forceEmitPersonality ||
+ !MMI->getLandingPads().empty();
if (!Asm->MF->getFunction()->needsUnwindTableEntry() &&
- MMI->getLandingPads().empty())
+ !shouldEmitPersonality)
ATS.emitCantUnwind();
- else {
- if (!MMI->getLandingPads().empty()) {
- // Emit references to personality.
- if (const Function *Personality = MMI->getPersonality()) {
- MCSymbol *PerSym = Asm->getSymbol(Personality);
- Asm->OutStreamer->EmitSymbolAttribute(PerSym, MCSA_Global);
- ATS.emitPersonality(PerSym);
- }
-
- // Emit .handlerdata directive.
- ATS.emitHandlerData();
-
- // Emit actual exception table
- emitExceptionTable();
+ else if (shouldEmitPersonality) {
+ // Emit references to personality.
+ if (Per) {
+ MCSymbol *PerSym = Asm->getSymbol(Per);
+ Asm->OutStreamer->EmitSymbolAttribute(PerSym, MCSA_Global);
+ ATS.emitPersonality(PerSym);
}
+
+ // Emit .handlerdata directive.
+ ATS.emitHandlerData();
+
+ // Emit actual exception table
+ emitExceptionTable();
}
if (Asm->MAI->getExceptionHandlingType() == ExceptionHandling::ARM)
diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 8a7e9f991611..125047e7bbb5 100644
--- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -19,7 +19,6 @@
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/ConstantFolding.h"
-#include "llvm/Analysis/JumpInstrTableInfo.h"
#include "llvm/CodeGen/Analysis.h"
#include "llvm/CodeGen/GCMetadataPrinter.h"
#include "llvm/CodeGen/MachineConstantPool.h"
@@ -820,7 +819,7 @@ void AsmPrinter::EmitFunctionBody() {
emitCFIInstruction(MI);
break;
- case TargetOpcode::FRAME_ALLOC:
+ case TargetOpcode::LOCAL_ESCAPE:
emitFrameAlloc(MI);
break;
@@ -1024,7 +1023,7 @@ bool AsmPrinter::doFinalization(Module &M) {
// Emit visibility info for declarations
for (const Function &F : M) {
- if (!F.isDeclaration())
+ if (!F.isDeclarationForLinker())
continue;
GlobalValue::VisibilityTypes V = F.getVisibility();
if (V == GlobalValue::DefaultVisibility)
diff --git a/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp b/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp
index 0bc873e326be..2c212c7ecee1 100644
--- a/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp
@@ -89,6 +89,7 @@ void DwarfCFIException::endModule() {
void DwarfCFIException::beginFunction(const MachineFunction *MF) {
shouldEmitMoves = shouldEmitPersonality = shouldEmitLSDA = false;
+ const Function *F = MF->getFunction();
// If any landing pads survive, we need an EH table.
bool hasLandingPads = !MMI->getLandingPads().empty();
@@ -104,10 +105,24 @@ void DwarfCFIException::beginFunction(const MachineFunction *MF) {
const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
unsigned PerEncoding = TLOF.getPersonalityEncoding();
- const Function *Per = MMI->getPersonality();
-
- shouldEmitPersonality = hasLandingPads &&
- PerEncoding != dwarf::DW_EH_PE_omit && Per;
+ const Function *Per = nullptr;
+ if (F->hasPersonalityFn())
+ Per = dyn_cast<Function>(F->getPersonalityFn()->stripPointerCasts());
+ assert(!MMI->getPersonality() || Per == MMI->getPersonality());
+
+ // Emit a personality function even when there are no landing pads
+ bool forceEmitPersonality =
+ // ...if a personality function is explicitly specified
+ F->hasPersonalityFn() &&
+ // ... and it's not known to be a noop in the absence of invokes
+ !isNoOpWithoutInvoke(classifyEHPersonality(Per)) &&
+ // ... and we're not explicitly asked not to emit it
+ F->needsUnwindTableEntry();
+
+ shouldEmitPersonality =
+ (forceEmitPersonality ||
+ (hasLandingPads && PerEncoding != dwarf::DW_EH_PE_omit)) &&
+ Per;
unsigned LSDAEncoding = TLOF.getLSDAEncoding();
shouldEmitLSDA = shouldEmitPersonality &&
@@ -123,6 +138,11 @@ void DwarfCFIException::beginFunction(const MachineFunction *MF) {
if (!shouldEmitPersonality)
return;
+ // If we are forced to emit this personality, make sure to record
+ // it because it might not appear in any landingpad
+ if (forceEmitPersonality)
+ MMI->addPersonality(Per);
+
const MCSymbol *Sym =
TLOF.getCFIPersonalitySymbol(Per, *Asm->Mang, Asm->TM, MMI);
Asm->OutStreamer->EmitCFIPersonality(Sym, PerEncoding);
diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.h b/lib/CodeGen/AsmPrinter/DwarfDebug.h
index 1c3e2aec64ab..01f34c6eb81c 100644
--- a/lib/CodeGen/AsmPrinter/DwarfDebug.h
+++ b/lib/CodeGen/AsmPrinter/DwarfDebug.h
@@ -49,7 +49,7 @@ class DwarfUnit;
class MachineModuleInfo;
//===----------------------------------------------------------------------===//
-/// \brief This class is used to record source line correspondence.
+/// This class is used to record source line correspondence.
class SrcLineInfo {
unsigned Line; // Source line number.
unsigned Column; // Source column.
@@ -161,7 +161,7 @@ public:
return dwarf::DW_TAG_variable;
}
- /// \brief Return true if DbgVariable is artificial.
+ /// Return true if DbgVariable is artificial.
bool isArtificial() const {
if (Var->isArtificial())
return true;
@@ -190,149 +190,152 @@ public:
const DIType *getType() const;
private:
- /// resolve - Look in the DwarfDebug map for the MDNode that
+ /// Look in the DwarfDebug map for the MDNode that
/// corresponds to the reference.
template <typename T> T *resolve(TypedDINodeRef<T> Ref) const;
};
-/// \brief Helper used to pair up a symbol and its DWARF compile unit.
+/// Helper used to pair up a symbol and its DWARF compile unit.
struct SymbolCU {
SymbolCU(DwarfCompileUnit *CU, const MCSymbol *Sym) : Sym(Sym), CU(CU) {}
const MCSymbol *Sym;
DwarfCompileUnit *CU;
};
-/// \brief Collects and handles dwarf debug information.
+/// Collects and handles dwarf debug information.
class DwarfDebug : public AsmPrinterHandler {
- // Target of Dwarf emission.
+ /// Target of Dwarf emission.
AsmPrinter *Asm;
- // Collected machine module information.
+ /// Collected machine module information.
MachineModuleInfo *MMI;
- // All DIEValues are allocated through this allocator.
+ /// All DIEValues are allocated through this allocator.
BumpPtrAllocator DIEValueAllocator;
- // Maps MDNode with its corresponding DwarfCompileUnit.
+ /// Maps MDNode with its corresponding DwarfCompileUnit.
MapVector<const MDNode *, DwarfCompileUnit *> CUMap;
- // Maps subprogram MDNode with its corresponding DwarfCompileUnit.
+ /// Maps subprogram MDNode with its corresponding DwarfCompileUnit.
MapVector<const MDNode *, DwarfCompileUnit *> SPMap;
- // Maps a CU DIE with its corresponding DwarfCompileUnit.
+ /// Maps a CU DIE with its corresponding DwarfCompileUnit.
DenseMap<const DIE *, DwarfCompileUnit *> CUDieMap;
- // List of all labels used in aranges generation.
+ /// List of all labels used in aranges generation.
std::vector<SymbolCU> ArangeLabels;
- // Size of each symbol emitted (for those symbols that have a specific size).
+ /// Size of each symbol emitted (for those symbols that have a specific size).
DenseMap<const MCSymbol *, uint64_t> SymSize;
LexicalScopes LScopes;
- // Collection of abstract variables.
+ /// Collection of abstract variables.
DenseMap<const MDNode *, std::unique_ptr<DbgVariable>> AbstractVariables;
SmallVector<std::unique_ptr<DbgVariable>, 64> ConcreteVariables;
- // Collection of DebugLocEntry. Stored in a linked list so that DIELocLists
- // can refer to them in spite of insertions into this list.
+ /// Collection of DebugLocEntry. Stored in a linked list so that DIELocLists
+ /// can refer to them in spite of insertions into this list.
DebugLocStream DebugLocs;
- // This is a collection of subprogram MDNodes that are processed to
- // create DIEs.
+ /// This is a collection of subprogram MDNodes that are processed to
+ /// create DIEs.
SmallPtrSet<const MDNode *, 16> ProcessedSPNodes;
- // Maps instruction with label emitted before instruction.
+ /// Maps instruction with label emitted before instruction.
DenseMap<const MachineInstr *, MCSymbol *> LabelsBeforeInsn;
- // Maps instruction with label emitted after instruction.
+ /// Maps instruction with label emitted after instruction.
DenseMap<const MachineInstr *, MCSymbol *> LabelsAfterInsn;
- // History of DBG_VALUE and clobber instructions for each user variable.
- // Variables are listed in order of appearance.
+ /// History of DBG_VALUE and clobber instructions for each user
+ /// variable. Variables are listed in order of appearance.
DbgValueHistoryMap DbgValues;
- // Previous instruction's location information. This is used to determine
- // label location to indicate scope boundries in dwarf debug info.
+ /// Previous instruction's location information. This is used to
+ /// determine label location to indicate scope boundries in dwarf
+ /// debug info.
DebugLoc PrevInstLoc;
MCSymbol *PrevLabel;
- // This location indicates end of function prologue and beginning of function
- // body.
+ /// This location indicates end of function prologue and beginning of
+ /// function body.
DebugLoc PrologEndLoc;
- // If nonnull, stores the current machine function we're processing.
+ /// If nonnull, stores the current machine function we're processing.
const MachineFunction *CurFn;
- // If nonnull, stores the current machine instruction we're processing.
+ /// If nonnull, stores the current machine instruction we're processing.
const MachineInstr *CurMI;
- // If nonnull, stores the CU in which the previous subprogram was contained.
+ /// If nonnull, stores the CU in which the previous subprogram was contained.
const DwarfCompileUnit *PrevCU;
- // As an optimization, there is no need to emit an entry in the directory
- // table for the same directory as DW_AT_comp_dir.
+ /// As an optimization, there is no need to emit an entry in the directory
+ /// table for the same directory as DW_AT_comp_dir.
StringRef CompilationDir;
- // Holder for the file specific debug information.
+ /// Holder for the file specific debug information.
DwarfFile InfoHolder;
- // Holders for the various debug information flags that we might need to
- // have exposed. See accessor functions below for description.
+ /// Holders for the various debug information flags that we might need to
+ /// have exposed. See accessor functions below for description.
- // Holder for imported entities.
+ /// Holder for imported entities.
typedef SmallVector<std::pair<const MDNode *, const MDNode *>, 32>
ImportedEntityMap;
ImportedEntityMap ScopesWithImportedEntities;
- // Map from MDNodes for user-defined types to the type units that describe
- // them.
+ /// Map from MDNodes for user-defined types to the type units that
+ /// describe them.
DenseMap<const MDNode *, const DwarfTypeUnit *> DwarfTypeUnits;
SmallVector<
std::pair<std::unique_ptr<DwarfTypeUnit>, const DICompositeType *>, 1>
TypeUnitsUnderConstruction;
- // Whether to emit the pubnames/pubtypes sections.
+ /// Whether to emit the pubnames/pubtypes sections.
bool HasDwarfPubSections;
- // Whether or not to use AT_ranges for compilation units.
+ /// Whether or not to use AT_ranges for compilation units.
bool HasCURanges;
- // Whether we emitted a function into a section other than the default
- // text.
+ /// Whether we emitted a function into a section other than the
+ /// default text.
bool UsedNonDefaultText;
- // Whether to use the GNU TLS opcode (instead of the standard opcode).
+ /// Whether to use the GNU TLS opcode (instead of the standard opcode).
bool UseGNUTLSOpcode;
- // Version of dwarf we're emitting.
+ /// Version of dwarf we're emitting.
unsigned DwarfVersion;
- // Maps from a type identifier to the actual MDNode.
+ /// Maps from a type identifier to the actual MDNode.
DITypeIdentifierMap TypeIdentifierMap;
- // DWARF5 Experimental Options
+ /// DWARF5 Experimental Options
+ /// @{
bool HasDwarfAccelTables;
bool HasSplitDwarf;
- // Separated Dwarf Variables
- // In general these will all be for bits that are left in the
- // original object file, rather than things that are meant
- // to be in the .dwo sections.
+ /// Separated Dwarf Variables
+ /// In general these will all be for bits that are left in the
+ /// original object file, rather than things that are meant
+ /// to be in the .dwo sections.
- // Holder for the skeleton information.
+ /// Holder for the skeleton information.
DwarfFile SkeletonHolder;
- /// Store file names for type units under fission in a line table header that
- /// will be emitted into debug_line.dwo.
- // FIXME: replace this with a map from comp_dir to table so that we can emit
- // multiple tables during LTO each of which uses directory 0, referencing the
- // comp_dir of all the type units that use it.
+ /// Store file names for type units under fission in a line table
+ /// header that will be emitted into debug_line.dwo.
+ // FIXME: replace this with a map from comp_dir to table so that we
+ // can emit multiple tables during LTO each of which uses directory
+ // 0, referencing the comp_dir of all the type units that use it.
MCDwarfDwoLineTable SplitTypeUnitFileTable;
-
- // True iff there are multiple CUs in this module.
+ /// @}
+
+ /// True iff there are multiple CUs in this module.
bool SingleCU;
bool IsDarwin;
bool IsPS4;
@@ -354,7 +357,7 @@ class DwarfDebug : public AsmPrinterHandler {
typedef DbgValueHistoryMap::InlinedVariable InlinedVariable;
- /// \brief Find abstract variable associated with Var.
+ /// Find abstract variable associated with Var.
DbgVariable *getExistingAbstractVariable(InlinedVariable IV,
const DILocalVariable *&Cleansed);
DbgVariable *getExistingAbstractVariable(InlinedVariable IV);
@@ -366,56 +369,56 @@ class DwarfDebug : public AsmPrinterHandler {
DbgVariable *createConcreteVariable(LexicalScope &Scope, InlinedVariable IV);
- /// \brief Construct a DIE for this abstract scope.
+ /// Construct a DIE for this abstract scope.
void constructAbstractSubprogramScopeDIE(LexicalScope *Scope);
- /// \brief Compute the size and offset of a DIE given an incoming Offset.
+ /// Compute the size and offset of a DIE given an incoming Offset.
unsigned computeSizeAndOffset(DIE *Die, unsigned Offset);
- /// \brief Compute the size and offset of all the DIEs.
+ /// Compute the size and offset of all the DIEs.
void computeSizeAndOffsets();
- /// \brief Collect info for variables that were optimized out.
+ /// Collect info for variables that were optimized out.
void collectDeadVariables();
void finishVariableDefinitions();
void finishSubprogramDefinitions();
- /// \brief Finish off debug information after all functions have been
+ /// Finish off debug information after all functions have been
/// processed.
void finalizeModuleInfo();
- /// \brief Emit the debug info section.
+ /// Emit the debug info section.
void emitDebugInfo();
- /// \brief Emit the abbreviation section.
+ /// Emit the abbreviation section.
void emitAbbreviations();
- /// \brief Emit a specified accelerator table.
+ /// Emit a specified accelerator table.
void emitAccel(DwarfAccelTable &Accel, MCSection *Section,
StringRef TableName);
- /// \brief Emit visible names into a hashed accelerator table section.
+ /// Emit visible names into a hashed accelerator table section.
void emitAccelNames();
- /// \brief Emit objective C classes and categories into a hashed
+ /// Emit objective C classes and categories into a hashed
/// accelerator table section.
void emitAccelObjC();
- /// \brief Emit namespace dies into a hashed accelerator table.
+ /// Emit namespace dies into a hashed accelerator table.
void emitAccelNamespaces();
- /// \brief Emit type dies into a hashed accelerator table.
+ /// Emit type dies into a hashed accelerator table.
void emitAccelTypes();
- /// \brief Emit visible names into a debug pubnames section.
+ /// Emit visible names into a debug pubnames section.
/// \param GnuStyle determines whether or not we want to emit
/// additional information into the table ala newer gcc for gdb
/// index.
void emitDebugPubNames(bool GnuStyle = false);
- /// \brief Emit visible types into a debug pubtypes section.
+ /// Emit visible types into a debug pubtypes section.
/// \param GnuStyle determines whether or not we want to emit
/// additional information into the table ala newer gcc for gdb
/// index.
@@ -425,91 +428,91 @@ class DwarfDebug : public AsmPrinterHandler {
bool GnuStyle, MCSection *PSec, StringRef Name,
const StringMap<const DIE *> &(DwarfCompileUnit::*Accessor)() const);
- /// \brief Emit visible names into a debug str section.
+ /// Emit visible names into a debug str section.
void emitDebugStr();
- /// \brief Emit visible names into a debug loc section.
+ /// Emit visible names into a debug loc section.
void emitDebugLoc();
- /// \brief Emit visible names into a debug loc dwo section.
+ /// Emit visible names into a debug loc dwo section.
void emitDebugLocDWO();
- /// \brief Emit visible names into a debug aranges section.
+ /// Emit visible names into a debug aranges section.
void emitDebugARanges();
- /// \brief Emit visible names into a debug ranges section.
+ /// Emit visible names into a debug ranges section.
void emitDebugRanges();
- /// \brief Emit inline info using custom format.
+ /// Emit inline info using custom format.
void emitDebugInlineInfo();
/// DWARF 5 Experimental Split Dwarf Emitters
- /// \brief Initialize common features of skeleton units.
+ /// Initialize common features of skeleton units.
void initSkeletonUnit(const DwarfUnit &U, DIE &Die,
std::unique_ptr<DwarfUnit> NewU);
- /// \brief Construct the split debug info compile unit for the debug info
+ /// Construct the split debug info compile unit for the debug info
/// section.
DwarfCompileUnit &constructSkeletonCU(const DwarfCompileUnit &CU);
- /// \brief Construct the split debug info compile unit for the debug info
+ /// Construct the split debug info compile unit for the debug info
/// section.
DwarfTypeUnit &constructSkeletonTU(DwarfTypeUnit &TU);
- /// \brief Emit the debug info dwo section.
+ /// Emit the debug info dwo section.
void emitDebugInfoDWO();
- /// \brief Emit the debug abbrev dwo section.
+ /// Emit the debug abbrev dwo section.
void emitDebugAbbrevDWO();
- /// \brief Emit the debug line dwo section.
+ /// Emit the debug line dwo section.
void emitDebugLineDWO();
- /// \brief Emit the debug str dwo section.
+ /// Emit the debug str dwo section.
void emitDebugStrDWO();
/// Flags to let the linker know we have emitted new style pubnames. Only
/// emit it here if we don't have a skeleton CU for split dwarf.
void addGnuPubAttributes(DwarfUnit &U, DIE &D) const;
- /// \brief Create new DwarfCompileUnit for the given metadata node with tag
+ /// Create new DwarfCompileUnit for the given metadata node with tag
/// DW_TAG_compile_unit.
DwarfCompileUnit &constructDwarfCompileUnit(const DICompileUnit *DIUnit);
- /// \brief Construct imported_module or imported_declaration DIE.
+ /// Construct imported_module or imported_declaration DIE.
void constructAndAddImportedEntityDIE(DwarfCompileUnit &TheCU,
const DIImportedEntity *N);
- /// \brief Register a source line with debug info. Returns the unique
+ /// Register a source line with debug info. Returns the unique
/// label that was emitted and which provides correspondence to the
/// source line list.
void recordSourceLine(unsigned Line, unsigned Col, const MDNode *Scope,
unsigned Flags);
- /// \brief Indentify instructions that are marking the beginning of or
+ /// Indentify instructions that are marking the beginning of or
/// ending of a scope.
void identifyScopeMarkers();
- /// \brief Populate LexicalScope entries with variables' info.
+ /// Populate LexicalScope entries with variables' info.
void collectVariableInfo(DwarfCompileUnit &TheCU, const DISubprogram *SP,
DenseSet<InlinedVariable> &ProcessedVars);
- /// \brief Build the location list for all DBG_VALUEs in the
+ /// Build the location list for all DBG_VALUEs in the
/// function that describe the same variable.
void buildLocationList(SmallVectorImpl<DebugLocEntry> &DebugLoc,
const DbgValueHistoryMap::InstrRanges &Ranges);
- /// \brief Collect variable information from the side table maintained
+ /// Collect variable information from the side table maintained
/// by MMI.
void collectVariableInfoFromMMITable(DenseSet<InlinedVariable> &P);
- /// \brief Ensure that a label will be emitted before MI.
+ /// Ensure that a label will be emitted before MI.
void requestLabelBeforeInsn(const MachineInstr *MI) {
LabelsBeforeInsn.insert(std::make_pair(MI, nullptr));
}
- /// \brief Ensure that a label will be emitted after MI.
+ /// Ensure that a label will be emitted after MI.
void requestLabelAfterInsn(const MachineInstr *MI) {
LabelsAfterInsn.insert(std::make_pair(MI, nullptr));
}
@@ -522,50 +525,50 @@ public:
~DwarfDebug() override;
- /// \brief Emit all Dwarf sections that should come prior to the
+ /// Emit all Dwarf sections that should come prior to the
/// content.
void beginModule();
- /// \brief Emit all Dwarf sections that should come after the content.
+ /// Emit all Dwarf sections that should come after the content.
void endModule() override;
- /// \brief Gather pre-function debug information.
+ /// Gather pre-function debug information.
void beginFunction(const MachineFunction *MF) override;
- /// \brief Gather and emit post-function debug information.
+ /// Gather and emit post-function debug information.
void endFunction(const MachineFunction *MF) override;
- /// \brief Process beginning of an instruction.
+ /// Process beginning of an instruction.
void beginInstruction(const MachineInstr *MI) override;
- /// \brief Process end of an instruction.
+ /// Process end of an instruction.
void endInstruction() override;
- /// \brief Add a DIE to the set of types that we're going to pull into
+ /// Add a DIE to the set of types that we're going to pull into
/// type units.
void addDwarfTypeUnitType(DwarfCompileUnit &CU, StringRef Identifier,
DIE &Die, const DICompositeType *CTy);
- /// \brief Add a label so that arange data can be generated for it.
+ /// Add a label so that arange data can be generated for it.
void addArangeLabel(SymbolCU SCU) { ArangeLabels.push_back(SCU); }
- /// \brief For symbols that have a size designated (e.g. common symbols),
+ /// For symbols that have a size designated (e.g. common symbols),
/// this tracks that size.
void setSymbolSize(const MCSymbol *Sym, uint64_t Size) override {
SymSize[Sym] = Size;
}
- /// \brief Returns whether to use DW_OP_GNU_push_tls_address, instead of the
+ /// Returns whether to use DW_OP_GNU_push_tls_address, instead of the
/// standard DW_OP_form_tls_address opcode
bool useGNUTLSOpcode() const { return UseGNUTLSOpcode; }
// Experimental DWARF5 features.
- /// \brief Returns whether or not to emit tables that dwarf consumers can
+ /// Returns whether or not to emit tables that dwarf consumers can
/// use to accelerate lookup.
bool useDwarfAccelTables() const { return HasDwarfAccelTables; }
- /// \brief Returns whether or not to change the current debug info for the
+ /// Returns whether or not to change the current debug info for the
/// split dwarf proposal support.
bool useSplitDwarf() const { return HasSplitDwarf; }
@@ -579,7 +582,7 @@ public:
/// Returns the entries for the .debug_loc section.
const DebugLocStream &getDebugLocs() const { return DebugLocs; }
- /// \brief Emit an entry for the debug loc section. This can be used to
+ /// Emit an entry for the debug loc section. This can be used to
/// handle an entry that's going to be emitted into the debug loc section.
void emitDebugLocEntry(ByteStreamer &Streamer,
const DebugLocStream::Entry &Entry);
@@ -592,7 +595,7 @@ public:
return Ref.resolve(TypeIdentifierMap);
}
- /// \brief Return the TypeIdentifierMap.
+ /// Return the TypeIdentifierMap.
const DITypeIdentifierMap &getTypeIdentifierMap() const {
return TypeIdentifierMap;
}
@@ -627,14 +630,14 @@ public:
less_first()));
}
- /// \brief A helper function to check whether the DIE for a given Scope is
+ /// A helper function to check whether the DIE for a given Scope is
/// going to be null.
bool isLexicalScopeDIENull(LexicalScope *Scope);
- /// \brief Return Label preceding the instruction.
+ /// Return Label preceding the instruction.
MCSymbol *getLabelBeforeInsn(const MachineInstr *MI);
- /// \brief Return Label immediately following the instruction.
+ /// Return Label immediately following the instruction.
MCSymbol *getLabelAfterInsn(const MachineInstr *MI);
// FIXME: Sink these functions down into DwarfFile/Dwarf*Unit.
diff --git a/lib/CodeGen/AsmPrinter/DwarfUnit.h b/lib/CodeGen/AsmPrinter/DwarfUnit.h
index 4000ae48a856..44d9d2245dda 100644
--- a/lib/CodeGen/AsmPrinter/DwarfUnit.h
+++ b/lib/CodeGen/AsmPrinter/DwarfUnit.h
@@ -113,7 +113,7 @@ protected:
DwarfUnit(unsigned UID, dwarf::Tag, const DICompileUnit *CU, AsmPrinter *A,
DwarfDebug *DW, DwarfFile *DWU);
- /// \brief Add a string attribute data and value.
+ /// Add a string attribute data and value.
///
/// This is guaranteed to be in the local string pool instead of indirected.
void addLocalString(DIE &Die, dwarf::Attribute Attribute, StringRef Str);
@@ -142,10 +142,10 @@ public:
unsigned getDebugInfoOffset() const { return DebugInfoOffset; }
void setDebugInfoOffset(unsigned DbgInfoOff) { DebugInfoOffset = DbgInfoOff; }
- /// \brief Return true if this compile unit has something to write out.
+ /// Return true if this compile unit has something to write out.
bool hasContent() const { return UnitDie.hasChildren(); }
- /// \brief Get string containing language specific context for a global name.
+ /// Get string containing language specific context for a global name.
///
/// Walks the metadata parent chain in a language specific manner (using the
/// compile unit language) and returns it as a string. This is done at the
@@ -162,42 +162,42 @@ public:
virtual void addGlobalType(const DIType *Ty, const DIE &Die,
const DIScope *Context) {}
- /// \brief Add a new name to the namespace accelerator table.
+ /// Add a new name to the namespace accelerator table.
void addAccelNamespace(StringRef Name, const DIE &Die);
- /// \brief Returns the DIE map slot for the specified debug variable.
+ /// Returns the DIE map slot for the specified debug variable.
///
/// We delegate the request to DwarfDebug when the MDNode can be part of the
/// type system, since DIEs for the type system can be shared across CUs and
/// the mappings are kept in DwarfDebug.
DIE *getDIE(const DINode *D) const;
- /// \brief Returns a fresh newly allocated DIELoc.
+ /// Returns a fresh newly allocated DIELoc.
DIELoc *getDIELoc() { return new (DIEValueAllocator) DIELoc; }
- /// \brief Insert DIE into the map.
+ /// Insert DIE into the map.
///
/// We delegate the request to DwarfDebug when the MDNode can be part of the
/// type system, since DIEs for the type system can be shared across CUs and
/// the mappings are kept in DwarfDebug.
void insertDIE(const DINode *Desc, DIE *D);
- /// \brief Add a flag that is true to the DIE.
+ /// Add a flag that is true to the DIE.
void addFlag(DIE &Die, dwarf::Attribute Attribute);
- /// \brief Add an unsigned integer attribute data and value.
+ /// Add an unsigned integer attribute data and value.
void addUInt(DIE &Die, dwarf::Attribute Attribute, Optional<dwarf::Form> Form,
uint64_t Integer);
void addUInt(DIE &Block, dwarf::Form Form, uint64_t Integer);
- /// \brief Add an signed integer attribute data and value.
+ /// Add an signed integer attribute data and value.
void addSInt(DIE &Die, dwarf::Attribute Attribute, Optional<dwarf::Form> Form,
int64_t Integer);
void addSInt(DIELoc &Die, Optional<dwarf::Form> Form, int64_t Integer);
- /// \brief Add a string attribute data and value.
+ /// Add a string attribute data and value.
///
/// We always emit a reference to the string pool instead of immediate
/// strings so that DIEs have more predictable sizes. In the case of split
@@ -205,38 +205,38 @@ public:
/// into the string table.
void addString(DIE &Die, dwarf::Attribute Attribute, StringRef Str);
- /// \brief Add a Dwarf label attribute data and value.
+ /// Add a Dwarf label attribute data and value.
DIE::value_iterator addLabel(DIE &Die, dwarf::Attribute Attribute,
dwarf::Form Form, const MCSymbol *Label);
void addLabel(DIELoc &Die, dwarf::Form Form, const MCSymbol *Label);
- /// \brief Add an offset into a section attribute data and value.
+ /// Add an offset into a section attribute data and value.
void addSectionOffset(DIE &Die, dwarf::Attribute Attribute, uint64_t Integer);
- /// \brief Add a dwarf op address data and value using the form given and an
+ /// Add a dwarf op address data and value using the form given and an
/// op of either DW_FORM_addr or DW_FORM_GNU_addr_index.
void addOpAddress(DIELoc &Die, const MCSymbol *Label);
- /// \brief Add a label delta attribute data and value.
+ /// Add a label delta attribute data and value.
void addLabelDelta(DIE &Die, dwarf::Attribute Attribute, const MCSymbol *Hi,
const MCSymbol *Lo);
- /// \brief Add a DIE attribute data and value.
+ /// Add a DIE attribute data and value.
void addDIEEntry(DIE &Die, dwarf::Attribute Attribute, DIE &Entry);
- /// \brief Add a DIE attribute data and value.
+ /// Add a DIE attribute data and value.
void addDIEEntry(DIE &Die, dwarf::Attribute Attribute, DIEEntry Entry);
void addDIETypeSignature(DIE &Die, const DwarfTypeUnit &Type);
- /// \brief Add block data.
+ /// Add block data.
void addBlock(DIE &Die, dwarf::Attribute Attribute, DIELoc *Block);
- /// \brief Add block data.
+ /// Add block data.
void addBlock(DIE &Die, dwarf::Attribute Attribute, DIEBlock *Block);
- /// \brief Add location information to specified debug information entry.
+ /// Add location information to specified debug information entry.
void addSourceLine(DIE &Die, unsigned Line, StringRef File,
StringRef Directory);
void addSourceLine(DIE &Die, const DILocalVariable *V);
@@ -246,30 +246,30 @@ public:
void addSourceLine(DIE &Die, const DINamespace *NS);
void addSourceLine(DIE &Die, const DIObjCProperty *Ty);
- /// \brief Add constant value entry in variable DIE.
+ /// Add constant value entry in variable DIE.
void addConstantValue(DIE &Die, const MachineOperand &MO, const DIType *Ty);
void addConstantValue(DIE &Die, const ConstantInt *CI, const DIType *Ty);
void addConstantValue(DIE &Die, const APInt &Val, const DIType *Ty);
void addConstantValue(DIE &Die, const APInt &Val, bool Unsigned);
void addConstantValue(DIE &Die, bool Unsigned, uint64_t Val);
- /// \brief Add constant value entry in variable DIE.
+ /// Add constant value entry in variable DIE.
void addConstantFPValue(DIE &Die, const MachineOperand &MO);
void addConstantFPValue(DIE &Die, const ConstantFP *CFP);
- /// \brief Add a linkage name, if it isn't empty.
+ /// Add a linkage name, if it isn't empty.
void addLinkageName(DIE &Die, StringRef LinkageName);
- /// \brief Add template parameters in buffer.
+ /// Add template parameters in buffer.
void addTemplateParams(DIE &Buffer, DINodeArray TParams);
- /// \brief Add register operand.
+ /// Add register operand.
/// \returns false if the register does not exist, e.g., because it was never
/// materialized.
bool addRegisterOpPiece(DIELoc &TheDie, unsigned Reg,
unsigned SizeInBits = 0, unsigned OffsetInBits = 0);
- /// \brief Add register offset.
+ /// Add register offset.
/// \returns false if the register does not exist, e.g., because it was never
/// materialized.
bool addRegisterOffset(DIELoc &TheDie, unsigned Reg, int64_t Offset);
@@ -283,7 +283,7 @@ public:
dwarf::Attribute Attribute,
const MachineLocation &Location);
- /// \brief Add a new type attribute to the specified entity.
+ /// Add a new type attribute to the specified entity.
///
/// This takes and attribute parameter because DW_AT_friend attributes are