From 85d8b2bbe386bcfe669575d05b61482d7be07e5d Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Tue, 9 Jun 2015 19:06:30 +0000 Subject: [PATCH] Vendor import of llvm trunk r239412: https://llvm.org/svn/llvm-project/llvm/trunk@239412 --- CMakeLists.txt | 17 +- autoconf/configure.ac | 7 + cmake/modules/AddOCaml.cmake | 2 +- cmake/modules/TableGen.cmake | 6 +- configure | 16 + docs/CommandGuide/llvm-profdata.rst | 30 + docs/LangRef.rst | 5 + docs/Lexicon.rst | 4 + docs/NVPTXUsage.rst | 8 +- docs/TableGen/LangIntro.rst | 2 +- docs/YamlIO.rst | 14 +- include/llvm-c/Core.h | 7 + include/llvm-c/Support.h | 18 + include/llvm/ADT/APInt.h | 5 +- include/llvm/ADT/Triple.h | 12 +- include/llvm/Analysis/AliasAnalysis.h | 92 +- .../llvm/Analysis/BlockFrequencyInfoImpl.h | 6 +- include/llvm/Analysis/BranchProbabilityInfo.h | 3 + include/llvm/Analysis/CallGraph.h | 2 +- include/llvm/Analysis/DependenceAnalysis.h | 9 +- include/llvm/Analysis/LoopAccessAnalysis.h | 18 +- include/llvm/Analysis/LoopInfo.h | 26 +- include/llvm/Analysis/LoopInfoImpl.h | 2 +- include/llvm/Analysis/MemoryLocation.h | 137 ++ include/llvm/Analysis/PHITransAddr.h | 8 +- include/llvm/Analysis/TargetTransformInfo.h | 73 +- .../llvm/Analysis/TargetTransformInfoImpl.h | 16 +- include/llvm/Bitcode/BitstreamReader.h | 2 +- include/llvm/Bitcode/BitstreamWriter.h | 4 +- include/llvm/CodeGen/BasicTTIImpl.h | 76 +- include/llvm/CodeGen/CommandFlags.h | 8 + include/llvm/CodeGen/DIE.h | 614 +++--- include/llvm/CodeGen/DIEValue.def | 47 + include/llvm/CodeGen/GCMetadata.h | 2 +- include/llvm/CodeGen/LiveRangeEdit.h | 4 + include/llvm/CodeGen/MIRParser/MIRParser.h | 52 + include/llvm/CodeGen/MIRYamlMapping.h | 40 + include/llvm/CodeGen/MachineFrameInfo.h | 14 +- include/llvm/CodeGen/MachineInstr.h | 20 +- include/llvm/CodeGen/MachineLoopInfo.h | 2 +- include/llvm/CodeGen/Passes.h | 15 +- include/llvm/CodeGen/ScheduleDAGInstrs.h | 2 +- include/llvm/CodeGen/SelectionDAG.h | 4 + include/llvm/CodeGen/WinEHFuncInfo.h | 7 + include/llvm/Config/config.h.in | 3 + include/llvm/DebugInfo/DIContext.h | 5 +- include/llvm/DebugInfo/DWARF/DWARFDebugLine.h | 27 +- .../Orc/CompileOnDemandLayer.h | 3 +- include/llvm/ExecutionEngine/RuntimeDyld.h | 7 +- include/llvm/IR/InlineAsm.h | 7 + include/llvm/IR/Instructions.h | 16 +- include/llvm/IR/Intrinsics.td | 3 +- include/llvm/IR/IntrinsicsX86.td | 34 +- include/llvm/IR/MDBuilder.h | 2 +- include/llvm/IR/Value.h | 16 +- include/llvm/InitializePasses.h | 1 + include/llvm/LTO/LTOCodeGenerator.h | 14 +- include/llvm/MC/MCAsmBackend.h | 6 + include/llvm/MC/MCAsmInfo.h | 9 + include/llvm/MC/MCAsmLayout.h | 1 - include/llvm/MC/MCAssembler.h | 72 +- include/llvm/MC/MCContext.h | 16 +- include/llvm/MC/MCELF.h | 35 - include/llvm/MC/MCELFObjectWriter.h | 8 +- include/llvm/MC/MCELFStreamer.h | 7 +- include/llvm/MC/MCELFSymbolFlags.h | 56 - include/llvm/MC/MCExpr.h | 135 +- include/llvm/MC/MCInst.h | 27 +- include/llvm/MC/MCInstPrinter.h | 26 +- include/llvm/MC/MCInstrDesc.h | 16 +- include/llvm/MC/MCLabel.h | 56 +- include/llvm/MC/MCLinkerOptimizationHint.h | 14 +- include/llvm/MC/MCMachOSymbolFlags.h | 46 - include/llvm/MC/MCMachObjectWriter.h | 79 +- include/llvm/MC/MCObjectFileInfo.h | 98 +- include/llvm/MC/MCObjectStreamer.h | 13 +- include/llvm/MC/MCObjectWriter.h | 83 +- include/llvm/MC/MCSection.h | 7 +- include/llvm/MC/MCSectionELF.h | 13 +- include/llvm/MC/MCStreamer.h | 18 +- include/llvm/MC/MCSubtargetInfo.h | 8 +- include/llvm/MC/MCSymbol.h | 301 +-- include/llvm/MC/MCSymbolCOFF.h | 64 + include/llvm/MC/MCSymbolELF.h | 57 + include/llvm/MC/MCSymbolMachO.h | 123 ++ include/llvm/MC/MCWinCOFFStreamer.h | 2 +- include/llvm/MC/SubtargetFeature.h | 4 + include/llvm/Object/ArchiveWriter.h | 51 + include/llvm/Object/COFF.h | 10 +- include/llvm/Object/ELF.h | 103 +- include/llvm/Object/ELFObjectFile.h | 148 +- include/llvm/Object/ELFTypes.h | 206 +- include/llvm/Object/Error.h | 7 +- include/llvm/Object/MachO.h | 38 +- include/llvm/Object/ObjectFile.h | 33 +- include/llvm/Object/RelocVisitor.h | 31 + include/llvm/Support/COFF.h | 10 - include/llvm/Support/CommandLine.h | 77 +- include/llvm/Support/Compiler.h | 13 - include/llvm/Support/ELFRelocs/Hexagon.def | 8 + include/llvm/Support/MathExtras.h | 4 +- include/llvm/Support/TargetParser.h | 51 +- include/llvm/Support/TargetRegistry.h | 11 +- include/llvm/Support/YAMLTraits.h | 6 +- include/llvm/TableGen/Record.h | 310 +-- include/llvm/TableGen/SetTheory.h | 4 +- include/llvm/Target/Target.td | 3 +- include/llvm/Target/TargetInstrInfo.h | 18 +- include/llvm/Target/TargetLowering.h | 17 +- include/llvm/Target/TargetOptions.h | 8 +- include/llvm/Target/TargetRecip.h | 73 + include/llvm/Transforms/Scalar.h | 16 +- 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 | 46 +- 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 +- .../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 | 57 +- lib/CodeGen/AsmPrinter/DwarfFile.h | 9 +- lib/CodeGen/AsmPrinter/DwarfUnit.cpp | 77 +- lib/CodeGen/AsmPrinter/DwarfUnit.h | 27 +- .../AsmPrinter/WinCodeViewLineTables.cpp | 6 +- .../{Win64Exception.cpp => WinException.cpp} | 439 ++-- .../{Win64Exception.h => WinException.h} | 26 +- 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 +- .../SelectionDAG/FunctionLoweringInfo.cpp | 374 +--- .../SelectionDAG/LegalizeIntegerTypes.cpp | 33 +- .../SelectionDAG/ScheduleDAGSDNodes.cpp | 2 +- lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 37 +- .../SelectionDAG/SelectionDAGBuilder.cpp | 67 +- .../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 | 130 +- lib/ExecutionEngine/ExecutionEngine.cpp | 2 +- .../ExecutionEngineBindings.cpp | 8 +- .../IntelJITEvents/IntelJITEventListener.cpp | 3 +- lib/ExecutionEngine/Interpreter/Execution.cpp | 2 +- lib/ExecutionEngine/LLVMBuild.txt | 2 +- .../RuntimeDyld/RuntimeDyld.cpp | 24 +- .../RuntimeDyld/RuntimeDyldELF.cpp | 311 ++- .../RuntimeDyld/RuntimeDyldELF.h | 25 +- .../RuntimeDyld/RuntimeDyldImpl.h | 7 + .../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 | 550 ++--- 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 +- .../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 | 237 +- 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 | 520 ++--- 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 | 108 +- lib/Support/YAMLTraits.cpp | 11 +- lib/Support/raw_ostream.cpp | 2 +- lib/TableGen/Record.cpp | 658 +++--- 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 +- .../AArch64/AArch64TargetObjectFile.cpp | 12 +- .../AArch64/AsmParser/AArch64AsmParser.cpp | 119 +- .../Disassembler/AArch64Disassembler.cpp | 40 + .../AArch64ExternalSymbolizer.cpp | 22 +- lib/Target/AArch64/Disassembler/LLVMBuild.txt | 2 +- .../InstPrinter/AArch64InstPrinter.cpp | 48 +- .../AArch64/InstPrinter/AArch64InstPrinter.h | 4 + lib/Target/AArch64/LLVMBuild.txt | 2 +- .../MCTargetDesc/AArch64AsmBackend.cpp | 4 +- .../MCTargetDesc/AArch64ELFStreamer.cpp | 18 +- .../AArch64/MCTargetDesc/AArch64MCAsmInfo.cpp | 9 +- .../AArch64/MCTargetDesc/AArch64MCAsmInfo.h | 7 +- .../MCTargetDesc/AArch64MCCodeEmitter.cpp | 13 +- .../AArch64/MCTargetDesc/AArch64MCExpr.cpp | 18 +- .../AArch64/MCTargetDesc/AArch64MCExpr.h | 8 +- .../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 | 413 +++- 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 +- .../ARM/MCTargetDesc/ARMAddressingModes.h | 2 - lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp | 17 +- .../ARM/MCTargetDesc/ARMELFObjectWriter.cpp | 4 +- .../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 +- .../ARM/MCTargetDesc/ARMMCTargetDesc.cpp | 9 +- .../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 +- .../BPF/MCTargetDesc/BPFELFObjectWriter.cpp | 5 +- lib/Target/BPF/MCTargetDesc/BPFMCAsmInfo.h | 7 +- .../BPF/MCTargetDesc/BPFMCCodeEmitter.cpp | 82 +- .../BPF/MCTargetDesc/BPFMCTargetDesc.cpp | 49 +- 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 +- .../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 + .../Hexagon/MCTargetDesc/CMakeLists.txt | 4 + .../MCTargetDesc/HexagonAsmBackend.cpp | 269 ++- .../Hexagon/MCTargetDesc/HexagonBaseInfo.h | 22 +- .../MCTargetDesc/HexagonELFObjectWriter.cpp | 306 ++- .../MCTargetDesc/HexagonInstPrinter.cpp | 120 +- .../Hexagon/MCTargetDesc/HexagonInstPrinter.h | 19 +- .../Hexagon/MCTargetDesc/HexagonMCAsmInfo.cpp | 2 +- .../Hexagon/MCTargetDesc/HexagonMCAsmInfo.h | 4 +- .../MCTargetDesc/HexagonMCCodeEmitter.cpp | 221 +- .../MCTargetDesc/HexagonMCCodeEmitter.h | 10 + .../MCTargetDesc/HexagonMCCompound.cpp | 420 ++++ .../MCTargetDesc/HexagonMCDuplexInfo.cpp | 1100 ++++++++++ .../MCTargetDesc/HexagonMCInstrInfo.cpp | 271 ++- .../Hexagon/MCTargetDesc/HexagonMCInstrInfo.h | 154 +- .../MCTargetDesc/HexagonMCShuffler.cpp | 237 ++ .../Hexagon/MCTargetDesc/HexagonMCShuffler.h | 65 + .../MCTargetDesc/HexagonMCTargetDesc.cpp | 10 +- .../MCTargetDesc/HexagonMCTargetDesc.h | 4 + .../Hexagon/MCTargetDesc/HexagonShuffler.cpp | 385 ++++ .../Hexagon/MCTargetDesc/HexagonShuffler.h | 139 ++ .../MSP430/InstPrinter/MSP430InstPrinter.cpp | 7 +- lib/Target/MSP430/MCTargetDesc/LLVMBuild.txt | 2 +- .../MSP430/MCTargetDesc/MSP430MCAsmInfo.cpp | 3 +- .../MSP430/MCTargetDesc/MSP430MCAsmInfo.h | 4 +- lib/Target/MSP430/MSP430AsmPrinter.cpp | 4 +- lib/Target/MSP430/MSP430MCInstLower.cpp | 8 +- lib/Target/Mips/AsmParser/MipsAsmParser.cpp | 98 +- .../Mips/Disassembler/MipsDisassembler.cpp | 12 + .../Mips/InstPrinter/MipsInstPrinter.cpp | 9 +- lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp | 4 + lib/Target/Mips/MCTargetDesc/MipsABIInfo.h | 1 + .../Mips/MCTargetDesc/MipsELFObjectWriter.cpp | 240 +-- .../Mips/MCTargetDesc/MipsELFStreamer.cpp | 12 +- .../Mips/MCTargetDesc/MipsMCAsmInfo.cpp | 3 +- lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.h | 4 +- .../Mips/MCTargetDesc/MipsMCCodeEmitter.cpp | 2 +- lib/Target/Mips/MCTargetDesc/MipsMCExpr.cpp | 10 +- lib/Target/Mips/MCTargetDesc/MipsMCExpr.h | 10 +- .../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 | 73 +- 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 +- .../NVPTX/InstPrinter/NVPTXInstPrinter.cpp | 2 +- .../NVPTX/MCTargetDesc/NVPTXMCAsmInfo.cpp | 3 +- .../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 +- .../PowerPC/InstPrinter/PPCInstPrinter.cpp | 2 +- .../PowerPC/MCTargetDesc/PPCAsmBackend.cpp | 19 +- .../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 +- .../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 +- .../R600/InstPrinter/AMDGPUInstPrinter.cpp | 2 +- .../R600/MCTargetDesc/AMDGPUAsmBackend.cpp | 8 +- .../R600/MCTargetDesc/AMDGPUMCAsmInfo.cpp | 2 +- .../R600/MCTargetDesc/AMDGPUMCAsmInfo.h | 4 +- .../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 +- .../Sparc/InstPrinter/SparcInstPrinter.cpp | 2 +- .../Sparc/MCTargetDesc/SparcAsmBackend.cpp | 2 +- .../Sparc/MCTargetDesc/SparcMCAsmInfo.cpp | 11 +- .../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 +- .../SystemZ/AsmParser/SystemZAsmParser.cpp | 6 +- .../InstPrinter/SystemZInstPrinter.cpp | 9 +- .../SystemZ/InstPrinter/SystemZInstPrinter.h | 3 +- .../MCTargetDesc/SystemZMCAsmBackend.cpp | 2 +- .../SystemZ/MCTargetDesc/SystemZMCAsmInfo.cpp | 2 +- .../SystemZ/MCTargetDesc/SystemZMCAsmInfo.h | 4 +- .../MCTargetDesc/SystemZMCCodeEmitter.cpp | 6 +- .../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 ++ .../X86/AsmParser/X86AsmInstrumentation.cpp | 42 +- lib/Target/X86/AsmParser/X86AsmParser.cpp | 34 +- .../X86/Disassembler/X86Disassembler.cpp | 3 + .../X86DisassemblerDecoderCommon.h | 1 + .../X86/InstPrinter/X86ATTInstPrinter.cpp | 12 +- .../X86/InstPrinter/X86IntelInstPrinter.cpp | 10 +- lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp | 6 +- .../X86/MCTargetDesc/X86ELFObjectWriter.cpp | 1 + .../X86/MCTargetDesc/X86ELFRelocationInfo.cpp | 24 +- lib/Target/X86/MCTargetDesc/X86MCAsmInfo.cpp | 11 +- .../X86/MCTargetDesc/X86MCCodeEmitter.cpp | 4 +- .../X86/MCTargetDesc/X86MCTargetDesc.cpp | 4 +- .../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 | 1480 +++++++------ 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 ++- .../XCore/InstPrinter/XCoreInstPrinter.cpp | 7 +- .../XCore/MCTargetDesc/XCoreMCAsmInfo.cpp | 3 +- .../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 +- .../InstCombine/InstCombineCompares.cpp | 2 + .../InstCombineLoadStoreAlloca.cpp | 15 +- .../InstCombine/InstCombineSelect.cpp | 104 +- .../InstCombine/InstructionCombining.cpp | 10 +- .../Instrumentation/AddressSanitizer.cpp | 269 +-- .../Instrumentation/InstrProfiling.cpp | 26 +- lib/Transforms/ObjCARC/ObjCARCContract.cpp | 2 +- .../Scalar/CorrelatedValuePropagation.cpp | 7 +- .../Scalar/DeadStoreElimination.cpp | 12 +- lib/Transforms/Scalar/IndVarSimplify.cpp | 154 +- lib/Transforms/Scalar/LoopStrengthReduce.cpp | 10 +- lib/Transforms/Scalar/LoopUnrollPass.cpp | 515 ++--- lib/Transforms/Scalar/MemCpyOptimizer.cpp | 24 +- .../Scalar/MergedLoadStoreMotion.cpp | 10 +- lib/Transforms/Scalar/NaryReassociate.cpp | 28 +- lib/Transforms/Scalar/PlaceSafepoints.cpp | 2 +- lib/Transforms/Scalar/Reassociate.cpp | 58 +- .../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 + .../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 +- .../NonCanonicalizedSubscript.ll | 70 + .../LoopAccessAnalysis/number-of-memchecks.ll | 58 + .../stride-access-dependence.ll | 540 +++++ .../ValueTracking/memory-dereferenceable.ll | 13 + .../{mdcompileunit.ll => dicompileunit.ll} | 0 .../{mdexpression.ll => diexpression.ll} | 0 ...caped-chars.ll => difile-escaped-chars.ll} | 0 ...dglobalvariable.ll => diglobalvariable.ll} | 0 ...dimportedentity.ll => diimportedentity.ll} | 0 .../{mdlexicalblock.ll => dilexicalblock.ll} | 0 test/Assembler/dilocalvariable-arg-large.ll | 10 + ...{mdlocalvariable.ll => dilocalvariable.ll} | 0 .../{mdlocation.ll => dilocation.ll} | 0 .../{mdnamespace.ll => dinamespace.ll} | 0 .../{mdobjcproperty.ll => diobjcproperty.ll} | 0 .../{mdsubprogram.ll => disubprogram.ll} | 0 ...pty-array.ll => disubrange-empty-array.ll} | 0 ...dsubroutinetype.ll => disubroutinetype.ll} | 0 ...ateparameter.ll => ditemplateparameter.ll} | 0 ...large-values.ll => ditype-large-values.ll} | 0 test/Assembler/getelementptr.ll | 4 + ... => invalid-dicompileunit-language-bad.ll} | 0 ...nvalid-dicompileunit-language-overflow.ll} | 0 ...invalid-dicompileunit-missing-language.ll} | 0 ....ll => invalid-dicompileunit-null-file.ll} | 0 ...=> invalid-dicompositetype-missing-tag.ll} | 0 ...invalid-diderivedtype-missing-basetype.ll} | 0 ...l => invalid-diderivedtype-missing-tag.ll} | 0 ...l => invalid-dienumerator-missing-name.ll} | 0 ... => invalid-dienumerator-missing-value.ll} | 0 ...large.ll => invalid-diexpression-large.ll} | 0 ...rify.ll => invalid-diexpression-verify.ll} | 0 ...ll => invalid-difile-missing-directory.ll} | 0 ....ll => invalid-difile-missing-filename.ll} | 0 ...=> invalid-diglobalvariable-empty-name.ll} | 0 ... invalid-diglobalvariable-missing-name.ll} | 0 ...invalid-diimportedentity-missing-scope.ll} | 0 ...> invalid-diimportedentity-missing-tag.ll} | 0 ...> invalid-dilexicalblock-missing-scope.ll} | 0 ...l => invalid-dilexicalblock-null-scope.ll} | 0 ...lexicalblockfile-missing-discriminator.ll} | 0 ...valid-dilexicalblockfile-missing-scope.ll} | 0 ... invalid-dilexicalblockfile-null-scope.ll} | 0 .../invalid-dilocalvariable-arg-large.ll | 6 + .../invalid-dilocalvariable-arg-negative.ll | 6 + ... invalid-dilocalvariable-missing-scope.ll} | 0 ...=> invalid-dilocalvariable-missing-tag.ll} | 0 ... => invalid-dilocalvariable-null-scope.ll} | 0 ...bad.ll => invalid-dilocation-field-bad.ll} | 0 ...e.ll => invalid-dilocation-field-twice.ll} | 0 ... => invalid-dilocation-missing-scope-2.ll} | 0 ...ll => invalid-dilocation-missing-scope.ll} | 0 ...pe.ll => invalid-dilocation-null-scope.ll} | 0 ... => invalid-dilocation-overflow-column.ll} | 0 ...ll => invalid-dilocation-overflow-line.ll} | 0 ... invalid-dinamespace-missing-namespace.ll} | 0 ...e.ll => invalid-disubrange-count-large.ll} | 0 ...ll => invalid-disubrange-count-missing.ll} | 0 ...l => invalid-disubrange-count-negative.ll} | 0 ...l => invalid-disubrange-lowerBound-max.ll} | 0 ...l => invalid-disubrange-lowerBound-min.ll} | 0 ...invalid-disubroutinetype-missing-types.ll} | 0 ...d-ditemplatetypeparameter-missing-type.ll} | 0 ...ditemplatevalueparameter-missing-value.ll} | 0 test/Assembler/metadata.ll | 13 +- .../Inputs/invalid-alias-type-mismatch.bc | Bin 0 -> 452 bytes ...nvalid-metadata-not-followed-named-node.bc | Bin 0 -> 878 bytes test/Bitcode/Inputs/invalid-vector-length.bc | Bin 0 -> 488 bytes test/Bitcode/invalid.test | 15 + test/CodeGen/AArch64/arm64-ccmp.ll | 40 + test/CodeGen/AArch64/arm64-named-reg-alloc.ll | 2 +- .../AArch64/arm64-named-reg-notareg.ll | 2 +- .../global-merge-ignore-single-use-minsize.ll | 74 + test/CodeGen/AArch64/minmax.ll | 11 + test/CodeGen/AArch64/special-reg.ll | 48 + test/CodeGen/ARM/atomic-ops-v8.ll | 14 +- test/CodeGen/ARM/build-attributes.ll | 6 +- test/CodeGen/ARM/ifcvt-callback.ll | 22 + test/CodeGen/ARM/jump-table-islands-split.ll | 52 + test/CodeGen/ARM/jump-table-islands.ll | 40 + test/CodeGen/ARM/jumptable-label.ll | 4 +- test/CodeGen/ARM/ldrd.ll | 16 + test/CodeGen/ARM/named-reg-alloc.ll | 2 +- test/CodeGen/ARM/named-reg-notareg.ll | 2 +- test/CodeGen/ARM/special-reg-acore.ll | 78 + test/CodeGen/ARM/special-reg-mcore.ll | 143 ++ test/CodeGen/ARM/special-reg.ll | 78 + test/CodeGen/BPF/alu8.ll | 3 +- test/CodeGen/BPF/atomics.ll | 3 +- test/CodeGen/BPF/basictest.ll | 2 +- test/CodeGen/BPF/cc_args.ll | 3 +- test/CodeGen/BPF/cc_args_be.ll | 96 + test/CodeGen/BPF/cc_ret.ll | 2 +- test/CodeGen/BPF/ex1.ll | 2 +- test/CodeGen/BPF/intrinsics.ll | 2 +- test/CodeGen/BPF/load.ll | 2 +- test/CodeGen/BPF/loops.ll | 2 +- test/CodeGen/BPF/sanity.ll | 2 +- test/CodeGen/BPF/setcc.ll | 2 +- test/CodeGen/BPF/shifts.ll | 3 +- test/CodeGen/BPF/sockex2.ll | 3 +- test/CodeGen/Generic/stop-after.ll | 3 +- test/CodeGen/Hexagon/args.ll | 8 +- test/CodeGen/Hexagon/calling-conv.ll | 73 - test/CodeGen/Hexagon/cext-valid-packet1.ll | 1 + test/CodeGen/Hexagon/cext-valid-packet2.ll | 1 + test/CodeGen/Hexagon/compound.ll | 17 + test/CodeGen/Hexagon/dualstore.ll | 15 +- test/CodeGen/Hexagon/duplex.ll | 7 + test/CodeGen/Hexagon/relax.ll | 14 + test/CodeGen/Hexagon/sube.ll | 4 +- test/CodeGen/MIR/lit.local.cfg | 2 + test/CodeGen/MIR/llvm-ir-error-reported.mir | 22 + test/CodeGen/MIR/llvmIR.mir | 32 + test/CodeGen/MIR/llvmIRMissing.mir | 5 + .../MIR/machine-function-missing-name.mir | 22 + test/CodeGen/MIR/machine-function.mir | 24 + test/CodeGen/Mips/Fast-ISel/bswap1.ll | 58 + test/CodeGen/Mips/Fast-ISel/div1.ll | 55 + test/CodeGen/Mips/Fast-ISel/memtest1.ll | 74 + test/CodeGen/Mips/Fast-ISel/mul1.ll | 18 + test/CodeGen/Mips/Fast-ISel/rem1.ll | 56 + test/CodeGen/Mips/Fast-ISel/sel1.ll | 91 + .../CodeGen/Mips/dynamic-stack-realignment.ll | 299 +++ test/CodeGen/Mips/ehframe-indirect.ll | 26 +- .../Mips/emergency-spill-slot-near-fp.ll | 4 +- test/CodeGen/NVPTX/access-non-generic.ll | 16 + test/CodeGen/NVPTX/bug21465.ll | 12 +- test/CodeGen/NVPTX/call-with-alloca-buffer.ll | 7 +- test/CodeGen/NVPTX/globals_init.ll | 23 + test/CodeGen/NVPTX/lower-kernel-ptr-arg.ll | 20 + test/CodeGen/NVPTX/pr13291-i1-store.ll | 8 +- test/CodeGen/NVPTX/surf-read-cuda.ll | 8 +- test/CodeGen/NVPTX/tex-read-cuda.ll | 8 +- test/CodeGen/PowerPC/fma.ll | 83 + test/CodeGen/PowerPC/vsx-fma-sp.ll | 167 ++ test/CodeGen/R600/cgp-addressing-modes.ll | 242 +++ test/CodeGen/R600/coalescer_remat.ll | 6 +- .../R600/codegen-prepare-addrmode-sext.ll | 10 +- test/CodeGen/R600/fmul.ll | 16 + test/CodeGen/R600/half.ll | 557 ++++- test/CodeGen/R600/imm.ll | 2 +- test/CodeGen/R600/loop-address.ll | 5 +- test/CodeGen/R600/loop-idiom.ll | 4 - test/CodeGen/R600/max.ll | 51 + test/CodeGen/R600/min.ll | 51 + test/CodeGen/R600/sext-in-reg.ll | 5 +- test/CodeGen/R600/si-vector-hang.ll | 3 - test/CodeGen/R600/subreg-eliminate-dead.ll | 19 + test/CodeGen/R600/trunc-store-f64-to-f16.ll | 56 + test/CodeGen/R600/unroll.ll | 5 +- test/CodeGen/R600/wrong-transalu-pos-fix.ll | 7 +- .../Thumb2/constant-islands-jump-table.ll | 2 +- test/CodeGen/Thumb2/float-ops.ll | 6 +- test/CodeGen/Thumb2/thumb2-tbh.ll | 12 +- .../X86/asm-reject-reg-type-mismatch.ll | 10 + test/CodeGen/X86/avx-vperm2x128.ll | 2 +- test/CodeGen/X86/avx2-vector-shifts.ll | 390 ++++ test/CodeGen/X86/avx512-build-vector.ll | 10 +- test/CodeGen/X86/avx512-intrinsics.ll | 45 +- test/CodeGen/X86/avx512-shuffle.ll | 336 +++ test/CodeGen/X86/avx512-vec-cmp.ll | 7 - test/CodeGen/X86/avx512vl-intrinsics.ll | 40 +- test/CodeGen/X86/buildvec-insertvec.ll | 55 +- test/CodeGen/X86/critical-anti-dep-breaker.ll | 3 +- test/CodeGen/X86/machine-cp.ll | 55 + test/CodeGen/X86/pic.ll | 8 +- test/CodeGen/X86/pr23603.ll | 24 + test/CodeGen/X86/pr23664.ll | 14 + test/CodeGen/X86/recip-fastmath.ll | 4 +- test/CodeGen/X86/sibcall-win64.ll | 24 + test/CodeGen/X86/sqrt-fastmath.ll | 2 +- test/CodeGen/X86/stack-folding-x86_64.ll | 51 + test/CodeGen/X86/statepoint-far-call.ll | 22 + test/CodeGen/X86/switch-or.ll | 21 +- test/CodeGen/X86/switch.ll | 15 + test/CodeGen/X86/tail-call-got.ll | 18 +- test/CodeGen/X86/tailcallpic1.ll | 3 + test/CodeGen/X86/tailcallpic3.ll | 73 + test/CodeGen/X86/vec_fp_to_int.ll | 2 - test/CodeGen/X86/vec_shift8.ll | 1016 +++++++++ test/CodeGen/X86/vector-ctpop.ll | 159 -- test/CodeGen/X86/vector-lzcnt-128.ll | 1915 +++++++++++++++++ test/CodeGen/X86/vector-lzcnt-256.ll | 1305 +++++++++++ test/CodeGen/X86/vector-popcnt-128.ll | 462 ++++ test/CodeGen/X86/vector-popcnt-256.ll | 220 ++ test/CodeGen/X86/vector-shuffle-256-v4.ll | 1 - test/CodeGen/X86/vector-shuffle-512-v8.ll | 713 ++---- test/CodeGen/X86/vector-tzcnt-128.ll | 1788 +++++++++++++++ test/CodeGen/X86/vector-tzcnt-256.ll | 1195 ++++++++++ test/CodeGen/X86/vector-zext.ll | 10 - test/CodeGen/X86/win32-eh-states.ll | 112 + test/CodeGen/X86/win32-eh.ll | 59 +- .../Inputs/dwarfdump.elf-mips64-64-bit-dwarf | Bin 0 -> 15638 bytes test/DebugInfo/Inputs/invalid.elf | Bin 0 -> 64 bytes test/DebugInfo/Inputs/invalid.elf.2 | 1 + test/DebugInfo/Inputs/invalid.elf.3 | 1 + test/DebugInfo/Inputs/test-multiple-macho.o | Bin 0 -> 2452 bytes test/DebugInfo/Inputs/test-simple-macho.o | Bin 0 -> 1944 bytes test/DebugInfo/X86/expressions.ll | 110 + test/DebugInfo/X86/inlined-indirect-value.ll | 81 + test/DebugInfo/debuglineinfo-macho.test | 43 + test/DebugInfo/debuglineinfo.test | 3 - test/DebugInfo/dwarfdump-64-bit-dwarf.test | 15 + test/DebugInfo/dwarfdump-invalid.test | 6 + .../MCJIT/cross-module-sm-pic-a.ll | 2 +- test/ExecutionEngine/MCJIT/eh-lg-pic.ll | 2 +- test/ExecutionEngine/MCJIT/eh-sm-pic.ll | 2 +- .../MCJIT/multi-module-sm-pic-a.ll | 2 +- .../MCJIT/remote/cross-module-sm-pic-a.ll | 2 +- .../MCJIT/remote/multi-module-sm-pic-a.ll | 2 +- .../remote/test-global-init-nonzero-sm-pic.ll | 2 +- .../MCJIT/remote/test-ptr-reloc-sm-pic.ll | 2 +- test/ExecutionEngine/MCJIT/stubs-sm-pic.ll | 2 +- .../MCJIT/test-global-init-nonzero-sm-pic.ll | 2 +- .../MCJIT/test-ptr-reloc-sm-pic.ll | 2 +- .../OrcMCJIT/cross-module-sm-pic-a.ll | 2 +- test/ExecutionEngine/OrcMCJIT/eh-lg-pic.ll | 2 +- test/ExecutionEngine/OrcMCJIT/eh-sm-pic.ll | 2 +- .../OrcMCJIT/multi-module-sm-pic-a.ll | 2 +- .../OrcMCJIT/remote/cross-module-sm-pic-a.ll | 2 +- .../OrcMCJIT/remote/multi-module-sm-pic-a.ll | 2 +- .../remote/test-global-init-nonzero-sm-pic.ll | 2 +- .../OrcMCJIT/remote/test-ptr-reloc-sm-pic.ll | 2 +- test/ExecutionEngine/OrcMCJIT/stubs-sm-pic.ll | 2 +- .../test-global-init-nonzero-sm-pic.ll | 2 +- .../OrcMCJIT/test-ptr-reloc-sm-pic.ll | 2 +- .../Mips/ELF_Mips64r2N64_PIC_relocations.s | 164 ++ .../Mips/ELF_O32_PIC_relocations.s | 50 + .../Mips/Inputs/ExternalFunction.ll | 4 + .../RuntimeDyld/Mips/lit.local.cfg | 3 + .../X86/MachO_i386_DynNoPIC_relocations.s | 4 +- .../do-not-instrument-llvm-metadata-darwin.ll | 12 + .../instrument-dynamic-allocas.ll | 8 +- .../undecidable-dynamic-alloca-1.ll | 23 - .../Instrumentation/InstrProfiling/PR23499.ll | 21 + test/MC/AArch64/armv8.1a-atomic.s | 184 ++ test/MC/AArch64/basic-a64-diagnostics.s | 4 + test/MC/AArch64/basic-a64-instructions.s | 2 + test/MC/AArch64/case-insen-reg-names.s | 8 + test/MC/ARM/arm-elf-symver.s | 56 +- test/MC/ARM/directive-arch-armv2.s | 2 +- test/MC/ARM/directive-arch-armv2a.s | 2 +- test/MC/ARM/directive-arch-armv3.s | 2 +- test/MC/ARM/directive-arch-armv3m.s | 2 +- test/MC/ARM/directive-fpu-multiple.s | 18 +- test/MC/ARM/elf-movt.s | 8 +- test/MC/AsmParser/defsym.s | 20 + test/MC/AsmParser/defsym_error1.s | 2 + test/MC/AsmParser/defsym_error2.s | 2 + test/MC/COFF/cross-section-relative.ll | 60 - test/MC/COFF/cross-section-relative.s | 118 + .../Disassembler/AArch64/armv8.1a-atomic.txt | 87 + .../AArch64/basic-a64-instructions.txt | 2 + test/MC/Disassembler/PowerPC/vsx.txt | 24 + test/MC/ELF/alias.s | 28 +- test/MC/ELF/basic-elf-32.s | 14 - test/MC/ELF/basic-elf-64.s | 10 - test/MC/ELF/comdat-dup-group-name.s | 9 - test/MC/ELF/comdat.s | 2 +- test/MC/ELF/common-error3.s | 5 + test/MC/ELF/common-redeclare.s | 5 + test/MC/ELF/empty.s | 4 +- test/MC/ELF/got.s | 11 +- test/MC/ELF/many-sections-2.s | 15 +- test/MC/ELF/many-sections.s | 15 +- test/MC/ELF/noexec.s | 12 +- test/MC/ELF/popsection.s | 21 + test/MC/ELF/reloc-same-name-section.s | 4 +- test/MC/ELF/relocation-386.s | 23 +- test/MC/ELF/relocation.s | 17 +- test/MC/ELF/section-sym.s | 78 +- test/MC/ELF/section-sym2.s | 10 +- test/MC/ELF/strtab-suffix-opt.s | 2 +- test/MC/ELF/symver.s | 56 +- test/MC/ELF/undef.s | 36 - test/MC/ELF/weakref-reloc.s | 32 +- test/MC/ELF/weakref.s | 20 +- test/MC/Hexagon/inst_add.ll | 6 +- test/MC/Hexagon/inst_cmp_eq.ll | 6 +- test/MC/Hexagon/inst_cmp_eqi.ll | 6 +- test/MC/Hexagon/inst_cmp_gt.ll | 6 +- test/MC/Hexagon/inst_cmp_gti.ll | 6 +- test/MC/Hexagon/inst_cmp_lt.ll | 6 +- test/MC/Hexagon/inst_cmp_ugt.ll | 6 +- test/MC/Hexagon/inst_cmp_ugti.ll | 6 +- test/MC/Hexagon/inst_cmp_ult.ll | 6 +- test/MC/Hexagon/inst_select.ll | 9 +- test/MC/Hexagon/inst_sxtb.ll | 6 +- test/MC/Hexagon/inst_sxth.ll | 6 +- test/MC/Hexagon/inst_zxtb.ll | 6 +- test/MC/Hexagon/inst_zxth.ll | 6 +- test/MC/MachO/absolutize.s | 46 +- test/MC/MachO/reloc-diff.s | 22 +- test/MC/Mips/mips-expansions.s | 65 +- test/MC/Mips/mips-pdr.s | 18 +- test/MC/Mips/mips-relocations.s | 26 +- test/MC/Mips/octeon-instructions.s | 4 + test/MC/Mips/relocation.s | 10 + test/MC/Mips/set-push-pop-directives-bad.s | 9 + test/MC/Mips/set-push-pop-directives.s | 17 + test/MC/Mips/set-softfloat-hardfloat-bad.s | 14 + test/MC/Mips/set-softfloat-hardfloat.s | 12 + test/MC/PowerPC/st-other-crash.s | 21 + test/MC/PowerPC/vsx.s | 24 + test/MC/X86/avx512-encodings.s | 1089 ++++++++++ test/MC/X86/hex-immediates.s | 10 + test/MC/X86/intel-syntax-avx512.s | 83 + test/MC/X86/intel-syntax.s | 3 + test/MC/X86/mpx-encodings.s | 38 + test/MC/X86/x86-64-avx512bw.s | 35 + test/MC/X86/x86-64-avx512bw_vl.s | 161 ++ test/MC/X86/x86-64-avx512dq.s | 232 ++ test/MC/X86/x86-64-avx512dq_vl.s | 239 ++ test/MC/X86/x86-64-avx512f_vl.s | 935 ++++++++ test/Object/Inputs/macho-invalid-header | Bin 0 -> 24 bytes ...64-invalid-incomplete-segment-load-command | Bin 0 -> 64 bytes test/Object/Inputs/no-start-symbol.elf-x86_64 | Bin 0 -> 544 bytes test/Object/X86/no-start-symbol.test | 9 + test/Object/macho-invalid.test | 20 +- test/Object/obj2yaml.test | 47 +- test/Object/readobj-shared-object.test | 20 +- .../CorrelatedValuePropagation/select.ll | 22 + .../GVN/unreachable_block_infinite_loop.ll | 29 + .../IndVarSimplify/exit_value_test2.ll | 52 + .../IndVarSimplify/exit_value_test3.ll | 24 + .../IndVarSimplify/lcssa-preservation.ll | 3 +- test/Transforms/InstCombine/fpcast.ll | 8 + test/Transforms/InstCombine/load-bitcast32.ll | 79 + test/Transforms/InstCombine/load-bitcast64.ll | 78 + test/Transforms/InstCombine/pr23751.ll | 13 + test/Transforms/InstCombine/select.ll | 13 + .../LoopUnroll/full-unroll-bad-cost.ll | 58 + .../LoopUnroll/full-unroll-bad-geps.ll | 2 +- .../LoopUnroll/full-unroll-heuristics.ll | 12 +- .../AArch64/arbitrary-induction-step.ll | 37 +- .../LoopVectorize/interleaved-accesses.ll | 467 ++++ .../LoopVectorize/zero-sized-pointee-crash.ll | 27 + .../MergeFunc/call-and-invoke-with-ranges.ll | 8 +- test/Transforms/MergeFunc/linkonce_odr.ll | 30 + .../NaryReassociate/NVPTX/nary-gep.ll | 31 +- test/Transforms/Reassociate/basictest.ll | 4 +- .../Reassociate/canonicalize-neg-const.ll | 22 +- .../RewriteStatepointsForGC/deref-pointers.ll | 77 + .../R600/lit.local.cfg | 3 + ...-gep-and-gvn-addrspace-addressing-modes.ll | 94 + test/Transforms/Sink/convergent.ll | 24 + test/tools/dsymutil/Inputs/frame-dw2.ll | 71 + test/tools/dsymutil/Inputs/frame-dw4.ll | 71 + test/tools/dsymutil/Inputs/frame.c | 10 + .../tools/dsymutil/X86/basic-linking-x86.test | 4 +- .../dsymutil/X86/basic-lto-linking-x86.test | 1 + test/tools/dsymutil/X86/frame-1.test | 32 + test/tools/dsymutil/X86/frame-2.test | 47 + test/tools/dsymutil/debug-map-parsing.test | 92 +- .../dsymutil/yaml-object-address-rewrite.test | 44 + test/tools/llvm-objdump/invalid-input.test | 6 + test/tools/llvm-readobj/elf-dtflags.test | 4 + test/tools/llvm-readobj/sections-ext.test | 2 +- tools/Makefile | 3 +- tools/bugpoint/CrashDebugger.cpp | 3 +- tools/bugpoint/Miscompilation.cpp | 12 +- tools/dsymutil/CMakeLists.txt | 1 + tools/dsymutil/DebugMap.cpp | 161 +- tools/dsymutil/DebugMap.h | 86 +- tools/dsymutil/DwarfLinker.cpp | 304 ++- tools/dsymutil/MachODebugMapParser.cpp | 14 +- tools/dsymutil/dsymutil.cpp | 44 +- tools/dsymutil/dsymutil.h | 7 +- tools/llc/CMakeLists.txt | 2 + tools/llc/LLVMBuild.txt | 2 +- tools/llc/Makefile | 2 +- tools/llc/llc.cpp | 8 +- tools/lli/CMakeLists.txt | 1 + tools/lli/OrcLazyJIT.cpp | 7 +- tools/lli/OrcLazyJIT.h | 3 +- tools/lli/lli.cpp | 26 +- tools/llvm-ar/llvm-ar.cpp | 332 +-- tools/llvm-cov/CodeCoverage.cpp | 3 +- tools/llvm-cov/llvm-cov.cpp | 8 + tools/llvm-cxxdump/llvm-cxxdump.cpp | 5 +- tools/llvm-dwarfdump/CMakeLists.txt | 4 + tools/llvm-dwarfdump/fuzzer/CMakeLists.txt | 14 + .../fuzzer/llvm-dwarfdump-fuzzer.cpp | 34 + tools/llvm-lto/CMakeLists.txt | 1 + tools/llvm-lto/llvm-lto.cpp | 8 +- tools/llvm-mc/llvm-mc.cpp | 26 + tools/llvm-nm/llvm-nm.cpp | 3 +- tools/llvm-objdump/COFFDump.cpp | 8 +- tools/llvm-objdump/MachODump.cpp | 103 +- tools/llvm-objdump/llvm-objdump.cpp | 547 ++++- tools/llvm-objdump/llvm-objdump.h | 2 +- tools/llvm-pdbdump/LinePrinter.h | 2 +- tools/llvm-readobj/COFFDumper.cpp | 2 +- tools/llvm-readobj/ELFDumper.cpp | 44 +- tools/llvm-readobj/Win64EHDumper.cpp | 2 +- tools/llvm-rtdyld/llvm-rtdyld.cpp | 75 +- tools/llvm-size/llvm-size.cpp | 17 +- tools/llvm-symbolizer/LLVMSymbolize.cpp | 8 +- tools/lto/CMakeLists.txt | 1 + tools/lto/lto.cpp | 43 +- tools/macho-dump/macho-dump.cpp | 16 +- tools/obj2yaml/coff2yaml.cpp | 2 +- tools/obj2yaml/elf2yaml.cpp | 2 +- tools/yaml2obj/yaml2elf.cpp | 8 +- unittests/ADT/APIntTest.cpp | 6 + unittests/ADT/ArrayRefTest.cpp | 2 +- unittests/ADT/TripleTest.cpp | 8 + unittests/CodeGen/DIEHashTest.cpp | 306 +-- .../ExecutionEngine/MCJIT/MCJITCAPITest.cpp | 2 + .../ExecutionEngine/MCJIT/MCJITTestBase.h | 2 + unittests/Support/YAMLIOTest.cpp | 120 ++ utils/FileCheck/FileCheck.cpp | 12 +- utils/TableGen/AsmMatcherEmitter.cpp | 61 +- utils/TableGen/AsmWriterEmitter.cpp | 5 +- utils/TableGen/AsmWriterInst.cpp | 15 +- utils/TableGen/CTagsEmitter.cpp | 13 +- utils/TableGen/CallingConvEmitter.cpp | 19 +- utils/TableGen/CodeGenDAGPatterns.cpp | 24 +- utils/TableGen/CodeGenInstruction.cpp | 13 +- utils/TableGen/CodeGenInstruction.h | 4 +- utils/TableGen/CodeGenMapTable.cpp | 40 +- utils/TableGen/CodeGenRegisters.cpp | 10 +- utils/TableGen/CodeGenSchedule.cpp | 15 +- utils/TableGen/CodeGenTarget.cpp | 6 +- utils/TableGen/FixedLenDecoderEmitter.cpp | 18 +- utils/TableGen/InstrInfoEmitter.cpp | 67 +- utils/TableGen/IntrinsicEmitter.cpp | 2 +- utils/TableGen/X86RecognizableInstr.cpp | 3 + utils/lit/lit/TestRunner.py | 9 + utils/lit/lit/TestingConfig.py | 6 +- utils/release/tag.sh | 2 +- utils/release/test-release.sh | 12 - 1006 files changed, 41275 insertions(+), 12680 deletions(-) create mode 100644 include/llvm/Analysis/MemoryLocation.h create mode 100644 include/llvm/CodeGen/DIEValue.def create mode 100644 include/llvm/CodeGen/MIRParser/MIRParser.h create mode 100644 include/llvm/CodeGen/MIRYamlMapping.h delete mode 100644 include/llvm/MC/MCELF.h delete mode 100644 include/llvm/MC/MCELFSymbolFlags.h delete mode 100644 include/llvm/MC/MCMachOSymbolFlags.h create mode 100644 include/llvm/MC/MCSymbolCOFF.h create mode 100644 include/llvm/MC/MCSymbolELF.h create mode 100644 include/llvm/MC/MCSymbolMachO.h create mode 100644 include/llvm/Object/ArchiveWriter.h create mode 100644 include/llvm/Target/TargetRecip.h create mode 100644 lib/Analysis/MemoryLocation.cpp rename lib/CodeGen/AsmPrinter/{Win64Exception.cpp => WinException.cpp} (73%) rename lib/CodeGen/AsmPrinter/{Win64Exception.h => WinException.h} (68%) 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 create mode 100644 test/Analysis/LoopAccessAnalysis/number-of-memchecks.ll create mode 100644 test/Analysis/LoopAccessAnalysis/stride-access-dependence.ll rename test/Assembler/{mdcompileunit.ll => dicompileunit.ll} (100%) rename test/Assembler/{mdexpression.ll => diexpression.ll} (100%) rename test/Assembler/{mdfile-escaped-chars.ll => difile-escaped-chars.ll} (100%) rename test/Assembler/{mdglobalvariable.ll => diglobalvariable.ll} (100%) rename test/Assembler/{mdimportedentity.ll => diimportedentity.ll} (100%) rename test/Assembler/{mdlexicalblock.ll => dilexicalblock.ll} (100%) create mode 100644 test/Assembler/dilocalvariable-arg-large.ll rename test/Assembler/{mdlocalvariable.ll => dilocalvariable.ll} (100%) rename test/Assembler/{mdlocation.ll => dilocation.ll} (100%) rename test/Assembler/{mdnamespace.ll => dinamespace.ll} (100%) rename test/Assembler/{mdobjcproperty.ll => diobjcproperty.ll} (100%) rename test/Assembler/{mdsubprogram.ll => disubprogram.ll} (100%) rename test/Assembler/{mdsubrange-empty-array.ll => disubrange-empty-array.ll} (100%) rename test/Assembler/{mdsubroutinetype.ll => disubroutinetype.ll} (100%) rename test/Assembler/{mdtemplateparameter.ll => ditemplateparameter.ll} (100%) rename test/Assembler/{mdtype-large-values.ll => ditype-large-values.ll} (100%) rename test/Assembler/{invalid-mdcompileunit-language-bad.ll => invalid-dicompileunit-language-bad.ll} (100%) rename test/Assembler/{invalid-mdcompileunit-language-overflow.ll => invalid-dicompileunit-language-overflow.ll} (100%) rename test/Assembler/{invalid-mdcompileunit-missing-language.ll => invalid-dicompileunit-missing-language.ll} (100%) rename test/Assembler/{invalid-mdcompileunit-null-file.ll => invalid-dicompileunit-null-file.ll} (100%) rename test/Assembler/{invalid-mdcompositetype-missing-tag.ll => invalid-dicompositetype-missing-tag.ll} (100%) rename test/Assembler/{invalid-mdderivedtype-missing-basetype.ll => invalid-diderivedtype-missing-basetype.ll} (100%) rename test/Assembler/{invalid-mdderivedtype-missing-tag.ll => invalid-diderivedtype-missing-tag.ll} (100%) rename test/Assembler/{invalid-mdenumerator-missing-name.ll => invalid-dienumerator-missing-name.ll} (100%) rename test/Assembler/{invalid-mdenumerator-missing-value.ll => invalid-dienumerator-missing-value.ll} (100%) rename test/Assembler/{invalid-mdexpression-large.ll => invalid-diexpression-large.ll} (100%) rename test/Assembler/{invalid-mdexpression-verify.ll => invalid-diexpression-verify.ll} (100%) rename test/Assembler/{invalid-mdfile-missing-directory.ll => invalid-difile-missing-directory.ll} (100%) rename test/Assembler/{invalid-mdfile-missing-filename.ll => invalid-difile-missing-filename.ll} (100%) rename test/Assembler/{invalid-mdglobalvariable-empty-name.ll => invalid-diglobalvariable-empty-name.ll} (100%) rename test/Assembler/{invalid-mdglobalvariable-missing-name.ll => invalid-diglobalvariable-missing-name.ll} (100%) rename test/Assembler/{invalid-mdimportedentity-missing-scope.ll => invalid-diimportedentity-missing-scope.ll} (100%) rename test/Assembler/{invalid-mdimportedentity-missing-tag.ll => invalid-diimportedentity-missing-tag.ll} (100%) rename test/Assembler/{invalid-mdlexicalblock-missing-scope.ll => invalid-dilexicalblock-missing-scope.ll} (100%) rename test/Assembler/{invalid-mdlexicalblock-null-scope.ll => invalid-dilexicalblock-null-scope.ll} (100%) rename test/Assembler/{invalid-mdlexicalblockfile-missing-discriminator.ll => invalid-dilexicalblockfile-missing-discriminator.ll} (100%) rename test/Assembler/{invalid-mdlexicalblockfile-missing-scope.ll => invalid-dilexicalblockfile-missing-scope.ll} (100%) rename test/Assembler/{invalid-mdlexicalblockfile-null-scope.ll => invalid-dilexicalblockfile-null-scope.ll} (100%) create mode 100644 test/Assembler/invalid-dilocalvariable-arg-large.ll create mode 100644 test/Assembler/invalid-dilocalvariable-arg-negative.ll rename test/Assembler/{invalid-mdlocalvariable-missing-scope.ll => invalid-dilocalvariable-missing-scope.ll} (100%) rename test/Assembler/{invalid-mdlocalvariable-missing-tag.ll => invalid-dilocalvariable-missing-tag.ll} (100%) rename test/Assembler/{invalid-mdlocalvariable-null-scope.ll => invalid-dilocalvariable-null-scope.ll} (100%) rename test/Assembler/{invalid-mdlocation-field-bad.ll => invalid-dilocation-field-bad.ll} (100%) rename test/Assembler/{invalid-mdlocation-field-twice.ll => invalid-dilocation-field-twice.ll} (100%) rename test/Assembler/{invalid-mdlocation-missing-scope-2.ll => invalid-dilocation-missing-scope-2.ll} (100%) rename test/Assembler/{invalid-mdlocation-missing-scope.ll => invalid-dilocation-missing-scope.ll} (100%) rename test/Assembler/{invalid-mdlocation-null-scope.ll => invalid-dilocation-null-scope.ll} (100%) rename test/Assembler/{invalid-mdlocation-overflow-column.ll => invalid-dilocation-overflow-column.ll} (100%) rename test/Assembler/{invalid-mdlocation-overflow-line.ll => invalid-dilocation-overflow-line.ll} (100%) rename test/Assembler/{invalid-mdnamespace-missing-namespace.ll => invalid-dinamespace-missing-namespace.ll} (100%) rename test/Assembler/{invalid-mdsubrange-count-large.ll => invalid-disubrange-count-large.ll} (100%) rename test/Assembler/{invalid-mdsubrange-count-missing.ll => invalid-disubrange-count-missing.ll} (100%) rename test/Assembler/{invalid-mdsubrange-count-negative.ll => invalid-disubrange-count-negative.ll} (100%) rename test/Assembler/{invalid-mdsubrange-lowerBound-max.ll => invalid-disubrange-lowerBound-max.ll} (100%) rename test/Assembler/{invalid-mdsubrange-lowerBound-min.ll => invalid-disubrange-lowerBound-min.ll} (100%) rename test/Assembler/{invalid-mdsubroutinetype-missing-types.ll => invalid-disubroutinetype-missing-types.ll} (100%) rename test/Assembler/{invalid-mdtemplatetypeparameter-missing-type.ll => invalid-ditemplatetypeparameter-missing-type.ll} (100%) rename test/Assembler/{invalid-mdtemplatevalueparameter-missing-value.ll => invalid-ditemplatevalueparameter-missing-value.ll} (100%) create mode 100644 test/Bitcode/Inputs/invalid-alias-type-mismatch.bc create mode 100644 test/Bitcode/Inputs/invalid-metadata-not-followed-named-node.bc create mode 100644 test/Bitcode/Inputs/invalid-vector-length.bc create mode 100644 test/CodeGen/AArch64/global-merge-ignore-single-use-minsize.ll create mode 100644 test/CodeGen/AArch64/special-reg.ll create mode 100644 test/CodeGen/ARM/ifcvt-callback.ll create mode 100644 test/CodeGen/ARM/jump-table-islands-split.ll create mode 100644 test/CodeGen/ARM/jump-table-islands.ll create mode 100644 test/CodeGen/ARM/special-reg-acore.ll create mode 100644 test/CodeGen/ARM/special-reg-mcore.ll create mode 100644 test/CodeGen/ARM/special-reg.ll create mode 100644 test/CodeGen/BPF/cc_args_be.ll delete mode 100644 test/CodeGen/Hexagon/calling-conv.ll create mode 100644 test/CodeGen/Hexagon/compound.ll create mode 100644 test/CodeGen/Hexagon/duplex.ll create mode 100644 test/CodeGen/Hexagon/relax.ll create mode 100644 test/CodeGen/MIR/lit.local.cfg create mode 100644 test/CodeGen/MIR/llvm-ir-error-reported.mir create mode 100644 test/CodeGen/MIR/llvmIR.mir create mode 100644 test/CodeGen/MIR/llvmIRMissing.mir create mode 100644 test/CodeGen/MIR/machine-function-missing-name.mir create mode 100644 test/CodeGen/MIR/machine-function.mir create mode 100644 test/CodeGen/Mips/Fast-ISel/bswap1.ll create mode 100644 test/CodeGen/Mips/Fast-ISel/div1.ll create mode 100644 test/CodeGen/Mips/Fast-ISel/memtest1.ll create mode 100644 test/CodeGen/Mips/Fast-ISel/mul1.ll create mode 100644 test/CodeGen/Mips/Fast-ISel/rem1.ll create mode 100644 test/CodeGen/Mips/Fast-ISel/sel1.ll create mode 100644 test/CodeGen/Mips/dynamic-stack-realignment.ll create mode 100644 test/CodeGen/NVPTX/globals_init.ll create mode 100644 test/CodeGen/NVPTX/lower-kernel-ptr-arg.ll create mode 100644 test/CodeGen/PowerPC/vsx-fma-sp.ll create mode 100644 test/CodeGen/R600/cgp-addressing-modes.ll create mode 100644 test/CodeGen/R600/subreg-eliminate-dead.ll create mode 100644 test/CodeGen/R600/trunc-store-f64-to-f16.ll create mode 100644 test/CodeGen/X86/asm-reject-reg-type-mismatch.ll create mode 100644 test/CodeGen/X86/avx512-shuffle.ll create mode 100644 test/CodeGen/X86/pr23603.ll create mode 100644 test/CodeGen/X86/pr23664.ll create mode 100644 test/CodeGen/X86/stack-folding-x86_64.ll create mode 100644 test/CodeGen/X86/statepoint-far-call.ll create mode 100644 test/CodeGen/X86/tailcallpic3.ll create mode 100644 test/CodeGen/X86/vec_shift8.ll delete mode 100644 test/CodeGen/X86/vector-ctpop.ll create mode 100644 test/CodeGen/X86/vector-lzcnt-128.ll create mode 100644 test/CodeGen/X86/vector-lzcnt-256.ll create mode 100644 test/CodeGen/X86/vector-popcnt-128.ll create mode 100644 test/CodeGen/X86/vector-popcnt-256.ll create mode 100644 test/CodeGen/X86/vector-tzcnt-128.ll create mode 100644 test/CodeGen/X86/vector-tzcnt-256.ll create mode 100644 test/CodeGen/X86/win32-eh-states.ll create mode 100755 test/DebugInfo/Inputs/dwarfdump.elf-mips64-64-bit-dwarf create mode 100644 test/DebugInfo/Inputs/invalid.elf create mode 100644 test/DebugInfo/Inputs/invalid.elf.2 create mode 100644 test/DebugInfo/Inputs/invalid.elf.3 create mode 100644 test/DebugInfo/Inputs/test-multiple-macho.o create mode 100644 test/DebugInfo/Inputs/test-simple-macho.o create mode 100644 test/DebugInfo/X86/expressions.ll create mode 100644 test/DebugInfo/X86/inlined-indirect-value.ll create mode 100644 test/DebugInfo/debuglineinfo-macho.test create mode 100644 test/DebugInfo/dwarfdump-64-bit-dwarf.test create mode 100644 test/DebugInfo/dwarfdump-invalid.test create mode 100644 test/ExecutionEngine/RuntimeDyld/Mips/ELF_Mips64r2N64_PIC_relocations.s create mode 100644 test/ExecutionEngine/RuntimeDyld/Mips/ELF_O32_PIC_relocations.s create mode 100644 test/ExecutionEngine/RuntimeDyld/Mips/Inputs/ExternalFunction.ll create mode 100644 test/ExecutionEngine/RuntimeDyld/Mips/lit.local.cfg create mode 100644 test/Instrumentation/AddressSanitizer/do-not-instrument-llvm-metadata-darwin.ll delete mode 100644 test/Instrumentation/AddressSanitizer/undecidable-dynamic-alloca-1.ll create mode 100644 test/Instrumentation/InstrProfiling/PR23499.ll create mode 100644 test/MC/AArch64/armv8.1a-atomic.s create mode 100644 test/MC/AArch64/case-insen-reg-names.s create mode 100644 test/MC/AsmParser/defsym.s create mode 100644 test/MC/AsmParser/defsym_error1.s create mode 100644 test/MC/AsmParser/defsym_error2.s create mode 100644 test/MC/COFF/cross-section-relative.s create mode 100644 test/MC/Disassembler/AArch64/armv8.1a-atomic.txt create mode 100644 test/MC/ELF/common-error3.s create mode 100644 test/MC/ELF/common-redeclare.s create mode 100644 test/MC/ELF/popsection.s create mode 100644 test/MC/Mips/relocation.s create mode 100644 test/MC/Mips/set-softfloat-hardfloat-bad.s create mode 100644 test/MC/Mips/set-softfloat-hardfloat.s create mode 100644 test/MC/PowerPC/st-other-crash.s create mode 100644 test/MC/X86/hex-immediates.s create mode 100644 test/MC/X86/mpx-encodings.s create mode 100644 test/Object/Inputs/macho-invalid-header create mode 100644 test/Object/Inputs/macho64-invalid-incomplete-segment-load-command create mode 100644 test/Object/Inputs/no-start-symbol.elf-x86_64 create mode 100644 test/Object/X86/no-start-symbol.test create mode 100644 test/Transforms/IndVarSimplify/exit_value_test2.ll create mode 100644 test/Transforms/IndVarSimplify/exit_value_test3.ll create mode 100644 test/Transforms/InstCombine/load-bitcast32.ll create mode 100644 test/Transforms/InstCombine/load-bitcast64.ll create mode 100644 test/Transforms/InstCombine/pr23751.ll create mode 100644 test/Transforms/LoopUnroll/full-unroll-bad-cost.ll create mode 100644 test/Transforms/LoopVectorize/interleaved-accesses.ll create mode 100644 test/Transforms/LoopVectorize/zero-sized-pointee-crash.ll create mode 100644 test/Transforms/MergeFunc/linkonce_odr.ll create mode 100644 test/Transforms/RewriteStatepointsForGC/deref-pointers.ll create mode 100644 test/Transforms/SeparateConstOffsetFromGEP/R600/lit.local.cfg create mode 100644 test/Transforms/SeparateConstOffsetFromGEP/R600/split-gep-and-gvn-addrspace-addressing-modes.ll create mode 100644 test/Transforms/Sink/convergent.ll create mode 100644 test/tools/dsymutil/Inputs/frame-dw2.ll create mode 100644 test/tools/dsymutil/Inputs/frame-dw4.ll create mode 100644 test/tools/dsymutil/Inputs/frame.c create mode 100644 test/tools/dsymutil/X86/frame-1.test create mode 100644 test/tools/dsymutil/X86/frame-2.test create mode 100644 test/tools/dsymutil/yaml-object-address-rewrite.test create mode 100644 test/tools/llvm-objdump/invalid-input.test create mode 100644 tools/llvm-dwarfdump/fuzzer/CMakeLists.txt create mode 100644 tools/llvm-dwarfdump/fuzzer/llvm-dwarfdump-fuzzer.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 776f3f6a2e0e..026fe479abd5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,15 +32,23 @@ project(LLVM) set(LLVM_PARALLEL_COMPILE_JOBS "" CACHE STRING "Define the maximum number of concurrent compilation jobs.") if(LLVM_PARALLEL_COMPILE_JOBS) - set_property(GLOBAL APPEND PROPERTY JOB_POOLS compile_job_pool=${LLVM_PARALLEL_COMPILE_JOBS}) - set(CMAKE_JOB_POOL_COMPILE compile_job_pool) + if(CMAKE_VERSION VERSION_LESS 3.0 OR NOT CMAKE_MAKE_PROGRAM MATCHES "ninja$") + message(WARNING "Job pooling is only available with Ninja generators and CMake 3.0 and later.") + else() + set_property(GLOBAL APPEND PROPERTY JOB_POOLS compile_job_pool=${LLVM_PARALLEL_COMPILE_JOBS}) + set(CMAKE_JOB_POOL_COMPILE compile_job_pool) + endif() endif() set(LLVM_PARALLEL_LINK_JOBS "" CACHE STRING "Define the maximum number of concurrent link jobs.") if(LLVM_PARALLEL_LINK_JOBS) - set_property(GLOBAL APPEND PROPERTY JOB_POOLS link_job_pool=${LLVM_PARALLEL_LINK_JOBS}) - set(CMAKE_JOB_POOL_LINK link_job_pool) + if(CMAKE_VERSION VERSION_LESS 3.0 OR NOT CMAKE_MAKE_PROGRAM MATCHES "ninja$") + message(WARNING "Job pooling is only available with Ninja generators and CMake 3.0 and later.") + else() + set_property(GLOBAL APPEND PROPERTY JOB_POOLS link_job_pool=${LLVM_PARALLEL_LINK_JOBS}) + set(CMAKE_JOB_POOL_LINK link_job_pool) + endif() endif() # Add path for custom modules @@ -169,6 +177,7 @@ set(LLVM_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/include) set(LLVM_ALL_TARGETS AArch64 ARM + BPF CppBackend Hexagon Mips diff --git a/autoconf/configure.ac b/autoconf/configure.ac index 586f3f26cb31..390d22e15c2c 100644 --- a/autoconf/configure.ac +++ b/autoconf/configure.ac @@ -1337,6 +1337,13 @@ AC_ARG_WITH(default-sysroot, AC_DEFINE_UNQUOTED(DEFAULT_SYSROOT,"$withval", [Default to all compiler invocations for --sysroot=.]) +AC_ARG_WITH(clang-default-openmp-runtime, + AS_HELP_STRING([--with-clang-default-openmp-runtime], + [The default OpenMP runtime for Clang.]),, + withval="libgomp") +AC_DEFINE_UNQUOTED(CLANG_DEFAULT_OPENMP_RUNTIME,"$withval", + [Default OpenMP runtime used by -fopenmp.]) + dnl Allow linking of LLVM with GPLv3 binutils code. AC_ARG_WITH(binutils-include, AS_HELP_STRING([--with-binutils-include], diff --git a/cmake/modules/AddOCaml.cmake b/cmake/modules/AddOCaml.cmake index c58ac9cb7349..8b33332d07bc 100644 --- a/cmake/modules/AddOCaml.cmake +++ b/cmake/modules/AddOCaml.cmake @@ -149,7 +149,7 @@ function(add_ocaml_library name) "-I" "${LLVM_LIBRARY_DIR}/ocaml/" "-dump" "${bin}/${name}.odoc" ${ocaml_pkgs} ${ocaml_inputs} - DEPENDS ${ocaml_inputs} + DEPENDS ${ocaml_inputs} ${ocaml_outputs} COMMENT "Building OCaml documentation for ${name}" VERBATIM) diff --git a/cmake/modules/TableGen.cmake b/cmake/modules/TableGen.cmake index 97e272b04a5c..85d720e91fd7 100644 --- a/cmake/modules/TableGen.cmake +++ b/cmake/modules/TableGen.cmake @@ -94,7 +94,11 @@ macro(add_tablegen target project) if(LLVM_USE_HOST_TOOLS) if( ${${project}_TABLEGEN} STREQUAL "${target}" ) - set(${project}_TABLEGEN_EXE "${LLVM_NATIVE_BUILD}/bin/${target}") + if (NOT CMAKE_CONFIGURATION_TYPES) + set(${project}_TABLEGEN_EXE "${LLVM_NATIVE_BUILD}/bin/${target}") + else() + set(${project}_TABLEGEN_EXE "${LLVM_NATIVE_BUILD}/Release/bin/${target}") + endif() set(${project}_TABLEGEN_EXE ${${project}_TABLEGEN_EXE} PARENT_SCOPE) add_custom_command(OUTPUT ${${project}_TABLEGEN_EXE} diff --git a/configure b/configure index 37f3d7d95ae6..254f7e0eb852 100755 --- a/configure +++ b/configure @@ -1495,6 +1495,8 @@ Optional Packages: search for headers --with-gcc-toolchain Directory where gcc is installed. --with-default-sysroot Add --sysroot= to all compiler invocations. + --with-clang-default-openmp-runtime + The default OpenMP runtime for Clang. --with-binutils-include Specify path to binutils/include/ containing plugin-api.h file for gold plugin. --with-bug-report-url Specify the URL where bug reports should be @@ -5948,6 +5950,20 @@ _ACEOF +# Check whether --with-clang-default-openmp-runtime was given. +if test "${with_clang_default_openmp_runtime+set}" = set; then + withval=$with_clang_default_openmp_runtime; +else + withval="libgomp" +fi + + +cat >>confdefs.h <<_ACEOF +#define CLANG_DEFAULT_OPENMP_RUNTIME "$withval" +_ACEOF + + + # Check whether --with-binutils-include was given. if test "${with_binutils_include+set}" = set; then withval=$with_binutils_include; diff --git a/docs/CommandGuide/llvm-profdata.rst b/docs/CommandGuide/llvm-profdata.rst index 45f70731d69e..7053b7fa710e 100644 --- a/docs/CommandGuide/llvm-profdata.rst +++ b/docs/CommandGuide/llvm-profdata.rst @@ -49,6 +49,28 @@ OPTIONS Specify the output file name. *Output* cannot be ``-`` as the resulting indexed profile data can't be written to standard output. +.. option:: -instr (default) + + Specify that the input profile is an instrumentation-based profile. + +.. option:: -sample + + Specify that the input profile is a sample-based profile. When using + sample-based profiles, the format of the generated file can be generated + in one of three ways: + + .. option:: -binary (default) + + Emit the profile using a binary encoding. + + .. option:: -text + + Emit the profile in text mode. + + .. option:: -gcc + + Emit the profile using GCC's gcov format (Not yet supported). + .. program:: llvm-profdata show .. _profdata-show: @@ -95,6 +117,14 @@ OPTIONS Specify the output file name. If *output* is ``-`` or it isn't specified, then the output is sent to standard output. +.. option:: -instr (default) + + Specify that the input profile is an instrumentation-based profile. + +.. option:: -sample + + Specify that the input profile is a sample-based profile. + EXIT STATUS ----------- diff --git a/docs/LangRef.rst b/docs/LangRef.rst index 397d5fe37567..0996820f724f 100644 --- a/docs/LangRef.rst +++ b/docs/LangRef.rst @@ -834,6 +834,11 @@ Named metadata is a collection of metadata. :ref:`Metadata nodes ` (but not metadata strings) are the only valid operands for a named metadata. +#. Named metadata are represented as a string of characters with the + metadata prefix. The rules for metadata names are the same as for + identifiers, but quoted names are not allowed. ``"\xx"`` type escapes + are still valid, which allows any character to be part of a name. + Syntax:: ; Some unnamed metadata nodes, which are referenced by the named metadata. diff --git a/docs/Lexicon.rst b/docs/Lexicon.rst index 112eb7d79ec1..912dee2cf079 100644 --- a/docs/Lexicon.rst +++ b/docs/Lexicon.rst @@ -131,6 +131,10 @@ L **LCSSA** Loop-Closed Static Single Assignment Form +**LGTM** + "Looks Good To Me". In a review thread, this indicates that the + reviewer thinks that the patch is okay to commit. + **LICM** Loop Invariant Code Motion diff --git a/docs/NVPTXUsage.rst b/docs/NVPTXUsage.rst index e1c401df877a..fc697ca00461 100644 --- a/docs/NVPTXUsage.rst +++ b/docs/NVPTXUsage.rst @@ -168,10 +168,10 @@ These are overloaded intrinsics. You can use these on any pointer types. .. code-block:: llvm - declare i8* @llvm.nvvm.ptr.gen.to.global.p1i8.p0i8(i8 addrspace(1)*) - declare i8* @llvm.nvvm.ptr.gen.to.shared.p3i8.p0i8(i8 addrspace(3)*) - declare i8* @llvm.nvvm.ptr.gen.to.constant.p4i8.p0i8(i8 addrspace(4)*) - declare i8* @llvm.nvvm.ptr.gen.to.local.p5i8.p0i8(i8 addrspace(5)*) + declare i8 addrspace(1)* @llvm.nvvm.ptr.gen.to.global.p1i8.p0i8(i8*) + declare i8 addrspace(3)* @llvm.nvvm.ptr.gen.to.shared.p3i8.p0i8(i8*) + declare i8 addrspace(4)* @llvm.nvvm.ptr.gen.to.constant.p4i8.p0i8(i8*) + declare i8 addrspace(5)* @llvm.nvvm.ptr.gen.to.local.p5i8.p0i8(i8*) Overview: """"""""" diff --git a/docs/TableGen/LangIntro.rst b/docs/TableGen/LangIntro.rst index 85c74a5b4608..4d4551e8a6e7 100644 --- a/docs/TableGen/LangIntro.rst +++ b/docs/TableGen/LangIntro.rst @@ -190,7 +190,7 @@ supported include: for 'a' in 'c.' This operation is analogous to $(subst) in GNU make. ``!foreach(a, b, c)`` - For each member 'b' of dag or list 'a' apply operator 'c.' 'b' is a dummy + For each member of dag or list 'b' apply operator 'c.' 'a' is a dummy variable that should be declared as a member variable of an instantiated class. This operation is analogous to $(foreach) in GNU make. diff --git a/docs/YamlIO.rst b/docs/YamlIO.rst index aa4bae35d1a4..f0baeb4c69d4 100644 --- a/docs/YamlIO.rst +++ b/docs/YamlIO.rst @@ -798,6 +798,8 @@ add "static const bool flow = true;". For instance: static const bool flow = true; } +Flow mappings are subject to line wrapping according to the Output object +configuration. Sequence ======== @@ -845,6 +847,8 @@ With the above, if you used MyList as the data type in your native data structures, then when converted to YAML, a flow sequence of integers will be used (e.g. [ 10, -3, 4 ]). +Flow sequences are subject to line wrapping according to the Output object +configuration. Utility Macros -------------- @@ -908,14 +912,14 @@ Output The llvm::yaml::Output class is used to generate a YAML document from your in-memory data structures, using traits defined on your data types. -To instantiate an Output object you need an llvm::raw_ostream, and optionally -a context pointer: +To instantiate an Output object you need an llvm::raw_ostream, an optional +context pointer and an optional wrapping column: .. code-block:: c++ class Output : public IO { public: - Output(llvm::raw_ostream &, void *context=NULL); + Output(llvm::raw_ostream &, void *context = NULL, int WrapColumn = 70); Once you have an Output object, you can use the C++ stream operator on it to write your native data as YAML. One thing to recall is that a YAML file @@ -924,6 +928,10 @@ streaming as YAML is a mapping, scalar, or sequence, then Output assumes you are generating one document and wraps the mapping output with "``---``" and trailing "``...``". +The WrapColumn parameter will cause the flow mappings and sequences to +line-wrap when they go over the supplied column. Pass 0 to completely +suppress the wrapping. + .. code-block:: c++ using llvm::yaml::Output; diff --git a/include/llvm-c/Core.h b/include/llvm-c/Core.h index effbd15c10dd..73bff0b7ec49 100644 --- a/include/llvm-c/Core.h +++ b/include/llvm-c/Core.h @@ -997,6 +997,13 @@ unsigned LLVMCountStructElementTypes(LLVMTypeRef StructTy); */ void LLVMGetStructElementTypes(LLVMTypeRef StructTy, LLVMTypeRef *Dest); +/** + * Get the type of the element at a given index in the structure. + * + * @see llvm::StructType::getTypeAtIndex() + */ +LLVMTypeRef LLVMStructGetTypeAtIndex(LLVMTypeRef StructTy, unsigned i); + /** * Determine whether a structure is packed. * diff --git a/include/llvm-c/Support.h b/include/llvm-c/Support.h index a9216d0364ad..eca3b7a42037 100644 --- a/include/llvm-c/Support.h +++ b/include/llvm-c/Support.h @@ -58,6 +58,24 @@ LLVMBool LLVMLoadLibraryPermanently(const char* Filename); void LLVMParseCommandLineOptions(int argc, const char *const *argv, const char *Overview); +/** + * This function will search through all previously loaded dynamic + * libraries for the symbol \p symbolName. If it is found, the address of + * that symbol is returned. If not, null is returned. + * + * @see sys::DynamicLibrary::SearchForAddressOfSymbol() + */ +void *LLVMSearchForAddressOfSymbol(const char *symbolName); + +/** + * This functions permanently adds the symbol \p symbolName with the + * value \p symbolValue. These symbols are searched before any + * libraries. + * + * @see sys::DynamicLibrary::AddSymbol() + */ +void LLVMAddSymbol(const char *symbolName, void *symbolValue); + #ifdef __cplusplus } #endif diff --git a/include/llvm/ADT/APInt.h b/include/llvm/ADT/APInt.h index 36d8159d21ba..e5d143d8ebe1 100644 --- a/include/llvm/ADT/APInt.h +++ b/include/llvm/ADT/APInt.h @@ -351,8 +351,7 @@ class APInt { /// This checks to see if the value of this APInt is the maximum signed /// value for the APInt's bit width. bool isMaxSignedValue() const { - return BitWidth == 1 ? VAL == 0 - : !isNegative() && countPopulation() == BitWidth - 1; + return !isNegative() && countPopulation() == BitWidth - 1; } /// \brief Determine if this is the smallest unsigned value. @@ -366,7 +365,7 @@ class APInt { /// This checks to see if the value of this APInt is the minimum signed /// value for the APInt's bit width. bool isMinSignedValue() const { - return BitWidth == 1 ? VAL == 1 : isNegative() && isPowerOf2(); + return isNegative() && isPowerOf2(); } /// \brief Check if this APInt has an N-bits unsigned integer value. diff --git a/include/llvm/ADT/Triple.h b/include/llvm/ADT/Triple.h index 2416ce342c9b..1362fe37c426 100644 --- a/include/llvm/ADT/Triple.h +++ b/include/llvm/ADT/Triple.h @@ -50,7 +50,8 @@ class Triple { armeb, // ARM (big endian): armeb aarch64, // AArch64 (little endian): aarch64 aarch64_be, // AArch64 (big endian): aarch64_be - bpf, // eBPF or extended BPF or 64-bit BPF (little endian) + bpfel, // eBPF or extended BPF or 64-bit BPF (little endian) + bpfeb, // eBPF or extended BPF or 64-bit BPF (big endian) hexagon, // Hexagon: hexagon mips, // MIPS: mips, mipsallegrex mipsel, // MIPSEL: mipsel, mipsallegrexel @@ -255,6 +256,15 @@ class Triple { /// getEnvironment - Get the parsed environment type of this triple. EnvironmentType getEnvironment() const { return Environment; } + /// \brief Parse the version number from the OS name component of the + /// triple, if present. + /// + /// For example, "fooos1.2.3" would return (1, 2, 3). + /// + /// If an entry is not defined, it will be returned as 0. + void getEnvironmentVersion(unsigned &Major, unsigned &Minor, + unsigned &Micro) const; + /// getFormat - Get the object format for this triple. ObjectFormatType getObjectFormat() const { return ObjectFormat; } diff --git a/include/llvm/Analysis/AliasAnalysis.h b/include/llvm/Analysis/AliasAnalysis.h index ac9d21c590a4..de18e585f11d 100644 --- a/include/llvm/Analysis/AliasAnalysis.h +++ b/include/llvm/Analysis/AliasAnalysis.h @@ -40,6 +40,7 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/IR/CallSite.h" #include "llvm/IR/Metadata.h" +#include "llvm/Analysis/MemoryLocation.h" namespace llvm { @@ -82,7 +83,7 @@ class AliasAnalysis { /// UnknownSize - This is a special value which can be used with the /// size arguments in alias queries to indicate that the caller does not /// know the sizes of the potential memory references. - static uint64_t const UnknownSize = ~UINT64_C(0); + static uint64_t const UnknownSize = MemoryLocation::UnknownSize; /// getTargetLibraryInfo - Return a pointer to the current TargetLibraryInfo /// object, or null if no TargetLibraryInfo object is available. @@ -98,70 +99,9 @@ class AliasAnalysis { /// Alias Queries... /// - /// Location - A description of a memory location. - struct Location { - /// Ptr - The address of the start of the location. - const Value *Ptr; - /// Size - The maximum size of the location, in address-units, or - /// UnknownSize if the size is not known. Note that an unknown size does - /// not mean the pointer aliases the entire virtual address space, because - /// there are restrictions on stepping out of one object and into another. - /// See http://llvm.org/docs/LangRef.html#pointeraliasing - uint64_t Size; - /// AATags - The metadata nodes which describes the aliasing of the - /// location (each member is null if that kind of information is - /// unavailable).. - AAMDNodes AATags; - - explicit Location(const Value *P = nullptr, uint64_t S = UnknownSize, - const AAMDNodes &N = AAMDNodes()) - : Ptr(P), Size(S), AATags(N) {} - - Location getWithNewPtr(const Value *NewPtr) const { - Location Copy(*this); - Copy.Ptr = NewPtr; - return Copy; - } - - Location getWithNewSize(uint64_t NewSize) const { - Location Copy(*this); - Copy.Size = NewSize; - return Copy; - } - - Location getWithoutAATags() const { - Location Copy(*this); - Copy.AATags = AAMDNodes(); - return Copy; - } - - bool operator==(const AliasAnalysis::Location &Other) const { - return Ptr == Other.Ptr && Size == Other.Size && AATags == Other.AATags; - } - }; - - /// getLocation - Fill in Loc with information about the memory reference by - /// the given instruction. - Location getLocation(const LoadInst *LI); - Location getLocation(const StoreInst *SI); - Location getLocation(const VAArgInst *VI); - Location getLocation(const AtomicCmpXchgInst *CXI); - Location getLocation(const AtomicRMWInst *RMWI); - static Location getLocationForSource(const MemTransferInst *MTI); - static Location getLocationForDest(const MemIntrinsic *MI); - Location getLocation(const Instruction *Inst) { - if (auto *I = dyn_cast(Inst)) - return getLocation(I); - else if (auto *I = dyn_cast(Inst)) - return getLocation(I); - else if (auto *I = dyn_cast(Inst)) - return getLocation(I); - else if (auto *I = dyn_cast(Inst)) - return getLocation(I); - else if (auto *I = dyn_cast(Inst)) - return getLocation(I); - llvm_unreachable("unsupported memory instruction"); - } + /// Legacy typedef for the AA location object. New code should use \c + /// MemoryLocation directly. + typedef MemoryLocation Location; /// Alias analysis result - Either we know for sure that it does not alias, we /// know for sure it must alias, or we don't know anything: The two pointers @@ -601,28 +541,6 @@ class AliasAnalysis { } }; -// Specialize DenseMapInfo for Location. -template<> -struct DenseMapInfo { - static inline AliasAnalysis::Location getEmptyKey() { - return AliasAnalysis::Location(DenseMapInfo::getEmptyKey(), - 0); - } - static inline AliasAnalysis::Location getTombstoneKey() { - return AliasAnalysis::Location( - DenseMapInfo::getTombstoneKey(), 0); - } - static unsigned getHashValue(const AliasAnalysis::Location &Val) { - return DenseMapInfo::getHashValue(Val.Ptr) ^ - DenseMapInfo::getHashValue(Val.Size) ^ - DenseMapInfo::getHashValue(Val.AATags); - } - static bool isEqual(const AliasAnalysis::Location &LHS, - const AliasAnalysis::Location &RHS) { - return LHS == RHS; - } -}; - /// isNoAliasCall - Return true if this pointer is returned by a noalias /// function. bool isNoAliasCall(const Value *V); diff --git a/include/llvm/Analysis/BlockFrequencyInfoImpl.h b/include/llvm/Analysis/BlockFrequencyInfoImpl.h index 9acc863a7382..85a299b6dddf 100644 --- a/include/llvm/Analysis/BlockFrequencyInfoImpl.h +++ b/include/llvm/Analysis/BlockFrequencyInfoImpl.h @@ -191,8 +191,8 @@ class BlockFrequencyInfoImplBase { /// \brief Data about a loop. /// - /// Contains the data necessary to represent represent a loop as a - /// pseudo-node once it's packaged. + /// Contains the data necessary to represent a loop as a pseudo-node once it's + /// packaged. struct LoopData { typedef SmallVector, 4> ExitMap; typedef SmallVector NodeList; @@ -930,7 +930,7 @@ void BlockFrequencyInfoImpl::doFunction(const FunctionT *F, initializeRPOT(); initializeLoops(); - // Visit loops in post-order to find thelocal mass distribution, and then do + // Visit loops in post-order to find the local mass distribution, and then do // the full function. computeMassInLoops(); computeMassInFunction(); diff --git a/include/llvm/Analysis/BranchProbabilityInfo.h b/include/llvm/Analysis/BranchProbabilityInfo.h index 89eef68d8431..9d867567ba29 100644 --- a/include/llvm/Analysis/BranchProbabilityInfo.h +++ b/include/llvm/Analysis/BranchProbabilityInfo.h @@ -47,6 +47,9 @@ class BranchProbabilityInfo : public FunctionPass { void getAnalysisUsage(AnalysisUsage &AU) const override; bool runOnFunction(Function &F) override; + + void releaseMemory() override; + void print(raw_ostream &OS, const Module *M = nullptr) const override; /// \brief Get an edge's probability, relative to other out-edges of the Src. diff --git a/include/llvm/Analysis/CallGraph.h b/include/llvm/Analysis/CallGraph.h index 14b88220202a..5b64d857bf71 100644 --- a/include/llvm/Analysis/CallGraph.h +++ b/include/llvm/Analysis/CallGraph.h @@ -230,7 +230,7 @@ class CallGraphNode { void addCalledFunction(CallSite CS, CallGraphNode *M) { assert(!CS.getInstruction() || !CS.getCalledFunction() || !CS.getCalledFunction()->isIntrinsic()); - CalledFunctions.push_back(std::make_pair(CS.getInstruction(), M)); + CalledFunctions.emplace_back(CS.getInstruction(), M); M->AddRef(); } diff --git a/include/llvm/Analysis/DependenceAnalysis.h b/include/llvm/Analysis/DependenceAnalysis.h index 0b3b2ea42813..a08ce574ea56 100644 --- a/include/llvm/Analysis/DependenceAnalysis.h +++ b/include/llvm/Analysis/DependenceAnalysis.h @@ -41,6 +41,7 @@ #define LLVM_ANALYSIS_DEPENDENCEANALYSIS_H #include "llvm/ADT/SmallBitVector.h" +#include "llvm/ADT/ArrayRef.h" #include "llvm/IR/Instructions.h" #include "llvm/Pass.h" @@ -520,11 +521,11 @@ namespace llvm { /// in LoopNest. bool isLoopInvariant(const SCEV *Expression, const Loop *LoopNest) const; - /// Makes sure both subscripts (i.e. Pair->Src and Pair->Dst) share the same - /// integer type by sign-extending one of them when necessary. + /// Makes sure all subscript pairs share the same integer type by + /// sign-extending as necessary. /// Sign-extending a subscript is safe because getelementptr assumes the - /// array subscripts are signed. - void unifySubscriptType(Subscript *Pair); + /// array subscripts are signed. + void unifySubscriptType(ArrayRef Pairs); /// removeMatchingExtensions - Examines a subscript pair. /// If the source and destination are identically sign (or zero) diff --git a/include/llvm/Analysis/LoopAccessAnalysis.h b/include/llvm/Analysis/LoopAccessAnalysis.h index c14e1451f338..7b635a8b4960 100644 --- a/include/llvm/Analysis/LoopAccessAnalysis.h +++ b/include/llvm/Analysis/LoopAccessAnalysis.h @@ -345,6 +345,10 @@ class LoopAccessInfo { /// to needsChecking. bool needsAnyChecking(const SmallVectorImpl *PtrPartition) const; + /// \brief Returns the number of run-time checks required according to + /// needsChecking. + unsigned getNumberOfChecks(const SmallVectorImpl *PtrPartition) const; + /// \brief Print the list run-time memory checks necessary. /// /// If \p PtrPartition is set, it contains the partition number for @@ -385,7 +389,10 @@ class LoopAccessInfo { /// \brief Number of memchecks required to prove independence of otherwise /// may-alias pointers. - unsigned getNumRuntimePointerChecks() const { return NumComparisons; } + unsigned getNumRuntimePointerChecks( + const SmallVectorImpl *PtrPartition = nullptr) const { + return PtrRtCheck.getNumberOfChecks(PtrPartition); + } /// Return true if the block BB needs to be predicated in order for the loop /// to be vectorized. @@ -460,10 +467,6 @@ class LoopAccessInfo { /// loop-independent and loop-carried dependences between memory accesses. MemoryDepChecker DepChecker; - /// \brief Number of memchecks required to prove independence of otherwise - /// may-alias pointers - unsigned NumComparisons; - Loop *TheLoop; ScalarEvolution *SE; const DataLayout &DL; @@ -501,6 +504,11 @@ const SCEV *replaceSymbolicStrideSCEV(ScalarEvolution *SE, const ValueToValueMap &PtrToStride, Value *Ptr, Value *OrigPtr = nullptr); +/// \brief Check the stride of the pointer and ensure that it does not wrap in +/// the address space. +int isStridedPtr(ScalarEvolution *SE, Value *Ptr, const Loop *Lp, + const ValueToValueMap &StridesMap); + /// \brief This analysis provides dependence information for the memory accesses /// of a loop. /// diff --git a/include/llvm/Analysis/LoopInfo.h b/include/llvm/Analysis/LoopInfo.h index be78c15e7224..bbcde8d9721a 100644 --- a/include/llvm/Analysis/LoopInfo.h +++ b/include/llvm/Analysis/LoopInfo.h @@ -47,13 +47,6 @@ namespace llvm { template class AnalysisManager; class PreservedAnalyses; -template -inline void RemoveFromVector(std::vector &V, T *N) { - typename std::vector::iterator I = std::find(V.begin(), V.end(), N); - assert(I != V.end() && "N is not in this list!"); - V.erase(I); -} - class DominatorTree; class LoopInfo; class Loop; @@ -324,7 +317,10 @@ class LoopBase { /// current loop, updating the Blocks as appropriate. This does not update /// the mapping in the LoopInfo class. void removeBlockFromLoop(BlockT *BB) { - RemoveFromVector(Blocks, BB); + auto I = std::find(Blocks.begin(), Blocks.end(), BB); + assert(I != Blocks.end() && "N is not in this list!"); + Blocks.erase(I); + DenseBlockSet.erase(BB); } @@ -493,7 +489,7 @@ class Loop : public LoopBase { template class LoopInfoBase { // BBMap - Mapping of basic blocks to the inner most loop they occur in - DenseMap BBMap; + DenseMap BBMap; std::vector TopLevelLoops; friend class LoopBase; friend class LoopInfo; @@ -543,9 +539,7 @@ class LoopInfoBase { /// getLoopFor - Return the inner most loop that BB lives in. If a basic /// block is in no loop (for example the entry node), null is returned. /// - LoopT *getLoopFor(const BlockT *BB) const { - return BBMap.lookup(const_cast(BB)); - } + LoopT *getLoopFor(const BlockT *BB) const { return BBMap.lookup(BB); } /// operator[] - same as getLoopFor... /// @@ -562,7 +556,7 @@ class LoopInfoBase { } // isLoopHeader - True if the block is a loop header node - bool isLoopHeader(BlockT *BB) const { + bool isLoopHeader(const BlockT *BB) const { const LoopT *L = getLoopFor(BB); return L && L->getHeader() == BB; } @@ -729,12 +723,6 @@ class LoopAnalysis { /// \brief Provide a name for the analysis for debugging and logging. static StringRef name() { return "LoopAnalysis"; } - LoopAnalysis() {} - LoopAnalysis(const LoopAnalysis &Arg) {} - LoopAnalysis(LoopAnalysis &&Arg) {} - LoopAnalysis &operator=(const LoopAnalysis &RHS) { return *this; } - LoopAnalysis &operator=(LoopAnalysis &&RHS) { return *this; } - LoopInfo run(Function &F, AnalysisManager *AM); }; diff --git a/include/llvm/Analysis/LoopInfoImpl.h b/include/llvm/Analysis/LoopInfoImpl.h index 0490bb1d761a..f5cc856f6247 100644 --- a/include/llvm/Analysis/LoopInfoImpl.h +++ b/include/llvm/Analysis/LoopInfoImpl.h @@ -527,7 +527,7 @@ void LoopInfoBase::verify() const { // Verify that blocks are mapped to valid loops. #ifndef NDEBUG for (auto &Entry : BBMap) { - BlockT *BB = Entry.first; + const BlockT *BB = Entry.first; LoopT *L = Entry.second; assert(Loops.count(L) && "orphaned loop"); assert(L->contains(BB) && "orphaned block"); diff --git a/include/llvm/Analysis/MemoryLocation.h b/include/llvm/Analysis/MemoryLocation.h new file mode 100644 index 000000000000..94d938dc491f --- /dev/null +++ b/include/llvm/Analysis/MemoryLocation.h @@ -0,0 +1,137 @@ +//===- MemoryLocation.h - Memory location descriptions ----------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// \file +/// This file provides utility analysis objects describing memory locations. +/// These are used both by the Alias Analysis infrastructure and more +/// specialized memory analysis layers. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ANALYSIS_MEMORYLOCATION_H +#define LLVM_ANALYSIS_MEMORYLOCATION_H + +#include "llvm/ADT/DenseMap.h" +#include "llvm/IR/CallSite.h" +#include "llvm/IR/Metadata.h" + +namespace llvm { + +class LoadInst; +class StoreInst; +class MemTransferInst; +class MemIntrinsic; + +/// Representation for a specific memory location. +/// +/// This abstraction can be used to represent a specific location in memory. +/// The goal of the location is to represent enough information to describe +/// abstract aliasing, modification, and reference behaviors of whatever +/// value(s) are stored in memory at the particular location. +/// +/// The primary user of this interface is LLVM's Alias Analysis, but other +/// memory analyses such as MemoryDependence can use it as well. +class MemoryLocation { +public: + /// UnknownSize - This is a special value which can be used with the + /// size arguments in alias queries to indicate that the caller does not + /// know the sizes of the potential memory references. + enum : uint64_t { UnknownSize = ~UINT64_C(0) }; + + /// The address of the start of the location. + const Value *Ptr; + + /// The maximum size of the location, in address-units, or + /// UnknownSize if the size is not known. + /// + /// Note that an unknown size does not mean the pointer aliases the entire + /// virtual address space, because there are restrictions on stepping out of + /// one object and into another. See + /// http://llvm.org/docs/LangRef.html#pointeraliasing + uint64_t Size; + + /// The metadata nodes which describes the aliasing of the location (each + /// member is null if that kind of information is unavailable). + AAMDNodes AATags; + + /// Return a location with information about the memory reference by the given + /// instruction. + static MemoryLocation get(const LoadInst *LI); + static MemoryLocation get(const StoreInst *SI); + static MemoryLocation get(const VAArgInst *VI); + static MemoryLocation get(const AtomicCmpXchgInst *CXI); + static MemoryLocation get(const AtomicRMWInst *RMWI); + static MemoryLocation get(const Instruction *Inst) { + if (auto *I = dyn_cast(Inst)) + return get(I); + else if (auto *I = dyn_cast(Inst)) + return get(I); + else if (auto *I = dyn_cast(Inst)) + return get(I); + else if (auto *I = dyn_cast(Inst)) + return get(I); + else if (auto *I = dyn_cast(Inst)) + return get(I); + llvm_unreachable("unsupported memory instruction"); + } + + /// Return a location representing the source of a memory transfer. + static MemoryLocation getForSource(const MemTransferInst *MTI); + + /// Return a location representing the destination of a memory set or + /// transfer. + static MemoryLocation getForDest(const MemIntrinsic *MI); + + explicit MemoryLocation(const Value *Ptr = nullptr, + uint64_t Size = UnknownSize, + const AAMDNodes &AATags = AAMDNodes()) + : Ptr(Ptr), Size(Size), AATags(AATags) {} + + MemoryLocation getWithNewPtr(const Value *NewPtr) const { + MemoryLocation Copy(*this); + Copy.Ptr = NewPtr; + return Copy; + } + + MemoryLocation getWithNewSize(uint64_t NewSize) const { + MemoryLocation Copy(*this); + Copy.Size = NewSize; + return Copy; + } + + MemoryLocation getWithoutAATags() const { + MemoryLocation Copy(*this); + Copy.AATags = AAMDNodes(); + return Copy; + } + + bool operator==(const MemoryLocation &Other) const { + return Ptr == Other.Ptr && Size == Other.Size && AATags == Other.AATags; + } +}; + +// Specialize DenseMapInfo for MemoryLocation. +template <> struct DenseMapInfo { + static inline MemoryLocation getEmptyKey() { + return MemoryLocation(DenseMapInfo::getEmptyKey(), 0); + } + static inline MemoryLocation getTombstoneKey() { + return MemoryLocation(DenseMapInfo::getTombstoneKey(), 0); + } + static unsigned getHashValue(const MemoryLocation &Val) { + return DenseMapInfo::getHashValue(Val.Ptr) ^ + DenseMapInfo::getHashValue(Val.Size) ^ + DenseMapInfo::getHashValue(Val.AATags); + } + static bool isEqual(const MemoryLocation &LHS, const MemoryLocation &RHS) { + return LHS == RHS; + } +}; +} + +#endif diff --git a/include/llvm/Analysis/PHITransAddr.h b/include/llvm/Analysis/PHITransAddr.h index 84bb9d8008b5..cbdbb88f7407 100644 --- a/include/llvm/Analysis/PHITransAddr.h +++ b/include/llvm/Analysis/PHITransAddr.h @@ -75,12 +75,12 @@ class PHITransAddr { bool IsPotentiallyPHITranslatable() const; /// 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 PHITranslateValue(BasicBlock *CurBB, BasicBlock *PredBB, - const DominatorTree *DT); - + const DominatorTree *DT, bool MustDominate); + /// PHITranslateWithInsertion - PHI translate this value into the specified /// predecessor block, inserting a computation of the value if it is /// unavailable. diff --git a/include/llvm/Analysis/TargetTransformInfo.h b/include/llvm/Analysis/TargetTransformInfo.h index 86bf1549dc78..3700c9e4ac22 100644 --- a/include/llvm/Analysis/TargetTransformInfo.h +++ b/include/llvm/Analysis/TargetTransformInfo.h @@ -221,19 +221,21 @@ class TargetTransformInfo { /// Parameters that control the generic loop unrolling transformation. struct UnrollingPreferences { - /// The cost threshold for the unrolled loop, compared to - /// CodeMetrics.NumInsts aggregated over all basic blocks in the loop body. - /// The unrolling factor is set such that the unrolled loop body does not - /// exceed this cost. Set this to UINT_MAX to disable the loop body cost + /// The cost threshold for the unrolled loop. Should be relative to the + /// getUserCost values returned by this API, and the expectation is that + /// the unrolled loop's instructions when run through that interface should + /// not exceed this cost. However, this is only an estimate. Also, specific + /// loops may be unrolled even with a cost above this threshold if deemed + /// profitable. Set this to UINT_MAX to disable the loop body cost /// restriction. unsigned Threshold; - /// If complete unrolling could help other optimizations (e.g. InstSimplify) - /// to remove N% of instructions, then we can go beyond unroll threshold. - /// This value set the minimal percent for allowing that. - unsigned MinPercentOfOptimized; - /// The absolute cost threshold. We won't go beyond this even if complete - /// unrolling could result in optimizing out 90% of instructions. - unsigned AbsoluteThreshold; + /// If complete unrolling will reduce the cost of the loop below its + /// expected dynamic cost while rolled by this percentage, apply a discount + /// (below) to its unrolled cost. + unsigned PercentDynamicCostSavedThreshold; + /// The discount applied to the unrolled cost when the *dynamic* cost + /// savings of unrolling exceed the \c PercentDynamicCostSavedThreshold. + unsigned DynamicCostSavingsDiscount; /// The cost threshold for the unrolled loop when optimizing for size (set /// to UINT_MAX to disable). unsigned OptSizeThreshold; @@ -303,7 +305,8 @@ class TargetTransformInfo { /// mode is legal for a load/store of any legal type. /// TODO: Handle pre/postinc as well. bool isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset, - bool HasBaseReg, int64_t Scale) const; + bool HasBaseReg, int64_t Scale, + unsigned AddrSpace = 0) const; /// \brief Return true if the target works with masked instruction /// AVX2 allows masks for consecutive load and store for i32 and i64 elements. @@ -319,7 +322,8 @@ class TargetTransformInfo { /// If the AM is not supported, it returns a negative value. /// TODO: Handle pre/postinc as well. int getScalingFactorCost(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset, - bool HasBaseReg, int64_t Scale) const; + bool HasBaseReg, int64_t Scale, + unsigned AddrSpace = 0) const; /// \brief Return true if it's free to truncate a value of type Ty1 to type /// Ty2. e.g. On x86 it's free to truncate a i32 value in register EAX to i16 @@ -444,6 +448,20 @@ class TargetTransformInfo { unsigned getMaskedMemoryOpCost(unsigned Opcode, Type *Src, unsigned Alignment, unsigned AddressSpace) const; + /// \return The cost of the interleaved memory operation. + /// \p Opcode is the memory operation code + /// \p VecTy is the vector type of the interleaved access. + /// \p Factor is the interleave factor + /// \p Indices is the indices for interleaved load members (as interleaved + /// load allows gaps) + /// \p Alignment is the alignment of the memory operation + /// \p AddressSpace is address space of the pointer. + unsigned getInterleavedMemoryOpCost(unsigned Opcode, Type *VecTy, + unsigned Factor, + ArrayRef Indices, + unsigned Alignment, + unsigned AddressSpace) const; + /// \brief Calculate the cost of performing a vector reduction. /// /// This is the cost of reducing the vector value of type \p Ty to a scalar @@ -539,12 +557,13 @@ class TargetTransformInfo::Concept { virtual bool isLegalICmpImmediate(int64_t Imm) = 0; virtual bool isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset, bool HasBaseReg, - int64_t Scale) = 0; + int64_t Scale, + unsigned AddrSpace) = 0; virtual bool isLegalMaskedStore(Type *DataType, int Consecutive) = 0; virtual bool isLegalMaskedLoad(Type *DataType, int Consecutive) = 0; virtual int getScalingFactorCost(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset, bool HasBaseReg, - int64_t Scale) = 0; + int64_t Scale, unsigned AddrSpace) = 0; virtual bool isTruncateFree(Type *Ty1, Type *Ty2) = 0; virtual bool isProfitableToHoist(Instruction *I) = 0; virtual bool isTypeLegal(Type *Ty) = 0; @@ -582,6 +601,11 @@ class TargetTransformInfo::Concept { virtual unsigned getMaskedMemoryOpCost(unsigned Opcode, Type *Src, unsigned Alignment, unsigned AddressSpace) = 0; + virtual unsigned getInterleavedMemoryOpCost(unsigned Opcode, Type *VecTy, + unsigned Factor, + ArrayRef Indices, + unsigned Alignment, + unsigned AddressSpace) = 0; virtual unsigned getReductionCost(unsigned Opcode, Type *Ty, bool IsPairwiseForm) = 0; virtual unsigned getIntrinsicInstrCost(Intrinsic::ID ID, Type *RetTy, @@ -648,9 +672,10 @@ class TargetTransformInfo::Model final : public TargetTransformInfo::Concept { return Impl.isLegalICmpImmediate(Imm); } bool isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset, - bool HasBaseReg, int64_t Scale) override { + bool HasBaseReg, int64_t Scale, + unsigned AddrSpace) override { return Impl.isLegalAddressingMode(Ty, BaseGV, BaseOffset, HasBaseReg, - Scale); + Scale, AddrSpace); } bool isLegalMaskedStore(Type *DataType, int Consecutive) override { return Impl.isLegalMaskedStore(DataType, Consecutive); @@ -659,8 +684,10 @@ class TargetTransformInfo::Model final : public TargetTransformInfo::Concept { return Impl.isLegalMaskedLoad(DataType, Consecutive); } int getScalingFactorCost(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset, - bool HasBaseReg, int64_t Scale) override { - return Impl.getScalingFactorCost(Ty, BaseGV, BaseOffset, HasBaseReg, Scale); + bool HasBaseReg, int64_t Scale, + unsigned AddrSpace) override { + return Impl.getScalingFactorCost(Ty, BaseGV, BaseOffset, HasBaseReg, + Scale, AddrSpace); } bool isTruncateFree(Type *Ty1, Type *Ty2) override { return Impl.isTruncateFree(Ty1, Ty2); @@ -740,6 +767,14 @@ class TargetTransformInfo::Model final : public TargetTransformInfo::Concept { unsigned AddressSpace) override { return Impl.getMaskedMemoryOpCost(Opcode, Src, Alignment, AddressSpace); } + unsigned getInterleavedMemoryOpCost(unsigned Opcode, Type *VecTy, + unsigned Factor, + ArrayRef Indices, + unsigned Alignment, + unsigned AddressSpace) override { + return Impl.getInterleavedMemoryOpCost(Opcode, VecTy, Factor, Indices, + Alignment, AddressSpace); + } unsigned getReductionCost(unsigned Opcode, Type *Ty, bool IsPairwiseForm) override { return Impl.getReductionCost(Opcode, Ty, IsPairwiseForm); diff --git a/include/llvm/Analysis/TargetTransformInfoImpl.h b/include/llvm/Analysis/TargetTransformInfoImpl.h index 253319ccd441..e6a8a7690820 100644 --- a/include/llvm/Analysis/TargetTransformInfoImpl.h +++ b/include/llvm/Analysis/TargetTransformInfoImpl.h @@ -207,7 +207,8 @@ class TargetTransformInfoImplBase { bool isLegalICmpImmediate(int64_t Imm) { return false; } bool isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset, - bool HasBaseReg, int64_t Scale) { + bool HasBaseReg, int64_t Scale, + unsigned AddrSpace) { // Guess that only reg and reg+reg addressing is allowed. This heuristic is // taken from the implementation of LSR. return !BaseGV && BaseOffset == 0 && (Scale == 0 || Scale == 1); @@ -218,9 +219,10 @@ class TargetTransformInfoImplBase { bool isLegalMaskedLoad(Type *DataType, int Consecutive) { return false; } int getScalingFactorCost(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset, - bool HasBaseReg, int64_t Scale) { + bool HasBaseReg, int64_t Scale, unsigned AddrSpace) { // Guess that all legal addressing mode are free. - if (isLegalAddressingMode(Ty, BaseGV, BaseOffset, HasBaseReg, Scale)) + if (isLegalAddressingMode(Ty, BaseGV, BaseOffset, HasBaseReg, + Scale, AddrSpace)) return 0; return -1; } @@ -300,6 +302,14 @@ class TargetTransformInfoImplBase { return 1; } + unsigned getInterleavedMemoryOpCost(unsigned Opcode, Type *VecTy, + unsigned Factor, + ArrayRef Indices, + unsigned Alignment, + unsigned AddressSpace) { + return 1; + } + unsigned getIntrinsicInstrCost(Intrinsic::ID ID, Type *RetTy, ArrayRef Tys) { return 1; diff --git a/include/llvm/Bitcode/BitstreamReader.h b/include/llvm/Bitcode/BitstreamReader.h index 46e64d112ea7..4c040a7f3e22 100644 --- a/include/llvm/Bitcode/BitstreamReader.h +++ b/include/llvm/Bitcode/BitstreamReader.h @@ -113,7 +113,7 @@ class BitstreamReader { return *const_cast(BI); // Otherwise, add a new record. - BlockInfoRecords.push_back(BlockInfo()); + BlockInfoRecords.emplace_back(); BlockInfoRecords.back().BlockID = BlockID; return BlockInfoRecords.back(); } diff --git a/include/llvm/Bitcode/BitstreamWriter.h b/include/llvm/Bitcode/BitstreamWriter.h index 9e2c2fa4a156..f7487a05bdb7 100644 --- a/include/llvm/Bitcode/BitstreamWriter.h +++ b/include/llvm/Bitcode/BitstreamWriter.h @@ -215,7 +215,7 @@ class BitstreamWriter { // Push the outer block's abbrev set onto the stack, start out with an // empty abbrev set. - BlockScope.push_back(Block(OldCodeSize, BlockSizeWordIndex)); + BlockScope.emplace_back(OldCodeSize, BlockSizeWordIndex); BlockScope.back().PrevAbbrevs.swap(CurAbbrevs); // If there is a blockinfo for this BlockID, add all the predefined abbrevs @@ -503,7 +503,7 @@ class BitstreamWriter { return *BI; // Otherwise, add a new record. - BlockInfoRecords.push_back(BlockInfo()); + BlockInfoRecords.emplace_back(); BlockInfoRecords.back().BlockID = BlockID; return BlockInfoRecords.back(); } diff --git a/include/llvm/CodeGen/BasicTTIImpl.h b/include/llvm/CodeGen/BasicTTIImpl.h index d07265560430..3e464f4f1e5a 100644 --- a/include/llvm/CodeGen/BasicTTIImpl.h +++ b/include/llvm/CodeGen/BasicTTIImpl.h @@ -125,23 +125,24 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase { } bool isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset, - bool HasBaseReg, int64_t Scale) { + bool HasBaseReg, int64_t Scale, + unsigned AddrSpace) { TargetLoweringBase::AddrMode AM; AM.BaseGV = BaseGV; AM.BaseOffs = BaseOffset; AM.HasBaseReg = HasBaseReg; AM.Scale = Scale; - return getTLI()->isLegalAddressingMode(AM, Ty); + return getTLI()->isLegalAddressingMode(AM, Ty, AddrSpace); } int getScalingFactorCost(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset, - bool HasBaseReg, int64_t Scale) { + bool HasBaseReg, int64_t Scale, unsigned AddrSpace) { TargetLoweringBase::AddrMode AM; AM.BaseGV = BaseGV; AM.BaseOffs = BaseOffset; AM.HasBaseReg = HasBaseReg; AM.Scale = Scale; - return getTLI()->getScalingFactorCost(AM, Ty); + return getTLI()->getScalingFactorCost(AM, Ty, AddrSpace); } bool isTruncateFree(Type *Ty1, Type *Ty2) { @@ -522,6 +523,73 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase { return Cost; } + unsigned getInterleavedMemoryOpCost(unsigned Opcode, Type *VecTy, + unsigned Factor, + ArrayRef Indices, + unsigned Alignment, + unsigned AddressSpace) { + VectorType *VT = dyn_cast(VecTy); + assert(VT && "Expect a vector type for interleaved memory op"); + + unsigned NumElts = VT->getNumElements(); + assert(Factor > 1 && NumElts % Factor == 0 && "Invalid interleave factor"); + + unsigned NumSubElts = NumElts / Factor; + VectorType *SubVT = VectorType::get(VT->getElementType(), NumSubElts); + + // Firstly, the cost of load/store operation. + unsigned Cost = getMemoryOpCost(Opcode, VecTy, Alignment, AddressSpace); + + // Then plus the cost of interleave operation. + if (Opcode == Instruction::Load) { + // The interleave cost is similar to extract sub vectors' elements + // from the wide vector, and insert them into sub vectors. + // + // E.g. An interleaved load of factor 2 (with one member of index 0): + // %vec = load <8 x i32>, <8 x i32>* %ptr + // %v0 = shuffle %vec, undef, <0, 2, 4, 6> ; Index 0 + // The cost is estimated as extract elements at 0, 2, 4, 6 from the + // <8 x i32> vector and insert them into a <4 x i32> vector. + + assert(Indices.size() <= Factor && + "Interleaved memory op has too many members"); + for (unsigned Index : Indices) { + assert(Index < Factor && "Invalid index for interleaved memory op"); + + // Extract elements from loaded vector for each sub vector. + for (unsigned i = 0; i < NumSubElts; i++) + Cost += getVectorInstrCost(Instruction::ExtractElement, VT, + Index + i * Factor); + } + + unsigned InsSubCost = 0; + for (unsigned i = 0; i < NumSubElts; i++) + InsSubCost += getVectorInstrCost(Instruction::InsertElement, SubVT, i); + + Cost += Indices.size() * InsSubCost; + } else { + // The interleave cost is extract all elements from sub vectors, and + // insert them into the wide vector. + // + // E.g. An interleaved store of factor 2: + // %v0_v1 = shuffle %v0, %v1, <0, 4, 1, 5, 2, 6, 3, 7> + // store <8 x i32> %interleaved.vec, <8 x i32>* %ptr + // The cost is estimated as extract all elements from both <4 x i32> + // vectors and insert into the <8 x i32> vector. + + unsigned ExtSubCost = 0; + for (unsigned i = 0; i < NumSubElts; i++) + ExtSubCost += getVectorInstrCost(Instruction::ExtractElement, SubVT, i); + + Cost += Factor * ExtSubCost; + + for (unsigned i = 0; i < NumElts; i++) + Cost += getVectorInstrCost(Instruction::InsertElement, VT, i); + } + + return Cost; + } + unsigned getIntrinsicInstrCost(Intrinsic::ID IID, Type *RetTy, ArrayRef Tys) { unsigned ISD = 0; diff --git a/include/llvm/CodeGen/CommandFlags.h b/include/llvm/CodeGen/CommandFlags.h index a1b9b4e566a2..b824df3013d9 100644 --- a/include/llvm/CodeGen/CommandFlags.h +++ b/include/llvm/CodeGen/CommandFlags.h @@ -24,6 +24,7 @@ #include "llvm/Support/Host.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetOptions.h" +#include "llvm/Target/TargetRecip.h" #include using namespace llvm; @@ -152,6 +153,12 @@ FuseFPOps("fp-contract", "Only fuse FP ops when the result won't be effected."), clEnumValEnd)); +cl::list +ReciprocalOps("recip", + cl::CommaSeparated, + cl::desc("Choose reciprocal operation types and parameters."), + cl::value_desc("all,none,default,divf,!vec-sqrtd,vec-divd:0,sqrt:9...")); + cl::opt DontPlaceZerosInBSS("nozero-initialized-in-bss", cl::desc("Don't place zero-initialized symbols into bss section"), @@ -230,6 +237,7 @@ static inline TargetOptions InitTargetOptionsFromCodeGenFlags() { TargetOptions Options; Options.LessPreciseFPMADOption = EnableFPMAD; Options.AllowFPOpFusion = FuseFPOps; + Options.Reciprocals = TargetRecip(ReciprocalOps); Options.UnsafeFPMath = EnableUnsafeFPMath; Options.NoInfsFPMath = EnableNoInfsFPMath; Options.NoNaNsFPMath = EnableNoNaNsFPMath; diff --git a/include/llvm/CodeGen/DIE.h b/include/llvm/CodeGen/DIE.h index 8e40ef77d374..464e0faa0ed3 100644 --- a/include/llvm/CodeGen/DIE.h +++ b/include/llvm/CodeGen/DIE.h @@ -104,154 +104,14 @@ class DIEAbbrev : public FoldingSetNode { #endif }; -//===--------------------------------------------------------------------===// -/// DIE - A structured debug information entry. Has an abbreviation which -/// describes its organization. -class DIEValue; - -class DIE { -protected: - /// Offset - Offset in debug info section. - /// - unsigned Offset; - - /// Size - Size of instance + children. - /// - unsigned Size; - - /// Abbrev - Buffer for constructing abbreviation. - /// - DIEAbbrev Abbrev; - - /// Children DIEs. - /// - // This can't be a vector because pointer validity is requirent for the - // Parent pointer and DIEEntry. - // It can't be a list because some clients need pointer validity before - // the object has been added to any child list - // (eg: DwarfUnit::constructVariableDIE). These aren't insurmountable, but may - // be more convoluted than beneficial. - std::vector> Children; - - DIE *Parent; - - /// Attribute values. - /// - SmallVector Values; - -protected: - DIE() - : Offset(0), Size(0), Abbrev((dwarf::Tag)0, dwarf::DW_CHILDREN_no), - Parent(nullptr) {} - -public: - explicit DIE(dwarf::Tag Tag) - : Offset(0), Size(0), Abbrev((dwarf::Tag)Tag, dwarf::DW_CHILDREN_no), - Parent(nullptr) {} - - // Accessors. - DIEAbbrev &getAbbrev() { return Abbrev; } - const DIEAbbrev &getAbbrev() const { return Abbrev; } - unsigned getAbbrevNumber() const { return Abbrev.getNumber(); } - dwarf::Tag getTag() const { return Abbrev.getTag(); } - unsigned getOffset() const { return Offset; } - unsigned getSize() const { return Size; } - const std::vector> &getChildren() const { - return Children; - } - const SmallVectorImpl &getValues() const { return Values; } - DIE *getParent() const { return Parent; } - /// Climb up the parent chain to get the compile or type unit DIE this DIE - /// belongs to. - const DIE *getUnit() const; - /// Similar to getUnit, returns null when DIE is not added to an - /// owner yet. - const DIE *getUnitOrNull() const; - void setOffset(unsigned O) { Offset = O; } - void setSize(unsigned S) { Size = S; } - - /// addValue - Add a value and attributes to a DIE. - /// - void addValue(dwarf::Attribute Attribute, dwarf::Form Form, DIEValue *Value) { - Abbrev.AddAttribute(Attribute, Form); - Values.push_back(Value); - } - - /// addChild - Add a child to the DIE. - /// - void addChild(std::unique_ptr Child) { - assert(!Child->getParent()); - Abbrev.setChildrenFlag(dwarf::DW_CHILDREN_yes); - Child->Parent = this; - Children.push_back(std::move(Child)); - } - - /// findAttribute - Find a value in the DIE with the attribute given, - /// returns NULL if no such attribute exists. - DIEValue *findAttribute(dwarf::Attribute Attribute) const; - -#ifndef NDEBUG - void print(raw_ostream &O, unsigned IndentCount = 0) const; - void dump(); -#endif -}; - -//===--------------------------------------------------------------------===// -/// DIEValue - A debug information entry value. Some of these roughly correlate -/// to DWARF attribute classes. -/// -class DIEValue { -public: - enum Type { - isInteger, - isString, - isExpr, - isLabel, - isDelta, - isEntry, - isTypeSignature, - isBlock, - isLoc, - isLocList, - }; - -private: - /// Ty - Type of data stored in the value. - /// - Type Ty; - -protected: - explicit DIEValue(Type T) : Ty(T) {} - ~DIEValue() {} - -public: - // Accessors - Type getType() const { return Ty; } - - /// EmitValue - Emit value via the Dwarf writer. - /// - void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const; - - /// SizeOf - Return the size of a value in bytes. - /// - unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const; - -#ifndef NDEBUG - void print(raw_ostream &O) const; - void dump() const; -#endif -}; - //===--------------------------------------------------------------------===// /// DIEInteger - An integer value DIE. /// -class DIEInteger : public DIEValue { - friend DIEValue; - +class DIEInteger { uint64_t Integer; public: - explicit DIEInteger(uint64_t I) : DIEValue(isInteger), Integer(I) {} + explicit DIEInteger(uint64_t I) : Integer(I) {} /// BestForm - Choose the best form for integer. /// @@ -278,120 +138,91 @@ class DIEInteger : public DIEValue { uint64_t getValue() const { return Integer; } void setValue(uint64_t Val) { Integer = Val; } - // Implement isa/cast/dyncast. - static bool classof(const DIEValue *I) { return I->getType() == isInteger; } - -private: - void EmitValueImpl(const AsmPrinter *AP, dwarf::Form Form) const; - unsigned SizeOfImpl(const AsmPrinter *AP, dwarf::Form Form) const; + void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const; + unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const; #ifndef NDEBUG - void printImpl(raw_ostream &O) const; + void print(raw_ostream &O) const; #endif }; //===--------------------------------------------------------------------===// /// DIEExpr - An expression DIE. // -class DIEExpr : public DIEValue { - friend class DIEValue; - +class DIEExpr { const MCExpr *Expr; public: - explicit DIEExpr(const MCExpr *E) : DIEValue(isExpr), Expr(E) {} + explicit DIEExpr(const MCExpr *E) : Expr(E) {} /// getValue - Get MCExpr. /// const MCExpr *getValue() const { return Expr; } - // Implement isa/cast/dyncast. - static bool classof(const DIEValue *E) { return E->getType() == isExpr; } - -private: - void EmitValueImpl(const AsmPrinter *AP, dwarf::Form Form) const; - unsigned SizeOfImpl(const AsmPrinter *AP, dwarf::Form Form) const; + void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const; + unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const; #ifndef NDEBUG - void printImpl(raw_ostream &O) const; + void print(raw_ostream &O) const; #endif }; //===--------------------------------------------------------------------===// /// DIELabel - A label DIE. // -class DIELabel : public DIEValue { - friend class DIEValue; - +class DIELabel { const MCSymbol *Label; public: - explicit DIELabel(const MCSymbol *L) : DIEValue(isLabel), Label(L) {} + explicit DIELabel(const MCSymbol *L) : Label(L) {} /// getValue - Get MCSymbol. /// const MCSymbol *getValue() const { return Label; } - // Implement isa/cast/dyncast. - static bool classof(const DIEValue *L) { return L->getType() == isLabel; } - -private: - void EmitValueImpl(const AsmPrinter *AP, dwarf::Form Form) const; - unsigned SizeOfImpl(const AsmPrinter *AP, dwarf::Form Form) const; + void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const; + unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const; #ifndef NDEBUG - void printImpl(raw_ostream &O) const; + void print(raw_ostream &O) const; #endif }; //===--------------------------------------------------------------------===// /// DIEDelta - A simple label difference DIE. /// -class DIEDelta : public DIEValue { - friend class DIEValue; - +class DIEDelta { const MCSymbol *LabelHi; const MCSymbol *LabelLo; public: - DIEDelta(const MCSymbol *Hi, const MCSymbol *Lo) - : DIEValue(isDelta), LabelHi(Hi), LabelLo(Lo) {} + DIEDelta(const MCSymbol *Hi, const MCSymbol *Lo) : LabelHi(Hi), LabelLo(Lo) {} - // Implement isa/cast/dyncast. - static bool classof(const DIEValue *D) { return D->getType() == isDelta; } - -private: - void EmitValueImpl(const AsmPrinter *AP, dwarf::Form Form) const; - unsigned SizeOfImpl(const AsmPrinter *AP, dwarf::Form Form) const; + void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const; + unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const; #ifndef NDEBUG - void printImpl(raw_ostream &O) const; + void print(raw_ostream &O) const; #endif }; //===--------------------------------------------------------------------===// /// DIEString - A container for string values. /// -class DIEString : public DIEValue { - friend class DIEValue; - +class DIEString { DwarfStringPoolEntryRef S; public: - DIEString(DwarfStringPoolEntryRef S) : DIEValue(isString), S(S) {} + DIEString(DwarfStringPoolEntryRef S) : S(S) {} /// getString - Grab the string out of the object. StringRef getString() const { return S.getString(); } - // Implement isa/cast/dyncast. - static bool classof(const DIEValue *D) { return D->getType() == isString; } - -private: - void EmitValueImpl(const AsmPrinter *AP, dwarf::Form Form) const; - unsigned SizeOfImpl(const AsmPrinter *AP, dwarf::Form Form) const; + void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const; + unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const; #ifndef NDEBUG - void printImpl(raw_ostream &O) const; + void print(raw_ostream &O) const; #endif }; @@ -399,72 +230,350 @@ class DIEString : public DIEValue { /// DIEEntry - A pointer to another debug information entry. An instance of /// this class can also be used as a proxy for a debug information entry not /// yet defined (ie. types.) -class DIEEntry : public DIEValue { - friend class DIEValue; +class DIE; +class DIEEntry { + DIE *Entry; - DIE &Entry; + DIEEntry() = delete; public: - explicit DIEEntry(DIE &E) : DIEValue(isEntry), Entry(E) { - } + explicit DIEEntry(DIE &E) : Entry(&E) {} - DIE &getEntry() const { return Entry; } + DIE &getEntry() const { return *Entry; } /// Returns size of a ref_addr entry. static unsigned getRefAddrSize(const AsmPrinter *AP); - // Implement isa/cast/dyncast. - static bool classof(const DIEValue *E) { return E->getType() == isEntry; } - -private: - void EmitValueImpl(const AsmPrinter *AP, dwarf::Form Form) const; - unsigned SizeOfImpl(const AsmPrinter *AP, dwarf::Form Form) const { + void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const; + unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const { return Form == dwarf::DW_FORM_ref_addr ? getRefAddrSize(AP) : sizeof(int32_t); } #ifndef NDEBUG - void printImpl(raw_ostream &O) const; + void print(raw_ostream &O) const; #endif }; //===--------------------------------------------------------------------===// /// \brief A signature reference to a type unit. -class DIETypeSignature : public DIEValue { - friend class DIEValue; +class DIETypeSignature { + const DwarfTypeUnit *Unit; - const DwarfTypeUnit &Unit; + DIETypeSignature() = delete; public: - explicit DIETypeSignature(const DwarfTypeUnit &Unit) - : DIEValue(isTypeSignature), Unit(Unit) {} + explicit DIETypeSignature(const DwarfTypeUnit &Unit) : Unit(&Unit) {} - // \brief Implement isa/cast/dyncast. - static bool classof(const DIEValue *E) { - return E->getType() == isTypeSignature; - } - -private: - void EmitValueImpl(const AsmPrinter *AP, dwarf::Form Form) const; - unsigned SizeOfImpl(const AsmPrinter *AP, dwarf::Form Form) const { + void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const; + unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const { assert(Form == dwarf::DW_FORM_ref_sig8); return 8; } #ifndef NDEBUG - void printImpl(raw_ostream &O) const; + void print(raw_ostream &O) const; +#endif +}; + +//===--------------------------------------------------------------------===// +/// DIELocList - Represents a pointer to a location list in the debug_loc +/// section. +// +class DIELocList { + // Index into the .debug_loc vector. + size_t Index; + +public: + DIELocList(size_t I) : Index(I) {} + + /// getValue - Grab the current index out. + size_t getValue() const { return Index; } + + void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const; + unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const; + +#ifndef NDEBUG + void print(raw_ostream &O) const; +#endif +}; + +//===--------------------------------------------------------------------===// +/// DIEValue - A debug information entry value. Some of these roughly correlate +/// to DWARF attribute classes. +/// +class DIEBlock; +class DIELoc; +class DIEValue { +public: + enum Type { + isNone, +#define HANDLE_DIEVALUE(T) is##T, +#include "llvm/CodeGen/DIEValue.def" + }; + +private: + /// Ty - Type of data stored in the value. + /// + Type Ty = isNone; + dwarf::Attribute Attribute = (dwarf::Attribute)0; + dwarf::Form Form = (dwarf::Form)0; + + /// Storage for the value. + /// + /// All values that aren't standard layout (or are larger than 8 bytes) + /// should be stored by reference instead of by value. + typedef AlignedCharArrayUnion ValTy; + static_assert(sizeof(ValTy) <= sizeof(uint64_t) || + sizeof(ValTy) <= sizeof(void *), + "Expected all large types to be stored via pointer"); + + /// Underlying stored value. + ValTy Val; + + template void construct(T V) { + static_assert(std::is_standard_layout::value || + std::is_pointer::value, + "Expected standard layout or pointer"); + new (reinterpret_cast(Val.buffer)) T(V); + } + + template T *get() { return reinterpret_cast(Val.buffer); } + template const T *get() const { + return reinterpret_cast(Val.buffer); + } + template void destruct() { get()->~T(); } + + /// Destroy the underlying value. + /// + /// This should get optimized down to a no-op. We could skip it if we could + /// add a static assert on \a std::is_trivially_copyable(), but we currently + /// support versions of GCC that don't understand that. + void destroyVal() { + switch (Ty) { + case isNone: + return; +#define HANDLE_DIEVALUE_SMALL(T) \ + case is##T: \ + destruct(); + return; +#define HANDLE_DIEVALUE_LARGE(T) \ + case is##T: \ + destruct(); + return; +#include "llvm/CodeGen/DIEValue.def" + } + } + + /// Copy the underlying value. + /// + /// This should get optimized down to a simple copy. We need to actually + /// construct the value, rather than calling memcpy, to satisfy strict + /// aliasing rules. + void copyVal(const DIEValue &X) { + switch (Ty) { + case isNone: + return; +#define HANDLE_DIEVALUE_SMALL(T) \ + case is##T: \ + construct(*X.get()); \ + return; +#define HANDLE_DIEVALUE_LARGE(T) \ + case is##T: \ + construct(*X.get()); \ + return; +#include "llvm/CodeGen/DIEValue.def" + } + } + +public: + DIEValue() = default; + DIEValue(const DIEValue &X) : Ty(X.Ty), Attribute(X.Attribute), Form(X.Form) { + copyVal(X); + } + DIEValue &operator=(const DIEValue &X) { + destroyVal(); + Ty = X.Ty; + Attribute = X.Attribute; + Form = X.Form; + copyVal(X); + return *this; + } + ~DIEValue() { destroyVal(); } + +#define HANDLE_DIEVALUE_SMALL(T) \ + DIEValue(dwarf::Attribute Attribute, dwarf::Form Form, const DIE##T &V) \ + : Ty(is##T), Attribute(Attribute), Form(Form) { \ + construct(V); \ + } +#define HANDLE_DIEVALUE_LARGE(T) \ + DIEValue(dwarf::Attribute Attribute, dwarf::Form Form, const DIE##T *V) \ + : Ty(is##T), Attribute(Attribute), Form(Form) { \ + assert(V && "Expected valid value"); \ + construct(V); \ + } +#include "llvm/CodeGen/DIEValue.def" + + // Accessors + Type getType() const { return Ty; } + dwarf::Attribute getAttribute() const { return Attribute; } + dwarf::Form getForm() const { return Form; } + explicit operator bool() const { return Ty; } + +#define HANDLE_DIEVALUE_SMALL(T) \ + const DIE##T &getDIE##T() const { \ + assert(getType() == is##T && "Expected " #T); \ + return *get(); \ + } +#define HANDLE_DIEVALUE_LARGE(T) \ + const DIE##T &getDIE##T() const { \ + assert(getType() == is##T && "Expected " #T); \ + return **get(); \ + } +#include "llvm/CodeGen/DIEValue.def" + + /// EmitValue - Emit value via the Dwarf writer. + /// + void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const; + + /// SizeOf - Return the size of a value in bytes. + /// + unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const; + +#ifndef NDEBUG + void print(raw_ostream &O) const; + void dump() const; +#endif +}; + +//===--------------------------------------------------------------------===// +/// DIE - A structured debug information entry. Has an abbreviation which +/// describes its organization. +class DIE { +protected: + /// Offset - Offset in debug info section. + /// + unsigned Offset; + + /// Size - Size of instance + children. + /// + unsigned Size; + + unsigned AbbrevNumber = ~0u; + + /// Tag - Dwarf tag code. + /// + dwarf::Tag Tag = (dwarf::Tag)0; + + /// Children DIEs. + /// + // This can't be a vector because pointer validity is requirent for the + // Parent pointer and DIEEntry. + // It can't be a list because some clients need pointer validity before + // the object has been added to any child list + // (eg: DwarfUnit::constructVariableDIE). These aren't insurmountable, but may + // be more convoluted than beneficial. + std::vector> Children; + + DIE *Parent; + + /// Attribute values. + /// + SmallVector Values; + +protected: + DIE() : Offset(0), Size(0), Parent(nullptr) {} + +public: + explicit DIE(dwarf::Tag Tag) + : Offset(0), Size(0), Tag(Tag), Parent(nullptr) {} + + // Accessors. + unsigned getAbbrevNumber() const { return AbbrevNumber; } + dwarf::Tag getTag() const { return Tag; } + unsigned getOffset() const { return Offset; } + unsigned getSize() const { return Size; } + bool hasChildren() const { return !Children.empty(); } + + typedef std::vector>::const_iterator child_iterator; + typedef iterator_range child_range; + + child_range children() const { + return llvm::make_range(Children.begin(), Children.end()); + } + + typedef SmallVectorImpl::const_iterator value_iterator; + typedef iterator_range value_range; + + value_iterator values_begin() const { return Values.begin(); } + value_iterator values_end() const { return Values.end(); } + value_range values() const { + return llvm::make_range(values_begin(), values_end()); + } + + void setValue(unsigned I, DIEValue New) { + assert(I < Values.size()); + Values[I] = New; + } + DIE *getParent() const { return Parent; } + + /// Generate the abbreviation for this DIE. + /// + /// Calculate the abbreviation for this, which should be uniqued and + /// eventually used to call \a setAbbrevNumber(). + DIEAbbrev generateAbbrev() const; + + /// Set the abbreviation number for this DIE. + void setAbbrevNumber(unsigned I) { AbbrevNumber = I; } + + /// Climb up the parent chain to get the compile or type unit DIE this DIE + /// belongs to. + const DIE *getUnit() const; + /// Similar to getUnit, returns null when DIE is not added to an + /// owner yet. + const DIE *getUnitOrNull() const; + void setOffset(unsigned O) { Offset = O; } + void setSize(unsigned S) { Size = S; } + + /// addValue - Add a value and attributes to a DIE. + /// + void addValue(DIEValue Value) { Values.push_back(Value); } + template + void addValue(dwarf::Attribute Attribute, dwarf::Form Form, T &&Value) { + Values.emplace_back(Attribute, Form, std::forward(Value)); + } + + /// addChild - Add a child to the DIE. + /// + DIE &addChild(std::unique_ptr Child) { + assert(!Child->getParent()); + Child->Parent = this; + Children.push_back(std::move(Child)); + return *Children.back(); + } + + /// Find a value in the DIE with the attribute given. + /// + /// Returns a default-constructed DIEValue (where \a DIEValue::getType() + /// gives \a DIEValue::isNone) if no such attribute exists. + DIEValue findAttribute(dwarf::Attribute Attribute) const; + +#ifndef NDEBUG + void print(raw_ostream &O, unsigned IndentCount = 0) const; + void dump(); #endif }; //===--------------------------------------------------------------------===// /// DIELoc - Represents an expression location. // -class DIELoc : public DIEValue, public DIE { - friend class DIEValue; - +class DIELoc : public DIE { mutable unsigned Size; // Size in bytes excluding size header. + public: - DIELoc() : DIEValue(isLoc), Size(0) {} + DIELoc() : Size(0) {} /// ComputeSize - Calculate the size of the location expression. /// @@ -485,27 +594,22 @@ class DIELoc : public DIEValue, public DIE { return dwarf::DW_FORM_block; } - // Implement isa/cast/dyncast. - static bool classof(const DIEValue *E) { return E->getType() == isLoc; } - -private: - void EmitValueImpl(const AsmPrinter *AP, dwarf::Form Form) const; - unsigned SizeOfImpl(const AsmPrinter *AP, dwarf::Form Form) const; + void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const; + unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const; #ifndef NDEBUG - void printImpl(raw_ostream &O) const; + void print(raw_ostream &O) const; #endif }; //===--------------------------------------------------------------------===// /// DIEBlock - Represents a block of values. // -class DIEBlock : public DIEValue, public DIE { - friend class DIEValue; - +class DIEBlock : public DIE { mutable unsigned Size; // Size in bytes excluding size header. + public: - DIEBlock() : DIEValue(isBlock), Size(0) {} + DIEBlock() : Size(0) {} /// ComputeSize - Calculate the size of the location expression. /// @@ -523,43 +627,11 @@ class DIEBlock : public DIEValue, public DIE { return dwarf::DW_FORM_block; } - // Implement isa/cast/dyncast. - static bool classof(const DIEValue *E) { return E->getType() == isBlock; } - -private: - void EmitValueImpl(const AsmPrinter *AP, dwarf::Form Form) const; - unsigned SizeOfImpl(const AsmPrinter *AP, dwarf::Form Form) const; + void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const; + unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const; #ifndef NDEBUG - void printImpl(raw_ostream &O) const; -#endif -}; - -//===--------------------------------------------------------------------===// -/// DIELocList - Represents a pointer to a location list in the debug_loc -/// section. -// -class DIELocList : public DIEValue { - friend class DIEValue; - - // Index into the .debug_loc vector. - size_t Index; - -public: - DIELocList(size_t I) : DIEValue(isLocList), Index(I) {} - - /// getValue - Grab the current index out. - size_t getValue() const { return Index; } - - // Implement isa/cast/dyncast. - static bool classof(const DIEValue *E) { return E->getType() == isLocList; } - -private: - void EmitValueImpl(const AsmPrinter *AP, dwarf::Form Form) const; - unsigned SizeOfImpl(const AsmPrinter *AP, dwarf::Form Form) const; - -#ifndef NDEBUG - void printImpl(raw_ostream &O) const; + void print(raw_ostream &O) const; #endif }; diff --git a/include/llvm/CodeGen/DIEValue.def b/include/llvm/CodeGen/DIEValue.def new file mode 100644 index 000000000000..2cfae7b608c6 --- /dev/null +++ b/include/llvm/CodeGen/DIEValue.def @@ -0,0 +1,47 @@ +//===- llvm/CodeGen/DIEValue.def - DIEValue types ---------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Macros for running through all types of DIEValue. +// +//===----------------------------------------------------------------------===// + +#if !(defined HANDLE_DIEVALUE || defined HANDLE_DIEVALUE_SMALL || \ + defined HANDLE_DIEVALUE_LARGE) +#error "Missing macro definition of HANDLE_DIEVALUE" +#endif + +// Handler for all values. +#ifndef HANDLE_DIEVALUE +#define HANDLE_DIEVALUE(T) +#endif + +// Handler for small values. +#ifndef HANDLE_DIEVALUE_SMALL +#define HANDLE_DIEVALUE_SMALL(T) HANDLE_DIEVALUE(T) +#endif + +// Handler for large values. +#ifndef HANDLE_DIEVALUE_LARGE +#define HANDLE_DIEVALUE_LARGE(T) HANDLE_DIEVALUE(T) +#endif + +HANDLE_DIEVALUE_SMALL(Integer) +HANDLE_DIEVALUE_SMALL(String) +HANDLE_DIEVALUE_SMALL(Expr) +HANDLE_DIEVALUE_SMALL(Label) +HANDLE_DIEVALUE_LARGE(Delta) +HANDLE_DIEVALUE_SMALL(Entry) +HANDLE_DIEVALUE_SMALL(TypeSignature) +HANDLE_DIEVALUE_LARGE(Block) +HANDLE_DIEVALUE_LARGE(Loc) +HANDLE_DIEVALUE_SMALL(LocList) + +#undef HANDLE_DIEVALUE +#undef HANDLE_DIEVALUE_SMALL +#undef HANDLE_DIEVALUE_LARGE diff --git a/include/llvm/CodeGen/GCMetadata.h b/include/llvm/CodeGen/GCMetadata.h index 357b2d8a7ca7..e883bd196ea3 100644 --- a/include/llvm/CodeGen/GCMetadata.h +++ b/include/llvm/CodeGen/GCMetadata.h @@ -121,7 +121,7 @@ class GCFunctionInfo { /// label just prior to the safe point (if the code generator is using /// MachineModuleInfo). void addSafePoint(GC::PointKind Kind, MCSymbol *Label, DebugLoc DL) { - SafePoints.push_back(GCPoint(Kind, Label, DL)); + SafePoints.emplace_back(Kind, Label, DL); } /// getFrameSize/setFrameSize - Records the function's frame size. diff --git a/include/llvm/CodeGen/LiveRangeEdit.h b/include/llvm/CodeGen/LiveRangeEdit.h index de855f2fe7a0..c97c636abbb4 100644 --- a/include/llvm/CodeGen/LiveRangeEdit.h +++ b/include/llvm/CodeGen/LiveRangeEdit.h @@ -102,6 +102,10 @@ class LiveRangeEdit : private MachineRegisterInfo::Delegate { /// registers are created. void MRI_NoteNewVirtualRegister(unsigned VReg) override; + /// \brief Check if MachineOperand \p MO is a last use/kill either in the + /// main live range of \p LI or in one of the matching subregister ranges. + bool useIsKill(const LiveInterval &LI, const MachineOperand &MO) const; + public: /// Create a LiveRangeEdit for breaking down parent into smaller pieces. /// @param parent The register being spilled or split. diff --git a/include/llvm/CodeGen/MIRParser/MIRParser.h b/include/llvm/CodeGen/MIRParser/MIRParser.h new file mode 100644 index 000000000000..710b2d4bef8e --- /dev/null +++ b/include/llvm/CodeGen/MIRParser/MIRParser.h @@ -0,0 +1,52 @@ +//===- MIRParser.h - MIR serialization format parser ----------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This MIR serialization library is currently a work in progress. It can't +// serialize machine functions at this time. +// +// This file declares the functions that parse the MIR serialization format +// files. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CODEGEN_MIRPARSER_MIRPARSER_H +#define LLVM_CODEGEN_MIRPARSER_MIRPARSER_H + +#include "llvm/ADT/StringRef.h" +#include "llvm/IR/Module.h" +#include "llvm/Support/MemoryBuffer.h" +#include + +namespace llvm { + +class SMDiagnostic; + +/// This function is the main interface to the MIR serialization format parser. +/// +/// It reads a YAML file that has an optional LLVM IR and returns an LLVM +/// module. +/// \param Filename - The name of the file to parse. +/// \param Error - Error result info. +/// \param Context - Context in which to allocate globals info. +std::unique_ptr parseMIRFile(StringRef Filename, SMDiagnostic &Error, + LLVMContext &Context); + +/// This function is another interface to the MIR serialization format parser. +/// +/// It parses the optional LLVM IR in the given buffer, and returns an LLVM +/// module. +/// \param Contents - The MemoryBuffer containing the machine level IR. +/// \param Error - Error result info. +/// \param Context - Context in which to allocate globals info. +std::unique_ptr parseMIR(std::unique_ptr Contents, + SMDiagnostic &Error, LLVMContext &Context); + +} // end namespace llvm + +#endif diff --git a/include/llvm/CodeGen/MIRYamlMapping.h b/include/llvm/CodeGen/MIRYamlMapping.h new file mode 100644 index 000000000000..f9d4c7471b93 --- /dev/null +++ b/include/llvm/CodeGen/MIRYamlMapping.h @@ -0,0 +1,40 @@ +//===- MIRYAMLMapping.h - Describes the mapping between MIR and YAML ------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// The MIR serialization library is currently a work in progress. It can't +// serialize machine functions at this time. +// +// This file implements the mapping between various MIR data structures and +// their corresponding YAML representation. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_CODEGEN_MIRYAMLMAPPING_H +#define LLVM_LIB_CODEGEN_MIRYAMLMAPPING_H + +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/YAMLTraits.h" + +namespace llvm { +namespace yaml { + +struct MachineFunction { + StringRef Name; +}; + +template <> struct MappingTraits { + static void mapping(IO &YamlIO, MachineFunction &MF) { + YamlIO.mapRequired("name", MF.Name); + } +}; + +} // end namespace yaml +} // end namespace llvm + +#endif diff --git a/include/llvm/CodeGen/MachineFrameInfo.h b/include/llvm/CodeGen/MachineFrameInfo.h index 40f3b4944cc1..3889d471ccf3 100644 --- a/include/llvm/CodeGen/MachineFrameInfo.h +++ b/include/llvm/CodeGen/MachineFrameInfo.h @@ -256,11 +256,6 @@ class MachineFrameInfo { /// Not null, if shrink-wrapping found a better place for the epilogue. MachineBasicBlock *Restore; - /// Check if it exists a path from \p MBB leading to the basic - /// block with a SavePoint (a.k.a. prologue). - bool isBeforeSavePoint(const MachineFunction &MF, - const MachineBasicBlock &MBB) const; - public: explicit MachineFrameInfo(unsigned StackAlign, bool isStackRealign, bool RealignOpt) @@ -627,16 +622,15 @@ class MachineFrameInfo { MachineBasicBlock *getRestorePoint() const { return Restore; } void setRestorePoint(MachineBasicBlock *NewRestore) { Restore = NewRestore; } - /// getPristineRegs - Return a set of physical registers that are pristine on - /// entry to the MBB. + /// Return a set of physical registers that are pristine. /// /// Pristine registers hold a value that is useless to the current function, - /// but that must be preserved - they are callee saved registers that have not - /// been saved yet. + /// but that must be preserved - they are callee saved registers that are not + /// saved. /// /// Before the PrologueEpilogueInserter has placed the CSR spill code, this /// method always returns an empty set. - BitVector getPristineRegs(const MachineBasicBlock *MBB) const; + BitVector getPristineRegs(const MachineFunction &MF) const; /// print - Used by the MachineFunction printer to print information about /// stack objects. Implemented in MachineFunction.cpp diff --git a/include/llvm/CodeGen/MachineInstr.h b/include/llvm/CodeGen/MachineInstr.h index e57257c76bc7..edda03fe3685 100644 --- a/include/llvm/CodeGen/MachineInstr.h +++ b/include/llvm/CodeGen/MachineInstr.h @@ -331,6 +331,11 @@ class MachineInstr : public ilist_node { operands_begin() + getDesc().getNumDefs(), operands_end()); } + /// Returns the number of the operand iterator \p I points to. + unsigned getOperandNo(const_mop_iterator I) const { + return I - operands_begin(); + } + /// Access to memory operands of the instruction mmo_iterator memoperands_begin() const { return MemRefs; } mmo_iterator memoperands_end() const { return MemRefs + NumMemRefs; } @@ -483,6 +488,13 @@ class MachineInstr : public ilist_node { return hasProperty(MCID::NotDuplicable, Type); } + /// Return true if this instruction is convergent. + /// Convergent instructions can only be moved to locations that are + /// control-equivalent to their initial position. + bool isConvergent(QueryType Type = AnyInBundle) const { + return hasProperty(MCID::Convergent, Type); + } + /// Returns true if the specified instruction has a delay slot /// which must be filled by the code generator. bool hasDelaySlot(QueryType Type = AnyInBundle) const { @@ -924,7 +936,7 @@ class MachineInstr : public ilist_node { /// For normal instructions, this is derived from the MCInstrDesc. /// For inline assembly it is derived from the flag words. /// - /// Returns NULL if the static register classs constraint cannot be + /// Returns NULL if the static register class constraint cannot be /// determined. /// const TargetRegisterClass* @@ -936,10 +948,10 @@ class MachineInstr : public ilist_node { /// the given \p CurRC. /// If \p ExploreBundle is set and MI is part of a bundle, all the /// instructions inside the bundle will be taken into account. In other words, - /// this method accumulates all the constrains of the operand of this MI and + /// this method accumulates all the constraints of the operand of this MI and /// the related bundle if MI is a bundle or inside a bundle. /// - /// Returns the register class that statisfies both \p CurRC and the + /// Returns the register class that satisfies both \p CurRC and the /// constraints set by MI. Returns NULL if such a register class does not /// exist. /// @@ -952,7 +964,7 @@ class MachineInstr : public ilist_node { /// \brief Applies the constraints (def/use) implied by the \p OpIdx operand /// to the given \p CurRC. /// - /// Returns the register class that statisfies both \p CurRC and the + /// Returns the register class that satisfies both \p CurRC and the /// constraints set by \p OpIdx MI. Returns NULL if such a register class /// does not exist. /// diff --git a/include/llvm/CodeGen/MachineLoopInfo.h b/include/llvm/CodeGen/MachineLoopInfo.h index f7bcf45d93c5..438ef2e37255 100644 --- a/include/llvm/CodeGen/MachineLoopInfo.h +++ b/include/llvm/CodeGen/MachineLoopInfo.h @@ -114,7 +114,7 @@ class MachineLoopInfo : public MachineFunctionPass { } // isLoopHeader - True if the block is a loop header node - inline bool isLoopHeader(MachineBasicBlock *BB) const { + inline bool isLoopHeader(const MachineBasicBlock *BB) const { return LI.isLoopHeader(BB); } diff --git a/include/llvm/CodeGen/Passes.h b/include/llvm/CodeGen/Passes.h index 39f69549d7cf..9c7e7b4001a4 100644 --- a/include/llvm/CodeGen/Passes.h +++ b/include/llvm/CodeGen/Passes.h @@ -17,11 +17,11 @@ #include "llvm/Pass.h" #include "llvm/Target/TargetMachine.h" +#include #include namespace llvm { -class FunctionPass; class MachineFunctionPass; class PassConfigImpl; class PassInfo; @@ -374,6 +374,10 @@ namespace llvm { createMachineFunctionPrinterPass(raw_ostream &OS, const std::string &Banner =""); + /// MIRPrinting pass - this pass prints out the LLVM IR into the given stream + /// using the MIR serialization format. + MachineFunctionPass *createPrintMIRPass(raw_ostream &OS); + /// createCodeGenPreparePass - Transform the code to expose more pattern /// matching during instruction selection. FunctionPass *createCodeGenPreparePass(const TargetMachine *TM = nullptr); @@ -488,6 +492,10 @@ namespace llvm { /// MachineFunctionPrinterPass - This pass prints out MachineInstr's. extern char &MachineFunctionPrinterPassID; + /// MIRPrintingPass - this pass prints out the LLVM IR using the MIR + /// serialization format. + extern char &MIRPrintingPassID; + /// TailDuplicate - Duplicate blocks with unconditional branches /// into tails of their predecessors. extern char &TailDuplicateID; @@ -511,6 +519,8 @@ namespace llvm { /// IfConverter - This pass performs machine code if conversion. extern char &IfConverterID; + FunctionPass *createIfConverter(std::function Ftor); + /// MachineBlockPlacement - This pass places basic blocks based on branch /// probabilities. extern char &MachineBlockPlacementID; @@ -605,6 +615,9 @@ namespace llvm { /// UnpackMachineBundles - This pass unpack machine instruction bundles. extern char &UnpackMachineBundlesID; + FunctionPass * + createUnpackMachineBundles(std::function Ftor); + /// FinalizeMachineBundles - This pass finalize machine instruction /// bundles (created earlier, e.g. during pre-RA scheduling). extern char &FinalizeMachineBundlesID; diff --git a/include/llvm/CodeGen/ScheduleDAGInstrs.h b/include/llvm/CodeGen/ScheduleDAGInstrs.h index 1196783e820b..b56d5ec8ce63 100644 --- a/include/llvm/CodeGen/ScheduleDAGInstrs.h +++ b/include/llvm/CodeGen/ScheduleDAGInstrs.h @@ -260,7 +260,7 @@ namespace llvm { #ifndef NDEBUG const SUnit *Addr = SUnits.empty() ? nullptr : &SUnits[0]; #endif - SUnits.push_back(SUnit(MI, (unsigned)SUnits.size())); + SUnits.emplace_back(MI, (unsigned)SUnits.size()); assert((Addr == nullptr || Addr == &SUnits[0]) && "SUnits std::vector reallocated on the fly!"); SUnits.back().OrigNode = &SUnits.back(); diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h index 89f9005b8b21..78fdd040773e 100644 --- a/include/llvm/CodeGen/SelectionDAG.h +++ b/include/llvm/CodeGen/SelectionDAG.h @@ -878,6 +878,10 @@ class SelectionDAG { /// Return an MDNodeSDNode which holds an MDNode. SDValue getMDNode(const MDNode *MD); + /// Return a bitcast using the SDLoc of the value operand, and casting to the + /// provided type. Use getNode to set a custom SDLoc. + SDValue getBitcast(EVT VT, SDValue V); + /// Return an AddrSpaceCastSDNode. SDValue getAddrSpaceCast(SDLoc dl, EVT VT, SDValue Ptr, unsigned SrcAS, unsigned DestAS); diff --git a/include/llvm/CodeGen/WinEHFuncInfo.h b/include/llvm/CodeGen/WinEHFuncInfo.h index e2644edd4d12..1cff3203f2bb 100644 --- a/include/llvm/CodeGen/WinEHFuncInfo.h +++ b/include/llvm/CodeGen/WinEHFuncInfo.h @@ -23,6 +23,7 @@ class BasicBlock; class Constant; class Function; class GlobalVariable; +class InvokeInst; class IntrinsicInst; class LandingPadInst; class MCSymbol; @@ -153,5 +154,11 @@ struct WinEHFuncInfo { NumIPToStateFuncsVisited(0) {} }; +/// Analyze the IR in ParentFn and it's handlers to build WinEHFuncInfo, which +/// describes the state numbers and tables used by __CxxFrameHandler3. This +/// analysis assumes that WinEHPrepare has already been run. +void calculateWinCXXEHStateNumbers(const Function *ParentFn, + WinEHFuncInfo &FuncInfo); + } #endif // LLVM_CODEGEN_WINEHFUNCINFO_H diff --git a/include/llvm/Config/config.h.in b/include/llvm/Config/config.h.in index 67d7c8485a40..211e1d0fad01 100644 --- a/include/llvm/Config/config.h.in +++ b/include/llvm/Config/config.h.in @@ -6,6 +6,9 @@ /* Bug report URL. */ #undef BUG_REPORT_URL +/* Default OpenMP runtime used by -fopenmp. */ +#undef CLANG_DEFAULT_OPENMP_RUNTIME + /* Define if we have libxml2 */ #undef CLANG_HAVE_LIBXML diff --git a/include/llvm/DebugInfo/DIContext.h b/include/llvm/DebugInfo/DIContext.h index dddc7faa73e8..871e60c56b13 100644 --- a/include/llvm/DebugInfo/DIContext.h +++ b/include/llvm/DebugInfo/DIContext.h @@ -141,8 +141,7 @@ class DIContext { /// on the fly. class LoadedObjectInfo { public: - LoadedObjectInfo() {} - virtual ~LoadedObjectInfo() {} + virtual ~LoadedObjectInfo() = default; /// Obtain the Load Address of a section by Name. /// @@ -170,7 +169,7 @@ class LoadedObjectInfo { /// Obtain a copy of this LoadedObjectInfo. /// /// The caller is responsible for deallocation once the copy is no longer required. - virtual LoadedObjectInfo *clone() const = 0; + virtual std::unique_ptr clone() const = 0; }; } diff --git a/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h b/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h index 37b22c2e82f6..93e7c790ccf9 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h +++ b/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h @@ -38,12 +38,12 @@ class DWARFDebugLine { // The size in bytes of the statement information for this compilation unit // (not including the total_length field itself). - uint32_t TotalLength; + uint64_t TotalLength; // Version identifier for the statement information format. uint16_t Version; // The number of bytes following the prologue_length field to the beginning // of the first byte of the statement program itself. - uint32_t PrologueLength; + uint64_t PrologueLength; // The size in bytes of the smallest target machine instruction. Statement // program opcodes that alter the address register first multiply their // operands by this value. @@ -63,14 +63,22 @@ class DWARFDebugLine { std::vector IncludeDirectories; std::vector FileNames; + bool IsDWARF64; + uint32_t sizeofTotalLength() const { + return IsDWARF64 ? 12 : 4; + } + uint32_t sizeofPrologueLength() const { + return IsDWARF64 ? 8 : 4; + } + // Length of the prologue in bytes. uint32_t getLength() const { - return PrologueLength + sizeof(TotalLength) + sizeof(Version) + - sizeof(PrologueLength); + return PrologueLength + sizeofTotalLength() + sizeof(Version) + + sizeofPrologueLength(); } // Length of the line table data in bytes (not including the prologue). uint32_t getStatementTableLength() const { - return TotalLength + sizeof(TotalLength) - getLength(); + return TotalLength + sizeofTotalLength() - getLength(); } int32_t getMaxLineIncrementForSpecialOpcode() const { return LineBase + (int8_t)LineRange - 1; @@ -163,6 +171,9 @@ class DWARFDebugLine { struct LineTable { LineTable(); + // Represents an invalid row + const uint32_t UnknownRowIndex = UINT32_MAX; + void appendRow(const DWARFDebugLine::Row &R) { Rows.push_back(R); } @@ -171,7 +182,7 @@ class DWARFDebugLine { } // Returns the index of the row with file/line info for a given address, - // or -1 if there is no such row. + // or UnknownRowIndex if there is no such row. uint32_t lookupAddress(uint64_t address) const; bool lookupAddressRange(uint64_t address, uint64_t size, @@ -203,6 +214,10 @@ class DWARFDebugLine { typedef SequenceVector::const_iterator SequenceIter; RowVector Rows; SequenceVector Sequences; + + private: + uint32_t findRowInSeq(const DWARFDebugLine::Sequence &seq, + uint64_t address) const; }; const LineTable *getLineTable(uint32_t offset) const; diff --git a/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h b/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h index 719adbc562c2..074d55e5034e 100644 --- a/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h +++ b/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h @@ -390,8 +390,7 @@ class CompileOnDemandLayer { for (auto &F : *M) { if (F.isDeclaration()) continue; - Partitioning.push_back(std::vector()); - Partitioning.back().push_back(&F); + Partitioning.emplace_back(1, &F); } addLogicalModule(*LogicalDylibs.back(), std::shared_ptr(std::move(M)), diff --git a/include/llvm/ExecutionEngine/RuntimeDyld.h b/include/llvm/ExecutionEngine/RuntimeDyld.h index ac0151aa7ec1..94c4038e8183 100644 --- a/include/llvm/ExecutionEngine/RuntimeDyld.h +++ b/include/llvm/ExecutionEngine/RuntimeDyld.h @@ -15,6 +15,7 @@ #define LLVM_EXECUTIONENGINE_RUNTIMEDYLD_H #include "JITSymbolFlags.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/Memory.h" #include "llvm/DebugInfo/DIContext.h" @@ -62,8 +63,6 @@ class RuntimeDyld { unsigned EndIdx) : RTDyld(RTDyld), BeginIdx(BeginIdx), EndIdx(EndIdx) { } - virtual ~LoadedObjectInfo() = default; - virtual object::OwningBinary getObjectForDebug(const object::ObjectFile &Obj) const = 0; @@ -80,8 +79,8 @@ class RuntimeDyld { LoadedObjectInfoHelper(RuntimeDyldImpl &RTDyld, unsigned BeginIdx, unsigned EndIdx) : LoadedObjectInfo(RTDyld, BeginIdx, EndIdx) {} - llvm::LoadedObjectInfo *clone() const override { - return new Derived(static_cast(*this)); + std::unique_ptr clone() const override { + return llvm::make_unique(static_cast(*this)); } }; diff --git a/include/llvm/IR/InlineAsm.h b/include/llvm/IR/InlineAsm.h index 15942f16e67e..08b51021116c 100644 --- a/include/llvm/IR/InlineAsm.h +++ b/include/llvm/IR/InlineAsm.h @@ -248,6 +248,13 @@ class InlineAsm : public Value { Constraint_R, Constraint_S, Constraint_T, + Constraint_Um, + Constraint_Un, + Constraint_Uq, + Constraint_Us, + Constraint_Ut, + Constraint_Uv, + Constraint_Uy, Constraint_X, Constraint_Z, Constraint_ZC, diff --git a/include/llvm/IR/Instructions.h b/include/llvm/IR/Instructions.h index 9f5e244f0021..8d8c530d2c6b 100644 --- a/include/llvm/IR/Instructions.h +++ b/include/llvm/IR/Instructions.h @@ -810,6 +810,7 @@ inline Type *checkGEPType(Type *Ty) { /// class GetElementPtrInst : public Instruction { Type *SourceElementType; + Type *ResultElementType; GetElementPtrInst(const GetElementPtrInst &GEPI); void init(Value *Ptr, ArrayRef IdxList, const Twine &NameStr); @@ -903,9 +904,12 @@ class GetElementPtrInst : public Instruction { Type *getSourceElementType() const { return SourceElementType; } void setSourceElementType(Type *Ty) { SourceElementType = Ty; } + void setResultElementType(Type *Ty) { ResultElementType = Ty; } Type *getResultElementType() const { - return cast(getType()->getScalarType())->getElementType(); + assert(ResultElementType == + cast(getType()->getScalarType())->getElementType()); + return ResultElementType; } /// \brief Returns the address space of this instruction's pointer type. @@ -1028,7 +1032,10 @@ GetElementPtrInst::GetElementPtrInst(Type *PointeeType, Value *Ptr, : Instruction(getGEPReturnType(PointeeType, Ptr, IdxList), GetElementPtr, OperandTraits::op_end(this) - Values, Values, InsertBefore), - SourceElementType(PointeeType) { + SourceElementType(PointeeType), + ResultElementType(getIndexedType(PointeeType, IdxList)) { + assert(ResultElementType == + cast(getType()->getScalarType())->getElementType()); init(Ptr, IdxList, NameStr); } GetElementPtrInst::GetElementPtrInst(Type *PointeeType, Value *Ptr, @@ -1038,7 +1045,10 @@ GetElementPtrInst::GetElementPtrInst(Type *PointeeType, Value *Ptr, : Instruction(getGEPReturnType(PointeeType, Ptr, IdxList), GetElementPtr, OperandTraits::op_end(this) - Values, Values, InsertAtEnd), - SourceElementType(PointeeType) { + SourceElementType(PointeeType), + ResultElementType(getIndexedType(PointeeType, IdxList)) { + assert(ResultElementType == + cast(getType()->getScalarType())->getElementType()); init(Ptr, IdxList, NameStr); } diff --git a/include/llvm/IR/Intrinsics.td b/include/llvm/IR/Intrinsics.td index 8f6cdebb0491..beeffde9f65a 100644 --- a/include/llvm/IR/Intrinsics.td +++ b/include/llvm/IR/Intrinsics.td @@ -537,7 +537,8 @@ def int_experimental_patchpoint_i64 : Intrinsic<[llvm_i64_ty], def int_experimental_gc_statepoint : Intrinsic<[llvm_i32_ty], [llvm_i64_ty, llvm_i32_ty, llvm_anyptr_ty, llvm_i32_ty, - llvm_i32_ty, llvm_vararg_ty]>; + llvm_i32_ty, llvm_vararg_ty], + [Throws]>; def int_experimental_gc_result : Intrinsic<[llvm_any_ty], [llvm_i32_ty]>; def int_experimental_gc_relocate : Intrinsic<[llvm_anyptr_ty], diff --git a/include/llvm/IR/IntrinsicsX86.td b/include/llvm/IR/IntrinsicsX86.td index 3a8a4a643a43..0826aa2287e9 100644 --- a/include/llvm/IR/IntrinsicsX86.td +++ b/include/llvm/IR/IntrinsicsX86.td @@ -3372,10 +3372,40 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>; - def int_x86_avx512_sqrt_pd_512 : GCCBuiltin<"__builtin_ia32_sqrtpd512_mask">, + def int_x86_avx512_mask_sqrt_pd_128 : GCCBuiltin<"__builtin_ia32_sqrtpd128_mask">, + Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, + llvm_i8_ty], [IntrNoMem]>; + def int_x86_avx512_mask_sqrt_pd_256 : GCCBuiltin<"__builtin_ia32_sqrtpd256_mask">, + Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_v4f64_ty, + llvm_i8_ty], [IntrNoMem]>; + def int_x86_avx512_mask_sqrt_pd_512 : GCCBuiltin<"__builtin_ia32_sqrtpd512_mask">, Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_v8f64_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>; - def int_x86_avx512_sqrt_ps_512 : GCCBuiltin<"__builtin_ia32_sqrtps512_mask">, + def int_x86_avx512_mask_sqrt_ps_128 : GCCBuiltin<"__builtin_ia32_sqrtps128_mask">, + Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, + llvm_i8_ty], [IntrNoMem]>; + def int_x86_avx512_mask_sqrt_ps_256 : GCCBuiltin<"__builtin_ia32_sqrtps256_mask">, + Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_v8f32_ty, + llvm_i8_ty], [IntrNoMem]>; + def int_x86_avx512_mask_sqrt_ps_512 : GCCBuiltin<"__builtin_ia32_sqrtps512_mask">, + Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_v16f32_ty, + llvm_i16_ty, llvm_i32_ty], [IntrNoMem]>; + def int_x86_avx512_mask_getexp_pd_128 : GCCBuiltin<"__builtin_ia32_getexppd128_mask">, + Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, + llvm_i8_ty], [IntrNoMem]>; + def int_x86_avx512_mask_getexp_pd_256 : GCCBuiltin<"__builtin_ia32_getexppd256_mask">, + Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_v4f64_ty, + llvm_i8_ty], [IntrNoMem]>; + def int_x86_avx512_mask_getexp_pd_512 : GCCBuiltin<"__builtin_ia32_getexppd512_mask">, + Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_v8f64_ty, + llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>; + def int_x86_avx512_mask_getexp_ps_128 : GCCBuiltin<"__builtin_ia32_getexpps128_mask">, + Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, + llvm_i8_ty], [IntrNoMem]>; + def int_x86_avx512_mask_getexp_ps_256 : GCCBuiltin<"__builtin_ia32_getexpps256_mask">, + Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_v8f32_ty, + llvm_i8_ty], [IntrNoMem]>; + def int_x86_avx512_mask_getexp_ps_512 : GCCBuiltin<"__builtin_ia32_getexpps512_mask">, Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_v16f32_ty, llvm_i16_ty, llvm_i32_ty], [IntrNoMem]>; diff --git a/include/llvm/IR/MDBuilder.h b/include/llvm/IR/MDBuilder.h index ba14457f7185..ceb1c736e5c7 100644 --- a/include/llvm/IR/MDBuilder.h +++ b/include/llvm/IR/MDBuilder.h @@ -153,7 +153,7 @@ class MDBuilder { /// \brief Return metadata for a TBAA tag node with the given /// base type, access type and offset relative to the base type. MDNode *createTBAAStructTagNode(MDNode *BaseType, MDNode *AccessType, - uint64_t Offset); + uint64_t Offset, bool IsConstant = false); }; } // end namespace llvm diff --git a/include/llvm/IR/Value.h b/include/llvm/IR/Value.h index 3bf2943a8980..19a1d6cd91da 100644 --- a/include/llvm/IR/Value.h +++ b/include/llvm/IR/Value.h @@ -69,9 +69,8 @@ class Value { Type *VTy; Use *UseList; - friend class ValueAsMetadata; // Allow access to NameAndIsUsedByMD. + friend class ValueAsMetadata; // Allow access to IsUsedByMD. friend class ValueHandleBase; - PointerIntPair NameAndIsUsedByMD; const unsigned char SubclassID; // Subclass identifier (for isa/dyn_cast) unsigned char HasValueHandle : 1; // Has a ValueHandle pointing to this? @@ -101,7 +100,10 @@ class Value { /// This is stored here to save space in User on 64-bit hosts. Since most /// instances of Value have operands, 32-bit hosts aren't significantly /// affected. - unsigned NumOperands; + unsigned NumOperands : 30; + + bool IsUsedByMD : 1; + bool HasName : 1; private: template // UseT == 'Use' or 'const Use' @@ -210,9 +212,9 @@ class Value { LLVMContext &getContext() const; // \brief All values can potentially be named. - bool hasName() const { return getValueName() != nullptr; } - ValueName *getValueName() const { return NameAndIsUsedByMD.getPointer(); } - void setValueName(ValueName *VN) { NameAndIsUsedByMD.setPointer(VN); } + bool hasName() const { return HasName; } + ValueName *getValueName() const; + void setValueName(ValueName *VN); private: void destroyValueName(); @@ -394,7 +396,7 @@ class Value { bool hasValueHandle() const { return HasValueHandle; } /// \brief Return true if there is metadata referencing this value. - bool isUsedByMetadata() const { return NameAndIsUsedByMD.getInt(); } + bool isUsedByMetadata() const { return IsUsedByMD; } /// \brief Strip off pointer casts, all-zero GEPs, and aliases. /// diff --git a/include/llvm/InitializePasses.h b/include/llvm/InitializePasses.h index 497ac55da4b4..4f95c886800f 100644 --- a/include/llvm/InitializePasses.h +++ b/include/llvm/InitializePasses.h @@ -289,6 +289,7 @@ void initializeLoopVectorizePass(PassRegistry&); void initializeSLPVectorizerPass(PassRegistry&); void initializeBBVectorizePass(PassRegistry&); void initializeMachineFunctionPrinterPassPass(PassRegistry&); +void initializeMIRPrintingPassPass(PassRegistry&); void initializeStackMapLivenessPass(PassRegistry&); void initializeMachineCombinerPass(PassRegistry &); void initializeLoadCombinePass(PassRegistry&); diff --git a/include/llvm/LTO/LTOCodeGenerator.h b/include/llvm/LTO/LTOCodeGenerator.h index 3b4be81b223c..0c46fc048a43 100644 --- a/include/llvm/LTO/LTOCodeGenerator.h +++ b/include/llvm/LTO/LTOCodeGenerator.h @@ -82,7 +82,7 @@ struct LTOCodeGenerator { void setShouldInternalize(bool Value) { ShouldInternalize = Value; } void setShouldEmbedUselists(bool Value) { ShouldEmbedUselists = Value; } - void addMustPreserveSymbol(const char *sym) { MustPreserveSymbols[sym] = 1; } + void addMustPreserveSymbol(StringRef sym) { MustPreserveSymbols[sym] = 1; } // To pass options to the driver and optimization passes. These options are // not necessarily for debugging purpose (The function name is misleading). @@ -117,11 +117,10 @@ struct LTOCodeGenerator { // (linker), it brings the object to a buffer, and return the buffer to the // caller. This function should delete intermediate object file once its content // is brought to memory. Return NULL if the compilation was not successful. - const void *compile(size_t *length, - bool disableInline, - bool disableGVNLoadPRE, - bool disableVectorization, - std::string &errMsg); + std::unique_ptr compile(bool disableInline, + bool disableGVNLoadPRE, + bool disableVectorization, + std::string &errMsg); // Optimizes the merged module. Returns true on success. bool optimize(bool disableInline, @@ -132,7 +131,7 @@ struct LTOCodeGenerator { // Compiles the merged optimized module into a single object file. It brings // the object to a buffer, and returns the buffer to the caller. Return NULL // if the compilation was not successful. - const void *compileOptimized(size_t *length, std::string &errMsg); + std::unique_ptr compileOptimized(std::string &errMsg); void setDiagnosticHandler(lto_diagnostic_handler_t, void *); @@ -166,7 +165,6 @@ struct LTOCodeGenerator { lto_codegen_model CodeModel = LTO_CODEGEN_PIC_MODEL_DEFAULT; StringSet MustPreserveSymbols; StringSet AsmUndefinedRefs; - std::unique_ptr NativeObjectFile; std::vector CodegenOptions; std::string MCpu; std::string MAttr; diff --git a/include/llvm/MC/MCAsmBackend.h b/include/llvm/MC/MCAsmBackend.h index c0a95d48e370..2bfad2d355b8 100644 --- a/include/llvm/MC/MCAsmBackend.h +++ b/include/llvm/MC/MCAsmBackend.h @@ -97,6 +97,12 @@ class MCAsmBackend { /// Target specific predicate for whether a given fixup requires the /// associated instruction to be relaxed. + virtual bool fixupNeedsRelaxationAdvanced(const MCFixup &Fixup, bool Resolved, + uint64_t Value, + const MCRelaxableFragment *DF, + const MCAsmLayout &Layout) const; + + /// Simple predicate for targets where !Resolved implies requiring relaxation virtual bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value, const MCRelaxableFragment *DF, const MCAsmLayout &Layout) const = 0; diff --git a/include/llvm/MC/MCAsmInfo.h b/include/llvm/MC/MCAsmInfo.h index 0335f3188fc3..9bb0fa63c523 100644 --- a/include/llvm/MC/MCAsmInfo.h +++ b/include/llvm/MC/MCAsmInfo.h @@ -155,6 +155,10 @@ class MCAsmInfo { /// Defaults to false. bool AllowAtInName; + /// If this is true, symbol names with invalid characters will be printed in + /// quotes. + bool SupportsQuotedNames; + /// This is true if data region markers should be printed as /// ".data_region/.end_data_region" directives. If false, use "$d/$a" labels /// instead. @@ -406,6 +410,10 @@ class MCAsmInfo { unsigned Encoding, MCStreamer &Streamer) const; + /// Return true if the identifier \p Name does not need quotes to be + /// syntactically correct. + virtual bool isValidUnquotedName(StringRef Name) const; + bool usesSunStyleELFSectionSwitchSyntax() const { return SunStyleELFSectionSwitchSyntax; } @@ -456,6 +464,7 @@ class MCAsmInfo { const char *getCode64Directive() const { return Code64Directive; } unsigned getAssemblerDialect() const { return AssemblerDialect; } bool doesAllowAtInName() const { return AllowAtInName; } + bool supportsNameQuoting() const { return SupportsQuotedNames; } bool doesSupportDataRegionDirectives() const { return UseDataRegionDirectives; } diff --git a/include/llvm/MC/MCAsmLayout.h b/include/llvm/MC/MCAsmLayout.h index fb28420e0fa3..1b20d5b804a4 100644 --- a/include/llvm/MC/MCAsmLayout.h +++ b/include/llvm/MC/MCAsmLayout.h @@ -18,7 +18,6 @@ class MCAssembler; class MCFragment; class MCSection; class MCSymbol; -class MCSymbolData; /// Encapsulates the layout of an assembly file at a particular point in time. /// diff --git a/include/llvm/MC/MCAssembler.h b/include/llvm/MC/MCAssembler.h index 593504ce0607..a6178c214d47 100644 --- a/include/llvm/MC/MCAssembler.h +++ b/include/llvm/MC/MCAssembler.h @@ -12,7 +12,6 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseSet.h" -#include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/ilist.h" @@ -24,7 +23,6 @@ #include "llvm/MC/MCLinkerOptimizationHint.h" #include "llvm/MC/MCSection.h" #include "llvm/MC/MCSubtargetInfo.h" -#include "llvm/MC/MCSymbol.h" #include "llvm/Support/Casting.h" #include "llvm/Support/DataTypes.h" #include @@ -60,7 +58,8 @@ class MCFragment : public ilist_node { FT_Org, FT_Dwarf, FT_DwarfFrame, - FT_LEB + FT_LEB, + FT_SafeSEH }; private: @@ -531,6 +530,28 @@ class MCDwarfCallFrameFragment : public MCFragment { } }; +class MCSafeSEHFragment : public MCFragment { + virtual void anchor(); + + const MCSymbol *Sym; + +public: + MCSafeSEHFragment(const MCSymbol *Sym, MCSection *Sec = nullptr) + : MCFragment(FT_SafeSEH, Sec), Sym(Sym) {} + + /// \name Accessors + /// @{ + + const MCSymbol *getSymbol() { return Sym; } + const MCSymbol *getSymbol() const { return Sym; } + + /// @} + + static bool classof(const MCFragment *F) { + return F->getKind() == MCFragment::FT_SafeSEH; + } +}; + // FIXME: This really doesn't belong here. See comments below. struct IndirectSymbolData { MCSymbol *Symbol; @@ -551,7 +572,7 @@ class MCAssembler { friend class MCAsmLayout; public: - typedef SetVector SectionListType; + typedef std::vector SectionListType; typedef std::vector SymbolDataListType; typedef pointee_iterator const_iterator; @@ -564,9 +585,6 @@ class MCAssembler { typedef iterator_range symbol_range; typedef iterator_range const_symbol_range; - typedef std::vector FileNameVectorType; - typedef FileNameVectorType::const_iterator const_file_name_iterator; - typedef std::vector::const_iterator const_indirect_symbol_iterator; typedef std::vector::iterator indirect_symbol_iterator; @@ -613,7 +631,7 @@ class MCAssembler { std::vector> LinkerOptions; /// List of declared file names - FileNameVectorType FileNames; + std::vector FileNames; /// The set of function symbols for which a .thumb_func directive has /// been seen. @@ -883,39 +901,21 @@ class MCAssembler { /// \name Backend Data Access /// @{ - bool registerSection(MCSection &Section) { return Sections.insert(&Section); } - - bool hasSymbolData(const MCSymbol &Symbol) const { return Symbol.hasData(); } - - MCSymbolData &getSymbolData(const MCSymbol &Symbol) { - return const_cast( - static_cast(*this).getSymbolData(Symbol)); + bool registerSection(MCSection &Section) { + if (Section.isRegistered()) + return false; + Sections.push_back(&Section); + Section.setIsRegistered(true); + return true; } - const MCSymbolData &getSymbolData(const MCSymbol &Symbol) const { - return Symbol.getData(); - } + void registerSymbol(const MCSymbol &Symbol, bool *Created = nullptr); - MCSymbolData &getOrCreateSymbolData(const MCSymbol &Symbol, - bool *Created = nullptr) { - if (Created) - *Created = !hasSymbolData(Symbol); - if (!hasSymbolData(Symbol)) { - Symbol.initializeData(); - Symbols.push_back(&Symbol); - } - return Symbol.getData(); - } - - const_file_name_iterator file_names_begin() const { - return FileNames.begin(); - } - - const_file_name_iterator file_names_end() const { return FileNames.end(); } + ArrayRef getFileNames() { return FileNames; } void addFileName(StringRef FileName) { - if (std::find(file_names_begin(), file_names_end(), FileName) == - file_names_end()) + if (std::find(FileNames.begin(), FileNames.end(), FileName) == + FileNames.end()) FileNames.push_back(FileName); } diff --git a/include/llvm/MC/MCContext.h b/include/llvm/MC/MCContext.h index 5b57b9d448e8..1790905a1245 100644 --- a/include/llvm/MC/MCContext.h +++ b/include/llvm/MC/MCContext.h @@ -30,6 +30,7 @@ namespace llvm { class MCExpr; class MCSection; class MCSymbol; + class MCSymbolELF; class MCLabel; struct MCDwarfFile; class MCDwarfLoc; @@ -75,7 +76,7 @@ namespace llvm { /// ELF sections can have a corresponding symbol. This maps one to the /// other. - DenseMap SectionSymbols; + DenseMap SectionSymbols; /// A mapping from a local label number and an instance count to a symbol. /// For example, in the assembly @@ -205,7 +206,10 @@ namespace llvm { /// Do automatic reset in destructor bool AutoReset; - MCSymbol *CreateSymbol(StringRef Name, bool AlwaysAddSuffix); + MCSymbol *createSymbolImpl(const StringMapEntry *Name, + bool IsTemporary); + MCSymbol *createSymbol(StringRef Name, bool AlwaysAddSuffix, + bool IsTemporary); MCSymbol *getOrCreateDirectionalLocalSymbol(unsigned LocalLabelVal, unsigned Instance); @@ -263,7 +267,7 @@ namespace llvm { /// \param Name - The symbol name, which must be unique across all symbols. MCSymbol *getOrCreateSymbol(const Twine &Name); - MCSymbol *getOrCreateSectionSymbol(const MCSectionELF &Section); + MCSymbolELF *getOrCreateSectionSymbol(const MCSectionELF &Section); /// Gets a symbol that will be defined to the final stack offset of a local /// variable after codegen. @@ -340,18 +344,18 @@ namespace llvm { MCSectionELF *getELFSection(StringRef Section, unsigned Type, unsigned Flags, unsigned EntrySize, - const MCSymbol *Group, unsigned UniqueID, + const MCSymbolELF *Group, unsigned UniqueID, const char *BeginSymName, const MCSectionELF *Associated); MCSectionELF *createELFRelSection(StringRef Name, unsigned Type, unsigned Flags, unsigned EntrySize, - const MCSymbol *Group, + const MCSymbolELF *Group, const MCSectionELF *Associated); void renameELFSection(MCSectionELF *Section, StringRef Name); - MCSectionELF *createELFGroupSection(const MCSymbol *Group); + MCSectionELF *createELFGroupSection(const MCSymbolELF *Group); MCSectionCOFF *getCOFFSection(StringRef Section, unsigned Characteristics, SectionKind Kind, StringRef COMDATSymName, diff --git a/include/llvm/MC/MCELF.h b/include/llvm/MC/MCELF.h deleted file mode 100644 index f409988d5726..000000000000 --- a/include/llvm/MC/MCELF.h +++ /dev/null @@ -1,35 +0,0 @@ -//===- lib/MC/MCELF.h - ELF MC --------------------------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains some support functions used by the ELF Streamer and -// ObjectWriter. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_MC_MCELF_H -#define LLVM_MC_MCELF_H - -namespace llvm { -class MCSymbolData; - -class MCELF { - public: - static void SetBinding(MCSymbolData &SD, unsigned Binding); - static unsigned GetBinding(const MCSymbolData &SD); - static void SetType(MCSymbolData &SD, unsigned Type); - static unsigned GetType(const MCSymbolData &SD); - static void SetVisibility(MCSymbolData &SD, unsigned Visibility); - static unsigned GetVisibility(const MCSymbolData &SD); - static void setOther(MCSymbolData &SD, unsigned Other); - static unsigned getOther(const MCSymbolData &SD); -}; - -} - -#endif diff --git a/include/llvm/MC/MCELFObjectWriter.h b/include/llvm/MC/MCELFObjectWriter.h index cf73eca340d7..01f694d3b756 100644 --- a/include/llvm/MC/MCELFObjectWriter.h +++ b/include/llvm/MC/MCELFObjectWriter.h @@ -21,17 +21,17 @@ class MCFixup; class MCFragment; class MCObjectWriter; class MCSymbol; -class MCSymbolData; +class MCSymbolELF; class MCValue; class raw_pwrite_stream; struct ELFRelocationEntry { uint64_t Offset; // Where is the relocation. - const MCSymbol *Symbol; // The symbol to relocate with. + const MCSymbolELF *Symbol; // The symbol to relocate with. unsigned Type; // The type of the relocation. uint64_t Addend; // The addend to use. - ELFRelocationEntry(uint64_t Offset, const MCSymbol *Symbol, unsigned Type, + ELFRelocationEntry(uint64_t Offset, const MCSymbolELF *Symbol, unsigned Type, uint64_t Addend) : Offset(Offset), Symbol(Symbol), Type(Type), Addend(Addend) {} }; @@ -69,7 +69,7 @@ class MCELFObjectTargetWriter { virtual unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup, bool IsPCRel) const = 0; - virtual bool needsRelocateWithSymbol(const MCSymbolData &SD, + virtual bool needsRelocateWithSymbol(const MCSymbol &Sym, unsigned Type) const; virtual void sortRelocs(const MCAssembler &Asm, diff --git a/include/llvm/MC/MCELFStreamer.h b/include/llvm/MC/MCELFStreamer.h index 97058f5e9981..241db0dc9cde 100644 --- a/include/llvm/MC/MCELFStreamer.h +++ b/include/llvm/MC/MCELFStreamer.h @@ -23,8 +23,6 @@ class MCAssembler; class MCCodeEmitter; class MCExpr; class MCInst; -class MCSymbol; -class MCSymbolData; class raw_ostream; class MCELFStreamer : public MCObjectStreamer { @@ -39,7 +37,6 @@ class MCELFStreamer : public MCObjectStreamer { void reset() override { SeenIdent = false; LocalCommons.clear(); - BindingExplicitlySet.clear(); BundleGroups.clear(); MCObjectStreamer::reset(); } @@ -62,7 +59,7 @@ class MCELFStreamer : public MCObjectStreamer { void EmitCOFFSymbolType(int Type) override; void EndCOFFSymbolDef() override; - void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) override; + void emitELFSize(MCSymbolELF *Symbol, const MCExpr *Value) override; void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment) override; @@ -108,8 +105,6 @@ class MCELFStreamer : public MCObjectStreamer { std::vector LocalCommons; - SmallPtrSet BindingExplicitlySet; - /// BundleGroups - The stack of fragments holding the bundle-locked /// instructions. llvm::SmallVector BundleGroups; diff --git a/include/llvm/MC/MCELFSymbolFlags.h b/include/llvm/MC/MCELFSymbolFlags.h deleted file mode 100644 index 297c44269a8f..000000000000 --- a/include/llvm/MC/MCELFSymbolFlags.h +++ /dev/null @@ -1,56 +0,0 @@ -//===- MCELFSymbolFlags.h - ELF Symbol Flags ----------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file declares the SymbolFlags used for the ELF target. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_MC_MCELFSYMBOLFLAGS_H -#define LLVM_MC_MCELFSYMBOLFLAGS_H - -#include "llvm/Support/ELF.h" - -// Because all the symbol flags need to be stored in the MCSymbolData -// 'flags' variable we need to provide shift constants per flag type. - -namespace llvm { - enum { - ELF_STT_Shift = 0, // Shift value for STT_* flags. - ELF_STB_Shift = 4, // Shift value for STB_* flags. - ELF_STV_Shift = 8, // Shift value for STV_* flags. - ELF_STO_Shift = 10 // Shift value for STO_* flags. - }; - - enum ELFSymbolFlags { - ELF_STB_Local = (ELF::STB_LOCAL << ELF_STB_Shift), - ELF_STB_Global = (ELF::STB_GLOBAL << ELF_STB_Shift), - ELF_STB_Weak = (ELF::STB_WEAK << ELF_STB_Shift), - ELF_STB_Loproc = (ELF::STB_LOPROC << ELF_STB_Shift), - ELF_STB_Hiproc = (ELF::STB_HIPROC << ELF_STB_Shift), - - ELF_STT_Notype = (ELF::STT_NOTYPE << ELF_STT_Shift), - ELF_STT_Object = (ELF::STT_OBJECT << ELF_STT_Shift), - ELF_STT_Func = (ELF::STT_FUNC << ELF_STT_Shift), - ELF_STT_Section = (ELF::STT_SECTION << ELF_STT_Shift), - ELF_STT_File = (ELF::STT_FILE << ELF_STT_Shift), - ELF_STT_Common = (ELF::STT_COMMON << ELF_STT_Shift), - ELF_STT_Tls = (ELF::STT_TLS << ELF_STT_Shift), - ELF_STT_GnuIFunc = (ELF::STT_GNU_IFUNC << ELF_STT_Shift), - ELF_STT_Loproc = (ELF::STT_LOPROC << ELF_STT_Shift), - ELF_STT_Hiproc = (ELF::STT_HIPROC << ELF_STT_Shift), - - ELF_STV_Default = (ELF::STV_DEFAULT << ELF_STV_Shift), - ELF_STV_Internal = (ELF::STV_INTERNAL << ELF_STV_Shift), - ELF_STV_Hidden = (ELF::STV_HIDDEN << ELF_STV_Shift), - ELF_STV_Protected = (ELF::STV_PROTECTED << ELF_STV_Shift) - }; - -} // end namespace llvm - -#endif diff --git a/include/llvm/MC/MCExpr.h b/include/llvm/MC/MCExpr.h index b38ad7daee3e..b3a607351a82 100644 --- a/include/llvm/MC/MCExpr.h +++ b/include/llvm/MC/MCExpr.h @@ -46,7 +46,7 @@ class MCExpr { MCExpr(const MCExpr&) = delete; void operator=(const MCExpr&) = delete; - bool EvaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm, + bool evaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm, const MCAsmLayout *Layout, const SectionAddrMap *Addrs) const; @@ -57,7 +57,7 @@ class MCExpr { protected: explicit MCExpr(ExprKind Kind) : Kind(Kind) {} - bool EvaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm, + bool evaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm, const MCAsmLayout *Layout, const MCFixup *Fixup, const SectionAddrMap *Addrs, bool InSet) const; @@ -72,7 +72,7 @@ class MCExpr { /// \name Utility Methods /// @{ - void print(raw_ostream &OS) const; + void print(raw_ostream &OS, const MCAsmInfo *MAI) const; void dump() const; /// @} @@ -86,11 +86,11 @@ class MCExpr { /// values. If not given, then only non-symbolic expressions will be /// evaluated. /// \return - True on success. - bool EvaluateAsAbsolute(int64_t &Res, const MCAsmLayout &Layout, + bool evaluateAsAbsolute(int64_t &Res, const MCAsmLayout &Layout, const SectionAddrMap &Addrs) const; - bool EvaluateAsAbsolute(int64_t &Res) const; - bool EvaluateAsAbsolute(int64_t &Res, const MCAssembler &Asm) const; - bool EvaluateAsAbsolute(int64_t &Res, const MCAsmLayout &Layout) const; + bool evaluateAsAbsolute(int64_t &Res) const; + bool evaluateAsAbsolute(int64_t &Res, const MCAssembler &Asm) const; + bool evaluateAsAbsolute(int64_t &Res, const MCAsmLayout &Layout) const; bool evaluateKnownAbsolute(int64_t &Res, const MCAsmLayout &Layout) const; @@ -101,13 +101,13 @@ class MCExpr { /// \param Layout - The assembler layout object to use for evaluating values. /// \param Fixup - The Fixup object if available. /// \return - True on success. - bool EvaluateAsRelocatable(MCValue &Res, const MCAsmLayout *Layout, + bool evaluateAsRelocatable(MCValue &Res, const MCAsmLayout *Layout, const MCFixup *Fixup) const; /// \brief Try to evaluate the expression to the form (a - b + constant) where /// neither a nor b are variables. /// - /// This is a more aggressive variant of EvaluateAsRelocatable. The intended + /// This is a more aggressive variant of evaluateAsRelocatable. The intended /// use is for when relocations are not available, like the .size directive. bool evaluateAsValue(MCValue &Res, const MCAsmLayout &Layout) const; @@ -115,13 +115,13 @@ class MCExpr { /// currently defined as the absolute section for constants, or /// otherwise the section associated with the first defined symbol in the /// expression. - MCSection *FindAssociatedSection() const; + MCSection *findAssociatedSection() const; /// @} }; inline raw_ostream &operator<<(raw_ostream &OS, const MCExpr &E) { - E.print(OS); + E.print(OS, nullptr); return OS; } @@ -136,7 +136,7 @@ class MCConstantExpr : public MCExpr { /// \name Construction /// @{ - static const MCConstantExpr *Create(int64_t Value, MCContext &Ctx); + static const MCConstantExpr *create(int64_t Value, MCContext &Ctx); /// @} /// \name Accessors @@ -312,13 +312,13 @@ class MCSymbolRefExpr : public MCExpr { /// \name Construction /// @{ - static const MCSymbolRefExpr *Create(const MCSymbol *Symbol, MCContext &Ctx) { - return MCSymbolRefExpr::Create(Symbol, VK_None, Ctx); + static const MCSymbolRefExpr *create(const MCSymbol *Symbol, MCContext &Ctx) { + return MCSymbolRefExpr::create(Symbol, VK_None, Ctx); } - static const MCSymbolRefExpr *Create(const MCSymbol *Symbol, VariantKind Kind, + static const MCSymbolRefExpr *create(const MCSymbol *Symbol, VariantKind Kind, MCContext &Ctx); - static const MCSymbolRefExpr *Create(StringRef Name, VariantKind Kind, + static const MCSymbolRefExpr *create(StringRef Name, VariantKind Kind, MCContext &Ctx); /// @} @@ -369,19 +369,19 @@ class MCUnaryExpr : public MCExpr { /// \name Construction /// @{ - static const MCUnaryExpr *Create(Opcode Op, const MCExpr *Expr, + static const MCUnaryExpr *create(Opcode Op, const MCExpr *Expr, MCContext &Ctx); - static const MCUnaryExpr *CreateLNot(const MCExpr *Expr, MCContext &Ctx) { - return Create(LNot, Expr, Ctx); + static const MCUnaryExpr *createLNot(const MCExpr *Expr, MCContext &Ctx) { + return create(LNot, Expr, Ctx); } - static const MCUnaryExpr *CreateMinus(const MCExpr *Expr, MCContext &Ctx) { - return Create(Minus, Expr, Ctx); + static const MCUnaryExpr *createMinus(const MCExpr *Expr, MCContext &Ctx) { + return create(Minus, Expr, Ctx); } - static const MCUnaryExpr *CreateNot(const MCExpr *Expr, MCContext &Ctx) { - return Create(Not, Expr, Ctx); + static const MCUnaryExpr *createNot(const MCExpr *Expr, MCContext &Ctx) { + return create(Not, Expr, Ctx); } - static const MCUnaryExpr *CreatePlus(const MCExpr *Expr, MCContext &Ctx) { - return Create(Plus, Expr, Ctx); + static const MCUnaryExpr *createPlus(const MCExpr *Expr, MCContext &Ctx) { + return create(Plus, Expr, Ctx); } /// @} @@ -441,83 +441,83 @@ class MCBinaryExpr : public MCExpr { /// \name Construction /// @{ - static const MCBinaryExpr *Create(Opcode Op, const MCExpr *LHS, + static const MCBinaryExpr *create(Opcode Op, const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx); - static const MCBinaryExpr *CreateAdd(const MCExpr *LHS, const MCExpr *RHS, + static const MCBinaryExpr *createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx) { - return Create(Add, LHS, RHS, Ctx); + return create(Add, LHS, RHS, Ctx); } - static const MCBinaryExpr *CreateAnd(const MCExpr *LHS, const MCExpr *RHS, + static const MCBinaryExpr *createAnd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx) { - return Create(And, LHS, RHS, Ctx); + return create(And, LHS, RHS, Ctx); } - static const MCBinaryExpr *CreateDiv(const MCExpr *LHS, const MCExpr *RHS, + static const MCBinaryExpr *createDiv(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx) { - return Create(Div, LHS, RHS, Ctx); + return create(Div, LHS, RHS, Ctx); } - static const MCBinaryExpr *CreateEQ(const MCExpr *LHS, const MCExpr *RHS, + static const MCBinaryExpr *createEQ(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx) { - return Create(EQ, LHS, RHS, Ctx); + return create(EQ, LHS, RHS, Ctx); } - static const MCBinaryExpr *CreateGT(const MCExpr *LHS, const MCExpr *RHS, + static const MCBinaryExpr *createGT(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx) { - return Create(GT, LHS, RHS, Ctx); + return create(GT, LHS, RHS, Ctx); } - static const MCBinaryExpr *CreateGTE(const MCExpr *LHS, const MCExpr *RHS, + static const MCBinaryExpr *createGTE(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx) { - return Create(GTE, LHS, RHS, Ctx); + return create(GTE, LHS, RHS, Ctx); } - static const MCBinaryExpr *CreateLAnd(const MCExpr *LHS, const MCExpr *RHS, + static const MCBinaryExpr *createLAnd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx) { - return Create(LAnd, LHS, RHS, Ctx); + return create(LAnd, LHS, RHS, Ctx); } - static const MCBinaryExpr *CreateLOr(const MCExpr *LHS, const MCExpr *RHS, + static const MCBinaryExpr *createLOr(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx) { - return Create(LOr, LHS, RHS, Ctx); + return create(LOr, LHS, RHS, Ctx); } - static const MCBinaryExpr *CreateLT(const MCExpr *LHS, const MCExpr *RHS, + static const MCBinaryExpr *createLT(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx) { - return Create(LT, LHS, RHS, Ctx); + return create(LT, LHS, RHS, Ctx); } - static const MCBinaryExpr *CreateLTE(const MCExpr *LHS, const MCExpr *RHS, + static const MCBinaryExpr *createLTE(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx) { - return Create(LTE, LHS, RHS, Ctx); + return create(LTE, LHS, RHS, Ctx); } - static const MCBinaryExpr *CreateMod(const MCExpr *LHS, const MCExpr *RHS, + static const MCBinaryExpr *createMod(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx) { - return Create(Mod, LHS, RHS, Ctx); + return create(Mod, LHS, RHS, Ctx); } - static const MCBinaryExpr *CreateMul(const MCExpr *LHS, const MCExpr *RHS, + static const MCBinaryExpr *createMul(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx) { - return Create(Mul, LHS, RHS, Ctx); + return create(Mul, LHS, RHS, Ctx); } - static const MCBinaryExpr *CreateNE(const MCExpr *LHS, const MCExpr *RHS, + static const MCBinaryExpr *createNE(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx) { - return Create(NE, LHS, RHS, Ctx); + return create(NE, LHS, RHS, Ctx); } - static const MCBinaryExpr *CreateOr(const MCExpr *LHS, const MCExpr *RHS, + static const MCBinaryExpr *createOr(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx) { - return Create(Or, LHS, RHS, Ctx); + return create(Or, LHS, RHS, Ctx); } - static const MCBinaryExpr *CreateShl(const MCExpr *LHS, const MCExpr *RHS, + static const MCBinaryExpr *createShl(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx) { - return Create(Shl, LHS, RHS, Ctx); + return create(Shl, LHS, RHS, Ctx); } - static const MCBinaryExpr *CreateAShr(const MCExpr *LHS, const MCExpr *RHS, + static const MCBinaryExpr *createAShr(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx) { - return Create(AShr, LHS, RHS, Ctx); + return create(AShr, LHS, RHS, Ctx); } - static const MCBinaryExpr *CreateLShr(const MCExpr *LHS, const MCExpr *RHS, + static const MCBinaryExpr *createLShr(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx) { - return Create(LShr, LHS, RHS, Ctx); + return create(LShr, LHS, RHS, Ctx); } - static const MCBinaryExpr *CreateSub(const MCExpr *LHS, const MCExpr *RHS, + static const MCBinaryExpr *createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx) { - return Create(Sub, LHS, RHS, Ctx); + return create(Sub, LHS, RHS, Ctx); } - static const MCBinaryExpr *CreateXor(const MCExpr *LHS, const MCExpr *RHS, + static const MCBinaryExpr *createXor(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx) { - return Create(Xor, LHS, RHS, Ctx); + return create(Xor, LHS, RHS, Ctx); } /// @} @@ -551,13 +551,12 @@ class MCTargetExpr : public MCExpr { MCTargetExpr() : MCExpr(Target) {} virtual ~MCTargetExpr() {} public: - - virtual void PrintImpl(raw_ostream &OS) const = 0; - virtual bool EvaluateAsRelocatableImpl(MCValue &Res, + virtual void printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const = 0; + virtual bool evaluateAsRelocatableImpl(MCValue &Res, const MCAsmLayout *Layout, const MCFixup *Fixup) const = 0; virtual void visitUsedExpr(MCStreamer& Streamer) const = 0; - virtual MCSection *FindAssociatedSection() const = 0; + virtual MCSection *findAssociatedSection() const = 0; virtual void fixELFSymbolsInTLSFixups(MCAssembler &) const = 0; diff --git a/include/llvm/MC/MCInst.h b/include/llvm/MC/MCInst.h index 2fc509148403..4688b5f2b6e9 100644 --- a/include/llvm/MC/MCInst.h +++ b/include/llvm/MC/MCInst.h @@ -32,12 +32,12 @@ class MCInst; /// This is a simple discriminated union. class MCOperand { enum MachineOperandType : unsigned char { - kInvalid, ///< Uninitialized. - kRegister, ///< Register operand. - kImmediate, ///< Immediate operand. - kFPImmediate, ///< Floating-point immediate operand. - kExpr, ///< Relocatable immediate operand. - kInst ///< Sub-instruction operand. + kInvalid, ///< Uninitialized. + kRegister, ///< Register operand. + kImmediate, ///< Immediate operand. + kFPImmediate, ///< Floating-point immediate operand. + kExpr, ///< Relocatable immediate operand. + kInst ///< Sub-instruction operand. }; MachineOperandType Kind; @@ -48,8 +48,8 @@ class MCOperand { const MCExpr *ExprVal; const MCInst *InstVal; }; -public: +public: MCOperand() : Kind(kInvalid), FPImmVal(0.0) {} bool isValid() const { return Kind != kInvalid; } @@ -151,6 +151,7 @@ class MCInst { unsigned Opcode; SMLoc Loc; SmallVector Operands; + public: MCInst() : Opcode(0) {} @@ -164,18 +165,16 @@ class MCInst { MCOperand &getOperand(unsigned i) { return Operands[i]; } unsigned getNumOperands() const { return Operands.size(); } - void addOperand(const MCOperand &Op) { - Operands.push_back(Op); - } - - void clear() { Operands.clear(); } - size_t size() const { return Operands.size(); } + void addOperand(const MCOperand &Op) { Operands.push_back(Op); } typedef SmallVectorImpl::iterator iterator; typedef SmallVectorImpl::const_iterator const_iterator; + void clear() { Operands.clear(); } + void erase(iterator I) { Operands.erase(I); } + size_t size() const { return Operands.size(); } iterator begin() { return Operands.begin(); } const_iterator begin() const { return Operands.begin(); } - iterator end() { return Operands.end(); } + iterator end() { return Operands.end(); } const_iterator end() const { return Operands.end(); } iterator insert(iterator I, const MCOperand &Op) { return Operands.insert(I, Op); diff --git a/include/llvm/MC/MCInstPrinter.h b/include/llvm/MC/MCInstPrinter.h index 7e8563a195d0..0eafd02c51c6 100644 --- a/include/llvm/MC/MCInstPrinter.h +++ b/include/llvm/MC/MCInstPrinter.h @@ -10,6 +10,7 @@ #ifndef LLVM_MC_MCINSTPRINTER_H #define LLVM_MC_MCINSTPRINTER_H +#include "llvm/ADT/ArrayRef.h" #include "llvm/Support/DataTypes.h" #include "llvm/Support/Format.h" @@ -22,11 +23,14 @@ class MCRegisterInfo; class MCSubtargetInfo; class StringRef; +/// Convert `Bytes' to a hex string and output to `OS' +void dumpBytes(ArrayRef Bytes, raw_ostream &OS); + namespace HexStyle { - enum Style { - C, ///< 0xff - Asm ///< 0ffh - }; +enum Style { + C, ///< 0xff + Asm ///< 0ffh +}; } /// \brief This is an instance of a target assembly language printer that @@ -52,12 +56,12 @@ class MCInstPrinter { /// Utility function for printing annotations. void printAnnotation(raw_ostream &OS, StringRef Annot); + public: MCInstPrinter(const MCAsmInfo &mai, const MCInstrInfo &mii, const MCRegisterInfo &mri) - : CommentStream(nullptr), MAI(mai), MII(mii), MRI(mri), - UseMarkup(0), PrintImmHex(0), - PrintHexStyle(HexStyle::C) {} + : CommentStream(nullptr), MAI(mai), MII(mii), MRI(mri), UseMarkup(0), + PrintImmHex(0), PrintHexStyle(HexStyle::C) {} virtual ~MCInstPrinter(); @@ -65,8 +69,8 @@ class MCInstPrinter { void setCommentStream(raw_ostream &OS) { CommentStream = &OS; } /// \brief Print the specified MCInst to the specified raw_ostream. - virtual void printInst(const MCInst *MI, raw_ostream &OS, - StringRef Annot, const MCSubtargetInfo &STI) = 0; + virtual void printInst(const MCInst *MI, raw_ostream &OS, StringRef Annot, + const MCSubtargetInfo &STI) = 0; /// \brief Return the name of the specified opcode enum (e.g. "MOV32ri") or /// empty if we can't resolve it. @@ -85,8 +89,8 @@ class MCInstPrinter { bool getPrintImmHex() const { return PrintImmHex; } void setPrintImmHex(bool Value) { PrintImmHex = Value; } - HexStyle::Style getPrintHexStyleHex() const { return PrintHexStyle; } - void setPrintImmHex(HexStyle::Style Value) { PrintHexStyle = Value; } + HexStyle::Style getPrintHexStyle() const { return PrintHexStyle; } + void setPrintHexStyle(HexStyle::Style Value) { PrintHexStyle = Value; } /// Utility function to print immediates in decimal or hex. format_object formatImm(int64_t Value) const { diff --git a/include/llvm/MC/MCInstrDesc.h b/include/llvm/MC/MCInstrDesc.h index de3a1959e05c..3209a2ce0408 100644 --- a/include/llvm/MC/MCInstrDesc.h +++ b/include/llvm/MC/MCInstrDesc.h @@ -125,7 +125,8 @@ enum Flag { ExtraDefRegAllocReq, RegSequence, ExtractSubreg, - InsertSubreg + InsertSubreg, + Convergent }; } @@ -138,10 +139,10 @@ class MCInstrDesc { public: unsigned short Opcode; // The opcode number unsigned short NumOperands; // Num of args (may be more if variable_ops) - unsigned short NumDefs; // Num of args that are definitions + unsigned char NumDefs; // Num of args that are definitions + unsigned char Size; // Number of bytes in encoding. unsigned short SchedClass; // enum identifying instr sched class - unsigned short Size; // Number of bytes in encoding. - unsigned Flags; // Flags identifying machine instr class + uint64_t Flags; // Flags identifying machine instr class uint64_t TSFlags; // Target Specific Flag values const uint16_t *ImplicitUses; // Registers implicitly read by this instr const uint16_t *ImplicitDefs; // Registers implicitly defined by this instr @@ -331,6 +332,13 @@ class MCInstrDesc { /// override accordingly. bool isInsertSubregLike() const { return Flags & (1 << MCID::InsertSubreg); } + + /// \brief Return true if this instruction is convergent. + /// + /// Convergent instructions may only be moved to locations that are + /// control-equivalent to their original positions. + bool isConvergent() const { return Flags & (1 << MCID::Convergent); } + //===--------------------------------------------------------------------===// // Side Effect Analysis //===--------------------------------------------------------------------===// diff --git a/include/llvm/MC/MCLabel.h b/include/llvm/MC/MCLabel.h index de2d0af1423a..a12473fdad02 100644 --- a/include/llvm/MC/MCLabel.h +++ b/include/llvm/MC/MCLabel.h @@ -17,41 +17,41 @@ #include "llvm/Support/Compiler.h" namespace llvm { - class MCContext; - class raw_ostream; +class MCContext; +class raw_ostream; - /// \brief Instances of this class represent a label name in the MC file, - /// and MCLabel are created and uniqued by the MCContext class. MCLabel - /// should only be constructed for valid instances in the object file. - class MCLabel { - // \brief The instance number of this Directional Local Label. - unsigned Instance; +/// \brief Instances of this class represent a label name in the MC file, +/// and MCLabel are created and uniqued by the MCContext class. MCLabel +/// should only be constructed for valid instances in the object file. +class MCLabel { + // \brief The instance number of this Directional Local Label. + unsigned Instance; - private: // MCContext creates and uniques these. - friend class MCContext; - MCLabel(unsigned instance) - : Instance(instance) {} +private: // MCContext creates and uniques these. + friend class MCContext; + MCLabel(unsigned instance) : Instance(instance) {} - MCLabel(const MCLabel&) = delete; - void operator=(const MCLabel&) = delete; - public: - /// \brief Get the current instance of this Directional Local Label. - unsigned getInstance() const { return Instance; } + MCLabel(const MCLabel &) = delete; + void operator=(const MCLabel &) = delete; - /// \brief Increment the current instance of this Directional Local Label. - unsigned incInstance() { return ++Instance; } +public: + /// \brief Get the current instance of this Directional Local Label. + unsigned getInstance() const { return Instance; } - /// \brief Print the value to the stream \p OS. - void print(raw_ostream &OS) const; + /// \brief Increment the current instance of this Directional Local Label. + unsigned incInstance() { return ++Instance; } - /// \brief Print the value to stderr. - void dump() const; - }; + /// \brief Print the value to the stream \p OS. + void print(raw_ostream &OS) const; - inline raw_ostream &operator<<(raw_ostream &OS, const MCLabel &Label) { - Label.print(OS); - return OS; - } + /// \brief Print the value to stderr. + void dump() const; +}; + +inline raw_ostream &operator<<(raw_ostream &OS, const MCLabel &Label) { + Label.print(OS); + return OS; +} } // end namespace llvm #endif diff --git a/include/llvm/MC/MCLinkerOptimizationHint.h b/include/llvm/MC/MCLinkerOptimizationHint.h index a186a14b8001..4b6f7ecc9fba 100644 --- a/include/llvm/MC/MCLinkerOptimizationHint.h +++ b/include/llvm/MC/MCLinkerOptimizationHint.h @@ -106,7 +106,7 @@ class MCLOHDirective { /// Emit this directive in \p OutStream using the information available /// in the given \p ObjWriter and \p Layout to get the address of the /// arguments within the object file. - void Emit_impl(raw_ostream &OutStream, const MachObjectWriter &ObjWriter, + void emit_impl(raw_ostream &OutStream, const MachObjectWriter &ObjWriter, const MCAsmLayout &Layout) const; public: @@ -123,9 +123,9 @@ class MCLOHDirective { /// Emit this directive as: /// - void Emit(MachObjectWriter &ObjWriter, const MCAsmLayout &Layout) const { + void emit(MachObjectWriter &ObjWriter, const MCAsmLayout &Layout) const { raw_ostream &OutStream = ObjWriter.getStream(); - Emit_impl(OutStream, ObjWriter, Layout); + emit_impl(OutStream, ObjWriter, Layout); } /// Get the size in bytes of this directive if emitted in \p ObjWriter with @@ -145,7 +145,7 @@ class MCLOHDirective { }; raw_counting_ostream OutStream; - Emit_impl(OutStream, ObjWriter, Layout); + emit_impl(OutStream, ObjWriter, Layout); return OutStream.tell(); } }; @@ -184,10 +184,10 @@ class MCLOHContainer { } /// Emit all Linker Optimization Hint in one big table. - /// Each line of the table is emitted by LOHDirective::Emit. - void Emit(MachObjectWriter &ObjWriter, const MCAsmLayout &Layout) const { + /// Each line of the table is emitted by LOHDirective::emit. + void emit(MachObjectWriter &ObjWriter, const MCAsmLayout &Layout) const { for (const MCLOHDirective &D : Directives) - D.Emit(ObjWriter, Layout); + D.emit(ObjWriter, Layout); } void reset() { diff --git a/include/llvm/MC/MCMachOSymbolFlags.h b/include/llvm/MC/MCMachOSymbolFlags.h deleted file mode 100644 index 71f01fab2064..000000000000 --- a/include/llvm/MC/MCMachOSymbolFlags.h +++ /dev/null @@ -1,46 +0,0 @@ -//===- MCMachOSymbolFlags.h - MachO Symbol Flags ----------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file declares the SymbolFlags used for the MachO target. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_MC_MCMACHOSYMBOLFLAGS_H -#define LLVM_MC_MCMACHOSYMBOLFLAGS_H - -// These flags are mostly used in MCMachOStreamer.cpp but also needed in -// MachObjectWriter.cpp to test for Weak Definitions of symbols to emit -// the correct relocation information. - -namespace llvm { - /// MachOSymbolFlags - We store the value for the 'desc' symbol field in the - /// lowest 16 bits of the implementation defined flags. - enum MachOSymbolFlags { // See . - SF_DescFlagsMask = 0xFFFF, - - // Reference type flags. - SF_ReferenceTypeMask = 0x0007, - SF_ReferenceTypeUndefinedNonLazy = 0x0000, - SF_ReferenceTypeUndefinedLazy = 0x0001, - SF_ReferenceTypeDefined = 0x0002, - SF_ReferenceTypePrivateDefined = 0x0003, - SF_ReferenceTypePrivateUndefinedNonLazy = 0x0004, - SF_ReferenceTypePrivateUndefinedLazy = 0x0005, - - // Other 'desc' flags. - SF_ThumbFunc = 0x0008, - SF_NoDeadStrip = 0x0020, - SF_WeakReference = 0x0040, - SF_WeakDefinition = 0x0080, - SF_SymbolResolver = 0x0100 - }; - -} // end namespace llvm - -#endif diff --git a/include/llvm/MC/MCMachObjectWriter.h b/include/llvm/MC/MCMachObjectWriter.h index 63c2a28a7c9c..175d73e72c10 100644 --- a/include/llvm/MC/MCMachObjectWriter.h +++ b/include/llvm/MC/MCMachObjectWriter.h @@ -27,15 +27,11 @@ class MCMachObjectTargetWriter { const unsigned Is64Bit : 1; const uint32_t CPUType; const uint32_t CPUSubtype; - // FIXME: Remove this, we should just always use it once we no longer care - // about Darwin 'as' compatibility. - const unsigned UseAggressiveSymbolFolding : 1; unsigned LocalDifference_RIT; protected: MCMachObjectTargetWriter(bool Is64Bit_, uint32_t CPUType_, - uint32_t CPUSubtype_, - bool UseAggressiveSymbolFolding_ = false); + uint32_t CPUSubtype_); void setLocalDifferenceRelocationType(unsigned Type) { LocalDifference_RIT = Type; @@ -47,7 +43,7 @@ class MCMachObjectTargetWriter { /// \name Lifetime Management /// @{ - virtual void reset() {}; + virtual void reset() {} /// @} @@ -55,7 +51,6 @@ class MCMachObjectTargetWriter { /// @{ bool is64Bit() const { return Is64Bit; } - bool useAggressiveSymbolFolding() const { return UseAggressiveSymbolFolding; } uint32_t getCPUType() const { return CPUType; } uint32_t getCPUSubtype() const { return CPUSubtype; } unsigned getLocalDifferenceRelocationType() const { @@ -67,7 +62,7 @@ class MCMachObjectTargetWriter { /// \name API /// @{ - virtual void RecordRelocation(MachObjectWriter *Writer, MCAssembler &Asm, + virtual void recordRelocation(MachObjectWriter *Writer, MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment *Fragment, const MCFixup &Fixup, MCValue Target, @@ -77,8 +72,7 @@ class MCMachObjectTargetWriter { }; class MachObjectWriter : public MCObjectWriter { - /// MachSymbolData - Helper struct for containing some precomputed information - /// on symbols. + /// Helper struct for containing some precomputed information on symbols. struct MachSymbolData { const MCSymbol *Symbol; uint64_t StringIndex; @@ -104,6 +98,8 @@ class MachObjectWriter : public MCObjectWriter { llvm::DenseMap> Relocations; llvm::DenseMap IndirectSymBase; + SectionAddrMap SectionAddress; + /// @} /// \name Symbol Table Data /// @{ @@ -136,8 +132,6 @@ class MachObjectWriter : public MCObjectWriter { bool isFixupKindPCRel(const MCAssembler &Asm, unsigned Kind); - SectionAddrMap SectionAddress; - SectionAddrMap &getSectionAddressMap() { return SectionAddress; } uint64_t getSectionAddress(const MCSection *Sec) const { @@ -165,41 +159,37 @@ class MachObjectWriter : public MCObjectWriter { /// @} - void WriteHeader(unsigned NumLoadCommands, unsigned LoadCommandsSize, + void writeHeader(unsigned NumLoadCommands, unsigned LoadCommandsSize, bool SubsectionsViaSymbols); - /// WriteSegmentLoadCommand - Write a segment load command. + /// Write a segment load command. /// /// \param NumSections The number of sections in this segment. /// \param SectionDataSize The total size of the sections. - void WriteSegmentLoadCommand(unsigned NumSections, - uint64_t VMSize, + void writeSegmentLoadCommand(unsigned NumSections, uint64_t VMSize, uint64_t SectionDataStartOffset, uint64_t SectionDataSize); - void WriteSection(const MCAssembler &Asm, const MCAsmLayout &Layout, + void writeSection(const MCAssembler &Asm, const MCAsmLayout &Layout, const MCSection &Sec, uint64_t FileOffset, uint64_t RelocationsStart, unsigned NumRelocations); - void WriteSymtabLoadCommand(uint32_t SymbolOffset, uint32_t NumSymbols, + void writeSymtabLoadCommand(uint32_t SymbolOffset, uint32_t NumSymbols, uint32_t StringTableOffset, uint32_t StringTableSize); - void WriteDysymtabLoadCommand(uint32_t FirstLocalSymbol, - uint32_t NumLocalSymbols, - uint32_t FirstExternalSymbol, - uint32_t NumExternalSymbols, - uint32_t FirstUndefinedSymbol, - uint32_t NumUndefinedSymbols, - uint32_t IndirectSymbolOffset, - uint32_t NumIndirectSymbols); + void writeDysymtabLoadCommand( + uint32_t FirstLocalSymbol, uint32_t NumLocalSymbols, + uint32_t FirstExternalSymbol, uint32_t NumExternalSymbols, + uint32_t FirstUndefinedSymbol, uint32_t NumUndefinedSymbols, + uint32_t IndirectSymbolOffset, uint32_t NumIndirectSymbols); - void WriteNlist(MachSymbolData &MSD, const MCAsmLayout &Layout); + void writeNlist(MachSymbolData &MSD, const MCAsmLayout &Layout); - void WriteLinkeditLoadCommand(uint32_t Type, uint32_t DataOffset, + void writeLinkeditLoadCommand(uint32_t Type, uint32_t DataOffset, uint32_t DataSize); - void WriteLinkerOptionsLoadCommand(const std::vector &Options); + void writeLinkerOptionsLoadCommand(const std::vector &Options); // FIXME: We really need to improve the relocation validation. Basically, we // want to implement a separate computation which evaluates the relocation @@ -226,29 +216,25 @@ class MachObjectWriter : public MCObjectWriter { Relocations[Sec].push_back(P); } - void RecordScatteredRelocation(const MCAssembler &Asm, + void recordScatteredRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment *Fragment, const MCFixup &Fixup, MCValue Target, - unsigned Log2Size, - uint64_t &FixedValue); + unsigned Log2Size, uint64_t &FixedValue); - void RecordTLVPRelocation(const MCAssembler &Asm, - const MCAsmLayout &Layout, - const MCFragment *Fragment, - const MCFixup &Fixup, MCValue Target, - uint64_t &FixedValue); + void recordTLVPRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout, + const MCFragment *Fragment, const MCFixup &Fixup, + MCValue Target, uint64_t &FixedValue); - void RecordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout, + void recordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment *Fragment, const MCFixup &Fixup, MCValue Target, bool &IsPCRel, uint64_t &FixedValue) override; - void BindIndirectSymbols(MCAssembler &Asm); + void bindIndirectSymbols(MCAssembler &Asm); - /// ComputeSymbolTable - Compute the symbol table data - /// - void ComputeSymbolTable(MCAssembler &Asm, + /// Compute the symbol table data. + void computeSymbolTable(MCAssembler &Asm, std::vector &LocalSymbolData, std::vector &ExternalSymbolData, std::vector &UndefinedSymbolData); @@ -256,19 +242,18 @@ class MachObjectWriter : public MCObjectWriter { void computeSectionAddresses(const MCAssembler &Asm, const MCAsmLayout &Layout); - void ExecutePostLayoutBinding(MCAssembler &Asm, + void executePostLayoutBinding(MCAssembler &Asm, const MCAsmLayout &Layout) override; - bool IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, + bool isSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, const MCSymbol &SymA, const MCFragment &FB, bool InSet, bool IsPCRel) const override; - void WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout) override; + void writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) override; }; - -/// \brief Construct a new Mach-O writer instance. +/// Construct a new Mach-O writer instance. /// /// This routine takes ownership of the target writer subclass. /// diff --git a/include/llvm/MC/MCObjectFileInfo.h b/include/llvm/MC/MCObjectFileInfo.h index f28b9c668cdc..0515f1cd738d 100644 --- a/include/llvm/MC/MCObjectFileInfo.h +++ b/include/llvm/MC/MCObjectFileInfo.h @@ -18,28 +18,25 @@ #include "llvm/Support/CodeGen.h" namespace llvm { - class MCContext; - class MCSection; - class StringRef; +class MCContext; +class MCSection; +class StringRef; class MCObjectFileInfo { protected: - /// CommDirectiveSupportsAlignment - True if .comm supports alignment. This - /// is a hack for as long as we support 10.4 Tiger, whose assembler doesn't - /// support alignment on comm. + /// True if .comm supports alignment. This is a hack for as long as we + /// support 10.4 Tiger, whose assembler doesn't support alignment on comm. bool CommDirectiveSupportsAlignment; - /// SupportsWeakEmptyEHFrame - True if target object file supports a - /// weak_definition of constant 0 for an omitted EH frame. + /// True if target object file supports a weak_definition of constant 0 for an + /// omitted EH frame. bool SupportsWeakOmittedEHFrame; - /// SupportsCompactUnwindWithoutEHFrame - True if the target object file - /// supports emitting a compact unwind section without an associated EH frame - /// section. + /// True if the target object file supports emitting a compact unwind section + /// without an associated EH frame section. bool SupportsCompactUnwindWithoutEHFrame; - /// PersonalityEncoding, LSDAEncoding, TTypeEncoding - Some encoding values - /// for EH. + /// Some encoding values for EH. unsigned PersonalityEncoding; unsigned LSDAEncoding; unsigned FDECFIEncoding; @@ -49,16 +46,13 @@ class MCObjectFileInfo { unsigned EHSectionType; unsigned EHSectionFlags; - /// CompactUnwindDwarfEHFrameOnly - Compact unwind encoding indicating that we - /// should emit only an EH frame. + /// Compact unwind encoding indicating that we should emit only an EH frame. unsigned CompactUnwindDwarfEHFrameOnly; /// Section directive for standard text. - /// MCSection *TextSection; /// Section directive for standard data. - /// MCSection *DataSection; /// Section that is default initialized to zero. @@ -101,7 +95,7 @@ class MCObjectFileInfo { // can be enabled by a compiler flag. MCSection *DwarfPubNamesSection; - // DWARF5 Experimental Debug Info Sections + /// DWARF5 Experimental Debug Info Sections /// DwarfAccelNamesSection, DwarfAccelObjCSection, /// DwarfAccelNamespaceSection, DwarfAccelTypesSection - /// If we use the DWARF accelerated hash tables then we want to emit these @@ -111,7 +105,7 @@ class MCObjectFileInfo { MCSection *DwarfAccelNamespaceSection; MCSection *DwarfAccelTypesSection; - /// These are used for the Fission separate debug information files. + // These are used for the Fission separate debug information files. MCSection *DwarfInfoDWOSection; MCSection *DwarfTypesDWOSection; MCSection *DwarfAbbrevDWOSection; @@ -121,32 +115,36 @@ class MCObjectFileInfo { MCSection *DwarfStrOffDWOSection; MCSection *DwarfAddrSection; - /// Sections for newer gnu pubnames and pubtypes. + /// Section for newer gnu pubnames. MCSection *DwarfGnuPubNamesSection; + /// Section for newer gnu pubtypes. MCSection *DwarfGnuPubTypesSection; MCSection *COFFDebugSymbolsSection; - // Extra TLS Variable Data section. If the target needs to put additional - // information for a TLS variable, it'll go here. + /// Extra TLS Variable Data section. + /// + /// If the target needs to put additional information for a TLS variable, + /// it'll go here. MCSection *TLSExtraDataSection; /// Section directive for Thread Local data. ELF, MachO and COFF. MCSection *TLSDataSection; // Defaults to ".tdata". - /// Section directive for Thread Local uninitialized data. Null if this target - /// doesn't support a BSS section. ELF and MachO only. + /// Section directive for Thread Local uninitialized data. + /// + /// Null if this target doesn't support a BSS section. ELF and MachO only. MCSection *TLSBSSSection; // Defaults to ".tbss". /// StackMap section. MCSection *StackMapSection; - /// EH frame section. It is initialized on demand so it can be overwritten - /// (with uniquing). + /// EH frame section. + /// + /// It is initialized on demand so it can be overwritten (with uniquing). MCSection *EHFrameSection; - /// ELF specific sections. - /// + // ELF specific sections. MCSection *DataRelSection; const MCSection *DataRelLocalSection; MCSection *DataRelROSection; @@ -155,17 +153,16 @@ class MCObjectFileInfo { MCSection *MergeableConst8Section; MCSection *MergeableConst16Section; - /// MachO specific sections. - /// + // MachO specific sections. - /// Section for thread local structure information. Contains the source code - /// name of the variable, visibility and a pointer to the initial value - /// (.tdata or .tbss). + /// Section for thread local structure information. + /// + /// Contains the source code name of the variable, visibility and a pointer to + /// the initial value (.tdata or .tbss). MCSection *TLSTLVSection; // Defaults to ".tlv". - /// TLSThreadInitSection - Section for thread local data initialization - /// functions. - const MCSection *TLSThreadInitSection; // Defaults to ".thread_init_func". + /// Section for thread local data initialization functions. + const MCSection *TLSThreadInitSection; // Defaults to ".thread_init_func". MCSection *CStringSection; MCSection *UStringSection; @@ -182,10 +179,10 @@ class MCObjectFileInfo { MCSection *NonLazySymbolPointerSection; /// COFF specific sections. - /// MCSection *DrectveSection; MCSection *PDataSection; MCSection *XDataSection; + MCSection *SXDataSection; public: void InitMCObjectFileInfo(StringRef TT, Reloc::Model RM, CodeModel::Model CM, @@ -266,8 +263,7 @@ class MCObjectFileInfo { MCSection *getStackMapSection() const { return StackMapSection; } - /// ELF specific sections. - /// + // ELF specific sections. MCSection *getDataRelSection() const { return DataRelSection; } const MCSection *getDataRelLocalSection() const { return DataRelLocalSection; @@ -284,8 +280,7 @@ class MCObjectFileInfo { return MergeableConst16Section; } - /// MachO specific sections. - /// + // MachO specific sections. const MCSection *getTLSTLVSection() const { return TLSTLVSection; } const MCSection *getTLSThreadInitSection() const { return TLSThreadInitSection; @@ -316,11 +311,11 @@ class MCObjectFileInfo { return NonLazySymbolPointerSection; } - /// COFF specific sections. - /// + // COFF specific sections. MCSection *getDrectveSection() const { return DrectveSection; } MCSection *getPDataSection() const { return PDataSection; } MCSection *getXDataSection() const { return XDataSection; } + MCSection *getSXDataSection() const { return SXDataSection; } MCSection *getEHFrameSection() { if (!EHFrameSection) @@ -329,13 +324,9 @@ class MCObjectFileInfo { } enum Environment { IsMachO, IsELF, IsCOFF }; - Environment getObjectFileType() const { - return Env; - } + Environment getObjectFileType() const { return Env; } - Reloc::Model getRelocM() const { - return RelocM; - } + Reloc::Model getRelocM() const { return RelocM; } private: Environment Env; @@ -344,12 +335,11 @@ class MCObjectFileInfo { MCContext *Ctx; Triple TT; - void InitMachOMCObjectFileInfo(Triple T); - void InitELFMCObjectFileInfo(Triple T); - void InitCOFFMCObjectFileInfo(Triple T); + void initMachOMCObjectFileInfo(Triple T); + void initELFMCObjectFileInfo(Triple T); + void initCOFFMCObjectFileInfo(Triple T); - /// InitEHFrameSection - Initialize EHFrameSection on demand. - /// + /// Initialize EHFrameSection on demand. void InitEHFrameSection(); public: diff --git a/include/llvm/MC/MCObjectStreamer.h b/include/llvm/MC/MCObjectStreamer.h index e75bc86cc131..462b3b484c58 100644 --- a/include/llvm/MC/MCObjectStreamer.h +++ b/include/llvm/MC/MCObjectStreamer.h @@ -35,11 +35,10 @@ class raw_pwrite_stream; /// implementation. class MCObjectStreamer : public MCStreamer { MCAssembler *Assembler; - MCSection *CurSectionData; MCSection::iterator CurInsertionPoint; bool EmitEHFrame; bool EmitDebugFrame; - SmallVector PendingLabels; + SmallVector PendingLabels; virtual void EmitInstToData(const MCInst &Inst, const MCSubtargetInfo&) = 0; void EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) override; @@ -57,21 +56,17 @@ class MCObjectStreamer : public MCStreamer { /// Object streamers require the integrated assembler. bool isIntegratedAssemblerRequired() const override { return true; } - MCSymbolData &getOrCreateSymbolData(const MCSymbol *Symbol) { - return getAssembler().getOrCreateSymbolData(*Symbol); - } void EmitFrames(MCAsmBackend *MAB); void EmitCFISections(bool EH, bool Debug) override; protected: - MCSection *getCurrentSectionData() const { return CurSectionData; } - MCFragment *getCurrentFragment() const; void insert(MCFragment *F) { flushPendingLabels(F); - CurSectionData->getFragmentList().insert(CurInsertionPoint, F); - F->setParent(CurSectionData); + MCSection *CurSection = getCurrentSectionOnly(); + CurSection->getFragmentList().insert(CurInsertionPoint, F); + F->setParent(CurSection); } /// Get a data fragment to write into, creating a new one if the current diff --git a/include/llvm/MC/MCObjectWriter.h b/include/llvm/MC/MCObjectWriter.h index 999d29471270..2211673efc31 100644 --- a/include/llvm/MC/MCObjectWriter.h +++ b/include/llvm/MC/MCObjectWriter.h @@ -22,18 +22,17 @@ class MCAsmLayout; class MCAssembler; class MCFixup; class MCFragment; -class MCSymbolData; class MCSymbolRefExpr; class MCValue; -/// MCObjectWriter - Defines the object file and target independent interfaces -/// used by the assembler backend to write native file format object files. +/// Defines the object file and target independent interfaces used by the +/// assembler backend to write native file format object files. /// /// The object writer contains a few callbacks used by the assembler to allow /// the object writer to modify the assembler data structures at appropriate /// points. Once assembly is complete, the object writer is given the /// MCAssembler instance, which contains all the symbol and section data which -/// should be emitted as part of WriteObject(). +/// should be emitted as part of writeObject(). /// /// The object writer also contains a number of helper methods for writing /// binary data to the output stream. @@ -54,7 +53,7 @@ class MCObjectWriter { virtual ~MCObjectWriter(); /// lifetime management - virtual void reset() { } + virtual void reset() {} bool isLittleEndian() const { return IsLittleEndian; } @@ -63,109 +62,106 @@ class MCObjectWriter { /// \name High-Level API /// @{ - /// \brief Perform any late binding of symbols (for example, to assign symbol + /// Perform any late binding of symbols (for example, to assign symbol /// indices for use when generating relocations). /// /// This routine is called by the assembler after layout and relaxation is /// complete. - virtual void ExecutePostLayoutBinding(MCAssembler &Asm, + virtual void executePostLayoutBinding(MCAssembler &Asm, const MCAsmLayout &Layout) = 0; - /// \brief Record a relocation entry. + /// Record a relocation entry. /// /// This routine is called by the assembler after layout and relaxation, and /// post layout binding. The implementation is responsible for storing /// information about the relocation so that it can be emitted during - /// WriteObject(). - virtual void RecordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout, + /// writeObject(). + virtual void recordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment *Fragment, const MCFixup &Fixup, MCValue Target, bool &IsPCRel, uint64_t &FixedValue) = 0; - /// \brief Check whether the difference (A - B) between two symbol - /// references is fully resolved. + /// Check whether the difference (A - B) between two symbol references is + /// fully resolved. /// /// Clients are not required to answer precisely and may conservatively return /// false, even when a difference is fully resolved. - bool IsSymbolRefDifferenceFullyResolved(const MCAssembler &Asm, + bool isSymbolRefDifferenceFullyResolved(const MCAssembler &Asm, const MCSymbolRefExpr *A, const MCSymbolRefExpr *B, bool InSet) const; - virtual bool IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, + virtual bool isSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, const MCSymbol &SymA, const MCFragment &FB, bool InSet, bool IsPCRel) const; - /// \brief True if this symbol (which is a variable) is weak. This is not + /// True if this symbol (which is a variable) is weak. This is not /// just STB_WEAK, but more generally whether or not we can evaluate /// past it. virtual bool isWeak(const MCSymbol &Sym) const; - /// \brief Write the object file. + /// Write the object file. /// /// This routine is called by the assembler after layout and relaxation is /// complete, fixups have been evaluated and applied, and relocations /// generated. - virtual void WriteObject(MCAssembler &Asm, - const MCAsmLayout &Layout) = 0; + virtual void writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) = 0; /// @} /// \name Binary Output /// @{ - void Write8(uint8_t Value) { - OS << char(Value); - } + void write8(uint8_t Value) { OS << char(Value); } - void WriteLE16(uint16_t Value) { + void writeLE16(uint16_t Value) { support::endian::Writer(OS).write(Value); } - void WriteLE32(uint32_t Value) { + void writeLE32(uint32_t Value) { support::endian::Writer(OS).write(Value); } - void WriteLE64(uint64_t Value) { + void writeLE64(uint64_t Value) { support::endian::Writer(OS).write(Value); } - void WriteBE16(uint16_t Value) { + void writeBE16(uint16_t Value) { support::endian::Writer(OS).write(Value); } - void WriteBE32(uint32_t Value) { + void writeBE32(uint32_t Value) { support::endian::Writer(OS).write(Value); } - void WriteBE64(uint64_t Value) { + void writeBE64(uint64_t Value) { support::endian::Writer(OS).write(Value); } - void Write16(uint16_t Value) { + void write16(uint16_t Value) { if (IsLittleEndian) - WriteLE16(Value); + writeLE16(Value); else - WriteBE16(Value); + writeBE16(Value); } - void Write32(uint32_t Value) { + void write32(uint32_t Value) { if (IsLittleEndian) - WriteLE32(Value); + writeLE32(Value); else - WriteBE32(Value); + writeBE32(Value); } - void Write64(uint64_t Value) { + void write64(uint64_t Value) { if (IsLittleEndian) - WriteLE64(Value); + writeLE64(Value); else - WriteBE64(Value); + writeBE64(Value); } void WriteZeros(unsigned N) { - const char Zeros[16] = { 0 }; + const char Zeros[16] = {0}; for (unsigned i = 0, e = N / 16; i != e; ++i) OS << StringRef(Zeros, 16); @@ -173,22 +169,23 @@ class MCObjectWriter { OS << StringRef(Zeros, N % 16); } - void WriteBytes(const SmallVectorImpl &ByteVec, unsigned ZeroFillSize = 0) { - WriteBytes(StringRef(ByteVec.data(), ByteVec.size()), ZeroFillSize); + void writeBytes(const SmallVectorImpl &ByteVec, + unsigned ZeroFillSize = 0) { + writeBytes(StringRef(ByteVec.data(), ByteVec.size()), ZeroFillSize); } - void WriteBytes(StringRef Str, unsigned ZeroFillSize = 0) { + void writeBytes(StringRef Str, unsigned ZeroFillSize = 0) { // TODO: this version may need to go away once all fragment contents are // converted to SmallVector - assert((ZeroFillSize == 0 || Str.size () <= ZeroFillSize) && - "data size greater than fill size, unexpected large write will occur"); + assert( + (ZeroFillSize == 0 || Str.size() <= ZeroFillSize) && + "data size greater than fill size, unexpected large write will occur"); OS << Str; if (ZeroFillSize) WriteZeros(ZeroFillSize - Str.size()); } /// @} - }; } // End llvm namespace diff --git a/include/llvm/MC/MCSection.h b/include/llvm/MC/MCSection.h index 96a4ef135f21..5f6e8ec1d506 100644 --- a/include/llvm/MC/MCSection.h +++ b/include/llvm/MC/MCSection.h @@ -73,11 +73,13 @@ class MCSection { /// \brief We've seen a bundle_lock directive but not its first instruction /// yet. - bool BundleGroupBeforeFirstInst = false; + unsigned BundleGroupBeforeFirstInst : 1; /// Whether this section has had instructions emitted into it. unsigned HasInstructions : 1; + unsigned IsRegistered : 1; + FragmentListType Fragments; /// Mapping from subsection number to insertion point for subsection numbers @@ -130,6 +132,9 @@ class MCSection { bool hasInstructions() const { return HasInstructions; } void setHasInstructions(bool Value) { HasInstructions = Value; } + bool isRegistered() const { return IsRegistered; } + void setIsRegistered(bool Value) { IsRegistered = Value; } + MCSection::FragmentListType &getFragmentList() { return Fragments; } const MCSection::FragmentListType &getFragmentList() const { return const_cast(this)->getFragmentList(); diff --git a/include/llvm/MC/MCSectionELF.h b/include/llvm/MC/MCSectionELF.h index 9efe1022f295..f6730371fe15 100644 --- a/include/llvm/MC/MCSectionELF.h +++ b/include/llvm/MC/MCSectionELF.h @@ -16,7 +16,7 @@ #include "llvm/ADT/Twine.h" #include "llvm/MC/MCSection.h" -#include "llvm/MC/MCSymbol.h" +#include "llvm/MC/MCSymbolELF.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ELF.h" #include "llvm/Support/raw_ostream.h" @@ -46,7 +46,7 @@ class MCSectionELF : public MCSection { /// section does not contain fixed-sized entries 'EntrySize' will be 0. unsigned EntrySize; - const MCSymbol *Group; + const MCSymbolELF *Group; /// Depending on the type of the section this is sh_link or sh_info. const MCSectionELF *Associated; @@ -54,11 +54,14 @@ class MCSectionELF : public MCSection { private: friend class MCContext; MCSectionELF(StringRef Section, unsigned type, unsigned flags, SectionKind K, - unsigned entrySize, const MCSymbol *group, unsigned UniqueID, + unsigned entrySize, const MCSymbolELF *group, unsigned UniqueID, MCSymbol *Begin, const MCSectionELF *Associated) : MCSection(SV_ELF, K, Begin), SectionName(Section), Type(type), Flags(flags), UniqueID(UniqueID), EntrySize(entrySize), Group(group), - Associated(Associated) {} + Associated(Associated) { + if (Group) + Group->setIsSignature(); + } ~MCSectionELF() override; void setSectionName(StringRef Name) { SectionName = Name; } @@ -73,7 +76,7 @@ class MCSectionELF : public MCSection { unsigned getType() const { return Type; } unsigned getFlags() const { return Flags; } unsigned getEntrySize() const { return EntrySize; } - const MCSymbol *getGroup() const { return Group; } + const MCSymbolELF *getGroup() const { return Group; } void PrintSwitchToSection(const MCAsmInfo &MAI, raw_ostream &OS, const MCExpr *Subsection) const override; diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h index 957913e934c4..628fb768856e 100644 --- a/include/llvm/MC/MCStreamer.h +++ b/include/llvm/MC/MCStreamer.h @@ -34,6 +34,7 @@ class MCInstPrinter; class MCSection; class MCStreamer; class MCSymbol; +class MCSymbolELF; class MCSymbolRefExpr; class MCSubtargetInfo; class StringRef; @@ -272,6 +273,7 @@ class MCStreamer { return SectionStack.back().first; return MCSectionSubPair(); } + MCSection *getCurrentSectionOnly() const { return getCurrentSection().first; } /// \brief Return the previous section that the streamer is emitting code to. MCSectionSubPair getPreviousSection() const { @@ -305,11 +307,15 @@ class MCStreamer { bool PopSection() { if (SectionStack.size() <= 1) return false; - MCSectionSubPair oldSection = SectionStack.pop_back_val().first; - MCSectionSubPair curSection = SectionStack.back().first; + auto I = SectionStack.end(); + --I; + MCSectionSubPair OldSection = I->first; + --I; + MCSectionSubPair NewSection = I->first; - if (oldSection != curSection) - ChangeSection(curSection.first, curSection.second); + if (OldSection != NewSection) + ChangeSection(NewSection.first, NewSection.second); + SectionStack.pop_back(); return true; } @@ -433,6 +439,8 @@ class MCStreamer { /// \brief Marks the end of the symbol definition. virtual void EndCOFFSymbolDef(); + virtual void EmitCOFFSafeSEH(MCSymbol const *Symbol); + /// \brief Emits a COFF section index. /// /// \param Symbol - Symbol the section number relocation should point to. @@ -447,7 +455,7 @@ class MCStreamer { /// /// This corresponds to an assembler statement such as: /// .size symbol, expression - virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value); + virtual void emitELFSize(MCSymbolELF *Symbol, const MCExpr *Value); /// \brief Emit a Linker Optimization Hint (LOH) directive. /// \param Args - Arguments of the LOH. diff --git a/include/llvm/MC/MCSubtargetInfo.h b/include/llvm/MC/MCSubtargetInfo.h index 1778a6d13fb8..ee5d56334a2f 100644 --- a/include/llvm/MC/MCSubtargetInfo.h +++ b/include/llvm/MC/MCSubtargetInfo.h @@ -73,7 +73,9 @@ class MCSubtargetInfo { /// setFeatureBits - Set the feature bits. /// - void setFeatureBits(FeatureBitset& FeatureBits_) { FeatureBits = FeatureBits_; } + void setFeatureBits(const FeatureBitset &FeatureBits_) { + FeatureBits = FeatureBits_; + } /// InitMCProcessorInfo - Set or change the CPU (optionally supplemented with /// feature string). Recompute feature bits and scheduling model. @@ -94,6 +96,10 @@ class MCSubtargetInfo { /// feature bits. This version will also change all implied bits. FeatureBitset ToggleFeature(StringRef FS); + /// Apply a feature flag and return the re-computed feature bits, including + /// all feature bits implied by the flag. + FeatureBitset ApplyFeatureFlag(StringRef FS); + /// getSchedModelForCPU - Get the machine model of a CPU. /// MCSchedModel getSchedModelForCPU(StringRef CPU) const; diff --git a/include/llvm/MC/MCSymbol.h b/include/llvm/MC/MCSymbol.h index cf99c919281e..078f3d77e55c 100644 --- a/include/llvm/MC/MCSymbol.h +++ b/include/llvm/MC/MCSymbol.h @@ -14,12 +14,14 @@ #ifndef LLVM_MC_MCSYMBOL_H #define LLVM_MC_MCSYMBOL_H -#include "llvm/ADT/PointerIntPair.h" +#include "llvm/ADT/PointerUnion.h" #include "llvm/ADT/StringMap.h" +#include "llvm/MC/MCAssembler.h" #include "llvm/MC/MCExpr.h" #include "llvm/Support/Compiler.h" namespace llvm { +class MCAsmInfo; class MCExpr; class MCSymbol; class MCFragment; @@ -27,109 +29,6 @@ class MCSection; class MCContext; class raw_ostream; -// TODO: Merge completely with MCSymbol. -class MCSymbolData { - /// Fragment - The fragment this symbol's value is relative to, if any. Also - /// stores if this symbol is visible outside this translation unit (bit 0) or - /// if it is private extern (bit 1). - PointerIntPair Fragment; - - union { - /// Offset - The offset to apply to the fragment address to form this - /// symbol's value. - uint64_t Offset; - - /// CommonSize - The size of the symbol, if it is 'common'. - uint64_t CommonSize; - }; - - /// SymbolSize - An expression describing how to calculate the size of - /// a symbol. If a symbol has no size this field will be NULL. - const MCExpr *SymbolSize = nullptr; - - /// CommonAlign - The alignment of the symbol, if it is 'common', or -1. - // - // FIXME: Pack this in with other fields? - unsigned CommonAlign = -1U; - - /// Flags - The Flags field is used by object file implementations to store - /// additional per symbol information which is not easily classified. - uint32_t Flags = 0; - -public: - MCSymbolData() { Offset = 0; } - - MCFragment *getFragment() const { return Fragment.getPointer(); } - void setFragment(MCFragment *Value) { Fragment.setPointer(Value); } - - uint64_t getOffset() const { - assert(!isCommon()); - return Offset; - } - void setOffset(uint64_t Value) { - assert(!isCommon()); - Offset = Value; - } - - /// @} - /// \name Symbol Attributes - /// @{ - - bool isExternal() const { return Fragment.getInt() & 1; } - void setExternal(bool Value) { - Fragment.setInt((Fragment.getInt() & ~1) | unsigned(Value)); - } - - bool isPrivateExtern() const { return Fragment.getInt() & 2; } - void setPrivateExtern(bool Value) { - Fragment.setInt((Fragment.getInt() & ~2) | (unsigned(Value) << 1)); - } - - /// isCommon - Is this a 'common' symbol. - bool isCommon() const { return CommonAlign != -1U; } - - /// setCommon - Mark this symbol as being 'common'. - /// - /// \param Size - The size of the symbol. - /// \param Align - The alignment of the symbol. - void setCommon(uint64_t Size, unsigned Align) { - assert(getOffset() == 0); - CommonSize = Size; - CommonAlign = Align; - } - - /// getCommonSize - Return the size of a 'common' symbol. - uint64_t getCommonSize() const { - assert(isCommon() && "Not a 'common' symbol!"); - return CommonSize; - } - - void setSize(const MCExpr *SS) { SymbolSize = SS; } - - const MCExpr *getSize() const { return SymbolSize; } - - /// getCommonAlignment - Return the alignment of a 'common' symbol. - unsigned getCommonAlignment() const { - assert(isCommon() && "Not a 'common' symbol!"); - return CommonAlign; - } - - /// getFlags - Get the (implementation defined) symbol flags. - uint32_t getFlags() const { return Flags; } - - /// setFlags - Set the (implementation defined) symbol flags. - void setFlags(uint32_t Value) { Flags = Value; } - - /// modifyFlags - Modify the flags via a mask - void modifyFlags(uint32_t Value, uint32_t Mask) { - Flags = (Flags & ~Mask) | Value; - } - - /// @} - - void dump() const; -}; - /// MCSymbol - Instances of this class represent a symbol name in the MC file, /// and MCSymbols are created and uniqued by the MCContext class. MCSymbols /// should only be constructed with valid names for the object file. @@ -138,6 +37,16 @@ class MCSymbolData { /// Section member is set to indicate what section it lives in. Otherwise, if /// it is a reference to an external entity, it has a null section. class MCSymbol { +protected: + /// The kind of the symbol. If it is any value other than unset then this + /// class is actually one of the appropriate subclasses of MCSymbol. + enum SymbolKind { + SymbolKindUnset, + SymbolKindCOFF, + SymbolKindELF, + SymbolKindMachO, + }; + // Special sentinal value for the absolute pseudo section. // // FIXME: Use a PointerInt wrapper for this? @@ -147,10 +56,18 @@ class MCSymbol { /// held by the StringMap that lives in MCContext. const StringMapEntry *Name; - /// The section the symbol is defined in. This is null for undefined symbols, - /// and the special AbsolutePseudoSection value for absolute symbols. If this - /// is a variable symbol, this caches the variable value's section. - mutable MCSection *Section; + /// If a symbol has a Fragment, the section is implied, so we only need + /// one pointer. + /// FIXME: We might be able to simplify this by having the asm streamer create + /// dummy fragments. + /// If this is a section, then it gives the symbol is defined in. This is null + /// for undefined symbols, and the special AbsolutePseudoSection value for + /// absolute symbols. If this is a variable symbol, this caches the variable + /// value's section. + /// + /// If this is a fragment, then it gives the fragment this symbol's value is + /// relative to, if any. + mutable PointerUnion SectionOrFragment; /// Value - If non-null, the value for a variable symbol. const MCExpr *Value; @@ -166,46 +83,68 @@ class MCSymbol { /// IsUsed - True if this symbol has been used. mutable unsigned IsUsed : 1; - mutable bool HasData : 1; + mutable bool IsRegistered : 1; + + /// This symbol is visible outside this translation unit. + mutable unsigned IsExternal : 1; + + /// This symbol is private extern. + mutable unsigned IsPrivateExtern : 1; + + /// LLVM RTTI discriminator. This is actually a SymbolKind enumerator, but is + /// unsigned to avoid sign extension and achieve better bitpacking with MSVC. + unsigned Kind : 2; /// Index field, for use by the object file implementation. - mutable uint64_t Index : 60; + mutable uint32_t Index = 0; - mutable MCSymbolData Data; + union { + /// The offset to apply to the fragment address to form this symbol's value. + uint64_t Offset; -private: // MCContext creates and uniques these. + /// The size of the symbol, if it is 'common'. + uint64_t CommonSize; + }; + + /// The alignment of the symbol, if it is 'common', or -1. + // + // FIXME: Pack this in with other fields? + unsigned CommonAlign = -1U; + + /// The Flags field is used by object file implementations to store + /// additional per symbol information which is not easily classified. + mutable uint32_t Flags = 0; + +protected: // MCContext creates and uniques these. friend class MCExpr; friend class MCContext; - MCSymbol(const StringMapEntry *Name, bool isTemporary) - : Name(Name), Section(nullptr), Value(nullptr), IsTemporary(isTemporary), - IsRedefinable(false), IsUsed(false), HasData(false), Index(0) {} + MCSymbol(SymbolKind Kind, const StringMapEntry *Name, bool isTemporary) + : Name(Name), Value(nullptr), IsTemporary(isTemporary), + IsRedefinable(false), IsUsed(false), IsRegistered(false), + IsExternal(false), IsPrivateExtern(false), + Kind(Kind) { + Offset = 0; + } +private: MCSymbol(const MCSymbol &) = delete; void operator=(const MCSymbol &) = delete; MCSection *getSectionPtr() const { + if (MCFragment *F = getFragment()) + return F->getParent(); + assert(!SectionOrFragment.is() && "Section or null expected"); + MCSection *Section = SectionOrFragment.dyn_cast(); if (Section || !Value) return Section; - return Section = Value->FindAssociatedSection(); + return Section = Value->findAssociatedSection(); } public: /// getName - Get the symbol name. StringRef getName() const { return Name ? Name->first() : ""; } - bool hasData() const { return HasData; } - - /// Get associated symbol data. - MCSymbolData &getData() const { - assert(HasData && "Missing symbol data!"); - return Data; - } - - /// Initialize symbol data. - /// - /// Nothing really to do here, but this is enables an assertion that \a - /// MCAssembler::getOrCreateSymbolData() has actually been called before - /// anyone calls \a getData(). - void initializeData() const { HasData = true; } + bool isRegistered() const { return IsRegistered; } + void setIsRegistered(bool Value) const { IsRegistered = Value; } /// \name Accessors /// @{ @@ -225,7 +164,7 @@ class MCSymbol { void redefineIfPossible() { if (IsRedefinable) { Value = nullptr; - Section = nullptr; + SectionOrFragment = nullptr; IsRedefinable = false; } } @@ -258,11 +197,20 @@ class MCSymbol { /// Mark the symbol as defined in the section \p S. void setSection(MCSection &S) { assert(!isVariable() && "Cannot set section of variable"); - Section = &S; + assert(!SectionOrFragment.is() && "Section or null expected"); + SectionOrFragment = &S; } - /// setUndefined - Mark the symbol as undefined. - void setUndefined() { Section = nullptr; } + /// Mark the symbol as undefined. + void setUndefined() { + SectionOrFragment = nullptr; + } + + bool isELF() const { return Kind == SymbolKindELF; } + + bool isCOFF() const { return Kind == SymbolKindCOFF; } + + bool isMachO() const { return Kind == SymbolKindMachO; } /// @} /// \name Variable Symbols @@ -283,27 +231,98 @@ class MCSymbol { /// @} /// Get the (implementation defined) index. - uint64_t getIndex() const { - assert(HasData && "Uninitialized symbol data"); + uint32_t getIndex() const { return Index; } /// Set the (implementation defined) index. - void setIndex(uint64_t Value) const { - assert(HasData && "Uninitialized symbol data"); - assert(!(Value >> 60) && "Not enough bits for value"); + void setIndex(uint32_t Value) const { Index = Value; } + uint64_t getOffset() const { + assert(!isCommon()); + return Offset; + } + void setOffset(uint64_t Value) { + assert(!isCommon()); + Offset = Value; + } + + /// Return the size of a 'common' symbol. + uint64_t getCommonSize() const { + assert(isCommon() && "Not a 'common' symbol!"); + return CommonSize; + } + + /// Mark this symbol as being 'common'. + /// + /// \param Size - The size of the symbol. + /// \param Align - The alignment of the symbol. + void setCommon(uint64_t Size, unsigned Align) { + assert(getOffset() == 0); + CommonSize = Size; + CommonAlign = Align; + } + + /// Return the alignment of a 'common' symbol. + unsigned getCommonAlignment() const { + assert(isCommon() && "Not a 'common' symbol!"); + return CommonAlign; + } + + /// Declare this symbol as being 'common'. + /// + /// \param Size - The size of the symbol. + /// \param Align - The alignment of the symbol. + /// \return True if symbol was already declared as a different type + bool declareCommon(uint64_t Size, unsigned Align) { + assert(isCommon() || getOffset() == 0); + if(isCommon()) { + if(CommonSize != Size || CommonAlign != Align) + return true; + } else + setCommon(Size, Align); + return false; + } + + /// Is this a 'common' symbol. + bool isCommon() const { return CommonAlign != -1U; } + + MCFragment *getFragment() const { + return SectionOrFragment.dyn_cast(); + } + void setFragment(MCFragment *Value) const { + SectionOrFragment = Value; + } + + bool isExternal() const { return IsExternal; } + void setExternal(bool Value) const { IsExternal = Value; } + + bool isPrivateExtern() const { return IsPrivateExtern; } + void setPrivateExtern(bool Value) { IsPrivateExtern = Value; } + /// print - Print the value to the stream \p OS. - void print(raw_ostream &OS) const; + void print(raw_ostream &OS, const MCAsmInfo *MAI) const; /// dump - Print the value to stderr. void dump() const; + +protected: + /// Get the (implementation defined) symbol flags. + uint32_t getFlags() const { return Flags; } + + /// Set the (implementation defined) symbol flags. + void setFlags(uint32_t Value) const { Flags = Value; } + + /// Modify the flags via a mask + void modifyFlags(uint32_t Value, uint32_t Mask) const { + Flags = (Flags & ~Mask) | Value; + } }; inline raw_ostream &operator<<(raw_ostream &OS, const MCSymbol &Sym) { - Sym.print(OS); + Sym.print(OS, nullptr); return OS; } } // end namespace llvm diff --git a/include/llvm/MC/MCSymbolCOFF.h b/include/llvm/MC/MCSymbolCOFF.h new file mode 100644 index 000000000000..2172c67981c0 --- /dev/null +++ b/include/llvm/MC/MCSymbolCOFF.h @@ -0,0 +1,64 @@ +//===- MCSymbolCOFF.h - ----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +#ifndef LLVM_MC_MCSYMBOLCOFF_H +#define LLVM_MC_MCSYMBOLCOFF_H + +#include "llvm/MC/MCSymbol.h" + +namespace llvm { +class MCSymbolCOFF : public MCSymbol { + + /// This corresponds to the e_type field of the COFF symbol. + mutable uint16_t Type; + + enum SymbolFlags : uint16_t { + SF_ClassMask = 0x00FF, + SF_ClassShift = 0, + + SF_WeakExternal = 0x0100, + SF_SafeSEH = 0x0200, + }; + +public: + MCSymbolCOFF(const StringMapEntry *Name, bool isTemporary) + : MCSymbol(SymbolKindCOFF, Name, isTemporary), Type(0) {} + + uint16_t getType() const { + return Type; + } + void setType(uint16_t Ty) const { + Type = Ty; + } + + uint16_t getClass() const { + return (getFlags() & SF_ClassMask) >> SF_ClassShift; + } + void setClass(uint16_t StorageClass) const { + modifyFlags(StorageClass << SF_ClassShift, SF_ClassMask); + } + + bool isWeakExternal() const { + return getFlags() & SF_WeakExternal; + } + void setIsWeakExternal() const { + modifyFlags(SF_WeakExternal, SF_WeakExternal); + } + + bool isSafeSEH() const { + return getFlags() & SF_SafeSEH; + } + void setIsSafeSEH() const { + modifyFlags(SF_SafeSEH, SF_SafeSEH); + } + + static bool classof(const MCSymbol *S) { return S->isCOFF(); } +}; +} + +#endif diff --git a/include/llvm/MC/MCSymbolELF.h b/include/llvm/MC/MCSymbolELF.h new file mode 100644 index 000000000000..0cc11156b5cd --- /dev/null +++ b/include/llvm/MC/MCSymbolELF.h @@ -0,0 +1,57 @@ +//===- MCSymbolELF.h - -----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +#ifndef LLVM_MC_MCSYMBOLELF_H +#define LLVM_MC_MCSYMBOLELF_H + +#include "llvm/MC/MCSymbol.h" + +namespace llvm { +class MCSymbolELF : public MCSymbol { + /// An expression describing how to calculate the size of a symbol. If a + /// symbol has no size this field will be NULL. + const MCExpr *SymbolSize = nullptr; + +public: + MCSymbolELF(const StringMapEntry *Name, bool isTemporary) + : MCSymbol(SymbolKindELF, Name, isTemporary) {} + void setSize(const MCExpr *SS) { SymbolSize = SS; } + + const MCExpr *getSize() const { return SymbolSize; } + + void setVisibility(unsigned Visibility); + unsigned getVisibility() const; + + void setOther(unsigned Other); + unsigned getOther() const; + + void setType(unsigned Type) const; + unsigned getType() const; + + void setBinding(unsigned Binding) const; + unsigned getBinding() const; + + bool isBindingSet() const; + + void setUsedInReloc() const; + bool isUsedInReloc() const; + + void setIsWeakrefUsedInReloc() const; + bool isWeakrefUsedInReloc() const; + + void setIsSignature() const; + bool isSignature() const; + + static bool classof(const MCSymbol *S) { return S->isELF(); } + +private: + void setIsBindingSet() const; +}; +} + +#endif diff --git a/include/llvm/MC/MCSymbolMachO.h b/include/llvm/MC/MCSymbolMachO.h new file mode 100644 index 000000000000..166ae9e755a1 --- /dev/null +++ b/include/llvm/MC/MCSymbolMachO.h @@ -0,0 +1,123 @@ +//===- MCSymbolMachO.h - ---------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +#ifndef LLVM_MC_MCSYMBOLMACHO_H +#define setIsWeakExternal + +#include "llvm/MC/MCSymbol.h" + +namespace llvm { +class MCSymbolMachO : public MCSymbol { + /// \brief We store the value for the 'desc' symbol field in the + /// lowest 16 bits of the implementation defined flags. + enum MachOSymbolFlags : uint16_t { // See . + SF_DescFlagsMask = 0xFFFF, + + // Reference type flags. + SF_ReferenceTypeMask = 0x0007, + SF_ReferenceTypeUndefinedNonLazy = 0x0000, + SF_ReferenceTypeUndefinedLazy = 0x0001, + SF_ReferenceTypeDefined = 0x0002, + SF_ReferenceTypePrivateDefined = 0x0003, + SF_ReferenceTypePrivateUndefinedNonLazy = 0x0004, + SF_ReferenceTypePrivateUndefinedLazy = 0x0005, + + // Other 'desc' flags. + SF_ThumbFunc = 0x0008, + SF_NoDeadStrip = 0x0020, + SF_WeakReference = 0x0040, + SF_WeakDefinition = 0x0080, + SF_SymbolResolver = 0x0100, + + // Common alignment + SF_CommonAlignmentMask = 0xF0FF, + SF_CommonAlignmentShift = 8 + }; + +public: + MCSymbolMachO(const StringMapEntry *Name, bool isTemporary) + : MCSymbol(SymbolKindMachO, Name, isTemporary) {} + + // Reference type methods. + + void clearReferenceType() const { + modifyFlags(0, SF_ReferenceTypeMask); + } + + void setReferenceTypeUndefinedLazy(bool Value) const { + modifyFlags(Value ? SF_ReferenceTypeUndefinedLazy : 0, + SF_ReferenceTypeUndefinedLazy); + } + + // Other 'desc' methods. + + void setThumbFunc() const { + modifyFlags(SF_ThumbFunc, SF_ThumbFunc); + } + + bool isNoDeadStrip() const { + return getFlags() & SF_NoDeadStrip; + } + void setNoDeadStrip() const { + modifyFlags(SF_NoDeadStrip, SF_NoDeadStrip); + } + + bool isWeakReference() const { + return getFlags() & SF_WeakReference; + } + void setWeakReference() const { + modifyFlags(SF_WeakReference, SF_WeakReference); + } + + bool isWeakDefinition() const { + return getFlags() & SF_WeakDefinition; + } + void setWeakDefinition() const { + modifyFlags(SF_WeakDefinition, SF_WeakDefinition); + } + + bool isSymbolResolver() const { + return getFlags() & SF_SymbolResolver; + } + void setSymbolResolver() const { + modifyFlags(SF_SymbolResolver, SF_SymbolResolver); + } + + void setDesc(unsigned Value) const { + assert(Value == (Value & SF_DescFlagsMask) && + "Invalid .desc value!"); + setFlags(Value & SF_DescFlagsMask); + } + + /// \brief Get the encoded value of the flags as they will be emitted in to + /// the MachO binary + uint16_t getEncodedFlags() const { + uint16_t Flags = getFlags(); + + // Common alignment is packed into the 'desc' bits. + if (isCommon()) { + if (unsigned Align = getCommonAlignment()) { + unsigned Log2Size = Log2_32(Align); + assert((1U << Log2Size) == Align && "Invalid 'common' alignment!"); + if (Log2Size > 15) + report_fatal_error("invalid 'common' alignment '" + + Twine(Align) + "' for '" + getName() + "'", + false); + Flags = (Flags & SF_CommonAlignmentMask) | + (Log2Size << SF_CommonAlignmentShift); + } + } + + return Flags; + } + + static bool classof(const MCSymbol *S) { return S->isMachO(); } +}; +} + +#endif diff --git a/include/llvm/MC/MCWinCOFFStreamer.h b/include/llvm/MC/MCWinCOFFStreamer.h index 6a83e02298ff..6fbc754f1125 100644 --- a/include/llvm/MC/MCWinCOFFStreamer.h +++ b/include/llvm/MC/MCWinCOFFStreamer.h @@ -50,9 +50,9 @@ class MCWinCOFFStreamer : public MCObjectStreamer { void EmitCOFFSymbolStorageClass(int StorageClass) override; void EmitCOFFSymbolType(int Type) override; void EndCOFFSymbolDef() override; + void EmitCOFFSafeSEH(MCSymbol const *Symbol) override; void EmitCOFFSectionIndex(MCSymbol const *Symbol) override; void EmitCOFFSecRel32(MCSymbol const *Symbol) override; - void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) override; void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment) override; void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, diff --git a/include/llvm/MC/SubtargetFeature.h b/include/llvm/MC/SubtargetFeature.h index 6a631ffe79bd..2fb9b4ae2503 100644 --- a/include/llvm/MC/SubtargetFeature.h +++ b/include/llvm/MC/SubtargetFeature.h @@ -103,6 +103,10 @@ class SubtargetFeatures { FeatureBitset ToggleFeature(FeatureBitset Bits, StringRef String, ArrayRef FeatureTable); + /// Apply the feature flag and return the newly updated feature bits. + FeatureBitset ApplyFeatureFlag(FeatureBitset Bits, StringRef Feature, + ArrayRef FeatureTable); + /// Get feature bits of a CPU. FeatureBitset getFeatureBits(StringRef CPU, ArrayRef CPUTable, diff --git a/include/llvm/Object/ArchiveWriter.h b/include/llvm/Object/ArchiveWriter.h new file mode 100644 index 000000000000..1616e46d3e6f --- /dev/null +++ b/include/llvm/Object/ArchiveWriter.h @@ -0,0 +1,51 @@ +//===- ArchiveWriter.h - ar archive file format writer ----------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Declares the writeArchive function for writing an archive file. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_OBJECT_ARCHIVEWRITER_H +#define LLVM_OBJECT_ARCHIVEWRITER_H + +#include "llvm/ADT/StringRef.h" +#include "llvm/Object/Archive.h" +#include "llvm/Support/FileSystem.h" + +namespace llvm { + +class NewArchiveIterator { + bool IsNewMember; + StringRef Name; + + object::Archive::child_iterator OldI; + + StringRef NewFilename; + +public: + NewArchiveIterator(object::Archive::child_iterator I, StringRef Name); + NewArchiveIterator(StringRef I, StringRef Name); + NewArchiveIterator(); + bool isNewMember() const; + StringRef getName() const; + + object::Archive::child_iterator getOld() const; + + StringRef getNew() const; + llvm::ErrorOr getFD(sys::fs::file_status &NewStatus) const; + const sys::fs::file_status &getStatus() const; +}; + +std::pair +writeArchive(StringRef ArcName, std::vector &NewMembers, + bool WriteSymtab); + +} + +#endif diff --git a/include/llvm/Object/COFF.h b/include/llvm/Object/COFF.h index ccac02036adc..564eb7a7a9c3 100644 --- a/include/llvm/Object/COFF.h +++ b/include/llvm/Object/COFF.h @@ -613,7 +613,7 @@ class COFFObjectFile : public ObjectFile { StringRef &Res) const override; std::error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const override; - std::error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const override; + uint64_t getSymbolSize(DataRefImpl Symb) const override; uint32_t getSymbolFlags(DataRefImpl Symb) const override; std::error_code getSymbolType(DataRefImpl Symb, SymbolRef::Type &Res) const override; @@ -647,10 +647,6 @@ class COFFObjectFile : public ObjectFile { std::error_code getRelocationTypeName(DataRefImpl Rel, SmallVectorImpl &Result) const override; - std::error_code - getRelocationValueString(DataRefImpl Rel, - SmallVectorImpl &Result) const override; - public: COFFObjectFile(MemoryBufferRef Object, std::error_code &EC); basic_symbol_iterator symbol_begin_impl() const override; @@ -699,7 +695,7 @@ class COFFObjectFile : public ObjectFile { return object_error::parse_failed; Res = reinterpret_cast(getSymbolTable()) + Index; - return object_error::success; + return std::error_code(); } ErrorOr getSymbol(uint32_t index) const { if (SymbolTable16) { @@ -722,7 +718,7 @@ class COFFObjectFile : public ObjectFile { if (std::error_code EC = s.getError()) return EC; Res = reinterpret_cast(s->getRawPtr()); - return object_error::success; + return std::error_code(); } std::error_code getSymbolName(COFFSymbolRef Symbol, StringRef &Res) const; diff --git a/include/llvm/Object/ELF.h b/include/llvm/Object/ELF.h index ddabf59f309e..e87737dcce7a 100644 --- a/include/llvm/Object/ELF.h +++ b/include/llvm/Object/ELF.h @@ -318,7 +318,7 @@ class ELFFile { std::pair getRelocationSymbol(const Elf_Shdr *RelSec, const RelT *Rel) const; - ELFFile(StringRef Object, std::error_code &ec); + ELFFile(StringRef Object, std::error_code &EC); bool isMipsELF64() const { return Header->e_machine == ELF::EM_MIPS && @@ -423,12 +423,10 @@ class ELFFile { StringRef getLoadName() const; }; -// Use an alignment of 2 for the typedefs since that is the worst case for -// ELF files in archives. -typedef ELFFile > ELF32LEFile; -typedef ELFFile > ELF64LEFile; -typedef ELFFile > ELF32BEFile; -typedef ELFFile > ELF64BEFile; +typedef ELFFile> ELF32LEFile; +typedef ELFFile> ELF64LEFile; +typedef ELFFile> ELF32BEFile; +typedef ELFFile> ELF64BEFile; // Iterate through the version definitions, and place each Elf_Verdef // in the VersionMap according to its index. @@ -622,7 +620,7 @@ typename ELFFile::uintX_t ELFFile::getStringTableIndex() const { } template -ELFFile::ELFFile(StringRef Object, std::error_code &ec) +ELFFile::ELFFile(StringRef Object, std::error_code &EC) : Buf(Object), SectionHeaderTable(nullptr), dot_shstrtab_sec(nullptr), dot_strtab_sec(nullptr), dot_symtab_sec(nullptr), SymbolTableSectionHeaderIndex(nullptr), dot_gnu_version_sec(nullptr), @@ -630,9 +628,11 @@ ELFFile::ELFFile(StringRef Object, std::error_code &ec) dt_soname(nullptr) { const uint64_t FileSize = Buf.size(); - if (sizeof(Elf_Ehdr) > FileSize) - // FIXME: Proper error handling. - report_fatal_error("File too short!"); + if (sizeof(Elf_Ehdr) > FileSize) { + // File too short! + EC = object_error::parse_failed; + return; + } Header = reinterpret_cast(base()); @@ -641,40 +641,50 @@ ELFFile::ELFFile(StringRef Object, std::error_code &ec) const uint64_t SectionTableOffset = Header->e_shoff; - if (SectionTableOffset + sizeof(Elf_Shdr) > FileSize) - // FIXME: Proper error handling. - report_fatal_error("Section header table goes past end of file!"); + if (SectionTableOffset + sizeof(Elf_Shdr) > FileSize) { + // Section header table goes past end of file! + EC = object_error::parse_failed; + return; + } // The getNumSections() call below depends on SectionHeaderTable being set. SectionHeaderTable = reinterpret_cast(base() + SectionTableOffset); const uint64_t SectionTableSize = getNumSections() * Header->e_shentsize; - if (SectionTableOffset + SectionTableSize > FileSize) - // FIXME: Proper error handling. - report_fatal_error("Section table goes past end of file!"); + if (SectionTableOffset + SectionTableSize > FileSize) { + // Section table goes past end of file! + EC = object_error::parse_failed; + return; + } // Scan sections for special sections. for (const Elf_Shdr &Sec : sections()) { switch (Sec.sh_type) { case ELF::SHT_SYMTAB_SHNDX: - if (SymbolTableSectionHeaderIndex) - // FIXME: Proper error handling. - report_fatal_error("More than one .symtab_shndx!"); + if (SymbolTableSectionHeaderIndex) { + // More than one .symtab_shndx! + EC = object_error::parse_failed; + return; + } SymbolTableSectionHeaderIndex = &Sec; break; case ELF::SHT_SYMTAB: - if (dot_symtab_sec) - // FIXME: Proper error handling. - report_fatal_error("More than one .symtab!"); + if (dot_symtab_sec) { + // More than one .symtab! + EC = object_error::parse_failed; + return; + } dot_symtab_sec = &Sec; dot_strtab_sec = getSection(Sec.sh_link); break; case ELF::SHT_DYNSYM: { - if (DynSymRegion.Addr) - // FIXME: Proper error handling. - report_fatal_error("More than one .dynsym!"); + if (DynSymRegion.Addr) { + // More than one .dynsym! + EC = object_error::parse_failed; + return; + } DynSymRegion.Addr = base() + Sec.sh_offset; DynSymRegion.Size = Sec.sh_size; DynSymRegion.EntSize = Sec.sh_entsize; @@ -685,29 +695,37 @@ ELFFile::ELFFile(StringRef Object, std::error_code &ec) break; } case ELF::SHT_DYNAMIC: - if (DynamicRegion.Addr) - // FIXME: Proper error handling. - report_fatal_error("More than one .dynamic!"); + if (DynamicRegion.Addr) { + // More than one .dynamic! + EC = object_error::parse_failed; + return; + } DynamicRegion.Addr = base() + Sec.sh_offset; DynamicRegion.Size = Sec.sh_size; DynamicRegion.EntSize = Sec.sh_entsize; break; case ELF::SHT_GNU_versym: - if (dot_gnu_version_sec != nullptr) - // FIXME: Proper error handling. - report_fatal_error("More than one .gnu.version section!"); + if (dot_gnu_version_sec != nullptr) { + // More than one .gnu.version section! + EC = object_error::parse_failed; + return; + } dot_gnu_version_sec = &Sec; break; case ELF::SHT_GNU_verdef: - if (dot_gnu_version_d_sec != nullptr) - // FIXME: Proper error handling. - report_fatal_error("More than one .gnu.version_d section!"); + if (dot_gnu_version_d_sec != nullptr) { + // More than one .gnu.version_d section! + EC = object_error::parse_failed; + return; + } dot_gnu_version_d_sec = &Sec; break; case ELF::SHT_GNU_verneed: - if (dot_gnu_version_r_sec != nullptr) - // FIXME: Proper error handling. - report_fatal_error("More than one .gnu.version_r section!"); + if (dot_gnu_version_r_sec != nullptr) { + // More than one .gnu.version_r section! + EC = object_error::parse_failed; + return; + } dot_gnu_version_r_sec = &Sec; break; } @@ -744,7 +762,7 @@ ELFFile::ELFFile(StringRef Object, std::error_code &ec) } } - ec = std::error_code(); + EC = std::error_code(); } // Get the symbol table index in the symtab section given a symbol @@ -898,11 +916,8 @@ ErrorOr ELFFile::getSymbolName(Elf_Sym_Iter Sym) const { template ErrorOr ELFFile::getSymbolName(const Elf_Shdr *Section, const Elf_Sym *Symb) const { - if (Symb->st_name == 0) { - const Elf_Shdr *ContainingSec = getSection(Symb); - if (ContainingSec) - return getSectionName(ContainingSec); - } + if (Symb->st_name == 0) + return StringRef(""); const Elf_Shdr *StrTab = getSection(Section->sh_link); if (Symb->st_name >= StrTab->sh_size) diff --git a/include/llvm/Object/ELFObjectFile.h b/include/llvm/Object/ELFObjectFile.h index 9bd4c3241118..78d77be5be8d 100644 --- a/include/llvm/Object/ELFObjectFile.h +++ b/include/llvm/Object/ELFObjectFile.h @@ -79,9 +79,8 @@ template class ELFObjectFile : public ELFObjectFileBase { StringRef &Res) const override; std::error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const override; - std::error_code getSymbolAlignment(DataRefImpl Symb, - uint32_t &Res) const override; - std::error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const override; + uint32_t getSymbolAlignment(DataRefImpl Symb) const override; + uint64_t getSymbolSize(DataRefImpl Symb) const override; uint32_t getSymbolFlags(DataRefImpl Symb) const override; std::error_code getSymbolOther(DataRefImpl Symb, uint8_t &Res) const override; std::error_code getSymbolType(DataRefImpl Symb, @@ -119,9 +118,6 @@ template class ELFObjectFile : public ELFObjectFileBase { std::error_code getRelocationTypeName(DataRefImpl Rel, SmallVectorImpl &Result) const override; - std::error_code - getRelocationValueString(DataRefImpl Rel, - SmallVectorImpl &Result) const override; uint64_t getROffset(DataRefImpl Rel) const; StringRef getRelocationTypeName(uint32_t Type) const; @@ -227,7 +223,7 @@ template class ELFObjectFile : public ELFObjectFileBase { std::error_code getPlatformFlags(unsigned &Result) const override { Result = EF.getHeader()->e_flags; - return object_error::success; + return std::error_code(); } const ELFFile *getELFFile() const { return &EF; } @@ -244,12 +240,10 @@ template class ELFObjectFile : public ELFObjectFileBase { bool isRelocatableObject() const override; }; -// Use an alignment of 2 for the typedefs since that is the worst case for -// ELF files in archives. -typedef ELFObjectFile > ELF32LEObjectFile; -typedef ELFObjectFile > ELF64LEObjectFile; -typedef ELFObjectFile > ELF32BEObjectFile; -typedef ELFObjectFile > ELF64BEObjectFile; +typedef ELFObjectFile> ELF32LEObjectFile; +typedef ELFObjectFile> ELF64LEObjectFile; +typedef ELFObjectFile> ELF32BEObjectFile; +typedef ELFObjectFile> ELF64BEObjectFile; template void ELFObjectFile::moveSymbolNext(DataRefImpl &Symb) const { @@ -263,7 +257,7 @@ std::error_code ELFObjectFile::getSymbolName(DataRefImpl Symb, if (!Name) return Name.getError(); Result = *Name; - return object_error::success; + return std::error_code(); } template @@ -277,7 +271,7 @@ std::error_code ELFObjectFile::getSymbolVersion(SymbolRef SymRef, if (!Ver) return Ver.getError(); Version = *Ver; - return object_error::success; + return std::error_code(); } template @@ -300,10 +294,10 @@ std::error_code ELFObjectFile::getSymbolAddress(DataRefImpl Symb, case ELF::SHN_COMMON: case ELF::SHN_UNDEF: Result = UnknownAddressOrSize; - return object_error::success; + return std::error_code(); case ELF::SHN_ABS: Result = ESym->st_value; - return object_error::success; + return std::error_code(); default: break; } @@ -322,32 +316,27 @@ std::error_code ELFObjectFile::getSymbolAddress(DataRefImpl Symb, Result += Section->sh_addr; } - return object_error::success; + return std::error_code(); } template -std::error_code ELFObjectFile::getSymbolAlignment(DataRefImpl Symb, - uint32_t &Res) const { +uint32_t ELFObjectFile::getSymbolAlignment(DataRefImpl Symb) const { Elf_Sym_Iter Sym = toELFSymIter(Symb); if (Sym->st_shndx == ELF::SHN_COMMON) - Res = Sym->st_value; - else - Res = 0; - return object_error::success; + return Sym->st_value; + return 0; } template -std::error_code ELFObjectFile::getSymbolSize(DataRefImpl Symb, - uint64_t &Result) const { - Result = toELFSymIter(Symb)->st_size; - return object_error::success; +uint64_t ELFObjectFile::getSymbolSize(DataRefImpl Symb) const { + return toELFSymIter(Symb)->st_size; } template std::error_code ELFObjectFile::getSymbolOther(DataRefImpl Symb, uint8_t &Result) const { Result = toELFSymIter(Symb)->st_other; - return object_error::success; + return std::error_code(); } template @@ -378,7 +367,7 @@ ELFObjectFile::getSymbolType(DataRefImpl Symb, Result = SymbolRef::ST_Other; break; } - return object_error::success; + return std::error_code(); } template @@ -435,7 +424,7 @@ std::error_code ELFObjectFile::getSymbolSection(DataRefImpl Symb, section_iterator &Res) const { Res = getSymbolSection(getSymbol(Symb)); - return object_error::success; + return std::error_code(); } template @@ -450,7 +439,7 @@ std::error_code ELFObjectFile::getSectionName(DataRefImpl Sec, if (!Name) return Name.getError(); Result = *Name; - return object_error::success; + return std::error_code(); } template @@ -469,7 +458,7 @@ ELFObjectFile::getSectionContents(DataRefImpl Sec, StringRef &Result) const { Elf_Shdr_Iter EShdr = toELFShdrIter(Sec); Result = StringRef((const char *)base() + EShdr->sh_offset, EShdr->sh_size); - return object_error::success; + return std::error_code(); } template @@ -624,7 +613,7 @@ ELFObjectFile::getRelocationAddress(DataRefImpl Rel, Result = ROffset; } - return object_error::success; + return std::error_code(); } template @@ -634,7 +623,7 @@ ELFObjectFile::getRelocationOffset(DataRefImpl Rel, assert(EF.getHeader()->e_type == ELF::ET_REL && "Only relocatable object files have relocation offsets"); Result = getROffset(Rel); - return object_error::success; + return std::error_code(); } template @@ -666,7 +655,7 @@ std::error_code ELFObjectFile::getRelocationType(DataRefImpl Rel, break; } } - return object_error::success; + return std::error_code(); } template @@ -693,7 +682,7 @@ std::error_code ELFObjectFile::getRelocationTypeName( } EF.getRelocationTypeName(type, Result); - return object_error::success; + return std::error_code(); } template @@ -706,96 +695,15 @@ ELFObjectFile::getRelocationAddend(DataRefImpl Rel, report_fatal_error("Invalid section type in Rel!"); case ELF::SHT_REL: { Result = 0; - return object_error::success; + return std::error_code(); } case ELF::SHT_RELA: { Result = getRela(Rel)->r_addend; - return object_error::success; + return std::error_code(); } } } -template -std::error_code ELFObjectFile::getRelocationValueString( - DataRefImpl Rel, SmallVectorImpl &Result) const { - const Elf_Shdr *sec = getRelSection(Rel); - uint8_t type; - StringRef res; - int64_t addend = 0; - uint16_t symbol_index = 0; - switch (sec->sh_type) { - default: - return object_error::parse_failed; - case ELF::SHT_REL: { - type = getRel(Rel)->getType(EF.isMips64EL()); - symbol_index = getRel(Rel)->getSymbol(EF.isMips64EL()); - // TODO: Read implicit addend from section data. - break; - } - case ELF::SHT_RELA: { - type = getRela(Rel)->getType(EF.isMips64EL()); - symbol_index = getRela(Rel)->getSymbol(EF.isMips64EL()); - addend = getRela(Rel)->r_addend; - break; - } - } - const Elf_Sym *symb = - EF.template getEntry(sec->sh_link, symbol_index); - ErrorOr SymName = - EF.getSymbolName(EF.getSection(sec->sh_link), symb); - if (!SymName) - return SymName.getError(); - switch (EF.getHeader()->e_machine) { - case ELF::EM_X86_64: - switch (type) { - case ELF::R_X86_64_PC8: - case ELF::R_X86_64_PC16: - case ELF::R_X86_64_PC32: { - std::string fmtbuf; - raw_string_ostream fmt(fmtbuf); - fmt << *SymName << (addend < 0 ? "" : "+") << addend << "-P"; - fmt.flush(); - Result.append(fmtbuf.begin(), fmtbuf.end()); - } break; - case ELF::R_X86_64_8: - case ELF::R_X86_64_16: - case ELF::R_X86_64_32: - case ELF::R_X86_64_32S: - case ELF::R_X86_64_64: { - std::string fmtbuf; - raw_string_ostream fmt(fmtbuf); - fmt << *SymName << (addend < 0 ? "" : "+") << addend; - fmt.flush(); - Result.append(fmtbuf.begin(), fmtbuf.end()); - } break; - default: - res = "Unknown"; - } - break; - case ELF::EM_AARCH64: { - std::string fmtbuf; - raw_string_ostream fmt(fmtbuf); - fmt << *SymName; - if (addend != 0) - fmt << (addend < 0 ? "" : "+") << addend; - fmt.flush(); - Result.append(fmtbuf.begin(), fmtbuf.end()); - break; - } - case ELF::EM_386: - case ELF::EM_ARM: - case ELF::EM_HEXAGON: - case ELF::EM_MIPS: - res = *SymName; - break; - default: - res = "Unknown"; - } - if (Result.empty()) - Result.append(res.begin(), res.end()); - return object_error::success; -} - template const typename ELFFile::Elf_Sym * ELFObjectFile::getSymbol(DataRefImpl Symb) const { diff --git a/include/llvm/Object/ELFTypes.h b/include/llvm/Object/ELFTypes.h index 287d3670678a..3f323b5b8200 100644 --- a/include/llvm/Object/ELFTypes.h +++ b/include/llvm/Object/ELFTypes.h @@ -10,7 +10,6 @@ #ifndef LLVM_OBJECT_ELFTYPES_H #define LLVM_OBJECT_ELFTYPES_H -#include "llvm/Support/AlignOf.h" #include "llvm/Support/DataTypes.h" #include "llvm/Support/ELF.h" #include "llvm/Support/Endian.h" @@ -20,95 +19,74 @@ namespace object { using support::endianness; -template -struct ELFType { +template struct ELFType { static const endianness TargetEndianness = target_endianness; - static const std::size_t MaxAlignment = max_alignment; static const bool Is64Bits = is64Bits; }; -template struct MaximumAlignment { - enum { value = AlignOf::Alignment > max_align ? max_align - : AlignOf::Alignment - }; -}; +// Use an alignment of 2 for the typedefs since that is the worst case for +// ELF files in archives. // Templates to choose Elf_Addr and Elf_Off depending on is64Bits. -template -struct ELFDataTypeTypedefHelperCommon { +template struct ELFDataTypeTypedefHelperCommon { typedef support::detail::packed_endian_specific_integral< - uint16_t, target_endianness, - MaximumAlignment::value> Elf_Half; + uint16_t, target_endianness, 2> Elf_Half; typedef support::detail::packed_endian_specific_integral< - uint32_t, target_endianness, - MaximumAlignment::value> Elf_Word; + uint32_t, target_endianness, 2> Elf_Word; typedef support::detail::packed_endian_specific_integral< - int32_t, target_endianness, - MaximumAlignment::value> Elf_Sword; + int32_t, target_endianness, 2> Elf_Sword; typedef support::detail::packed_endian_specific_integral< - uint64_t, target_endianness, - MaximumAlignment::value> Elf_Xword; + uint64_t, target_endianness, 2> Elf_Xword; typedef support::detail::packed_endian_specific_integral< - int64_t, target_endianness, - MaximumAlignment::value> Elf_Sxword; + int64_t, target_endianness, 2> Elf_Sxword; }; template struct ELFDataTypeTypedefHelper; /// ELF 32bit types. -template -struct ELFDataTypeTypedefHelper > - : ELFDataTypeTypedefHelperCommon { +template +struct ELFDataTypeTypedefHelper> + : ELFDataTypeTypedefHelperCommon { typedef uint32_t value_type; typedef support::detail::packed_endian_specific_integral< - value_type, TargetEndianness, - MaximumAlignment::value> Elf_Addr; + value_type, TargetEndianness, 2> Elf_Addr; typedef support::detail::packed_endian_specific_integral< - value_type, TargetEndianness, - MaximumAlignment::value> Elf_Off; + value_type, TargetEndianness, 2> Elf_Off; }; /// ELF 64bit types. -template -struct ELFDataTypeTypedefHelper > - : ELFDataTypeTypedefHelperCommon { +template +struct ELFDataTypeTypedefHelper> + : ELFDataTypeTypedefHelperCommon { typedef uint64_t value_type; typedef support::detail::packed_endian_specific_integral< - value_type, TargetEndianness, - MaximumAlignment::value> Elf_Addr; + value_type, TargetEndianness, 2> Elf_Addr; typedef support::detail::packed_endian_specific_integral< - value_type, TargetEndianness, - MaximumAlignment::value> Elf_Off; + value_type, TargetEndianness, 2> Elf_Off; }; // I really don't like doing this, but the alternative is copypasta. -#define LLVM_ELF_IMPORT_TYPES(E, M, W) \ -typedef typename ELFDataTypeTypedefHelper >::Elf_Addr \ - Elf_Addr; \ -typedef typename ELFDataTypeTypedefHelper >::Elf_Off \ - Elf_Off; \ -typedef typename ELFDataTypeTypedefHelper >::Elf_Half \ - Elf_Half; \ -typedef typename ELFDataTypeTypedefHelper >::Elf_Word \ - Elf_Word; \ -typedef typename ELFDataTypeTypedefHelper >::Elf_Sword \ - Elf_Sword; \ -typedef typename ELFDataTypeTypedefHelper >::Elf_Xword \ - Elf_Xword; \ -typedef typename ELFDataTypeTypedefHelper >::Elf_Sxword \ - Elf_Sxword; +#define LLVM_ELF_IMPORT_TYPES(E, W) \ + typedef typename ELFDataTypeTypedefHelper>::Elf_Addr Elf_Addr; \ + typedef typename ELFDataTypeTypedefHelper>::Elf_Off Elf_Off; \ + typedef typename ELFDataTypeTypedefHelper>::Elf_Half Elf_Half; \ + typedef typename ELFDataTypeTypedefHelper>::Elf_Word Elf_Word; \ + typedef \ + typename ELFDataTypeTypedefHelper>::Elf_Sword Elf_Sword; \ + typedef \ + typename ELFDataTypeTypedefHelper>::Elf_Xword Elf_Xword; \ + typedef \ + typename ELFDataTypeTypedefHelper>::Elf_Sxword Elf_Sxword; #define LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) \ - LLVM_ELF_IMPORT_TYPES(ELFT::TargetEndianness, ELFT::MaxAlignment, \ - ELFT::Is64Bits) + LLVM_ELF_IMPORT_TYPES(ELFT::TargetEndianness, ELFT::Is64Bits) // Section header. template struct Elf_Shdr_Base; -template -struct Elf_Shdr_Base > { - LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false) +template +struct Elf_Shdr_Base> { + LLVM_ELF_IMPORT_TYPES(TargetEndianness, false) Elf_Word sh_name; // Section name (index into string table) Elf_Word sh_type; // Section type (SHT_*) Elf_Word sh_flags; // Section flags (SHF_*) @@ -121,9 +99,9 @@ struct Elf_Shdr_Base > { Elf_Word sh_entsize; // Size of records contained within the section }; -template -struct Elf_Shdr_Base > { - LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true) +template +struct Elf_Shdr_Base> { + LLVM_ELF_IMPORT_TYPES(TargetEndianness, true) Elf_Word sh_name; // Section name (index into string table) Elf_Word sh_type; // Section type (SHT_*) Elf_Xword sh_flags; // Section flags (SHF_*) @@ -151,9 +129,9 @@ struct Elf_Shdr_Impl : Elf_Shdr_Base { template struct Elf_Sym_Base; -template -struct Elf_Sym_Base > { - LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false) +template +struct Elf_Sym_Base> { + LLVM_ELF_IMPORT_TYPES(TargetEndianness, false) Elf_Word st_name; // Symbol name (index into string table) Elf_Addr st_value; // Value or address associated with the symbol Elf_Word st_size; // Size of the symbol @@ -162,9 +140,9 @@ struct Elf_Sym_Base > { Elf_Half st_shndx; // Which section (header table index) it's defined in }; -template -struct Elf_Sym_Base > { - LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true) +template +struct Elf_Sym_Base> { + LLVM_ELF_IMPORT_TYPES(TargetEndianness, true) Elf_Word st_name; // Symbol name (index into string table) unsigned char st_info; // Symbol's type and binding attributes unsigned char st_other; // Must be zero; reserved @@ -176,6 +154,7 @@ struct Elf_Sym_Base > { template struct Elf_Sym_Impl : Elf_Sym_Base { using Elf_Sym_Base::st_info; + using Elf_Sym_Base::st_shndx; using Elf_Sym_Base::st_other; // These accessors and mutators correspond to the ELF32_ST_BIND, @@ -198,6 +177,25 @@ struct Elf_Sym_Impl : Elf_Sym_Base { assert(v < 4 && "Invalid value for visibility"); st_other = (st_other & ~0x3) | v; } + + bool isAbsolute() const { return st_shndx == ELF::SHN_ABS; } + bool isCommon() const { + return getType() == ELF::STT_COMMON || st_shndx == ELF::SHN_COMMON; + } + bool isDefined() const { + return !isUndefined() && + !(st_shndx >= ELF::SHN_LORESERVE && st_shndx < ELF::SHN_ABS); + } + bool isProcessorSpecific() const { + return st_shndx >= ELF::SHN_LOPROC && st_shndx <= ELF::SHN_HIPROC; + } + bool isOSSpecific() const { + return st_shndx >= ELF::SHN_LOOS && st_shndx <= ELF::SHN_HIOS; + } + bool isReserved() const { + return st_shndx > ELF::SHN_HIOS && st_shndx < ELF::SHN_ABS; + } + bool isUndefined() const { return st_shndx == ELF::SHN_UNDEF; } }; /// Elf_Versym: This is the structure of entries in the SHT_GNU_versym section @@ -267,9 +265,9 @@ struct Elf_Vernaux_Impl { /// table section (.dynamic) look like. template struct Elf_Dyn_Base; -template -struct Elf_Dyn_Base > { - LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false) +template +struct Elf_Dyn_Base> { + LLVM_ELF_IMPORT_TYPES(TargetEndianness, false) Elf_Sword d_tag; union { Elf_Word d_val; @@ -277,9 +275,9 @@ struct Elf_Dyn_Base > { } d_un; }; -template -struct Elf_Dyn_Base > { - LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true) +template +struct Elf_Dyn_Base> { + LLVM_ELF_IMPORT_TYPES(TargetEndianness, true) Elf_Sxword d_tag; union { Elf_Xword d_val; @@ -300,9 +298,9 @@ struct Elf_Dyn_Impl : Elf_Dyn_Base { // Elf_Rel: Elf Relocation template struct Elf_Rel_Base; -template -struct Elf_Rel_Base, false> { - LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false) +template +struct Elf_Rel_Base, false> { + LLVM_ELF_IMPORT_TYPES(TargetEndianness, false) Elf_Addr r_offset; // Location (file byte offset, or program virtual addr) Elf_Word r_info; // Symbol table index and type of relocation to apply @@ -316,9 +314,9 @@ struct Elf_Rel_Base, false> { } }; -template -struct Elf_Rel_Base, false> { - LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true) +template +struct Elf_Rel_Base, false> { + LLVM_ELF_IMPORT_TYPES(TargetEndianness, true) Elf_Addr r_offset; // Location (file byte offset, or program virtual addr) Elf_Xword r_info; // Symbol table index and type of relocation to apply @@ -341,9 +339,9 @@ struct Elf_Rel_Base, false> { } }; -template -struct Elf_Rel_Base, true> { - LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false) +template +struct Elf_Rel_Base, true> { + LLVM_ELF_IMPORT_TYPES(TargetEndianness, false) Elf_Addr r_offset; // Location (file byte offset, or program virtual addr) Elf_Word r_info; // Symbol table index and type of relocation to apply Elf_Sword r_addend; // Compute value for relocatable field by adding this @@ -358,9 +356,9 @@ struct Elf_Rel_Base, true> { } }; -template -struct Elf_Rel_Base, true> { - LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true) +template +struct Elf_Rel_Base, true> { + LLVM_ELF_IMPORT_TYPES(TargetEndianness, true) Elf_Addr r_offset; // Location (file byte offset, or program virtual addr) Elf_Xword r_info; // Symbol table index and type of relocation to apply Elf_Sxword r_addend; // Compute value for relocatable field by adding this. @@ -386,11 +384,10 @@ struct Elf_Rel_Base, true> { template struct Elf_Rel_Impl; -template -struct Elf_Rel_Impl, - isRela> : Elf_Rel_Base< - ELFType, isRela> { - LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true) +template +struct Elf_Rel_Impl, isRela> + : Elf_Rel_Base, isRela> { + LLVM_ELF_IMPORT_TYPES(TargetEndianness, true) // These accessors and mutators correspond to the ELF64_R_SYM, ELF64_R_TYPE, // and ELF64_R_INFO macros defined in the ELF specification: @@ -411,11 +408,10 @@ struct Elf_Rel_Impl, } }; -template -struct Elf_Rel_Impl, - isRela> : Elf_Rel_Base< - ELFType, isRela> { - LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false) +template +struct Elf_Rel_Impl, isRela> + : Elf_Rel_Base, isRela> { + LLVM_ELF_IMPORT_TYPES(TargetEndianness, false) // These accessors and mutators correspond to the ELF32_R_SYM, ELF32_R_TYPE, // and ELF32_R_INFO macros defined in the ELF specification: @@ -463,9 +459,9 @@ struct Elf_Ehdr_Impl { template struct Elf_Phdr_Impl; -template -struct Elf_Phdr_Impl > { - LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false) +template +struct Elf_Phdr_Impl> { + LLVM_ELF_IMPORT_TYPES(TargetEndianness, false) Elf_Word p_type; // Type of segment Elf_Off p_offset; // FileOffset where segment is located, in bytes Elf_Addr p_vaddr; // Virtual Address of beginning of segment @@ -476,9 +472,9 @@ struct Elf_Phdr_Impl > { Elf_Word p_align; // Segment alignment constraint }; -template -struct Elf_Phdr_Impl > { - LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true) +template +struct Elf_Phdr_Impl> { + LLVM_ELF_IMPORT_TYPES(TargetEndianness, true) Elf_Word p_type; // Type of segment Elf_Word p_flags; // Segment flags Elf_Off p_offset; // FileOffset where segment is located, in bytes @@ -493,17 +489,17 @@ struct Elf_Phdr_Impl > { template struct Elf_Mips_RegInfo; -template -struct Elf_Mips_RegInfo> { - LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false) +template +struct Elf_Mips_RegInfo> { + LLVM_ELF_IMPORT_TYPES(TargetEndianness, false) Elf_Word ri_gprmask; // bit-mask of used general registers Elf_Word ri_cprmask[4]; // bit-mask of used co-processor registers Elf_Addr ri_gp_value; // gp register value }; -template -struct Elf_Mips_RegInfo> { - LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true) +template +struct Elf_Mips_RegInfo> { + LLVM_ELF_IMPORT_TYPES(TargetEndianness, true) Elf_Word ri_gprmask; // bit-mask of used general registers Elf_Word ri_pad; // unused padding field Elf_Word ri_cprmask[4]; // bit-mask of used co-processor registers diff --git a/include/llvm/Object/Error.h b/include/llvm/Object/Error.h index 90c2bd74b43c..c9db1b80b916 100644 --- a/include/llvm/Object/Error.h +++ b/include/llvm/Object/Error.h @@ -22,12 +22,15 @@ namespace object { const std::error_category &object_category(); enum class object_error { - success = 0, - arch_not_found, + // Error code 0 is absent. Use std::error_code() instead. + arch_not_found = 1, invalid_file_type, parse_failed, unexpected_eof, bitcode_section_not_found, + macho_small_load_command, + macho_load_segment_too_many_sections, + macho_load_segment_too_small, }; inline std::error_code make_error_code(object_error e) { diff --git a/include/llvm/Object/MachO.h b/include/llvm/Object/MachO.h index 0a9b62c9055f..b163534fd9df 100644 --- a/include/llvm/Object/MachO.h +++ b/include/llvm/Object/MachO.h @@ -190,6 +190,8 @@ class MachOObjectFile : public ObjectFile { const char *Ptr; // Where in memory the load command is. MachO::load_command C; // The command itself. }; + typedef SmallVector LoadCommandList; + typedef LoadCommandList::const_iterator load_command_iterator; MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian, bool Is64Bits, std::error_code &EC); @@ -204,9 +206,8 @@ class MachOObjectFile : public ObjectFile { std::error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const override; - std::error_code getSymbolAlignment(DataRefImpl Symb, - uint32_t &Res) const override; - std::error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const override; + uint32_t getSymbolAlignment(DataRefImpl Symb) const override; + uint64_t getSymbolSize(DataRefImpl Symb) const override; std::error_code getSymbolType(DataRefImpl Symb, SymbolRef::Type &Res) const override; uint32_t getSymbolFlags(DataRefImpl Symb) const override; @@ -241,11 +242,9 @@ class MachOObjectFile : public ObjectFile { std::error_code getRelocationTypeName(DataRefImpl Rel, SmallVectorImpl &Result) const override; - std::error_code - getRelocationValueString(DataRefImpl Rel, - SmallVectorImpl &Result) const override; std::error_code getRelocationHidden(DataRefImpl Rel, bool &Result) const override; + uint8_t getRelocationLength(DataRefImpl Rel) const; // MachO specific. std::error_code getLibraryShortNameByIndex(unsigned Index, StringRef &) const; @@ -273,10 +272,14 @@ class MachOObjectFile : public ObjectFile { dice_iterator begin_dices() const; dice_iterator end_dices() const; - + + load_command_iterator begin_load_commands() const; + load_command_iterator end_load_commands() const; + iterator_range load_commands() const; + /// For use iterating over all exported symbols. iterator_range exports() const; - + /// For use examining a trie not in a MachOObjectFile. static iterator_range exports(ArrayRef Trie); @@ -329,10 +332,6 @@ class MachOObjectFile : public ObjectFile { unsigned getAnyRelocationType(const MachO::any_relocation_info &RE) const; SectionRef getAnyRelocationSection(const MachO::any_relocation_info &RE) const; - // Walk load commands. - LoadCommandInfo getFirstLoadCommandInfo() const; - LoadCommandInfo getNextLoadCommandInfo(const LoadCommandInfo &L) const; - // MachO specific structures. MachO::section getSection(DataRefImpl DRI) const; MachO::section_64 getSection64(DataRefImpl DRI) const; @@ -386,8 +385,8 @@ class MachOObjectFile : public ObjectFile { MachO::any_relocation_info getRelocation(DataRefImpl Rel) const; MachO::data_in_code_entry getDice(DataRefImpl Rel) const; - MachO::mach_header getHeader() const; - MachO::mach_header_64 getHeader64() const; + const MachO::mach_header &getHeader() const; + const MachO::mach_header_64 &getHeader64() const; uint32_t getIndirectSymbolTableEntry(const MachO::dysymtab_command &DLC, unsigned Index) const; @@ -430,10 +429,15 @@ class MachOObjectFile : public ObjectFile { } private: + union { + MachO::mach_header_64 Header64; + MachO::mach_header Header; + }; typedef SmallVector SectionList; SectionList Sections; typedef SmallVector LibraryList; LibraryList Libraries; + LoadCommandList LoadCommands; typedef SmallVector LibraryShortName; mutable LibraryShortName LibrariesShortNames; const char *SymtabLoadCmd; @@ -472,7 +476,7 @@ inline std::error_code DiceRef::getOffset(uint32_t &Result) const { static_cast(OwningObject); MachO::data_in_code_entry Dice = MachOOF->getDice(DicePimpl); Result = Dice.offset; - return object_error::success; + return std::error_code(); } inline std::error_code DiceRef::getLength(uint16_t &Result) const { @@ -480,7 +484,7 @@ inline std::error_code DiceRef::getLength(uint16_t &Result) const { static_cast(OwningObject); MachO::data_in_code_entry Dice = MachOOF->getDice(DicePimpl); Result = Dice.length; - return object_error::success; + return std::error_code(); } inline std::error_code DiceRef::getKind(uint16_t &Result) const { @@ -488,7 +492,7 @@ inline std::error_code DiceRef::getKind(uint16_t &Result) const { static_cast(OwningObject); MachO::data_in_code_entry Dice = MachOOF->getDice(DicePimpl); Result = Dice.kind; - return object_error::success; + return std::error_code(); } inline DataRefImpl DiceRef::getRawDataRefImpl() const { diff --git a/include/llvm/Object/ObjectFile.h b/include/llvm/Object/ObjectFile.h index 14cd082870b0..a1ae19ecdfed 100644 --- a/include/llvm/Object/ObjectFile.h +++ b/include/llvm/Object/ObjectFile.h @@ -66,11 +66,6 @@ class RelocationRef { /// This is for display purposes only. std::error_code getTypeName(SmallVectorImpl &Result) const; - /// @brief Get a string that represents the calculation of the value of this - /// relocation. - /// - /// This is for display purposes only. - std::error_code getValueString(SmallVectorImpl &Result) const; DataRefImpl getRawDataRefImpl() const; const ObjectFile *getObjectFile() const; @@ -146,8 +141,8 @@ class SymbolRef : public BasicSymbolRef { /// mapped). std::error_code getAddress(uint64_t &Result) const; /// @brief Get the alignment of this symbol as the actual value (not log 2). - std::error_code getAlignment(uint32_t &Result) const; - std::error_code getSize(uint64_t &Result) const; + uint32_t getAlignment() const; + uint64_t getSize() const; std::error_code getType(SymbolRef::Type &Result) const; std::error_code getOther(uint8_t &Result) const; @@ -206,10 +201,8 @@ class ObjectFile : public SymbolicFile { DataRefImpl Symb) const override; virtual std::error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const = 0; - virtual std::error_code getSymbolAlignment(DataRefImpl Symb, - uint32_t &Res) const; - virtual std::error_code getSymbolSize(DataRefImpl Symb, - uint64_t &Res) const = 0; + virtual uint32_t getSymbolAlignment(DataRefImpl Symb) const; + virtual uint64_t getSymbolSize(DataRefImpl Symb) const = 0; virtual std::error_code getSymbolType(DataRefImpl Symb, SymbolRef::Type &Res) const = 0; virtual std::error_code getSymbolSection(DataRefImpl Symb, @@ -254,13 +247,10 @@ class ObjectFile : public SymbolicFile { virtual std::error_code getRelocationTypeName(DataRefImpl Rel, SmallVectorImpl &Result) const = 0; - virtual std::error_code - getRelocationValueString(DataRefImpl Rel, - SmallVectorImpl &Result) const = 0; virtual std::error_code getRelocationHidden(DataRefImpl Rel, bool &Result) const { Result = false; - return object_error::success; + return std::error_code(); } public: @@ -334,12 +324,12 @@ inline std::error_code SymbolRef::getAddress(uint64_t &Result) const { return getObject()->getSymbolAddress(getRawDataRefImpl(), Result); } -inline std::error_code SymbolRef::getAlignment(uint32_t &Result) const { - return getObject()->getSymbolAlignment(getRawDataRefImpl(), Result); +inline uint32_t SymbolRef::getAlignment() const { + return getObject()->getSymbolAlignment(getRawDataRefImpl()); } -inline std::error_code SymbolRef::getSize(uint64_t &Result) const { - return getObject()->getSymbolSize(getRawDataRefImpl(), Result); +inline uint64_t SymbolRef::getSize() const { + return getObject()->getSymbolSize(getRawDataRefImpl()); } inline std::error_code SymbolRef::getSection(section_iterator &Result) const { @@ -482,11 +472,6 @@ RelocationRef::getTypeName(SmallVectorImpl &Result) const { return OwningObject->getRelocationTypeName(RelocationPimpl, Result); } -inline std::error_code -RelocationRef::getValueString(SmallVectorImpl &Result) const { - return OwningObject->getRelocationValueString(RelocationPimpl, Result); -} - inline std::error_code RelocationRef::getHidden(bool &Result) const { return OwningObject->getRelocationHidden(RelocationPimpl, Result); } diff --git a/include/llvm/Object/RelocVisitor.h b/include/llvm/Object/RelocVisitor.h index 91eafd55ad76..02ffda5642d5 100644 --- a/include/llvm/Object/RelocVisitor.h +++ b/include/llvm/Object/RelocVisitor.h @@ -19,9 +19,11 @@ #include "llvm/ADT/StringRef.h" #include "llvm/Object/COFF.h" #include "llvm/Object/ELFObjectFile.h" +#include "llvm/Object/MachO.h" #include "llvm/Object/ObjectFile.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ELF.h" +#include "llvm/Support/MachO.h" #include "llvm/Support/raw_ostream.h" namespace llvm { @@ -52,6 +54,8 @@ class RelocVisitor { return visitELF(RelocType, R, Value); if (isa(ObjToVisit)) return visitCOFF(RelocType, R, Value); + if (isa(ObjToVisit)) + return visitMachO(RelocType, R, Value); HasError = true; return RelocToApply(); @@ -221,6 +225,20 @@ class RelocVisitor { return RelocToApply(); } + RelocToApply visitMachO(uint32_t RelocType, RelocationRef R, uint64_t Value) { + switch (ObjToVisit.getArch()) { + default: break; + case Triple::x86_64: + switch (RelocType) { + default: break; + case MachO::X86_64_RELOC_UNSIGNED: + return visitMACHO_X86_64_UNSIGNED(R, Value); + } + } + HasError = true; + return RelocToApply(); + } + int64_t getELFAddend32LE(RelocationRef R) { const ELF32LEObjectFile *Obj = cast(R.getObjectFile()); DataRefImpl DRI = R.getRawDataRefImpl(); @@ -252,6 +270,12 @@ class RelocVisitor { Obj->getRelocationAddend(DRI, Addend); return Addend; } + + uint8_t getLengthMachO64(RelocationRef R) { + const MachOObjectFile *Obj = cast(R.getObjectFile()); + return Obj->getRelocationLength(R.getRawDataRefImpl()); + } + /// Operations /// 386-ELF @@ -413,6 +437,13 @@ class RelocVisitor { RelocToApply visitCOFF_AMD64_ADDR64(RelocationRef R, uint64_t Value) { return RelocToApply(Value, /*Width=*/8); } + + // X86_64 MachO + RelocToApply visitMACHO_X86_64_UNSIGNED(RelocationRef R, uint64_t Value) { + uint8_t Length = getLengthMachO64(R); + Length = 1< class list_storage { } }; -// Define how to hold a class type object, such as a string. Since we can -// inherit from a class, we do so. This makes us exactly compatible with the -// object in all cases that it is used. +// Define how to hold a class type object, such as a string. +// Originally this code inherited from std::vector. In transitioning to a new +// API for command line options we should change this. The new implementation +// of this list_storage specialization implements the minimum subset of the +// std::vector API required for all the current clients. // -template -class list_storage : public std::vector { +// FIXME: Reduce this API to a more narrow subset of std::vector +// +template class list_storage { + std::vector Storage; + public: - template void addValue(const T &V) { - std::vector::push_back(V); + typedef typename std::vector::iterator iterator; + + iterator begin() { return Storage.begin(); } + iterator end() { return Storage.end(); } + + typedef typename std::vector::const_iterator const_iterator; + const_iterator begin() const { return Storage.begin(); } + const_iterator end() const { return Storage.end(); } + + typedef typename std::vector::size_type size_type; + size_type size() const { return Storage.size(); } + + bool empty() const { return Storage.empty(); } + + void push_back(const DataType &value) { Storage.push_back(value); } + void push_back(DataType &&value) { Storage.push_back(value); } + + typedef typename std::vector::reference reference; + typedef typename std::vector::const_reference const_reference; + reference operator[](size_type pos) { return Storage[pos]; } + const_reference operator[](size_type pos) const { return Storage[pos]; } + + iterator erase(const_iterator pos) { return Storage.erase(pos); } + iterator erase(const_iterator first, const_iterator last) { + return Storage.erase(first, last); } + + iterator erase(iterator pos) { return Storage.erase(pos); } + iterator erase(iterator first, iterator last) { + return Storage.erase(first, last); + } + + iterator insert(const_iterator pos, const DataType &value) { + return Storage.insert(pos, value); + } + iterator insert(const_iterator pos, DataType &&value) { + return Storage.insert(pos, value); + } + + iterator insert(iterator pos, const DataType &value) { + return Storage.insert(pos, value); + } + iterator insert(iterator pos, DataType &&value) { + return Storage.insert(pos, value); + } + + reference front() { return Storage.front(); } + const_reference front() const { return Storage.front(); } + + operator std::vector&() { return Storage; } + operator ArrayRef() { return Storage; } + std::vector *operator&() { return &Storage; } + const std::vector *operator&() const { return &Storage; } + + template void addValue(const T &V) { Storage.push_back(V); } }; //===----------------------------------------------------------------------===// // list - A list of command line options. // -template > -class list : public Option, public list_storage { +class list : public Option, public list_storage { std::vector Positions; ParserClass Parser; @@ -1319,7 +1376,7 @@ class list : public Option, public list_storage { typename ParserClass::parser_data_type(); if (Parser.parse(*this, ArgName, Arg, Val)) return true; // Parse Error! - list_storage::addValue(Val); + list_storage::addValue(Val); setPosition(pos); Positions.push_back(pos); return false; diff --git a/include/llvm/Support/Compiler.h b/include/llvm/Support/Compiler.h index c81fbaff9dba..67ef23d43c99 100644 --- a/include/llvm/Support/Compiler.h +++ b/include/llvm/Support/Compiler.h @@ -350,19 +350,6 @@ # define LLVM_ADDRESS_SANITIZER_BUILD 0 #endif -/// \macro LLVM_IS_UNALIGNED_ACCESS_FAST -/// \brief Is unaligned memory access fast on the host machine. -/// -/// Don't specialize on alignment for platforms where unaligned memory accesses -/// generates the same code as aligned memory accesses for common types. -#if defined(_M_AMD64) || defined(_M_IX86) || defined(__amd64) || \ - defined(__amd64__) || defined(__x86_64) || defined(__x86_64__) || \ - defined(_X86_) || defined(__i386) || defined(__i386__) -# define LLVM_IS_UNALIGNED_ACCESS_FAST 1 -#else -# define LLVM_IS_UNALIGNED_ACCESS_FAST 0 -#endif - /// \brief Mark debug helper function definitions like dump() that should not be /// stripped from debug builds. // FIXME: Move this to a private config.h as it's not usable in public headers. diff --git a/include/llvm/Support/ELFRelocs/Hexagon.def b/include/llvm/Support/ELFRelocs/Hexagon.def index c9d35b8bd75e..a698ecb89e16 100644 --- a/include/llvm/Support/ELFRelocs/Hexagon.def +++ b/include/llvm/Support/ELFRelocs/Hexagon.def @@ -90,3 +90,11 @@ ELF_RELOC(R_HEX_IE_GOT_11_X, 82) ELF_RELOC(R_HEX_TPREL_32_6_X, 83) ELF_RELOC(R_HEX_TPREL_16_X, 84) ELF_RELOC(R_HEX_TPREL_11_X, 85) +ELF_RELOC(R_HEX_LD_PLT_B22_PCREL, 86) +ELF_RELOC(R_HEX_LD_GOT_LO16, 87) +ELF_RELOC(R_HEX_LD_GOT_HI16, 88) +ELF_RELOC(R_HEX_LD_GOT_32, 89) +ELF_RELOC(R_HEX_LD_GOT_16, 90) +ELF_RELOC(R_HEX_LD_GOT_32_6_X, 91) +ELF_RELOC(R_HEX_LD_GOT_16_X, 92) +ELF_RELOC(R_HEX_LD_GOT_11_X, 93) diff --git a/include/llvm/Support/MathExtras.h b/include/llvm/Support/MathExtras.h index e3166165a483..2cf7e0e5d0b3 100644 --- a/include/llvm/Support/MathExtras.h +++ b/include/llvm/Support/MathExtras.h @@ -562,7 +562,7 @@ inline uint64_t MinAlign(uint64_t A, uint64_t B) { /// /// Alignment should be a power of two. This method rounds up, so /// alignAddr(7, 4) == 8 and alignAddr(8, 4) == 8. -inline uintptr_t alignAddr(void *Addr, size_t Alignment) { +inline uintptr_t alignAddr(const void *Addr, size_t Alignment) { assert(Alignment && isPowerOf2_64((uint64_t)Alignment) && "Alignment is not a power of two!"); @@ -573,7 +573,7 @@ inline uintptr_t alignAddr(void *Addr, size_t Alignment) { /// \brief Returns the necessary adjustment for aligning \c Ptr to \c Alignment /// bytes, rounding up. -inline size_t alignmentAdjustment(void *Ptr, size_t Alignment) { +inline size_t alignmentAdjustment(const void *Ptr, size_t Alignment) { return alignAddr(Ptr, Alignment) - (uintptr_t)Ptr; } diff --git a/include/llvm/Support/TargetParser.h b/include/llvm/Support/TargetParser.h index ca626f271d51..777ee2075d61 100644 --- a/include/llvm/Support/TargetParser.h +++ b/include/llvm/Support/TargetParser.h @@ -15,6 +15,10 @@ #ifndef LLVM_SUPPORT_TARGETPARSER_H #define LLVM_SUPPORT_TARGETPARSER_H +// FIXME: vector is used because that's what clang uses for subtarget feature +// lists, but SmallVector would probably be better +#include + namespace llvm { class StringRef; @@ -28,13 +32,16 @@ namespace ARM { // FPU names. enum FPUKind { FK_INVALID = 0, + FK_NONE, FK_VFP, FK_VFPV2, FK_VFPV3, FK_VFPV3_D16, FK_VFPV4, FK_VFPV4_D16, + FK_FPV4_SP_D16, FK_FPV5_D16, + FK_FPV5_SP_D16, FK_FP_ARMV8, FK_NEON, FK_NEON_VFPV4, @@ -44,6 +51,20 @@ namespace ARM { FK_LAST }; + // An FPU name implies one of three levels of Neon support: + enum NeonSupportLevel { + NS_None = 0, ///< No Neon + NS_Neon, ///< Neon + NS_Crypto ///< Neon with Crypto + }; + + // An FPU name restricts the FPU in one of three ways: + enum FPURestriction { + FR_None = 0, ///< No restriction + FR_D16, ///< Only 16 D registers + FR_SP_D16 ///< Only single-precision instructions, with 16 D registers + }; + // Arch names. enum ArchKind { AK_INVALID = 0, @@ -53,34 +74,34 @@ namespace ARM { AK_ARMV3M, AK_ARMV4, AK_ARMV4T, - AK_ARMV5, AK_ARMV5T, AK_ARMV5TE, + AK_ARMV5TEJ, AK_ARMV6, - AK_ARMV6J, AK_ARMV6K, AK_ARMV6T2, AK_ARMV6Z, AK_ARMV6ZK, AK_ARMV6M, - AK_ARMV7, + AK_ARMV6SM, AK_ARMV7A, AK_ARMV7R, AK_ARMV7M, + AK_ARMV7EM, AK_ARMV8A, AK_ARMV8_1A, // Non-standard Arch names. AK_IWMMXT, AK_IWMMXT2, AK_XSCALE, + AK_ARMV5, AK_ARMV5E, - AK_ARMV5TEJ, - AK_ARMV6SM, + AK_ARMV6J, AK_ARMV6HL, + AK_ARMV7, AK_ARMV7L, AK_ARMV7HL, AK_ARMV7S, - AK_ARMV7EM, AK_LAST }; @@ -92,8 +113,15 @@ namespace ARM { AEK_FP, AEK_HWDIV, AEK_MP, + AEK_SIMD, AEK_SEC, AEK_VIRT, + // Unsupported extensions. + AEK_OS, + AEK_IWMMXT, + AEK_IWMMXT2, + AEK_MAVERICK, + AEK_XSCALE, AEK_LAST }; @@ -132,9 +160,16 @@ class ARMTargetParser { // Information by ID static const char * getFPUName(unsigned FPUKind); + static unsigned getFPUVersion(unsigned FPUKind); + static unsigned getFPUNeonSupportLevel(unsigned FPUKind); + static unsigned getFPURestriction(unsigned FPUKind); + // FIXME: This should be moved to TargetTuple once it exists + static bool getFPUFeatures(unsigned FPUKind, + std::vector &Features); static const char * getArchName(unsigned ArchKind); - static unsigned getArchDefaultCPUArch(unsigned ArchKind); - static const char * getArchDefaultCPUName(unsigned ArchKind); + static unsigned getArchAttr(unsigned ArchKind); + static const char * getCPUAttr(unsigned ArchKind); + static const char * getSubArch(unsigned ArchKind); static const char * getArchExtName(unsigned ArchExtKind); static const char * getDefaultCPU(StringRef Arch); diff --git a/include/llvm/Support/TargetRegistry.h b/include/llvm/Support/TargetRegistry.h index 408e908aa04c..837fc66f38af 100644 --- a/include/llvm/Support/TargetRegistry.h +++ b/include/llvm/Support/TargetRegistry.h @@ -91,7 +91,7 @@ class Target { typedef bool (*ArchMatchFnTy)(Triple::ArchType Arch); typedef MCAsmInfo *(*MCAsmInfoCtorFnTy)(const MCRegisterInfo &MRI, - StringRef TT); + const Triple &TT); typedef MCCodeGenInfo *(*MCCodeGenInfoCtorFnTy)(StringRef TT, Reloc::Model RM, CodeModel::Model CM, CodeGenOpt::Level OL); @@ -287,15 +287,15 @@ class Target { /// createMCAsmInfo - Create a MCAsmInfo implementation for the specified /// target triple. /// - /// \param Triple This argument is used to determine the target machine + /// \param TheTriple This argument is used to determine the target machine /// feature set; it should always be provided. Generally this should be /// either the target triple from the module, or the target triple of the /// host if that does not exist. MCAsmInfo *createMCAsmInfo(const MCRegisterInfo &MRI, - StringRef Triple) const { + StringRef TheTriple) const { if (!MCAsmInfoCtorFn) return nullptr; - return MCAsmInfoCtorFn(MRI, Triple); + return MCAsmInfoCtorFn(MRI, Triple(TheTriple)); } /// createMCCodeGenInfo - Create a MCCodeGenInfo implementation. @@ -889,7 +889,8 @@ template struct RegisterMCAsmInfo { } private: - static MCAsmInfo *Allocator(const MCRegisterInfo & /*MRI*/, StringRef TT) { + static MCAsmInfo *Allocator(const MCRegisterInfo & /*MRI*/, + const Triple &TT) { return new MCAsmInfoImpl(TT); } }; diff --git a/include/llvm/Support/YAMLTraits.h b/include/llvm/Support/YAMLTraits.h index 3bdff2091809..c04294a5e87a 100644 --- a/include/llvm/Support/YAMLTraits.h +++ b/include/llvm/Support/YAMLTraits.h @@ -1090,6 +1090,9 @@ class Input : public IO { bool setCurrentDocument(); bool nextDocument(); + /// Returns the current node that's being parsed by the YAML Parser. + const Node *getCurrentNode() const; + private: llvm::SourceMgr SrcMgr; // must be before Strm std::unique_ptr Strm; @@ -1111,7 +1114,7 @@ class Input : public IO { /// class Output : public IO { public: - Output(llvm::raw_ostream &, void *Ctxt=nullptr); + Output(llvm::raw_ostream &, void *Ctxt = nullptr, int WrapColumn = 70); ~Output() override; bool outputting() override; @@ -1167,6 +1170,7 @@ class Output : public IO { }; llvm::raw_ostream &Out; + int WrapColumn; SmallVector StateStack; int Column; int ColumnAtFlowStart; diff --git a/include/llvm/TableGen/Record.h b/include/llvm/TableGen/Record.h index 75765557a776..14ad63603358 100644 --- a/include/llvm/TableGen/Record.h +++ b/include/llvm/TableGen/Record.h @@ -17,48 +17,20 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/FoldingSet.h" -#include "llvm/Support/Allocator.h" +#include "llvm/ADT/PointerIntPair.h" #include "llvm/Support/Casting.h" #include "llvm/Support/DataTypes.h" #include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/SourceMgr.h" +#include "llvm/Support/SMLoc.h" #include "llvm/Support/raw_ostream.h" #include namespace llvm { -// RecTy subclasses. -class BitRecTy; -class BitsRecTy; -class IntRecTy; -class StringRecTy; class ListRecTy; -class DagRecTy; -class RecordRecTy; - -// Init subclasses. -class Init; -class UnsetInit; -class BitInit; -class BitsInit; -class IntInit; -class StringInit; -class ListInit; -class UnOpInit; -class BinOpInit; -class TernOpInit; -class DefInit; -class DagInit; -class TypedInit; -class VarInit; -class FieldInit; -class VarBitInit; -class VarListElementInit; - -// Other classes. +struct MultiClass; class Record; class RecordVal; -struct MultiClass; class RecordKeeper; //===----------------------------------------------------------------------===// @@ -81,12 +53,11 @@ class RecTy { private: RecTyKind Kind; std::unique_ptr ListTy; - virtual void anchor(); public: RecTyKind getRecTyKind() const { return Kind; } - RecTy(RecTyKind K) : Kind(K), ListTy(nullptr) {} + RecTy(RecTyKind K) : Kind(K) {} virtual ~RecTy() {} virtual std::string getAsString() const = 0; @@ -95,40 +66,10 @@ class RecTy { /// typeIsConvertibleTo - Return true if all values of 'this' type can be /// converted to the specified type. - virtual bool typeIsConvertibleTo(const RecTy *RHS) const = 0; + virtual bool typeIsConvertibleTo(const RecTy *RHS) const; /// getListTy - Returns the type representing list. ListRecTy *getListTy(); - -public: // These methods should only be called from subclasses of Init - virtual Init *convertValue( UnsetInit *UI) { return nullptr; } - virtual Init *convertValue( BitInit *BI) { return nullptr; } - virtual Init *convertValue( BitsInit *BI) { return nullptr; } - virtual Init *convertValue( IntInit *II) { return nullptr; } - virtual Init *convertValue(StringInit *SI) { return nullptr; } - virtual Init *convertValue( ListInit *LI) { return nullptr; } - virtual Init *convertValue( UnOpInit *UO) { - return convertValue((TypedInit*)UO); - } - virtual Init *convertValue( BinOpInit *BO) { - return convertValue((TypedInit*)BO); - } - virtual Init *convertValue( TernOpInit *TO) { - return convertValue((TypedInit*)TO); - } - virtual Init *convertValue(VarBitInit *VB) { return nullptr; } - virtual Init *convertValue( DefInit *DI) { return nullptr; } - virtual Init *convertValue( DagInit *DI) { return nullptr; } - virtual Init *convertValue( TypedInit *TI) { return nullptr; } - virtual Init *convertValue( VarInit *VI) { - return convertValue((TypedInit*)VI); - } - virtual Init *convertValue( FieldInit *FI) { - return convertValue((TypedInit*)FI); - } - -public: - virtual bool baseClassOf(const RecTy*) const; }; inline raw_ostream &operator<<(raw_ostream &OS, const RecTy &Ty) { @@ -149,20 +90,9 @@ class BitRecTy : public RecTy { static BitRecTy *get() { return &Shared; } - using RecTy::convertValue; - Init *convertValue( UnsetInit *UI) override { return (Init*)UI; } - Init *convertValue( BitInit *BI) override { return (Init*)BI; } - Init *convertValue( BitsInit *BI) override; - Init *convertValue( IntInit *II) override; - Init *convertValue(VarBitInit *VB) override { return (Init*)VB; } - Init *convertValue( TypedInit *TI) override; - std::string getAsString() const override { return "bit"; } - bool typeIsConvertibleTo(const RecTy *RHS) const override { - return RHS->baseClassOf(this); - } - bool baseClassOf(const RecTy*) const override; + bool typeIsConvertibleTo(const RecTy *RHS) const override; }; /// BitsRecTy - 'bits' - Represent a fixed number of bits @@ -180,19 +110,9 @@ class BitsRecTy : public RecTy { unsigned getNumBits() const { return Size; } - using RecTy::convertValue; - Init *convertValue( UnsetInit *UI) override; - Init *convertValue( BitInit *UI) override; - Init *convertValue( BitsInit *BI) override; - Init *convertValue( IntInit *II) override; - Init *convertValue( TypedInit *TI) override; - std::string getAsString() const override; - bool typeIsConvertibleTo(const RecTy *RHS) const override { - return RHS->baseClassOf(this); - } - bool baseClassOf(const RecTy*) const override; + bool typeIsConvertibleTo(const RecTy *RHS) const override; }; /// IntRecTy - 'int' - Represent an integer value of no particular size @@ -208,20 +128,9 @@ class IntRecTy : public RecTy { static IntRecTy *get() { return &Shared; } - using RecTy::convertValue; - Init *convertValue( UnsetInit *UI) override { return (Init*)UI; } - Init *convertValue( BitInit *BI) override; - Init *convertValue( BitsInit *BI) override; - Init *convertValue( IntInit *II) override { return (Init*)II; } - Init *convertValue( TypedInit *TI) override; - std::string getAsString() const override { return "int"; } - bool typeIsConvertibleTo(const RecTy *RHS) const override { - return RHS->baseClassOf(this); - } - - bool baseClassOf(const RecTy*) const override; + bool typeIsConvertibleTo(const RecTy *RHS) const override; }; /// StringRecTy - 'string' - Represent an string value @@ -237,18 +146,7 @@ class StringRecTy : public RecTy { static StringRecTy *get() { return &Shared; } - using RecTy::convertValue; - Init *convertValue( UnsetInit *UI) override { return (Init*)UI; } - Init *convertValue(StringInit *SI) override { return (Init*)SI; } - Init *convertValue( UnOpInit *UO) override; - Init *convertValue( BinOpInit *BO) override; - Init *convertValue( TypedInit *TI) override; - - std::string getAsString() const override { return "string"; } - - bool typeIsConvertibleTo(const RecTy *RHS) const override { - return RHS->baseClassOf(this); - } + std::string getAsString() const override; }; /// ListRecTy - 'list' - Represent a list of values, all of which must be of @@ -267,18 +165,9 @@ class ListRecTy : public RecTy { static ListRecTy *get(RecTy *T) { return T->getListTy(); } RecTy *getElementType() const { return Ty; } - using RecTy::convertValue; - Init *convertValue( UnsetInit *UI) override { return (Init*)UI; } - Init *convertValue( ListInit *LI) override; - Init *convertValue( TypedInit *TI) override; - std::string getAsString() const override; - bool typeIsConvertibleTo(const RecTy *RHS) const override { - return RHS->baseClassOf(this); - } - - bool baseClassOf(const RecTy*) const override; + bool typeIsConvertibleTo(const RecTy *RHS) const override; }; /// DagRecTy - 'dag' - Represent a dag fragment @@ -294,18 +183,7 @@ class DagRecTy : public RecTy { static DagRecTy *get() { return &Shared; } - using RecTy::convertValue; - Init *convertValue( UnsetInit *UI) override { return (Init*)UI; } - Init *convertValue( UnOpInit *UO) override; - Init *convertValue( BinOpInit *BO) override; - Init *convertValue( DagInit *DI) override { return (Init*)DI; } - Init *convertValue( TypedInit *TI) override; - - std::string getAsString() const override { return "dag"; } - - bool typeIsConvertibleTo(const RecTy *RHS) const override { - return RHS->baseClassOf(this); - } + std::string getAsString() const override; }; /// RecordRecTy - '[classname]' - Represent an instance of a class, such as: @@ -325,17 +203,9 @@ class RecordRecTy : public RecTy { Record *getRecord() const { return Rec; } - using RecTy::convertValue; - Init *convertValue( UnsetInit *UI) override { return (Init*)UI; } - Init *convertValue( DefInit *DI) override; - Init *convertValue( TypedInit *TI) override; - std::string getAsString() const override; - bool typeIsConvertibleTo(const RecTy *RHS) const override { - return RHS->baseClassOf(this); - } - bool baseClassOf(const RecTy*) const override; + bool typeIsConvertibleTo(const RecTy *RHS) const override; }; /// resolveTypes - Find a common type that T1 and T2 convert to. @@ -418,10 +288,8 @@ class Init { /// invokes print on stderr. void dump() const; - /// convertInitializerTo - This virtual function is a simple call-back - /// function that should be overridden to call the appropriate - /// RecTy::convertValue method. - /// + /// convertInitializerTo - This virtual function converts to the appropriate + /// Init based on the passed in type. virtual Init *convertInitializerTo(RecTy *Ty) const = 0; /// convertInitializerBitRange - This method is used to implement the bitrange @@ -511,6 +379,8 @@ class TypedInit : public Init { } RecTy *getType() const { return Ty; } + Init *convertInitializerTo(RecTy *Ty) const override; + Init * convertInitializerBitRange(const std::vector &Bits) const override; Init * @@ -535,7 +405,6 @@ class UnsetInit : public Init { UnsetInit() : Init(IK_UnsetInit) {} UnsetInit(const UnsetInit &) = delete; UnsetInit &operator=(const UnsetInit &Other) = delete; - void anchor() override; public: static bool classof(const Init *I) { @@ -543,9 +412,7 @@ class UnsetInit : public Init { } static UnsetInit *get(); - Init *convertInitializerTo(RecTy *Ty) const override { - return Ty->convertValue(const_cast(this)); - } + Init *convertInitializerTo(RecTy *Ty) const override; Init *getBit(unsigned Bit) const override { return const_cast(this); @@ -563,7 +430,6 @@ class BitInit : public Init { explicit BitInit(bool V) : Init(IK_BitInit), Value(V) {} BitInit(const BitInit &Other) = delete; BitInit &operator=(BitInit &Other) = delete; - void anchor() override; public: static bool classof(const Init *I) { @@ -573,9 +439,7 @@ class BitInit : public Init { bool getValue() const { return Value; } - Init *convertInitializerTo(RecTy *Ty) const override { - return Ty->convertValue(const_cast(this)); - } + Init *convertInitializerTo(RecTy *Ty) const override; Init *getBit(unsigned Bit) const override { assert(Bit < 1 && "Bit index out of range!"); @@ -608,9 +472,7 @@ class BitsInit : public TypedInit, public FoldingSetNode { unsigned getNumBits() const { return Bits.size(); } - Init *convertInitializerTo(RecTy *Ty) const override { - return Ty->convertValue(const_cast(this)); - } + Init *convertInitializerTo(RecTy *Ty) const override; Init * convertInitializerBitRange(const std::vector &Bits) const override; @@ -661,9 +523,7 @@ class IntInit : public TypedInit { int64_t getValue() const { return Value; } - Init *convertInitializerTo(RecTy *Ty) const override { - return Ty->convertValue(const_cast(this)); - } + Init *convertInitializerTo(RecTy *Ty) const override; Init * convertInitializerBitRange(const std::vector &Bits) const override; @@ -692,7 +552,6 @@ class StringInit : public TypedInit { StringInit(const StringInit &Other) = delete; StringInit &operator=(const StringInit &Other) = delete; - void anchor() override; public: static bool classof(const Init *I) { @@ -702,9 +561,7 @@ class StringInit : public TypedInit { const std::string &getValue() const { return Value; } - Init *convertInitializerTo(RecTy *Ty) const override { - return Ty->convertValue(const_cast(this)); - } + Init *convertInitializerTo(RecTy *Ty) const override; std::string getAsString() const override { return "\"" + Value + "\""; } std::string getAsUnquotedString() const override { return Value; } @@ -746,7 +603,6 @@ class ListInit : public TypedInit, public FoldingSetNode { void Profile(FoldingSetNodeID &ID) const; - unsigned getSize() const { return Values.size(); } Init *getElement(unsigned i) const { assert(i < Values.size() && "List element index out of range!"); return Values[i]; @@ -757,9 +613,7 @@ class ListInit : public TypedInit, public FoldingSetNode { Init * convertInitListSlice(const std::vector &Elements) const override; - Init *convertInitializerTo(RecTy *Ty) const override { - return Ty->convertValue(const_cast(this)); - } + Init *convertInitializerTo(RecTy *Ty) const override; /// resolveReferences - This method is used by classes that refer to other /// variables which may not be defined at the time they expression is formed. @@ -772,10 +626,11 @@ class ListInit : public TypedInit, public FoldingSetNode { ArrayRef getValues() const { return Values; } - inline const_iterator begin() const { return Values.begin(); } - inline const_iterator end () const { return Values.end(); } + const_iterator begin() const { return Values.begin(); } + const_iterator end () const { return Values.end(); } - inline bool empty() const { return Values.empty(); } + size_t size () const { return Values.size(); } + bool empty() const { return Values.empty(); } /// resolveListElementReference - This method is used to implement /// VarListElementInit::resolveReferences. If the list element is resolvable @@ -805,17 +660,13 @@ class OpInit : public TypedInit { // Clone - Clone this operator, replacing arguments with the new list virtual OpInit *clone(std::vector &Operands) const = 0; - virtual int getNumOperands() const = 0; - virtual Init *getOperand(int i) const = 0; + virtual unsigned getNumOperands() const = 0; + virtual Init *getOperand(unsigned i) const = 0; // Fold - If possible, fold this to a simpler init. Return this if not // possible to fold. virtual Init *Fold(Record *CurRec, MultiClass *CurMultiClass) const = 0; - Init *convertInitializerTo(RecTy *Ty) const override { - return Ty->convertValue(const_cast(this)); - } - Init *resolveListElementReference(Record &R, const RecordVal *RV, unsigned Elt) const override; @@ -851,8 +702,8 @@ class UnOpInit : public OpInit { return UnOpInit::get(getOpcode(), *Operands.begin(), getType()); } - int getNumOperands() const override { return 1; } - Init *getOperand(int i) const override { + unsigned getNumOperands() const override { return 1; } + Init *getOperand(unsigned i) const override { assert(i == 0 && "Invalid operand id for unary operator"); return getOperand(); } @@ -899,13 +750,12 @@ class BinOpInit : public OpInit { return BinOpInit::get(getOpcode(), Operands[0], Operands[1], getType()); } - int getNumOperands() const override { return 2; } - Init *getOperand(int i) const override { - assert((i == 0 || i == 1) && "Invalid operand id for binary operator"); - if (i == 0) { - return getLHS(); - } else { - return getRHS(); + unsigned getNumOperands() const override { return 2; } + Init *getOperand(unsigned i) const override { + switch (i) { + default: llvm_unreachable("Invalid operand id for binary operator"); + case 0: return getLHS(); + case 1: return getRHS(); } } @@ -955,16 +805,13 @@ class TernOpInit : public OpInit { getType()); } - int getNumOperands() const override { return 3; } - Init *getOperand(int i) const override { - assert((i == 0 || i == 1 || i == 2) && - "Invalid operand id for ternary operator"); - if (i == 0) { - return getLHS(); - } else if (i == 1) { - return getMHS(); - } else { - return getRHS(); + unsigned getNumOperands() const override { return 3; } + Init *getOperand(unsigned i) const override { + switch (i) { + default: llvm_unreachable("Invalid operand id for ternary operator"); + case 0: return getLHS(); + case 1: return getMHS(); + case 2: return getRHS(); } } @@ -1004,10 +851,6 @@ class VarInit : public TypedInit { static VarInit *get(const std::string &VN, RecTy *T); static VarInit *get(Init *VN, RecTy *T); - Init *convertInitializerTo(RecTy *Ty) const override { - return Ty->convertValue(const_cast(this)); - } - const std::string &getName() const; Init *getNameInit() const { return VarName; } std::string getNameInitAsString() const { @@ -1056,9 +899,7 @@ class VarBitInit : public Init { } static VarBitInit *get(TypedInit *T, unsigned B); - Init *convertInitializerTo(RecTy *Ty) const override { - return Ty->convertValue(const_cast(this)); - } + Init *convertInitializerTo(RecTy *Ty) const override; Init *getBitVar() const override { return TI; } unsigned getBitNum() const override { return Bit; } @@ -1095,10 +936,6 @@ class VarListElementInit : public TypedInit { } static VarListElementInit *get(TypedInit *T, unsigned E); - Init *convertInitializerTo(RecTy *Ty) const override { - return Ty->convertValue(const_cast(this)); - } - TypedInit *getVariable() const { return TI; } unsigned getElementNum() const { return Element; } @@ -1131,9 +968,7 @@ class DefInit : public TypedInit { } static DefInit *get(Record*); - Init *convertInitializerTo(RecTy *Ty) const override { - return Ty->convertValue(const_cast(this)); - } + Init *convertInitializerTo(RecTy *Ty) const override; Record *getDef() const { return Def; } @@ -1179,10 +1014,6 @@ class FieldInit : public TypedInit { static FieldInit *get(Init *R, const std::string &FN); static FieldInit *get(Init *R, const Init *FN); - Init *convertInitializerTo(RecTy *Ty) const override { - return Ty->convertValue(const_cast(this)); - } - Init *getBit(unsigned Bit) const override; Init *resolveListElementReference(Record &R, const RecordVal *RV, @@ -1228,9 +1059,7 @@ class DagInit : public TypedInit, public FoldingSetNode { void Profile(FoldingSetNodeID &ID) const; - Init *convertInitializerTo(RecTy *Ty) const override { - return Ty->convertValue(const_cast(this)); - } + Init *convertInitializerTo(RecTy *Ty) const override; Init *getOperator() const { return Val; } @@ -1280,22 +1109,21 @@ class DagInit : public TypedInit, public FoldingSetNode { //===----------------------------------------------------------------------===// class RecordVal { - Init *Name; + PointerIntPair NameAndPrefix; RecTy *Ty; - unsigned Prefix; Init *Value; public: - RecordVal(Init *N, RecTy *T, unsigned P); - RecordVal(const std::string &N, RecTy *T, unsigned P); + RecordVal(Init *N, RecTy *T, bool P); + RecordVal(const std::string &N, RecTy *T, bool P); const std::string &getName() const; - const Init *getNameInit() const { return Name; } + const Init *getNameInit() const { return NameAndPrefix.getPointer(); } std::string getNameInitAsString() const { return getNameInit()->getAsUnquotedString(); } - unsigned getPrefix() const { return Prefix; } + bool getPrefix() const { return NameAndPrefix.getInt(); } RecTy *getType() const { return Ty; } Init *getValue() const { return Value; } @@ -1344,7 +1172,7 @@ class Record { // def Def : Class>; // // These need to get fully resolved before instantiating any other - // definitions that usie them (e.g. Def). However, inside a multiclass they + // definitions that use them (e.g. Def). However, inside a multiclass they // can't be immediately resolved so we mark them ResolveFirst to fully // resolve them later as soon as the multiclass is instantiated. bool ResolveFirst; @@ -1354,13 +1182,6 @@ class Record { public: // Constructs a record. - explicit Record(const std::string &N, ArrayRef locs, - RecordKeeper &records, bool Anonymous = false) : - ID(LastID++), Name(StringInit::get(N)), Locs(locs.begin(), locs.end()), - TrackedRecords(records), TheInit(nullptr), IsAnonymous(Anonymous), - ResolveFirst(false) { - init(); - } explicit Record(Init *N, ArrayRef locs, RecordKeeper &records, bool Anonymous = false) : ID(LastID++), Name(N), Locs(locs.begin(), locs.end()), @@ -1368,6 +1189,10 @@ class Record { ResolveFirst(false) { init(); } + explicit Record(const std::string &N, ArrayRef locs, + RecordKeeper &records, bool Anonymous = false) + : Record(StringInit::get(N), locs, records, Anonymous) {} + // When copy-constructing a Record, we must still guarantee a globally unique // ID number. All other fields can be copied normally. @@ -1406,8 +1231,8 @@ class Record { ArrayRef getSuperClassRanges() const { return SuperClassRanges; } bool isTemplateArg(Init *Name) const { - for (unsigned i = 0, e = TemplateArgs.size(); i != e; ++i) - if (TemplateArgs[i] == Name) return true; + for (Init *TA : TemplateArgs) + if (TA == Name) return true; return false; } bool isTemplateArg(StringRef Name) const { @@ -1415,16 +1240,16 @@ class Record { } const RecordVal *getValue(const Init *Name) const { - for (unsigned i = 0, e = Values.size(); i != e; ++i) - if (Values[i].getNameInit() == Name) return &Values[i]; + for (const RecordVal &Val : Values) + if (Val.getNameInit() == Name) return &Val; return nullptr; } const RecordVal *getValue(StringRef Name) const { return getValue(StringInit::get(Name)); } RecordVal *getValue(const Init *Name) { - for (unsigned i = 0, e = Values.size(); i != e; ++i) - if (Values[i].getNameInit() == Name) return &Values[i]; + for (RecordVal &Val : Values) + if (Val.getNameInit() == Name) return &Val; return nullptr; } RecordVal *getValue(StringRef Name) { @@ -1465,15 +1290,15 @@ class Record { } bool isSubClassOf(const Record *R) const { - for (unsigned i = 0, e = SuperClasses.size(); i != e; ++i) - if (SuperClasses[i] == R) + for (const Record *SC : SuperClasses) + if (SC == R) return true; return false; } bool isSubClassOf(StringRef Name) const { - for (unsigned i = 0, e = SuperClasses.size(); i != e; ++i) - if (SuperClasses[i]->getNameInitAsString() == Name) + for (const Record *SC : SuperClasses) + if (SC->getNameInitAsString() == Name) return true; return false; } @@ -1523,7 +1348,7 @@ class Record { /// Return true if the named field is unset. bool isValueUnset(StringRef FieldName) const { - return getValueInit(FieldName) == UnsetInit::get(); + return isa(getValueInit(FieldName)); } /// getValueAsString - This method looks up the specified field and returns @@ -1675,7 +1500,6 @@ struct LessRecordFieldName { }; struct LessRecordRegister { - static size_t min(size_t a, size_t b) { return a < b ? a : b; } static bool ascii_isdigit(char x) { return x >= '0' && x <= '9'; } struct RecordParts { diff --git a/include/llvm/TableGen/SetTheory.h b/include/llvm/TableGen/SetTheory.h index 595c29f2ee1d..d4e0f53d3efa 100644 --- a/include/llvm/TableGen/SetTheory.h +++ b/include/llvm/TableGen/SetTheory.h @@ -47,9 +47,10 @@ #ifndef LLVM_TABLEGEN_SETTHEORY_H #define LLVM_TABLEGEN_SETTHEORY_H +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SetVector.h" #include "llvm/ADT/StringMap.h" -#include "llvm/Support/SourceMgr.h" +#include "llvm/Support/SMLoc.h" #include #include @@ -58,7 +59,6 @@ namespace llvm { class DagInit; class Init; class Record; -class RecordKeeper; class SetTheory { public: diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td index ec8a12df9fc6..d99f0e1c5dc5 100644 --- a/include/llvm/Target/Target.td +++ b/include/llvm/Target/Target.td @@ -381,6 +381,7 @@ class Instruction { bit hasPostISelHook = 0; // To be *adjusted* after isel by target hook. bit hasCtrlDep = 0; // Does this instruction r/w ctrl-flow chains? bit isNotDuplicable = 0; // Is it unsafe to duplicate this instruction? + bit isConvergent = 0; // Is this instruction convergent? bit isAsCheapAsAMove = 0; // As cheap (or cheaper) than a move instruction. bit hasExtraSrcRegAllocReq = 0; // Sources have special regalloc requirement? bit hasExtraDefRegAllocReq = 0; // Defs have special regalloc requirement? @@ -506,7 +507,7 @@ class Requires preds> { /// ops definition - This is just a simple marker used to identify the operand /// list for an instruction. outs and ins are identical both syntactically and -/// semanticallyr; they are used to define def operands and use operands to +/// semantically; they are used to define def operands and use operands to /// improve readibility. This should be used like this: /// (outs R32:$dst), (ins R32:$src1, R32:$src2) or something similar. def ops; diff --git a/include/llvm/Target/TargetInstrInfo.h b/include/llvm/Target/TargetInstrInfo.h index 5ec15658b696..902b99c61044 100644 --- a/include/llvm/Target/TargetInstrInfo.h +++ b/include/llvm/Target/TargetInstrInfo.h @@ -711,20 +711,22 @@ class TargetInstrInfo : public MCInstrInfo { /// Target-dependent implementation for foldMemoryOperand. /// Target-independent code in foldMemoryOperand will /// take care of adding a MachineMemOperand to the newly created instruction. - virtual MachineInstr *foldMemoryOperandImpl(MachineFunction &MF, - MachineInstr *MI, - ArrayRef Ops, - int FrameIndex) const { + /// The instruction and any auxiliary instructions necessary will be inserted + /// at InsertPt. + virtual MachineInstr *foldMemoryOperandImpl( + MachineFunction &MF, MachineInstr *MI, ArrayRef Ops, + MachineBasicBlock::iterator InsertPt, int FrameIndex) const { return nullptr; } /// Target-dependent implementation for foldMemoryOperand. /// Target-independent code in foldMemoryOperand will /// take care of adding a MachineMemOperand to the newly created instruction. - virtual MachineInstr *foldMemoryOperandImpl(MachineFunction &MF, - MachineInstr *MI, - ArrayRef Ops, - MachineInstr *LoadMI) const { + /// The instruction and any auxiliary instructions necessary will be inserted + /// at InsertPt. + virtual MachineInstr *foldMemoryOperandImpl( + MachineFunction &MF, MachineInstr *MI, ArrayRef Ops, + MachineBasicBlock::iterator InsertPt, MachineInstr *LoadMI) const { return nullptr; } diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h index e2fe9e85fc92..616edd8c2480 100644 --- a/include/llvm/Target/TargetLowering.h +++ b/include/llvm/Target/TargetLowering.h @@ -1431,7 +1431,8 @@ class TargetLoweringBase { /// load/store. virtual bool GetAddrModeArguments(IntrinsicInst * /*I*/, SmallVectorImpl &/*Ops*/, - Type *&/*AccessTy*/) const { + Type *&/*AccessTy*/, + unsigned AddrSpace = 0) const { return false; } @@ -1456,7 +1457,12 @@ class TargetLoweringBase { /// The type may be VoidTy, in which case only return true if the addressing /// mode is legal for a load/store of any legal type. TODO: Handle /// pre/postinc as well. - virtual bool isLegalAddressingMode(const AddrMode &AM, Type *Ty) const; + /// + /// If the address space cannot be determined, it will be -1. + /// + /// TODO: Remove default argument + virtual bool isLegalAddressingMode(const AddrMode &AM, Type *Ty, + unsigned AddrSpace) const; /// \brief Return the cost of the scaling factor used in the addressing mode /// represented by AM for this target, for a load/store of the specified type. @@ -1464,9 +1470,12 @@ class TargetLoweringBase { /// If the AM is supported, the return value must be >= 0. /// If the AM is not supported, it returns a negative value. /// TODO: Handle pre/postinc as well. - virtual int getScalingFactorCost(const AddrMode &AM, Type *Ty) const { + /// TODO: Remove default argument + virtual int getScalingFactorCost(const AddrMode &AM, Type *Ty, + unsigned AS = 0) const { // Default: assume that any scaling factor used in a legal AM is free. - if (isLegalAddressingMode(AM, Ty)) return 0; + if (isLegalAddressingMode(AM, Ty, AS)) + return 0; return -1; } diff --git a/include/llvm/Target/TargetOptions.h b/include/llvm/Target/TargetOptions.h index 07a8f6d3d4cd..8f8b78d9b0b1 100644 --- a/include/llvm/Target/TargetOptions.h +++ b/include/llvm/Target/TargetOptions.h @@ -15,6 +15,7 @@ #ifndef LLVM_TARGET_TARGETOPTIONS_H #define LLVM_TARGET_TARGETOPTIONS_H +#include "llvm/Target/TargetRecip.h" #include "llvm/MC/MCTargetOptions.h" #include @@ -72,7 +73,8 @@ namespace llvm { CompressDebugSections(false), FunctionSections(false), DataSections(false), UniqueSectionNames(true), TrapUnreachable(false), TrapFuncName(), FloatABIType(FloatABI::Default), - AllowFPOpFusion(FPOpFusion::Standard), JTType(JumpTable::Single), + AllowFPOpFusion(FPOpFusion::Standard), Reciprocals(TargetRecip()), + JTType(JumpTable::Single), ThreadModel(ThreadModel::POSIX) {} /// PrintMachineCode - This flag is enabled when the -print-machineinstrs @@ -206,6 +208,9 @@ namespace llvm { /// the value of this option. FPOpFusion::FPOpFusionMode AllowFPOpFusion; + /// This class encapsulates options for reciprocal-estimate code generation. + TargetRecip Reciprocals; + /// JTType - This flag specifies the type of jump-instruction table to /// create for functions that have the jumptable attribute. JumpTable::JumpTableType JTType; @@ -240,6 +245,7 @@ inline bool operator==(const TargetOptions &LHS, ARE_EQUAL(TrapFuncName) && ARE_EQUAL(FloatABIType) && ARE_EQUAL(AllowFPOpFusion) && + ARE_EQUAL(Reciprocals) && ARE_EQUAL(JTType) && ARE_EQUAL(ThreadModel) && ARE_EQUAL(MCOptions); diff --git a/include/llvm/Target/TargetRecip.h b/include/llvm/Target/TargetRecip.h new file mode 100644 index 000000000000..4cc3672d758d --- /dev/null +++ b/include/llvm/Target/TargetRecip.h @@ -0,0 +1,73 @@ +//===--------------------- llvm/Target/TargetRecip.h ------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This class is used to customize machine-specific reciprocal estimate code +// generation in a target-independent way. +// If a target does not support operations in this specification, then code +// generation will default to using supported operations. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TARGET_TARGETRECIP_H +#define LLVM_TARGET_TARGETRECIP_H + +#include "llvm/ADT/StringRef.h" +#include +#include +#include + +namespace llvm { + +struct TargetRecip { +public: + TargetRecip(); + + /// Initialize all or part of the operations from command-line options or + /// a front end. + TargetRecip(const std::vector &Args); + + /// Set whether a particular reciprocal operation is enabled and how many + /// refinement steps are needed when using it. Use "all" to set enablement + /// and refinement steps for all operations. + void setDefaults(const StringRef &Key, bool Enable, unsigned RefSteps); + + /// Return true if the reciprocal operation has been enabled by default or + /// from the command-line. Return false if the operation has been disabled + /// by default or from the command-line. + bool isEnabled(const StringRef &Key) const; + + /// Return the number of iterations necessary to refine the + /// the result of a machine instruction for the given reciprocal operation. + unsigned getRefinementSteps(const StringRef &Key) const; + + bool operator==(const TargetRecip &Other) const; + +private: + enum { + Uninitialized = -1 + }; + + struct RecipParams { + int8_t Enabled; + int8_t RefinementSteps; + + RecipParams() : Enabled(Uninitialized), RefinementSteps(Uninitialized) {} + }; + + std::map RecipMap; + typedef std::map::iterator RecipIter; + typedef std::map::const_iterator ConstRecipIter; + + bool parseGlobalParams(const std::string &Arg); + void parseIndividualParams(const std::vector &Args); +}; + +} // End llvm namespace + +#endif diff --git a/include/llvm/Transforms/Scalar.h b/include/llvm/Transforms/Scalar.h index c4669f121e6a..4676c95d7cd4 100644 --- a/include/llvm/Transforms/Scalar.h +++ b/include/llvm/Transforms/Scalar.h @@ -16,10 +16,12 @@ #define LLVM_TRANSFORMS_SCALAR_H #include "llvm/ADT/StringRef.h" +#include namespace llvm { class BasicBlockPass; +class Function; class FunctionPass; class ModulePass; class Pass; @@ -152,7 +154,14 @@ Pass *createLoopInterchangePass(); // Pass *createLoopStrengthReducePass(); -Pass *createGlobalMergePass(const TargetMachine *TM, unsigned MaximalOffset); +//===----------------------------------------------------------------------===// +// +// GlobalMerge - This pass merges internal (by default) globals into structs +// to enable reuse of a base pointer by indexed addressing modes. +// It can also be configured to focus on size optimizations only. +// +Pass *createGlobalMergePass(const TargetMachine *TM, unsigned MaximalOffset, + bool OnlyOptimizeForSize = false); //===----------------------------------------------------------------------===// // @@ -238,7 +247,8 @@ FunctionPass *createJumpThreadingPass(int Threshold = -1); // CFGSimplification - Merge basic blocks, eliminate unreachable blocks, // simplify terminator instructions, etc... // -FunctionPass *createCFGSimplificationPass(int Threshold = -1); +FunctionPass *createCFGSimplificationPass( + int Threshold = -1, std::function Ftor = nullptr); //===----------------------------------------------------------------------===// // @@ -456,7 +466,7 @@ FunctionPass *createPlaceSafepointsPass(); // RewriteStatepointsForGC - Rewrite any gc.statepoints which do not yet have // explicit relocations to include explicit relocations. // -FunctionPass *createRewriteStatepointsForGCPass(); +ModulePass *createRewriteStatepointsForGCPass(); //===----------------------------------------------------------------------===// // diff --git a/lib/Analysis/AliasAnalysis.cpp b/lib/Analysis/AliasAnalysis.cpp index f54e234bbead..ce46d5300517 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 273eacc16e72..dd6a3a0715e1 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 50890c17f2eb..12c1c7d4af90 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 091943bfc7b3..430b41241edf 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 32fe9b9495d1..b22ee7e24931 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 808a38b6346b..b16cdfef3375 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 097b99eb0a5e..ec56d888dc2f 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 b70de00db04b..c661c7b87dcb 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 @@ class AccessAnalysis { } /// \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); - // 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'); + // 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; + } + + // 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); + bool NeedRTCheck; + bool CanDoRT = Accesses.canCheckPtrAtRT(PtrRtCheck, + NeedRTCheck, SE, + TheLoop, Strides); - DEBUG(dbgs() << "LAA: We need to do " << NumComparisons << - " pointer comparisons.\n"); - - // 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 3c1826a58e66..255bae61eb2f 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 000000000000..f87a017b9211 --- /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 177684fdc9a7..633d6aaad35e 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 0bd427bf74e9..f82235d0c26e 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 - // 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(); - 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; + // 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 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; + } + } + // 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 e1744d1f2965..24cada3e5313 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 a55712c6296a..c4f046340fce 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 05c24285028f..09fe6c0a0bd8 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 a52e20fb35b0..681af2a90072 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 f6d5ccc1a59e..056d87beef15 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/lib/Bitcode/Reader/BitcodeReader.cpp @@ -63,9 +63,7 @@ class BitcodeReaderValueList { // 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 58b87e12912c..5fe4c4bcaec4 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 2487aba448cb..8c6838394ac9 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 206be702e724..2e3b83a09520 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 3258961bfb11..7dbfddf60691 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 e7631dd51521..793e62960dd6 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 01d2c7220ab9..f2da8557a522 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 1ccffe97b80b..fa8449e94c9f 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 a2e5aad96570..1445254e6c28 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 ac014b727b75..1850e042f924 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 @@ class DIEHash { /// \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 58b406b788fb..f8cdde203187 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 c10e70352af0..689184a651ed 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 105ff6c198f8..3f6665bd5768 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 a2799b8d6300..d56982712d53 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 78ec937a6b60..f6249fff4253 100644 --- a/lib/CodeGen/AsmPrinter/DwarfExpression.h +++ b/lib/CodeGen/AsmPrinter/DwarfExpression.h @@ -83,6 +83,9 @@ class DwarfExpression { 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 10b58d4e86ae..5ef333c4cf44 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); +DIEAbbrev &DwarfFile::assignAbbrevNumber(DIE &Die) { + FoldingSetNodeID ID; + DIEAbbrev Abbrev = Die.generateAbbrev(); + Abbrev.Profile(ID); - // 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()); + 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 532ed96c2689..8402027edd6f 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 @@ class DwarfFile { /// \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 04836c614044..907f6706bc6a 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 0d01a9e9fb38..f56c9b4eb13e 100644 --- a/lib/CodeGen/AsmPrinter/DwarfUnit.h +++ b/lib/CodeGen/AsmPrinter/DwarfUnit.h @@ -93,10 +93,6 @@ class DwarfUnit { /// 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 @@ class DwarfUnit { // 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 @@ class DwarfUnit { 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 @@ class DwarfUnit { 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 @@ class DwarfUnit { 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 @@ class DwarfUnit { /// 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/WinCodeViewLineTables.cpp b/lib/CodeGen/AsmPrinter/WinCodeViewLineTables.cpp index 371e20a3e5a0..535b1f605853 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/Win64Exception.cpp b/lib/CodeGen/AsmPrinter/WinException.cpp similarity index 73% rename from lib/CodeGen/AsmPrinter/Win64Exception.cpp rename to lib/CodeGen/AsmPrinter/WinException.cpp index dc6df9cb0144..f1663503c08e 100644 --- a/lib/CodeGen/AsmPrinter/Win64Exception.cpp +++ b/lib/CodeGen/AsmPrinter/WinException.cpp @@ -1,4 +1,4 @@ -//===-- CodeGen/AsmPrinter/Win64Exception.cpp - Dwarf Exception Impl ------===// +//===-- CodeGen/AsmPrinter/WinException.cpp - Dwarf Exception Impl ------===// // // The LLVM Compiler Infrastructure // @@ -11,7 +11,7 @@ // //===----------------------------------------------------------------------===// -#include "Win64Exception.h" +#include "WinException.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/Twine.h" @@ -29,6 +29,7 @@ #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" @@ -38,28 +39,33 @@ #include "llvm/Target/TargetRegisterInfo.h" using namespace llvm; -Win64Exception::Win64Exception(AsmPrinter *A) - : EHStreamer(A), shouldEmitPersonality(false), shouldEmitLSDA(false), - shouldEmitMoves(false) {} +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); +} -Win64Exception::~Win64Exception() {} +WinException::~WinException() {} /// endModule - Emit all exception information that should come after the /// content. -void Win64Exception::endModule() { +void WinException::endModule() { } -void Win64Exception::beginFunction(const MachineFunction *MF) { +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 = MF->getMMI().getPersonality(); + const Function *Per = MMI->getPersonality(); shouldEmitPersonality = hasLandingPads && PerEncoding != dwarf::DW_EH_PE_omit && Per; @@ -68,12 +74,17 @@ void Win64Exception::beginFunction(const MachineFunction *MF) { 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. - 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); @@ -85,27 +96,24 @@ void Win64Exception::beginFunction(const MachineFunction *MF) { // Emit a symbol assignment. Asm->OutStreamer->EmitAssignment( HandlerTypeParentFrameOffset, - MCConstantExpr::Create(I->second, Asm->OutContext)); + MCConstantExpr::create(I->second, Asm->OutContext)); } } - if (!shouldEmitPersonality && !shouldEmitMoves) - return; + if (shouldEmitMoves || shouldEmitPersonality) + Asm->OutStreamer->EmitWinCFIStartProc(Asm->CurrentFnSym); - 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); + 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 Win64Exception::endFunction(const MachineFunction *MF) { - if (!shouldEmitPersonality && !shouldEmitMoves) +void WinException::endFunction(const MachineFunction *MF) { + if (!shouldEmitPersonality && !shouldEmitMoves && !shouldEmitLSDA) return; EHPersonality Per = MMI->getPersonalityType(); @@ -116,16 +124,27 @@ void Win64Exception::endFunction(const MachineFunction *MF) { if (!isMSVCEHPersonality(Per)) MMI->TidyLandingPads(); - if (shouldEmitPersonality) { + if (shouldEmitPersonality || shouldEmitLSDA) { Asm->OutStreamer->PushSection(); - // Emit an UNWIND_INFO struct describing the prologue. - Asm->OutStreamer->EmitWinEHHandlerData(); + 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 @@ -133,20 +152,24 @@ void Win64Exception::endFunction(const MachineFunction *MF) { Asm->OutStreamer->PopSection(); } - Asm->OutStreamer->EmitWinCFIEndProc(); + + if (shouldEmitMoves) + Asm->OutStreamer->EmitWinCFIEndProc(); } -const MCExpr *Win64Exception::createImageRel32(const MCSymbol *Value) { +const MCExpr *WinException::create32bitRef(const MCSymbol *Value) { if (!Value) - return MCConstantExpr::Create(0, Asm->OutContext); - return MCSymbolRefExpr::Create(Value, MCSymbolRefExpr::VK_COFF_IMGREL32, + return MCConstantExpr::create(0, Asm->OutContext); + return MCSymbolRefExpr::create(Value, useImageRel32 + ? MCSymbolRefExpr::VK_COFF_IMGREL32 + : MCSymbolRefExpr::VK_None, Asm->OutContext); } -const MCExpr *Win64Exception::createImageRel32(const GlobalValue *GV) { +const MCExpr *WinException::create32bitRef(const GlobalValue *GV) { if (!GV) - return MCConstantExpr::Create(0, Asm->OutContext); - return createImageRel32(Asm->getSymbol(GV)); + return MCConstantExpr::create(0, Asm->OutContext); + return create32bitRef(Asm->getSymbol(GV)); } /// Emit the language-specific data that __C_specific_handler expects. This @@ -177,7 +200,7 @@ const MCExpr *Win64Exception::createImageRel32(const GlobalValue *GV) { /// imagerel32 LabelLPad; // Zero means __finally. /// } Entries[NumEntries]; /// }; -void Win64Exception::emitCSpecificHandlerTable() { +void WinException::emitCSpecificHandlerTable() { const std::vector &PadInfos = MMI->getLandingPads(); // Simplifying assumptions for first implementation: @@ -227,16 +250,16 @@ void Win64Exception::emitCSpecificHandlerTable() { // 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); + 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(createImageRel32(CSE.EndLabel), - MCConstantExpr::Create(1, Asm->OutContext), + End = MCBinaryExpr::createAdd(create32bitRef(CSE.EndLabel), + MCConstantExpr::create(1, Asm->OutContext), Asm->OutContext); } else { - End = createImageRel32(EHFuncEndSym); + End = create32bitRef(EHFuncEndSym); } // Emit an entry for each action. @@ -248,7 +271,7 @@ void Win64Exception::emitCSpecificHandlerTable() { // emit '1' to indicate a catch-all. const Function *F = Handler.FilterOrFinally; if (F) - Asm->OutStreamer->EmitValue(createImageRel32(Asm->getSymbol(F)), 4); + Asm->OutStreamer->EmitValue(create32bitRef(Asm->getSymbol(F)), 4); else Asm->OutStreamer->EmitIntValue(1, 4); @@ -257,14 +280,14 @@ void Win64Exception::emitCSpecificHandlerTable() { const BlockAddress *BA = Handler.RecoverBA; if (BA) Asm->OutStreamer->EmitValue( - createImageRel32(Asm->GetBlockAddressSymbol(BA)), 4); + create32bitRef(Asm->GetBlockAddressSymbol(BA)), 4); else Asm->OutStreamer->EmitIntValue(0, 4); } } } -void Win64Exception::emitCXXFrameHandler3Table(const MachineFunction *MF) { +void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) { const Function *F = MF->getFunction(); const Function *ParentF = MMI->getWinEHParent(F); auto &OS = *Asm->OutStreamer; @@ -273,9 +296,178 @@ void Win64Exception::emitCXXFrameHandler3Table(const MachineFunction *MF) { StringRef ParentLinkageName = GlobalValue::getRealLinkageName(ParentF->getName()); - MCSymbol *FuncInfoXData = - Asm->OutContext.getOrCreateSymbol(Twine("$cppxdata$", ParentLinkageName)); - OS.EmitValue(createImageRel32(FuncInfoXData), 4); + 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. @@ -306,8 +498,8 @@ void Win64Exception::emitCXXFrameHandler3Table(const MachineFunction *MF) { 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])); + FuncInfo.IPToStateList.push_back( + std::make_pair(LastLabel, FuncInfo.HandlerBaseState[F])); LastEHState = FuncInfo.HandlerBaseState[F]; } for (const auto &MBB : *MF) { @@ -348,157 +540,4 @@ void Win64Exception::emitCXXFrameHandler3Table(const MachineFunction *MF) { 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/WinException.h similarity index 68% rename from lib/CodeGen/AsmPrinter/Win64Exception.h rename to lib/CodeGen/AsmPrinter/WinException.h index 5f4237fc0152..478899b79da9 100644 --- a/lib/CodeGen/AsmPrinter/Win64Exception.h +++ b/lib/CodeGen/AsmPrinter/WinException.h @@ -1,4 +1,4 @@ -//===-- Win64Exception.h - Windows Exception Handling ----------*- C++ -*--===// +//===-- WinException.h - Windows Exception Handling ----------*- C++ -*--===// // // The LLVM Compiler Infrastructure // @@ -17,33 +17,41 @@ #include "EHStreamer.h" namespace llvm { +class Function; class GlobalValue; class MachineFunction; class MCExpr; +struct WinEHFuncInfo; -class Win64Exception : public EHStreamer { +class WinException : public EHStreamer { /// Per-function flag to indicate if personality info should be emitted. - bool shouldEmitPersonality; + bool shouldEmitPersonality = false; /// Per-function flag to indicate if the LSDA should be emitted. - bool shouldEmitLSDA; + bool shouldEmitLSDA = false; /// Per-function flag to indicate if frame moves info should be emitted. - bool shouldEmitMoves; + 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); - const MCExpr *createImageRel32(const MCSymbol *Value); - const MCExpr *createImageRel32(const GlobalValue *GV); + 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. // - Win64Exception(AsmPrinter *A); - ~Win64Exception() override; + WinException(AsmPrinter *A); + ~WinException() override; /// Emit all exception information that should come after the content. void endModule() override; diff --git a/lib/CodeGen/CMakeLists.txt b/lib/CodeGen/CMakeLists.txt index 9fc3e0bcec9a..6d2af9003509 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 2c1858b944c6..6a814038c688 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 @@ class AddressingModeMatcher { /// 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 @@ class AddressingModeMatcher { 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 3d62d4887602..dba280fd5aa2 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 092b7f804e4f..d3687b98b344 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 79de17567f76..37b3bf17ed1f 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 0d59c72cb8f7..e861ceb2a664 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 fee0347ea659..05905d04dabf 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 610c9f47bac7..ff5205801bc4 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 adca4cc738e1..c00b010e763b 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 @@ class LiveIntervals::HMEditor { 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 27c57d5f3029..08bbe0c3f379 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 000000000000..468f072ed7f3 --- /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 000000000000..04ae72290f93 --- /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 000000000000..7a51b3881afc --- /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 000000000000..c02d18806a9c --- /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 000000000000..5e0f4cdcbfde --- /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 43c80b7c21bf..a6863412132b 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 8ec63f823e17..09662b6e48d3 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 205032f92971..e67102865bfa 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 0690f08d495b..cd820ee1ac52 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 3967a2fbf8c8..cce590c6dc5b 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 d9da7bcca4fa..eec984f53b90 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 5f03390f146c..aed0e500d441 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 e07250bf4f34..34ac9d5b0ed7 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 f5edcb7393e4..ca35ec5fdcf8 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 4ab3e3c0013e..96f7ca585138 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 690224342f64..4cd86e66c0e8 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 b1538006e724..5f8194983484 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 ac7d98f258b1..e513a4f1ccf5 100644 --- a/lib/CodeGen/RegisterCoalescer.cpp +++ b/lib/CodeGen/RegisterCoalescer.cpp @@ -1834,12 +1834,12 @@ class JoinVals { 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 667783e29526..450a3051c6ff 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 7626dd29c00a..a34bd6341d22 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 c60c5183b429..e8e47b764dd2 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 2c2dc8598169..a71c6761c75f 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 7b5b8c4eabcf..f3d75cb32a7d 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 eeaebf780cc3..96e2ff89013a 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 3853ada5fb0b..f4c7b5934829 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 efd4bd9a4d89..cf51e756d847 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 85303d27dcf8..8ba957d62870 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 2d4ab6c5077a..8bbfa01e7594 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 833da4b6d59c..9daf2a50ad8f 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 ffe59c19d3e0..1e8e03f9a7df 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 92488defc793..c809087d3da4 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 b7f1db6529f7..1bc89aa2271d 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 a32bdf8955ce..d7b043dac013 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 9fb1b5b65fbb..32d5100f8495 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 7246e1cf3ea5..c2b3d84ca363 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 cc2fbbdc8ca7..baab3873b915 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 b63af6a64ee4..a0bee0da1765 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; + 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); - // 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. + // 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 d7038fd2c9a8..9e71b108280b 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 ce1ab594dfa3..55ab5af2b909 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 ec67019947ab..08d9d6b05a0a 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 a26740b0da8a..39a8027005f8 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 8509852b652e..9d29a41f5041 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 24a3ec19aed4..6d64d6837430 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,