From 85d8b2bbe386bcfe669575d05b61482d7be07e5d Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Tue, 9 Jun 2015 19:06:30 +0000 Subject: Vendor import of llvm trunk r239412: https://llvm.org/svn/llvm-project/llvm/trunk@239412 --- lib/Analysis/AliasAnalysis.cpp | 84 +- lib/Analysis/AliasAnalysisEvaluator.cpp | 8 +- lib/Analysis/AliasSetTracker.cpp | 2 +- lib/Analysis/BranchProbabilityInfo.cpp | 4 + lib/Analysis/CMakeLists.txt | 1 + lib/Analysis/DependenceAnalysis.cpp | 70 +- lib/Analysis/InstructionSimplify.cpp | 149 +- lib/Analysis/LoopAccessAnalysis.cpp | 198 ++- lib/Analysis/MemoryDependenceAnalysis.cpp | 19 +- lib/Analysis/MemoryLocation.cpp | 90 ++ lib/Analysis/PHITransAddr.cpp | 25 +- lib/Analysis/ScalarEvolutionExpander.cpp | 40 +- lib/Analysis/TargetTransformInfo.cpp | 17 +- lib/Analysis/ValueTracking.cpp | 43 +- lib/AsmParser/LLLexer.cpp | 20 +- lib/AsmParser/LLParser.cpp | 28 +- lib/Bitcode/Reader/BitcodeReader.cpp | 19 +- lib/CodeGen/AggressiveAntiDepBreaker.cpp | 2 +- lib/CodeGen/AsmPrinter/AddressPool.cpp | 2 +- lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 82 +- lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp | 32 +- lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp | 7 +- lib/CodeGen/AsmPrinter/CMakeLists.txt | 2 +- lib/CodeGen/AsmPrinter/DIE.cpp | 180 +-- lib/CodeGen/AsmPrinter/DIEHash.cpp | 74 +- lib/CodeGen/AsmPrinter/DIEHash.h | 109 +- lib/CodeGen/AsmPrinter/DwarfAccelTable.cpp | 6 +- lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp | 35 +- lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 7 +- lib/CodeGen/AsmPrinter/DwarfExpression.cpp | 37 +- lib/CodeGen/AsmPrinter/DwarfExpression.h | 3 + lib/CodeGen/AsmPrinter/DwarfFile.cpp | 59 +- lib/CodeGen/AsmPrinter/DwarfFile.h | 9 +- lib/CodeGen/AsmPrinter/DwarfUnit.cpp | 77 +- lib/CodeGen/AsmPrinter/DwarfUnit.h | 27 +- lib/CodeGen/AsmPrinter/Win64Exception.cpp | 504 ------- lib/CodeGen/AsmPrinter/Win64Exception.h | 61 - lib/CodeGen/AsmPrinter/WinCodeViewLineTables.cpp | 6 +- lib/CodeGen/AsmPrinter/WinException.cpp | 543 +++++++ lib/CodeGen/AsmPrinter/WinException.h | 69 + lib/CodeGen/CMakeLists.txt | 2 + lib/CodeGen/CodeGenPrepare.cpp | 66 +- lib/CodeGen/CriticalAntiDepBreaker.cpp | 2 +- lib/CodeGen/EarlyIfConversion.cpp | 22 +- lib/CodeGen/GlobalMerge.cpp | 24 +- lib/CodeGen/IfConversion.cpp | 13 +- lib/CodeGen/LLVMBuild.txt | 2 +- lib/CodeGen/LLVMTargetMachine.cpp | 7 +- lib/CodeGen/LiveIntervalAnalysis.cpp | 20 +- lib/CodeGen/LiveRangeEdit.cpp | 21 +- lib/CodeGen/MIRParser/CMakeLists.txt | 5 + lib/CodeGen/MIRParser/LLVMBuild.txt | 22 + lib/CodeGen/MIRParser/MIRParser.cpp | 171 +++ lib/CodeGen/MIRParser/Makefile | 13 + lib/CodeGen/MIRPrintingPass.cpp | 109 ++ lib/CodeGen/MachineCopyPropagation.cpp | 28 +- lib/CodeGen/MachineFunction.cpp | 50 +- lib/CodeGen/MachineInstr.cpp | 5 +- lib/CodeGen/MachineInstrBundle.cpp | 13 +- lib/CodeGen/MachineLICM.cpp | 6 +- lib/CodeGen/MachineModuleInfo.cpp | 3 +- lib/CodeGen/MachineSink.cpp | 4 + lib/CodeGen/MachineTraceMetrics.cpp | 49 +- lib/CodeGen/MachineVerifier.cpp | 2 +- lib/CodeGen/Makefile | 2 +- lib/CodeGen/Passes.cpp | 34 +- lib/CodeGen/ProcessImplicitDefs.cpp | 14 +- lib/CodeGen/RegisterCoalescer.cpp | 26 +- lib/CodeGen/RegisterPressure.cpp | 4 +- lib/CodeGen/RegisterScavenging.cpp | 3 +- lib/CodeGen/ScheduleDAGInstrs.cpp | 12 +- lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 42 +- lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp | 374 +---- lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp | 33 +- lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp | 2 +- lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 37 +- lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | 67 +- lib/CodeGen/SelectionDAG/StatepointLowering.cpp | 11 - lib/CodeGen/SelectionDAG/TargetLowering.cpp | 2 +- lib/CodeGen/StackMaps.cpp | 6 +- lib/CodeGen/TargetInstrInfo.cpp | 15 +- lib/CodeGen/TargetLoweringBase.cpp | 3 +- lib/CodeGen/TargetLoweringObjectFileImpl.cpp | 23 +- lib/CodeGen/VirtRegMap.cpp | 16 +- lib/CodeGen/WinEHPrepare.cpp | 374 +++++ lib/DebugInfo/DWARF/DWARFContext.cpp | 4 +- lib/DebugInfo/DWARF/DWARFDebugLine.cpp | 132 +- lib/ExecutionEngine/ExecutionEngine.cpp | 2 +- lib/ExecutionEngine/ExecutionEngineBindings.cpp | 8 +- .../IntelJITEvents/IntelJITEventListener.cpp | 3 +- lib/ExecutionEngine/Interpreter/Execution.cpp | 2 +- lib/ExecutionEngine/LLVMBuild.txt | 2 +- lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp | 24 +- lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp | 311 ++++- lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h | 25 +- lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h | 7 + .../RuntimeDyld/Targets/RuntimeDyldMachOI386.h | 11 +- lib/Fuzzer/FuzzerInterface.h | 4 +- lib/Fuzzer/FuzzerLoop.cpp | 8 +- lib/Fuzzer/FuzzerTraceState.cpp | 4 +- lib/IR/AsmWriter.cpp | 52 +- lib/IR/ConstantFold.cpp | 6 +- lib/IR/Core.cpp | 5 + lib/IR/Instructions.cpp | 5 +- lib/IR/LLVMContext.cpp | 11 +- lib/IR/LLVMContextImpl.h | 2 + lib/IR/LegacyPassManager.cpp | 89 +- lib/IR/MDBuilder.cpp | 15 +- lib/IR/Metadata.cpp | 14 +- lib/IR/Type.cpp | 13 +- lib/IR/Value.cpp | 35 +- lib/LTO/LTOCodeGenerator.cpp | 21 +- lib/MC/CMakeLists.txt | 2 +- lib/MC/ConstantPools.cpp | 2 +- lib/MC/ELFObjectWriter.cpp | 552 +++----- lib/MC/MCAsmBackend.cpp | 44 +- lib/MC/MCAsmInfo.cpp | 28 +- lib/MC/MCAsmStreamer.cpp | 124 +- lib/MC/MCAssembler.cpp | 110 +- lib/MC/MCContext.cpp | 71 +- lib/MC/MCDisassembler/MCExternalSymbolizer.cpp | 20 +- lib/MC/MCDwarf.cpp | 22 +- lib/MC/MCELF.cpp | 85 -- lib/MC/MCELFObjectTargetWriter.cpp | 2 +- lib/MC/MCELFStreamer.cpp | 143 +- lib/MC/MCExpr.cpp | 108 +- lib/MC/MCInstPrinter.cpp | 9 + lib/MC/MCLinkerOptimizationHint.cpp | 2 +- lib/MC/MCMachOStreamer.cpp | 85 +- lib/MC/MCMachObjectTargetWriter.cpp | 13 +- lib/MC/MCObjectFileInfo.cpp | 27 +- lib/MC/MCObjectStreamer.cpp | 77 +- lib/MC/MCObjectWriter.cpp | 10 +- lib/MC/MCParser/AsmParser.cpp | 51 +- lib/MC/MCParser/COFFAsmParser.cpp | 19 +- lib/MC/MCParser/ELFAsmParser.cpp | 16 +- lib/MC/MCSection.cpp | 3 +- lib/MC/MCSectionCOFF.cpp | 2 +- lib/MC/MCSectionELF.cpp | 13 +- lib/MC/MCStreamer.cpp | 17 +- lib/MC/MCSubtargetInfo.cpp | 5 + lib/MC/MCSymbol.cpp | 40 +- lib/MC/MCSymbolELF.cpp | 213 +++ lib/MC/MCWin64EH.cpp | 18 +- lib/MC/MachObjectWriter.cpp | 376 +++-- lib/MC/SubtargetFeature.cpp | 79 +- lib/MC/WinCOFFObjectWriter.cpp | 239 ++-- lib/MC/WinCOFFStreamer.cpp | 64 +- lib/Object/Archive.cpp | 12 +- lib/Object/ArchiveWriter.cpp | 342 +++++ lib/Object/CMakeLists.txt | 1 + lib/Object/COFFObjectFile.cpp | 146 +- lib/Object/ELFObjectFile.cpp | 53 +- lib/Object/Error.cpp | 7 +- lib/Object/IRObjectFile.cpp | 4 +- lib/Object/MachOObjectFile.cpp | 518 ++----- lib/Object/MachOUniversal.cpp | 2 +- lib/Object/Object.cpp | 13 +- lib/Object/ObjectFile.cpp | 8 +- lib/ProfileData/CoverageMappingReader.cpp | 5 + lib/Support/Debug.cpp | 4 +- lib/Support/DynamicLibrary.cpp | 9 + lib/Support/SmallVector.cpp | 1 + lib/Support/TargetParser.cpp | 292 ++-- lib/Support/Triple.cpp | 102 +- lib/Support/YAMLTraits.cpp | 11 +- lib/Support/raw_ostream.cpp | 2 +- lib/TableGen/Record.cpp | 662 +++++---- lib/TableGen/TGParser.cpp | 45 +- lib/Target/AArch64/AArch64AsmPrinter.cpp | 2 +- lib/Target/AArch64/AArch64ISelDAGToDAG.cpp | 127 ++ lib/Target/AArch64/AArch64ISelLowering.cpp | 225 ++- lib/Target/AArch64/AArch64ISelLowering.h | 13 +- lib/Target/AArch64/AArch64InstrFormats.td | 249 +++- lib/Target/AArch64/AArch64InstrInfo.cpp | 7 +- lib/Target/AArch64/AArch64InstrInfo.h | 1 + lib/Target/AArch64/AArch64InstrInfo.td | 97 +- lib/Target/AArch64/AArch64MCInstLower.cpp | 16 +- lib/Target/AArch64/AArch64RegisterInfo.td | 41 + lib/Target/AArch64/AArch64TargetMachine.cpp | 10 +- lib/Target/AArch64/AArch64TargetObjectFile.cpp | 12 +- lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp | 119 +- .../AArch64/Disassembler/AArch64Disassembler.cpp | 40 + .../Disassembler/AArch64ExternalSymbolizer.cpp | 22 +- lib/Target/AArch64/Disassembler/LLVMBuild.txt | 2 +- .../AArch64/InstPrinter/AArch64InstPrinter.cpp | 48 +- .../AArch64/InstPrinter/AArch64InstPrinter.h | 4 + lib/Target/AArch64/LLVMBuild.txt | 2 +- .../AArch64/MCTargetDesc/AArch64AsmBackend.cpp | 4 +- .../AArch64/MCTargetDesc/AArch64ELFStreamer.cpp | 18 +- .../AArch64/MCTargetDesc/AArch64MCAsmInfo.cpp | 9 +- lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.h | 7 +- .../AArch64/MCTargetDesc/AArch64MCCodeEmitter.cpp | 13 +- lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.cpp | 18 +- lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.h | 8 +- .../AArch64/MCTargetDesc/AArch64MCTargetDesc.cpp | 6 +- .../MCTargetDesc/AArch64MachObjectWriter.cpp | 31 +- lib/Target/AArch64/Utils/AArch64BaseInfo.cpp | 1 + lib/Target/AArch64/Utils/AArch64BaseInfo.h | 1 + lib/Target/ARM/ARM.h | 5 +- lib/Target/ARM/ARMAsmPrinter.cpp | 216 ++- lib/Target/ARM/ARMAsmPrinter.h | 5 +- lib/Target/ARM/ARMBaseInstrInfo.cpp | 40 +- lib/Target/ARM/ARMConstantIslandPass.cpp | 429 ++++-- lib/Target/ARM/ARMISelDAGToDAG.cpp | 458 +++++- lib/Target/ARM/ARMISelLowering.cpp | 51 +- lib/Target/ARM/ARMISelLowering.h | 30 +- lib/Target/ARM/ARMInstrInfo.td | 43 +- lib/Target/ARM/ARMInstrThumb.td | 1 + lib/Target/ARM/ARMInstrThumb2.td | 32 +- lib/Target/ARM/ARMLoadStoreOptimizer.cpp | 120 +- lib/Target/ARM/ARMMCInstLower.cpp | 18 +- lib/Target/ARM/ARMTargetMachine.cpp | 38 +- lib/Target/ARM/ARMTargetObjectFile.cpp | 4 +- lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 149 +- lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp | 14 +- lib/Target/ARM/MCTargetDesc/ARMAddressingModes.h | 2 - lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp | 17 +- lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp | 4 +- lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp | 54 +- lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.cpp | 6 +- lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.h | 5 +- lib/Target/ARM/MCTargetDesc/ARMMCExpr.cpp | 6 +- lib/Target/ARM/MCTargetDesc/ARMMCExpr.h | 18 +- lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp | 9 +- .../ARM/MCTargetDesc/ARMMachORelocationInfo.cpp | 4 +- .../ARM/MCTargetDesc/ARMMachObjectWriter.cpp | 37 +- lib/Target/ARM/Thumb2ITBlockPass.cpp | 8 +- lib/Target/ARM/Thumb2SizeReduction.cpp | 15 +- lib/Target/BPF/BPFAsmPrinter.cpp | 4 +- lib/Target/BPF/BPFMCInstLower.cpp | 4 +- lib/Target/BPF/BPFTargetMachine.cpp | 19 +- lib/Target/BPF/MCTargetDesc/BPFAsmBackend.cpp | 26 +- lib/Target/BPF/MCTargetDesc/BPFELFObjectWriter.cpp | 5 +- lib/Target/BPF/MCTargetDesc/BPFMCAsmInfo.h | 7 +- lib/Target/BPF/MCTargetDesc/BPFMCCodeEmitter.cpp | 82 +- lib/Target/BPF/MCTargetDesc/BPFMCTargetDesc.cpp | 51 +- lib/Target/BPF/MCTargetDesc/BPFMCTargetDesc.h | 10 +- lib/Target/BPF/TargetInfo/BPFTargetInfo.cpp | 14 +- lib/Target/CMakeLists.txt | 1 + lib/Target/CppBackend/CPPBackend.cpp | 11 +- .../Hexagon/Disassembler/HexagonDisassembler.cpp | 790 ++++++++++- lib/Target/Hexagon/Hexagon.h | 7 + lib/Target/Hexagon/HexagonAsmPrinter.cpp | 70 +- lib/Target/Hexagon/HexagonFrameLowering.cpp | 8 +- lib/Target/Hexagon/HexagonISelLowering.cpp | 3 +- lib/Target/Hexagon/HexagonISelLowering.h | 3 +- lib/Target/Hexagon/HexagonInstrFormats.td | 2 - lib/Target/Hexagon/HexagonInstrFormatsV4.td | 5 + lib/Target/Hexagon/HexagonInstrInfo.cpp | 7 +- lib/Target/Hexagon/HexagonInstrInfo.h | 2 + lib/Target/Hexagon/HexagonInstrInfoV4.td | 4 + lib/Target/Hexagon/HexagonIsetDx.td | 728 ++++++++++ lib/Target/Hexagon/HexagonMCInstLower.cpp | 27 +- lib/Target/Hexagon/HexagonOperands.td | 8 + lib/Target/Hexagon/MCTargetDesc/CMakeLists.txt | 4 + .../Hexagon/MCTargetDesc/HexagonAsmBackend.cpp | 269 +++- lib/Target/Hexagon/MCTargetDesc/HexagonBaseInfo.h | 22 +- .../MCTargetDesc/HexagonELFObjectWriter.cpp | 306 +++- .../Hexagon/MCTargetDesc/HexagonInstPrinter.cpp | 118 +- .../Hexagon/MCTargetDesc/HexagonInstPrinter.h | 19 +- .../Hexagon/MCTargetDesc/HexagonMCAsmInfo.cpp | 2 +- lib/Target/Hexagon/MCTargetDesc/HexagonMCAsmInfo.h | 4 +- .../Hexagon/MCTargetDesc/HexagonMCCodeEmitter.cpp | 221 ++- .../Hexagon/MCTargetDesc/HexagonMCCodeEmitter.h | 10 + .../Hexagon/MCTargetDesc/HexagonMCCompound.cpp | 420 ++++++ .../Hexagon/MCTargetDesc/HexagonMCDuplexInfo.cpp | 1100 +++++++++++++++ .../Hexagon/MCTargetDesc/HexagonMCInstrInfo.cpp | 271 +++- .../Hexagon/MCTargetDesc/HexagonMCInstrInfo.h | 154 +- .../Hexagon/MCTargetDesc/HexagonMCShuffler.cpp | 237 ++++ .../Hexagon/MCTargetDesc/HexagonMCShuffler.h | 65 + .../Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp | 10 +- .../Hexagon/MCTargetDesc/HexagonMCTargetDesc.h | 4 + .../Hexagon/MCTargetDesc/HexagonShuffler.cpp | 385 +++++ lib/Target/Hexagon/MCTargetDesc/HexagonShuffler.h | 139 ++ .../MSP430/InstPrinter/MSP430InstPrinter.cpp | 7 +- lib/Target/MSP430/MCTargetDesc/LLVMBuild.txt | 2 +- lib/Target/MSP430/MCTargetDesc/MSP430MCAsmInfo.cpp | 3 +- lib/Target/MSP430/MCTargetDesc/MSP430MCAsmInfo.h | 4 +- lib/Target/MSP430/MSP430AsmPrinter.cpp | 4 +- lib/Target/MSP430/MSP430MCInstLower.cpp | 8 +- lib/Target/Mips/AsmParser/MipsAsmParser.cpp | 98 +- lib/Target/Mips/Disassembler/MipsDisassembler.cpp | 12 + lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp | 9 +- lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp | 4 + lib/Target/Mips/MCTargetDesc/MipsABIInfo.h | 1 + .../Mips/MCTargetDesc/MipsELFObjectWriter.cpp | 182 +-- lib/Target/Mips/MCTargetDesc/MipsELFStreamer.cpp | 12 +- lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.cpp | 3 +- lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.h | 4 +- lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp | 2 +- lib/Target/Mips/MCTargetDesc/MipsMCExpr.cpp | 10 +- lib/Target/Mips/MCTargetDesc/MipsMCExpr.h | 10 +- lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp | 3 +- .../Mips/MCTargetDesc/MipsTargetStreamer.cpp | 62 +- lib/Target/Mips/Mips64InstrInfo.td | 12 +- lib/Target/Mips/MipsAsmPrinter.cpp | 19 +- lib/Target/Mips/MipsFastISel.cpp | 301 +++- lib/Target/Mips/MipsFrameLowering.cpp | 17 +- lib/Target/Mips/MipsFrameLowering.h | 2 + lib/Target/Mips/MipsISelLowering.cpp | 3 +- lib/Target/Mips/MipsISelLowering.h | 3 +- lib/Target/Mips/MipsInstrFormats.td | 12 + lib/Target/Mips/MipsMCInstLower.cpp | 14 +- lib/Target/Mips/MipsRegisterInfo.cpp | 71 + lib/Target/Mips/MipsRegisterInfo.h | 8 + lib/Target/Mips/MipsSEFrameLowering.cpp | 34 +- lib/Target/Mips/MipsSERegisterInfo.cpp | 12 +- lib/Target/Mips/MipsTargetStreamer.h | 4 + lib/Target/Mips/TargetInfo/MipsTargetInfo.cpp | 4 +- lib/Target/NVPTX/CMakeLists.txt | 2 +- lib/Target/NVPTX/InstPrinter/NVPTXInstPrinter.cpp | 2 +- lib/Target/NVPTX/MCTargetDesc/NVPTXMCAsmInfo.cpp | 3 +- lib/Target/NVPTX/MCTargetDesc/NVPTXMCAsmInfo.h | 4 +- lib/Target/NVPTX/NVPTX.h | 2 +- lib/Target/NVPTX/NVPTXAsmPrinter.cpp | 143 +- lib/Target/NVPTX/NVPTXAsmPrinter.h | 4 +- .../NVPTX/NVPTXFavorNonGenericAddrSpaces.cpp | 207 ++- lib/Target/NVPTX/NVPTXISelDAGToDAG.cpp | 4 + lib/Target/NVPTX/NVPTXISelLowering.cpp | 3 +- lib/Target/NVPTX/NVPTXISelLowering.h | 9 +- lib/Target/NVPTX/NVPTXLowerKernelArgs.cpp | 170 +++ lib/Target/NVPTX/NVPTXLowerStructArgs.cpp | 136 -- lib/Target/NVPTX/NVPTXMCExpr.cpp | 13 +- lib/Target/NVPTX/NVPTXMCExpr.h | 24 +- lib/Target/NVPTX/NVPTXTargetMachine.cpp | 13 +- lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp | 39 +- lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp | 2 +- lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp | 19 +- .../PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp | 8 +- .../PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp | 30 +- lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.cpp | 24 +- lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.h | 26 +- .../PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp | 50 +- .../PowerPC/MCTargetDesc/PPCMachObjectWriter.cpp | 31 +- lib/Target/PowerPC/PPCAsmPrinter.cpp | 116 +- lib/Target/PowerPC/PPCFastISel.cpp | 27 +- lib/Target/PowerPC/PPCISelLowering.cpp | 3 +- lib/Target/PowerPC/PPCISelLowering.h | 3 +- lib/Target/PowerPC/PPCInstrVSX.td | 76 + lib/Target/PowerPC/PPCMCInstLower.cpp | 16 +- lib/Target/PowerPC/PPCTargetObjectFile.cpp | 6 +- lib/Target/PowerPC/PPCTargetStreamer.h | 2 +- lib/Target/R600/AMDGPU.h | 7 +- lib/Target/R600/AMDGPUISelLowering.cpp | 58 +- lib/Target/R600/AMDGPUISelLowering.h | 4 - lib/Target/R600/AMDGPUInstrInfo.cpp | 14 +- lib/Target/R600/AMDGPUInstrInfo.h | 2 + lib/Target/R600/AMDGPUInstrInfo.td | 10 - lib/Target/R600/AMDGPUMCInstLower.cpp | 8 +- lib/Target/R600/AMDGPUSubtarget.h | 2 +- lib/Target/R600/AsmParser/AMDGPUAsmParser.cpp | 2 +- lib/Target/R600/InstPrinter/AMDGPUInstPrinter.cpp | 2 +- lib/Target/R600/MCTargetDesc/AMDGPUAsmBackend.cpp | 8 +- lib/Target/R600/MCTargetDesc/AMDGPUMCAsmInfo.cpp | 2 +- lib/Target/R600/MCTargetDesc/AMDGPUMCAsmInfo.h | 4 +- lib/Target/R600/MCTargetDesc/R600MCCodeEmitter.cpp | 9 +- lib/Target/R600/R600Instructions.td | 8 +- lib/Target/R600/SIISelLowering.cpp | 159 ++- lib/Target/R600/SIISelLowering.h | 2 +- lib/Target/R600/SIInstructions.td | 8 +- lib/Target/Sparc/AsmParser/SparcAsmParser.cpp | 12 +- lib/Target/Sparc/InstPrinter/SparcInstPrinter.cpp | 2 +- lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp | 2 +- lib/Target/Sparc/MCTargetDesc/SparcMCAsmInfo.cpp | 11 +- lib/Target/Sparc/MCTargetDesc/SparcMCAsmInfo.h | 4 +- .../Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp | 12 +- lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp | 19 +- lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h | 10 +- .../Sparc/MCTargetDesc/SparcMCTargetDesc.cpp | 4 +- lib/Target/Sparc/SparcAsmPrinter.cpp | 24 +- lib/Target/Sparc/SparcMCInstLower.cpp | 4 +- lib/Target/Sparc/SparcTargetObjectFile.cpp | 4 +- lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp | 6 +- .../SystemZ/InstPrinter/SystemZInstPrinter.cpp | 9 +- .../SystemZ/InstPrinter/SystemZInstPrinter.h | 3 +- .../SystemZ/MCTargetDesc/SystemZMCAsmBackend.cpp | 2 +- .../SystemZ/MCTargetDesc/SystemZMCAsmInfo.cpp | 2 +- lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmInfo.h | 4 +- .../SystemZ/MCTargetDesc/SystemZMCCodeEmitter.cpp | 6 +- .../SystemZ/MCTargetDesc/SystemZMCTargetDesc.cpp | 2 +- lib/Target/SystemZ/SystemZAsmPrinter.cpp | 8 +- lib/Target/SystemZ/SystemZISelLowering.cpp | 5 +- lib/Target/SystemZ/SystemZISelLowering.h | 3 +- lib/Target/SystemZ/SystemZInstrInfo.cpp | 73 +- lib/Target/SystemZ/SystemZInstrInfo.h | 2 + lib/Target/SystemZ/SystemZMCInstLower.cpp | 6 +- lib/Target/TargetLoweringObjectFile.cpp | 8 +- lib/Target/TargetRecip.cpp | 225 +++ lib/Target/X86/AsmParser/X86AsmInstrumentation.cpp | 42 +- lib/Target/X86/AsmParser/X86AsmParser.cpp | 34 +- lib/Target/X86/Disassembler/X86Disassembler.cpp | 3 + .../Disassembler/X86DisassemblerDecoderCommon.h | 1 + lib/Target/X86/InstPrinter/X86ATTInstPrinter.cpp | 12 +- lib/Target/X86/InstPrinter/X86IntelInstPrinter.cpp | 10 +- lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp | 6 +- lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp | 1 + .../X86/MCTargetDesc/X86ELFRelocationInfo.cpp | 24 +- lib/Target/X86/MCTargetDesc/X86MCAsmInfo.cpp | 11 +- lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp | 4 +- lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp | 4 +- .../X86/MCTargetDesc/X86MachORelocationInfo.cpp | 30 +- .../X86/MCTargetDesc/X86MachObjectWriter.cpp | 53 +- lib/Target/X86/X86.td | 12 +- lib/Target/X86/X86AsmPrinter.cpp | 25 +- lib/Target/X86/X86FastISel.cpp | 21 +- lib/Target/X86/X86ISelLowering.cpp | 1474 +++++++++++--------- lib/Target/X86/X86ISelLowering.h | 26 +- lib/Target/X86/X86InstrAVX512.td | 446 ++++-- lib/Target/X86/X86InstrFormats.td | 8 + lib/Target/X86/X86InstrFragmentsSIMD.td | 19 +- lib/Target/X86/X86InstrInfo.cpp | 95 +- lib/Target/X86/X86InstrInfo.h | 3 + lib/Target/X86/X86InstrInfo.td | 4 + lib/Target/X86/X86InstrMPX.td | 70 + lib/Target/X86/X86InstrSSE.td | 26 +- lib/Target/X86/X86IntrinsicsInfo.h | 29 +- lib/Target/X86/X86MCInstLower.cpp | 41 +- lib/Target/X86/X86RegisterInfo.cpp | 4 +- lib/Target/X86/X86RegisterInfo.td | 8 + lib/Target/X86/X86Subtarget.cpp | 3 +- lib/Target/X86/X86Subtarget.h | 16 +- lib/Target/X86/X86TargetMachine.cpp | 11 +- lib/Target/X86/X86TargetObjectFile.cpp | 16 +- lib/Target/X86/X86WinEHState.cpp | 311 +++-- lib/Target/XCore/InstPrinter/XCoreInstPrinter.cpp | 7 +- lib/Target/XCore/MCTargetDesc/XCoreMCAsmInfo.cpp | 3 +- lib/Target/XCore/MCTargetDesc/XCoreMCAsmInfo.h | 14 +- .../XCore/MCTargetDesc/XCoreMCTargetDesc.cpp | 2 +- lib/Target/XCore/XCoreAsmPrinter.cpp | 15 +- lib/Target/XCore/XCoreISelLowering.cpp | 3 +- lib/Target/XCore/XCoreISelLowering.h | 3 +- lib/Target/XCore/XCoreMCInstLower.cpp | 6 +- lib/Transforms/IPO/ArgumentPromotion.cpp | 4 +- lib/Transforms/IPO/FunctionAttrs.cpp | 6 +- lib/Transforms/IPO/MergeFunctions.cpp | 48 +- lib/Transforms/InstCombine/InstCombineCompares.cpp | 2 + .../InstCombine/InstCombineLoadStoreAlloca.cpp | 15 +- lib/Transforms/InstCombine/InstCombineSelect.cpp | 104 +- .../InstCombine/InstructionCombining.cpp | 10 +- .../Instrumentation/AddressSanitizer.cpp | 267 ++-- lib/Transforms/Instrumentation/InstrProfiling.cpp | 26 +- lib/Transforms/ObjCARC/ObjCARCContract.cpp | 2 +- .../Scalar/CorrelatedValuePropagation.cpp | 7 +- lib/Transforms/Scalar/DeadStoreElimination.cpp | 12 +- lib/Transforms/Scalar/IndVarSimplify.cpp | 152 +- lib/Transforms/Scalar/LoopStrengthReduce.cpp | 10 +- lib/Transforms/Scalar/LoopUnrollPass.cpp | 517 +++---- lib/Transforms/Scalar/MemCpyOptimizer.cpp | 24 +- lib/Transforms/Scalar/MergedLoadStoreMotion.cpp | 10 +- lib/Transforms/Scalar/NaryReassociate.cpp | 28 +- lib/Transforms/Scalar/PlaceSafepoints.cpp | 2 +- lib/Transforms/Scalar/Reassociate.cpp | 58 +- lib/Transforms/Scalar/RewriteStatepointsForGC.cpp | 131 +- .../Scalar/SeparateConstOffsetFromGEP.cpp | 4 +- lib/Transforms/Scalar/SimplifyCFGPass.cpp | 15 +- lib/Transforms/Scalar/Sink.cpp | 8 +- lib/Transforms/Utils/LoopUtils.cpp | 3 + lib/Transforms/Utils/PromoteMemoryToRegister.cpp | 4 +- lib/Transforms/Utils/SimplifyIndVar.cpp | 10 +- lib/Transforms/Utils/ValueMapper.cpp | 5 +- lib/Transforms/Vectorize/LoopVectorize.cpp | 701 +++++++++- lib/Transforms/Vectorize/SLPVectorizer.cpp | 6 +- 463 files changed, 18480 insertions(+), 8524 deletions(-) create mode 100644 lib/Analysis/MemoryLocation.cpp delete mode 100644 lib/CodeGen/AsmPrinter/Win64Exception.cpp delete mode 100644 lib/CodeGen/AsmPrinter/Win64Exception.h create mode 100644 lib/CodeGen/AsmPrinter/WinException.cpp create mode 100644 lib/CodeGen/AsmPrinter/WinException.h create mode 100644 lib/CodeGen/MIRParser/CMakeLists.txt create mode 100644 lib/CodeGen/MIRParser/LLVMBuild.txt create mode 100644 lib/CodeGen/MIRParser/MIRParser.cpp create mode 100644 lib/CodeGen/MIRParser/Makefile create mode 100644 lib/CodeGen/MIRPrintingPass.cpp delete mode 100644 lib/MC/MCELF.cpp create mode 100644 lib/MC/MCSymbolELF.cpp create mode 100644 lib/Object/ArchiveWriter.cpp create mode 100644 lib/Target/Hexagon/HexagonIsetDx.td create mode 100644 lib/Target/Hexagon/MCTargetDesc/HexagonMCCompound.cpp create mode 100644 lib/Target/Hexagon/MCTargetDesc/HexagonMCDuplexInfo.cpp create mode 100644 lib/Target/Hexagon/MCTargetDesc/HexagonMCShuffler.cpp create mode 100644 lib/Target/Hexagon/MCTargetDesc/HexagonMCShuffler.h create mode 100644 lib/Target/Hexagon/MCTargetDesc/HexagonShuffler.cpp create mode 100644 lib/Target/Hexagon/MCTargetDesc/HexagonShuffler.h create mode 100644 lib/Target/NVPTX/NVPTXLowerKernelArgs.cpp delete mode 100644 lib/Target/NVPTX/NVPTXLowerStructArgs.cpp create mode 100644 lib/Target/TargetRecip.cpp create mode 100644 lib/Target/X86/X86InstrMPX.td (limited to 'lib') diff --git a/lib/Analysis/AliasAnalysis.cpp b/lib/Analysis/AliasAnalysis.cpp index f54e234bbeadf..ce46d53005171 100644 --- a/lib/Analysis/AliasAnalysis.cpp +++ b/lib/Analysis/AliasAnalysis.cpp @@ -93,7 +93,7 @@ AliasAnalysis::getModRefInfo(Instruction *I, ImmutableCallSite Call) { // location this memory access defines. The best we can say // is that if the call references what this instruction // defines, it must be clobbered by this location. - const AliasAnalysis::Location DefLoc = AA->getLocation(I); + const AliasAnalysis::Location DefLoc = MemoryLocation::get(I); if (getModRefInfo(Call, DefLoc) != AliasAnalysis::NoModRef) return AliasAnalysis::ModRef; } @@ -267,78 +267,6 @@ AliasAnalysis::getModRefBehavior(const Function *F) { // AliasAnalysis non-virtual helper method implementation //===----------------------------------------------------------------------===// -AliasAnalysis::Location AliasAnalysis::getLocation(const LoadInst *LI) { - AAMDNodes AATags; - LI->getAAMetadata(AATags); - - return Location(LI->getPointerOperand(), - getTypeStoreSize(LI->getType()), AATags); -} - -AliasAnalysis::Location AliasAnalysis::getLocation(const StoreInst *SI) { - AAMDNodes AATags; - SI->getAAMetadata(AATags); - - return Location(SI->getPointerOperand(), - getTypeStoreSize(SI->getValueOperand()->getType()), AATags); -} - -AliasAnalysis::Location AliasAnalysis::getLocation(const VAArgInst *VI) { - AAMDNodes AATags; - VI->getAAMetadata(AATags); - - return Location(VI->getPointerOperand(), UnknownSize, AATags); -} - -AliasAnalysis::Location -AliasAnalysis::getLocation(const AtomicCmpXchgInst *CXI) { - AAMDNodes AATags; - CXI->getAAMetadata(AATags); - - return Location(CXI->getPointerOperand(), - getTypeStoreSize(CXI->getCompareOperand()->getType()), - AATags); -} - -AliasAnalysis::Location -AliasAnalysis::getLocation(const AtomicRMWInst *RMWI) { - AAMDNodes AATags; - RMWI->getAAMetadata(AATags); - - return Location(RMWI->getPointerOperand(), - getTypeStoreSize(RMWI->getValOperand()->getType()), AATags); -} - -AliasAnalysis::Location -AliasAnalysis::getLocationForSource(const MemTransferInst *MTI) { - uint64_t Size = UnknownSize; - if (ConstantInt *C = dyn_cast(MTI->getLength())) - Size = C->getValue().getZExtValue(); - - // memcpy/memmove can have AA tags. For memcpy, they apply - // to both the source and the destination. - AAMDNodes AATags; - MTI->getAAMetadata(AATags); - - return Location(MTI->getRawSource(), Size, AATags); -} - -AliasAnalysis::Location -AliasAnalysis::getLocationForDest(const MemIntrinsic *MTI) { - uint64_t Size = UnknownSize; - if (ConstantInt *C = dyn_cast(MTI->getLength())) - Size = C->getValue().getZExtValue(); - - // memcpy/memmove can have AA tags. For memcpy, they apply - // to both the source and the destination. - AAMDNodes AATags; - MTI->getAAMetadata(AATags); - - return Location(MTI->getRawDest(), Size, AATags); -} - - - AliasAnalysis::ModRefResult AliasAnalysis::getModRefInfo(const LoadInst *L, const Location &Loc) { // Be conservative in the face of volatile/atomic. @@ -347,7 +275,7 @@ AliasAnalysis::getModRefInfo(const LoadInst *L, const Location &Loc) { // If the load address doesn't alias the given address, it doesn't read // or write the specified memory. - if (Loc.Ptr && !alias(getLocation(L), Loc)) + if (Loc.Ptr && !alias(MemoryLocation::get(L), Loc)) return NoModRef; // Otherwise, a load just reads. @@ -363,7 +291,7 @@ AliasAnalysis::getModRefInfo(const StoreInst *S, const Location &Loc) { if (Loc.Ptr) { // If the store address cannot alias the pointer in question, then the // specified memory cannot be modified by the store. - if (!alias(getLocation(S), Loc)) + if (!alias(MemoryLocation::get(S), Loc)) return NoModRef; // If the pointer is a pointer to constant memory, then it could not have @@ -383,7 +311,7 @@ AliasAnalysis::getModRefInfo(const VAArgInst *V, const Location &Loc) { if (Loc.Ptr) { // If the va_arg address cannot alias the pointer in question, then the // specified memory cannot be accessed by the va_arg. - if (!alias(getLocation(V), Loc)) + if (!alias(MemoryLocation::get(V), Loc)) return NoModRef; // If the pointer is a pointer to constant memory, then it could not have @@ -403,7 +331,7 @@ AliasAnalysis::getModRefInfo(const AtomicCmpXchgInst *CX, const Location &Loc) { return ModRef; // If the cmpxchg address does not alias the location, it does not access it. - if (Loc.Ptr && !alias(getLocation(CX), Loc)) + if (Loc.Ptr && !alias(MemoryLocation::get(CX), Loc)) return NoModRef; return ModRef; @@ -416,7 +344,7 @@ AliasAnalysis::getModRefInfo(const AtomicRMWInst *RMW, const Location &Loc) { return ModRef; // If the atomicrmw address does not alias the location, it does not access it. - if (Loc.Ptr && !alias(getLocation(RMW), Loc)) + if (Loc.Ptr && !alias(MemoryLocation::get(RMW), Loc)) return NoModRef; return ModRef; diff --git a/lib/Analysis/AliasAnalysisEvaluator.cpp b/lib/Analysis/AliasAnalysisEvaluator.cpp index 273eacc16e724..dd6a3a0715e16 100644 --- a/lib/Analysis/AliasAnalysisEvaluator.cpp +++ b/lib/Analysis/AliasAnalysisEvaluator.cpp @@ -219,8 +219,8 @@ bool AAEval::runOnFunction(Function &F) { I1 != E; ++I1) { for (SetVector::iterator I2 = Stores.begin(), E2 = Stores.end(); I2 != E2; ++I2) { - switch (AA.alias(AA.getLocation(cast(*I1)), - AA.getLocation(cast(*I2)))) { + switch (AA.alias(MemoryLocation::get(cast(*I1)), + MemoryLocation::get(cast(*I2)))) { case AliasAnalysis::NoAlias: PrintLoadStoreResults("NoAlias", PrintNoAlias, *I1, *I2, F.getParent()); @@ -245,8 +245,8 @@ bool AAEval::runOnFunction(Function &F) { for (SetVector::iterator I1 = Stores.begin(), E = Stores.end(); I1 != E; ++I1) { for (SetVector::iterator I2 = Stores.begin(); I2 != I1; ++I2) { - switch (AA.alias(AA.getLocation(cast(*I1)), - AA.getLocation(cast(*I2)))) { + switch (AA.alias(MemoryLocation::get(cast(*I1)), + MemoryLocation::get(cast(*I2)))) { case AliasAnalysis::NoAlias: PrintLoadStoreResults("NoAlias", PrintNoAlias, *I1, *I2, F.getParent()); diff --git a/lib/Analysis/AliasSetTracker.cpp b/lib/Analysis/AliasSetTracker.cpp index 50890c17f2eb9..12c1c7d4af90f 100644 --- a/lib/Analysis/AliasSetTracker.cpp +++ b/lib/Analysis/AliasSetTracker.cpp @@ -130,7 +130,7 @@ void AliasSet::addPointer(AliasSetTracker &AST, PointerRec &Entry, void AliasSet::addUnknownInst(Instruction *I, AliasAnalysis &AA) { if (UnknownInsts.empty()) addRef(); - UnknownInsts.push_back(I); + UnknownInsts.emplace_back(I); if (!I->mayWriteToMemory()) { AliasTy = MayAlias; diff --git a/lib/Analysis/BranchProbabilityInfo.cpp b/lib/Analysis/BranchProbabilityInfo.cpp index 091943bfc7b3a..430b41241edf5 100644 --- a/lib/Analysis/BranchProbabilityInfo.cpp +++ b/lib/Analysis/BranchProbabilityInfo.cpp @@ -543,6 +543,10 @@ bool BranchProbabilityInfo::runOnFunction(Function &F) { return false; } +void BranchProbabilityInfo::releaseMemory() { + Weights.clear(); +} + void BranchProbabilityInfo::print(raw_ostream &OS, const Module *) const { OS << "---- Branch Probabilities ----\n"; // We print the probabilities from the last function the analysis ran over, diff --git a/lib/Analysis/CMakeLists.txt b/lib/Analysis/CMakeLists.txt index 32fe9b9495d1a..b22ee7e24931f 100644 --- a/lib/Analysis/CMakeLists.txt +++ b/lib/Analysis/CMakeLists.txt @@ -42,6 +42,7 @@ add_llvm_library(LLVMAnalysis MemDerefPrinter.cpp MemoryBuiltins.cpp MemoryDependenceAnalysis.cpp + MemoryLocation.cpp ModuleDebugInfoPrinter.cpp NoAliasAnalysis.cpp PHITransAddr.cpp diff --git a/lib/Analysis/DependenceAnalysis.cpp b/lib/Analysis/DependenceAnalysis.cpp index 808a38b6346bd..b16cdfef33759 100644 --- a/lib/Analysis/DependenceAnalysis.cpp +++ b/lib/Analysis/DependenceAnalysis.cpp @@ -779,23 +779,56 @@ void DependenceAnalysis::collectCommonLoops(const SCEV *Expression, } } -void DependenceAnalysis::unifySubscriptType(Subscript *Pair) { - const SCEV *Src = Pair->Src; - const SCEV *Dst = Pair->Dst; - IntegerType *SrcTy = dyn_cast(Src->getType()); - IntegerType *DstTy = dyn_cast(Dst->getType()); - if (SrcTy == nullptr || DstTy == nullptr) { - assert(SrcTy == DstTy && "This function only unify integer types and " - "expect Src and Dst share the same type " - "otherwise."); - return; +void DependenceAnalysis::unifySubscriptType(ArrayRef Pairs) { + + unsigned widestWidthSeen = 0; + Type *widestType; + + // Go through each pair and find the widest bit to which we need + // to extend all of them. + for (unsigned i = 0; i < Pairs.size(); i++) { + const SCEV *Src = Pairs[i]->Src; + const SCEV *Dst = Pairs[i]->Dst; + IntegerType *SrcTy = dyn_cast(Src->getType()); + IntegerType *DstTy = dyn_cast(Dst->getType()); + if (SrcTy == nullptr || DstTy == nullptr) { + assert(SrcTy == DstTy && "This function only unify integer types and " + "expect Src and Dst share the same type " + "otherwise."); + continue; + } + if (SrcTy->getBitWidth() > widestWidthSeen) { + widestWidthSeen = SrcTy->getBitWidth(); + widestType = SrcTy; + } + if (DstTy->getBitWidth() > widestWidthSeen) { + widestWidthSeen = DstTy->getBitWidth(); + widestType = DstTy; + } } - if (SrcTy->getBitWidth() > DstTy->getBitWidth()) { - // Sign-extend Dst to typeof(Src) if typeof(Src) is wider than typeof(Dst). - Pair->Dst = SE->getSignExtendExpr(Dst, SrcTy); - } else if (SrcTy->getBitWidth() < DstTy->getBitWidth()) { - // Sign-extend Src to typeof(Dst) if typeof(Dst) is wider than typeof(Src). - Pair->Src = SE->getSignExtendExpr(Src, DstTy); + + + assert(widestWidthSeen > 0); + + // Now extend each pair to the widest seen. + for (unsigned i = 0; i < Pairs.size(); i++) { + const SCEV *Src = Pairs[i]->Src; + const SCEV *Dst = Pairs[i]->Dst; + IntegerType *SrcTy = dyn_cast(Src->getType()); + IntegerType *DstTy = dyn_cast(Dst->getType()); + if (SrcTy == nullptr || DstTy == nullptr) { + assert(SrcTy == DstTy && "This function only unify integer types and " + "expect Src and Dst share the same type " + "otherwise."); + continue; + } + if (SrcTy->getBitWidth() < widestWidthSeen) + // Sign-extend Src to widestType + Pairs[i]->Src = SE->getSignExtendExpr(Src, widestType); + if (DstTy->getBitWidth() < widestWidthSeen) { + // Sign-extend Dst to widestType + Pairs[i]->Dst = SE->getSignExtendExpr(Dst, widestType); + } } } @@ -2937,7 +2970,7 @@ const SCEV *DependenceAnalysis::getUpperBound(BoundInfo *Bound) const { // return the coefficient (the step) // corresponding to the specified loop. // If there isn't one, return 0. -// For example, given a*i + b*j + c*k, zeroing the coefficient +// For example, given a*i + b*j + c*k, finding the coefficient // corresponding to the j loop would yield b. const SCEV *DependenceAnalysis::findCoefficient(const SCEV *Expr, const Loop *TargetLoop) const { @@ -3574,13 +3607,16 @@ DependenceAnalysis::depends(Instruction *Src, Instruction *Dst, SmallBitVector Sivs(Pairs); SmallBitVector Mivs(Pairs); SmallBitVector ConstrainedLevels(MaxLevels + 1); + SmallVector PairsInGroup; for (int SJ = Group.find_first(); SJ >= 0; SJ = Group.find_next(SJ)) { DEBUG(dbgs() << SJ << " "); if (Pair[SJ].Classification == Subscript::SIV) Sivs.set(SJ); else Mivs.set(SJ); + PairsInGroup.push_back(&Pair[SJ]); } + unifySubscriptType(PairsInGroup); DEBUG(dbgs() << "}\n"); while (Sivs.any()) { bool Changed = false; diff --git a/lib/Analysis/InstructionSimplify.cpp b/lib/Analysis/InstructionSimplify.cpp index 097b99eb0a5e4..ec56d888dc2fd 100644 --- a/lib/Analysis/InstructionSimplify.cpp +++ b/lib/Analysis/InstructionSimplify.cpp @@ -3144,6 +3144,90 @@ Value *llvm::SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS, RecursionLimit); } +/// SimplifyWithOpReplaced - See if V simplifies when its operand Op is +/// replaced with RepOp. +static const Value *SimplifyWithOpReplaced(Value *V, Value *Op, Value *RepOp, + const Query &Q, + unsigned MaxRecurse) { + // Trivial replacement. + if (V == Op) + return RepOp; + + auto *I = dyn_cast(V); + if (!I) + return nullptr; + + // If this is a binary operator, try to simplify it with the replaced op. + if (auto *B = dyn_cast(I)) { + // Consider: + // %cmp = icmp eq i32 %x, 2147483647 + // %add = add nsw i32 %x, 1 + // %sel = select i1 %cmp, i32 -2147483648, i32 %add + // + // We can't replace %sel with %add unless we strip away the flags. + if (isa(B)) + if (B->hasNoSignedWrap() || B->hasNoUnsignedWrap()) + return nullptr; + if (isa(B)) + if (B->isExact()) + return nullptr; + + if (MaxRecurse) { + if (B->getOperand(0) == Op) + return SimplifyBinOp(B->getOpcode(), RepOp, B->getOperand(1), Q, + MaxRecurse - 1); + if (B->getOperand(1) == Op) + return SimplifyBinOp(B->getOpcode(), B->getOperand(0), RepOp, Q, + MaxRecurse - 1); + } + } + + // Same for CmpInsts. + if (CmpInst *C = dyn_cast(I)) { + if (MaxRecurse) { + if (C->getOperand(0) == Op) + return SimplifyCmpInst(C->getPredicate(), RepOp, C->getOperand(1), Q, + MaxRecurse - 1); + if (C->getOperand(1) == Op) + return SimplifyCmpInst(C->getPredicate(), C->getOperand(0), RepOp, Q, + MaxRecurse - 1); + } + } + + // TODO: We could hand off more cases to instsimplify here. + + // If all operands are constant after substituting Op for RepOp then we can + // constant fold the instruction. + if (Constant *CRepOp = dyn_cast(RepOp)) { + // Build a list of all constant operands. + SmallVector ConstOps; + for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) { + if (I->getOperand(i) == Op) + ConstOps.push_back(CRepOp); + else if (Constant *COp = dyn_cast(I->getOperand(i))) + ConstOps.push_back(COp); + else + break; + } + + // All operands were constants, fold it. + if (ConstOps.size() == I->getNumOperands()) { + if (CmpInst *C = dyn_cast(I)) + return ConstantFoldCompareInstOperands(C->getPredicate(), ConstOps[0], + ConstOps[1], Q.DL, Q.TLI); + + if (LoadInst *LI = dyn_cast(I)) + if (!LI->isVolatile()) + return ConstantFoldLoadFromConstPtr(ConstOps[0], Q.DL); + + return ConstantFoldInstOperands(I->getOpcode(), I->getType(), ConstOps, + Q.DL, Q.TLI); + } + } + + return nullptr; +} + /// SimplifySelectInst - Given operands for a SelectInst, see if we can fold /// the result. If not, this returns null. static Value *SimplifySelectInst(Value *CondVal, Value *TrueVal, @@ -3172,29 +3256,28 @@ static Value *SimplifySelectInst(Value *CondVal, Value *TrueVal, if (isa(FalseVal)) // select C, X, undef -> X return TrueVal; - const auto *ICI = dyn_cast(CondVal); - unsigned BitWidth = TrueVal->getType()->getScalarSizeInBits(); - if (ICI && BitWidth) { + if (const auto *ICI = dyn_cast(CondVal)) { + unsigned BitWidth = Q.DL.getTypeSizeInBits(TrueVal->getType()); ICmpInst::Predicate Pred = ICI->getPredicate(); + Value *CmpLHS = ICI->getOperand(0); + Value *CmpRHS = ICI->getOperand(1); APInt MinSignedValue = APInt::getSignBit(BitWidth); Value *X; const APInt *Y; bool TrueWhenUnset; bool IsBitTest = false; if (ICmpInst::isEquality(Pred) && - match(ICI->getOperand(0), m_And(m_Value(X), m_APInt(Y))) && - match(ICI->getOperand(1), m_Zero())) { + match(CmpLHS, m_And(m_Value(X), m_APInt(Y))) && + match(CmpRHS, m_Zero())) { IsBitTest = true; TrueWhenUnset = Pred == ICmpInst::ICMP_EQ; - } else if (Pred == ICmpInst::ICMP_SLT && - match(ICI->getOperand(1), m_Zero())) { - X = ICI->getOperand(0); + } else if (Pred == ICmpInst::ICMP_SLT && match(CmpRHS, m_Zero())) { + X = CmpLHS; Y = &MinSignedValue; IsBitTest = true; TrueWhenUnset = false; - } else if (Pred == ICmpInst::ICMP_SGT && - match(ICI->getOperand(1), m_AllOnes())) { - X = ICI->getOperand(0); + } else if (Pred == ICmpInst::ICMP_SGT && match(CmpRHS, m_AllOnes())) { + X = CmpLHS; Y = &MinSignedValue; IsBitTest = true; TrueWhenUnset = true; @@ -3225,6 +3308,50 @@ static Value *SimplifySelectInst(Value *CondVal, Value *TrueVal, return TrueWhenUnset ? TrueVal : FalseVal; } } + if (ICI->hasOneUse()) { + const APInt *C; + if (match(CmpRHS, m_APInt(C))) { + // X < MIN ? T : F --> F + if (Pred == ICmpInst::ICMP_SLT && C->isMinSignedValue()) + return FalseVal; + // X < MIN ? T : F --> F + if (Pred == ICmpInst::ICMP_ULT && C->isMinValue()) + return FalseVal; + // X > MAX ? T : F --> F + if (Pred == ICmpInst::ICMP_SGT && C->isMaxSignedValue()) + return FalseVal; + // X > MAX ? T : F --> F + if (Pred == ICmpInst::ICMP_UGT && C->isMaxValue()) + return FalseVal; + } + } + + // If we have an equality comparison then we know the value in one of the + // arms of the select. See if substituting this value into the arm and + // simplifying the result yields the same value as the other arm. + if (Pred == ICmpInst::ICMP_EQ) { + if (SimplifyWithOpReplaced(FalseVal, CmpLHS, CmpRHS, Q, MaxRecurse) == + TrueVal || + SimplifyWithOpReplaced(FalseVal, CmpRHS, CmpLHS, Q, MaxRecurse) == + TrueVal) + return FalseVal; + if (SimplifyWithOpReplaced(TrueVal, CmpLHS, CmpRHS, Q, MaxRecurse) == + FalseVal || + SimplifyWithOpReplaced(TrueVal, CmpRHS, CmpLHS, Q, MaxRecurse) == + FalseVal) + return FalseVal; + } else if (Pred == ICmpInst::ICMP_NE) { + if (SimplifyWithOpReplaced(TrueVal, CmpLHS, CmpRHS, Q, MaxRecurse) == + FalseVal || + SimplifyWithOpReplaced(TrueVal, CmpRHS, CmpLHS, Q, MaxRecurse) == + FalseVal) + return TrueVal; + if (SimplifyWithOpReplaced(FalseVal, CmpLHS, CmpRHS, Q, MaxRecurse) == + TrueVal || + SimplifyWithOpReplaced(FalseVal, CmpRHS, CmpLHS, Q, MaxRecurse) == + TrueVal) + return TrueVal; + } } return nullptr; diff --git a/lib/Analysis/LoopAccessAnalysis.cpp b/lib/Analysis/LoopAccessAnalysis.cpp index b70de00db04b5..c661c7b87dcb2 100644 --- a/lib/Analysis/LoopAccessAnalysis.cpp +++ b/lib/Analysis/LoopAccessAnalysis.cpp @@ -177,15 +177,21 @@ void LoopAccessInfo::RuntimePointerCheck::print( } } -bool LoopAccessInfo::RuntimePointerCheck::needsAnyChecking( +unsigned LoopAccessInfo::RuntimePointerCheck::getNumberOfChecks( const SmallVectorImpl *PtrPartition) const { unsigned NumPointers = Pointers.size(); + unsigned CheckCount = 0; for (unsigned I = 0; I < NumPointers; ++I) for (unsigned J = I + 1; J < NumPointers; ++J) if (needsChecking(I, J, PtrPartition)) - return true; - return false; + CheckCount++; + return CheckCount; +} + +bool LoopAccessInfo::RuntimePointerCheck::needsAnyChecking( + const SmallVectorImpl *PtrPartition) const { + return getNumberOfChecks(PtrPartition) != 0; } namespace { @@ -220,10 +226,11 @@ public: } /// \brief Check whether we can check the pointers at runtime for - /// non-intersection. + /// 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, - unsigned &NumComparisons, ScalarEvolution *SE, - Loop *TheLoop, const ValueToValueMap &Strides, + bool &NeedRTCheck, ScalarEvolution *SE, Loop *TheLoop, + const ValueToValueMap &Strides, bool ShouldCheckStride = false); /// \brief Goes over all memory accesses, checks whether a RT check is needed @@ -289,29 +296,23 @@ static bool hasComputableBounds(ScalarEvolution *SE, return AR->isAffine(); } -/// \brief Check the stride of the pointer and ensure that it does not wrap in -/// the address space. -static int isStridedPtr(ScalarEvolution *SE, Value *Ptr, const Loop *Lp, - const ValueToValueMap &StridesMap); - bool AccessAnalysis::canCheckPtrAtRT( - LoopAccessInfo::RuntimePointerCheck &RtCheck, unsigned &NumComparisons, + LoopAccessInfo::RuntimePointerCheck &RtCheck, bool &NeedRTCheck, 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 IsDepCheckNeeded = isDependencyCheckNeeded(); - NumComparisons = 0; // We assign a consecutive id to access from different alias sets. // Accesses between different groups doesn't need to be checked. unsigned ASId = 1; for (auto &AS : AST) { - unsigned NumReadPtrChecks = 0; - unsigned 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; @@ -322,11 +323,6 @@ 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. @@ -354,16 +350,15 @@ bool AccessAnalysis::canCheckPtrAtRT( } } - if (IsDepCheckNeeded && CanDoRT && RunningDepId == 2) - NumComparisons += 0; // Only one dependence set. - else { - NumComparisons += (NumWritePtrChecks * (NumReadPtrChecks + - 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 @@ -510,8 +505,8 @@ static bool isInBoundsGep(Value *Ptr) { } /// \brief Check whether the access through \p Ptr has a constant stride. -static int isStridedPtr(ScalarEvolution *SE, Value *Ptr, const Loop *Lp, - const ValueToValueMap &StridesMap) { +int llvm::isStridedPtr(ScalarEvolution *SE, Value *Ptr, const Loop *Lp, + const ValueToValueMap &StridesMap) { const Type *Ty = Ptr->getType(); assert(Ty->isPointerTy() && "Unexpected non-ptr"); @@ -678,6 +673,42 @@ bool MemoryDepChecker::couldPreventStoreLoadForward(unsigned Distance, return false; } +/// \brief Check the dependence for two accesses with the same stride \p Stride. +/// \p Distance is the positive distance and \p TypeByteSize is type size in +/// bytes. +/// +/// \returns true if they are independent. +static bool areStridedAccessesIndependent(unsigned Distance, unsigned Stride, + unsigned TypeByteSize) { + assert(Stride > 1 && "The stride must be greater than 1"); + assert(TypeByteSize > 0 && "The type size in byte must be non-zero"); + assert(Distance > 0 && "The distance must be non-zero"); + + // Skip if the distance is not multiple of type byte size. + if (Distance % TypeByteSize) + return false; + + unsigned ScaledDist = Distance / TypeByteSize; + + // No dependence if the scaled distance is not multiple of the stride. + // E.g. + // for (i = 0; i < 1024 ; i += 4) + // A[i+2] = A[i] + 1; + // + // Two accesses in memory (scaled distance is 2, stride is 4): + // | A[0] | | | | A[4] | | | | + // | | | A[2] | | | | A[6] | | + // + // E.g. + // for (i = 0; i < 1024 ; i += 3) + // A[i+4] = A[i] + 1; + // + // Two accesses in memory (scaled distance is 4, stride is 3): + // | A[0] | | | A[3] | | | A[6] | | | + // | | | | | A[4] | | | A[7] | | + return ScaledDist % Stride; +} + MemoryDepChecker::Dependence::DepType MemoryDepChecker::isDependent(const MemAccessInfo &A, unsigned AIdx, const MemAccessInfo &B, unsigned BIdx, @@ -778,34 +809,87 @@ MemoryDepChecker::isDependent(const MemAccessInfo &A, unsigned AIdx, unsigned Distance = (unsigned) Val.getZExtValue(); + unsigned Stride = std::abs(StrideAPtr); + if (Stride > 1 && + areStridedAccessesIndependent(Distance, Stride, TypeByteSize)) + return Dependence::NoDep; + // Bail out early if passed-in parameters make vectorization not feasible. unsigned ForcedFactor = (VectorizerParams::VectorizationFactor ? VectorizerParams::VectorizationFactor : 1); unsigned ForcedUnroll = (VectorizerParams::VectorizationInterleave ? VectorizerParams::VectorizationInterleave : 1); + // The minimum number of iterations for a vectorized/unrolled version. + unsigned MinNumIter = std::max(ForcedFactor * ForcedUnroll, 2U); + + // It's not vectorizable if the distance is smaller than the minimum distance + // needed for a vectroized/unrolled version. Vectorizing one iteration in + // front needs TypeByteSize * Stride. Vectorizing the last iteration needs + // TypeByteSize (No need to plus the last gap distance). + // + // E.g. Assume one char is 1 byte in memory and one int is 4 bytes. + // foo(int *A) { + // int *B = (int *)((char *)A + 14); + // for (i = 0 ; i < 1024 ; i += 2) + // B[i] = A[i] + 1; + // } + // + // Two accesses in memory (stride is 2): + // | A[0] | | A[2] | | A[4] | | A[6] | | + // | B[0] | | B[2] | | B[4] | + // + // Distance needs for vectorizing iterations except the last iteration: + // 4 * 2 * (MinNumIter - 1). Distance needs for the last iteration: 4. + // So the minimum distance needed is: 4 * 2 * (MinNumIter - 1) + 4. + // + // If MinNumIter is 2, it is vectorizable as the minimum distance needed is + // 12, which is less than distance. + // + // If MinNumIter is 4 (Say if a user forces the vectorization factor to be 4), + // the minimum distance needed is 28, which is greater than distance. It is + // not safe to do vectorization. + unsigned MinDistanceNeeded = + TypeByteSize * Stride * (MinNumIter - 1) + TypeByteSize; + if (MinDistanceNeeded > Distance) { + DEBUG(dbgs() << "LAA: Failure because of positive distance " << Distance + << '\n'); + return Dependence::Backward; + } - // The distance must be bigger than the size needed for a vectorized version - // of the operation and the size of the vectorized operation must not be - // bigger than the currrent maximum size. - if (Distance < 2*TypeByteSize || - 2*TypeByteSize > MaxSafeDepDistBytes || - Distance < TypeByteSize * ForcedUnroll * ForcedFactor) { - DEBUG(dbgs() << "LAA: Failure because of Positive distance " - << Val.getSExtValue() << '\n'); + // Unsafe if the minimum distance needed is greater than max safe distance. + if (MinDistanceNeeded > MaxSafeDepDistBytes) { + DEBUG(dbgs() << "LAA: Failure because it needs at least " + << MinDistanceNeeded << " size in bytes"); return Dependence::Backward; } // Positive distance bigger than max vectorization factor. - MaxSafeDepDistBytes = Distance < MaxSafeDepDistBytes ? - Distance : MaxSafeDepDistBytes; + // FIXME: Should use max factor instead of max distance in bytes, which could + // not handle different types. + // E.g. Assume one char is 1 byte in memory and one int is 4 bytes. + // void foo (int *A, char *B) { + // for (unsigned i = 0; i < 1024; i++) { + // A[i+2] = A[i] + 1; + // B[i+2] = B[i] + 1; + // } + // } + // + // This case is currently unsafe according to the max safe distance. If we + // analyze the two accesses on array B, the max safe dependence distance + // is 2. Then we analyze the accesses on array A, the minimum distance needed + // is 8, which is less than 2 and forbidden vectorization, But actually + // both A and B could be vectorized by 2 iterations. + MaxSafeDepDistBytes = + Distance < MaxSafeDepDistBytes ? Distance : MaxSafeDepDistBytes; bool IsTrueDataDependence = (!AIsWrite && BIsWrite); if (IsTrueDataDependence && couldPreventStoreLoadForward(Distance, TypeByteSize)) return Dependence::BackwardVectorizableButPreventsForwarding; - DEBUG(dbgs() << "LAA: Positive distance " << Val.getSExtValue() << - " with max VF = " << MaxSafeDepDistBytes / TypeByteSize << '\n'); + DEBUG(dbgs() << "LAA: Positive distance " << Val.getSExtValue() + << " with max VF = " + << MaxSafeDepDistBytes / (TypeByteSize * Stride) << '\n'); return Dependence::BackwardVectorizable; } @@ -1066,7 +1150,7 @@ void LoopAccessInfo::analyzeLoop(const ValueToValueMap &Strides) { if (Seen.insert(Ptr).second) { ++NumReadWrites; - AliasAnalysis::Location Loc = AA->getLocation(ST); + AliasAnalysis::Location Loc = MemoryLocation::get(ST); // The TBAA metadata could have a control dependency on the predication // condition, so we cannot rely on it when determining whether or not we // need runtime pointer checks. @@ -1102,7 +1186,7 @@ void LoopAccessInfo::analyzeLoop(const ValueToValueMap &Strides) { IsReadOnlyPtr = true; } - AliasAnalysis::Location Loc = AA->getLocation(LD); + AliasAnalysis::Location Loc = MemoryLocation::get(LD); // The TBAA metadata could have a control dependency on the predication // condition, so we cannot rely on it when determining whether or not we // need runtime pointer checks. @@ -1123,22 +1207,17 @@ void LoopAccessInfo::analyzeLoop(const ValueToValueMap &Strides) { // Build dependence sets and check whether we need a runtime pointer bounds // check. Accesses.buildDependenceSets(); - bool NeedRTCheck = Accesses.isRTCheckNeeded(); // Find pointers with computable bounds. We are going to use this information // to place a runtime bound check. - bool CanDoRT = false; - if (NeedRTCheck) - CanDoRT = Accesses.canCheckPtrAtRT(PtrRtCheck, NumComparisons, SE, TheLoop, - Strides); - - DEBUG(dbgs() << "LAA: We need to do " << NumComparisons << - " pointer comparisons.\n"); + bool NeedRTCheck; + bool CanDoRT = Accesses.canCheckPtrAtRT(PtrRtCheck, + NeedRTCheck, SE, + TheLoop, Strides); - // If we only have one set of dependences to check pointers among we don't - // need a runtime check. - if (NumComparisons == 0 && NeedRTCheck) - NeedRTCheck = false; + DEBUG(dbgs() << "LAA: We need to do " + << PtrRtCheck.getNumberOfChecks(nullptr) + << " pointer comparisons.\n"); // Check that we found the bounds for the pointer. if (CanDoRT) @@ -1171,10 +1250,11 @@ void LoopAccessInfo::analyzeLoop(const ValueToValueMap &Strides) { PtrRtCheck.reset(); PtrRtCheck.Need = true; - CanDoRT = Accesses.canCheckPtrAtRT(PtrRtCheck, NumComparisons, SE, + CanDoRT = Accesses.canCheckPtrAtRT(PtrRtCheck, NeedRTCheck, SE, TheLoop, Strides, true); + // Check that we found the bounds for the pointer. - if (!CanDoRT && NumComparisons > 0) { + if (NeedRTCheck && !CanDoRT) { emitAnalysis(LoopAccessReport() << "cannot check memory dependencies at runtime"); DEBUG(dbgs() << "LAA: Can't vectorize with memory checks\n"); @@ -1319,7 +1399,7 @@ LoopAccessInfo::LoopAccessInfo(Loop *L, ScalarEvolution *SE, const TargetLibraryInfo *TLI, AliasAnalysis *AA, DominatorTree *DT, LoopInfo *LI, const ValueToValueMap &Strides) - : DepChecker(SE, L), NumComparisons(0), TheLoop(L), SE(SE), DL(DL), + : 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) { diff --git a/lib/Analysis/MemoryDependenceAnalysis.cpp b/lib/Analysis/MemoryDependenceAnalysis.cpp index 3c1826a58e669..255bae61eb2fe 100644 --- a/lib/Analysis/MemoryDependenceAnalysis.cpp +++ b/lib/Analysis/MemoryDependenceAnalysis.cpp @@ -124,11 +124,11 @@ AliasAnalysis::ModRefResult GetLocation(const Instruction *Inst, AliasAnalysis *AA) { if (const LoadInst *LI = dyn_cast(Inst)) { if (LI->isUnordered()) { - Loc = AA->getLocation(LI); + Loc = MemoryLocation::get(LI); return AliasAnalysis::Ref; } if (LI->getOrdering() == Monotonic) { - Loc = AA->getLocation(LI); + Loc = MemoryLocation::get(LI); return AliasAnalysis::ModRef; } Loc = AliasAnalysis::Location(); @@ -137,11 +137,11 @@ AliasAnalysis::ModRefResult GetLocation(const Instruction *Inst, if (const StoreInst *SI = dyn_cast(Inst)) { if (SI->isUnordered()) { - Loc = AA->getLocation(SI); + Loc = MemoryLocation::get(SI); return AliasAnalysis::Mod; } if (SI->getOrdering() == Monotonic) { - Loc = AA->getLocation(SI); + Loc = MemoryLocation::get(SI); return AliasAnalysis::ModRef; } Loc = AliasAnalysis::Location(); @@ -149,7 +149,7 @@ AliasAnalysis::ModRefResult GetLocation(const Instruction *Inst, } if (const VAArgInst *V = dyn_cast(Inst)) { - Loc = AA->getLocation(V); + Loc = MemoryLocation::get(V); return AliasAnalysis::ModRef; } @@ -486,7 +486,7 @@ getPointerDependencyFrom(const AliasAnalysis::Location &MemLoc, bool isLoad, } } - AliasAnalysis::Location LoadLoc = AA->getLocation(LI); + AliasAnalysis::Location LoadLoc = MemoryLocation::get(LI); // If we found a pointer, check if it could be the same as our pointer. AliasAnalysis::AliasResult R = AA->alias(LoadLoc, MemLoc); @@ -575,7 +575,7 @@ getPointerDependencyFrom(const AliasAnalysis::Location &MemLoc, bool isLoad, // Ok, this store might clobber the query pointer. Check to see if it is // a must alias: in this case, we want to return this as a def. - AliasAnalysis::Location StoreLoc = AA->getLocation(SI); + AliasAnalysis::Location StoreLoc = MemoryLocation::get(SI); // If we found a pointer, check if it could be the same as our pointer. AliasAnalysis::AliasResult R = AA->alias(StoreLoc, MemLoc); @@ -872,7 +872,7 @@ MemoryDependenceAnalysis::getNonLocalCallDependency(CallSite QueryCS) { void MemoryDependenceAnalysis:: getNonLocalPointerDependency(Instruction *QueryInst, SmallVectorImpl &Result) { - const AliasAnalysis::Location Loc = AA->getLocation(QueryInst); + const AliasAnalysis::Location Loc = MemoryLocation::get(QueryInst); bool isLoad = isa(QueryInst); BasicBlock *FromBB = QueryInst->getParent(); assert(FromBB); @@ -1278,8 +1278,7 @@ getNonLocalPointerDepFromBB(Instruction *QueryInst, // Get the PHI translated pointer in this predecessor. This can fail if // not translatable, in which case the getAddr() returns null. PHITransAddr &PredPointer = PredList.back().second; - PredPointer.PHITranslateValue(BB, Pred, nullptr); - + PredPointer.PHITranslateValue(BB, Pred, DT, /*MustDominate=*/false); Value *PredPtrVal = PredPointer.getAddr(); // Check to see if we have already visited this pred block with another diff --git a/lib/Analysis/MemoryLocation.cpp b/lib/Analysis/MemoryLocation.cpp new file mode 100644 index 0000000000000..f87a017b9211a --- /dev/null +++ b/lib/Analysis/MemoryLocation.cpp @@ -0,0 +1,90 @@ +//===- MemoryLocation.cpp - Memory location descriptions -------------------==// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Analysis/MemoryLocation.h" +#include "llvm/IR/BasicBlock.h" +#include "llvm/IR/DataLayout.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/IntrinsicInst.h" +#include "llvm/IR/LLVMContext.h" +#include "llvm/IR/Module.h" +#include "llvm/IR/Type.h" +using namespace llvm; + +MemoryLocation MemoryLocation::get(const LoadInst *LI) { + AAMDNodes AATags; + LI->getAAMetadata(AATags); + const auto &DL = LI->getModule()->getDataLayout(); + + return MemoryLocation(LI->getPointerOperand(), + DL.getTypeStoreSize(LI->getType()), AATags); +} + +MemoryLocation MemoryLocation::get(const StoreInst *SI) { + AAMDNodes AATags; + SI->getAAMetadata(AATags); + const auto &DL = SI->getModule()->getDataLayout(); + + return MemoryLocation(SI->getPointerOperand(), + DL.getTypeStoreSize(SI->getValueOperand()->getType()), + AATags); +} + +MemoryLocation MemoryLocation::get(const VAArgInst *VI) { + AAMDNodes AATags; + VI->getAAMetadata(AATags); + + return MemoryLocation(VI->getPointerOperand(), UnknownSize, AATags); +} + +MemoryLocation MemoryLocation::get(const AtomicCmpXchgInst *CXI) { + AAMDNodes AATags; + CXI->getAAMetadata(AATags); + const auto &DL = CXI->getModule()->getDataLayout(); + + return MemoryLocation( + CXI->getPointerOperand(), + DL.getTypeStoreSize(CXI->getCompareOperand()->getType()), AATags); +} + +MemoryLocation MemoryLocation::get(const AtomicRMWInst *RMWI) { + AAMDNodes AATags; + RMWI->getAAMetadata(AATags); + const auto &DL = RMWI->getModule()->getDataLayout(); + + return MemoryLocation(RMWI->getPointerOperand(), + DL.getTypeStoreSize(RMWI->getValOperand()->getType()), + AATags); +} + +MemoryLocation MemoryLocation::getForSource(const MemTransferInst *MTI) { + uint64_t Size = UnknownSize; + if (ConstantInt *C = dyn_cast(MTI->getLength())) + Size = C->getValue().getZExtValue(); + + // memcpy/memmove can have AA tags. For memcpy, they apply + // to both the source and the destination. + AAMDNodes AATags; + MTI->getAAMetadata(AATags); + + return MemoryLocation(MTI->getRawSource(), Size, AATags); +} + +MemoryLocation MemoryLocation::getForDest(const MemIntrinsic *MTI) { + uint64_t Size = UnknownSize; + if (ConstantInt *C = dyn_cast(MTI->getLength())) + Size = C->getValue().getZExtValue(); + + // memcpy/memmove can have AA tags. For memcpy, they apply + // to both the source and the destination. + AAMDNodes AATags; + MTI->getAAMetadata(AATags); + + return MemoryLocation(MTI->getRawDest(), Size, AATags); +} diff --git a/lib/Analysis/PHITransAddr.cpp b/lib/Analysis/PHITransAddr.cpp index 177684fdc9a75..633d6aaad35e9 100644 --- a/lib/Analysis/PHITransAddr.cpp +++ b/lib/Analysis/PHITransAddr.cpp @@ -150,7 +150,8 @@ Value *PHITransAddr::PHITranslateSubExpr(Value *V, BasicBlock *CurBB, if (!Inst) return V; // Determine whether 'Inst' is an input to our PHI translatable expression. - bool isInput = std::count(InstInputs.begin(), InstInputs.end(), Inst); + bool isInput = + std::find(InstInputs.begin(), InstInputs.end(), Inst) != InstInputs.end(); // Handle inputs instructions if needed. if (isInput) { @@ -276,7 +277,8 @@ Value *PHITransAddr::PHITranslateSubExpr(Value *V, BasicBlock *CurBB, isNSW = isNUW = false; // If the old 'LHS' was an input, add the new 'LHS' as an input. - if (std::count(InstInputs.begin(), InstInputs.end(), BOp)) { + if (std::find(InstInputs.begin(), InstInputs.end(), BOp) != + InstInputs.end()) { RemoveInstInputs(BOp, InstInputs); AddAsInput(LHS); } @@ -313,21 +315,26 @@ Value *PHITransAddr::PHITranslateSubExpr(Value *V, BasicBlock *CurBB, /// PHITranslateValue - PHI translate the current address up the CFG from -/// CurBB to Pred, updating our state to reflect any needed changes. If the -/// dominator tree DT is non-null, the translated value must dominate +/// CurBB to Pred, updating our state to reflect any needed changes. If +/// 'MustDominate' is true, the translated value must dominate /// PredBB. This returns true on failure and sets Addr to null. bool PHITransAddr::PHITranslateValue(BasicBlock *CurBB, BasicBlock *PredBB, - const DominatorTree *DT) { + const DominatorTree *DT, + bool MustDominate) { + assert(DT || !MustDominate); assert(Verify() && "Invalid PHITransAddr!"); - Addr = PHITranslateSubExpr(Addr, CurBB, PredBB, DT); + if (DT && DT->isReachableFromEntry(PredBB)) + Addr = + PHITranslateSubExpr(Addr, CurBB, PredBB, MustDominate ? DT : nullptr); + else + Addr = nullptr; assert(Verify() && "Invalid PHITransAddr!"); - if (DT) { + if (MustDominate) // Make sure the value is live in the predecessor. if (Instruction *Inst = dyn_cast_or_null(Addr)) if (!DT->dominates(Inst->getParent(), PredBB)) Addr = nullptr; - } return Addr == nullptr; } @@ -370,7 +377,7 @@ InsertPHITranslatedSubExpr(Value *InVal, BasicBlock *CurBB, // See if we have a version of this value already available and dominating // PredBB. If so, there is no need to insert a new instance of it. PHITransAddr Tmp(InVal, DL, AC); - if (!Tmp.PHITranslateValue(CurBB, PredBB, &DT)) + if (!Tmp.PHITranslateValue(CurBB, PredBB, &DT, /*MustDominate=*/true)) return Tmp.getAddr(); // If we don't have an available version of this value, it must be an diff --git a/lib/Analysis/ScalarEvolutionExpander.cpp b/lib/Analysis/ScalarEvolutionExpander.cpp index 0bd427bf74e9e..f82235d0c26e0 100644 --- a/lib/Analysis/ScalarEvolutionExpander.cpp +++ b/lib/Analysis/ScalarEvolutionExpander.cpp @@ -1712,7 +1712,7 @@ unsigned SCEVExpander::replaceCongruentIVs(Loop *L, const DominatorTree *DT, // would confuse the logic below that expects proper IVs. if (Value *V = SimplifyInstruction(Phi, DL, SE.TLI, SE.DT, SE.AC)) { Phi->replaceAllUsesWith(V); - DeadInsts.push_back(Phi); + DeadInsts.emplace_back(Phi); ++NumElim; DEBUG_WITH_TYPE(DebugType, dbgs() << "INDVARS: Eliminated constant iv: " << *Phi << '\n'); @@ -1787,7 +1787,7 @@ unsigned SCEVExpander::replaceCongruentIVs(Loop *L, const DominatorTree *DT, CreateTruncOrBitCast(OrigInc, IsomorphicInc->getType(), IVName); } IsomorphicInc->replaceAllUsesWith(NewInc); - DeadInsts.push_back(IsomorphicInc); + DeadInsts.emplace_back(IsomorphicInc); } } DEBUG_WITH_TYPE(DebugType, dbgs() @@ -1800,13 +1800,30 @@ unsigned SCEVExpander::replaceCongruentIVs(Loop *L, const DominatorTree *DT, NewIV = Builder.CreateTruncOrBitCast(OrigPhiRef, Phi->getType(), IVName); } Phi->replaceAllUsesWith(NewIV); - DeadInsts.push_back(Phi); + DeadInsts.emplace_back(Phi); } return NumElim; } bool SCEVExpander::isHighCostExpansionHelper( const SCEV *S, Loop *L, SmallPtrSetImpl &Processed) { + + // Zero/One operand expressions + switch (S->getSCEVType()) { + case scUnknown: + case scConstant: + return false; + case scTruncate: + return isHighCostExpansionHelper(cast(S)->getOperand(), L, + Processed); + case scZeroExtend: + return isHighCostExpansionHelper(cast(S)->getOperand(), + L, Processed); + case scSignExtend: + return isHighCostExpansionHelper(cast(S)->getOperand(), + L, Processed); + } + if (!Processed.insert(S).second) return false; @@ -1849,23 +1866,22 @@ bool SCEVExpander::isHighCostExpansionHelper( } } - // Recurse past add expressions, which commonly occur in the + // HowManyLessThans uses a Max expression whenever the loop is not guarded by + // the exit condition. + if (isa(S) || isa(S)) + return true; + + // Recurse past nary expressions, which commonly occur in the // BackedgeTakenCount. They may already exist in program code, and if not, // they are not too expensive rematerialize. - if (const SCEVAddExpr *Add = dyn_cast(S)) { - for (SCEVAddExpr::op_iterator I = Add->op_begin(), E = Add->op_end(); + if (const SCEVNAryExpr *NAry = dyn_cast(S)) { + for (SCEVNAryExpr::op_iterator I = NAry->op_begin(), E = NAry->op_end(); I != E; ++I) { if (isHighCostExpansionHelper(*I, L, Processed)) return true; } - return false; } - // HowManyLessThans uses a Max expression whenever the loop is not guarded by - // the exit condition. - if (isa(S) || isa(S)) - return true; - // If we haven't recognized an expensive SCEV pattern, assume it's an // expression produced by program code. return false; diff --git a/lib/Analysis/TargetTransformInfo.cpp b/lib/Analysis/TargetTransformInfo.cpp index e1744d1f2965b..24cada3e5313f 100644 --- a/lib/Analysis/TargetTransformInfo.cpp +++ b/lib/Analysis/TargetTransformInfo.cpp @@ -100,9 +100,10 @@ bool TargetTransformInfo::isLegalICmpImmediate(int64_t Imm) const { bool TargetTransformInfo::isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset, bool HasBaseReg, - int64_t Scale) const { + int64_t Scale, + unsigned AddrSpace) const { return TTIImpl->isLegalAddressingMode(Ty, BaseGV, BaseOffset, HasBaseReg, - Scale); + Scale, AddrSpace); } bool TargetTransformInfo::isLegalMaskedStore(Type *DataType, @@ -118,9 +119,10 @@ bool TargetTransformInfo::isLegalMaskedLoad(Type *DataType, int TargetTransformInfo::getScalingFactorCost(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset, bool HasBaseReg, - int64_t Scale) const { + int64_t Scale, + unsigned AddrSpace) const { return TTIImpl->getScalingFactorCost(Ty, BaseGV, BaseOffset, HasBaseReg, - Scale); + Scale, AddrSpace); } bool TargetTransformInfo::isTruncateFree(Type *Ty1, Type *Ty2) const { @@ -235,6 +237,13 @@ TargetTransformInfo::getMaskedMemoryOpCost(unsigned Opcode, Type *Src, return TTIImpl->getMaskedMemoryOpCost(Opcode, Src, Alignment, AddressSpace); } +unsigned TargetTransformInfo::getInterleavedMemoryOpCost( + unsigned Opcode, Type *VecTy, unsigned Factor, ArrayRef Indices, + unsigned Alignment, unsigned AddressSpace) const { + return TTIImpl->getInterleavedMemoryOpCost(Opcode, VecTy, Factor, Indices, + Alignment, AddressSpace); +} + unsigned TargetTransformInfo::getIntrinsicInstrCost(Intrinsic::ID ID, Type *RetTy, ArrayRef Tys) const { diff --git a/lib/Analysis/ValueTracking.cpp b/lib/Analysis/ValueTracking.cpp index a55712c6296a2..c4f046340fce4 100644 --- a/lib/Analysis/ValueTracking.cpp +++ b/lib/Analysis/ValueTracking.cpp @@ -2967,38 +2967,25 @@ static bool isDereferenceablePointer(const Value *V, const DataLayout &DL, // For GEPs, determine if the indexing lands within the allocated object. if (const GEPOperator *GEP = dyn_cast(V)) { + Type *VTy = GEP->getType(); + Type *Ty = VTy->getPointerElementType(); + const Value *Base = GEP->getPointerOperand(); + // Conservatively require that the base pointer be fully dereferenceable. - if (!Visited.insert(GEP->getOperand(0)).second) + if (!Visited.insert(Base).second) return false; - if (!isDereferenceablePointer(GEP->getOperand(0), DL, CtxI, + if (!isDereferenceablePointer(Base, DL, CtxI, DT, TLI, Visited)) return false; - // Check the indices. - gep_type_iterator GTI = gep_type_begin(GEP); - for (User::const_op_iterator I = GEP->op_begin()+1, - E = GEP->op_end(); I != E; ++I) { - Value *Index = *I; - Type *Ty = *GTI++; - // Struct indices can't be out of bounds. - if (isa(Ty)) - continue; - ConstantInt *CI = dyn_cast(Index); - if (!CI) - return false; - // Zero is always ok. - if (CI->isZero()) - continue; - // Check to see that it's within the bounds of an array. - ArrayType *ATy = dyn_cast(Ty); - if (!ATy) - return false; - if (CI->getValue().getActiveBits() > 64) - return false; - if (CI->getZExtValue() >= ATy->getNumElements()) - return false; - } - // Indices check out; this is dereferenceable. - return true; + + APInt Offset(DL.getPointerTypeSizeInBits(VTy), 0); + if (!GEP->accumulateConstantOffset(DL, Offset)) + return false; + + // Check if the load is within the bounds of the underlying object. + uint64_t LoadSize = DL.getTypeStoreSize(Ty); + Type *BaseType = Base->getType()->getPointerElementType(); + return (Offset + LoadSize).ule(DL.getTypeAllocSize(BaseType)); } // For gc.relocate, look through relocations diff --git a/lib/AsmParser/LLLexer.cpp b/lib/AsmParser/LLLexer.cpp index 05c24285028f9..09fe6c0a0bd8c 100644 --- a/lib/AsmParser/LLLexer.cpp +++ b/lib/AsmParser/LLLexer.cpp @@ -252,7 +252,7 @@ void LLLexer::SkipLineComment() { } } -/// LexAt - Lex all tokens that start with an @ character: +/// Lex all tokens that start with an @ character. /// GlobalVar @\"[^\"]*\" /// GlobalVar @[-a-zA-Z$._][-a-zA-Z$._0-9]* /// GlobalVarID @[0-9]+ @@ -375,7 +375,7 @@ lltok::Kind LLLexer::LexVar(lltok::Kind Var, lltok::Kind VarID) { return lltok::Error; } -/// LexPercent - Lex all tokens that start with a % character: +/// Lex all tokens that start with a % character. /// LocalVar ::= %\"[^\"]*\" /// LocalVar ::= %[-a-zA-Z$._][-a-zA-Z$._0-9]* /// LocalVarID ::= %[0-9]+ @@ -383,7 +383,7 @@ lltok::Kind LLLexer::LexPercent() { return LexVar(lltok::LocalVar, lltok::LocalVarID); } -/// LexQuote - Lex all tokens that start with a " character: +/// Lex all tokens that start with a " character. /// QuoteLabel "[^"]+": /// StringConstant "[^"]*" lltok::Kind LLLexer::LexQuote() { @@ -404,7 +404,7 @@ lltok::Kind LLLexer::LexQuote() { return kind; } -/// LexExclaim: +/// Lex all tokens that start with a ! character. /// !foo /// ! lltok::Kind LLLexer::LexExclaim() { @@ -425,7 +425,7 @@ lltok::Kind LLLexer::LexExclaim() { return lltok::exclaim; } -/// LexHash - Lex all tokens that start with a # character: +/// Lex all tokens that start with a # character. /// AttrGrpID ::= #[0-9]+ lltok::Kind LLLexer::LexHash() { // Handle AttrGrpID: #[0-9]+ @@ -443,7 +443,7 @@ lltok::Kind LLLexer::LexHash() { return lltok::Error; } -/// LexIdentifier: Handle several related productions: +/// Lex a label, integer type, keyword, or hexadecimal integer constant. /// Label [-a-zA-Z$._0-9]+: /// IntegerType i[0-9]+ /// Keyword sdiv, float, ... @@ -800,9 +800,8 @@ lltok::Kind LLLexer::LexIdentifier() { return lltok::Error; } - -/// Lex0x: Handle productions that start with 0x, knowing that it matches and -/// that this is not a label: +/// Lex all tokens that start with a 0x prefix, knowing they match and are not +/// labels. /// HexFPConstant 0x[0-9A-Fa-f]+ /// HexFP80Constant 0xK[0-9A-Fa-f]+ /// HexFP128Constant 0xL[0-9A-Fa-f]+ @@ -860,7 +859,7 @@ lltok::Kind LLLexer::Lex0x() { } } -/// LexIdentifier: Handle several related productions: +/// Lex tokens for a label or a numeric constant, possibly starting with -. /// Label [-a-zA-Z$._0-9]+: /// NInteger -[0-9]+ /// FPConstant [-+]?[0-9]+[.][0-9]*([eE][-+]?[0-9]+)? @@ -938,6 +937,7 @@ lltok::Kind LLLexer::LexDigitOrNegative() { return lltok::APFloat; } +/// Lex a floating point constant starting with +. /// FPConstant [-+]?[0-9]+[.][0-9]*([eE][-+]?[0-9]+)? lltok::Kind LLLexer::LexPositive() { // If the letter after the negative is a number, this is probably not a diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp index a52e20fb35b02..681af2a900729 100644 --- a/lib/AsmParser/LLParser.cpp +++ b/lib/AsmParser/LLParser.cpp @@ -189,7 +189,7 @@ bool LLParser::ParseTopLevelEntities() { // The Global variable production with no name can have many different // optional leading prefixes, the production is: // GlobalVar ::= OptionalLinkage OptionalVisibility OptionalDLLStorageClass - // OptionalThreadLocal OptionalAddrSpace OptionalUnNammedAddr + // OptionalThreadLocal OptionalAddrSpace OptionalUnnamedAddr // ('constant'|'global') ... case lltok::kw_private: // OptionalLinkage case lltok::kw_internal: // OptionalLinkage @@ -615,12 +615,12 @@ static bool isValidVisibilityForLinkage(unsigned V, unsigned L) { /// ParseAlias: /// ::= GlobalVar '=' OptionalLinkage OptionalVisibility /// OptionalDLLStorageClass OptionalThreadLocal -/// OptionalUnNammedAddr 'alias' Aliasee +/// OptionalUnnamedAddr 'alias' Aliasee /// /// Aliasee /// ::= TypeAndValue /// -/// Everything through OptionalUnNammedAddr has already been parsed. +/// Everything through OptionalUnnamedAddr has already been parsed. /// bool LLParser::ParseAlias(const std::string &Name, LocTy NameLoc, unsigned L, unsigned Visibility, unsigned DLLStorageClass, @@ -705,13 +705,13 @@ bool LLParser::ParseAlias(const std::string &Name, LocTy NameLoc, unsigned L, /// ParseGlobal /// ::= GlobalVar '=' OptionalLinkage OptionalVisibility OptionalDLLStorageClass -/// OptionalThreadLocal OptionalUnNammedAddr OptionalAddrSpace +/// OptionalThreadLocal OptionalUnnamedAddr OptionalAddrSpace /// OptionalExternallyInitialized GlobalType Type Const /// ::= OptionalLinkage OptionalVisibility OptionalDLLStorageClass -/// OptionalThreadLocal OptionalUnNammedAddr OptionalAddrSpace +/// OptionalThreadLocal OptionalUnnamedAddr OptionalAddrSpace /// OptionalExternallyInitialized GlobalType Type Const /// -/// Everything up to and including OptionalUnNammedAddr has been parsed +/// Everything up to and including OptionalUnnamedAddr has been parsed /// already. /// bool LLParser::ParseGlobal(const std::string &Name, LocTy NameLoc, @@ -1902,9 +1902,9 @@ bool LLParser::ParseArgumentList(SmallVectorImpl &ArgList, return Error(TypeLoc, "invalid type for function argument"); unsigned AttrIndex = 1; - ArgList.push_back(ArgInfo(TypeLoc, ArgTy, - AttributeSet::get(ArgTy->getContext(), - AttrIndex++, Attrs), Name)); + ArgList.emplace_back(TypeLoc, ArgTy, AttributeSet::get(ArgTy->getContext(), + AttrIndex++, Attrs), + std::move(Name)); while (EatIfPresent(lltok::comma)) { // Handle ... at end of arg list. @@ -1930,10 +1930,10 @@ bool LLParser::ParseArgumentList(SmallVectorImpl &ArgList, if (!ArgTy->isFirstClassType()) return Error(TypeLoc, "invalid type for function argument"); - ArgList.push_back(ArgInfo(TypeLoc, ArgTy, - AttributeSet::get(ArgTy->getContext(), - AttrIndex++, Attrs), - Name)); + ArgList.emplace_back( + TypeLoc, ArgTy, + AttributeSet::get(ArgTy->getContext(), AttrIndex++, Attrs), + std::move(Name)); } } @@ -3730,7 +3730,7 @@ bool LLParser::ParseDILocalVariable(MDNode *&Result, bool IsDistinct) { OPTIONAL(file, MDField, ); \ OPTIONAL(line, LineField, ); \ OPTIONAL(type, MDField, ); \ - OPTIONAL(arg, MDUnsignedField, (0, UINT8_MAX)); \ + OPTIONAL(arg, MDUnsignedField, (0, UINT16_MAX)); \ OPTIONAL(flags, DIFlagField, ); PARSE_MD_FIELDS(); #undef VISIT_MD_FIELDS diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index f6d5ccc1a59ef..056d87beef151 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/lib/Bitcode/Reader/BitcodeReader.cpp @@ -63,9 +63,7 @@ public: // vector compatibility methods unsigned size() const { return ValuePtrs.size(); } void resize(unsigned N) { ValuePtrs.resize(N); } - void push_back(Value *V) { - ValuePtrs.push_back(V); - } + void push_back(Value *V) { ValuePtrs.emplace_back(V); } void clear() { assert(ResolveConstants.empty() && "Constants not resolved?"); @@ -1499,6 +1497,8 @@ std::error_code BitcodeReader::ParseTypeTableBody() { case bitc::TYPE_CODE_VECTOR: // VECTOR: [numelts, eltty] if (Record.size() < 2) return Error("Invalid record"); + if (Record[0] == 0) + return Error("Invalid vector length"); ResultTy = getTypeByID(Record[1]); if (!ResultTy || !StructType::isValidElementType(ResultTy)) return Error("Invalid type"); @@ -1636,9 +1636,9 @@ std::error_code BitcodeReader::ParseMetadata() { Record.clear(); Code = Stream.ReadCode(); - // METADATA_NAME is always followed by METADATA_NAMED_NODE. unsigned NextBitCode = Stream.readRecord(Code, Record); - assert(NextBitCode == bitc::METADATA_NAMED_NODE); (void)NextBitCode; + if (NextBitCode != bitc::METADATA_NAMED_NODE) + return Error("METADATA_NAME not followed by METADATA_NAMED_NODE"); // Read named metadata elements. unsigned Size = Record.size(); @@ -2065,10 +2065,13 @@ std::error_code BitcodeReader::ResolveGlobalAndAliasInits() { if (ValID >= ValueList.size()) { AliasInits.push_back(AliasInitWorklist.back()); } else { - if (Constant *C = dyn_cast_or_null(ValueList[ValID])) - AliasInitWorklist.back().first->setAliasee(C); - else + Constant *C = dyn_cast_or_null(ValueList[ValID]); + if (!C) return Error("Expected a constant"); + GlobalAlias *Alias = AliasInitWorklist.back().first; + if (C->getType() != Alias->getType()) + return Error("Alias and aliasee types don't match"); + Alias->setAliasee(C); } AliasInitWorklist.pop_back(); } diff --git a/lib/CodeGen/AggressiveAntiDepBreaker.cpp b/lib/CodeGen/AggressiveAntiDepBreaker.cpp index 58b87e12912cf..5fe4c4bcaec43 100644 --- a/lib/CodeGen/AggressiveAntiDepBreaker.cpp +++ b/lib/CodeGen/AggressiveAntiDepBreaker.cpp @@ -163,7 +163,7 @@ void AggressiveAntiDepBreaker::StartBlock(MachineBasicBlock *BB) { // all callee-saved registers. In non-return this is any // callee-saved register that is not saved in the prolog. const MachineFrameInfo *MFI = MF.getFrameInfo(); - BitVector Pristine = MFI->getPristineRegs(BB); + BitVector Pristine = MFI->getPristineRegs(MF); for (const MCPhysReg *I = TRI->getCalleeSavedRegs(&MF); *I; ++I) { unsigned Reg = *I; if (!IsReturnBlock && !Pristine.test(Reg)) continue; diff --git a/lib/CodeGen/AsmPrinter/AddressPool.cpp b/lib/CodeGen/AsmPrinter/AddressPool.cpp index 2487aba448cbd..8c6838394ac90 100644 --- a/lib/CodeGen/AsmPrinter/AddressPool.cpp +++ b/lib/CodeGen/AsmPrinter/AddressPool.cpp @@ -38,7 +38,7 @@ void AddressPool::emit(AsmPrinter &Asm, MCSection *AddrSection) { Entries[I.second.Number] = I.second.TLS ? Asm.getObjFileLowering().getDebugThreadLocalSymbol(I.first) - : MCSymbolRefExpr::Create(I.first, Asm.OutContext); + : MCSymbolRefExpr::create(I.first, Asm.OutContext); for (const MCExpr *Entry : Entries) Asm.OutStreamer->EmitValue(Entry, Asm.getDataLayout().getPointerSize()); diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index 206be702e7249..2e3b83a09520d 100644 --- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -14,7 +14,7 @@ #include "llvm/CodeGen/AsmPrinter.h" #include "DwarfDebug.h" #include "DwarfException.h" -#include "Win64Exception.h" +#include "WinException.h" #include "WinCodeViewLineTables.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/Statistic.h" @@ -40,7 +40,7 @@ #include "llvm/MC/MCInst.h" #include "llvm/MC/MCSection.h" #include "llvm/MC/MCStreamer.h" -#include "llvm/MC/MCSymbol.h" +#include "llvm/MC/MCSymbolELF.h" #include "llvm/MC/MCValue.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/Format.h" @@ -268,8 +268,9 @@ bool AsmPrinter::doInitialization(Module &M) { default: llvm_unreachable("unsupported unwinding information encoding"); case WinEH::EncodingType::Invalid: break; + case WinEH::EncodingType::X86: case WinEH::EncodingType::Itanium: - ES = new Win64Exception(this); + ES = new WinException(this); break; } break; @@ -511,7 +512,8 @@ void AsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) { if (MAI->hasDotTypeDotSizeDirective()) // .size foo, 42 - OutStreamer->EmitELFSize(GVSym, MCConstantExpr::Create(Size, OutContext)); + OutStreamer->emitELFSize(cast(GVSym), + MCConstantExpr::create(Size, OutContext)); OutStreamer->AddBlankLine(); } @@ -565,7 +567,7 @@ void AsmPrinter::EmitFunctionHeader() { MCSymbol *CurPos = OutContext.createTempSymbol(); OutStreamer->EmitLabel(CurPos); OutStreamer->EmitAssignment(CurrentFnBegin, - MCSymbolRefExpr::Create(CurPos, OutContext)); + MCSymbolRefExpr::create(CurPos, OutContext)); } else { OutStreamer->EmitLabel(CurrentFnBegin); } @@ -775,7 +777,7 @@ void AsmPrinter::emitFrameAlloc(const MachineInstr &MI) { // Emit a symbol assignment. OutStreamer->EmitAssignment(FrameAllocSym, - MCConstantExpr::Create(FrameOffset, OutContext)); + MCConstantExpr::create(FrameOffset, OutContext)); } /// EmitFunctionBody - This method emits the body and trailer for a @@ -899,11 +901,11 @@ void AsmPrinter::EmitFunctionBody() { // We can get the size as difference between the function label and the // temp label. const MCExpr *SizeExp = - MCBinaryExpr::CreateSub(MCSymbolRefExpr::Create(CurrentFnEnd, OutContext), - MCSymbolRefExpr::Create(CurrentFnSymForSize, + MCBinaryExpr::createSub(MCSymbolRefExpr::create(CurrentFnEnd, OutContext), + MCSymbolRefExpr::create(CurrentFnSymForSize, OutContext), OutContext); - OutStreamer->EmitELFSize(CurrentFnSym, SizeExp); + OutStreamer->emitELFSize(cast(CurrentFnSym), SizeExp); } for (const HandlerInfo &HI : Handlers) { @@ -1325,9 +1327,9 @@ void AsmPrinter::EmitJumpTableInfo() { // .set LJTSet, LBB32-base const MCExpr *LHS = - MCSymbolRefExpr::Create(MBB->getSymbol(), OutContext); + MCSymbolRefExpr::create(MBB->getSymbol(), OutContext); OutStreamer->EmitAssignment(GetJTSetSymbol(JTI, MBB->getNumber()), - MCBinaryExpr::CreateSub(LHS, Base, + MCBinaryExpr::createSub(LHS, Base, OutContext)); } } @@ -1367,14 +1369,14 @@ void AsmPrinter::EmitJumpTableEntry(const MachineJumpTableInfo *MJTI, case MachineJumpTableInfo::EK_BlockAddress: // EK_BlockAddress - Each entry is a plain address of block, e.g.: // .word LBB123 - Value = MCSymbolRefExpr::Create(MBB->getSymbol(), OutContext); + Value = MCSymbolRefExpr::create(MBB->getSymbol(), OutContext); break; case MachineJumpTableInfo::EK_GPRel32BlockAddress: { // EK_GPRel32BlockAddress - Each entry is an address of block, encoded // with a relocation as gp-relative, e.g.: // .gprel32 LBB123 MCSymbol *MBBSym = MBB->getSymbol(); - OutStreamer->EmitGPRel32Value(MCSymbolRefExpr::Create(MBBSym, OutContext)); + OutStreamer->EmitGPRel32Value(MCSymbolRefExpr::create(MBBSym, OutContext)); return; } @@ -1383,7 +1385,7 @@ void AsmPrinter::EmitJumpTableEntry(const MachineJumpTableInfo *MJTI, // with a relocation as gp-relative, e.g.: // .gpdword LBB123 MCSymbol *MBBSym = MBB->getSymbol(); - OutStreamer->EmitGPRel64Value(MCSymbolRefExpr::Create(MBBSym, OutContext)); + OutStreamer->EmitGPRel64Value(MCSymbolRefExpr::create(MBBSym, OutContext)); return; } @@ -1396,14 +1398,14 @@ void AsmPrinter::EmitJumpTableEntry(const MachineJumpTableInfo *MJTI, // .set L4_5_set_123, LBB123 - LJTI1_2 // .word L4_5_set_123 if (MAI->doesSetDirectiveSuppressesReloc()) { - Value = MCSymbolRefExpr::Create(GetJTSetSymbol(UID, MBB->getNumber()), + Value = MCSymbolRefExpr::create(GetJTSetSymbol(UID, MBB->getNumber()), OutContext); break; } - Value = MCSymbolRefExpr::Create(MBB->getSymbol(), OutContext); + Value = MCSymbolRefExpr::create(MBB->getSymbol(), OutContext); const TargetLowering *TLI = MF->getSubtarget().getTargetLowering(); const MCExpr *Base = TLI->getPICJumpTableRelocBaseExpr(MF, UID, OutContext); - Value = MCBinaryExpr::CreateSub(Value, Base, OutContext); + Value = MCBinaryExpr::createSub(Value, Base, OutContext); break; } } @@ -1595,8 +1597,8 @@ void AsmPrinter::EmitLabelDifference(const MCSymbol *Hi, const MCSymbol *Lo, // Get the Hi-Lo expression. const MCExpr *Diff = - MCBinaryExpr::CreateSub(MCSymbolRefExpr::Create(Hi, OutContext), - MCSymbolRefExpr::Create(Lo, OutContext), + MCBinaryExpr::createSub(MCSymbolRefExpr::create(Hi, OutContext), + MCSymbolRefExpr::create(Lo, OutContext), OutContext); if (!MAI->doesSetDirectiveSuppressesReloc()) { @@ -1622,10 +1624,10 @@ void AsmPrinter::EmitLabelPlusOffset(const MCSymbol *Label, uint64_t Offset, } // Emit Label+Offset (or just Label if Offset is zero) - const MCExpr *Expr = MCSymbolRefExpr::Create(Label, OutContext); + const MCExpr *Expr = MCSymbolRefExpr::create(Label, OutContext); if (Offset) - Expr = MCBinaryExpr::CreateAdd( - Expr, MCConstantExpr::Create(Offset, OutContext), OutContext); + Expr = MCBinaryExpr::createAdd( + Expr, MCConstantExpr::create(Offset, OutContext), OutContext); OutStreamer->EmitValue(Expr, Size); } @@ -1662,16 +1664,16 @@ const MCExpr *AsmPrinter::lowerConstant(const Constant *CV) { MCContext &Ctx = OutContext; if (CV->isNullValue() || isa(CV)) - return MCConstantExpr::Create(0, Ctx); + return MCConstantExpr::create(0, Ctx); if (const ConstantInt *CI = dyn_cast(CV)) - return MCConstantExpr::Create(CI->getZExtValue(), Ctx); + return MCConstantExpr::create(CI->getZExtValue(), Ctx); if (const GlobalValue *GV = dyn_cast(CV)) - return MCSymbolRefExpr::Create(getSymbol(GV), Ctx); + return MCSymbolRefExpr::create(getSymbol(GV), Ctx); if (const BlockAddress *BA = dyn_cast(CV)) - return MCSymbolRefExpr::Create(GetBlockAddressSymbol(BA), Ctx); + return MCSymbolRefExpr::create(GetBlockAddressSymbol(BA), Ctx); const ConstantExpr *CE = dyn_cast(CV); if (!CE) { @@ -1712,7 +1714,7 @@ const MCExpr *AsmPrinter::lowerConstant(const Constant *CV) { return Base; int64_t Offset = OffsetAI.getSExtValue(); - return MCBinaryExpr::CreateAdd(Base, MCConstantExpr::Create(Offset, Ctx), + return MCBinaryExpr::createAdd(Base, MCConstantExpr::create(Offset, Ctx), Ctx); } @@ -1755,8 +1757,8 @@ const MCExpr *AsmPrinter::lowerConstant(const Constant *CV) { // the high bits so we are sure to get a proper truncation if the input is // a constant expr. unsigned InBits = DL.getTypeAllocSizeInBits(Op->getType()); - const MCExpr *MaskExpr = MCConstantExpr::Create(~0ULL >> (64-InBits), Ctx); - return MCBinaryExpr::CreateAnd(OpExpr, MaskExpr, Ctx); + const MCExpr *MaskExpr = MCConstantExpr::create(~0ULL >> (64-InBits), Ctx); + return MCBinaryExpr::createAnd(OpExpr, MaskExpr, Ctx); } // The MC library also has a right-shift operator, but it isn't consistently @@ -1774,15 +1776,15 @@ const MCExpr *AsmPrinter::lowerConstant(const Constant *CV) { const MCExpr *RHS = lowerConstant(CE->getOperand(1)); switch (CE->getOpcode()) { default: llvm_unreachable("Unknown binary operator constant cast expr"); - case Instruction::Add: return MCBinaryExpr::CreateAdd(LHS, RHS, Ctx); - case Instruction::Sub: return MCBinaryExpr::CreateSub(LHS, RHS, Ctx); - case Instruction::Mul: return MCBinaryExpr::CreateMul(LHS, RHS, Ctx); - case Instruction::SDiv: return MCBinaryExpr::CreateDiv(LHS, RHS, Ctx); - case Instruction::SRem: return MCBinaryExpr::CreateMod(LHS, RHS, Ctx); - case Instruction::Shl: return MCBinaryExpr::CreateShl(LHS, RHS, Ctx); - case Instruction::And: return MCBinaryExpr::CreateAnd(LHS, RHS, Ctx); - case Instruction::Or: return MCBinaryExpr::CreateOr (LHS, RHS, Ctx); - case Instruction::Xor: return MCBinaryExpr::CreateXor(LHS, RHS, Ctx); + case Instruction::Add: return MCBinaryExpr::createAdd(LHS, RHS, Ctx); + case Instruction::Sub: return MCBinaryExpr::createSub(LHS, RHS, Ctx); + case Instruction::Mul: return MCBinaryExpr::createMul(LHS, RHS, Ctx); + case Instruction::SDiv: return MCBinaryExpr::createDiv(LHS, RHS, Ctx); + case Instruction::SRem: return MCBinaryExpr::createMod(LHS, RHS, Ctx); + case Instruction::Shl: return MCBinaryExpr::createShl(LHS, RHS, Ctx); + case Instruction::And: return MCBinaryExpr::createAnd(LHS, RHS, Ctx); + case Instruction::Or: return MCBinaryExpr::createOr (LHS, RHS, Ctx); + case Instruction::Xor: return MCBinaryExpr::createXor(LHS, RHS, Ctx); } } } @@ -2106,13 +2108,13 @@ static void handleIndirectSymViaGOTPCRel(AsmPrinter &AP, const MCExpr **ME, // cstexpr := - "." + // cstexpr := - ( - ) + // - // After canonicalization by EvaluateAsRelocatable `ME` turns into: + // After canonicalization by evaluateAsRelocatable `ME` turns into: // // cstexpr := - + gotpcrelcst, where // gotpcrelcst := + // MCValue MV; - if (!(*ME)->EvaluateAsRelocatable(MV, nullptr, nullptr) || MV.isAbsolute()) + if (!(*ME)->evaluateAsRelocatable(MV, nullptr, nullptr) || MV.isAbsolute()) return; const MCSymbol *GOTEquivSym = &MV.getSymA()->getSymbol(); diff --git a/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp b/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp index 3258961bfb118..7dbfddf606916 100644 --- a/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp +++ b/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp @@ -254,40 +254,34 @@ void AsmPrinter::emitCFIInstruction(const MCCFIInstruction &Inst) const { } void AsmPrinter::emitDwarfDIE(const DIE &Die) const { - // Get the abbreviation for this DIE. - const DIEAbbrev &Abbrev = Die.getAbbrev(); - // Emit the code (index) for the abbreviation. if (isVerbose()) - OutStreamer->AddComment("Abbrev [" + Twine(Abbrev.getNumber()) + - "] 0x" + Twine::utohexstr(Die.getOffset()) + - ":0x" + Twine::utohexstr(Die.getSize()) + " " + - dwarf::TagString(Abbrev.getTag())); - EmitULEB128(Abbrev.getNumber()); - - const SmallVectorImpl &Values = Die.getValues(); - const SmallVectorImpl &AbbrevData = Abbrev.getData(); + OutStreamer->AddComment("Abbrev [" + Twine(Die.getAbbrevNumber()) + "] 0x" + + Twine::utohexstr(Die.getOffset()) + ":0x" + + Twine::utohexstr(Die.getSize()) + " " + + dwarf::TagString(Die.getTag())); + EmitULEB128(Die.getAbbrevNumber()); // Emit the DIE attribute values. - for (unsigned i = 0, N = Values.size(); i < N; ++i) { - dwarf::Attribute Attr = AbbrevData[i].getAttribute(); - dwarf::Form Form = AbbrevData[i].getForm(); + for (const auto &V : Die.values()) { + dwarf::Attribute Attr = V.getAttribute(); + dwarf::Form Form = V.getForm(); assert(Form && "Too many attributes for DIE (check abbreviation)"); if (isVerbose()) { OutStreamer->AddComment(dwarf::AttributeString(Attr)); if (Attr == dwarf::DW_AT_accessibility) - OutStreamer->AddComment(dwarf::AccessibilityString( - cast(Values[i])->getValue())); + OutStreamer->AddComment( + dwarf::AccessibilityString(V.getDIEInteger().getValue())); } // Emit an attribute using the defined form. - Values[i]->EmitValue(this, Form); + V.EmitValue(this, Form); } // Emit the DIE children if any. - if (Abbrev.hasChildren()) { - for (auto &Child : Die.getChildren()) + if (Die.hasChildren()) { + for (auto &Child : Die.children()) emitDwarfDIE(*Child); OutStreamer->AddComment("End Of Children Mark"); diff --git a/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp b/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp index e7631dd515215..793e62960dd63 100644 --- a/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp +++ b/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp @@ -402,10 +402,11 @@ static void EmitGCCInlineAsmStr(const char *AsmStr, const MachineInstr *MI, unsigned OpFlags = MI->getOperand(OpNo).getImm(); ++OpNo; // Skip over the ID number. - if (Modifier[0] == 'l') // labels are target independent + if (Modifier[0] == 'l') { // Labels are target independent. // FIXME: What if the operand isn't an MBB, report error? - OS << *MI->getOperand(OpNo).getMBB()->getSymbol(); - else { + const MCSymbol *Sym = MI->getOperand(OpNo).getMBB()->getSymbol(); + Sym->print(OS, AP->MAI); + } else { if (InlineAsm::isMemKind(OpFlags)) { Error = AP->PrintAsmMemoryOperand(MI, OpNo, InlineAsmVariant, Modifier[0] ? Modifier : nullptr, diff --git a/lib/CodeGen/AsmPrinter/CMakeLists.txt b/lib/CodeGen/AsmPrinter/CMakeLists.txt index 01d2c7220ab94..f2da8557a5226 100644 --- a/lib/CodeGen/AsmPrinter/CMakeLists.txt +++ b/lib/CodeGen/AsmPrinter/CMakeLists.txt @@ -18,7 +18,7 @@ add_llvm_library(LLVMAsmPrinter EHStreamer.cpp ErlangGCPrinter.cpp OcamlGCPrinter.cpp - Win64Exception.cpp + WinException.cpp WinCodeViewLineTables.cpp ) diff --git a/lib/CodeGen/AsmPrinter/DIE.cpp b/lib/CodeGen/AsmPrinter/DIE.cpp index 1ccffe97b80b2..fa8449e94c9fb 100644 --- a/lib/CodeGen/AsmPrinter/DIE.cpp +++ b/lib/CodeGen/AsmPrinter/DIE.cpp @@ -107,6 +107,13 @@ void DIEAbbrev::print(raw_ostream &O) { void DIEAbbrev::dump() { print(dbgs()); } #endif +DIEAbbrev DIE::generateAbbrev() const { + DIEAbbrev Abbrev(Tag, hasChildren()); + for (const DIEValue &V : Values) + Abbrev.AddAttribute(V.getAttribute(), V.getForm()); + return Abbrev; +} + /// Climb up the parent chain to get the unit DIE to which this DIE /// belongs. const DIE *DIE::getUnit() const { @@ -128,22 +135,19 @@ const DIE *DIE::getUnitOrNull() const { return nullptr; } -DIEValue *DIE::findAttribute(dwarf::Attribute Attribute) const { - const SmallVectorImpl &Values = getValues(); - const DIEAbbrev &Abbrevs = getAbbrev(); - +DIEValue DIE::findAttribute(dwarf::Attribute Attribute) const { // Iterate through all the attributes until we find the one we're // looking for, if we can't find it return NULL. - for (size_t i = 0; i < Values.size(); ++i) - if (Abbrevs.getData()[i].getAttribute() == Attribute) - return Values[i]; - return nullptr; + for (const auto &V : values()) + if (V.getAttribute() == Attribute) + return V; + return DIEValue(); } #ifndef NDEBUG void DIE::print(raw_ostream &O, unsigned IndentCount) const { const std::string Indent(IndentCount, ' '); - bool isBlock = Abbrev.getTag() == 0; + bool isBlock = getTag() == 0; if (!isBlock) { O << Indent @@ -153,28 +157,26 @@ void DIE::print(raw_ostream &O, unsigned IndentCount) const { << ", Size: " << Size << "\n"; O << Indent - << dwarf::TagString(Abbrev.getTag()) + << dwarf::TagString(getTag()) << " " - << dwarf::ChildrenString(Abbrev.hasChildren()) << "\n"; + << dwarf::ChildrenString(hasChildren()) << "\n"; } else { O << "Size: " << Size << "\n"; } - const SmallVectorImpl &Data = Abbrev.getData(); - IndentCount += 2; - for (unsigned i = 0, N = Data.size(); i < N; ++i) { + for (unsigned i = 0, N = Values.size(); i < N; ++i) { O << Indent; if (!isBlock) - O << dwarf::AttributeString(Data[i].getAttribute()); + O << dwarf::AttributeString(Values[i].getAttribute()); else O << "Blk[" << i << "]"; O << " " - << dwarf::FormEncodingString(Data[i].getForm()) + << dwarf::FormEncodingString(Values[i].getForm()) << " "; - Values[i]->print(O); + Values[i].print(O); O << "\n"; } IndentCount -= 2; @@ -193,40 +195,24 @@ void DIE::dump() { void DIEValue::EmitValue(const AsmPrinter *AP, dwarf::Form Form) const { switch (Ty) { -#define EMIT_VALUE_IMPL(Kind) \ - case is##Kind: \ - cast(this)->EmitValueImpl(AP, Form); \ + case isNone: + llvm_unreachable("Expected valid DIEValue"); +#define HANDLE_DIEVALUE(T) \ + case is##T: \ + getDIE##T().EmitValue(AP, Form); \ break; - EMIT_VALUE_IMPL(Integer) - EMIT_VALUE_IMPL(String) - EMIT_VALUE_IMPL(Expr) - EMIT_VALUE_IMPL(Label) - EMIT_VALUE_IMPL(Delta) - EMIT_VALUE_IMPL(Entry) - EMIT_VALUE_IMPL(TypeSignature) - EMIT_VALUE_IMPL(Block) - EMIT_VALUE_IMPL(Loc) - EMIT_VALUE_IMPL(LocList) -#undef EMIT_VALUE_IMPL +#include "llvm/CodeGen/DIEValue.def" } } unsigned DIEValue::SizeOf(const AsmPrinter *AP, dwarf::Form Form) const { switch (Ty) { -#define SIZE_OF_IMPL(Kind) \ - case is##Kind: \ - return cast(this)->SizeOfImpl(AP, Form); - SIZE_OF_IMPL(Integer) - SIZE_OF_IMPL(String) - SIZE_OF_IMPL(Expr) - SIZE_OF_IMPL(Label) - SIZE_OF_IMPL(Delta) - SIZE_OF_IMPL(Entry) - SIZE_OF_IMPL(TypeSignature) - SIZE_OF_IMPL(Block) - SIZE_OF_IMPL(Loc) - SIZE_OF_IMPL(LocList) -#undef SIZE_OF_IMPL + case isNone: + llvm_unreachable("Expected valid DIEValue"); +#define HANDLE_DIEVALUE(T) \ + case is##T: \ + return getDIE##T().SizeOf(AP, Form); +#include "llvm/CodeGen/DIEValue.def" } llvm_unreachable("Unknown DIE kind"); } @@ -234,21 +220,13 @@ unsigned DIEValue::SizeOf(const AsmPrinter *AP, dwarf::Form Form) const { #ifndef NDEBUG void DIEValue::print(raw_ostream &O) const { switch (Ty) { -#define PRINT_IMPL(Kind) \ - case is##Kind: \ - cast(this)->printImpl(O); \ + case isNone: + llvm_unreachable("Expected valid DIEValue"); +#define HANDLE_DIEVALUE(T) \ + case is##T: \ + getDIE##T().print(O); \ break; - PRINT_IMPL(Integer) - PRINT_IMPL(String) - PRINT_IMPL(Expr) - PRINT_IMPL(Label) - PRINT_IMPL(Delta) - PRINT_IMPL(Entry) - PRINT_IMPL(TypeSignature) - PRINT_IMPL(Block) - PRINT_IMPL(Loc) - PRINT_IMPL(LocList) -#undef PRINT_IMPL +#include "llvm/CodeGen/DIEValue.def" } } @@ -263,7 +241,7 @@ void DIEValue::dump() const { /// EmitValue - Emit integer of appropriate size. /// -void DIEInteger::EmitValueImpl(const AsmPrinter *Asm, dwarf::Form Form) const { +void DIEInteger::EmitValue(const AsmPrinter *Asm, dwarf::Form Form) const { unsigned Size = ~0U; switch (Form) { case dwarf::DW_FORM_flag_present: @@ -299,7 +277,7 @@ void DIEInteger::EmitValueImpl(const AsmPrinter *Asm, dwarf::Form Form) const { /// SizeOf - Determine size of integer value in bytes. /// -unsigned DIEInteger::SizeOfImpl(const AsmPrinter *AP, dwarf::Form Form) const { +unsigned DIEInteger::SizeOf(const AsmPrinter *AP, dwarf::Form Form) const { switch (Form) { case dwarf::DW_FORM_flag_present: return 0; case dwarf::DW_FORM_flag: // Fall thru @@ -328,7 +306,7 @@ unsigned DIEInteger::SizeOfImpl(const AsmPrinter *AP, dwarf::Form Form) const { } #ifndef NDEBUG -void DIEInteger::printImpl(raw_ostream &O) const { +void DIEInteger::print(raw_ostream &O) const { O << "Int: " << (int64_t)Integer << " 0x"; O.write_hex(Integer); } @@ -340,13 +318,13 @@ void DIEInteger::printImpl(raw_ostream &O) const { /// EmitValue - Emit expression value. /// -void DIEExpr::EmitValueImpl(const AsmPrinter *AP, dwarf::Form Form) const { +void DIEExpr::EmitValue(const AsmPrinter *AP, dwarf::Form Form) const { AP->OutStreamer->EmitValue(Expr, SizeOf(AP, Form)); } /// SizeOf - Determine size of expression value in bytes. /// -unsigned DIEExpr::SizeOfImpl(const AsmPrinter *AP, dwarf::Form Form) const { +unsigned DIEExpr::SizeOf(const AsmPrinter *AP, dwarf::Form Form) const { if (Form == dwarf::DW_FORM_data4) return 4; if (Form == dwarf::DW_FORM_sec_offset) return 4; if (Form == dwarf::DW_FORM_strp) return 4; @@ -354,7 +332,7 @@ unsigned DIEExpr::SizeOfImpl(const AsmPrinter *AP, dwarf::Form Form) const { } #ifndef NDEBUG -void DIEExpr::printImpl(raw_ostream &O) const { O << "Expr: " << *Expr; } +void DIEExpr::print(raw_ostream &O) const { O << "Expr: " << *Expr; } #endif //===----------------------------------------------------------------------===// @@ -363,7 +341,7 @@ void DIEExpr::printImpl(raw_ostream &O) const { O << "Expr: " << *Expr; } /// EmitValue - Emit label value. /// -void DIELabel::EmitValueImpl(const AsmPrinter *AP, dwarf::Form Form) const { +void DIELabel::EmitValue(const AsmPrinter *AP, dwarf::Form Form) const { AP->EmitLabelReference(Label, SizeOf(AP, Form), Form == dwarf::DW_FORM_strp || Form == dwarf::DW_FORM_sec_offset || @@ -372,7 +350,7 @@ void DIELabel::EmitValueImpl(const AsmPrinter *AP, dwarf::Form Form) const { /// SizeOf - Determine size of label value in bytes. /// -unsigned DIELabel::SizeOfImpl(const AsmPrinter *AP, dwarf::Form Form) const { +unsigned DIELabel::SizeOf(const AsmPrinter *AP, dwarf::Form Form) const { if (Form == dwarf::DW_FORM_data4) return 4; if (Form == dwarf::DW_FORM_sec_offset) return 4; if (Form == dwarf::DW_FORM_strp) return 4; @@ -380,9 +358,7 @@ unsigned DIELabel::SizeOfImpl(const AsmPrinter *AP, dwarf::Form Form) const { } #ifndef NDEBUG -void DIELabel::printImpl(raw_ostream &O) const { - O << "Lbl: " << Label->getName(); -} +void DIELabel::print(raw_ostream &O) const { O << "Lbl: " << Label->getName(); } #endif //===----------------------------------------------------------------------===// @@ -391,13 +367,13 @@ void DIELabel::printImpl(raw_ostream &O) const { /// EmitValue - Emit delta value. /// -void DIEDelta::EmitValueImpl(const AsmPrinter *AP, dwarf::Form Form) const { +void DIEDelta::EmitValue(const AsmPrinter *AP, dwarf::Form Form) const { AP->EmitLabelDifference(LabelHi, LabelLo, SizeOf(AP, Form)); } /// SizeOf - Determine size of delta value in bytes. /// -unsigned DIEDelta::SizeOfImpl(const AsmPrinter *AP, dwarf::Form Form) const { +unsigned DIEDelta::SizeOf(const AsmPrinter *AP, dwarf::Form Form) const { if (Form == dwarf::DW_FORM_data4) return 4; if (Form == dwarf::DW_FORM_sec_offset) return 4; if (Form == dwarf::DW_FORM_strp) return 4; @@ -405,7 +381,7 @@ unsigned DIEDelta::SizeOfImpl(const AsmPrinter *AP, dwarf::Form Form) const { } #ifndef NDEBUG -void DIEDelta::printImpl(raw_ostream &O) const { +void DIEDelta::print(raw_ostream &O) const { O << "Del: " << LabelHi->getName() << "-" << LabelLo->getName(); } #endif @@ -416,7 +392,7 @@ void DIEDelta::printImpl(raw_ostream &O) const { /// EmitValue - Emit string value. /// -void DIEString::EmitValueImpl(const AsmPrinter *AP, dwarf::Form Form) const { +void DIEString::EmitValue(const AsmPrinter *AP, dwarf::Form Form) const { assert( (Form == dwarf::DW_FORM_strp || Form == dwarf::DW_FORM_GNU_str_index) && "Expected valid string form"); @@ -440,7 +416,7 @@ void DIEString::EmitValueImpl(const AsmPrinter *AP, dwarf::Form Form) const { /// SizeOf - Determine size of delta value in bytes. /// -unsigned DIEString::SizeOfImpl(const AsmPrinter *AP, dwarf::Form Form) const { +unsigned DIEString::SizeOf(const AsmPrinter *AP, dwarf::Form Form) const { assert( (Form == dwarf::DW_FORM_strp || Form == dwarf::DW_FORM_GNU_str_index) && "Expected valid string form"); @@ -458,7 +434,7 @@ unsigned DIEString::SizeOfImpl(const AsmPrinter *AP, dwarf::Form Form) const { } #ifndef NDEBUG -void DIEString::printImpl(raw_ostream &O) const { +void DIEString::print(raw_ostream &O) const { O << "String: " << S.getString(); } #endif @@ -469,16 +445,16 @@ void DIEString::printImpl(raw_ostream &O) const { /// EmitValue - Emit debug information entry offset. /// -void DIEEntry::EmitValueImpl(const AsmPrinter *AP, dwarf::Form Form) const { +void DIEEntry::EmitValue(const AsmPrinter *AP, dwarf::Form Form) const { if (Form == dwarf::DW_FORM_ref_addr) { const DwarfDebug *DD = AP->getDwarfDebug(); - unsigned Addr = Entry.getOffset(); + unsigned Addr = Entry->getOffset(); assert(!DD->useSplitDwarf() && "TODO: dwo files can't have relocations."); // For DW_FORM_ref_addr, output the offset from beginning of debug info // section. Entry->getOffset() returns the offset from start of the // compile unit. - DwarfCompileUnit *CU = DD->lookupUnit(Entry.getUnit()); + DwarfCompileUnit *CU = DD->lookupUnit(Entry->getUnit()); assert(CU && "CUDie should belong to a CU."); Addr += CU->getDebugInfoOffset(); if (AP->MAI->doesDwarfUseRelocationsAcrossSections()) @@ -487,7 +463,7 @@ void DIEEntry::EmitValueImpl(const AsmPrinter *AP, dwarf::Form Form) const { else AP->OutStreamer->EmitIntValue(Addr, DIEEntry::getRefAddrSize(AP)); } else - AP->EmitInt32(Entry.getOffset()); + AP->EmitInt32(Entry->getOffset()); } unsigned DIEEntry::getRefAddrSize(const AsmPrinter *AP) { @@ -503,7 +479,7 @@ unsigned DIEEntry::getRefAddrSize(const AsmPrinter *AP) { } #ifndef NDEBUG -void DIEEntry::printImpl(raw_ostream &O) const { +void DIEEntry::print(raw_ostream &O) const { O << format("Die: 0x%lx", (long)(intptr_t)&Entry); } #endif @@ -511,14 +487,15 @@ void DIEEntry::printImpl(raw_ostream &O) const { //===----------------------------------------------------------------------===// // DIETypeSignature Implementation //===----------------------------------------------------------------------===// -void DIETypeSignature::EmitValueImpl(const AsmPrinter *Asm, dwarf::Form Form) const { +void DIETypeSignature::EmitValue(const AsmPrinter *Asm, + dwarf::Form Form) const { assert(Form == dwarf::DW_FORM_ref_sig8); - Asm->OutStreamer->EmitIntValue(Unit.getTypeSignature(), 8); + Asm->OutStreamer->EmitIntValue(Unit->getTypeSignature(), 8); } #ifndef NDEBUG -void DIETypeSignature::printImpl(raw_ostream &O) const { - O << format("Type Unit: 0x%lx", Unit.getTypeSignature()); +void DIETypeSignature::print(raw_ostream &O) const { + O << format("Type Unit: 0x%lx", Unit->getTypeSignature()); } #endif @@ -530,9 +507,8 @@ void DIETypeSignature::printImpl(raw_ostream &O) const { /// unsigned DIELoc::ComputeSize(const AsmPrinter *AP) const { if (!Size) { - const SmallVectorImpl &AbbrevData = Abbrev.getData(); for (unsigned i = 0, N = Values.size(); i < N; ++i) - Size += Values[i]->SizeOf(AP, AbbrevData[i].getForm()); + Size += Values[i].SizeOf(AP, Values[i].getForm()); } return Size; @@ -540,7 +516,7 @@ unsigned DIELoc::ComputeSize(const AsmPrinter *AP) const { /// EmitValue - Emit location data. /// -void DIELoc::EmitValueImpl(const AsmPrinter *Asm, dwarf::Form Form) const { +void DIELoc::EmitValue(const AsmPrinter *Asm, dwarf::Form Form) const { switch (Form) { default: llvm_unreachable("Improper form for block"); case dwarf::DW_FORM_block1: Asm->EmitInt8(Size); break; @@ -551,14 +527,13 @@ void DIELoc::EmitValueImpl(const AsmPrinter *Asm, dwarf::Form Form) const { Asm->EmitULEB128(Size); break; } - const SmallVectorImpl &AbbrevData = Abbrev.getData(); for (unsigned i = 0, N = Values.size(); i < N; ++i) - Values[i]->EmitValue(Asm, AbbrevData[i].getForm()); + Values[i].EmitValue(Asm, Values[i].getForm()); } /// SizeOf - Determine size of location data in bytes. /// -unsigned DIELoc::SizeOfImpl(const AsmPrinter *AP, dwarf::Form Form) const { +unsigned DIELoc::SizeOf(const AsmPrinter *AP, dwarf::Form Form) const { switch (Form) { case dwarf::DW_FORM_block1: return Size + sizeof(int8_t); case dwarf::DW_FORM_block2: return Size + sizeof(int16_t); @@ -571,7 +546,7 @@ unsigned DIELoc::SizeOfImpl(const AsmPrinter *AP, dwarf::Form Form) const { } #ifndef NDEBUG -void DIELoc::printImpl(raw_ostream &O) const { +void DIELoc::print(raw_ostream &O) const { O << "ExprLoc: "; DIE::print(O, 5); } @@ -585,9 +560,8 @@ void DIELoc::printImpl(raw_ostream &O) const { /// unsigned DIEBlock::ComputeSize(const AsmPrinter *AP) const { if (!Size) { - const SmallVectorImpl &AbbrevData = Abbrev.getData(); for (unsigned i = 0, N = Values.size(); i < N; ++i) - Size += Values[i]->SizeOf(AP, AbbrevData[i].getForm()); + Size += Values[i].SizeOf(AP, Values[i].getForm()); } return Size; @@ -595,7 +569,7 @@ unsigned DIEBlock::ComputeSize(const AsmPrinter *AP) const { /// EmitValue - Emit block data. /// -void DIEBlock::EmitValueImpl(const AsmPrinter *Asm, dwarf::Form Form) const { +void DIEBlock::EmitValue(const AsmPrinter *Asm, dwarf::Form Form) const { switch (Form) { default: llvm_unreachable("Improper form for block"); case dwarf::DW_FORM_block1: Asm->EmitInt8(Size); break; @@ -604,14 +578,13 @@ void DIEBlock::EmitValueImpl(const AsmPrinter *Asm, dwarf::Form Form) const { case dwarf::DW_FORM_block: Asm->EmitULEB128(Size); break; } - const SmallVectorImpl &AbbrevData = Abbrev.getData(); for (unsigned i = 0, N = Values.size(); i < N; ++i) - Values[i]->EmitValue(Asm, AbbrevData[i].getForm()); + Values[i].EmitValue(Asm, Values[i].getForm()); } /// SizeOf - Determine size of block data in bytes. /// -unsigned DIEBlock::SizeOfImpl(const AsmPrinter *AP, dwarf::Form Form) const { +unsigned DIEBlock::SizeOf(const AsmPrinter *AP, dwarf::Form Form) const { switch (Form) { case dwarf::DW_FORM_block1: return Size + sizeof(int8_t); case dwarf::DW_FORM_block2: return Size + sizeof(int16_t); @@ -622,7 +595,7 @@ unsigned DIEBlock::SizeOfImpl(const AsmPrinter *AP, dwarf::Form Form) const { } #ifndef NDEBUG -void DIEBlock::printImpl(raw_ostream &O) const { +void DIEBlock::print(raw_ostream &O) const { O << "Blk: "; DIE::print(O, 5); } @@ -632,7 +605,7 @@ void DIEBlock::printImpl(raw_ostream &O) const { // DIELocList Implementation //===----------------------------------------------------------------------===// -unsigned DIELocList::SizeOfImpl(const AsmPrinter *AP, dwarf::Form Form) const { +unsigned DIELocList::SizeOf(const AsmPrinter *AP, dwarf::Form Form) const { if (Form == dwarf::DW_FORM_data4) return 4; if (Form == dwarf::DW_FORM_sec_offset) @@ -642,7 +615,7 @@ unsigned DIELocList::SizeOfImpl(const AsmPrinter *AP, dwarf::Form Form) const { /// EmitValue - Emit label value. /// -void DIELocList::EmitValueImpl(const AsmPrinter *AP, dwarf::Form Form) const { +void DIELocList::EmitValue(const AsmPrinter *AP, dwarf::Form Form) const { DwarfDebug *DD = AP->getDwarfDebug(); MCSymbol *Label = DD->getDebugLocs().getList(Index).Label; @@ -653,8 +626,5 @@ void DIELocList::EmitValueImpl(const AsmPrinter *AP, dwarf::Form Form) const { } #ifndef NDEBUG -void DIELocList::printImpl(raw_ostream &O) const { - O << "LocList: " << Index; - -} +void DIELocList::print(raw_ostream &O) const { O << "LocList: " << Index; } #endif diff --git a/lib/CodeGen/AsmPrinter/DIEHash.cpp b/lib/CodeGen/AsmPrinter/DIEHash.cpp index a2e5aad96570f..1445254e6c284 100644 --- a/lib/CodeGen/AsmPrinter/DIEHash.cpp +++ b/lib/CodeGen/AsmPrinter/DIEHash.cpp @@ -31,19 +31,12 @@ using namespace llvm; /// \brief Grabs the string in whichever attribute is passed in and returns /// a reference to it. static StringRef getDIEStringAttr(const DIE &Die, uint16_t Attr) { - const SmallVectorImpl &Values = Die.getValues(); - const DIEAbbrev &Abbrevs = Die.getAbbrev(); - // Iterate through all the attributes until we find the one we're // looking for, if we can't find it return an empty string. - for (size_t i = 0; i < Values.size(); ++i) { - if (Abbrevs.getData()[i].getAttribute() == Attr) { - DIEValue *V = Values[i]; - assert(isa(V) && "String requested. Not a string."); - DIEString *S = cast(V); - return S->getString(); - } - } + for (const auto &V : Die.values()) + if (V.getAttribute() == Attr) + return V.getDIEString().getString(); + return StringRef(""); } @@ -123,20 +116,16 @@ void DIEHash::addParentContext(const DIE &Parent) { // Collect all of the attributes for a particular DIE in single structure. void DIEHash::collectAttributes(const DIE &Die, DIEAttrs &Attrs) { - const SmallVectorImpl &Values = Die.getValues(); - const DIEAbbrev &Abbrevs = Die.getAbbrev(); - #define COLLECT_ATTR(NAME) \ case dwarf::NAME: \ - Attrs.NAME.Val = Values[i]; \ - Attrs.NAME.Desc = &Abbrevs.getData()[i]; \ + Attrs.NAME = V; \ break - for (size_t i = 0, e = Values.size(); i != e; ++i) { + for (const auto &V : Die.values()) { DEBUG(dbgs() << "Attribute: " - << dwarf::AttributeString(Abbrevs.getData()[i].getAttribute()) + << dwarf::AttributeString(V.getAttribute()) << " added.\n"); - switch (Abbrevs.getData()[i].getAttribute()) { + switch (V.getAttribute()) { COLLECT_ATTR(DW_AT_name); COLLECT_ATTR(DW_AT_accessibility); COLLECT_ATTR(DW_AT_address_class); @@ -274,11 +263,9 @@ void DIEHash::hashDIEEntry(dwarf::Attribute Attribute, dwarf::Tag Tag, // Hash all of the values in a block like set of values. This assumes that // all of the data is going to be added as integers. -void DIEHash::hashBlockData(const SmallVectorImpl &Values) { - for (SmallVectorImpl::const_iterator I = Values.begin(), - E = Values.end(); - I != E; ++I) - Hash.update((uint64_t)cast(*I)->getValue()); +void DIEHash::hashBlockData(const DIE::value_range &Values) { + for (const auto &V : Values) + Hash.update((uint64_t)V.getDIEInteger().getValue()); } // Hash the contents of a loclistptr class. @@ -292,10 +279,8 @@ void DIEHash::hashLocList(const DIELocList &LocList) { // Hash an individual attribute \param Attr based on the type of attribute and // the form. -void DIEHash::hashAttribute(AttrEntry Attr, dwarf::Tag Tag) { - const DIEValue *Value = Attr.Val; - const DIEAbbrevData *Desc = Attr.Desc; - dwarf::Attribute Attribute = Desc->getAttribute(); +void DIEHash::hashAttribute(DIEValue Value, dwarf::Tag Tag) { + dwarf::Attribute Attribute = Value.getAttribute(); // Other attribute values use the letter 'A' as the marker, and the value // consists of the form code (encoded as an unsigned LEB128 value) followed by @@ -304,17 +289,20 @@ void DIEHash::hashAttribute(AttrEntry Attr, dwarf::Tag Tag) { // computation is limited to the following: DW_FORM_sdata, DW_FORM_flag, // DW_FORM_string, and DW_FORM_block. - switch (Value->getType()) { + switch (Value.getType()) { + case DIEValue::isNone: + llvm_unreachable("Expected valid DIEValue"); + // 7.27 Step 3 // ... An attribute that refers to another type entry T is processed as // follows: case DIEValue::isEntry: - hashDIEEntry(Attribute, Tag, cast(Value)->getEntry()); + hashDIEEntry(Attribute, Tag, Value.getDIEEntry().getEntry()); break; case DIEValue::isInteger: { addULEB128('A'); addULEB128(Attribute); - switch (Desc->getForm()) { + switch (Value.getForm()) { case dwarf::DW_FORM_data1: case dwarf::DW_FORM_data2: case dwarf::DW_FORM_data4: @@ -322,14 +310,14 @@ void DIEHash::hashAttribute(AttrEntry Attr, dwarf::Tag Tag) { case dwarf::DW_FORM_udata: case dwarf::DW_FORM_sdata: addULEB128(dwarf::DW_FORM_sdata); - addSLEB128((int64_t)cast(Value)->getValue()); + addSLEB128((int64_t)Value.getDIEInteger().getValue()); break; // DW_FORM_flag_present is just flag with a value of one. We still give it a // value so just use the value. case dwarf::DW_FORM_flag_present: case dwarf::DW_FORM_flag: addULEB128(dwarf::DW_FORM_flag); - addULEB128((int64_t)cast(Value)->getValue()); + addULEB128((int64_t)Value.getDIEInteger().getValue()); break; default: llvm_unreachable("Unknown integer form!"); @@ -340,7 +328,7 @@ void DIEHash::hashAttribute(AttrEntry Attr, dwarf::Tag Tag) { addULEB128('A'); addULEB128(Attribute); addULEB128(dwarf::DW_FORM_string); - addString(cast(Value)->getString()); + addString(Value.getDIEString().getString()); break; case DIEValue::isBlock: case DIEValue::isLoc: @@ -348,17 +336,17 @@ void DIEHash::hashAttribute(AttrEntry Attr, dwarf::Tag Tag) { addULEB128('A'); addULEB128(Attribute); addULEB128(dwarf::DW_FORM_block); - if (isa(Value)) { - addULEB128(cast(Value)->ComputeSize(AP)); - hashBlockData(cast(Value)->getValues()); - } else if (isa(Value)) { - addULEB128(cast(Value)->ComputeSize(AP)); - hashBlockData(cast(Value)->getValues()); + if (Value.getType() == DIEValue::isBlock) { + addULEB128(Value.getDIEBlock().ComputeSize(AP)); + hashBlockData(Value.getDIEBlock().values()); + } else if (Value.getType() == DIEValue::isLoc) { + addULEB128(Value.getDIELoc().ComputeSize(AP)); + hashBlockData(Value.getDIELoc().values()); } else { // We could add the block length, but that would take // a bit of work and not add a lot of uniqueness // to the hash in some way we could test. - hashLocList(*cast(Value)); + hashLocList(Value.getDIELocList()); } break; // FIXME: It's uncertain whether or not we should handle this at the moment. @@ -375,7 +363,7 @@ void DIEHash::hashAttribute(AttrEntry Attr, dwarf::Tag Tag) { void DIEHash::hashAttributes(const DIEAttrs &Attrs, dwarf::Tag Tag) { #define ADD_ATTR(ATTR) \ { \ - if (ATTR.Val != 0) \ + if (ATTR) \ hashAttribute(ATTR, Tag); \ } @@ -463,7 +451,7 @@ void DIEHash::computeHash(const DIE &Die) { addAttributes(Die); // Then hash each of the children of the DIE. - for (auto &C : Die.getChildren()) { + for (auto &C : Die.children()) { // 7.27 Step 7 // If C is a nested type entry or a member function entry, ... if (isType(C->getTag()) || C->getTag() == dwarf::DW_TAG_subprogram) { diff --git a/lib/CodeGen/AsmPrinter/DIEHash.h b/lib/CodeGen/AsmPrinter/DIEHash.h index ac014b727b753..1850e042f924b 100644 --- a/lib/CodeGen/AsmPrinter/DIEHash.h +++ b/lib/CodeGen/AsmPrinter/DIEHash.h @@ -26,64 +26,57 @@ class CompileUnit; /// \brief An object containing the capability of hashing and adding hash /// attributes onto a DIE. class DIEHash { - - // The entry for a particular attribute. - struct AttrEntry { - const DIEValue *Val; - const DIEAbbrevData *Desc; - }; - // Collection of all attributes used in hashing a particular DIE. struct DIEAttrs { - AttrEntry DW_AT_name; - AttrEntry DW_AT_accessibility; - AttrEntry DW_AT_address_class; - AttrEntry DW_AT_allocated; - AttrEntry DW_AT_artificial; - AttrEntry DW_AT_associated; - AttrEntry DW_AT_binary_scale; - AttrEntry DW_AT_bit_offset; - AttrEntry DW_AT_bit_size; - AttrEntry DW_AT_bit_stride; - AttrEntry DW_AT_byte_size; - AttrEntry DW_AT_byte_stride; - AttrEntry DW_AT_const_expr; - AttrEntry DW_AT_const_value; - AttrEntry DW_AT_containing_type; - AttrEntry DW_AT_count; - AttrEntry DW_AT_data_bit_offset; - AttrEntry DW_AT_data_location; - AttrEntry DW_AT_data_member_location; - AttrEntry DW_AT_decimal_scale; - AttrEntry DW_AT_decimal_sign; - AttrEntry DW_AT_default_value; - AttrEntry DW_AT_digit_count; - AttrEntry DW_AT_discr; - AttrEntry DW_AT_discr_list; - AttrEntry DW_AT_discr_value; - AttrEntry DW_AT_encoding; - AttrEntry DW_AT_enum_class; - AttrEntry DW_AT_endianity; - AttrEntry DW_AT_explicit; - AttrEntry DW_AT_is_optional; - AttrEntry DW_AT_location; - AttrEntry DW_AT_lower_bound; - AttrEntry DW_AT_mutable; - AttrEntry DW_AT_ordering; - AttrEntry DW_AT_picture_string; - AttrEntry DW_AT_prototyped; - AttrEntry DW_AT_small; - AttrEntry DW_AT_segment; - AttrEntry DW_AT_string_length; - AttrEntry DW_AT_threads_scaled; - AttrEntry DW_AT_upper_bound; - AttrEntry DW_AT_use_location; - AttrEntry DW_AT_use_UTF8; - AttrEntry DW_AT_variable_parameter; - AttrEntry DW_AT_virtuality; - AttrEntry DW_AT_visibility; - AttrEntry DW_AT_vtable_elem_location; - AttrEntry DW_AT_type; + DIEValue DW_AT_name; + DIEValue DW_AT_accessibility; + DIEValue DW_AT_address_class; + DIEValue DW_AT_allocated; + DIEValue DW_AT_artificial; + DIEValue DW_AT_associated; + DIEValue DW_AT_binary_scale; + DIEValue DW_AT_bit_offset; + DIEValue DW_AT_bit_size; + DIEValue DW_AT_bit_stride; + DIEValue DW_AT_byte_size; + DIEValue DW_AT_byte_stride; + DIEValue DW_AT_const_expr; + DIEValue DW_AT_const_value; + DIEValue DW_AT_containing_type; + DIEValue DW_AT_count; + DIEValue DW_AT_data_bit_offset; + DIEValue DW_AT_data_location; + DIEValue DW_AT_data_member_location; + DIEValue DW_AT_decimal_scale; + DIEValue DW_AT_decimal_sign; + DIEValue DW_AT_default_value; + DIEValue DW_AT_digit_count; + DIEValue DW_AT_discr; + DIEValue DW_AT_discr_list; + DIEValue DW_AT_discr_value; + DIEValue DW_AT_encoding; + DIEValue DW_AT_enum_class; + DIEValue DW_AT_endianity; + DIEValue DW_AT_explicit; + DIEValue DW_AT_is_optional; + DIEValue DW_AT_location; + DIEValue DW_AT_lower_bound; + DIEValue DW_AT_mutable; + DIEValue DW_AT_ordering; + DIEValue DW_AT_picture_string; + DIEValue DW_AT_prototyped; + DIEValue DW_AT_small; + DIEValue DW_AT_segment; + DIEValue DW_AT_string_length; + DIEValue DW_AT_threads_scaled; + DIEValue DW_AT_upper_bound; + DIEValue DW_AT_use_location; + DIEValue DW_AT_use_UTF8; + DIEValue DW_AT_variable_parameter; + DIEValue DW_AT_virtuality; + DIEValue DW_AT_visibility; + DIEValue DW_AT_vtable_elem_location; + DIEValue DW_AT_type; // Insert any additional ones here... }; @@ -135,13 +128,13 @@ private: /// \brief Hashes the data in a block like DIEValue, e.g. DW_FORM_block or /// DW_FORM_exprloc. - void hashBlockData(const SmallVectorImpl &Values); + void hashBlockData(const DIE::value_range &Values); /// \brief Hashes the contents pointed to in the .debug_loc section. void hashLocList(const DIELocList &LocList); /// \brief Hashes an individual attribute. - void hashAttribute(AttrEntry Attr, dwarf::Tag Tag); + void hashAttribute(DIEValue Value, dwarf::Tag Tag); /// \brief Hashes an attribute that refers to another DIE. void hashDIEEntry(dwarf::Attribute Attribute, dwarf::Tag Tag, diff --git a/lib/CodeGen/AsmPrinter/DwarfAccelTable.cpp b/lib/CodeGen/AsmPrinter/DwarfAccelTable.cpp index 58b406b788fbb..f8cdde203187e 100644 --- a/lib/CodeGen/AsmPrinter/DwarfAccelTable.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfAccelTable.cpp @@ -192,9 +192,9 @@ void DwarfAccelTable::emitOffsets(AsmPrinter *Asm, const MCSymbol *SecBegin) { PrevHash = HashValue; Asm->OutStreamer->AddComment("Offset in Bucket " + Twine(i)); MCContext &Context = Asm->OutStreamer->getContext(); - const MCExpr *Sub = MCBinaryExpr::CreateSub( - MCSymbolRefExpr::Create((*HI)->Sym, Context), - MCSymbolRefExpr::Create(SecBegin, Context), Context); + const MCExpr *Sub = MCBinaryExpr::createSub( + MCSymbolRefExpr::create((*HI)->Sym, Context), + MCSymbolRefExpr::create(SecBegin, Context), Context); Asm->OutStreamer->EmitValue(Sub, sizeof(uint32_t)); } } diff --git a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp index c10e70352af00..689184a651ed1 100644 --- a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp @@ -42,8 +42,7 @@ void DwarfCompileUnit::addLabelAddress(DIE &Die, dwarf::Attribute Attribute, DD->addArangeLabel(SymbolCU(this, Label)); unsigned idx = DD->getAddressPool().getIndex(Label); - DIEValue *Value = new (DIEValueAllocator) DIEInteger(idx); - Die.addValue(Attribute, dwarf::DW_FORM_GNU_addr_index, Value); + Die.addValue(Attribute, dwarf::DW_FORM_GNU_addr_index, DIEInteger(idx)); } void DwarfCompileUnit::addLocalLabelAddress(DIE &Die, @@ -52,9 +51,10 @@ void DwarfCompileUnit::addLocalLabelAddress(DIE &Die, if (Label) DD->addArangeLabel(SymbolCU(this, Label)); - Die.addValue(Attribute, dwarf::DW_FORM_addr, - Label ? (DIEValue *)new (DIEValueAllocator) DIELabel(Label) - : new (DIEValueAllocator) DIEInteger(0)); + if (Label) + Die.addValue(Attribute, dwarf::DW_FORM_addr, DIELabel(Label)); + else + Die.addValue(Attribute, dwarf::DW_FORM_addr, DIEInteger(0)); } unsigned DwarfCompileUnit::getOrCreateSourceID(StringRef FileName, @@ -145,7 +145,7 @@ DIE *DwarfCompileUnit::getOrCreateGlobalVariableDIE( bool addToAccelTable = false; if (auto *Global = dyn_cast_or_null(GV->getVariable())) { addToAccelTable = true; - DIELoc *Loc = new (DIEValueAllocator) DIELoc(); + DIELoc *Loc = new (DIEValueAllocator) DIELoc; const MCSymbol *Sym = Asm->getSymbol(Global); if (Global->isThreadLocal()) { // FIXME: Make this work with -gsplit-dwarf. @@ -183,7 +183,7 @@ DIE *DwarfCompileUnit::getOrCreateGlobalVariableDIE( } else if (const ConstantExpr *CE = getMergedGlobalExpr(GV->getVariable())) { addToAccelTable = true; // GV is a merged global. - DIELoc *Loc = new (DIEValueAllocator) DIELoc(); + DIELoc *Loc = new (DIEValueAllocator) DIELoc; Value *Ptr = CE->getOperand(0); MCSymbol *Sym = Asm->getSymbol(cast(Ptr)); DD->addArangeLabel(SymbolCU(this, Sym)); @@ -242,7 +242,7 @@ void DwarfCompileUnit::initStmtList() { MCSymbol *LineTableStartSym = Asm->OutStreamer->getDwarfLineTableSymbol(getUniqueID()); - stmtListIndex = UnitDie.getValues().size(); + stmtListIndex = std::distance(UnitDie.values_begin(), UnitDie.values_end()); // DW_AT_stmt_list is a offset of line number information for this // compile unit in debug_line section. For split dwarf this is @@ -255,9 +255,7 @@ void DwarfCompileUnit::initStmtList() { } void DwarfCompileUnit::applyStmtList(DIE &D) { - D.addValue(dwarf::DW_AT_stmt_list, - UnitDie.getAbbrev().getData()[stmtListIndex].getForm(), - UnitDie.getValues()[stmtListIndex]); + D.addValue(UnitDie.values_begin()[stmtListIndex]); } void DwarfCompileUnit::attachLowHighPC(DIE &D, const MCSymbol *Begin, @@ -365,10 +363,9 @@ void DwarfCompileUnit::constructScopeDIE( void DwarfCompileUnit::addSectionDelta(DIE &Die, dwarf::Attribute Attribute, const MCSymbol *Hi, const MCSymbol *Lo) { - DIEValue *Value = new (DIEValueAllocator) DIEDelta(Hi, Lo); Die.addValue(Attribute, DD->getDwarfVersion() >= 4 ? dwarf::DW_FORM_sec_offset : dwarf::DW_FORM_data4, - Value); + new (DIEValueAllocator) DIEDelta(Hi, Lo)); } void DwarfCompileUnit::addScopeRangeList(DIE &ScopeDIE, @@ -515,7 +512,7 @@ DwarfCompileUnit::constructVariableDIEImpl(const DbgVariable &DV, return VariableDie; auto Expr = DV.getExpression().begin(); - DIELoc *Loc = new (DIEValueAllocator) DIELoc(); + DIELoc *Loc = new (DIEValueAllocator) DIELoc; DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc); for (auto FI : DV.getFrameIndex()) { unsigned FrameReg = 0; @@ -739,7 +736,7 @@ void DwarfCompileUnit::addVariableAddress(const DbgVariable &DV, DIE &Die, /// Add an address attribute to a die based on the location provided. void DwarfCompileUnit::addAddress(DIE &Die, dwarf::Attribute Attribute, const MachineLocation &Location) { - DIELoc *Loc = new (DIEValueAllocator) DIELoc(); + DIELoc *Loc = new (DIEValueAllocator) DIELoc; bool validReg; if (Location.isReg()) @@ -761,7 +758,7 @@ void DwarfCompileUnit::addAddress(DIE &Die, dwarf::Attribute Attribute, void DwarfCompileUnit::addComplexAddress(const DbgVariable &DV, DIE &Die, dwarf::Attribute Attribute, const MachineLocation &Location) { - DIELoc *Loc = new (DIEValueAllocator) DIELoc(); + DIELoc *Loc = new (DIEValueAllocator) DIELoc; DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc); assert(DV.getExpression().size() == 1); const DIExpression *Expr = DV.getExpression().back(); @@ -782,10 +779,9 @@ void DwarfCompileUnit::addComplexAddress(const DbgVariable &DV, DIE &Die, /// Add a Dwarf loclistptr attribute data and value. void DwarfCompileUnit::addLocationList(DIE &Die, dwarf::Attribute Attribute, unsigned Index) { - DIEValue *Value = new (DIEValueAllocator) DIELocList(Index); dwarf::Form Form = DD->getDwarfVersion() >= 4 ? dwarf::DW_FORM_sec_offset : dwarf::DW_FORM_data4; - Die.addValue(Attribute, Form, Value); + Die.addValue(Attribute, Form, DIELocList(Index)); } void DwarfCompileUnit::applyVariableAttributes(const DbgVariable &Var, @@ -802,8 +798,7 @@ void DwarfCompileUnit::applyVariableAttributes(const DbgVariable &Var, /// Add a Dwarf expression attribute data and value. void DwarfCompileUnit::addExpr(DIELoc &Die, dwarf::Form Form, const MCExpr *Expr) { - DIEValue *Value = new (DIEValueAllocator) DIEExpr(Expr); - Die.addValue((dwarf::Attribute)0, Form, Value); + Die.addValue((dwarf::Attribute)0, Form, DIEExpr(Expr)); } void DwarfCompileUnit::applySubprogramAttributesToDefinition( diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 105ff6c198f88..3f6665bd57686 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -1340,9 +1340,8 @@ static dwarf::PubIndexEntryDescriptor computeIndexValue(DwarfUnit *CU, // We could have a specification DIE that has our most of our knowledge, // look for that now. - DIEValue *SpecVal = Die->findAttribute(dwarf::DW_AT_specification); - if (SpecVal) { - DIE &SpecDIE = cast(SpecVal)->getEntry(); + if (DIEValue SpecVal = Die->findAttribute(dwarf::DW_AT_specification)) { + DIE &SpecDIE = SpecVal.getDIEEntry().getEntry(); if (SpecDIE.findAttribute(dwarf::DW_AT_external)) Linkage = dwarf::GIEL_EXTERNAL; } else if (Die->findAttribute(dwarf::DW_AT_external)) @@ -1563,6 +1562,8 @@ void DwarfDebug::emitDebugLoc() { Asm->OutStreamer->EmitLabel(List.Label); const DwarfCompileUnit *CU = List.CU; for (const auto &Entry : DebugLocs.getEntries(List)) { + if (Entry.BeginSym == Entry.EndSym) + continue; // Set up the range. This range is relative to the entry point of the // compile unit. This is a hard coded 0 for low_pc when we're emitting // ranges, or the DW_AT_low_pc on the compile unit otherwise. diff --git a/lib/CodeGen/AsmPrinter/DwarfExpression.cpp b/lib/CodeGen/AsmPrinter/DwarfExpression.cpp index a2799b8d63002..d56982712d53e 100644 --- a/lib/CodeGen/AsmPrinter/DwarfExpression.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfExpression.cpp @@ -65,6 +65,11 @@ void DwarfExpression::AddShr(unsigned ShiftBy) { EmitOp(dwarf::DW_OP_shr); } +void DwarfExpression::AddOpStackValue() { + if (DwarfVersion >= 4) + EmitOp(dwarf::DW_OP_stack_value); +} + bool DwarfExpression::AddMachineRegIndirect(unsigned MachineReg, int Offset) { if (isFrameRegister(MachineReg)) { // If variable offset is based in frame register then use fbreg. @@ -172,16 +177,14 @@ void DwarfExpression::AddSignedConstant(int Value) { // value, so the producers and consumers started to rely on heuristics // to disambiguate the value vs. location status of the expression. // See PR21176 for more details. - if (DwarfVersion >= 4) - EmitOp(dwarf::DW_OP_stack_value); + AddOpStackValue(); } void DwarfExpression::AddUnsignedConstant(unsigned Value) { EmitOp(dwarf::DW_OP_constu); EmitUnsigned(Value); // cf. comment in DwarfExpression::AddSignedConstant(). - if (DwarfVersion >= 4) - EmitOp(dwarf::DW_OP_stack_value); + AddOpStackValue(); } static unsigned getOffsetOrZero(unsigned OffsetInBits, @@ -212,15 +215,30 @@ bool DwarfExpression::AddMachineRegExpression(const DIExpression *Expr, getOffsetOrZero(OffsetInBits, PieceOffsetInBits)); } case dwarf::DW_OP_plus: { - // [DW_OP_reg,Offset,DW_OP_plus,DW_OP_deref] --> [DW_OP_breg,Offset]. auto N = I.getNext(); + unsigned Offset = I->getArg(0); + // First combine all DW_OP_plus until we hit either a DW_OP_deref or a + // DW_OP_bit_piece + while (N != E && N->getOp() == dwarf::DW_OP_plus) { + Offset += N->getArg(0); + ++I; + N = I.getNext(); + } if (N != E && N->getOp() == dwarf::DW_OP_deref) { - unsigned Offset = I->getArg(0); + // [DW_OP_reg,Offset,DW_OP_plus,DW_OP_deref] --> [DW_OP_breg,Offset]. ValidReg = AddMachineRegIndirect(MachineReg, Offset); std::advance(I, 2); - break; - } else - ValidReg = AddMachineRegPiece(MachineReg); + } else { + assert ((N == E) || (N->getOp() == dwarf::DW_OP_bit_piece)); + if (Offset == 0) { + ValidReg = AddMachineRegPiece(MachineReg); + } else { + ValidReg = AddMachineRegIndirect(MachineReg, Offset); + AddOpStackValue(); + } + ++I; + } + break; } case dwarf::DW_OP_deref: { // [DW_OP_reg,DW_OP_deref] --> [DW_OP_breg]. @@ -237,6 +255,7 @@ bool DwarfExpression::AddMachineRegExpression(const DIExpression *Expr, // Emit remaining elements of the expression. AddExpression(I, E, PieceOffsetInBits); + return true; } diff --git a/lib/CodeGen/AsmPrinter/DwarfExpression.h b/lib/CodeGen/AsmPrinter/DwarfExpression.h index 78ec937a6b602..f6249fff4253e 100644 --- a/lib/CodeGen/AsmPrinter/DwarfExpression.h +++ b/lib/CodeGen/AsmPrinter/DwarfExpression.h @@ -83,6 +83,9 @@ public: bool AddMachineRegPiece(unsigned MachineReg, unsigned PieceSizeInBits = 0, unsigned PieceOffsetInBits = 0); + /// Emit a DW_OP_stack_value + void AddOpStackValue(); + /// Emit a signed constant. void AddSignedConstant(int Value); /// Emit an unsigned constant. diff --git a/lib/CodeGen/AsmPrinter/DwarfFile.cpp b/lib/CodeGen/AsmPrinter/DwarfFile.cpp index 10b58d4e86ae9..5ef333c4cf443 100644 --- a/lib/CodeGen/AsmPrinter/DwarfFile.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfFile.cpp @@ -20,25 +20,34 @@ namespace llvm { DwarfFile::DwarfFile(AsmPrinter *AP, StringRef Pref, BumpPtrAllocator &DA) : Asm(AP), StrPool(DA, *Asm, Pref) {} -DwarfFile::~DwarfFile() {} +DwarfFile::~DwarfFile() { + for (DIEAbbrev *Abbrev : Abbreviations) + Abbrev->~DIEAbbrev(); +} // Define a unique number for the abbreviation. // -void DwarfFile::assignAbbrevNumber(DIEAbbrev &Abbrev) { - // Check the set for priors. - DIEAbbrev *InSet = AbbreviationsSet.GetOrInsertNode(&Abbrev); - - // If it's newly added. - if (InSet == &Abbrev) { - // Add to abbreviation list. - Abbreviations.push_back(&Abbrev); - - // Assign the vector position + 1 as its number. - Abbrev.setNumber(Abbreviations.size()); - } else { - // Assign existing abbreviation number. - Abbrev.setNumber(InSet->getNumber()); +DIEAbbrev &DwarfFile::assignAbbrevNumber(DIE &Die) { + FoldingSetNodeID ID; + DIEAbbrev Abbrev = Die.generateAbbrev(); + Abbrev.Profile(ID); + + void *InsertPos; + if (DIEAbbrev *Existing = + AbbreviationsSet.FindNodeOrInsertPos(ID, InsertPos)) { + Die.setAbbrevNumber(Existing->getNumber()); + return *Existing; } + + // Move the abbreviation to the heap and assign a number. + DIEAbbrev *New = new (AbbrevAllocator) DIEAbbrev(std::move(Abbrev)); + Abbreviations.push_back(New); + New->setNumber(Abbreviations.size()); + Die.setAbbrevNumber(Abbreviations.size()); + + // Store it for lookup. + AbbreviationsSet.InsertNode(New, InsertPos); + return *New; } void DwarfFile::addUnit(std::unique_ptr U) { @@ -83,10 +92,7 @@ void DwarfFile::computeSizeAndOffsets() { // CU. It returns the offset after laying out the DIE. unsigned DwarfFile::computeSizeAndOffset(DIE &Die, unsigned Offset) { // Record the abbreviation. - assignAbbrevNumber(Die.getAbbrev()); - - // Get the abbreviation for this DIE. - const DIEAbbrev &Abbrev = Die.getAbbrev(); + const DIEAbbrev &Abbrev = assignAbbrevNumber(Die); // Set DIE offset Die.setOffset(Offset); @@ -94,22 +100,17 @@ unsigned DwarfFile::computeSizeAndOffset(DIE &Die, unsigned Offset) { // Start the size with the size of abbreviation code. Offset += getULEB128Size(Die.getAbbrevNumber()); - const SmallVectorImpl &Values = Die.getValues(); - const SmallVectorImpl &AbbrevData = Abbrev.getData(); - // Size the DIE attribute values. - for (unsigned i = 0, N = Values.size(); i < N; ++i) + for (const auto &V : Die.values()) // Size attribute value. - Offset += Values[i]->SizeOf(Asm, AbbrevData[i].getForm()); - - // Get the children. - const auto &Children = Die.getChildren(); + Offset += V.SizeOf(Asm, V.getForm()); // Size the DIE children if any. - if (!Children.empty()) { + if (Die.hasChildren()) { + (void)Abbrev; assert(Abbrev.hasChildren() && "Children flag not set"); - for (auto &Child : Children) + for (auto &Child : Die.children()) Offset = computeSizeAndOffset(*Child, Offset); // End of children marker. diff --git a/lib/CodeGen/AsmPrinter/DwarfFile.h b/lib/CodeGen/AsmPrinter/DwarfFile.h index 532ed96c2689b..8402027edd6ff 100644 --- a/lib/CodeGen/AsmPrinter/DwarfFile.h +++ b/lib/CodeGen/AsmPrinter/DwarfFile.h @@ -37,6 +37,8 @@ class DwarfFile { // Target of Dwarf emission, used for sizing of abbreviations. AsmPrinter *Asm; + BumpPtrAllocator AbbrevAllocator; + // Used to uniquely define abbreviations. FoldingSet AbbreviationsSet; @@ -72,8 +74,11 @@ public: /// \brief Compute the size and offset of all the DIEs. void computeSizeAndOffsets(); - /// \brief Define a unique number for the abbreviation. - void assignAbbrevNumber(DIEAbbrev &Abbrev); + /// Define a unique number for the abbreviation. + /// + /// Compute the abbreviation for \c Die, look up its unique number, and + /// return a reference to it in the uniquing table. + DIEAbbrev &assignAbbrevNumber(DIE &Die); /// \brief Add a unit to the list of CUs. void addUnit(std::unique_ptr U); diff --git a/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/lib/CodeGen/AsmPrinter/DwarfUnit.cpp index 04836c6140445..907f6706bc6a9 100644 --- a/lib/CodeGen/AsmPrinter/DwarfUnit.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfUnit.cpp @@ -70,7 +70,6 @@ DwarfUnit::DwarfUnit(unsigned UID, dwarf::Tag UnitTag, DD(DW), DU(DWU), IndexTyDie(nullptr), Section(nullptr) { assert(UnitTag == dwarf::DW_TAG_compile_unit || UnitTag == dwarf::DW_TAG_type_unit); - DIEIntegerOne = new (DIEValueAllocator) DIEInteger(1); } DwarfTypeUnit::DwarfTypeUnit(unsigned UID, DwarfCompileUnit &CU, AsmPrinter *A, @@ -89,11 +88,6 @@ DwarfUnit::~DwarfUnit() { DIELocs[j]->~DIELoc(); } -DIEEntry *DwarfUnit::createDIEEntry(DIE &Entry) { - DIEEntry *Value = new (DIEValueAllocator) DIEEntry(Entry); - return Value; -} - int64_t DwarfUnit::getDefaultLowerBound() const { switch (getLanguage()) { default: @@ -190,18 +184,16 @@ void DwarfUnit::insertDIE(const DINode *Desc, DIE *D) { void DwarfUnit::addFlag(DIE &Die, dwarf::Attribute Attribute) { if (DD->getDwarfVersion() >= 4) - Die.addValue(Attribute, dwarf::DW_FORM_flag_present, DIEIntegerOne); + Die.addValue(Attribute, dwarf::DW_FORM_flag_present, DIEInteger(1)); else - Die.addValue(Attribute, dwarf::DW_FORM_flag, DIEIntegerOne); + Die.addValue(Attribute, dwarf::DW_FORM_flag, DIEInteger(1)); } void DwarfUnit::addUInt(DIE &Die, dwarf::Attribute Attribute, Optional Form, uint64_t Integer) { if (!Form) Form = DIEInteger::BestForm(false, Integer); - DIEValue *Value = Integer == 1 ? DIEIntegerOne : new (DIEValueAllocator) - DIEInteger(Integer); - Die.addValue(Attribute, *Form, Value); + Die.addValue(Attribute, *Form, DIEInteger(Integer)); } void DwarfUnit::addUInt(DIE &Block, dwarf::Form Form, uint64_t Integer) { @@ -212,8 +204,7 @@ void DwarfUnit::addSInt(DIE &Die, dwarf::Attribute Attribute, Optional Form, int64_t Integer) { if (!Form) Form = DIEInteger::BestForm(true, Integer); - DIEValue *Value = new (DIEValueAllocator) DIEInteger(Integer); - Die.addValue(Attribute, *Form, Value); + Die.addValue(Attribute, *Form, DIEInteger(Integer)); } void DwarfUnit::addSInt(DIELoc &Die, Optional Form, @@ -225,14 +216,12 @@ void DwarfUnit::addString(DIE &Die, dwarf::Attribute Attribute, StringRef String) { Die.addValue(Attribute, isDwoUnit() ? dwarf::DW_FORM_GNU_str_index : dwarf::DW_FORM_strp, - new (DIEValueAllocator) DIEString(DU->getStringPool().getEntry(*Asm, String))); } void DwarfUnit::addLabel(DIE &Die, dwarf::Attribute Attribute, dwarf::Form Form, const MCSymbol *Label) { - DIEValue *Value = new (DIEValueAllocator) DIELabel(Label); - Die.addValue(Attribute, Form, Value); + Die.addValue(Attribute, Form, DIELabel(Label)); } void DwarfUnit::addLabel(DIELoc &Die, dwarf::Form Form, const MCSymbol *Label) { @@ -265,12 +254,12 @@ void DwarfUnit::addOpAddress(DIELoc &Die, const MCSymbol *Sym) { void DwarfUnit::addLabelDelta(DIE &Die, dwarf::Attribute Attribute, const MCSymbol *Hi, const MCSymbol *Lo) { - DIEValue *Value = new (DIEValueAllocator) DIEDelta(Hi, Lo); - Die.addValue(Attribute, dwarf::DW_FORM_data4, Value); + Die.addValue(Attribute, dwarf::DW_FORM_data4, + new (DIEValueAllocator) DIEDelta(Hi, Lo)); } void DwarfUnit::addDIEEntry(DIE &Die, dwarf::Attribute Attribute, DIE &Entry) { - addDIEEntry(Die, Attribute, createDIEEntry(Entry)); + addDIEEntry(Die, Attribute, DIEEntry(Entry)); } void DwarfUnit::addDIETypeSignature(DIE &Die, const DwarfTypeUnit &Type) { @@ -281,13 +270,13 @@ void DwarfUnit::addDIETypeSignature(DIE &Die, const DwarfTypeUnit &Type) { addFlag(Die, dwarf::DW_AT_declaration); Die.addValue(dwarf::DW_AT_signature, dwarf::DW_FORM_ref_sig8, - new (DIEValueAllocator) DIETypeSignature(Type)); + DIETypeSignature(Type)); } void DwarfUnit::addDIEEntry(DIE &Die, dwarf::Attribute Attribute, - DIEEntry *Entry) { + DIEEntry Entry) { const DIE *DieCU = Die.getUnitOrNull(); - const DIE *EntryCU = Entry->getEntry().getUnitOrNull(); + const DIE *EntryCU = Entry.getEntry().getUnitOrNull(); if (!DieCU) // We assume that Die belongs to this CU, if it is not linked to any CU yet. DieCU = &getUnitDie(); @@ -301,8 +290,7 @@ void DwarfUnit::addDIEEntry(DIE &Die, dwarf::Attribute Attribute, DIE &DwarfUnit::createAndAddDIE(unsigned Tag, DIE &Parent, const DINode *N) { assert(Tag != dwarf::DW_TAG_auto_variable && Tag != dwarf::DW_TAG_arg_variable); - Parent.addChild(make_unique((dwarf::Tag)Tag)); - DIE &Die = *Parent.getChildren().back(); + DIE &Die = Parent.addChild(make_unique((dwarf::Tag)Tag)); if (N) insertDIE(N, &Die); return Die; @@ -471,7 +459,7 @@ void DwarfUnit::addBlockByrefAddress(const DbgVariable &DV, DIE &Die, // Decode the original location, and use that as the start of the byref // variable's location. - DIELoc *Loc = new (DIEValueAllocator) DIELoc(); + DIELoc *Loc = new (DIEValueAllocator) DIELoc; bool validReg; if (Location.isReg()) @@ -588,7 +576,7 @@ static uint64_t getBaseTypeSize(DwarfDebug *DD, const DIDerivedType *Ty) { void DwarfUnit::addConstantFPValue(DIE &Die, const MachineOperand &MO) { assert(MO.isFPImm() && "Invalid machine operand!"); - DIEBlock *Block = new (DIEValueAllocator) DIEBlock(); + DIEBlock *Block = new (DIEValueAllocator) DIEBlock; APFloat FPImm = MO.getFPImm()->getValueAPF(); // Get the raw data form of the floating point. @@ -644,7 +632,7 @@ void DwarfUnit::addConstantValue(DIE &Die, const APInt &Val, bool Unsigned) { return; } - DIEBlock *Block = new (DIEValueAllocator) DIEBlock(); + DIEBlock *Block = new (DIEValueAllocator) DIEBlock; // Get the raw data form of the large APInt. const uint64_t *Ptr64 = Val.getRawData(); @@ -777,22 +765,7 @@ void DwarfUnit::updateAcceleratorTables(const DIScope *Context, void DwarfUnit::addType(DIE &Entity, const DIType *Ty, dwarf::Attribute Attribute) { assert(Ty && "Trying to add a type that doesn't exist?"); - - // Check for pre-existence. - DIEEntry *Entry = getDIEEntry(Ty); - // If it exists then use the existing value. - if (Entry) { - addDIEEntry(Entity, Attribute, Entry); - return; - } - - // Construct type. - DIE *Buffer = getOrCreateTypeDIE(Ty); - - // Set up proxy. - Entry = createDIEEntry(*Buffer); - insertDIEEntry(Ty, Entry); - addDIEEntry(Entity, Attribute, Entry); + addDIEEntry(Entity, Attribute, DIEEntry(*getOrCreateTypeDIE(Ty))); } std::string DwarfUnit::getParentContextString(const DIScope *Context) const { @@ -969,12 +942,6 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, const DICompositeType *CTy) { if (unsigned PropertyAttributes = Property->getAttributes()) addUInt(ElemDie, dwarf::DW_AT_APPLE_property_attribute, None, PropertyAttributes); - - DIEEntry *Entry = getDIEEntry(Element); - if (!Entry) { - Entry = createDIEEntry(ElemDie); - insertDIEEntry(Element, Entry); - } } } @@ -1061,7 +1028,7 @@ void DwarfUnit::constructTemplateValueParameterDIE( else if (GlobalValue *GV = mdconst::dyn_extract(Val)) { // For declaration non-type template parameters (such as global values and // functions) - DIELoc *Loc = new (DIEValueAllocator) DIELoc(); + DIELoc *Loc = new (DIEValueAllocator) DIELoc; addOpAddress(*Loc, Asm->getSymbol(GV)); // Emit DW_OP_stack_value to use the address as the immediate value of the // parameter, rather than a pointer to it. @@ -1354,7 +1321,7 @@ void DwarfUnit::constructMemberDIE(DIE &Buffer, const DIDerivedType *DT) { // expression to extract appropriate offset from vtable. // BaseAddr = ObAddr + *((*ObAddr) - Offset) - DIELoc *VBaseLocationDie = new (DIEValueAllocator) DIELoc(); + DIELoc *VBaseLocationDie = new (DIEValueAllocator) DIELoc; addUInt(*VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_dup); addUInt(*VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_deref); addUInt(*VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_constu); @@ -1393,7 +1360,7 @@ void DwarfUnit::constructMemberDIE(DIE &Buffer, const DIDerivedType *DT) { OffsetInBytes = DT->getOffsetInBits() >> 3; if (DD->getDwarfVersion() <= 2) { - DIELoc *MemLocationDie = new (DIEValueAllocator) DIELoc(); + DIELoc *MemLocationDie = new (DIEValueAllocator) DIELoc; addUInt(*MemLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst); addUInt(*MemLocationDie, dwarf::DW_FORM_udata, OffsetInBytes); addBlock(MemberDie, dwarf::DW_AT_data_member_location, MemLocationDie); @@ -1417,10 +1384,10 @@ void DwarfUnit::constructMemberDIE(DIE &Buffer, const DIDerivedType *DT) { dwarf::DW_VIRTUALITY_virtual); // Objective-C properties. - if (MDNode *PNode = DT->getObjCProperty()) - if (DIEEntry *PropertyDie = getDIEEntry(PNode)) + if (DINode *PNode = DT->getObjCProperty()) + if (DIE *PDie = getDIE(PNode)) MemberDie.addValue(dwarf::DW_AT_APPLE_property, dwarf::DW_FORM_ref4, - PropertyDie); + DIEEntry(*PDie)); if (DT->isArtificial()) addFlag(MemberDie, dwarf::DW_AT_artificial); diff --git a/lib/CodeGen/AsmPrinter/DwarfUnit.h b/lib/CodeGen/AsmPrinter/DwarfUnit.h index 0d01a9e9fb386..f56c9b4eb13e7 100644 --- a/lib/CodeGen/AsmPrinter/DwarfUnit.h +++ b/lib/CodeGen/AsmPrinter/DwarfUnit.h @@ -93,10 +93,6 @@ protected: /// information entries. DenseMap MDNodeToDieMap; - /// Tracks the mapping of unit level debug information descriptors to debug - /// information entries using a DIEEntry proxy. - DenseMap MDNodeToDIEEntryMap; - /// A list of all the DIEBlocks in use. std::vector DIEBlocks; @@ -111,9 +107,6 @@ protected: // All DIEValues are allocated through this allocator. BumpPtrAllocator DIEValueAllocator; - // A preallocated DIEValue because 1 is used frequently. - DIEInteger *DIEIntegerOne; - /// The section this unit will be emitted in. MCSection *Section; @@ -150,7 +143,7 @@ public: void setDebugInfoOffset(unsigned DbgInfoOff) { DebugInfoOffset = DbgInfoOff; } /// \brief Return true if this compile unit has something to write out. - bool hasContent() const { return !UnitDie.getChildren().empty(); } + bool hasContent() const { return UnitDie.hasChildren(); } /// \brief Get string containing language specific context for a global name. /// @@ -180,7 +173,7 @@ public: DIE *getDIE(const DINode *D) const; /// \brief Returns a fresh newly allocated DIELoc. - DIELoc *getDIELoc() { return new (DIEValueAllocator) DIELoc(); } + DIELoc *getDIELoc() { return new (DIEValueAllocator) DIELoc; } /// \brief Insert DIE into the map. /// @@ -233,7 +226,7 @@ public: void addDIEEntry(DIE &Die, dwarf::Attribute Attribute, DIE &Entry); /// \brief Add a DIE attribute data and value. - void addDIEEntry(DIE &Die, dwarf::Attribute Attribute, DIEEntry *Entry); + void addDIEEntry(DIE &Die, dwarf::Attribute Attribute, DIEEntry Entry); void addDIETypeSignature(DIE &Die, const DwarfTypeUnit &Type); @@ -369,26 +362,12 @@ private: /// If the DWARF version doesn't handle the language, return -1. int64_t getDefaultLowerBound() const; - /// \brief Returns the DIE entry for the specified debug variable. - DIEEntry *getDIEEntry(const MDNode *N) const { - return MDNodeToDIEEntryMap.lookup(N); - } - - /// \brief Insert debug information entry into the map. - void insertDIEEntry(const MDNode *N, DIEEntry *E) { - MDNodeToDIEEntryMap.insert(std::make_pair(N, E)); - } - /// \brief Get an anonymous type for index type. DIE *getIndexTyDie(); /// \brief Set D as anonymous type for index which can be reused later. void setIndexTyDie(DIE *D) { IndexTyDie = D; } - /// \brief Creates a new DIEEntry to be a proxy for a debug information - /// entry. - DIEEntry *createDIEEntry(DIE &Entry); - /// If this is a named finished type then include it in the list of types for /// the accelerator tables. void updateAcceleratorTables(const DIScope *Context, const DIType *Ty, diff --git a/lib/CodeGen/AsmPrinter/Win64Exception.cpp b/lib/CodeGen/AsmPrinter/Win64Exception.cpp deleted file mode 100644 index dc6df9cb0144a..0000000000000 --- a/lib/CodeGen/AsmPrinter/Win64Exception.cpp +++ /dev/null @@ -1,504 +0,0 @@ -//===-- CodeGen/AsmPrinter/Win64Exception.cpp - Dwarf Exception Impl ------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains support for writing Win64 exception info into asm files. -// -//===----------------------------------------------------------------------===// - -#include "Win64Exception.h" -#include "llvm/ADT/SmallString.h" -#include "llvm/ADT/StringExtras.h" -#include "llvm/ADT/Twine.h" -#include "llvm/CodeGen/AsmPrinter.h" -#include "llvm/CodeGen/MachineFrameInfo.h" -#include "llvm/CodeGen/MachineFunction.h" -#include "llvm/CodeGen/MachineModuleInfo.h" -#include "llvm/CodeGen/WinEHFuncInfo.h" -#include "llvm/IR/DataLayout.h" -#include "llvm/IR/Mangler.h" -#include "llvm/IR/Module.h" -#include "llvm/MC/MCAsmInfo.h" -#include "llvm/MC/MCContext.h" -#include "llvm/MC/MCExpr.h" -#include "llvm/MC/MCSection.h" -#include "llvm/MC/MCStreamer.h" -#include "llvm/MC/MCSymbol.h" -#include "llvm/Support/Dwarf.h" -#include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/FormattedStream.h" -#include "llvm/Target/TargetFrameLowering.h" -#include "llvm/Target/TargetLoweringObjectFile.h" -#include "llvm/Target/TargetOptions.h" -#include "llvm/Target/TargetRegisterInfo.h" -using namespace llvm; - -Win64Exception::Win64Exception(AsmPrinter *A) - : EHStreamer(A), shouldEmitPersonality(false), shouldEmitLSDA(false), - shouldEmitMoves(false) {} - -Win64Exception::~Win64Exception() {} - -/// endModule - Emit all exception information that should come after the -/// content. -void Win64Exception::endModule() { -} - -void Win64Exception::beginFunction(const MachineFunction *MF) { - shouldEmitMoves = shouldEmitPersonality = shouldEmitLSDA = false; - - // If any landing pads survive, we need an EH table. - bool hasLandingPads = !MMI->getLandingPads().empty(); - - shouldEmitMoves = Asm->needsSEHMoves(); - - const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering(); - unsigned PerEncoding = TLOF.getPersonalityEncoding(); - const Function *Per = MF->getMMI().getPersonality(); - - shouldEmitPersonality = hasLandingPads && - PerEncoding != dwarf::DW_EH_PE_omit && Per; - - unsigned LSDAEncoding = TLOF.getLSDAEncoding(); - shouldEmitLSDA = shouldEmitPersonality && - LSDAEncoding != dwarf::DW_EH_PE_omit; - - - // If this was an outlined handler, we need to define the label corresponding - // to the offset of the parent frame relative to the stack pointer after the - // prologue. - const Function *F = MF->getFunction(); - const Function *ParentF = MMI->getWinEHParent(F); - if (F != ParentF) { - WinEHFuncInfo &FuncInfo = MMI->getWinEHFuncInfo(ParentF); - auto I = FuncInfo.CatchHandlerParentFrameObjOffset.find(F); - if (I != FuncInfo.CatchHandlerParentFrameObjOffset.end()) { - MCSymbol *HandlerTypeParentFrameOffset = - Asm->OutContext.getOrCreateParentFrameOffsetSymbol( - GlobalValue::getRealLinkageName(F->getName())); - - // Emit a symbol assignment. - Asm->OutStreamer->EmitAssignment( - HandlerTypeParentFrameOffset, - MCConstantExpr::Create(I->second, Asm->OutContext)); - } - } - - if (!shouldEmitPersonality && !shouldEmitMoves) - return; - - Asm->OutStreamer->EmitWinCFIStartProc(Asm->CurrentFnSym); - - if (!shouldEmitPersonality) - return; - - const MCSymbol *PersHandlerSym = - TLOF.getCFIPersonalitySymbol(Per, *Asm->Mang, Asm->TM, MMI); - Asm->OutStreamer->EmitWinEHHandler(PersHandlerSym, true, true); -} - -/// endFunction - Gather and emit post-function exception information. -/// -void Win64Exception::endFunction(const MachineFunction *MF) { - if (!shouldEmitPersonality && !shouldEmitMoves) - return; - - EHPersonality Per = MMI->getPersonalityType(); - - // Get rid of any dead landing pads if we're not using a Windows EH scheme. In - // Windows EH schemes, the landing pad is not actually reachable. It only - // exists so that we can emit the right table data. - if (!isMSVCEHPersonality(Per)) - MMI->TidyLandingPads(); - - if (shouldEmitPersonality) { - Asm->OutStreamer->PushSection(); - - // Emit an UNWIND_INFO struct describing the prologue. - Asm->OutStreamer->EmitWinEHHandlerData(); - - // Emit the tables appropriate to the personality function in use. If we - // don't recognize the personality, assume it uses an Itanium-style LSDA. - if (Per == EHPersonality::MSVC_Win64SEH) - emitCSpecificHandlerTable(); - else if (Per == EHPersonality::MSVC_CXX) - emitCXXFrameHandler3Table(MF); - else - emitExceptionTable(); - - Asm->OutStreamer->PopSection(); - } - Asm->OutStreamer->EmitWinCFIEndProc(); -} - -const MCExpr *Win64Exception::createImageRel32(const MCSymbol *Value) { - if (!Value) - return MCConstantExpr::Create(0, Asm->OutContext); - return MCSymbolRefExpr::Create(Value, MCSymbolRefExpr::VK_COFF_IMGREL32, - Asm->OutContext); -} - -const MCExpr *Win64Exception::createImageRel32(const GlobalValue *GV) { - if (!GV) - return MCConstantExpr::Create(0, Asm->OutContext); - return createImageRel32(Asm->getSymbol(GV)); -} - -/// Emit the language-specific data that __C_specific_handler expects. This -/// handler lives in the x64 Microsoft C runtime and allows catching or cleaning -/// up after faults with __try, __except, and __finally. The typeinfo values -/// are not really RTTI data, but pointers to filter functions that return an -/// integer (1, 0, or -1) indicating how to handle the exception. For __finally -/// blocks and other cleanups, the landing pad label is zero, and the filter -/// function is actually a cleanup handler with the same prototype. A catch-all -/// entry is modeled with a null filter function field and a non-zero landing -/// pad label. -/// -/// Possible filter function return values: -/// EXCEPTION_EXECUTE_HANDLER (1): -/// Jump to the landing pad label after cleanups. -/// EXCEPTION_CONTINUE_SEARCH (0): -/// Continue searching this table or continue unwinding. -/// EXCEPTION_CONTINUE_EXECUTION (-1): -/// Resume execution at the trapping PC. -/// -/// Inferred table structure: -/// struct Table { -/// int NumEntries; -/// struct Entry { -/// imagerel32 LabelStart; -/// imagerel32 LabelEnd; -/// imagerel32 FilterOrFinally; // One means catch-all. -/// imagerel32 LabelLPad; // Zero means __finally. -/// } Entries[NumEntries]; -/// }; -void Win64Exception::emitCSpecificHandlerTable() { - const std::vector &PadInfos = MMI->getLandingPads(); - - // Simplifying assumptions for first implementation: - // - Cleanups are not implemented. - // - Filters are not implemented. - - // The Itanium LSDA table sorts similar landing pads together to simplify the - // actions table, but we don't need that. - SmallVector LandingPads; - LandingPads.reserve(PadInfos.size()); - for (const auto &LP : PadInfos) - LandingPads.push_back(&LP); - - // Compute label ranges for call sites as we would for the Itanium LSDA, but - // use an all zero action table because we aren't using these actions. - SmallVector FirstActions; - FirstActions.resize(LandingPads.size()); - SmallVector CallSites; - computeCallSiteTable(CallSites, LandingPads, FirstActions); - - MCSymbol *EHFuncBeginSym = Asm->getFunctionBegin(); - MCSymbol *EHFuncEndSym = Asm->getFunctionEnd(); - - // Emit the number of table entries. - unsigned NumEntries = 0; - for (const CallSiteEntry &CSE : CallSites) { - if (!CSE.LPad) - continue; // Ignore gaps. - NumEntries += CSE.LPad->SEHHandlers.size(); - } - Asm->OutStreamer->EmitIntValue(NumEntries, 4); - - // If there are no actions, we don't need to iterate again. - if (NumEntries == 0) - return; - - // Emit the four-label records for each call site entry. The table has to be - // sorted in layout order, and the call sites should already be sorted. - for (const CallSiteEntry &CSE : CallSites) { - // Ignore gaps. Unlike the Itanium model, unwinding through a frame without - // an EH table entry will propagate the exception rather than terminating - // the program. - if (!CSE.LPad) - continue; - const LandingPadInfo *LPad = CSE.LPad; - - // Compute the label range. We may reuse the function begin and end labels - // rather than forming new ones. - const MCExpr *Begin = - createImageRel32(CSE.BeginLabel ? CSE.BeginLabel : EHFuncBeginSym); - const MCExpr *End; - if (CSE.EndLabel) { - // The interval is half-open, so we have to add one to include the return - // address of the last invoke in the range. - End = MCBinaryExpr::CreateAdd(createImageRel32(CSE.EndLabel), - MCConstantExpr::Create(1, Asm->OutContext), - Asm->OutContext); - } else { - End = createImageRel32(EHFuncEndSym); - } - - // Emit an entry for each action. - for (SEHHandler Handler : LPad->SEHHandlers) { - Asm->OutStreamer->EmitValue(Begin, 4); - Asm->OutStreamer->EmitValue(End, 4); - - // Emit the filter or finally function pointer, if present. Otherwise, - // emit '1' to indicate a catch-all. - const Function *F = Handler.FilterOrFinally; - if (F) - Asm->OutStreamer->EmitValue(createImageRel32(Asm->getSymbol(F)), 4); - else - Asm->OutStreamer->EmitIntValue(1, 4); - - // Emit the recovery address, if present. Otherwise, this must be a - // finally. - const BlockAddress *BA = Handler.RecoverBA; - if (BA) - Asm->OutStreamer->EmitValue( - createImageRel32(Asm->GetBlockAddressSymbol(BA)), 4); - else - Asm->OutStreamer->EmitIntValue(0, 4); - } - } -} - -void Win64Exception::emitCXXFrameHandler3Table(const MachineFunction *MF) { - const Function *F = MF->getFunction(); - const Function *ParentF = MMI->getWinEHParent(F); - auto &OS = *Asm->OutStreamer; - WinEHFuncInfo &FuncInfo = MMI->getWinEHFuncInfo(ParentF); - - StringRef ParentLinkageName = - GlobalValue::getRealLinkageName(ParentF->getName()); - - MCSymbol *FuncInfoXData = - Asm->OutContext.getOrCreateSymbol(Twine("$cppxdata$", ParentLinkageName)); - OS.EmitValue(createImageRel32(FuncInfoXData), 4); - - // The Itanium LSDA table sorts similar landing pads together to simplify the - // actions table, but we don't need that. - SmallVector LandingPads; - const std::vector &PadInfos = MMI->getLandingPads(); - LandingPads.reserve(PadInfos.size()); - for (const auto &LP : PadInfos) - LandingPads.push_back(&LP); - - RangeMapType PadMap; - computePadMap(LandingPads, PadMap); - - // The end label of the previous invoke or nounwind try-range. - MCSymbol *LastLabel = Asm->getFunctionBegin(); - - // Whether there is a potentially throwing instruction (currently this means - // an ordinary call) between the end of the previous try-range and now. - bool SawPotentiallyThrowing = false; - - int LastEHState = -2; - - // The parent function and the catch handlers contribute to the 'ip2state' - // table. - - // Include ip2state entries for the beginning of the main function and - // for catch handler functions. - if (F == ParentF) { - FuncInfo.IPToStateList.push_back(std::make_pair(LastLabel, -1)); - LastEHState = -1; - } else if (FuncInfo.HandlerBaseState.count(F)) { - FuncInfo.IPToStateList.push_back(std::make_pair(LastLabel, - FuncInfo.HandlerBaseState[F])); - LastEHState = FuncInfo.HandlerBaseState[F]; - } - for (const auto &MBB : *MF) { - for (const auto &MI : MBB) { - if (!MI.isEHLabel()) { - if (MI.isCall()) - SawPotentiallyThrowing |= !callToNoUnwindFunction(&MI); - continue; - } - - // End of the previous try-range? - MCSymbol *BeginLabel = MI.getOperand(0).getMCSymbol(); - if (BeginLabel == LastLabel) - SawPotentiallyThrowing = false; - - // Beginning of a new try-range? - RangeMapType::const_iterator L = PadMap.find(BeginLabel); - if (L == PadMap.end()) - // Nope, it was just some random label. - continue; - - const PadRange &P = L->second; - const LandingPadInfo *LandingPad = LandingPads[P.PadIndex]; - assert(BeginLabel == LandingPad->BeginLabels[P.RangeIndex] && - "Inconsistent landing pad map!"); - - // FIXME: Should this be using FuncInfo.HandlerBaseState? - if (SawPotentiallyThrowing && LastEHState != -1) { - FuncInfo.IPToStateList.push_back(std::make_pair(LastLabel, -1)); - SawPotentiallyThrowing = false; - LastEHState = -1; - } - - if (LandingPad->WinEHState != LastEHState) - FuncInfo.IPToStateList.push_back( - std::make_pair(BeginLabel, LandingPad->WinEHState)); - LastEHState = LandingPad->WinEHState; - LastLabel = LandingPad->EndLabels[P.RangeIndex]; - } - } - - // Defer emission until we've visited the parent function and all the catch - // handlers. Cleanups don't contribute to the ip2state table yet, so don't - // count them. - if (ParentF != F && !FuncInfo.CatchHandlerMaxState.count(F)) - return; - ++FuncInfo.NumIPToStateFuncsVisited; - if (FuncInfo.NumIPToStateFuncsVisited != FuncInfo.CatchHandlerMaxState.size()) - return; - - MCSymbol *UnwindMapXData = nullptr; - MCSymbol *TryBlockMapXData = nullptr; - MCSymbol *IPToStateXData = nullptr; - if (!FuncInfo.UnwindMap.empty()) - UnwindMapXData = Asm->OutContext.getOrCreateSymbol( - Twine("$stateUnwindMap$", ParentLinkageName)); - if (!FuncInfo.TryBlockMap.empty()) - TryBlockMapXData = Asm->OutContext.getOrCreateSymbol( - Twine("$tryMap$", ParentLinkageName)); - if (!FuncInfo.IPToStateList.empty()) - IPToStateXData = Asm->OutContext.getOrCreateSymbol( - Twine("$ip2state$", ParentLinkageName)); - - // FuncInfo { - // uint32_t MagicNumber - // int32_t MaxState; - // UnwindMapEntry *UnwindMap; - // uint32_t NumTryBlocks; - // TryBlockMapEntry *TryBlockMap; - // uint32_t IPMapEntries; - // IPToStateMapEntry *IPToStateMap; - // uint32_t UnwindHelp; // (x64/ARM only) - // ESTypeList *ESTypeList; - // int32_t EHFlags; - // } - // EHFlags & 1 -> Synchronous exceptions only, no async exceptions. - // EHFlags & 2 -> ??? - // EHFlags & 4 -> The function is noexcept(true), unwinding can't continue. - OS.EmitLabel(FuncInfoXData); - OS.EmitIntValue(0x19930522, 4); // MagicNumber - OS.EmitIntValue(FuncInfo.UnwindMap.size(), 4); // MaxState - OS.EmitValue(createImageRel32(UnwindMapXData), 4); // UnwindMap - OS.EmitIntValue(FuncInfo.TryBlockMap.size(), 4); // NumTryBlocks - OS.EmitValue(createImageRel32(TryBlockMapXData), 4); // TryBlockMap - OS.EmitIntValue(FuncInfo.IPToStateList.size(), 4); // IPMapEntries - OS.EmitValue(createImageRel32(IPToStateXData), 4); // IPToStateMap - OS.EmitIntValue(FuncInfo.UnwindHelpFrameOffset, 4); // UnwindHelp - OS.EmitIntValue(0, 4); // ESTypeList - OS.EmitIntValue(1, 4); // EHFlags - - // UnwindMapEntry { - // int32_t ToState; - // void (*Action)(); - // }; - if (UnwindMapXData) { - OS.EmitLabel(UnwindMapXData); - for (const WinEHUnwindMapEntry &UME : FuncInfo.UnwindMap) { - OS.EmitIntValue(UME.ToState, 4); // ToState - OS.EmitValue(createImageRel32(UME.Cleanup), 4); // Action - } - } - - // TryBlockMap { - // int32_t TryLow; - // int32_t TryHigh; - // int32_t CatchHigh; - // int32_t NumCatches; - // HandlerType *HandlerArray; - // }; - if (TryBlockMapXData) { - OS.EmitLabel(TryBlockMapXData); - SmallVector HandlerMaps; - for (size_t I = 0, E = FuncInfo.TryBlockMap.size(); I != E; ++I) { - WinEHTryBlockMapEntry &TBME = FuncInfo.TryBlockMap[I]; - MCSymbol *HandlerMapXData = nullptr; - - if (!TBME.HandlerArray.empty()) - HandlerMapXData = - Asm->OutContext.getOrCreateSymbol(Twine("$handlerMap$") - .concat(Twine(I)) - .concat("$") - .concat(ParentLinkageName)); - - HandlerMaps.push_back(HandlerMapXData); - - int CatchHigh = -1; - for (WinEHHandlerType &HT : TBME.HandlerArray) - CatchHigh = - std::max(CatchHigh, FuncInfo.CatchHandlerMaxState[HT.Handler]); - - assert(TBME.TryLow <= TBME.TryHigh); - OS.EmitIntValue(TBME.TryLow, 4); // TryLow - OS.EmitIntValue(TBME.TryHigh, 4); // TryHigh - OS.EmitIntValue(CatchHigh, 4); // CatchHigh - OS.EmitIntValue(TBME.HandlerArray.size(), 4); // NumCatches - OS.EmitValue(createImageRel32(HandlerMapXData), 4); // HandlerArray - } - - for (size_t I = 0, E = FuncInfo.TryBlockMap.size(); I != E; ++I) { - WinEHTryBlockMapEntry &TBME = FuncInfo.TryBlockMap[I]; - MCSymbol *HandlerMapXData = HandlerMaps[I]; - if (!HandlerMapXData) - continue; - // HandlerType { - // int32_t Adjectives; - // TypeDescriptor *Type; - // int32_t CatchObjOffset; - // void (*Handler)(); - // int32_t ParentFrameOffset; // x64 only - // }; - OS.EmitLabel(HandlerMapXData); - for (const WinEHHandlerType &HT : TBME.HandlerArray) { - MCSymbol *ParentFrameOffset = - Asm->OutContext.getOrCreateParentFrameOffsetSymbol( - GlobalValue::getRealLinkageName(HT.Handler->getName())); - const MCSymbolRefExpr *ParentFrameOffsetRef = MCSymbolRefExpr::Create( - ParentFrameOffset, MCSymbolRefExpr::VK_None, Asm->OutContext); - - // Get the frame escape label with the offset of the catch object. If - // the index is -1, then there is no catch object, and we should emit an - // offset of zero, indicating that no copy will occur. - const MCExpr *FrameAllocOffsetRef = nullptr; - if (HT.CatchObjRecoverIdx >= 0) { - MCSymbol *FrameAllocOffset = - Asm->OutContext.getOrCreateFrameAllocSymbol( - GlobalValue::getRealLinkageName(ParentF->getName()), - HT.CatchObjRecoverIdx); - FrameAllocOffsetRef = MCSymbolRefExpr::Create( - FrameAllocOffset, MCSymbolRefExpr::VK_None, Asm->OutContext); - } else { - FrameAllocOffsetRef = MCConstantExpr::Create(0, Asm->OutContext); - } - - OS.EmitIntValue(HT.Adjectives, 4); // Adjectives - OS.EmitValue(createImageRel32(HT.TypeDescriptor), 4); // Type - OS.EmitValue(FrameAllocOffsetRef, 4); // CatchObjOffset - OS.EmitValue(createImageRel32(HT.Handler), 4); // Handler - OS.EmitValue(ParentFrameOffsetRef, 4); // ParentFrameOffset - } - } - } - - // IPToStateMapEntry { - // void *IP; - // int32_t State; - // }; - if (IPToStateXData) { - OS.EmitLabel(IPToStateXData); - for (auto &IPStatePair : FuncInfo.IPToStateList) { - OS.EmitValue(createImageRel32(IPStatePair.first), 4); // IP - OS.EmitIntValue(IPStatePair.second, 4); // State - } - } -} diff --git a/lib/CodeGen/AsmPrinter/Win64Exception.h b/lib/CodeGen/AsmPrinter/Win64Exception.h deleted file mode 100644 index 5f4237fc01524..0000000000000 --- a/lib/CodeGen/AsmPrinter/Win64Exception.h +++ /dev/null @@ -1,61 +0,0 @@ -//===-- Win64Exception.h - Windows Exception Handling ----------*- C++ -*--===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains support for writing windows exception info into asm files. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_LIB_CODEGEN_ASMPRINTER_WIN64EXCEPTION_H -#define LLVM_LIB_CODEGEN_ASMPRINTER_WIN64EXCEPTION_H - -#include "EHStreamer.h" - -namespace llvm { -class GlobalValue; -class MachineFunction; -class MCExpr; - -class Win64Exception : public EHStreamer { - /// Per-function flag to indicate if personality info should be emitted. - bool shouldEmitPersonality; - - /// Per-function flag to indicate if the LSDA should be emitted. - bool shouldEmitLSDA; - - /// Per-function flag to indicate if frame moves info should be emitted. - bool shouldEmitMoves; - - void emitCSpecificHandlerTable(); - - void emitCXXFrameHandler3Table(const MachineFunction *MF); - - const MCExpr *createImageRel32(const MCSymbol *Value); - const MCExpr *createImageRel32(const GlobalValue *GV); - -public: - //===--------------------------------------------------------------------===// - // Main entry points. - // - Win64Exception(AsmPrinter *A); - ~Win64Exception() override; - - /// Emit all exception information that should come after the content. - void endModule() override; - - /// Gather pre-function exception information. Assumes being emitted - /// immediately after the function entry point. - void beginFunction(const MachineFunction *MF) override; - - /// Gather and emit post-function exception information. - void endFunction(const MachineFunction *) override; -}; -} - -#endif - diff --git a/lib/CodeGen/AsmPrinter/WinCodeViewLineTables.cpp b/lib/CodeGen/AsmPrinter/WinCodeViewLineTables.cpp index 371e20a3e5a08..535b1f605853b 100644 --- a/lib/CodeGen/AsmPrinter/WinCodeViewLineTables.cpp +++ b/lib/CodeGen/AsmPrinter/WinCodeViewLineTables.cpp @@ -171,10 +171,10 @@ static void EmitLabelDiff(MCStreamer &Streamer, unsigned int Size = 4) { MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None; MCContext &Context = Streamer.getContext(); - const MCExpr *FromRef = MCSymbolRefExpr::Create(From, Variant, Context), - *ToRef = MCSymbolRefExpr::Create(To, Variant, Context); + const MCExpr *FromRef = MCSymbolRefExpr::create(From, Variant, Context), + *ToRef = MCSymbolRefExpr::create(To, Variant, Context); const MCExpr *AddrDelta = - MCBinaryExpr::Create(MCBinaryExpr::Sub, ToRef, FromRef, Context); + MCBinaryExpr::create(MCBinaryExpr::Sub, ToRef, FromRef, Context); Streamer.EmitValue(AddrDelta, Size); } diff --git a/lib/CodeGen/AsmPrinter/WinException.cpp b/lib/CodeGen/AsmPrinter/WinException.cpp new file mode 100644 index 0000000000000..f1663503c08ec --- /dev/null +++ b/lib/CodeGen/AsmPrinter/WinException.cpp @@ -0,0 +1,543 @@ +//===-- CodeGen/AsmPrinter/WinException.cpp - Dwarf Exception Impl ------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains support for writing Win64 exception info into asm files. +// +//===----------------------------------------------------------------------===// + +#include "WinException.h" +#include "llvm/ADT/SmallString.h" +#include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/Twine.h" +#include "llvm/CodeGen/AsmPrinter.h" +#include "llvm/CodeGen/MachineFrameInfo.h" +#include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/MachineModuleInfo.h" +#include "llvm/CodeGen/WinEHFuncInfo.h" +#include "llvm/IR/DataLayout.h" +#include "llvm/IR/Mangler.h" +#include "llvm/IR/Module.h" +#include "llvm/MC/MCAsmInfo.h" +#include "llvm/MC/MCContext.h" +#include "llvm/MC/MCExpr.h" +#include "llvm/MC/MCSection.h" +#include "llvm/MC/MCStreamer.h" +#include "llvm/MC/MCSymbol.h" +#include "llvm/MC/MCWin64EH.h" +#include "llvm/Support/Dwarf.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/FormattedStream.h" +#include "llvm/Target/TargetFrameLowering.h" +#include "llvm/Target/TargetLoweringObjectFile.h" +#include "llvm/Target/TargetOptions.h" +#include "llvm/Target/TargetRegisterInfo.h" +using namespace llvm; + +WinException::WinException(AsmPrinter *A) : EHStreamer(A) { + // MSVC's EH tables are always composed of 32-bit words. All known 64-bit + // platforms use an imagerel32 relocation to refer to symbols. + useImageRel32 = (A->getDataLayout().getPointerSizeInBits() == 64); +} + +WinException::~WinException() {} + +/// endModule - Emit all exception information that should come after the +/// content. +void WinException::endModule() { +} + +void WinException::beginFunction(const MachineFunction *MF) { + shouldEmitMoves = shouldEmitPersonality = shouldEmitLSDA = false; + + // If any landing pads survive, we need an EH table. + bool hasLandingPads = !MMI->getLandingPads().empty(); + + const Function *F = MF->getFunction(); + const Function *ParentF = MMI->getWinEHParent(F); + + shouldEmitMoves = Asm->needsSEHMoves(); + + const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering(); + unsigned PerEncoding = TLOF.getPersonalityEncoding(); + const Function *Per = MMI->getPersonality(); + + shouldEmitPersonality = hasLandingPads && + PerEncoding != dwarf::DW_EH_PE_omit && Per; + + unsigned LSDAEncoding = TLOF.getLSDAEncoding(); + shouldEmitLSDA = shouldEmitPersonality && + LSDAEncoding != dwarf::DW_EH_PE_omit; + + // If we're not using CFI, we don't want the CFI or the personality. Emit the + // LSDA if this is the parent function. + if (!Asm->MAI->usesWindowsCFI()) { + shouldEmitLSDA = (hasLandingPads && F == ParentF); + shouldEmitPersonality = false; + return; + } + + // If this was an outlined handler, we need to define the label corresponding + // to the offset of the parent frame relative to the stack pointer after the + // prologue. + if (F != ParentF) { + WinEHFuncInfo &FuncInfo = MMI->getWinEHFuncInfo(ParentF); + auto I = FuncInfo.CatchHandlerParentFrameObjOffset.find(F); + if (I != FuncInfo.CatchHandlerParentFrameObjOffset.end()) { + MCSymbol *HandlerTypeParentFrameOffset = + Asm->OutContext.getOrCreateParentFrameOffsetSymbol( + GlobalValue::getRealLinkageName(F->getName())); + + // Emit a symbol assignment. + Asm->OutStreamer->EmitAssignment( + HandlerTypeParentFrameOffset, + MCConstantExpr::create(I->second, Asm->OutContext)); + } + } + + if (shouldEmitMoves || shouldEmitPersonality) + Asm->OutStreamer->EmitWinCFIStartProc(Asm->CurrentFnSym); + + if (shouldEmitPersonality) { + const MCSymbol *PersHandlerSym = + TLOF.getCFIPersonalitySymbol(Per, *Asm->Mang, Asm->TM, MMI); + Asm->OutStreamer->EmitWinEHHandler(PersHandlerSym, true, true); + } +} + +/// endFunction - Gather and emit post-function exception information. +/// +void WinException::endFunction(const MachineFunction *MF) { + if (!shouldEmitPersonality && !shouldEmitMoves && !shouldEmitLSDA) + return; + + EHPersonality Per = MMI->getPersonalityType(); + + // Get rid of any dead landing pads if we're not using a Windows EH scheme. In + // Windows EH schemes, the landing pad is not actually reachable. It only + // exists so that we can emit the right table data. + if (!isMSVCEHPersonality(Per)) + MMI->TidyLandingPads(); + + if (shouldEmitPersonality || shouldEmitLSDA) { + Asm->OutStreamer->PushSection(); + + if (shouldEmitMoves || shouldEmitPersonality) { + // Emit an UNWIND_INFO struct describing the prologue. + Asm->OutStreamer->EmitWinEHHandlerData(); + } else { + // Just switch sections to the right xdata section. This use of + // CurrentFnSym assumes that we only emit the LSDA when ending the parent + // function. + MCSection *XData = WinEH::UnwindEmitter::getXDataSection( + Asm->CurrentFnSym, Asm->OutContext); + Asm->OutStreamer->SwitchSection(XData); + } + + // Emit the tables appropriate to the personality function in use. If we + // don't recognize the personality, assume it uses an Itanium-style LSDA. + if (Per == EHPersonality::MSVC_Win64SEH) + emitCSpecificHandlerTable(); + else if (Per == EHPersonality::MSVC_X86SEH) + emitCSpecificHandlerTable(); // FIXME + else if (Per == EHPersonality::MSVC_CXX) + emitCXXFrameHandler3Table(MF); + else + emitExceptionTable(); + + Asm->OutStreamer->PopSection(); + } + + if (shouldEmitMoves) + Asm->OutStreamer->EmitWinCFIEndProc(); +} + +const MCExpr *WinException::create32bitRef(const MCSymbol *Value) { + if (!Value) + return MCConstantExpr::create(0, Asm->OutContext); + return MCSymbolRefExpr::create(Value, useImageRel32 + ? MCSymbolRefExpr::VK_COFF_IMGREL32 + : MCSymbolRefExpr::VK_None, + Asm->OutContext); +} + +const MCExpr *WinException::create32bitRef(const GlobalValue *GV) { + if (!GV) + return MCConstantExpr::create(0, Asm->OutContext); + return create32bitRef(Asm->getSymbol(GV)); +} + +/// Emit the language-specific data that __C_specific_handler expects. This +/// handler lives in the x64 Microsoft C runtime and allows catching or cleaning +/// up after faults with __try, __except, and __finally. The typeinfo values +/// are not really RTTI data, but pointers to filter functions that return an +/// integer (1, 0, or -1) indicating how to handle the exception. For __finally +/// blocks and other cleanups, the landing pad label is zero, and the filter +/// function is actually a cleanup handler with the same prototype. A catch-all +/// entry is modeled with a null filter function field and a non-zero landing +/// pad label. +/// +/// Possible filter function return values: +/// EXCEPTION_EXECUTE_HANDLER (1): +/// Jump to the landing pad label after cleanups. +/// EXCEPTION_CONTINUE_SEARCH (0): +/// Continue searching this table or continue unwinding. +/// EXCEPTION_CONTINUE_EXECUTION (-1): +/// Resume execution at the trapping PC. +/// +/// Inferred table structure: +/// struct Table { +/// int NumEntries; +/// struct Entry { +/// imagerel32 LabelStart; +/// imagerel32 LabelEnd; +/// imagerel32 FilterOrFinally; // One means catch-all. +/// imagerel32 LabelLPad; // Zero means __finally. +/// } Entries[NumEntries]; +/// }; +void WinException::emitCSpecificHandlerTable() { + const std::vector &PadInfos = MMI->getLandingPads(); + + // Simplifying assumptions for first implementation: + // - Cleanups are not implemented. + // - Filters are not implemented. + + // The Itanium LSDA table sorts similar landing pads together to simplify the + // actions table, but we don't need that. + SmallVector LandingPads; + LandingPads.reserve(PadInfos.size()); + for (const auto &LP : PadInfos) + LandingPads.push_back(&LP); + + // Compute label ranges for call sites as we would for the Itanium LSDA, but + // use an all zero action table because we aren't using these actions. + SmallVector FirstActions; + FirstActions.resize(LandingPads.size()); + SmallVector CallSites; + computeCallSiteTable(CallSites, LandingPads, FirstActions); + + MCSymbol *EHFuncBeginSym = Asm->getFunctionBegin(); + MCSymbol *EHFuncEndSym = Asm->getFunctionEnd(); + + // Emit the number of table entries. + unsigned NumEntries = 0; + for (const CallSiteEntry &CSE : CallSites) { + if (!CSE.LPad) + continue; // Ignore gaps. + NumEntries += CSE.LPad->SEHHandlers.size(); + } + Asm->OutStreamer->EmitIntValue(NumEntries, 4); + + // If there are no actions, we don't need to iterate again. + if (NumEntries == 0) + return; + + // Emit the four-label records for each call site entry. The table has to be + // sorted in layout order, and the call sites should already be sorted. + for (const CallSiteEntry &CSE : CallSites) { + // Ignore gaps. Unlike the Itanium model, unwinding through a frame without + // an EH table entry will propagate the exception rather than terminating + // the program. + if (!CSE.LPad) + continue; + const LandingPadInfo *LPad = CSE.LPad; + + // Compute the label range. We may reuse the function begin and end labels + // rather than forming new ones. + const MCExpr *Begin = + create32bitRef(CSE.BeginLabel ? CSE.BeginLabel : EHFuncBeginSym); + const MCExpr *End; + if (CSE.EndLabel) { + // The interval is half-open, so we have to add one to include the return + // address of the last invoke in the range. + End = MCBinaryExpr::createAdd(create32bitRef(CSE.EndLabel), + MCConstantExpr::create(1, Asm->OutContext), + Asm->OutContext); + } else { + End = create32bitRef(EHFuncEndSym); + } + + // Emit an entry for each action. + for (SEHHandler Handler : LPad->SEHHandlers) { + Asm->OutStreamer->EmitValue(Begin, 4); + Asm->OutStreamer->EmitValue(End, 4); + + // Emit the filter or finally function pointer, if present. Otherwise, + // emit '1' to indicate a catch-all. + const Function *F = Handler.FilterOrFinally; + if (F) + Asm->OutStreamer->EmitValue(create32bitRef(Asm->getSymbol(F)), 4); + else + Asm->OutStreamer->EmitIntValue(1, 4); + + // Emit the recovery address, if present. Otherwise, this must be a + // finally. + const BlockAddress *BA = Handler.RecoverBA; + if (BA) + Asm->OutStreamer->EmitValue( + create32bitRef(Asm->GetBlockAddressSymbol(BA)), 4); + else + Asm->OutStreamer->EmitIntValue(0, 4); + } + } +} + +void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) { + const Function *F = MF->getFunction(); + const Function *ParentF = MMI->getWinEHParent(F); + auto &OS = *Asm->OutStreamer; + WinEHFuncInfo &FuncInfo = MMI->getWinEHFuncInfo(ParentF); + + StringRef ParentLinkageName = + GlobalValue::getRealLinkageName(ParentF->getName()); + + MCSymbol *FuncInfoXData = nullptr; + if (shouldEmitPersonality) { + FuncInfoXData = Asm->OutContext.getOrCreateSymbol( + Twine("$cppxdata$", ParentLinkageName)); + OS.EmitValue(create32bitRef(FuncInfoXData), 4); + + extendIP2StateTable(MF, ParentF, FuncInfo); + + // Defer emission until we've visited the parent function and all the catch + // handlers. Cleanups don't contribute to the ip2state table, so don't count + // them. + if (ParentF != F && !FuncInfo.CatchHandlerMaxState.count(F)) + return; + ++FuncInfo.NumIPToStateFuncsVisited; + if (FuncInfo.NumIPToStateFuncsVisited != FuncInfo.CatchHandlerMaxState.size()) + return; + } else { + FuncInfoXData = Asm->OutContext.getOrCreateLSDASymbol(ParentLinkageName); + } + + MCSymbol *UnwindMapXData = nullptr; + MCSymbol *TryBlockMapXData = nullptr; + MCSymbol *IPToStateXData = nullptr; + if (!FuncInfo.UnwindMap.empty()) + UnwindMapXData = Asm->OutContext.getOrCreateSymbol( + Twine("$stateUnwindMap$", ParentLinkageName)); + if (!FuncInfo.TryBlockMap.empty()) + TryBlockMapXData = Asm->OutContext.getOrCreateSymbol( + Twine("$tryMap$", ParentLinkageName)); + if (!FuncInfo.IPToStateList.empty()) + IPToStateXData = Asm->OutContext.getOrCreateSymbol( + Twine("$ip2state$", ParentLinkageName)); + + // FuncInfo { + // uint32_t MagicNumber + // int32_t MaxState; + // UnwindMapEntry *UnwindMap; + // uint32_t NumTryBlocks; + // TryBlockMapEntry *TryBlockMap; + // uint32_t IPMapEntries; // always 0 for x86 + // IPToStateMapEntry *IPToStateMap; // always 0 for x86 + // uint32_t UnwindHelp; // non-x86 only + // ESTypeList *ESTypeList; + // int32_t EHFlags; + // } + // EHFlags & 1 -> Synchronous exceptions only, no async exceptions. + // EHFlags & 2 -> ??? + // EHFlags & 4 -> The function is noexcept(true), unwinding can't continue. + OS.EmitLabel(FuncInfoXData); + OS.EmitIntValue(0x19930522, 4); // MagicNumber + OS.EmitIntValue(FuncInfo.UnwindMap.size(), 4); // MaxState + OS.EmitValue(create32bitRef(UnwindMapXData), 4); // UnwindMap + OS.EmitIntValue(FuncInfo.TryBlockMap.size(), 4); // NumTryBlocks + OS.EmitValue(create32bitRef(TryBlockMapXData), 4); // TryBlockMap + OS.EmitIntValue(FuncInfo.IPToStateList.size(), 4); // IPMapEntries + OS.EmitValue(create32bitRef(IPToStateXData), 4); // IPToStateMap + if (Asm->MAI->usesWindowsCFI()) + OS.EmitIntValue(FuncInfo.UnwindHelpFrameOffset, 4); // UnwindHelp + OS.EmitIntValue(0, 4); // ESTypeList + OS.EmitIntValue(1, 4); // EHFlags + + // UnwindMapEntry { + // int32_t ToState; + // void (*Action)(); + // }; + if (UnwindMapXData) { + OS.EmitLabel(UnwindMapXData); + for (const WinEHUnwindMapEntry &UME : FuncInfo.UnwindMap) { + OS.EmitIntValue(UME.ToState, 4); // ToState + OS.EmitValue(create32bitRef(UME.Cleanup), 4); // Action + } + } + + // TryBlockMap { + // int32_t TryLow; + // int32_t TryHigh; + // int32_t CatchHigh; + // int32_t NumCatches; + // HandlerType *HandlerArray; + // }; + if (TryBlockMapXData) { + OS.EmitLabel(TryBlockMapXData); + SmallVector HandlerMaps; + for (size_t I = 0, E = FuncInfo.TryBlockMap.size(); I != E; ++I) { + WinEHTryBlockMapEntry &TBME = FuncInfo.TryBlockMap[I]; + MCSymbol *HandlerMapXData = nullptr; + + if (!TBME.HandlerArray.empty()) + HandlerMapXData = + Asm->OutContext.getOrCreateSymbol(Twine("$handlerMap$") + .concat(Twine(I)) + .concat("$") + .concat(ParentLinkageName)); + + HandlerMaps.push_back(HandlerMapXData); + + int CatchHigh = -1; + for (WinEHHandlerType &HT : TBME.HandlerArray) + CatchHigh = + std::max(CatchHigh, FuncInfo.CatchHandlerMaxState[HT.Handler]); + + assert(TBME.TryLow <= TBME.TryHigh); + OS.EmitIntValue(TBME.TryLow, 4); // TryLow + OS.EmitIntValue(TBME.TryHigh, 4); // TryHigh + OS.EmitIntValue(CatchHigh, 4); // CatchHigh + OS.EmitIntValue(TBME.HandlerArray.size(), 4); // NumCatches + OS.EmitValue(create32bitRef(HandlerMapXData), 4); // HandlerArray + } + + for (size_t I = 0, E = FuncInfo.TryBlockMap.size(); I != E; ++I) { + WinEHTryBlockMapEntry &TBME = FuncInfo.TryBlockMap[I]; + MCSymbol *HandlerMapXData = HandlerMaps[I]; + if (!HandlerMapXData) + continue; + // HandlerType { + // int32_t Adjectives; + // TypeDescriptor *Type; + // int32_t CatchObjOffset; + // void (*Handler)(); + // int32_t ParentFrameOffset; // x64 only + // }; + OS.EmitLabel(HandlerMapXData); + for (const WinEHHandlerType &HT : TBME.HandlerArray) { + // Get the frame escape label with the offset of the catch object. If + // the index is -1, then there is no catch object, and we should emit an + // offset of zero, indicating that no copy will occur. + const MCExpr *FrameAllocOffsetRef = nullptr; + if (HT.CatchObjRecoverIdx >= 0) { + MCSymbol *FrameAllocOffset = + Asm->OutContext.getOrCreateFrameAllocSymbol( + GlobalValue::getRealLinkageName(ParentF->getName()), + HT.CatchObjRecoverIdx); + FrameAllocOffsetRef = MCSymbolRefExpr::create( + FrameAllocOffset, MCSymbolRefExpr::VK_None, Asm->OutContext); + } else { + FrameAllocOffsetRef = MCConstantExpr::create(0, Asm->OutContext); + } + + OS.EmitIntValue(HT.Adjectives, 4); // Adjectives + OS.EmitValue(create32bitRef(HT.TypeDescriptor), 4); // Type + OS.EmitValue(FrameAllocOffsetRef, 4); // CatchObjOffset + OS.EmitValue(create32bitRef(HT.Handler), 4); // Handler + + if (shouldEmitPersonality) { + MCSymbol *ParentFrameOffset = + Asm->OutContext.getOrCreateParentFrameOffsetSymbol( + GlobalValue::getRealLinkageName(HT.Handler->getName())); + const MCSymbolRefExpr *ParentFrameOffsetRef = MCSymbolRefExpr::create( + ParentFrameOffset, MCSymbolRefExpr::VK_None, Asm->OutContext); + OS.EmitValue(ParentFrameOffsetRef, 4); // ParentFrameOffset + } + } + } + } + + // IPToStateMapEntry { + // void *IP; + // int32_t State; + // }; + if (IPToStateXData) { + OS.EmitLabel(IPToStateXData); + for (auto &IPStatePair : FuncInfo.IPToStateList) { + OS.EmitValue(create32bitRef(IPStatePair.first), 4); // IP + OS.EmitIntValue(IPStatePair.second, 4); // State + } + } +} + +void WinException::extendIP2StateTable(const MachineFunction *MF, + const Function *ParentF, + WinEHFuncInfo &FuncInfo) { + const Function *F = MF->getFunction(); + + // The Itanium LSDA table sorts similar landing pads together to simplify the + // actions table, but we don't need that. + SmallVector LandingPads; + const std::vector &PadInfos = MMI->getLandingPads(); + LandingPads.reserve(PadInfos.size()); + for (const auto &LP : PadInfos) + LandingPads.push_back(&LP); + + RangeMapType PadMap; + computePadMap(LandingPads, PadMap); + + // The end label of the previous invoke or nounwind try-range. + MCSymbol *LastLabel = Asm->getFunctionBegin(); + + // Whether there is a potentially throwing instruction (currently this means + // an ordinary call) between the end of the previous try-range and now. + bool SawPotentiallyThrowing = false; + + int LastEHState = -2; + + // The parent function and the catch handlers contribute to the 'ip2state' + // table. + + // Include ip2state entries for the beginning of the main function and + // for catch handler functions. + if (F == ParentF) { + FuncInfo.IPToStateList.push_back(std::make_pair(LastLabel, -1)); + LastEHState = -1; + } else if (FuncInfo.HandlerBaseState.count(F)) { + FuncInfo.IPToStateList.push_back( + std::make_pair(LastLabel, FuncInfo.HandlerBaseState[F])); + LastEHState = FuncInfo.HandlerBaseState[F]; + } + for (const auto &MBB : *MF) { + for (const auto &MI : MBB) { + if (!MI.isEHLabel()) { + if (MI.isCall()) + SawPotentiallyThrowing |= !callToNoUnwindFunction(&MI); + continue; + } + + // End of the previous try-range? + MCSymbol *BeginLabel = MI.getOperand(0).getMCSymbol(); + if (BeginLabel == LastLabel) + SawPotentiallyThrowing = false; + + // Beginning of a new try-range? + RangeMapType::const_iterator L = PadMap.find(BeginLabel); + if (L == PadMap.end()) + // Nope, it was just some random label. + continue; + + const PadRange &P = L->second; + const LandingPadInfo *LandingPad = LandingPads[P.PadIndex]; + assert(BeginLabel == LandingPad->BeginLabels[P.RangeIndex] && + "Inconsistent landing pad map!"); + + // FIXME: Should this be using FuncInfo.HandlerBaseState? + if (SawPotentiallyThrowing && LastEHState != -1) { + FuncInfo.IPToStateList.push_back(std::make_pair(LastLabel, -1)); + SawPotentiallyThrowing = false; + LastEHState = -1; + } + + if (LandingPad->WinEHState != LastEHState) + FuncInfo.IPToStateList.push_back( + std::make_pair(BeginLabel, LandingPad->WinEHState)); + LastEHState = LandingPad->WinEHState; + LastLabel = LandingPad->EndLabels[P.RangeIndex]; + } + } +} diff --git a/lib/CodeGen/AsmPrinter/WinException.h b/lib/CodeGen/AsmPrinter/WinException.h new file mode 100644 index 0000000000000..478899b79da92 --- /dev/null +++ b/lib/CodeGen/AsmPrinter/WinException.h @@ -0,0 +1,69 @@ +//===-- WinException.h - Windows Exception Handling ----------*- C++ -*--===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains support for writing windows exception info into asm files. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_CODEGEN_ASMPRINTER_WIN64EXCEPTION_H +#define LLVM_LIB_CODEGEN_ASMPRINTER_WIN64EXCEPTION_H + +#include "EHStreamer.h" + +namespace llvm { +class Function; +class GlobalValue; +class MachineFunction; +class MCExpr; +struct WinEHFuncInfo; + +class WinException : public EHStreamer { + /// Per-function flag to indicate if personality info should be emitted. + bool shouldEmitPersonality = false; + + /// Per-function flag to indicate if the LSDA should be emitted. + bool shouldEmitLSDA = false; + + /// Per-function flag to indicate if frame moves info should be emitted. + bool shouldEmitMoves = false; + + /// True if this is a 64-bit target and we should use image relative offsets. + bool useImageRel32 = false; + + void emitCSpecificHandlerTable(); + + void emitCXXFrameHandler3Table(const MachineFunction *MF); + + void extendIP2StateTable(const MachineFunction *MF, const Function *ParentF, + WinEHFuncInfo &FuncInfo); + + const MCExpr *create32bitRef(const MCSymbol *Value); + const MCExpr *create32bitRef(const GlobalValue *GV); + +public: + //===--------------------------------------------------------------------===// + // Main entry points. + // + WinException(AsmPrinter *A); + ~WinException() override; + + /// Emit all exception information that should come after the content. + void endModule() override; + + /// Gather pre-function exception information. Assumes being emitted + /// immediately after the function entry point. + void beginFunction(const MachineFunction *MF) override; + + /// Gather and emit post-function exception information. + void endFunction(const MachineFunction *) override; +}; +} + +#endif + diff --git a/lib/CodeGen/CMakeLists.txt b/lib/CodeGen/CMakeLists.txt index 9fc3e0bcec9a6..6d2af90035097 100644 --- a/lib/CodeGen/CMakeLists.txt +++ b/lib/CodeGen/CMakeLists.txt @@ -71,6 +71,7 @@ add_llvm_library(LLVMCodeGen MachineSink.cpp MachineTraceMetrics.cpp MachineVerifier.cpp + MIRPrintingPass.cpp OcamlGC.cpp OptimizePHIs.cpp PHIElimination.cpp @@ -129,3 +130,4 @@ add_dependencies(LLVMCodeGen intrinsics_gen) add_subdirectory(SelectionDAG) add_subdirectory(AsmPrinter) +add_subdirectory(MIRParser) diff --git a/lib/CodeGen/CodeGenPrepare.cpp b/lib/CodeGen/CodeGenPrepare.cpp index 2c1858b944c65..6a814038c6881 100644 --- a/lib/CodeGen/CodeGenPrepare.cpp +++ b/lib/CodeGen/CodeGenPrepare.cpp @@ -170,7 +170,8 @@ class TypePromotionTransaction; void EliminateMostlyEmptyBlock(BasicBlock *BB); bool OptimizeBlock(BasicBlock &BB, bool& ModifiedDT); bool OptimizeInst(Instruction *I, bool& ModifiedDT); - bool OptimizeMemoryInst(Instruction *I, Value *Addr, Type *AccessTy); + bool OptimizeMemoryInst(Instruction *I, Value *Addr, + Type *AccessTy, unsigned AS); bool OptimizeInlineAsmInst(CallInst *CS); bool OptimizeCallInst(CallInst *CI, bool& ModifiedDT); bool MoveExtToFormExtLoad(Instruction *&I); @@ -1410,11 +1411,15 @@ bool CodeGenPrepare::OptimizeCallInst(CallInst *CI, bool& ModifiedDT) { } if (TLI) { + // Unknown address space. + // TODO: Target hook to pick which address space the intrinsic cares + // about? + unsigned AddrSpace = ~0u; SmallVector PtrOps; Type *AccessTy; - if (TLI->GetAddrModeArguments(II, PtrOps, AccessTy)) + if (TLI->GetAddrModeArguments(II, PtrOps, AccessTy, AddrSpace)) while (!PtrOps.empty()) - if (OptimizeMemoryInst(II, PtrOps.pop_back_val(), AccessTy)) + if (OptimizeMemoryInst(II, PtrOps.pop_back_val(), AccessTy, AddrSpace)) return true; } } @@ -2095,6 +2100,7 @@ class AddressingModeMatcher { /// AccessTy/MemoryInst - This is the type for the access (e.g. double) and /// the memory instruction that we're computing this address for. Type *AccessTy; + unsigned AddrSpace; Instruction *MemoryInst; /// AddrMode - This is the addressing mode that we're building up. This is @@ -2114,14 +2120,15 @@ class AddressingModeMatcher { bool IgnoreProfitability; AddressingModeMatcher(SmallVectorImpl &AMI, - const TargetMachine &TM, Type *AT, Instruction *MI, - ExtAddrMode &AM, const SetOfInstrs &InsertedTruncs, + const TargetMachine &TM, Type *AT, unsigned AS, + Instruction *MI, ExtAddrMode &AM, + const SetOfInstrs &InsertedTruncs, InstrToOrigTy &PromotedInsts, TypePromotionTransaction &TPT) : AddrModeInsts(AMI), TM(TM), TLI(*TM.getSubtargetImpl(*MI->getParent()->getParent()) ->getTargetLowering()), - AccessTy(AT), MemoryInst(MI), AddrMode(AM), + AccessTy(AT), AddrSpace(AS), MemoryInst(MI), AddrMode(AM), InsertedTruncs(InsertedTruncs), PromotedInsts(PromotedInsts), TPT(TPT) { IgnoreProfitability = false; } @@ -2135,7 +2142,7 @@ public: /// optimizations. /// \p PromotedInsts maps the instructions to their type before promotion. /// \p The ongoing transaction where every action should be registered. - static ExtAddrMode Match(Value *V, Type *AccessTy, + static ExtAddrMode Match(Value *V, Type *AccessTy, unsigned AS, Instruction *MemoryInst, SmallVectorImpl &AddrModeInsts, const TargetMachine &TM, @@ -2144,7 +2151,7 @@ public: TypePromotionTransaction &TPT) { ExtAddrMode Result; - bool Success = AddressingModeMatcher(AddrModeInsts, TM, AccessTy, + bool Success = AddressingModeMatcher(AddrModeInsts, TM, AccessTy, AS, MemoryInst, Result, InsertedTruncs, PromotedInsts, TPT).MatchAddr(V, 0); (void)Success; assert(Success && "Couldn't select *anything*?"); @@ -2190,7 +2197,7 @@ bool AddressingModeMatcher::MatchScaledValue(Value *ScaleReg, int64_t Scale, TestAddrMode.ScaledReg = ScaleReg; // If the new address isn't legal, bail out. - if (!TLI.isLegalAddressingMode(TestAddrMode, AccessTy)) + if (!TLI.isLegalAddressingMode(TestAddrMode, AccessTy, AddrSpace)) return false; // It was legal, so commit it. @@ -2207,7 +2214,7 @@ bool AddressingModeMatcher::MatchScaledValue(Value *ScaleReg, int64_t Scale, // If this addressing mode is legal, commit it and remember that we folded // this instruction. - if (TLI.isLegalAddressingMode(TestAddrMode, AccessTy)) { + if (TLI.isLegalAddressingMode(TestAddrMode, AccessTy, AddrSpace)) { AddrModeInsts.push_back(cast(ScaleReg)); AddrMode = TestAddrMode; return true; @@ -2771,7 +2778,8 @@ bool AddressingModeMatcher::MatchOperationAddr(User *AddrInst, unsigned Opcode, // just add it to the disp field and check validity. if (VariableOperand == -1) { AddrMode.BaseOffs += ConstantOffset; - if (ConstantOffset == 0 || TLI.isLegalAddressingMode(AddrMode, AccessTy)){ + if (ConstantOffset == 0 || + TLI.isLegalAddressingMode(AddrMode, AccessTy, AddrSpace)) { // Check to see if we can fold the base pointer in too. if (MatchAddr(AddrInst->getOperand(0), Depth+1)) return true; @@ -2894,14 +2902,14 @@ bool AddressingModeMatcher::MatchAddr(Value *Addr, unsigned Depth) { if (ConstantInt *CI = dyn_cast(Addr)) { // Fold in immediates if legal for the target. AddrMode.BaseOffs += CI->getSExtValue(); - if (TLI.isLegalAddressingMode(AddrMode, AccessTy)) + if (TLI.isLegalAddressingMode(AddrMode, AccessTy, AddrSpace)) return true; AddrMode.BaseOffs -= CI->getSExtValue(); } else if (GlobalValue *GV = dyn_cast(Addr)) { // If this is a global variable, try to fold it into the addressing mode. if (!AddrMode.BaseGV) { AddrMode.BaseGV = GV; - if (TLI.isLegalAddressingMode(AddrMode, AccessTy)) + if (TLI.isLegalAddressingMode(AddrMode, AccessTy, AddrSpace)) return true; AddrMode.BaseGV = nullptr; } @@ -2945,7 +2953,7 @@ bool AddressingModeMatcher::MatchAddr(Value *Addr, unsigned Depth) { AddrMode.HasBaseReg = true; AddrMode.BaseReg = Addr; // Still check for legality in case the target supports [imm] but not [i+r]. - if (TLI.isLegalAddressingMode(AddrMode, AccessTy)) + if (TLI.isLegalAddressingMode(AddrMode, AccessTy, AddrSpace)) return true; AddrMode.HasBaseReg = false; AddrMode.BaseReg = nullptr; @@ -2955,7 +2963,7 @@ bool AddressingModeMatcher::MatchAddr(Value *Addr, unsigned Depth) { if (AddrMode.Scale == 0) { AddrMode.Scale = 1; AddrMode.ScaledReg = Addr; - if (TLI.isLegalAddressingMode(AddrMode, AccessTy)) + if (TLI.isLegalAddressingMode(AddrMode, AccessTy, AddrSpace)) return true; AddrMode.Scale = 0; AddrMode.ScaledReg = nullptr; @@ -3136,9 +3144,11 @@ IsProfitableToFoldIntoAddressingMode(Instruction *I, ExtAddrMode &AMBefore, // Get the access type of this use. If the use isn't a pointer, we don't // know what it accesses. Value *Address = User->getOperand(OpNo); - if (!Address->getType()->isPointerTy()) + PointerType *AddrTy = dyn_cast(Address->getType()); + if (!AddrTy) return false; - Type *AddressAccessTy = Address->getType()->getPointerElementType(); + Type *AddressAccessTy = AddrTy->getElementType(); + unsigned AS = AddrTy->getAddressSpace(); // Do a match against the root of this address, ignoring profitability. This // will tell us if the addressing mode for the memory operation will @@ -3146,7 +3156,7 @@ IsProfitableToFoldIntoAddressingMode(Instruction *I, ExtAddrMode &AMBefore, ExtAddrMode Result; TypePromotionTransaction::ConstRestorationPt LastKnownGood = TPT.getRestorationPoint(); - AddressingModeMatcher Matcher(MatchedAddrModeInsts, TM, AddressAccessTy, + AddressingModeMatcher Matcher(MatchedAddrModeInsts, TM, AddressAccessTy, AS, MemoryInst, Result, InsertedTruncs, PromotedInsts, TPT); Matcher.IgnoreProfitability = true; @@ -3189,7 +3199,7 @@ static bool IsNonLocalValue(Value *V, BasicBlock *BB) { /// This method is used to optimize both load/store and inline asms with memory /// operands. bool CodeGenPrepare::OptimizeMemoryInst(Instruction *MemoryInst, Value *Addr, - Type *AccessTy) { + Type *AccessTy, unsigned AddrSpace) { Value *Repl = Addr; // Try to collapse single-value PHI nodes. This is necessary to undo @@ -3229,8 +3239,8 @@ bool CodeGenPrepare::OptimizeMemoryInst(Instruction *MemoryInst, Value *Addr, // For non-PHIs, determine the addressing mode being computed. SmallVector NewAddrModeInsts; ExtAddrMode NewAddrMode = AddressingModeMatcher::Match( - V, AccessTy, MemoryInst, NewAddrModeInsts, *TM, InsertedTruncsSet, - PromotedInsts, TPT); + V, AccessTy, AddrSpace, MemoryInst, NewAddrModeInsts, *TM, + InsertedTruncsSet, PromotedInsts, TPT); // This check is broken into two cases with very similar code to avoid using // getNumUses() as much as possible. Some values have a lot of uses, so @@ -3545,7 +3555,7 @@ bool CodeGenPrepare::OptimizeInlineAsmInst(CallInst *CS) { if (OpInfo.ConstraintType == TargetLowering::C_Memory && OpInfo.isIndirect) { Value *OpVal = CS->getArgOperand(ArgNo++); - MadeChange |= OptimizeMemoryInst(CS, OpVal, OpVal->getType()); + MadeChange |= OptimizeMemoryInst(CS, OpVal, OpVal->getType(), ~0u); } else if (OpInfo.Type == InlineAsm::isInput) ArgNo++; } @@ -4394,15 +4404,19 @@ bool CodeGenPrepare::OptimizeInst(Instruction *I, bool& ModifiedDT) { return OptimizeCmpExpression(CI); if (LoadInst *LI = dyn_cast(I)) { - if (TLI) - return OptimizeMemoryInst(I, I->getOperand(0), LI->getType()); + if (TLI) { + unsigned AS = LI->getPointerAddressSpace(); + return OptimizeMemoryInst(I, I->getOperand(0), LI->getType(), AS); + } return false; } if (StoreInst *SI = dyn_cast(I)) { - if (TLI) + if (TLI) { + unsigned AS = SI->getPointerAddressSpace(); return OptimizeMemoryInst(I, SI->getOperand(1), - SI->getOperand(0)->getType()); + SI->getOperand(0)->getType(), AS); + } return false; } diff --git a/lib/CodeGen/CriticalAntiDepBreaker.cpp b/lib/CodeGen/CriticalAntiDepBreaker.cpp index 3d62d48876025..dba280fd5aa25 100644 --- a/lib/CodeGen/CriticalAntiDepBreaker.cpp +++ b/lib/CodeGen/CriticalAntiDepBreaker.cpp @@ -71,7 +71,7 @@ void CriticalAntiDepBreaker::StartBlock(MachineBasicBlock *BB) { // all callee-saved registers. In non-return this is any // callee-saved register that is not saved in the prolog. const MachineFrameInfo *MFI = MF.getFrameInfo(); - BitVector Pristine = MFI->getPristineRegs(BB); + BitVector Pristine = MFI->getPristineRegs(MF); for (const MCPhysReg *I = TRI->getCalleeSavedRegs(&MF); *I; ++I) { if (!IsReturnBlock && !Pristine.test(*I)) continue; for (MCRegAliasIterator AI(*I, TRI, true); AI.isValid(); ++AI) { diff --git a/lib/CodeGen/EarlyIfConversion.cpp b/lib/CodeGen/EarlyIfConversion.cpp index 092b7f804e4fe..d3687b98b3445 100644 --- a/lib/CodeGen/EarlyIfConversion.cpp +++ b/lib/CodeGen/EarlyIfConversion.cpp @@ -226,21 +226,21 @@ bool SSAIfConv::canSpeculateInstrs(MachineBasicBlock *MBB) { } // Check for any dependencies on Head instructions. - for (MIOperands MO(I); MO.isValid(); ++MO) { - if (MO->isRegMask()) { + for (const MachineOperand &MO : I->operands()) { + if (MO.isRegMask()) { DEBUG(dbgs() << "Won't speculate regmask: " << *I); return false; } - if (!MO->isReg()) + if (!MO.isReg()) continue; - unsigned Reg = MO->getReg(); + unsigned Reg = MO.getReg(); // Remember clobbered regunits. - if (MO->isDef() && TargetRegisterInfo::isPhysicalRegister(Reg)) + if (MO.isDef() && TargetRegisterInfo::isPhysicalRegister(Reg)) for (MCRegUnitIterator Units(Reg, TRI); Units.isValid(); ++Units) ClobberedRegUnits.set(*Units); - if (!MO->readsReg() || !TargetRegisterInfo::isVirtualRegister(Reg)) + if (!MO.readsReg() || !TargetRegisterInfo::isVirtualRegister(Reg)) continue; MachineInstr *DefMI = MRI->getVRegDef(Reg); if (!DefMI || DefMI->getParent() != Head) @@ -284,19 +284,19 @@ bool SSAIfConv::findInsertionPoint() { } // Update live regunits. - for (MIOperands MO(I); MO.isValid(); ++MO) { + for (const MachineOperand &MO : I->operands()) { // We're ignoring regmask operands. That is conservatively correct. - if (!MO->isReg()) + if (!MO.isReg()) continue; - unsigned Reg = MO->getReg(); + unsigned Reg = MO.getReg(); if (!TargetRegisterInfo::isPhysicalRegister(Reg)) continue; // I clobbers Reg, so it isn't live before I. - if (MO->isDef()) + if (MO.isDef()) for (MCRegUnitIterator Units(Reg, TRI); Units.isValid(); ++Units) LiveRegUnits.erase(*Units); // Unless I reads Reg. - if (MO->readsReg()) + if (MO.readsReg()) Reads.push_back(Reg); } // Anything read by I is live before I. diff --git a/lib/CodeGen/GlobalMerge.cpp b/lib/CodeGen/GlobalMerge.cpp index 79de17567f764..37b3bf17ed1f3 100644 --- a/lib/CodeGen/GlobalMerge.cpp +++ b/lib/CodeGen/GlobalMerge.cpp @@ -124,6 +124,12 @@ namespace { // for more information. unsigned MaxOffset; + /// Whether we should try to optimize for size only. + /// Currently, this applies a dead simple heuristic: only consider globals + /// used in minsize functions for merging. + /// FIXME: This could learn about optsize, and be used in the cost model. + bool OnlyOptimizeForSize; + bool doMerge(SmallVectorImpl &Globals, Module &M, bool isConst, unsigned AddrSpace) const; /// \brief Merge everything in \p Globals for which the corresponding bit @@ -152,9 +158,10 @@ namespace { public: static char ID; // Pass identification, replacement for typeid. explicit GlobalMerge(const TargetMachine *TM = nullptr, - unsigned MaximalOffset = 0) + unsigned MaximalOffset = 0, + bool OnlyOptimizeForSize = false) : FunctionPass(ID), TM(TM), DL(TM->getDataLayout()), - MaxOffset(MaximalOffset) { + MaxOffset(MaximalOffset), OnlyOptimizeForSize(OnlyOptimizeForSize) { initializeGlobalMergePass(*PassRegistry::getPassRegistry()); } @@ -273,6 +280,8 @@ bool GlobalMerge::doMerge(SmallVectorImpl &Globals, // users, so look through ConstantExpr... Use *UI, *UE; if (ConstantExpr *CE = dyn_cast(U.getUser())) { + if (CE->use_empty()) + continue; UI = &*CE->use_begin(); UE = nullptr; } else if (isa(U.getUser())) { @@ -290,6 +299,12 @@ bool GlobalMerge::doMerge(SmallVectorImpl &Globals, continue; Function *ParentFn = I->getParent()->getParent(); + + // If we're only optimizing for size, ignore non-minsize functions. + if (OnlyOptimizeForSize && + !ParentFn->hasFnAttribute(Attribute::MinSize)) + continue; + size_t UGSIdx = GlobalUsesByFunction[ParentFn]; // If this is the first global the basic block uses, map it to the set @@ -585,6 +600,7 @@ bool GlobalMerge::doFinalization(Module &M) { return false; } -Pass *llvm::createGlobalMergePass(const TargetMachine *TM, unsigned Offset) { - return new GlobalMerge(TM, Offset); +Pass *llvm::createGlobalMergePass(const TargetMachine *TM, unsigned Offset, + bool OnlyOptimizeForSize) { + return new GlobalMerge(TM, Offset, OnlyOptimizeForSize); } diff --git a/lib/CodeGen/IfConversion.cpp b/lib/CodeGen/IfConversion.cpp index 0d59c72cb8f77..e861ceb2a664b 100644 --- a/lib/CodeGen/IfConversion.cpp +++ b/lib/CodeGen/IfConversion.cpp @@ -170,9 +170,12 @@ namespace { bool PreRegAlloc; bool MadeChange; int FnNum; + std::function PredicateFtor; + public: static char ID; - IfConverter() : MachineFunctionPass(ID), FnNum(-1) { + IfConverter(std::function Ftor = nullptr) + : MachineFunctionPass(ID), FnNum(-1), PredicateFtor(Ftor) { initializeIfConverterPass(*PassRegistry::getPassRegistry()); } @@ -270,6 +273,9 @@ INITIALIZE_PASS_DEPENDENCY(MachineBranchProbabilityInfo) INITIALIZE_PASS_END(IfConverter, "if-converter", "If Converter", false, false) bool IfConverter::runOnMachineFunction(MachineFunction &MF) { + if (PredicateFtor && !PredicateFtor(*MF.getFunction())) + return false; + const TargetSubtargetInfo &ST = MF.getSubtarget(); TLI = ST.getTargetLowering(); TII = ST.getInstrInfo(); @@ -1691,3 +1697,8 @@ void IfConverter::MergeBlocks(BBInfo &ToBBI, BBInfo &FromBBI, bool AddEdges) { ToBBI.IsAnalyzed = false; FromBBI.IsAnalyzed = false; } + +FunctionPass * +llvm::createIfConverter(std::function Ftor) { + return new IfConverter(Ftor); +} diff --git a/lib/CodeGen/LLVMBuild.txt b/lib/CodeGen/LLVMBuild.txt index fee0347ea6592..05905d04dabfa 100644 --- a/lib/CodeGen/LLVMBuild.txt +++ b/lib/CodeGen/LLVMBuild.txt @@ -16,7 +16,7 @@ ;===------------------------------------------------------------------------===; [common] -subdirectories = AsmPrinter SelectionDAG +subdirectories = AsmPrinter SelectionDAG MIRParser [component_0] type = Library diff --git a/lib/CodeGen/LLVMTargetMachine.cpp b/lib/CodeGen/LLVMTargetMachine.cpp index 610c9f47bac7c..ff5205801bc4a 100644 --- a/lib/CodeGen/LLVMTargetMachine.cpp +++ b/lib/CodeGen/LLVMTargetMachine.cpp @@ -150,12 +150,7 @@ bool LLVMTargetMachine::addPassesToEmitFile( return true; if (StopAfter) { - // FIXME: The intent is that this should eventually write out a YAML file, - // containing the LLVM IR, the machine-level IR (when stopping after a - // machine-level pass), and whatever other information is needed to - // deserialize the code and resume compilation. For now, just write the - // LLVM IR. - PM.add(createPrintModulePass(Out)); + PM.add(createPrintMIRPass(outs())); return false; } diff --git a/lib/CodeGen/LiveIntervalAnalysis.cpp b/lib/CodeGen/LiveIntervalAnalysis.cpp index adca4cc738e1e..c00b010e763b3 100644 --- a/lib/CodeGen/LiveIntervalAnalysis.cpp +++ b/lib/CodeGen/LiveIntervalAnalysis.cpp @@ -223,11 +223,11 @@ void LiveIntervals::computeRegMasks() { RMB.first = RegMaskSlots.size(); for (MachineBasicBlock::iterator MI = MBB->begin(), ME = MBB->end(); MI != ME; ++MI) - for (MIOperands MO(MI); MO.isValid(); ++MO) { - if (!MO->isRegMask()) + for (const MachineOperand &MO : MI->operands()) { + if (!MO.isRegMask()) continue; RegMaskSlots.push_back(Indexes->getInstructionIndex(MI).getRegSlot()); - RegMaskBits.push_back(MO->getRegMask()); + RegMaskBits.push_back(MO.getRegMask()); } // Compute the number of register mask instructions in this block. RMB.second = RegMaskSlots.size() - RMB.first; @@ -927,23 +927,23 @@ public: void updateAllRanges(MachineInstr *MI) { DEBUG(dbgs() << "handleMove " << OldIdx << " -> " << NewIdx << ": " << *MI); bool hasRegMask = false; - for (MIOperands MO(MI); MO.isValid(); ++MO) { - if (MO->isRegMask()) + for (MachineOperand &MO : MI->operands()) { + if (MO.isRegMask()) hasRegMask = true; - if (!MO->isReg()) + if (!MO.isReg()) continue; // Aggressively clear all kill flags. // They are reinserted by VirtRegRewriter. - if (MO->isUse()) - MO->setIsKill(false); + if (MO.isUse()) + MO.setIsKill(false); - unsigned Reg = MO->getReg(); + unsigned Reg = MO.getReg(); if (!Reg) continue; if (TargetRegisterInfo::isVirtualRegister(Reg)) { LiveInterval &LI = LIS.getInterval(Reg); if (LI.hasSubRanges()) { - unsigned SubReg = MO->getSubReg(); + unsigned SubReg = MO.getSubReg(); unsigned LaneMask = TRI.getSubRegIndexLaneMask(SubReg); for (LiveInterval::SubRange &S : LI.subranges()) { if ((S.LaneMask & LaneMask) == 0) diff --git a/lib/CodeGen/LiveRangeEdit.cpp b/lib/CodeGen/LiveRangeEdit.cpp index 27c57d5f3029b..08bbe0c3f379d 100644 --- a/lib/CodeGen/LiveRangeEdit.cpp +++ b/lib/CodeGen/LiveRangeEdit.cpp @@ -218,6 +218,22 @@ bool LiveRangeEdit::foldAsLoad(LiveInterval *LI, return true; } +bool LiveRangeEdit::useIsKill(const LiveInterval &LI, + const MachineOperand &MO) const { + const MachineInstr *MI = MO.getParent(); + SlotIndex Idx = LIS.getInstructionIndex(MI).getRegSlot(); + if (LI.Query(Idx).isKill()) + return true; + const TargetRegisterInfo &TRI = *MRI.getTargetRegisterInfo(); + unsigned SubReg = MO.getSubReg(); + unsigned LaneMask = TRI.getSubRegIndexLaneMask(SubReg); + for (const LiveInterval::SubRange &S : LI.subranges()) { + if ((S.LaneMask & LaneMask) != 0 && S.Query(Idx).isKill()) + return true; + } + return false; +} + /// Find all live intervals that need to shrink, then remove the instruction. void LiveRangeEdit::eliminateDeadDef(MachineInstr *MI, ToShrinkSet &ToShrink) { assert(MI->allDefsAreDead() && "Def isn't really dead"); @@ -266,9 +282,8 @@ void LiveRangeEdit::eliminateDeadDef(MachineInstr *MI, ToShrinkSet &ToShrink) { // unlikely to change anything. We typically don't want to shrink the // PIC base register that has lots of uses everywhere. // Always shrink COPY uses that probably come from live range splitting. - if (MI->readsVirtualRegister(Reg) && - (MI->isCopy() || MOI->isDef() || MRI.hasOneNonDBGUse(Reg) || - LI.Query(Idx).isKill())) + if ((MI->readsVirtualRegister(Reg) && (MI->isCopy() || MOI->isDef())) || + (MOI->readsReg() && (MRI.hasOneNonDBGUse(Reg) || useIsKill(LI, *MOI)))) ToShrink.insert(&LI); // Remove defined value. diff --git a/lib/CodeGen/MIRParser/CMakeLists.txt b/lib/CodeGen/MIRParser/CMakeLists.txt new file mode 100644 index 0000000000000..468f072ed7f3b --- /dev/null +++ b/lib/CodeGen/MIRParser/CMakeLists.txt @@ -0,0 +1,5 @@ +add_llvm_library(LLVMMIRParser + MIRParser.cpp + ) + +add_dependencies(LLVMMIRParser intrinsics_gen) diff --git a/lib/CodeGen/MIRParser/LLVMBuild.txt b/lib/CodeGen/MIRParser/LLVMBuild.txt new file mode 100644 index 0000000000000..04ae72290f938 --- /dev/null +++ b/lib/CodeGen/MIRParser/LLVMBuild.txt @@ -0,0 +1,22 @@ +;===- ./lib/CodeGen/MIRParser/LLVMBuild.txt --------------------*- Conf -*--===; +; +; The LLVM Compiler Infrastructure +; +; This file is distributed under the University of Illinois Open Source +; License. See LICENSE.TXT for details. +; +;===------------------------------------------------------------------------===; +; +; This is an LLVMBuild description file for the components in this subdirectory. +; +; For more information on the LLVMBuild system, please see: +; +; http://llvm.org/docs/LLVMBuild.html +; +;===------------------------------------------------------------------------===; + +[component_0] +type = Library +name = MIRParser +parent = CodeGen +required_libraries = Core Support Target AsmParser CodeGen diff --git a/lib/CodeGen/MIRParser/MIRParser.cpp b/lib/CodeGen/MIRParser/MIRParser.cpp new file mode 100644 index 0000000000000..7a51b3881afc6 --- /dev/null +++ b/lib/CodeGen/MIRParser/MIRParser.cpp @@ -0,0 +1,171 @@ +//===- MIRParser.cpp - MIR serialization format parser implementation -----===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements the class that parses the optional LLVM IR and machine +// functions that are stored in MIR files. +// +//===----------------------------------------------------------------------===// + +#include "llvm/CodeGen/MIRParser/MIRParser.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/AsmParser/Parser.h" +#include "llvm/CodeGen/MIRYamlMapping.h" +#include "llvm/IR/Module.h" +#include "llvm/Support/LineIterator.h" +#include "llvm/Support/SMLoc.h" +#include "llvm/Support/SourceMgr.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/YAMLTraits.h" +#include + +using namespace llvm; + +namespace { + +/// This class implements the parsing of LLVM IR that's embedded inside a MIR +/// file. +class MIRParserImpl { + SourceMgr SM; + StringRef Filename; + LLVMContext &Context; + +public: + MIRParserImpl(std::unique_ptr Contents, StringRef Filename, + LLVMContext &Context); + + /// Try to parse the optional LLVM module and the machine functions in the MIR + /// file. + /// + /// Return null if an error occurred. + std::unique_ptr parse(SMDiagnostic &Error); + + /// Parse the machine function in the current YAML document. + /// + /// Return true if an error occurred. + bool parseMachineFunction(yaml::Input &In); + +private: + /// Return a MIR diagnostic converted from an LLVM assembly diagnostic. + SMDiagnostic diagFromLLVMAssemblyDiag(const SMDiagnostic &Error, + SMRange SourceRange); +}; + +} // end anonymous namespace + +MIRParserImpl::MIRParserImpl(std::unique_ptr Contents, + StringRef Filename, LLVMContext &Context) + : SM(), Filename(Filename), Context(Context) { + SM.AddNewSourceBuffer(std::move(Contents), SMLoc()); +} + +static void handleYAMLDiag(const SMDiagnostic &Diag, void *Context) { + *reinterpret_cast(Context) = Diag; +} + +std::unique_ptr MIRParserImpl::parse(SMDiagnostic &Error) { + yaml::Input In(SM.getMemoryBuffer(SM.getMainFileID())->getBuffer(), + /*Ctxt=*/nullptr, handleYAMLDiag, &Error); + + if (!In.setCurrentDocument()) { + if (!Error.getMessage().empty()) + return nullptr; + // Create an empty module when the MIR file is empty. + return llvm::make_unique(Filename, Context); + } + + std::unique_ptr M; + // Parse the block scalar manually so that we can return unique pointer + // without having to go trough YAML traits. + if (const auto *BSN = + dyn_cast_or_null(In.getCurrentNode())) { + M = parseAssembly(MemoryBufferRef(BSN->getValue(), Filename), Error, + Context); + if (!M) { + Error = diagFromLLVMAssemblyDiag(Error, BSN->getSourceRange()); + return M; + } + In.nextDocument(); + if (!In.setCurrentDocument()) + return M; + } else { + // Create an new, empty module. + M = llvm::make_unique(Filename, Context); + } + + // Parse the machine functions. + do { + if (parseMachineFunction(In)) + return nullptr; + In.nextDocument(); + } while (In.setCurrentDocument()); + + return M; +} + +bool MIRParserImpl::parseMachineFunction(yaml::Input &In) { + yaml::MachineFunction MF; + yaml::yamlize(In, MF, false); + if (In.error()) + return true; + // TODO: Initialize the real machine function with the state in the yaml + // machine function later on. + return false; +} + +SMDiagnostic MIRParserImpl::diagFromLLVMAssemblyDiag(const SMDiagnostic &Error, + SMRange SourceRange) { + assert(SourceRange.isValid()); + + // Translate the location of the error from the location in the llvm IR string + // to the corresponding location in the MIR file. + auto LineAndColumn = SM.getLineAndColumn(SourceRange.Start); + unsigned Line = LineAndColumn.first + Error.getLineNo() - 1; + unsigned Column = Error.getColumnNo(); + StringRef LineStr = Error.getLineContents(); + SMLoc Loc = Error.getLoc(); + + // Get the full line and adjust the column number by taking the indentation of + // LLVM IR into account. + for (line_iterator L(*SM.getMemoryBuffer(SM.getMainFileID()), false), E; + L != E; ++L) { + if (L.line_number() == Line) { + LineStr = *L; + Loc = SMLoc::getFromPointer(LineStr.data()); + auto Indent = LineStr.find(Error.getLineContents()); + if (Indent != StringRef::npos) + Column += Indent; + break; + } + } + + return SMDiagnostic(SM, Loc, Filename, Line, Column, Error.getKind(), + Error.getMessage(), LineStr, Error.getRanges(), + Error.getFixIts()); +} + +std::unique_ptr llvm::parseMIRFile(StringRef Filename, + SMDiagnostic &Error, + LLVMContext &Context) { + auto FileOrErr = MemoryBuffer::getFile(Filename); + if (std::error_code EC = FileOrErr.getError()) { + Error = SMDiagnostic(Filename, SourceMgr::DK_Error, + "Could not open input file: " + EC.message()); + return std::unique_ptr(); + } + return parseMIR(std::move(FileOrErr.get()), Error, Context); +} + +std::unique_ptr llvm::parseMIR(std::unique_ptr Contents, + SMDiagnostic &Error, + LLVMContext &Context) { + auto Filename = Contents->getBufferIdentifier(); + MIRParserImpl Parser(std::move(Contents), Filename, Context); + return Parser.parse(Error); +} diff --git a/lib/CodeGen/MIRParser/Makefile b/lib/CodeGen/MIRParser/Makefile new file mode 100644 index 0000000000000..c02d18806a9c2 --- /dev/null +++ b/lib/CodeGen/MIRParser/Makefile @@ -0,0 +1,13 @@ +##===- lib/CodeGen/MIRParser/Makefile ----------------------*- Makefile -*-===## +# +# The LLVM Compiler Infrastructure +# +# This file is distributed under the University of Illinois Open Source +# License. See LICENSE.TXT for details. +# +##===----------------------------------------------------------------------===## + +LEVEL = ../../.. +LIBRARYNAME = LLVMMIRParser + +include $(LEVEL)/Makefile.common diff --git a/lib/CodeGen/MIRPrintingPass.cpp b/lib/CodeGen/MIRPrintingPass.cpp new file mode 100644 index 0000000000000..5e0f4cdcbfde0 --- /dev/null +++ b/lib/CodeGen/MIRPrintingPass.cpp @@ -0,0 +1,109 @@ +//===- MIRPrintingPass.cpp - Pass that prints out using the MIR format ----===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements a pass that prints out the LLVM module using the MIR +// serialization format. +// +//===----------------------------------------------------------------------===// + +#include "llvm/CodeGen/Passes.h" +#include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/CodeGen/MIRYamlMapping.h" +#include "llvm/IR/Module.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/Support/YAMLTraits.h" + +using namespace llvm; + +namespace llvm { +namespace yaml { + +/// This struct serializes the LLVM IR module. +template <> struct BlockScalarTraits { + static void output(const Module &Mod, void *Ctxt, raw_ostream &OS) { + Mod.print(OS, nullptr); + } + static StringRef input(StringRef Str, void *Ctxt, Module &Mod) { + llvm_unreachable("LLVM Module is supposed to be parsed separately"); + return ""; + } +}; + +} // end namespace yaml +} // end namespace llvm + +namespace { + +/// This class prints out the machine functions using the MIR serialization +/// format. +class MIRPrinter { + raw_ostream &OS; + +public: + MIRPrinter(raw_ostream &OS) : OS(OS) {} + + void print(const MachineFunction &MF); +}; + +void MIRPrinter::print(const MachineFunction &MF) { + yaml::MachineFunction YamlMF; + YamlMF.Name = MF.getName(); + yaml::Output Out(OS); + Out << YamlMF; +} + +/// This pass prints out the LLVM IR to an output stream using the MIR +/// serialization format. +struct MIRPrintingPass : public MachineFunctionPass { + static char ID; + raw_ostream &OS; + std::string MachineFunctions; + + MIRPrintingPass() : MachineFunctionPass(ID), OS(dbgs()) {} + MIRPrintingPass(raw_ostream &OS) : MachineFunctionPass(ID), OS(OS) {} + + const char *getPassName() const override { return "MIR Printing Pass"; } + + void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.setPreservesAll(); + MachineFunctionPass::getAnalysisUsage(AU); + } + + virtual bool runOnMachineFunction(MachineFunction &MF) override { + std::string Str; + raw_string_ostream StrOS(Str); + MIRPrinter(StrOS).print(MF); + MachineFunctions.append(StrOS.str()); + return false; + } + + virtual bool doFinalization(Module &M) override { + yaml::Output Out(OS); + Out << M; + OS << MachineFunctions; + return false; + } +}; + +char MIRPrintingPass::ID = 0; + +} // end anonymous namespace + +char &llvm::MIRPrintingPassID = MIRPrintingPass::ID; +INITIALIZE_PASS(MIRPrintingPass, "mir-printer", "MIR Printer", false, false) + +namespace llvm { + +MachineFunctionPass *createPrintMIRPass(raw_ostream &OS) { + return new MIRPrintingPass(OS); +} + +} // end namespace llvm diff --git a/lib/CodeGen/MachineCopyPropagation.cpp b/lib/CodeGen/MachineCopyPropagation.cpp index 43c80b7c21bf4..a6863412132bd 100644 --- a/lib/CodeGen/MachineCopyPropagation.cpp +++ b/lib/CodeGen/MachineCopyPropagation.cpp @@ -54,7 +54,6 @@ namespace { SourceMap &SrcMap, DenseMap &AvailCopyMap); bool CopyPropagateBlock(MachineBasicBlock &MBB); - void removeCopy(MachineInstr *MI); }; } char MachineCopyPropagation::ID = 0; @@ -127,13 +126,6 @@ static bool isNopCopy(MachineInstr *CopyMI, unsigned Def, unsigned Src, return false; } -// Remove MI from the function because it has been determined it is dead. -// Turn it into a noop KILL instruction as opposed to removing it to -// maintain imp-use/imp-def chains. -void MachineCopyPropagation::removeCopy(MachineInstr *MI) { - MI->setDesc(TII->get(TargetOpcode::KILL)); -} - bool MachineCopyPropagation::CopyPropagateBlock(MachineBasicBlock &MBB) { SmallSetVector MaybeDeadCopies; // Candidates for deletion DenseMap AvailCopyMap; // Def -> available copies map @@ -183,7 +175,7 @@ bool MachineCopyPropagation::CopyPropagateBlock(MachineBasicBlock &MBB) { for (MachineBasicBlock::iterator I = CopyMI, E = MI; I != E; ++I) I->clearRegisterKills(Def, TRI); - removeCopy(MI); + MI->eraseFromParent(); Changed = true; ++NumDeletes; continue; @@ -252,11 +244,7 @@ bool MachineCopyPropagation::CopyPropagateBlock(MachineBasicBlock &MBB) { report_fatal_error("MachineCopyPropagation should be run after" " register allocation!"); - // Treat undef use like defs. - // The backends are allowed to do whatever they want with undef value - // and we cannot be sure this register will not be rewritten to break - // some false dependencies for the hardware for instance. - if (MO.isDef() || MO.isUndef()) { + if (MO.isDef()) { Defs.push_back(Reg); continue; } @@ -270,6 +258,14 @@ bool MachineCopyPropagation::CopyPropagateBlock(MachineBasicBlock &MBB) { MaybeDeadCopies.remove(CI->second); } } + // Treat undef use like defs for copy propagation but not for + // dead copy. We would need to do a liveness check to be sure the copy + // is dead for undef uses. + // The backends are allowed to do whatever they want with undef value + // and we cannot be sure this register will not be rewritten to break + // some false dependencies for the hardware for instance. + if (MO.isUndef()) + Defs.push_back(Reg); } // The instruction has a register mask operand which means that it clobbers @@ -287,7 +283,7 @@ bool MachineCopyPropagation::CopyPropagateBlock(MachineBasicBlock &MBB) { continue; DEBUG(dbgs() << "MCP: Removing copy due to regmask clobbering: "; (*DI)->dump()); - removeCopy(*DI); + (*DI)->eraseFromParent(); Changed = true; ++NumDeletes; } @@ -323,7 +319,7 @@ bool MachineCopyPropagation::CopyPropagateBlock(MachineBasicBlock &MBB) { DI = MaybeDeadCopies.begin(), DE = MaybeDeadCopies.end(); DI != DE; ++DI) { if (!MRI->isReserved((*DI)->getOperand(0).getReg())) { - removeCopy(*DI); + (*DI)->eraseFromParent(); Changed = true; ++NumDeletes; } diff --git a/lib/CodeGen/MachineFunction.cpp b/lib/CodeGen/MachineFunction.cpp index 8ec63f823e17d..09662b6e48d31 100644 --- a/lib/CodeGen/MachineFunction.cpp +++ b/lib/CodeGen/MachineFunction.cpp @@ -584,12 +584,8 @@ int MachineFrameInfo::CreateFixedSpillStackObject(uint64_t Size, return -++NumFixedObjects; } -BitVector -MachineFrameInfo::getPristineRegs(const MachineBasicBlock *MBB) const { - assert(MBB && "MBB must be valid"); - const MachineFunction *MF = MBB->getParent(); - assert(MF && "MBB must be part of a MachineFunction"); - const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo(); +BitVector MachineFrameInfo::getPristineRegs(const MachineFunction &MF) const { + const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo(); BitVector BV(TRI->getNumRegs()); // Before CSI is calculated, no registers are considered pristine. They can be @@ -597,14 +593,10 @@ MachineFrameInfo::getPristineRegs(const MachineBasicBlock *MBB) const { if (!isCalleeSavedInfoValid()) return BV; - for (const MCPhysReg *CSR = TRI->getCalleeSavedRegs(MF); CSR && *CSR; ++CSR) + for (const MCPhysReg *CSR = TRI->getCalleeSavedRegs(&MF); CSR && *CSR; ++CSR) BV.set(*CSR); - // Each MBB before the save point has all CSRs pristine. - if (isBeforeSavePoint(*MF, *MBB)) - return BV; - - // On other MBBs the saved CSRs are not pristine. + // Saved CSRs are not pristine. const std::vector &CSI = getCalleeSavedInfo(); for (std::vector::const_iterator I = CSI.begin(), E = CSI.end(); I != E; ++I) @@ -613,40 +605,6 @@ MachineFrameInfo::getPristineRegs(const MachineBasicBlock *MBB) const { return BV; } -// Note: We could use some sort of caching mecanism, but we lack the ability -// to know when the cache is invalid, i.e., the CFG changed. -// Assuming we have that, we can simply compute all the set of MBBs -// that are before the save point. -bool MachineFrameInfo::isBeforeSavePoint(const MachineFunction &MF, - const MachineBasicBlock &MBB) const { - // Early exit if shrink-wrapping did not kick. - if (!Save) - return &MBB == &MF.front(); - - // Starting from MBB, check if there is a path leading to Save that do - // not cross Restore. - SmallPtrSet Visited; - SmallVector WorkList; - WorkList.push_back(&MBB); - Visited.insert(&MBB); - do { - const MachineBasicBlock *CurBB = WorkList.pop_back_val(); - // By construction, the region that is after the save point is - // dominated by the Save and post-dominated by the Restore. - // If we do not reach Restore and still reach Save, this - // means MBB is before Save. - if (CurBB == Save) - return true; - if (CurBB == Restore) - continue; - // Enqueue all the successors not already visited. - for (MachineBasicBlock *SuccBB : CurBB->successors()) - if (Visited.insert(SuccBB).second) - WorkList.push_back(SuccBB); - } while (!WorkList.empty()); - return false; -} - unsigned MachineFrameInfo::estimateStackSize(const MachineFunction &MF) const { const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering(); const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo(); diff --git a/lib/CodeGen/MachineInstr.cpp b/lib/CodeGen/MachineInstr.cpp index 205032f929711..e67102865bfa6 100644 --- a/lib/CodeGen/MachineInstr.cpp +++ b/lib/CodeGen/MachineInstr.cpp @@ -1092,9 +1092,8 @@ const TargetRegisterClass *MachineInstr::getRegClassConstraintEffectForVReg( OpndIt.getOperandNo(), Reg, CurRC, TII, TRI); else // Otherwise, just check the current operands. - for (ConstMIOperands OpndIt(this); OpndIt.isValid() && CurRC; ++OpndIt) - CurRC = getRegClassConstraintEffectForVRegImpl(OpndIt.getOperandNo(), Reg, - CurRC, TII, TRI); + for (unsigned i = 0, e = NumOperands; i < e && CurRC; ++i) + CurRC = getRegClassConstraintEffectForVRegImpl(i, Reg, CurRC, TII, TRI); return CurRC; } diff --git a/lib/CodeGen/MachineInstrBundle.cpp b/lib/CodeGen/MachineInstrBundle.cpp index 0690f08d495ba..cd820ee1ac526 100644 --- a/lib/CodeGen/MachineInstrBundle.cpp +++ b/lib/CodeGen/MachineInstrBundle.cpp @@ -23,11 +23,15 @@ namespace { class UnpackMachineBundles : public MachineFunctionPass { public: static char ID; // Pass identification - UnpackMachineBundles() : MachineFunctionPass(ID) { + UnpackMachineBundles(std::function Ftor = nullptr) + : MachineFunctionPass(ID), PredicateFtor(Ftor) { initializeUnpackMachineBundlesPass(*PassRegistry::getPassRegistry()); } bool runOnMachineFunction(MachineFunction &MF) override; + + private: + std::function PredicateFtor; }; } // end anonymous namespace @@ -37,6 +41,9 @@ INITIALIZE_PASS(UnpackMachineBundles, "unpack-mi-bundles", "Unpack machine instruction bundles", false, false) bool UnpackMachineBundles::runOnMachineFunction(MachineFunction &MF) { + if (PredicateFtor && !PredicateFtor(*MF.getFunction())) + return false; + bool Changed = false; for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) { MachineBasicBlock *MBB = &*I; @@ -69,6 +76,10 @@ bool UnpackMachineBundles::runOnMachineFunction(MachineFunction &MF) { return Changed; } +FunctionPass * +llvm::createUnpackMachineBundles(std::function Ftor) { + return new UnpackMachineBundles(Ftor); +} namespace { class FinalizeMachineBundles : public MachineFunctionPass { diff --git a/lib/CodeGen/MachineLICM.cpp b/lib/CodeGen/MachineLICM.cpp index 3967a2fbf8c84..cce590c6dc5b6 100644 --- a/lib/CodeGen/MachineLICM.cpp +++ b/lib/CodeGen/MachineLICM.cpp @@ -1012,10 +1012,10 @@ bool MachineLICM::HasLoopPHIUse(const MachineInstr *MI) const { SmallVector Work(1, MI); do { MI = Work.pop_back_val(); - for (ConstMIOperands MO(MI); MO.isValid(); ++MO) { - if (!MO->isReg() || !MO->isDef()) + for (const MachineOperand &MO : MI->operands()) { + if (!MO.isReg() || !MO.isDef()) continue; - unsigned Reg = MO->getReg(); + unsigned Reg = MO.getReg(); if (!TargetRegisterInfo::isVirtualRegister(Reg)) continue; for (MachineInstr &UseMI : MRI->use_instructions(Reg)) { diff --git a/lib/CodeGen/MachineModuleInfo.cpp b/lib/CodeGen/MachineModuleInfo.cpp index d9da7bcca4fac..eec984f53b90a 100644 --- a/lib/CodeGen/MachineModuleInfo.cpp +++ b/lib/CodeGen/MachineModuleInfo.cpp @@ -114,7 +114,7 @@ MCSymbol *MMIAddrLabelMap::getAddrLabelSymbol(BasicBlock *BB) { // Otherwise, this is a new entry, create a new symbol for it and add an // entry to BBCallbacks so we can be notified if the BB is deleted or RAUWd. - BBCallbacks.push_back(BB); + BBCallbacks.emplace_back(BB); BBCallbacks.back().setMap(this); Entry.Index = BBCallbacks.size()-1; Entry.Fn = BB->getParent(); @@ -308,6 +308,7 @@ void MachineModuleInfo::EndFunction() { // Clean up exception info. LandingPads.clear(); + PersonalityTypeCache = EHPersonality::Unknown; CallSiteMap.clear(); TypeInfos.clear(); FilterIds.clear(); diff --git a/lib/CodeGen/MachineSink.cpp b/lib/CodeGen/MachineSink.cpp index 5f03390f146ce..aed0e500d4419 100644 --- a/lib/CodeGen/MachineSink.cpp +++ b/lib/CodeGen/MachineSink.cpp @@ -655,6 +655,10 @@ bool MachineSinking::SinkInstruction(MachineInstr *MI, bool &SawStore) { if (!MI->isSafeToMove(AA, SawStore)) return false; + // Convergent operations may only be moved to control equivalent locations. + if (MI->isConvergent()) + return false; + // FIXME: This should include support for sinking instructions within the // block they are currently in to shorten the live ranges. We often get // instructions sunk into the top of a large block, but it would be better to diff --git a/lib/CodeGen/MachineTraceMetrics.cpp b/lib/CodeGen/MachineTraceMetrics.cpp index e07250bf4f340..34ac9d5b0ed7a 100644 --- a/lib/CodeGen/MachineTraceMetrics.cpp +++ b/lib/CodeGen/MachineTraceMetrics.cpp @@ -627,10 +627,12 @@ static bool getDataDeps(const MachineInstr *UseMI, SmallVectorImpl &Deps, const MachineRegisterInfo *MRI) { bool HasPhysRegs = false; - for (ConstMIOperands MO(UseMI); MO.isValid(); ++MO) { - if (!MO->isReg()) + for (MachineInstr::const_mop_iterator I = UseMI->operands_begin(), + E = UseMI->operands_end(); I != E; ++I) { + const MachineOperand &MO = *I; + if (!MO.isReg()) continue; - unsigned Reg = MO->getReg(); + unsigned Reg = MO.getReg(); if (!Reg) continue; if (TargetRegisterInfo::isPhysicalRegister(Reg)) { @@ -638,8 +640,8 @@ static bool getDataDeps(const MachineInstr *UseMI, continue; } // Collect virtual register reads. - if (MO->readsReg()) - Deps.push_back(DataDep(MRI, Reg, MO.getOperandNo())); + if (MO.readsReg()) + Deps.push_back(DataDep(MRI, Reg, UseMI->getOperandNo(I))); } return HasPhysRegs; } @@ -690,28 +692,30 @@ static void updatePhysDepsDownwards(const MachineInstr *UseMI, SmallVector Kills; SmallVector LiveDefOps; - for (ConstMIOperands MO(UseMI); MO.isValid(); ++MO) { - if (!MO->isReg()) + for (MachineInstr::const_mop_iterator MI = UseMI->operands_begin(), + ME = UseMI->operands_end(); MI != ME; ++MI) { + const MachineOperand &MO = *MI; + if (!MO.isReg()) continue; - unsigned Reg = MO->getReg(); + unsigned Reg = MO.getReg(); if (!TargetRegisterInfo::isPhysicalRegister(Reg)) continue; // Track live defs and kills for updating RegUnits. - if (MO->isDef()) { - if (MO->isDead()) + if (MO.isDef()) { + if (MO.isDead()) Kills.push_back(Reg); else - LiveDefOps.push_back(MO.getOperandNo()); - } else if (MO->isKill()) + LiveDefOps.push_back(UseMI->getOperandNo(MI)); + } else if (MO.isKill()) Kills.push_back(Reg); // Identify dependencies. - if (!MO->readsReg()) + if (!MO.readsReg()) continue; for (MCRegUnitIterator Units(Reg, TRI); Units.isValid(); ++Units) { SparseSet::iterator I = RegUnits.find(*Units); if (I == RegUnits.end()) continue; - Deps.push_back(DataDep(I->MI, I->Op, MO.getOperandNo())); + Deps.push_back(DataDep(I->MI, I->Op, UseMI->getOperandNo(MI))); break; } } @@ -864,15 +868,18 @@ static unsigned updatePhysDepsUpwards(const MachineInstr *MI, unsigned Height, const TargetInstrInfo *TII, const TargetRegisterInfo *TRI) { SmallVector ReadOps; - for (ConstMIOperands MO(MI); MO.isValid(); ++MO) { - if (!MO->isReg()) + + for (MachineInstr::const_mop_iterator MOI = MI->operands_begin(), + MOE = MI->operands_end(); MOI != MOE; ++MOI) { + const MachineOperand &MO = *MOI; + if (!MO.isReg()) continue; - unsigned Reg = MO->getReg(); + unsigned Reg = MO.getReg(); if (!TargetRegisterInfo::isPhysicalRegister(Reg)) continue; - if (MO->readsReg()) - ReadOps.push_back(MO.getOperandNo()); - if (!MO->isDef()) + if (MO.readsReg()) + ReadOps.push_back(MI->getOperandNo(MOI)); + if (!MO.isDef()) continue; // This is a def of Reg. Remove corresponding entries from RegUnits, and // update MI Height to consider the physreg dependencies. @@ -885,7 +892,7 @@ static unsigned updatePhysDepsUpwards(const MachineInstr *MI, unsigned Height, // We may not know the UseMI of this dependency, if it came from the // live-in list. SchedModel can handle a NULL UseMI. DepHeight += SchedModel - .computeOperandLatency(MI, MO.getOperandNo(), I->MI, I->Op); + .computeOperandLatency(MI, MI->getOperandNo(MOI), I->MI, I->Op); } Height = std::max(Height, DepHeight); // This regunit is dead above MI. diff --git a/lib/CodeGen/MachineVerifier.cpp b/lib/CodeGen/MachineVerifier.cpp index f5edcb7393e45..ca35ec5fdcf82 100644 --- a/lib/CodeGen/MachineVerifier.cpp +++ b/lib/CodeGen/MachineVerifier.cpp @@ -694,7 +694,7 @@ MachineVerifier::visitMachineBasicBlockBefore(const MachineBasicBlock *MBB) { const MachineFrameInfo *MFI = MF->getFrameInfo(); assert(MFI && "Function has no frame info"); - BitVector PR = MFI->getPristineRegs(MBB); + BitVector PR = MFI->getPristineRegs(*MF); for (int I = PR.find_first(); I>0; I = PR.find_next(I)) { for (MCSubRegIterator SubRegs(I, TRI, /*IncludeSelf=*/true); SubRegs.isValid(); ++SubRegs) diff --git a/lib/CodeGen/Makefile b/lib/CodeGen/Makefile index 4ab3e3c0013eb..96f7ca5851387 100644 --- a/lib/CodeGen/Makefile +++ b/lib/CodeGen/Makefile @@ -9,7 +9,7 @@ LEVEL = ../.. LIBRARYNAME = LLVMCodeGen -PARALLEL_DIRS = SelectionDAG AsmPrinter +PARALLEL_DIRS = SelectionDAG AsmPrinter MIRParser BUILD_ARCHIVE = 1 include $(LEVEL)/Makefile.common diff --git a/lib/CodeGen/Passes.cpp b/lib/CodeGen/Passes.cpp index 690224342f644..4cd86e66c0e86 100644 --- a/lib/CodeGen/Passes.cpp +++ b/lib/CodeGen/Passes.cpp @@ -295,6 +295,24 @@ void TargetPassConfig::addPass(Pass *P, bool verifyAfter, bool printAfter) { if (verifyAfter) addVerifyPass(Banner); } + + // Add the passes after the pass P if there is any. + for (SmallVectorImpl >::iterator + I = Impl->InsertedPasses.begin(), + E = Impl->InsertedPasses.end(); + I != E; ++I) { + if ((*I).first == PassID) { + assert((*I).second.isValid() && "Illegal Pass ID!"); + Pass *NP; + if ((*I).second.isInstance()) + NP = (*I).second.getInstance(); + else { + NP = Pass::createPass((*I).second.getID()); + assert(NP && "Pass ID not registered"); + } + addPass(NP, false, false); + } + } } else { delete P; } @@ -329,22 +347,6 @@ AnalysisID TargetPassConfig::addPass(AnalysisID PassID, bool verifyAfter, AnalysisID FinalID = P->getPassID(); addPass(P, verifyAfter, printAfter); // Ends the lifetime of P. - // Add the passes after the pass P if there is any. - for (SmallVectorImpl >::iterator - I = Impl->InsertedPasses.begin(), E = Impl->InsertedPasses.end(); - I != E; ++I) { - if ((*I).first == PassID) { - assert((*I).second.isValid() && "Illegal Pass ID!"); - Pass *NP; - if ((*I).second.isInstance()) - NP = (*I).second.getInstance(); - else { - NP = Pass::createPass((*I).second.getID()); - assert(NP && "Pass ID not registered"); - } - addPass(NP, false, false); - } - } return FinalID; } diff --git a/lib/CodeGen/ProcessImplicitDefs.cpp b/lib/CodeGen/ProcessImplicitDefs.cpp index b1538006e7249..5f81949834841 100644 --- a/lib/CodeGen/ProcessImplicitDefs.cpp +++ b/lib/CodeGen/ProcessImplicitDefs.cpp @@ -68,8 +68,8 @@ bool ProcessImplicitDefs::canTurnIntoImplicitDef(MachineInstr *MI) { !MI->isRegSequence() && !MI->isPHI()) return false; - for (MIOperands MO(MI); MO.isValid(); ++MO) - if (MO->isReg() && MO->isUse() && MO->readsReg()) + for (const MachineOperand &MO : MI->operands()) + if (MO.isReg() && MO.isUse() && MO.readsReg()) return false; return true; } @@ -100,17 +100,17 @@ void ProcessImplicitDefs::processImplicitDef(MachineInstr *MI) { MachineBasicBlock::instr_iterator UserE = MI->getParent()->instr_end(); bool Found = false; for (++UserMI; UserMI != UserE; ++UserMI) { - for (MIOperands MO(UserMI); MO.isValid(); ++MO) { - if (!MO->isReg()) + for (MachineOperand &MO : UserMI->operands()) { + if (!MO.isReg()) continue; - unsigned UserReg = MO->getReg(); + unsigned UserReg = MO.getReg(); if (!TargetRegisterInfo::isPhysicalRegister(UserReg) || !TRI->regsOverlap(Reg, UserReg)) continue; // UserMI uses or redefines Reg. Set flags on all uses. Found = true; - if (MO->isUse()) - MO->setIsUndef(); + if (MO.isUse()) + MO.setIsUndef(); } if (Found) break; diff --git a/lib/CodeGen/RegisterCoalescer.cpp b/lib/CodeGen/RegisterCoalescer.cpp index ac7d98f258b1f..e513a4f1ccf50 100644 --- a/lib/CodeGen/RegisterCoalescer.cpp +++ b/lib/CodeGen/RegisterCoalescer.cpp @@ -1834,12 +1834,12 @@ public: unsigned JoinVals::computeWriteLanes(const MachineInstr *DefMI, bool &Redef) const { unsigned L = 0; - for (ConstMIOperands MO(DefMI); MO.isValid(); ++MO) { - if (!MO->isReg() || MO->getReg() != Reg || !MO->isDef()) + for (const MachineOperand &MO : DefMI->operands()) { + if (!MO.isReg() || MO.getReg() != Reg || !MO.isDef()) continue; L |= TRI->getSubRegIndexLaneMask( - TRI->composeSubRegIndices(SubIdx, MO->getSubReg())); - if (MO->readsReg()) + TRI->composeSubRegIndices(SubIdx, MO.getSubReg())); + if (MO.readsReg()) Redef = true; } return L; @@ -2224,13 +2224,13 @@ bool JoinVals::usesLanes(const MachineInstr *MI, unsigned Reg, unsigned SubIdx, unsigned Lanes) const { if (MI->isDebugValue()) return false; - for (ConstMIOperands MO(MI); MO.isValid(); ++MO) { - if (!MO->isReg() || MO->isDef() || MO->getReg() != Reg) + for (const MachineOperand &MO : MI->operands()) { + if (!MO.isReg() || MO.isDef() || MO.getReg() != Reg) continue; - if (!MO->readsReg()) + if (!MO.readsReg()) continue; if (Lanes & TRI->getSubRegIndexLaneMask( - TRI->composeSubRegIndices(SubIdx, MO->getSubReg()))) + TRI->composeSubRegIndices(SubIdx, MO.getSubReg()))) return true; } return false; @@ -2339,11 +2339,11 @@ void JoinVals::pruneValues(JoinVals &Other, // Remove flags. This def is now a partial redef. // Also remove flags since the joined live range will // continue past this instruction. - for (MIOperands MO(Indexes->getInstructionFromIndex(Def)); - MO.isValid(); ++MO) { - if (MO->isReg() && MO->isDef() && MO->getReg() == Reg) { - MO->setIsUndef(EraseImpDef); - MO->setIsDead(false); + for (MachineOperand &MO : + Indexes->getInstructionFromIndex(Def)->operands()) { + if (MO.isReg() && MO.isDef() && MO.getReg() == Reg) { + MO.setIsUndef(EraseImpDef); + MO.setIsDead(false); } } } diff --git a/lib/CodeGen/RegisterPressure.cpp b/lib/CodeGen/RegisterPressure.cpp index 667783e295266..450a3051c6ffb 100644 --- a/lib/CodeGen/RegisterPressure.cpp +++ b/lib/CodeGen/RegisterPressure.cpp @@ -60,11 +60,11 @@ void RegisterPressure::dump(const TargetRegisterInfo *TRI) const { dumpRegSetPressure(MaxSetPressure, TRI); dbgs() << "Live In: "; for (unsigned i = 0, e = LiveInRegs.size(); i < e; ++i) - dbgs() << PrintReg(LiveInRegs[i], TRI) << " "; + dbgs() << PrintVRegOrUnit(LiveInRegs[i], TRI) << " "; dbgs() << '\n'; dbgs() << "Live Out: "; for (unsigned i = 0, e = LiveOutRegs.size(); i < e; ++i) - dbgs() << PrintReg(LiveOutRegs[i], TRI) << " "; + dbgs() << PrintVRegOrUnit(LiveOutRegs[i], TRI) << " "; dbgs() << '\n'; } diff --git a/lib/CodeGen/RegisterScavenging.cpp b/lib/CodeGen/RegisterScavenging.cpp index 7626dd29c00a3..a34bd6341d228 100644 --- a/lib/CodeGen/RegisterScavenging.cpp +++ b/lib/CodeGen/RegisterScavenging.cpp @@ -55,7 +55,8 @@ void RegScavenger::initRegState() { setRegUsed(*I); // Pristine CSRs are also unavailable. - BitVector PR = MBB->getParent()->getFrameInfo()->getPristineRegs(MBB); + const MachineFunction &MF = *MBB->getParent(); + BitVector PR = MF.getFrameInfo()->getPristineRegs(MF); for (int I = PR.find_first(); I>0; I = PR.find_next(I)) setRegUsed(I); } diff --git a/lib/CodeGen/ScheduleDAGInstrs.cpp b/lib/CodeGen/ScheduleDAGInstrs.cpp index c60c5183b4292..e8e47b764dd21 100644 --- a/lib/CodeGen/ScheduleDAGInstrs.cpp +++ b/lib/CodeGen/ScheduleDAGInstrs.cpp @@ -1106,25 +1106,25 @@ static void toggleBundleKillFlag(MachineInstr *MI, unsigned Reg, MachineBasicBlock::instr_iterator Begin = MI; MachineBasicBlock::instr_iterator End = getBundleEnd(MI); while (Begin != End) { - for (MIOperands MO(--End); MO.isValid(); ++MO) { - if (!MO->isReg() || MO->isDef() || Reg != MO->getReg()) + for (MachineOperand &MO : (--End)->operands()) { + if (!MO.isReg() || MO.isDef() || Reg != MO.getReg()) continue; // DEBUG_VALUE nodes do not contribute to code generation and should // always be ignored. Failure to do so may result in trying to modify // KILL flags on DEBUG_VALUE nodes, which is distressing. - if (MO->isDebug()) + if (MO.isDebug()) continue; // If the register has the internal flag then it could be killing an // internal def of the register. In this case, just skip. We only want // to toggle the flag on operands visible outside the bundle. - if (MO->isInternalRead()) + if (MO.isInternalRead()) continue; - if (MO->isKill() == NewKillState) + if (MO.isKill() == NewKillState) continue; - MO->setIsKill(NewKillState); + MO.setIsKill(NewKillState); if (NewKillState) return; } diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 2c2dc85981691..a71c6761c75f7 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -619,7 +619,7 @@ static SDValue GetNegatedExpression(SDValue Op, SelectionDAG &DAG, // fold (fneg (fsub 0, B)) -> B if (ConstantFPSDNode *N0CFP = dyn_cast(Op.getOperand(0))) - if (N0CFP->getValueAPF().isZero()) + if (N0CFP->isZero()) return Op.getOperand(1); // fold (fneg (fsub A, B)) -> (fsub B, A) @@ -1587,6 +1587,11 @@ static bool isNullConstant(SDValue V) { return Const != nullptr && Const->isNullValue(); } +static bool isNullFPConstant(SDValue V) { + ConstantFPSDNode *Const = dyn_cast(V); + return Const != nullptr && Const->isZero() && !Const->isNegative(); +} + static bool isAllOnesConstant(SDValue V) { ConstantSDNode *Const = dyn_cast(V); return Const != nullptr && Const->isAllOnesValue(); @@ -4764,7 +4769,7 @@ SDValue DAGCombiner::visitCTLZ(SDNode *N) { EVT VT = N->getValueType(0); // fold (ctlz c1) -> c2 - if (isa(N0)) + if (isConstantIntBuildVectorOrConstantInt(N0)) return DAG.getNode(ISD::CTLZ, SDLoc(N), VT, N0); return SDValue(); } @@ -4774,7 +4779,7 @@ SDValue DAGCombiner::visitCTLZ_ZERO_UNDEF(SDNode *N) { EVT VT = N->getValueType(0); // fold (ctlz_zero_undef c1) -> c2 - if (isa(N0)) + if (isConstantIntBuildVectorOrConstantInt(N0)) return DAG.getNode(ISD::CTLZ_ZERO_UNDEF, SDLoc(N), VT, N0); return SDValue(); } @@ -4784,7 +4789,7 @@ SDValue DAGCombiner::visitCTTZ(SDNode *N) { EVT VT = N->getValueType(0); // fold (cttz c1) -> c2 - if (isa(N0)) + if (isConstantIntBuildVectorOrConstantInt(N0)) return DAG.getNode(ISD::CTTZ, SDLoc(N), VT, N0); return SDValue(); } @@ -4794,7 +4799,7 @@ SDValue DAGCombiner::visitCTTZ_ZERO_UNDEF(SDNode *N) { EVT VT = N->getValueType(0); // fold (cttz_zero_undef c1) -> c2 - if (isa(N0)) + if (isConstantIntBuildVectorOrConstantInt(N0)) return DAG.getNode(ISD::CTTZ_ZERO_UNDEF, SDLoc(N), VT, N0); return SDValue(); } @@ -4804,7 +4809,7 @@ SDValue DAGCombiner::visitCTPOP(SDNode *N) { EVT VT = N->getValueType(0); // fold (ctpop c1) -> c2 - if (isa(N0)) + if (isConstantIntBuildVectorOrConstantInt(N0)) return DAG.getNode(ISD::CTPOP, SDLoc(N), VT, N0); return SDValue(); } @@ -7859,7 +7864,7 @@ SDValue DAGCombiner::visitFADD(SDNode *N) { bool AllowNewConst = (Level < AfterLegalizeDAG); // fold (fadd A, 0) -> A - if (N1CFP && N1CFP->getValueAPF().isZero()) + if (N1CFP && N1CFP->isZero()) return N0; // fold (fadd (fadd x, c1), c2) -> (fadd x, (fadd c1, c2)) @@ -7990,11 +7995,11 @@ SDValue DAGCombiner::visitFSUB(SDNode *N) { // If 'unsafe math' is enabled, fold lots of things. if (Options.UnsafeFPMath) { // (fsub A, 0) -> A - if (N1CFP && N1CFP->getValueAPF().isZero()) + if (N1CFP && N1CFP->isZero()) return N0; // (fsub 0, B) -> -B - if (N0CFP && N0CFP->getValueAPF().isZero()) { + if (N0CFP && N0CFP->isZero()) { if (isNegatibleForFree(N1, LegalOperations, TLI, &Options)) return GetNegatedExpression(N1, DAG, LegalOperations); if (!LegalOperations || TLI.isOperationLegal(ISD::FNEG, VT)) @@ -8060,7 +8065,7 @@ SDValue DAGCombiner::visitFMUL(SDNode *N) { if (Options.UnsafeFPMath) { // fold (fmul A, 0) -> 0 - if (N1CFP && N1CFP->getValueAPF().isZero()) + if (N1CFP && N1CFP->isZero()) return N1; // fold (fmul (fmul x, c1), c2) -> (fmul x, (fmul c1, c2)) @@ -8776,7 +8781,8 @@ SDValue DAGCombiner::visitFNEG(SDNode *N) { } // (fneg (fmul c, x)) -> (fmul -c, x) - if (N0.getOpcode() == ISD::FMUL) { + if (N0.getOpcode() == ISD::FMUL && + (N0.getNode()->hasOneUse() || !TLI.isFNegFree(VT))) { ConstantFPSDNode *CFP1 = dyn_cast(N0.getOperand(1)); if (CFP1) { APFloat CVal = CFP1->getValueAPF(); @@ -9061,14 +9067,18 @@ static bool canFoldInAddressingMode(SDNode *N, SDNode *Use, SelectionDAG &DAG, const TargetLowering &TLI) { EVT VT; + unsigned AS; + if (LoadSDNode *LD = dyn_cast(Use)) { if (LD->isIndexed() || LD->getBasePtr().getNode() != N) return false; VT = LD->getMemoryVT(); + AS = LD->getAddressSpace(); } else if (StoreSDNode *ST = dyn_cast(Use)) { if (ST->isIndexed() || ST->getBasePtr().getNode() != N) return false; VT = ST->getMemoryVT(); + AS = ST->getAddressSpace(); } else return false; @@ -9092,7 +9102,7 @@ static bool canFoldInAddressingMode(SDNode *N, SDNode *Use, } else return false; - return TLI.isLegalAddressingMode(AM, VT.getTypeForEVT(*DAG.getContext())); + return TLI.isLegalAddressingMode(AM, VT.getTypeForEVT(*DAG.getContext()), AS); } /// Try turning a load/store into a pre-indexed load/store when the base @@ -11908,9 +11918,7 @@ SDValue DAGCombiner::visitBUILD_VECTOR(SDNode *N) { if (Op.getOpcode() == ISD::UNDEF) continue; // See if we can combine this build_vector into a blend with a zero vector. - if (!VecIn2.getNode() && (isNullConstant(Op) || - (Op.getOpcode() == ISD::ConstantFP && - cast(Op.getNode())->getValueAPF().isZero()))) { + if (!VecIn2.getNode() && (isNullConstant(Op) || isNullFPConstant(Op))) { UsesZeroVector = true; continue; } @@ -12988,7 +12996,7 @@ SDValue DAGCombiner::SimplifyVBinOp(SDNode *N) { if (N->getOpcode() == ISD::SDIV || N->getOpcode() == ISD::UDIV || N->getOpcode() == ISD::FDIV) { if (isNullConstant(RHSOp) || (RHSOp.getOpcode() == ISD::ConstantFP && - cast(RHSOp.getNode())->getValueAPF().isZero())) + cast(RHSOp.getNode())->isZero())) break; } @@ -13252,7 +13260,7 @@ SDValue DAGCombiner::SimplifySelectCC(SDLoc DL, SDValue N0, SDValue N1, // Check to see if we can simplify the select into an fabs node if (ConstantFPSDNode *CFP = dyn_cast(N1)) { // Allow either -0.0 or 0.0 - if (CFP->getValueAPF().isZero()) { + if (CFP->isZero()) { // select (setg[te] X, +/-0.0), X, fneg(X) -> fabs if ((CC == ISD::SETGE || CC == ISD::SETGT) && N0 == N2 && N3.getOpcode() == ISD::FNEG && diff --git a/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp b/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp index 7b5b8c4eabcf2..f3d75cb32a7d1 100644 --- a/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp +++ b/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp @@ -80,33 +80,6 @@ static ISD::NodeType getPreferredExtendForValue(const Value *V) { return ExtendKind; } -namespace { -struct WinEHNumbering { - WinEHNumbering(WinEHFuncInfo &FuncInfo) : FuncInfo(FuncInfo), - CurrentBaseState(-1), NextState(0) {} - - WinEHFuncInfo &FuncInfo; - int CurrentBaseState; - int NextState; - - SmallVector, 4> HandlerStack; - SmallPtrSet VisitedHandlers; - - int currentEHNumber() const { - return HandlerStack.empty() ? CurrentBaseState : HandlerStack.back()->getEHState(); - } - - void createUnwindMapEntry(int ToState, ActionHandler *AH); - void createTryBlockMapEntry(int TryLow, int TryHigh, - ArrayRef Handlers); - void processCallSite(MutableArrayRef> Actions, - ImmutableCallSite CS); - void popUnmatchedActions(int FirstMismatch); - void calculateStateNumbers(const Function &F); - void findActionRootLPads(const Function &F); -}; -} - void FunctionLoweringInfo::set(const Function &fn, MachineFunction &mf, SelectionDAG *DAG) { Fn = &fn; @@ -291,31 +264,18 @@ void FunctionLoweringInfo::set(const Function &fn, MachineFunction &mf, if (!isMSVCEHPersonality(Personality)) return; - WinEHFuncInfo *EHInfo = nullptr; if (Personality == EHPersonality::MSVC_Win64SEH) { addSEHHandlersForLPads(LPads); } else if (Personality == EHPersonality::MSVC_CXX) { const Function *WinEHParentFn = MMI.getWinEHParent(&fn); - EHInfo = &MMI.getWinEHFuncInfo(WinEHParentFn); - if (EHInfo->LandingPadStateMap.empty()) { - WinEHNumbering Num(*EHInfo); - Num.findActionRootLPads(*WinEHParentFn); - // The VisitedHandlers list is used by both findActionRootLPads and - // calculateStateNumbers, but both functions need to visit all handlers. - Num.VisitedHandlers.clear(); - Num.calculateStateNumbers(*WinEHParentFn); - // Pop everything on the handler stack. - // It may be necessary to call this more than once because a handler can - // be pushed on the stack as a result of clearing the stack. - while (!Num.HandlerStack.empty()) - Num.processCallSite(None, ImmutableCallSite()); - } + WinEHFuncInfo &EHInfo = MMI.getWinEHFuncInfo(WinEHParentFn); + calculateWinCXXEHStateNumbers(WinEHParentFn, EHInfo); // Copy the state numbers to LandingPadInfo for the current function, which // could be a handler or the parent. for (const LandingPadInst *LP : LPads) { MachineBasicBlock *LPadMBB = MBBMap[LP->getParent()]; - MMI.addWinEHState(LPadMBB, EHInfo->LandingPadStateMap[LP]); + MMI.addWinEHState(LPadMBB, EHInfo.LandingPadStateMap[LP]); } } } @@ -358,334 +318,6 @@ void FunctionLoweringInfo::addSEHHandlersForLPads( } } -void WinEHNumbering::createUnwindMapEntry(int ToState, ActionHandler *AH) { - WinEHUnwindMapEntry UME; - UME.ToState = ToState; - if (auto *CH = dyn_cast_or_null(AH)) - UME.Cleanup = cast(CH->getHandlerBlockOrFunc()); - else - UME.Cleanup = nullptr; - FuncInfo.UnwindMap.push_back(UME); -} - -void WinEHNumbering::createTryBlockMapEntry(int TryLow, int TryHigh, - ArrayRef Handlers) { - // See if we already have an entry for this set of handlers. - // This is using iterators rather than a range-based for loop because - // if we find the entry we're looking for we'll need the iterator to erase it. - int NumHandlers = Handlers.size(); - auto I = FuncInfo.TryBlockMap.begin(); - auto E = FuncInfo.TryBlockMap.end(); - for ( ; I != E; ++I) { - auto &Entry = *I; - if (Entry.HandlerArray.size() != (size_t)NumHandlers) - continue; - int N; - for (N = 0; N < NumHandlers; ++N) { - if (Entry.HandlerArray[N].Handler != Handlers[N]->getHandlerBlockOrFunc()) - break; // breaks out of inner loop - } - // If all the handlers match, this is what we were looking for. - if (N == NumHandlers) { - break; - } - } - - // If we found an existing entry for this set of handlers, extend the range - // but move the entry to the end of the map vector. The order of entries - // in the map is critical to the way that the runtime finds handlers. - // FIXME: Depending on what has happened with block ordering, this may - // incorrectly combine entries that should remain separate. - if (I != E) { - // Copy the existing entry. - WinEHTryBlockMapEntry Entry = *I; - Entry.TryLow = std::min(TryLow, Entry.TryLow); - Entry.TryHigh = std::max(TryHigh, Entry.TryHigh); - assert(Entry.TryLow <= Entry.TryHigh); - // Erase the old entry and add this one to the back. - FuncInfo.TryBlockMap.erase(I); - FuncInfo.TryBlockMap.push_back(Entry); - return; - } - - // If we didn't find an entry, create a new one. - WinEHTryBlockMapEntry TBME; - TBME.TryLow = TryLow; - TBME.TryHigh = TryHigh; - assert(TBME.TryLow <= TBME.TryHigh); - for (CatchHandler *CH : Handlers) { - WinEHHandlerType HT; - if (CH->getSelector()->isNullValue()) { - HT.Adjectives = 0x40; - HT.TypeDescriptor = nullptr; - } else { - auto *GV = cast(CH->getSelector()->stripPointerCasts()); - // Selectors are always pointers to GlobalVariables with 'struct' type. - // The struct has two fields, adjectives and a type descriptor. - auto *CS = cast(GV->getInitializer()); - HT.Adjectives = - cast(CS->getAggregateElement(0U))->getZExtValue(); - HT.TypeDescriptor = - cast(CS->getAggregateElement(1)->stripPointerCasts()); - } - HT.Handler = cast(CH->getHandlerBlockOrFunc()); - HT.CatchObjRecoverIdx = CH->getExceptionVarIndex(); - TBME.HandlerArray.push_back(HT); - } - FuncInfo.TryBlockMap.push_back(TBME); -} - -static void print_name(const Value *V) { -#ifndef NDEBUG - if (!V) { - DEBUG(dbgs() << "null"); - return; - } - - if (const auto *F = dyn_cast(V)) - DEBUG(dbgs() << F->getName()); - else - DEBUG(V->dump()); -#endif -} - -void WinEHNumbering::processCallSite( - MutableArrayRef> Actions, - ImmutableCallSite CS) { - DEBUG(dbgs() << "processCallSite (EH state = " << currentEHNumber() - << ") for: "); - print_name(CS ? CS.getCalledValue() : nullptr); - DEBUG(dbgs() << '\n'); - - DEBUG(dbgs() << "HandlerStack: \n"); - for (int I = 0, E = HandlerStack.size(); I < E; ++I) { - DEBUG(dbgs() << " "); - print_name(HandlerStack[I]->getHandlerBlockOrFunc()); - DEBUG(dbgs() << '\n'); - } - DEBUG(dbgs() << "Actions: \n"); - for (int I = 0, E = Actions.size(); I < E; ++I) { - DEBUG(dbgs() << " "); - print_name(Actions[I]->getHandlerBlockOrFunc()); - DEBUG(dbgs() << '\n'); - } - int FirstMismatch = 0; - for (int E = std::min(HandlerStack.size(), Actions.size()); FirstMismatch < E; - ++FirstMismatch) { - if (HandlerStack[FirstMismatch]->getHandlerBlockOrFunc() != - Actions[FirstMismatch]->getHandlerBlockOrFunc()) - break; - } - - // Remove unmatched actions from the stack and process their EH states. - popUnmatchedActions(FirstMismatch); - - DEBUG(dbgs() << "Pushing actions for CallSite: "); - print_name(CS ? CS.getCalledValue() : nullptr); - DEBUG(dbgs() << '\n'); - - bool LastActionWasCatch = false; - const LandingPadInst *LastRootLPad = nullptr; - for (size_t I = FirstMismatch; I != Actions.size(); ++I) { - // We can reuse eh states when pushing two catches for the same invoke. - bool CurrActionIsCatch = isa(Actions[I].get()); - auto *Handler = cast(Actions[I]->getHandlerBlockOrFunc()); - // Various conditions can lead to a handler being popped from the - // stack and re-pushed later. That shouldn't create a new state. - // FIXME: Can code optimization lead to re-used handlers? - if (FuncInfo.HandlerEnclosedState.count(Handler)) { - // If we already assigned the state enclosed by this handler re-use it. - Actions[I]->setEHState(FuncInfo.HandlerEnclosedState[Handler]); - continue; - } - const LandingPadInst* RootLPad = FuncInfo.RootLPad[Handler]; - if (CurrActionIsCatch && LastActionWasCatch && RootLPad == LastRootLPad) { - DEBUG(dbgs() << "setEHState for handler to " << currentEHNumber() << "\n"); - Actions[I]->setEHState(currentEHNumber()); - } else { - DEBUG(dbgs() << "createUnwindMapEntry(" << currentEHNumber() << ", "); - print_name(Actions[I]->getHandlerBlockOrFunc()); - DEBUG(dbgs() << ") with EH state " << NextState << "\n"); - createUnwindMapEntry(currentEHNumber(), Actions[I].get()); - DEBUG(dbgs() << "setEHState for handler to " << NextState << "\n"); - Actions[I]->setEHState(NextState); - NextState++; - } - HandlerStack.push_back(std::move(Actions[I])); - LastActionWasCatch = CurrActionIsCatch; - LastRootLPad = RootLPad; - } - - // This is used to defer numbering states for a handler until after the - // last time it appears in an invoke action list. - if (CS.isInvoke()) { - for (int I = 0, E = HandlerStack.size(); I < E; ++I) { - auto *Handler = cast(HandlerStack[I]->getHandlerBlockOrFunc()); - if (FuncInfo.LastInvoke[Handler] != cast(CS.getInstruction())) - continue; - FuncInfo.LastInvokeVisited[Handler] = true; - DEBUG(dbgs() << "Last invoke of "); - print_name(Handler); - DEBUG(dbgs() << " has been visited.\n"); - } - } - - DEBUG(dbgs() << "In EHState " << currentEHNumber() << " for CallSite: "); - print_name(CS ? CS.getCalledValue() : nullptr); - DEBUG(dbgs() << '\n'); -} - -void WinEHNumbering::popUnmatchedActions(int FirstMismatch) { - // Don't recurse while we are looping over the handler stack. Instead, defer - // the numbering of the catch handlers until we are done popping. - SmallVector PoppedCatches; - for (int I = HandlerStack.size() - 1; I >= FirstMismatch; --I) { - std::unique_ptr Handler = HandlerStack.pop_back_val(); - if (isa(Handler.get())) - PoppedCatches.push_back(cast(Handler.release())); - } - - int TryHigh = NextState - 1; - int LastTryLowIdx = 0; - for (int I = 0, E = PoppedCatches.size(); I != E; ++I) { - CatchHandler *CH = PoppedCatches[I]; - DEBUG(dbgs() << "Popped handler with state " << CH->getEHState() << "\n"); - if (I + 1 == E || CH->getEHState() != PoppedCatches[I + 1]->getEHState()) { - int TryLow = CH->getEHState(); - auto Handlers = - makeArrayRef(&PoppedCatches[LastTryLowIdx], I - LastTryLowIdx + 1); - DEBUG(dbgs() << "createTryBlockMapEntry(" << TryLow << ", " << TryHigh); - for (size_t J = 0; J < Handlers.size(); ++J) { - DEBUG(dbgs() << ", "); - print_name(Handlers[J]->getHandlerBlockOrFunc()); - } - DEBUG(dbgs() << ")\n"); - createTryBlockMapEntry(TryLow, TryHigh, Handlers); - LastTryLowIdx = I + 1; - } - } - - for (CatchHandler *CH : PoppedCatches) { - if (auto *F = dyn_cast(CH->getHandlerBlockOrFunc())) { - if (FuncInfo.LastInvokeVisited[F]) { - DEBUG(dbgs() << "Assigning base state " << NextState << " to "); - print_name(F); - DEBUG(dbgs() << '\n'); - FuncInfo.HandlerBaseState[F] = NextState; - DEBUG(dbgs() << "createUnwindMapEntry(" << currentEHNumber() - << ", null)\n"); - createUnwindMapEntry(currentEHNumber(), nullptr); - ++NextState; - calculateStateNumbers(*F); - } - else { - DEBUG(dbgs() << "Deferring handling of "); - print_name(F); - DEBUG(dbgs() << " until last invoke visited.\n"); - } - } - delete CH; - } -} - -void WinEHNumbering::calculateStateNumbers(const Function &F) { - auto I = VisitedHandlers.insert(&F); - if (!I.second) - return; // We've already visited this handler, don't renumber it. - - int OldBaseState = CurrentBaseState; - if (FuncInfo.HandlerBaseState.count(&F)) { - CurrentBaseState = FuncInfo.HandlerBaseState[&F]; - } - - size_t SavedHandlerStackSize = HandlerStack.size(); - - DEBUG(dbgs() << "Calculating state numbers for: " << F.getName() << '\n'); - SmallVector, 4> ActionList; - for (const BasicBlock &BB : F) { - for (const Instruction &I : BB) { - const auto *CI = dyn_cast(&I); - if (!CI || CI->doesNotThrow()) - continue; - processCallSite(None, CI); - } - const auto *II = dyn_cast(BB.getTerminator()); - if (!II) - continue; - const LandingPadInst *LPI = II->getLandingPadInst(); - auto *ActionsCall = dyn_cast(LPI->getNextNode()); - if (!ActionsCall) - continue; - assert(ActionsCall->getIntrinsicID() == Intrinsic::eh_actions); - parseEHActions(ActionsCall, ActionList); - if (ActionList.empty()) - continue; - processCallSite(ActionList, II); - ActionList.clear(); - FuncInfo.LandingPadStateMap[LPI] = currentEHNumber(); - DEBUG(dbgs() << "Assigning state " << currentEHNumber() - << " to landing pad at " << LPI->getParent()->getName() - << '\n'); - } - - // Pop any actions that were pushed on the stack for this function. - popUnmatchedActions(SavedHandlerStackSize); - - DEBUG(dbgs() << "Assigning max state " << NextState - 1 - << " to " << F.getName() << '\n'); - FuncInfo.CatchHandlerMaxState[&F] = NextState - 1; - - CurrentBaseState = OldBaseState; -} - -// This function follows the same basic traversal as calculateStateNumbers -// but it is necessary to identify the root landing pad associated -// with each action before we start assigning state numbers. -void WinEHNumbering::findActionRootLPads(const Function &F) { - auto I = VisitedHandlers.insert(&F); - if (!I.second) - return; // We've already visited this handler, don't revisit it. - - SmallVector, 4> ActionList; - for (const BasicBlock &BB : F) { - const auto *II = dyn_cast(BB.getTerminator()); - if (!II) - continue; - const LandingPadInst *LPI = II->getLandingPadInst(); - auto *ActionsCall = dyn_cast(LPI->getNextNode()); - if (!ActionsCall) - continue; - - assert(ActionsCall->getIntrinsicID() == Intrinsic::eh_actions); - parseEHActions(ActionsCall, ActionList); - if (ActionList.empty()) - continue; - for (int I = 0, E = ActionList.size(); I < E; ++I) { - if (auto *Handler - = dyn_cast(ActionList[I]->getHandlerBlockOrFunc())) { - FuncInfo.LastInvoke[Handler] = II; - // Don't replace the root landing pad if we previously saw this - // handler in a different function. - if (FuncInfo.RootLPad.count(Handler) && - FuncInfo.RootLPad[Handler]->getParent()->getParent() != &F) - continue; - DEBUG(dbgs() << "Setting root lpad for "); - print_name(Handler); - DEBUG(dbgs() << " to " << LPI->getParent()->getName() << '\n'); - FuncInfo.RootLPad[Handler] = LPI; - } - } - // Walk the actions again and look for nested handlers. This has to - // happen after all of the actions have been processed in the current - // function. - for (int I = 0, E = ActionList.size(); I < E; ++I) - if (auto *Handler - = dyn_cast(ActionList[I]->getHandlerBlockOrFunc())) - findActionRootLPads(*Handler); - ActionList.clear(); - } -} - /// clear - Clear out all the function-specific state. This returns this /// FunctionLoweringInfo to an empty state, ready to be used for a /// different function. diff --git a/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp index eeaebf780cc34..96e2ff89013a5 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp @@ -602,10 +602,13 @@ SDValue DAGTypeLegalizer::PromoteIntRes_SETCC(SDNode *N) { } SDValue DAGTypeLegalizer::PromoteIntRes_SHL(SDNode *N) { - SDValue Res = GetPromotedInteger(N->getOperand(0)); - SDValue Amt = N->getOperand(1); - Amt = Amt.getValueType().isVector() ? ZExtPromotedInteger(Amt) : Amt; - return DAG.getNode(ISD::SHL, SDLoc(N), Res.getValueType(), Res, Amt); + SDValue LHS = N->getOperand(0); + SDValue RHS = N->getOperand(1); + if (getTypeAction(LHS.getValueType()) == TargetLowering::TypePromoteInteger) + LHS = GetPromotedInteger(LHS); + if (getTypeAction(RHS.getValueType()) == TargetLowering::TypePromoteInteger) + RHS = ZExtPromotedInteger(RHS); + return DAG.getNode(ISD::SHL, SDLoc(N), LHS.getValueType(), LHS, RHS); } SDValue DAGTypeLegalizer::PromoteIntRes_SIGN_EXTEND_INREG(SDNode *N) { @@ -625,19 +628,25 @@ SDValue DAGTypeLegalizer::PromoteIntRes_SimpleIntBinOp(SDNode *N) { } SDValue DAGTypeLegalizer::PromoteIntRes_SRA(SDNode *N) { + SDValue LHS = N->getOperand(0); + SDValue RHS = N->getOperand(1); // The input value must be properly sign extended. - SDValue Res = SExtPromotedInteger(N->getOperand(0)); - SDValue Amt = N->getOperand(1); - Amt = Amt.getValueType().isVector() ? ZExtPromotedInteger(Amt) : Amt; - return DAG.getNode(ISD::SRA, SDLoc(N), Res.getValueType(), Res, Amt); + if (getTypeAction(LHS.getValueType()) == TargetLowering::TypePromoteInteger) + LHS = SExtPromotedInteger(LHS); + if (getTypeAction(RHS.getValueType()) == TargetLowering::TypePromoteInteger) + RHS = ZExtPromotedInteger(RHS); + return DAG.getNode(ISD::SRA, SDLoc(N), LHS.getValueType(), LHS, RHS); } SDValue DAGTypeLegalizer::PromoteIntRes_SRL(SDNode *N) { + SDValue LHS = N->getOperand(0); + SDValue RHS = N->getOperand(1); // The input value must be properly zero extended. - SDValue Res = ZExtPromotedInteger(N->getOperand(0)); - SDValue Amt = N->getOperand(1); - Amt = Amt.getValueType().isVector() ? ZExtPromotedInteger(Amt) : Amt; - return DAG.getNode(ISD::SRL, SDLoc(N), Res.getValueType(), Res, Amt); + if (getTypeAction(LHS.getValueType()) == TargetLowering::TypePromoteInteger) + LHS = ZExtPromotedInteger(LHS); + if (getTypeAction(RHS.getValueType()) == TargetLowering::TypePromoteInteger) + RHS = ZExtPromotedInteger(RHS); + return DAG.getNode(ISD::SRL, SDLoc(N), LHS.getValueType(), LHS, RHS); } SDValue DAGTypeLegalizer::PromoteIntRes_TRUNCATE(SDNode *N) { diff --git a/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp b/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp index 3853ada5fb0bc..f4c7b59348294 100644 --- a/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp +++ b/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp @@ -71,7 +71,7 @@ SUnit *ScheduleDAGSDNodes::newSUnit(SDNode *N) { if (!SUnits.empty()) Addr = &SUnits[0]; #endif - SUnits.push_back(SUnit(N, (unsigned)SUnits.size())); + SUnits.emplace_back(N, (unsigned)SUnits.size()); assert((Addr == nullptr || Addr == &SUnits[0]) && "SUnits std::vector reallocated on the fly!"); SUnits.back().OrigNode = &SUnits.back(); diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index efd4bd9a4d893..cf51e756d847d 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -1810,6 +1810,13 @@ SDValue SelectionDAG::getMDNode(const MDNode *MD) { return SDValue(N, 0); } +SDValue SelectionDAG::getBitcast(EVT VT, SDValue V) { + if (VT == V.getValueType()) + return V; + + return getNode(ISD::BITCAST, SDLoc(V), VT, V); +} + /// getAddrSpaceCast - Return an AddrSpaceCastSDNode. SDValue SelectionDAG::getAddrSpaceCast(SDLoc dl, EVT VT, SDValue Ptr, unsigned SrcAS, unsigned DestAS) { @@ -2425,6 +2432,19 @@ void SelectionDAG::computeKnownBits(SDValue Op, APInt &KnownZero, KnownOne = KnownOne.trunc(BitWidth); break; } + case ISD::SMIN: + case ISD::SMAX: + case ISD::UMIN: + case ISD::UMAX: { + APInt Op0Zero, Op0One; + APInt Op1Zero, Op1One; + computeKnownBits(Op.getOperand(0), Op0Zero, Op0One, Depth); + computeKnownBits(Op.getOperand(1), Op1Zero, Op1One, Depth); + + KnownZero = Op0Zero & Op1Zero; + KnownOne = Op0One & Op1One; + break; + } case ISD::FrameIndex: case ISD::TargetFrameIndex: if (unsigned Align = InferPtrAlignment(Op)) { @@ -2528,7 +2548,15 @@ unsigned SelectionDAG::ComputeNumSignBits(SDValue Op, unsigned Depth) const{ if (Tmp == 1) return 1; // Early out. Tmp2 = ComputeNumSignBits(Op.getOperand(2), Depth+1); return std::min(Tmp, Tmp2); - + case ISD::SMIN: + case ISD::SMAX: + case ISD::UMIN: + case ISD::UMAX: + Tmp = ComputeNumSignBits(Op.getOperand(0), Depth + 1); + if (Tmp == 1) + return 1; // Early out. + Tmp2 = ComputeNumSignBits(Op.getOperand(1), Depth + 1); + return std::min(Tmp, Tmp2); case ISD::SADDO: case ISD::UADDO: case ISD::SSUBO: @@ -2903,7 +2931,12 @@ SDValue SelectionDAG::getNode(unsigned Opcode, SDLoc DL, case ISD::FP_TO_UINT: case ISD::TRUNCATE: case ISD::UINT_TO_FP: - case ISD::SINT_TO_FP: { + case ISD::SINT_TO_FP: + case ISD::CTLZ: + case ISD::CTLZ_ZERO_UNDEF: + case ISD::CTTZ: + case ISD::CTTZ_ZERO_UNDEF: + case ISD::CTPOP: { EVT SVT = VT.getScalarType(); EVT InVT = BV->getValueType(0); EVT InSVT = InVT.getScalarType(); diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index 85303d27dcf8f..8ba957d628708 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -1002,7 +1002,16 @@ bool SelectionDAGBuilder::findValue(const Value *V) const { SDValue SelectionDAGBuilder::getNonRegisterValue(const Value *V) { // If we already have an SDValue for this value, use it. SDValue &N = NodeMap[V]; - if (N.getNode()) return N; + if (N.getNode()) { + if (isa(N) || isa(N)) { + // Remove the debug location from the node as the node is about to be used + // in a location which may differ from the original debug location. This + // is relevant to Constant and ConstantFP nodes because they can appear + // as constant expressions inside PHI nodes. + N->setDebugLoc(DebugLoc()); + } + return N; + } // Otherwise create a new SDValue and remember it. SDValue Val = getValueImpl(V); @@ -2282,7 +2291,11 @@ void SelectionDAGBuilder::visitSelect(const User &I) { while (TLI.getTypeAction(Ctx, VT) == TargetLoweringBase::TypeSplitVector) VT = TLI.getTypeToTransformTo(Ctx, VT); - if (Opc != ISD::DELETED_NODE && TLI.isOperationLegalOrCustom(Opc, VT)) { + if (Opc != ISD::DELETED_NODE && TLI.isOperationLegalOrCustom(Opc, VT) && + // If the underlying comparison instruction is used by any other instruction, + // the consumed instructions won't be destroyed, so it is not profitable + // to convert to a min/max. + cast(&I)->getCondition()->hasOneUse()) { OpCode = Opc; LHSVal = getValue(LHS); RHSVal = getValue(RHS); @@ -2848,7 +2861,17 @@ void SelectionDAGBuilder::visitLoad(const LoadInst &I) { bool isVolatile = I.isVolatile(); bool isNonTemporal = I.getMetadata(LLVMContext::MD_nontemporal) != nullptr; - bool isInvariant = I.getMetadata(LLVMContext::MD_invariant_load) != nullptr; + + // The IR notion of invariant_load only guarantees that all *non-faulting* + // invariant loads result in the same value. The MI notion of invariant load + // guarantees that the load can be legally moved to any location within its + // containing function. The MI notion of invariant_load is stronger than the + // IR notion of invariant_load -- an MI invariant_load is an IR invariant_load + // with a guarantee that the location being loaded from is dereferenceable + // throughout the function's lifetime. + + bool isInvariant = I.getMetadata(LLVMContext::MD_invariant_load) != nullptr && + isDereferenceablePointer(SV, *DAG.getTarget().getDataLayout()); unsigned Alignment = I.getAlignment(); AAMDNodes AAInfo; @@ -7437,7 +7460,7 @@ bool SelectionDAGBuilder::buildJumpTable(CaseClusterVector &Clusters, JumpTableHeader JTH(Clusters[First].Low->getValue(), Clusters[Last].High->getValue(), SI->getCondition(), nullptr, false); - JTCases.push_back(JumpTableBlock(JTH, JT)); + JTCases.emplace_back(std::move(JTH), std::move(JT)); JTCluster = CaseCluster::jumpTable(Clusters[First].Low, Clusters[Last].High, JTCases.size() - 1, Weight); @@ -7600,7 +7623,7 @@ bool SelectionDAGBuilder::buildBitTests(CaseClusterVector &Clusters, const int BitWidth = DAG.getTargetLoweringInfo().getPointerTy().getSizeInBits(); - assert((High - Low + 1).sle(BitWidth) && "Case range must fit in bit mask!"); + assert(rangeFitsInWord(Low, High) && "Case range must fit in bit mask!"); if (Low.isNonNegative() && High.slt(BitWidth)) { // Optimize the case where all the case values fit in a @@ -7628,10 +7651,9 @@ bool SelectionDAGBuilder::buildBitTests(CaseClusterVector &Clusters, // Update Mask, Bits and ExtraWeight. uint64_t Lo = (Clusters[i].Low->getValue() - LowBound).getZExtValue(); uint64_t Hi = (Clusters[i].High->getValue() - LowBound).getZExtValue(); - for (uint64_t j = Lo; j <= Hi; ++j) { - CB->Mask |= 1ULL << j; - CB->Bits++; - } + assert(Hi >= Lo && Hi < 64 && "Invalid bit case!"); + CB->Mask |= (-1ULL >> (63 - (Hi - Lo))) << Lo; + CB->Bits += Hi - Lo + 1; CB->ExtraWeight += Clusters[i].Weight; TotalWeight += Clusters[i].Weight; assert(TotalWeight >= Clusters[i].Weight && "Weight overflow!"); @@ -7650,9 +7672,9 @@ bool SelectionDAGBuilder::buildBitTests(CaseClusterVector &Clusters, FuncInfo.MF->CreateMachineBasicBlock(SI->getParent()); BTI.push_back(BitTestCase(CB.Mask, BitTestBB, CB.BB, CB.ExtraWeight)); } - BitTestCases.push_back(BitTestBlock(LowBound, CmpRange, SI->getCondition(), - -1U, MVT::Other, false, nullptr, - nullptr, std::move(BTI))); + BitTestCases.emplace_back(std::move(LowBound), std::move(CmpRange), + SI->getCondition(), -1U, MVT::Other, false, nullptr, + nullptr, std::move(BTI)); BTCluster = CaseCluster::bitTests(Clusters[First].Low, Clusters[Last].High, BitTestCases.size() - 1, TotalWeight); @@ -7746,8 +7768,10 @@ void SelectionDAGBuilder::findBitTestClusters(CaseClusterVector &Clusters, if (buildBitTests(Clusters, First, Last, SI, BitTestCluster)) { Clusters[DstIndex++] = BitTestCluster; } else { - for (unsigned I = First; I <= Last; ++I) - std::memmove(&Clusters[DstIndex++], &Clusters[I], sizeof(Clusters[I])); + size_t NumClusters = Last - First + 1; + std::memmove(&Clusters[DstIndex], &Clusters[First], + sizeof(Clusters[0]) * NumClusters); + DstIndex += NumClusters; } } Clusters.resize(DstIndex); @@ -7783,22 +7807,17 @@ void SelectionDAGBuilder::lowerWorkItem(SwitchWorkListItem W, Value *Cond, const APInt &BigValue = Big.Low->getValue(); // Check that there is only one bit different. - if (BigValue.countPopulation() == SmallValue.countPopulation() + 1 && - (SmallValue | BigValue) == BigValue) { - // Isolate the common bit. - APInt CommonBit = BigValue & ~SmallValue; - assert((SmallValue | CommonBit) == BigValue && - CommonBit.countPopulation() == 1 && "Not a common bit?"); - + APInt CommonBit = BigValue ^ SmallValue; + if (CommonBit.isPowerOf2()) { SDValue CondLHS = getValue(Cond); EVT VT = CondLHS.getValueType(); SDLoc DL = getCurSDLoc(); SDValue Or = DAG.getNode(ISD::OR, DL, VT, CondLHS, DAG.getConstant(CommonBit, DL, VT)); - SDValue Cond = DAG.getSetCC(DL, MVT::i1, Or, - DAG.getConstant(BigValue, DL, VT), - ISD::SETEQ); + SDValue Cond = DAG.getSetCC( + DL, MVT::i1, Or, DAG.getConstant(BigValue | SmallValue, DL, VT), + ISD::SETEQ); // Update successor info. // Both Small and Big will jump to Small.BB, so we sum up the weights. diff --git a/lib/CodeGen/SelectionDAG/StatepointLowering.cpp b/lib/CodeGen/SelectionDAG/StatepointLowering.cpp index 2d4ab6c5077a2..8bbfa01e7594c 100644 --- a/lib/CodeGen/SelectionDAG/StatepointLowering.cpp +++ b/lib/CodeGen/SelectionDAG/StatepointLowering.cpp @@ -238,17 +238,6 @@ lowerCallFromStatepoint(ImmutableStatepoint ISP, MachineBasicBlock *LandingPad, SDValue ActualCallee = Builder.getValue(ISP.getActualCallee()); - // Handle immediate and symbolic callees. - if (auto *ConstCallee = dyn_cast(ActualCallee.getNode())) - ActualCallee = Builder.DAG.getIntPtrConstant(ConstCallee->getZExtValue(), - Builder.getCurSDLoc(), - /*isTarget=*/true); - else if (auto *SymbolicCallee = - dyn_cast(ActualCallee.getNode())) - ActualCallee = Builder.DAG.getTargetGlobalAddress( - SymbolicCallee->getGlobal(), SDLoc(SymbolicCallee), - SymbolicCallee->getValueType(0)); - assert(CS.getCallingConv() != CallingConv::AnyReg && "anyregcc is not supported on statepoints!"); diff --git a/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/lib/CodeGen/SelectionDAG/TargetLowering.cpp index 833da4b6d59ce..9daf2a50ad8fb 100644 --- a/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -254,7 +254,7 @@ const MCExpr * TargetLowering::getPICJumpTableRelocBaseExpr(const MachineFunction *MF, unsigned JTI,MCContext &Ctx) const{ // The normal PIC reloc base is the label at the start of the jump table. - return MCSymbolRefExpr::Create(MF->getJTISymbol(JTI, Ctx), Ctx); + return MCSymbolRefExpr::create(MF->getJTISymbol(JTI, Ctx), Ctx); } bool diff --git a/lib/CodeGen/StackMaps.cpp b/lib/CodeGen/StackMaps.cpp index ffe59c19d3e0f..1e8e03f9a7df3 100644 --- a/lib/CodeGen/StackMaps.cpp +++ b/lib/CodeGen/StackMaps.cpp @@ -315,9 +315,9 @@ void StackMaps::recordStackMapOpers(const MachineInstr &MI, uint64_t ID, // Create an expression to calculate the offset of the callsite from function // entry. - const MCExpr *CSOffsetExpr = MCBinaryExpr::CreateSub( - MCSymbolRefExpr::Create(MILabel, OutContext), - MCSymbolRefExpr::Create(AP.CurrentFnSymForSize, OutContext), + const MCExpr *CSOffsetExpr = MCBinaryExpr::createSub( + MCSymbolRefExpr::create(MILabel, OutContext), + MCSymbolRefExpr::create(AP.CurrentFnSymForSize, OutContext), OutContext); CSInfos.emplace_back(CSOffsetExpr, ID, std::move(Locations), diff --git a/lib/CodeGen/TargetInstrInfo.cpp b/lib/CodeGen/TargetInstrInfo.cpp index 92488defc793d..c809087d3da4d 100644 --- a/lib/CodeGen/TargetInstrInfo.cpp +++ b/lib/CodeGen/TargetInstrInfo.cpp @@ -471,11 +471,13 @@ MachineInstr *TargetInstrInfo::foldMemoryOperand(MachineBasicBlock::iterator MI, MI->getOpcode() == TargetOpcode::PATCHPOINT) { // Fold stackmap/patchpoint. NewMI = foldPatchpoint(MF, MI, Ops, FI, *this); + if (NewMI) + MBB->insert(MI, NewMI); } else { // Ask the target to do the actual folding. - NewMI =foldMemoryOperandImpl(MF, MI, Ops, FI); + NewMI = foldMemoryOperandImpl(MF, MI, Ops, MI, FI); } - + if (NewMI) { NewMI->setMemRefs(MI->memoperands_begin(), MI->memoperands_end()); // Add a memory operand, foldMemoryOperandImpl doesn't do that. @@ -493,8 +495,7 @@ MachineInstr *TargetInstrInfo::foldMemoryOperand(MachineBasicBlock::iterator MI, MFI.getObjectAlignment(FI)); NewMI->addMemOperand(MF, MMO); - // FIXME: change foldMemoryOperandImpl semantics to also insert NewMI. - return MBB->insert(MI, NewMI); + return NewMI; } // Straight COPY may fold as load/store. @@ -539,15 +540,15 @@ MachineInstr *TargetInstrInfo::foldMemoryOperand(MachineBasicBlock::iterator MI, isLoadFromStackSlot(LoadMI, FrameIndex)) { // Fold stackmap/patchpoint. NewMI = foldPatchpoint(MF, MI, Ops, FrameIndex, *this); + if (NewMI) + NewMI = MBB.insert(MI, NewMI); } else { // Ask the target to do the actual folding. - NewMI = foldMemoryOperandImpl(MF, MI, Ops, LoadMI); + NewMI = foldMemoryOperandImpl(MF, MI, Ops, MI, LoadMI); } if (!NewMI) return nullptr; - NewMI = MBB.insert(MI, NewMI); - // Copy the memoperands from the load to the folded instruction. if (MI->memoperands_empty()) { NewMI->setMemRefs(LoadMI->memoperands_begin(), diff --git a/lib/CodeGen/TargetLoweringBase.cpp b/lib/CodeGen/TargetLoweringBase.cpp index b7f1db6529f70..1bc89aa2271d4 100644 --- a/lib/CodeGen/TargetLoweringBase.cpp +++ b/lib/CodeGen/TargetLoweringBase.cpp @@ -1632,7 +1632,8 @@ TargetLoweringBase::getTypeLegalizationCost(Type *Ty) const { /// isLegalAddressingMode - Return true if the addressing mode represented /// by AM is legal for this target, for a load/store of the specified type. bool TargetLoweringBase::isLegalAddressingMode(const AddrMode &AM, - Type *Ty) const { + Type *Ty, + unsigned AS) const { // The default implementation of this implements a conservative RISCy, r+r and // r+i addr mode. diff --git a/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/lib/CodeGen/TargetLoweringObjectFileImpl.cpp index a32bdf8955cec..d7b043dac0132 100644 --- a/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ b/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -30,7 +30,7 @@ #include "llvm/MC/MCSectionELF.h" #include "llvm/MC/MCSectionMachO.h" #include "llvm/MC/MCStreamer.h" -#include "llvm/MC/MCSymbol.h" +#include "llvm/MC/MCSymbolELF.h" #include "llvm/MC/MCValue.h" #include "llvm/Support/Dwarf.h" #include "llvm/Support/ELF.h" @@ -63,7 +63,8 @@ void TargetLoweringObjectFileELF::emitPersonalityValue(MCStreamer &Streamer, const MCSymbol *Sym) const { SmallString<64> NameData("DW.ref."); NameData += Sym->getName(); - MCSymbol *Label = getContext().getOrCreateSymbol(NameData); + MCSymbolELF *Label = + cast(getContext().getOrCreateSymbol(NameData)); Streamer.EmitSymbolAttribute(Label, MCSA_Hidden); Streamer.EmitSymbolAttribute(Label, MCSA_Weak); StringRef Prefix = ".data."; @@ -75,8 +76,8 @@ void TargetLoweringObjectFileELF::emitPersonalityValue(MCStreamer &Streamer, Streamer.SwitchSection(Sec); Streamer.EmitValueToAlignment(TM.getDataLayout()->getPointerABIAlignment()); Streamer.EmitSymbolAttribute(Label, MCSA_ELF_TypeObject); - const MCExpr *E = MCConstantExpr::Create(Size, getContext()); - Streamer.EmitELFSize(Label, E); + const MCExpr *E = MCConstantExpr::create(Size, getContext()); + Streamer.emitELFSize(Label, E); Streamer.EmitLabel(Label); Streamer.EmitSymbolValue(Sym, Size); @@ -101,7 +102,7 @@ const MCExpr *TargetLoweringObjectFileELF::getTTypeGlobalReference( } return TargetLoweringObjectFile:: - getTTypeReference(MCSymbolRefExpr::Create(SSym, getContext()), + getTTypeReference(MCSymbolRefExpr::create(SSym, getContext()), Encoding & ~dwarf::DW_EH_PE_indirect, Streamer); } @@ -684,7 +685,7 @@ const MCExpr *TargetLoweringObjectFileMachO::getTTypeGlobalReference( } return TargetLoweringObjectFile:: - getTTypeReference(MCSymbolRefExpr::Create(SSym, getContext()), + getTTypeReference(MCSymbolRefExpr::create(SSym, getContext()), Encoding & ~dwarf::DW_EH_PE_indirect, Streamer); } @@ -760,16 +761,16 @@ const MCExpr *TargetLoweringObjectFileMachO::getIndirectSymViaGOTPCRel( StubValueTy(const_cast(Sym), true /* access indirectly */); const MCExpr *BSymExpr = - MCSymbolRefExpr::Create(BaseSym, MCSymbolRefExpr::VK_None, Ctx); + MCSymbolRefExpr::create(BaseSym, MCSymbolRefExpr::VK_None, Ctx); const MCExpr *LHS = - MCSymbolRefExpr::Create(Stub, MCSymbolRefExpr::VK_None, Ctx); + MCSymbolRefExpr::create(Stub, MCSymbolRefExpr::VK_None, Ctx); if (!Offset) - return MCBinaryExpr::CreateSub(LHS, BSymExpr, Ctx); + return MCBinaryExpr::createSub(LHS, BSymExpr, Ctx); const MCExpr *RHS = - MCBinaryExpr::CreateAdd(BSymExpr, MCConstantExpr::Create(Offset, Ctx), Ctx); - return MCBinaryExpr::CreateSub(LHS, RHS, Ctx); + MCBinaryExpr::createAdd(BSymExpr, MCConstantExpr::create(Offset, Ctx), Ctx); + return MCBinaryExpr::createSub(LHS, RHS, Ctx); } //===----------------------------------------------------------------------===// diff --git a/lib/CodeGen/VirtRegMap.cpp b/lib/CodeGen/VirtRegMap.cpp index 9fb1b5b65fbb9..32d5100f84959 100644 --- a/lib/CodeGen/VirtRegMap.cpp +++ b/lib/CodeGen/VirtRegMap.cpp @@ -417,17 +417,11 @@ void VirtRegRewriter::rewrite() { // Finally, remove any identity copies. if (MI->isIdentityCopy()) { ++NumIdCopies; - if (MI->getNumOperands() == 2) { - DEBUG(dbgs() << "Deleting identity copy.\n"); - if (Indexes) - Indexes->removeMachineInstrFromMaps(MI); - // It's safe to erase MI because MII has already been incremented. - MI->eraseFromParent(); - } else { - // Transform identity copy to a KILL to deal with subregisters. - MI->setDesc(TII->get(TargetOpcode::KILL)); - DEBUG(dbgs() << "Identity copy: " << *MI); - } + DEBUG(dbgs() << "Deleting identity copy.\n"); + if (Indexes) + Indexes->removeMachineInstrFromMaps(MI); + // It's safe to erase MI because MII has already been incremented. + MI->eraseFromParent(); } } } diff --git a/lib/CodeGen/WinEHPrepare.cpp b/lib/CodeGen/WinEHPrepare.cpp index 7246e1cf3ea59..c2b3d84ca363a 100644 --- a/lib/CodeGen/WinEHPrepare.cpp +++ b/lib/CodeGen/WinEHPrepare.cpp @@ -2480,3 +2480,377 @@ void llvm::parseEHActions( } std::reverse(Actions.begin(), Actions.end()); } + +namespace { +struct WinEHNumbering { + WinEHNumbering(WinEHFuncInfo &FuncInfo) : FuncInfo(FuncInfo), + CurrentBaseState(-1), NextState(0) {} + + WinEHFuncInfo &FuncInfo; + int CurrentBaseState; + int NextState; + + SmallVector, 4> HandlerStack; + SmallPtrSet VisitedHandlers; + + int currentEHNumber() const { + return HandlerStack.empty() ? CurrentBaseState : HandlerStack.back()->getEHState(); + } + + void createUnwindMapEntry(int ToState, ActionHandler *AH); + void createTryBlockMapEntry(int TryLow, int TryHigh, + ArrayRef Handlers); + void processCallSite(MutableArrayRef> Actions, + ImmutableCallSite CS); + void popUnmatchedActions(int FirstMismatch); + void calculateStateNumbers(const Function &F); + void findActionRootLPads(const Function &F); +}; +} + +void WinEHNumbering::createUnwindMapEntry(int ToState, ActionHandler *AH) { + WinEHUnwindMapEntry UME; + UME.ToState = ToState; + if (auto *CH = dyn_cast_or_null(AH)) + UME.Cleanup = cast(CH->getHandlerBlockOrFunc()); + else + UME.Cleanup = nullptr; + FuncInfo.UnwindMap.push_back(UME); +} + +void WinEHNumbering::createTryBlockMapEntry(int TryLow, int TryHigh, + ArrayRef Handlers) { + // See if we already have an entry for this set of handlers. + // This is using iterators rather than a range-based for loop because + // if we find the entry we're looking for we'll need the iterator to erase it. + int NumHandlers = Handlers.size(); + auto I = FuncInfo.TryBlockMap.begin(); + auto E = FuncInfo.TryBlockMap.end(); + for ( ; I != E; ++I) { + auto &Entry = *I; + if (Entry.HandlerArray.size() != (size_t)NumHandlers) + continue; + int N; + for (N = 0; N < NumHandlers; ++N) { + if (Entry.HandlerArray[N].Handler != Handlers[N]->getHandlerBlockOrFunc()) + break; // breaks out of inner loop + } + // If all the handlers match, this is what we were looking for. + if (N == NumHandlers) { + break; + } + } + + // If we found an existing entry for this set of handlers, extend the range + // but move the entry to the end of the map vector. The order of entries + // in the map is critical to the way that the runtime finds handlers. + // FIXME: Depending on what has happened with block ordering, this may + // incorrectly combine entries that should remain separate. + if (I != E) { + // Copy the existing entry. + WinEHTryBlockMapEntry Entry = *I; + Entry.TryLow = std::min(TryLow, Entry.TryLow); + Entry.TryHigh = std::max(TryHigh, Entry.TryHigh); + assert(Entry.TryLow <= Entry.TryHigh); + // Erase the old entry and add this one to the back. + FuncInfo.TryBlockMap.erase(I); + FuncInfo.TryBlockMap.push_back(Entry); + return; + } + + // If we didn't find an entry, create a new one. + WinEHTryBlockMapEntry TBME; + TBME.TryLow = TryLow; + TBME.TryHigh = TryHigh; + assert(TBME.TryLow <= TBME.TryHigh); + for (CatchHandler *CH : Handlers) { + WinEHHandlerType HT; + if (CH->getSelector()->isNullValue()) { + HT.Adjectives = 0x40; + HT.TypeDescriptor = nullptr; + } else { + auto *GV = cast(CH->getSelector()->stripPointerCasts()); + // Selectors are always pointers to GlobalVariables with 'struct' type. + // The struct has two fields, adjectives and a type descriptor. + auto *CS = cast(GV->getInitializer()); + HT.Adjectives = + cast(CS->getAggregateElement(0U))->getZExtValue(); + HT.TypeDescriptor = + cast(CS->getAggregateElement(1)->stripPointerCasts()); + } + HT.Handler = cast(CH->getHandlerBlockOrFunc()); + HT.CatchObjRecoverIdx = CH->getExceptionVarIndex(); + TBME.HandlerArray.push_back(HT); + } + FuncInfo.TryBlockMap.push_back(TBME); +} + +static void print_name(const Value *V) { +#ifndef NDEBUG + if (!V) { + DEBUG(dbgs() << "null"); + return; + } + + if (const auto *F = dyn_cast(V)) + DEBUG(dbgs() << F->getName()); + else + DEBUG(V->dump()); +#endif +} + +void WinEHNumbering::processCallSite( + MutableArrayRef> Actions, + ImmutableCallSite CS) { + DEBUG(dbgs() << "processCallSite (EH state = " << currentEHNumber() + << ") for: "); + print_name(CS ? CS.getCalledValue() : nullptr); + DEBUG(dbgs() << '\n'); + + DEBUG(dbgs() << "HandlerStack: \n"); + for (int I = 0, E = HandlerStack.size(); I < E; ++I) { + DEBUG(dbgs() << " "); + print_name(HandlerStack[I]->getHandlerBlockOrFunc()); + DEBUG(dbgs() << '\n'); + } + DEBUG(dbgs() << "Actions: \n"); + for (int I = 0, E = Actions.size(); I < E; ++I) { + DEBUG(dbgs() << " "); + print_name(Actions[I]->getHandlerBlockOrFunc()); + DEBUG(dbgs() << '\n'); + } + int FirstMismatch = 0; + for (int E = std::min(HandlerStack.size(), Actions.size()); FirstMismatch < E; + ++FirstMismatch) { + if (HandlerStack[FirstMismatch]->getHandlerBlockOrFunc() != + Actions[FirstMismatch]->getHandlerBlockOrFunc()) + break; + } + + // Remove unmatched actions from the stack and process their EH states. + popUnmatchedActions(FirstMismatch); + + DEBUG(dbgs() << "Pushing actions for CallSite: "); + print_name(CS ? CS.getCalledValue() : nullptr); + DEBUG(dbgs() << '\n'); + + bool LastActionWasCatch = false; + const LandingPadInst *LastRootLPad = nullptr; + for (size_t I = FirstMismatch; I != Actions.size(); ++I) { + // We can reuse eh states when pushing two catches for the same invoke. + bool CurrActionIsCatch = isa(Actions[I].get()); + auto *Handler = cast(Actions[I]->getHandlerBlockOrFunc()); + // Various conditions can lead to a handler being popped from the + // stack and re-pushed later. That shouldn't create a new state. + // FIXME: Can code optimization lead to re-used handlers? + if (FuncInfo.HandlerEnclosedState.count(Handler)) { + // If we already assigned the state enclosed by this handler re-use it. + Actions[I]->setEHState(FuncInfo.HandlerEnclosedState[Handler]); + continue; + } + const LandingPadInst* RootLPad = FuncInfo.RootLPad[Handler]; + if (CurrActionIsCatch && LastActionWasCatch && RootLPad == LastRootLPad) { + DEBUG(dbgs() << "setEHState for handler to " << currentEHNumber() << "\n"); + Actions[I]->setEHState(currentEHNumber()); + } else { + DEBUG(dbgs() << "createUnwindMapEntry(" << currentEHNumber() << ", "); + print_name(Actions[I]->getHandlerBlockOrFunc()); + DEBUG(dbgs() << ") with EH state " << NextState << "\n"); + createUnwindMapEntry(currentEHNumber(), Actions[I].get()); + DEBUG(dbgs() << "setEHState for handler to " << NextState << "\n"); + Actions[I]->setEHState(NextState); + NextState++; + } + HandlerStack.push_back(std::move(Actions[I])); + LastActionWasCatch = CurrActionIsCatch; + LastRootLPad = RootLPad; + } + + // This is used to defer numbering states for a handler until after the + // last time it appears in an invoke action list. + if (CS.isInvoke()) { + for (int I = 0, E = HandlerStack.size(); I < E; ++I) { + auto *Handler = cast(HandlerStack[I]->getHandlerBlockOrFunc()); + if (FuncInfo.LastInvoke[Handler] != cast(CS.getInstruction())) + continue; + FuncInfo.LastInvokeVisited[Handler] = true; + DEBUG(dbgs() << "Last invoke of "); + print_name(Handler); + DEBUG(dbgs() << " has been visited.\n"); + } + } + + DEBUG(dbgs() << "In EHState " << currentEHNumber() << " for CallSite: "); + print_name(CS ? CS.getCalledValue() : nullptr); + DEBUG(dbgs() << '\n'); +} + +void WinEHNumbering::popUnmatchedActions(int FirstMismatch) { + // Don't recurse while we are looping over the handler stack. Instead, defer + // the numbering of the catch handlers until we are done popping. + SmallVector PoppedCatches; + for (int I = HandlerStack.size() - 1; I >= FirstMismatch; --I) { + std::unique_ptr Handler = HandlerStack.pop_back_val(); + if (isa(Handler.get())) + PoppedCatches.push_back(cast(Handler.release())); + } + + int TryHigh = NextState - 1; + int LastTryLowIdx = 0; + for (int I = 0, E = PoppedCatches.size(); I != E; ++I) { + CatchHandler *CH = PoppedCatches[I]; + DEBUG(dbgs() << "Popped handler with state " << CH->getEHState() << "\n"); + if (I + 1 == E || CH->getEHState() != PoppedCatches[I + 1]->getEHState()) { + int TryLow = CH->getEHState(); + auto Handlers = + makeArrayRef(&PoppedCatches[LastTryLowIdx], I - LastTryLowIdx + 1); + DEBUG(dbgs() << "createTryBlockMapEntry(" << TryLow << ", " << TryHigh); + for (size_t J = 0; J < Handlers.size(); ++J) { + DEBUG(dbgs() << ", "); + print_name(Handlers[J]->getHandlerBlockOrFunc()); + } + DEBUG(dbgs() << ")\n"); + createTryBlockMapEntry(TryLow, TryHigh, Handlers); + LastTryLowIdx = I + 1; + } + } + + for (CatchHandler *CH : PoppedCatches) { + if (auto *F = dyn_cast(CH->getHandlerBlockOrFunc())) { + if (FuncInfo.LastInvokeVisited[F]) { + DEBUG(dbgs() << "Assigning base state " << NextState << " to "); + print_name(F); + DEBUG(dbgs() << '\n'); + FuncInfo.HandlerBaseState[F] = NextState; + DEBUG(dbgs() << "createUnwindMapEntry(" << currentEHNumber() + << ", null)\n"); + createUnwindMapEntry(currentEHNumber(), nullptr); + ++NextState; + calculateStateNumbers(*F); + } + else { + DEBUG(dbgs() << "Deferring handling of "); + print_name(F); + DEBUG(dbgs() << " until last invoke visited.\n"); + } + } + delete CH; + } +} + +void WinEHNumbering::calculateStateNumbers(const Function &F) { + auto I = VisitedHandlers.insert(&F); + if (!I.second) + return; // We've already visited this handler, don't renumber it. + + int OldBaseState = CurrentBaseState; + if (FuncInfo.HandlerBaseState.count(&F)) { + CurrentBaseState = FuncInfo.HandlerBaseState[&F]; + } + + size_t SavedHandlerStackSize = HandlerStack.size(); + + DEBUG(dbgs() << "Calculating state numbers for: " << F.getName() << '\n'); + SmallVector, 4> ActionList; + for (const BasicBlock &BB : F) { + for (const Instruction &I : BB) { + const auto *CI = dyn_cast(&I); + if (!CI || CI->doesNotThrow()) + continue; + processCallSite(None, CI); + } + const auto *II = dyn_cast(BB.getTerminator()); + if (!II) + continue; + const LandingPadInst *LPI = II->getLandingPadInst(); + auto *ActionsCall = dyn_cast(LPI->getNextNode()); + if (!ActionsCall) + continue; + assert(ActionsCall->getIntrinsicID() == Intrinsic::eh_actions); + parseEHActions(ActionsCall, ActionList); + if (ActionList.empty()) + continue; + processCallSite(ActionList, II); + ActionList.clear(); + FuncInfo.LandingPadStateMap[LPI] = currentEHNumber(); + DEBUG(dbgs() << "Assigning state " << currentEHNumber() + << " to landing pad at " << LPI->getParent()->getName() + << '\n'); + } + + // Pop any actions that were pushed on the stack for this function. + popUnmatchedActions(SavedHandlerStackSize); + + DEBUG(dbgs() << "Assigning max state " << NextState - 1 + << " to " << F.getName() << '\n'); + FuncInfo.CatchHandlerMaxState[&F] = NextState - 1; + + CurrentBaseState = OldBaseState; +} + +// This function follows the same basic traversal as calculateStateNumbers +// but it is necessary to identify the root landing pad associated +// with each action before we start assigning state numbers. +void WinEHNumbering::findActionRootLPads(const Function &F) { + auto I = VisitedHandlers.insert(&F); + if (!I.second) + return; // We've already visited this handler, don't revisit it. + + SmallVector, 4> ActionList; + for (const BasicBlock &BB : F) { + const auto *II = dyn_cast(BB.getTerminator()); + if (!II) + continue; + const LandingPadInst *LPI = II->getLandingPadInst(); + auto *ActionsCall = dyn_cast(LPI->getNextNode()); + if (!ActionsCall) + continue; + + assert(ActionsCall->getIntrinsicID() == Intrinsic::eh_actions); + parseEHActions(ActionsCall, ActionList); + if (ActionList.empty()) + continue; + for (int I = 0, E = ActionList.size(); I < E; ++I) { + if (auto *Handler + = dyn_cast(ActionList[I]->getHandlerBlockOrFunc())) { + FuncInfo.LastInvoke[Handler] = II; + // Don't replace the root landing pad if we previously saw this + // handler in a different function. + if (FuncInfo.RootLPad.count(Handler) && + FuncInfo.RootLPad[Handler]->getParent()->getParent() != &F) + continue; + DEBUG(dbgs() << "Setting root lpad for "); + print_name(Handler); + DEBUG(dbgs() << " to " << LPI->getParent()->getName() << '\n'); + FuncInfo.RootLPad[Handler] = LPI; + } + } + // Walk the actions again and look for nested handlers. This has to + // happen after all of the actions have been processed in the current + // function. + for (int I = 0, E = ActionList.size(); I < E; ++I) + if (auto *Handler + = dyn_cast(ActionList[I]->getHandlerBlockOrFunc())) + findActionRootLPads(*Handler); + ActionList.clear(); + } +} + +void llvm::calculateWinCXXEHStateNumbers(const Function *ParentFn, + WinEHFuncInfo &FuncInfo) { + // Return if it's already been done. + if (!FuncInfo.LandingPadStateMap.empty()) + return; + + WinEHNumbering Num(FuncInfo); + Num.findActionRootLPads(*ParentFn); + // The VisitedHandlers list is used by both findActionRootLPads and + // calculateStateNumbers, but both functions need to visit all handlers. + Num.VisitedHandlers.clear(); + Num.calculateStateNumbers(*ParentFn); + // Pop everything on the handler stack. + // It may be necessary to call this more than once because a handler can + // be pushed on the stack as a result of clearing the stack. + while (!Num.HandlerStack.empty()) + Num.processCallSite(None, ImmutableCallSite()); +} diff --git a/lib/DebugInfo/DWARF/DWARFContext.cpp b/lib/DebugInfo/DWARF/DWARFContext.cpp index cc2fbbdc8ca7f..baab3873b9154 100644 --- a/lib/DebugInfo/DWARF/DWARFContext.cpp +++ b/lib/DebugInfo/DWARF/DWARFContext.cpp @@ -352,7 +352,7 @@ void DWARFContext::parseTypeUnits() { if (!TUs.empty()) return; for (const auto &I : getTypesSections()) { - TUs.push_back(DWARFUnitSection()); + TUs.emplace_back(); TUs.back().parse(*this, I.second); } } @@ -365,7 +365,7 @@ void DWARFContext::parseDWOTypeUnits() { if (!DWOTUs.empty()) return; for (const auto &I : getTypesDWOSections()) { - DWOTUs.push_back(DWARFUnitSection()); + DWOTUs.emplace_back(); DWOTUs.back().parseDWO(*this, I.second); } } diff --git a/lib/DebugInfo/DWARF/DWARFDebugLine.cpp b/lib/DebugInfo/DWARF/DWARFDebugLine.cpp index b63af6a64ee40..a0bee0da17656 100644 --- a/lib/DebugInfo/DWARF/DWARFDebugLine.cpp +++ b/lib/DebugInfo/DWARF/DWARFDebugLine.cpp @@ -25,6 +25,7 @@ void DWARFDebugLine::Prologue::clear() { TotalLength = Version = PrologueLength = 0; MinInstLength = MaxOpsPerInst = DefaultIsStmt = LineBase = LineRange = 0; OpcodeBase = 0; + IsDWARF64 = false; StandardOpcodeLengths.clear(); IncludeDirectories.clear(); FileNames.clear(); @@ -32,9 +33,9 @@ void DWARFDebugLine::Prologue::clear() { void DWARFDebugLine::Prologue::dump(raw_ostream &OS) const { OS << "Line table prologue:\n" - << format(" total_length: 0x%8.8x\n", TotalLength) + << format(" total_length: 0x%8.8" PRIx64 "\n", TotalLength) << format(" version: %u\n", Version) - << format(" prologue_length: 0x%8.8x\n", PrologueLength) + << format(" prologue_length: 0x%8.8" PRIx64 "\n", PrologueLength) << format(" min_inst_length: %u\n", MinInstLength) << format(Version >= 4 ? "max_ops_per_inst: %u\n" : "", MaxOpsPerInst) << format(" default_is_stmt: %u\n", DefaultIsStmt) @@ -67,16 +68,23 @@ void DWARFDebugLine::Prologue::dump(raw_ostream &OS) const { bool DWARFDebugLine::Prologue::parse(DataExtractor debug_line_data, uint32_t *offset_ptr) { - const uint32_t prologue_offset = *offset_ptr; + const uint64_t prologue_offset = *offset_ptr; clear(); TotalLength = debug_line_data.getU32(offset_ptr); + if (TotalLength == UINT32_MAX) { + IsDWARF64 = true; + TotalLength = debug_line_data.getU64(offset_ptr); + } else if (TotalLength > 0xffffff00) { + return false; + } Version = debug_line_data.getU16(offset_ptr); if (Version < 2) return false; - PrologueLength = debug_line_data.getU32(offset_ptr); - const uint32_t end_prologue_offset = PrologueLength + *offset_ptr; + PrologueLength = debug_line_data.getUnsigned(offset_ptr, + sizeofPrologueLength()); + const uint64_t end_prologue_offset = PrologueLength + *offset_ptr; MinInstLength = debug_line_data.getU8(offset_ptr); if (Version >= 4) MaxOpsPerInst = debug_line_data.getU8(offset_ptr); @@ -114,9 +122,10 @@ bool DWARFDebugLine::Prologue::parse(DataExtractor debug_line_data, } if (*offset_ptr != end_prologue_offset) { - fprintf(stderr, "warning: parsing line table prologue at 0x%8.8x should" - " have ended at 0x%8.8x but it ended at 0x%8.8x\n", - prologue_offset, end_prologue_offset, *offset_ptr); + fprintf(stderr, "warning: parsing line table prologue at 0x%8.8" PRIx64 + " should have ended at 0x%8.8" PRIx64 + " but it ended at 0x%8.8" PRIx64 "\n", + prologue_offset, end_prologue_offset, (uint64_t)*offset_ptr); return false; } return true; @@ -258,7 +267,7 @@ bool DWARFDebugLine::LineTable::parse(DataExtractor debug_line_data, } const uint32_t end_offset = debug_line_offset + Prologue.TotalLength + - sizeof(Prologue.TotalLength); + Prologue.sizeofTotalLength(); ParsingState State(this); @@ -522,10 +531,36 @@ bool DWARFDebugLine::LineTable::parse(DataExtractor debug_line_data, return end_offset; } +uint32_t +DWARFDebugLine::LineTable::findRowInSeq(const DWARFDebugLine::Sequence &seq, + uint64_t address) const { + if (!seq.containsPC(address)) + return UnknownRowIndex; + // Search for instruction address in the rows describing the sequence. + // Rows are stored in a vector, so we may use arithmetical operations with + // iterators. + DWARFDebugLine::Row row; + row.Address = address; + RowIter first_row = Rows.begin() + seq.FirstRowIndex; + RowIter last_row = Rows.begin() + seq.LastRowIndex; + LineTable::RowIter row_pos = std::lower_bound( + first_row, last_row, row, DWARFDebugLine::Row::orderByAddress); + if (row_pos == last_row) { + return seq.LastRowIndex - 1; + } + uint32_t index = seq.FirstRowIndex + (row_pos - first_row); + if (row_pos->Address > address) { + if (row_pos == first_row) + return UnknownRowIndex; + else + index--; + } + return index; +} + uint32_t DWARFDebugLine::LineTable::lookupAddress(uint64_t address) const { - uint32_t unknown_index = UINT32_MAX; if (Sequences.empty()) - return unknown_index; + return UnknownRowIndex; // First, find an instruction sequence containing the given address. DWARFDebugLine::Sequence sequence; sequence.LowPC = address; @@ -540,31 +575,10 @@ uint32_t DWARFDebugLine::LineTable::lookupAddress(uint64_t address) const { found_seq = *seq_pos; } else { if (seq_pos == first_seq) - return unknown_index; + return UnknownRowIndex; found_seq = *(seq_pos - 1); } - if (!found_seq.containsPC(address)) - return unknown_index; - // Search for instruction address in the rows describing the sequence. - // Rows are stored in a vector, so we may use arithmetical operations with - // iterators. - DWARFDebugLine::Row row; - row.Address = address; - RowIter first_row = Rows.begin() + found_seq.FirstRowIndex; - RowIter last_row = Rows.begin() + found_seq.LastRowIndex; - RowIter row_pos = std::lower_bound(first_row, last_row, row, - DWARFDebugLine::Row::orderByAddress); - if (row_pos == last_row) { - return found_seq.LastRowIndex - 1; - } - uint32_t index = found_seq.FirstRowIndex + (row_pos - first_row); - if (row_pos->Address > address) { - if (row_pos == first_row) - return unknown_index; - else - index--; - } - return index; + return findRowInSeq(found_seq, address); } bool DWARFDebugLine::LineTable::lookupAddressRange( @@ -593,45 +607,21 @@ bool DWARFDebugLine::LineTable::lookupAddressRange( // index we just calculated while (seq_pos != last_seq && seq_pos->LowPC < end_addr) { - DWARFDebugLine::Sequence cur_seq = *seq_pos; - uint32_t first_row_index; - uint32_t last_row_index; - if (seq_pos == start_pos) { - // For the first sequence, we need to find which row in the sequence is the - // first in our range. Rows are stored in a vector, so we may use - // arithmetical operations with iterators. - DWARFDebugLine::Row row; - row.Address = address; - RowIter first_row = Rows.begin() + cur_seq.FirstRowIndex; - RowIter last_row = Rows.begin() + cur_seq.LastRowIndex; - RowIter row_pos = std::upper_bound(first_row, last_row, row, - DWARFDebugLine::Row::orderByAddress); - // The 'row_pos' iterator references the first row that is greater than - // our start address. Unless that's the first row, we want to start at - // the row before that. - first_row_index = cur_seq.FirstRowIndex + (row_pos - first_row); - if (row_pos != first_row) - --first_row_index; - } else - first_row_index = cur_seq.FirstRowIndex; - - // For the last sequence in our range, we need to figure out the last row in - // range. For all other sequences we can go to the end of the sequence. - if (cur_seq.HighPC > end_addr) { - DWARFDebugLine::Row row; - row.Address = end_addr; - RowIter first_row = Rows.begin() + cur_seq.FirstRowIndex; - RowIter last_row = Rows.begin() + cur_seq.LastRowIndex; - RowIter row_pos = std::upper_bound(first_row, last_row, row, - DWARFDebugLine::Row::orderByAddress); - // The 'row_pos' iterator references the first row that is greater than - // our end address. The row before that is the last row we want. - last_row_index = cur_seq.FirstRowIndex + (row_pos - first_row) - 1; - } else - // Contrary to what you might expect, DWARFDebugLine::SequenceLastRowIndex - // isn't a valid index within the current sequence. It's that plus one. + const DWARFDebugLine::Sequence &cur_seq = *seq_pos; + // For the first sequence, we need to find which row in the sequence is the + // first in our range. + uint32_t first_row_index = cur_seq.FirstRowIndex; + if (seq_pos == start_pos) + first_row_index = findRowInSeq(cur_seq, address); + + // Figure out the last row in the range. + uint32_t last_row_index = findRowInSeq(cur_seq, end_addr - 1); + if (last_row_index == UnknownRowIndex) last_row_index = cur_seq.LastRowIndex - 1; + assert(first_row_index != UnknownRowIndex); + assert(last_row_index != UnknownRowIndex); + for (uint32_t i = first_row_index; i <= last_row_index; ++i) { result.push_back(i); } diff --git a/lib/ExecutionEngine/ExecutionEngine.cpp b/lib/ExecutionEngine/ExecutionEngine.cpp index d7038fd2c9a8d..9e71b108280ba 100644 --- a/lib/ExecutionEngine/ExecutionEngine.cpp +++ b/lib/ExecutionEngine/ExecutionEngine.cpp @@ -438,7 +438,7 @@ int ExecutionEngine::runFunctionAsMain(Function *Fn, if (NumArgs > 2) { std::vector EnvVars; for (unsigned i = 0; envp[i]; ++i) - EnvVars.push_back(envp[i]); + EnvVars.emplace_back(envp[i]); // Arg #2 = envp. GVArgs.push_back(PTOGV(CEnv.reset(Fn->getContext(), this, EnvVars))); } diff --git a/lib/ExecutionEngine/ExecutionEngineBindings.cpp b/lib/ExecutionEngine/ExecutionEngineBindings.cpp index ce1ab594dfa39..55ab5af2b9098 100644 --- a/lib/ExecutionEngine/ExecutionEngineBindings.cpp +++ b/lib/ExecutionEngine/ExecutionEngineBindings.cpp @@ -18,6 +18,7 @@ #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/Module.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Target/TargetOptions.h" #include using namespace llvm; @@ -254,11 +255,8 @@ int LLVMRunFunctionAsMain(LLVMExecutionEngineRef EE, LLVMValueRef F, unsigned ArgC, const char * const *ArgV, const char * const *EnvP) { unwrap(EE)->finalizeObject(); - - std::vector ArgVec; - for (unsigned I = 0; I != ArgC; ++I) - ArgVec.push_back(ArgV[I]); - + + std::vector ArgVec(ArgV, ArgV + ArgC); return unwrap(EE)->runFunctionAsMain(unwrap(F), ArgVec, EnvP); } diff --git a/lib/ExecutionEngine/IntelJITEvents/IntelJITEventListener.cpp b/lib/ExecutionEngine/IntelJITEvents/IntelJITEventListener.cpp index ec67019947ab4..08d9d6b05a0ad 100644 --- a/lib/ExecutionEngine/IntelJITEvents/IntelJITEventListener.cpp +++ b/lib/ExecutionEngine/IntelJITEvents/IntelJITEventListener.cpp @@ -119,10 +119,9 @@ void IntelJITEventListener::NotifyObjectEmitted( if (SymType == SymbolRef::ST_Function) { StringRef Name; uint64_t Addr; - uint64_t Size; if (I->getName(Name)) continue; if (I->getAddress(Addr)) continue; - if (I->getSize(Size)) continue; + uint64_t Size = I->getSize(); // Record this address in a local vector Functions.push_back((void*)Addr); diff --git a/lib/ExecutionEngine/Interpreter/Execution.cpp b/lib/ExecutionEngine/Interpreter/Execution.cpp index a26740b0da8a4..39a8027005f89 100644 --- a/lib/ExecutionEngine/Interpreter/Execution.cpp +++ b/lib/ExecutionEngine/Interpreter/Execution.cpp @@ -2079,7 +2079,7 @@ void Interpreter::callFunction(Function *F, ECStack.back().Caller.arg_size() == ArgVals.size()) && "Incorrect number of arguments passed into function call!"); // Make a new stack frame... and fill it in. - ECStack.push_back(ExecutionContext()); + ECStack.emplace_back(); ExecutionContext &StackFrame = ECStack.back(); StackFrame.CurFunction = F; diff --git a/lib/ExecutionEngine/LLVMBuild.txt b/lib/ExecutionEngine/LLVMBuild.txt index 8509852b652e7..9d29a41f50413 100644 --- a/lib/ExecutionEngine/LLVMBuild.txt +++ b/lib/ExecutionEngine/LLVMBuild.txt @@ -22,4 +22,4 @@ subdirectories = Interpreter MCJIT RuntimeDyld IntelJITEvents OProfileJIT Orc type = Library name = ExecutionEngine parent = Libraries -required_libraries = Core MC Object RuntimeDyld Support +required_libraries = Core MC Object RuntimeDyld Support Target diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp index 24a3ec19aed40..6d64d68374305 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp @@ -120,7 +120,7 @@ static std::error_code getOffset(const SymbolRef &Sym, uint64_t &Result) { if (Address == UnknownAddressOrSize) { Result = UnknownAddressOrSize; - return object_error::success; + return std::error_code(); } const ObjectFile *Obj = Sym.getObject(); @@ -130,12 +130,12 @@ static std::error_code getOffset(const SymbolRef &Sym, uint64_t &Result) { if (SecI == Obj->section_end()) { Result = UnknownAddressOrSize; - return object_error::success; + return std::error_code(); } uint64_t SectionAddress = SecI->getAddress(); Result = Address - SectionAddress; - return object_error::success; + return std::error_code(); } std::pair @@ -149,6 +149,7 @@ RuntimeDyldImpl::loadObjectImpl(const object::ObjectFile &Obj) { // Save information about our target Arch = (Triple::ArchType)Obj.getArch(); IsTargetLittleEndian = Obj.isLittleEndian(); + setMipsABI(Obj); // Compute the memory size required to load all sections to be loaded // and pass this information to the memory manager @@ -386,8 +387,7 @@ void RuntimeDyldImpl::computeTotalAllocSize(const ObjectFile &Obj, uint32_t Flags = I->getFlags(); if (Flags & SymbolRef::SF_Common) { // Add the common symbols to a list. We'll allocate them all below. - uint64_t Size = 0; - Check(I->getSize(Size)); + uint64_t Size = I->getSize(); CommonSize += Size; } } @@ -493,10 +493,8 @@ void RuntimeDyldImpl::emitCommonSymbols(const ObjectFile &Obj, continue; } - uint32_t Align = 0; - uint64_t Size = 0; - Check(Sym.getAlignment(Align)); - Check(Sym.getSize(Size)); + uint32_t Align = Sym.getAlignment(); + uint64_t Size = Sym.getSize(); CommonSize += Align + Size; SymbolsToAllocate.push_back(Sym); @@ -517,11 +515,9 @@ void RuntimeDyldImpl::emitCommonSymbols(const ObjectFile &Obj, // Assign the address of each symbol for (auto &Sym : SymbolsToAllocate) { - uint32_t Align; - uint64_t Size; + uint32_t Align = Sym.getAlignment(); StringRef Name; - Check(Sym.getAlignment(Align)); - Check(Sym.getSize(Size)); + uint64_t Size = Sym.getSize(); Check(Sym.getName(Name)); if (Align) { // This symbol has an alignment requirement. @@ -689,7 +685,7 @@ uint8_t *RuntimeDyldImpl::createStubFunction(uint8_t *Addr, // and stubs for branches Thumb - ARM and ARM - Thumb. writeBytesUnaligned(0xe51ff004, Addr, 4); // ldr pc,